diff --git a/docs/actions.rst b/docs/actions.rst new file mode 100644 index 000000000..3430296c9 --- /dev/null +++ b/docs/actions.rst @@ -0,0 +1,15 @@ +:tocdepth: 2 + +Mappable actions +=================== + +.. highlight:: conf + +The actions described below can be mapped to any key press or mouse action +using the ``map`` and ``mouse_map`` directives in :file:`kitty.conf`. + +.. contents:: + :local: + :depth: 1 + +.. include:: /generated/actions.rst diff --git a/docs/basic.rst b/docs/basic.rst index 8089968ec..c7010306c 100644 --- a/docs/basic.rst +++ b/docs/basic.rst @@ -102,6 +102,9 @@ the currently active window:: Other keyboard shortcuts ---------------------------------- +The full list of actions that can be mapped to key presses is available +:doc:`here `. + ================================== ======================= Action Shortcut ================================== ======================= diff --git a/docs/conf.py b/docs/conf.py index 152d5642b..8b8a2b143 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -510,6 +510,10 @@ def write_conf_docs(app: Any, all_kitten_names: Iterable[str]) -> None: definition = get_kitten_conf_docs(kitten) if definition: generate_default_config(definition, f'kitten-{kitten}') + + from kitty.actions import as_rst + with open(f'generated/actions.rst', 'w', encoding='utf-8') as f: + f.write(as_rst()) # }}} diff --git a/kitty/actions.py b/kitty/actions.py new file mode 100644 index 000000000..bb9e65fd1 --- /dev/null +++ b/kitty/actions.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python +# vim:fileencoding=utf-8 +# License: GPLv3 Copyright: 2021, Kovid Goyal + +from typing import NamedTuple, Dict, List +from .window import Window +from .tabs import Tab +from .boss import Boss +from .types import run_once +import inspect + + +class Action(NamedTuple): + name: str + group: str + short_help: str + long_help: str + + +groups = { + 'cp': 'Copy/paste', + 'sc': 'Scrolling', + 'win': 'Window management', + 'tab': 'Tab management', + 'mouse': 'Mouse actions', + 'mk': 'Marks', + 'misc': 'Miscellaneous', +} +group_title = groups.__getitem__ + + +@run_once +def get_all_actions() -> Dict[str, List[Action]]: + + ans: Dict[str, List[Action]] = {} + + def is_action(x: object) -> bool: + doc = getattr(x, '__doc__', '') + return bool(doc and doc.strip().startswith('@ac:')) + + def as_action(x: object) -> Action: + doc = (x.__doc__ or '').strip() + lines = doc.splitlines() + first = lines.pop(0) + parts = first.split(':', 2) + grp = parts[1].strip() + short_help = parts[2].strip() + long_help = '\n'.join(lines).strip() + return Action(getattr(x, '__name__'), grp, short_help, long_help) + + seen = set() + for cls in (Window, Tab, Boss): + for (name, func) in inspect.getmembers(cls, is_action): + ac = as_action(func) + if ac.name not in seen: + ans.setdefault(ac.group, []).append(ac) + seen.add(ac.name) + return ans + + +def dump() -> None: + from pprint import pprint + pprint(get_all_actions()) + + +def as_rst() -> str: + allg = get_all_actions() + lines: List[str] = [] + a = lines.append + for group in sorted(allg, key=lambda x: group_title(x).lower()): + title = group_title(group) + a('') + a(f'.. _action-group-{group}:') + a('') + a(title) + a('-' * len(title)) + a('') + a('.. contents::') + a(' :local:') + a(' :depth: 1') + a('') + + for action in allg[group]: + a('') + a(f'.. _action-{action.name}:') + a('') + a(action.name) + a('^' * len(action.name)) + a('') + a(action.short_help) + a('') + if action.long_help: + a(action.long_help) + return '\n'.join(lines) diff --git a/kitty/boss.py b/kitty/boss.py index 79465018d..644579c16 100755 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -566,7 +566,7 @@ class Boss: ''' @ac:misc: Clear the terminal - For example:: + See :sc:`reset_terminal` for details. For example:: # Reset the terminal map kitty_mod+f9 clear_terminal reset active @@ -577,7 +577,6 @@ class Boss: # Scroll the contents of the screen into the scrollback map kitty_mod+f12 clear_terminal scroll active - See :sc:`reset_terminal` for details. ''' if only_active: windows = [] @@ -1067,7 +1066,7 @@ class Boss: return overlay_window def kitten(self, kitten: str, *args: str) -> None: - '@ac:misc: Run the specified kitten. See :doc:`kittens/custom` for details' + '@ac:misc: Run the specified kitten. See :doc:`/kittens/custom` for details' import shlex cmdline = args[0] if args else '' kargs = shlex.split(cmdline) if cmdline else [] @@ -1084,7 +1083,7 @@ class Boss: end_kitten(data, target_window_id, self) def input_unicode_character(self) -> None: - '@ac:misc: Input an arbitrary unicode character. See :doc:`kittens/unicode_input` for details.' + '@ac:misc: Input an arbitrary unicode character. See :doc:`/kittens/unicode-input` for details.' self._run_kitten('unicode_input') def set_tab_title(self) -> None: @@ -1739,7 +1738,7 @@ class Boss: ''' @ac:win: Detach a window, moving it to another tab or OS Window - See :ref:`detach_window` for details. + See :ref:`detaching windows ` for details. ''' if not args or args[0] == 'new': return self._move_window_to(target_os_window_id='new') @@ -1794,7 +1793,7 @@ class Boss: ''' @ac:tab: Detach a tab, moving it to another OS Window - See :ref:`detach_window` for details. + See :ref:`detaching windows ` for details. ''' if not args or args[0] == 'new': return self._move_tab_to() diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 200b25699..8dfbbed5a 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -2700,6 +2700,9 @@ You can use multi-key shortcuts using the syntax shown below:: For example:: map ctrl+f>2 set_font_size 20 + +The full list of actions that can be mapped to key presses is available +:doc:`here `. ''') opt('kitty_mod', 'ctrl+shift',