diff --git a/docs/changelog.rst b/docs/changelog.rst index d883902c0..511a5a729 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -46,7 +46,7 @@ Detailed list of changes 0.31.0 [future] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Allow :ref:`easily running arbitrarily complex remote control scripts ` without needing to turn on remote control (:iss:`6712`) +- Allow :ac:`easily running arbitrarily complex remote control scripts ` without needing to turn on remote control (:iss:`6712`) - A new option :opt:`menu_map` that allows adding entries to the global menubar on macOS (:disc:`6680`) diff --git a/docs/remote-control.rst b/docs/remote-control.rst index a6896d0bf..469aef3aa 100644 --- a/docs/remote-control.rst +++ b/docs/remote-control.rst @@ -283,10 +283,14 @@ are matched:: If you wish to run a more complex script, you can use:: - map f1 launch --type=background --allow-remote-control /path/to/myscript + map f1 remote_control_script /path/to/myscript -In this script you can use the ``kitten @`` command to run as many remote -control commands as you like. +In this script you can use ``kitten @`` to run as many remote +control commands as you like and process their output. +:ac:`remote_control_script` is really just an alias for the +:ac:`launch` command with ``--type=background --allow-remote-control``. +For more advanced usage, including fine grained permissions, setting +env vars, etc. see the docs for the :doc:`launch ` command. .. 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 reuse the diff --git a/kitty/boss.py b/kitty/boss.py index 472c8c0a4..7b3bea76a 100644 --- a/kitty/boss.py +++ b/kitty/boss.py @@ -722,7 +722,7 @@ def _execute_remote_command( return response @ac('misc', ''' - Run a remote control command + Run a remote control command without needing to allow remote control For example:: @@ -737,6 +737,22 @@ def remote_control(self, *args: str) -> None: import shlex self.show_error(_('remote_control mapping failed'), shlex.join(args) + '\n' + str(e)) + @ac('misc', ''' + Run a remote control script without needing to allow remote control + + For example:: + + map f1 remote_control_script arg1 arg2 ... + + See :ref:`rc_mapping` for details. + ''') + def remote_control_script(self, path: str, *args: str) -> None: + path = which(path) or path + if not os.access(path, os.X_OK): + self.show_error('Remote control script not executable', f'The script {path} is not executable check its permissions') + return + self.run_background_process([path] + list(args), allow_remote_control=True) + def call_remote_control(self, self_window: Optional[Window], args: Tuple[str, ...]) -> 'ResponseType': from .rc.base import PayloadGetter, command_for_name, parse_subcommand_cli from .remote_control import parse_rc_args diff --git a/kitty/options/utils.py b/kitty/options/utils.py index 4042c140a..8340babb8 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -287,6 +287,14 @@ def remote_control(func: str, rest: str) -> FuncArgsType: return func, args +@func_with_args('remote_control_script') +def remote_control_script(func: str, rest: str) -> FuncArgsType: + func, args = shlex_parse(func, rest) + if len(args) < 1: + log_error('Too few arguments to remote_control_script function') + return func, args + + @func_with_args('nth_os_window', 'nth_window', 'scroll_to_prompt', 'visual_window_select_action_trigger', 'next_layout') def single_integer_arg(func: str, rest: str) -> FuncArgsType: try: