From b5fa643c5dc78e458cb3124250ac41dad8d15ff4 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 24 Aug 2022 14:21:54 +0530 Subject: [PATCH] Allow ignoring failures when mapping remote control commands --- docs/remote-control.rst | 6 ++++++ kitty/boss.py | 23 +++++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/docs/remote-control.rst b/docs/remote-control.rst index 16410d51e..d6a2994e7 100644 --- a/docs/remote-control.rst +++ b/docs/remote-control.rst @@ -276,6 +276,12 @@ Then pressing the :kbd:`F1` key will set the active window margins to :code:`30`. The syntax for what follows :ac:`remote_control` is exactly the same as the syntax for what follows :code:`kitty @` above. +If you wish to ignore errors from the command, prefix the command with an +``!``. For example, the following will not return an error when no windows +are matched:: + + map f1 !focus-window --match XXXXXX + .. note:: You do not need :opt:`allow_remote_control` to use these mappings, as they are not actual remote programs, but are simply a way to resuse the remote control infrastructure via keybings. diff --git a/kitty/boss.py b/kitty/boss.py index cc433c955..8de82195f 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -578,8 +578,13 @@ class Boss: PayloadGetter, command_for_name, parse_subcommand_cli ) from .remote_control import parse_rc_args + aa = list(args) + silent = False + if aa and aa[0].startswith('!'): + aa[0] = aa[0][1:] + silent = True try: - global_opts, items = parse_rc_args(['@'] + list(args)) + global_opts, items = parse_rc_args(['@'] + aa) if not items: return None cmd = items[0] @@ -589,11 +594,17 @@ class Boss: except SystemExit as e: raise Exception(str(e)) from e import types - if isinstance(payload, types.GeneratorType): - for x in payload: - c.response_from_kitty(self, active_window, PayloadGetter(c, x if isinstance(x, dict) else {})) - return None - return c.response_from_kitty(self, active_window, PayloadGetter(c, payload if isinstance(payload, dict) else {})) + try: + if isinstance(payload, types.GeneratorType): + for x in payload: + c.response_from_kitty(self, active_window, PayloadGetter(c, x if isinstance(x, dict) else {})) + return None + return c.response_from_kitty(self, active_window, PayloadGetter(c, payload if isinstance(payload, dict) else {})) + except Exception as e: + if silent: + log_error(f'Failed to run remote_control mapping: {aa} with error: {e}') + return None + raise def peer_message_received(self, msg_bytes: bytes, peer_id: int) -> Union[bytes, bool, None]: cmd_prefix = b'\x1bP@kitty-cmd'