diff --git a/docs/changelog.rst b/docs/changelog.rst index c2bbd6d22..65eb0433e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -44,6 +44,8 @@ Detailed list of changes - A new option :opt:`modify_font` to adjust various font metrics like underlines, cell sizes etc. (:pull:`5265`) +- A new mappable action :ac:`show_kitty_doc` to display the kitty docs in a browser + - Graphics protocol: Only delete temp files if they have the string :code:`tty-graphics-protocol` in their file paths. This prevents deletion of arbitrary files in :file:`/tmp`. diff --git a/kitty/options/utils.py b/kitty/options/utils.py index 9ab74d042..749018559 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -136,7 +136,7 @@ def detach_tab_parse(func: str, rest: str) -> FuncArgsType: return func, (rest,) -@func_with_args('set_background_opacity', 'goto_layout', 'toggle_layout', 'kitty_shell') +@func_with_args('set_background_opacity', 'goto_layout', 'toggle_layout', 'kitty_shell', 'show_kitty_doc') def simple_parse(func: str, rest: str) -> FuncArgsType: return func, [rest] diff --git a/kitty/utils.py b/kitty/utils.py index 2f1d86fb7..db72d38cd 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -1069,3 +1069,18 @@ def safer_fork() -> int: import atexit atexit._clear() return pid + + +def docs_url(which: str = '', local_docs_root: str = '') -> str: + from urllib.parse import quote + from .constants import local_docs, website_url + ld = local_docs_root or local_docs() + base, frag = which.partition('#')[::2] + if ld: + base = base or 'index' + url = f'file://{ld}/' + quote(base) + '.html' + else: + url = website_url(base) + if frag: + url += '#' + frag + return url diff --git a/kitty/window.py b/kitty/window.py index d9bd3cc55..3140ee38e 100644 --- a/kitty/window.py +++ b/kitty/window.py @@ -48,8 +48,8 @@ from .terminfo import get_capabilities from .types import MouseEvent, WindowGeometry, ac, run_once from .typing import BossType, ChildType, EdgeLiteral, TabType, TypedDict from .utils import ( - get_primary_selection, kitty_ansi_sanitizer_pat, load_shaders, log_error, - open_cmd, open_url, parse_color_set, path_from_osc7_url, + docs_url, get_primary_selection, kitty_ansi_sanitizer_pat, load_shaders, + log_error, open_cmd, open_url, parse_color_set, path_from_osc7_url, resolve_custom_file, resolved_shell, sanitize_title, set_primary_selection ) @@ -1669,4 +1669,18 @@ class Window: if pid is not None: for sig in signals: os.kill(pid, sig) + + @ac('misc', ''' + Display the specified kitty documentation, preferring a local copy, if found. + + For example:: + + # show the config docs + map F1 show_kitty_doc conf + # show the ssh kitten docs + map F1 show_kitty_doc kittens/ssh + ''') + def show_kitty_doc(self, which: str = '') -> None: + url = docs_url(which) + get_boss().open_url(url) # }}} diff --git a/kitty_tests/check_build.py b/kitty_tests/check_build.py index 741af9d2a..a9f282021 100644 --- a/kitty_tests/check_build.py +++ b/kitty_tests/check_build.py @@ -5,6 +5,7 @@ import os import sys import unittest +from functools import partial from . import BaseTest @@ -74,6 +75,13 @@ class TestBuild(BaseTest): import pygments del pygments + def test_docs_url(self): + from kitty.utils import docs_url + p = partial(docs_url, local_docs_root='/docs') + self.ae(p(), 'file:///docs/index.html') + self.ae(p('conf'), 'file:///docs/conf.html') + self.ae(p('kittens/ssh#frag'), 'file:///docs/kittens/ssh.html#frag') + def main() -> None: tests = unittest.defaultTestLoader.loadTestsFromTestCase(TestBuild)