diff --git a/docs/changelog.rst b/docs/changelog.rst index 0a918a611..7b3293e63 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,6 +10,11 @@ Changelog extended scrollback to use when viewing the scrollback buffer in a pager (:iss:`970`) +- Modify the kittens sub-system to allow creating custom kittens without any + user interface. This is useful for creating more complex actions that can + be bound to key presses in :file:`kitty.conf`. See + `https://sw.kovidgoyal.net/kitty/kittens/custom.html`_. (:iss:`870`) + - Fix the ``*_with_cwd`` actions using the cwd of the overlay window rather than the underlying window's cwd (:iss:`1045`) diff --git a/docs/kittens/custom.rst b/docs/kittens/custom.rst index b7732e63e..5b777602f 100644 --- a/docs/kittens/custom.rst +++ b/docs/kittens/custom.rst @@ -78,3 +78,45 @@ This will send the plain text of the active window to the kitten's instead. If you want line wrap markers as well, use ``screen-ansi`` or just ``screen``. For the scrollback buffer as well, use ``history``, ``ansi-history`` or ``screen-history``. + + +Using kittens to script kitty, without any terminal UI +----------------------------------------------------------- + +If you would like your kitten to script kitty, without bothering to write a +terminal program, you can tell the kittens system to run the +``handle_result()`` function without first running the ``main()`` function. + +For example, here is a kitten that "zooms/unzooms" the current terminal window +by switching to the stack layout or back to the previous layout. + +Create a file in the kitty config folder, :file:`~/.config/kitty/zoom_toggle.py` + +.. code-block:: py + + def main(args): + pass + + def handle_result(args, answer, target_window_id, boss): + tab = boss.active_tab + if tab is not None: + if tab.current_layout.name == 'stack': + tab.last_used_layout() + else: + tab.goto_layout('stack') + + handle_result.no_ui = True + + +Now in kitty.conf add:: + + map f11 kitten zoom_toggle.py + +Pressing :kbd:`F11` will now act as a zoom toggle function. You can get even +more fancy, switching the kitty OS window to fullscreen as well as changing the +layout, by simply adding the line:: + + boss.toggle_fullscreen() + + +to the handle_result() function, above. diff --git a/kittens/runner.py b/kittens/runner.py index 867a2d2f5..0176718cc 100644 --- a/kittens/runner.py +++ b/kittens/runner.py @@ -46,6 +46,7 @@ def create_kitten_handler(kitten, orig_args): m = import_kitten_main_module(config_dir, kitten) ans = partial(m['end'], [kitten] + orig_args) ans.type_of_input = getattr(m['end'], 'type_of_input', None) + ans.no_ui = getattr(m['end'], 'no_ui', False) return ans diff --git a/kitty/boss.py b/kitty/boss.py index 091be2c4a..891c150c4 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -642,17 +642,20 @@ class Boss: return output def _run_kitten(self, kitten, args=(), input_data=None, window=None): + orig_args, args = list(args), list(args) + from kittens.runner import create_kitten_handler + end_kitten = create_kitten_handler(kitten, orig_args) if window is None: w = self.active_window tab = self.active_tab else: w = window tab = w.tabref() + if end_kitten.no_ui: + end_kitten(None, getattr(w, 'id', None), self) + return if w is not None and tab is not None and w.overlay_for is None: - orig_args, args = list(args), list(args) - from kittens.runner import create_kitten_handler - end_kitten = create_kitten_handler(kitten, orig_args) args[0:0] = [config_dir, kitten] if input_data is None: type_of_input = end_kitten.type_of_input