From 18a1402ae25704b93bbc3058bedc4afb50540f09 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 13 Nov 2019 15:00:13 +0530 Subject: [PATCH] Remote control interface for launch --- kitty/cmds.py | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/kitty/cmds.py b/kitty/cmds.py index deda13e7f..b82426450 100644 --- a/kitty/cmds.py +++ b/kitty/cmds.py @@ -7,10 +7,16 @@ import sys from contextlib import suppress -from .cli import parse_args, parse_option_spec, get_defaults_from_seq +from .cli import ( + Namespace, get_defaults_from_seq, parse_args, parse_option_spec +) from .config import parse_config, parse_send_text_bytes from .constants import appname from .fast_data_types import focus_os_window +from .launch import ( + launch as do_launch, options_spec as launch_options_spec, + parse_launch_args +) from .tabs import SpecialWindow from .utils import natsort_ints @@ -769,6 +775,76 @@ def new_window(boss, window, payload): # }}} +# launch {{{ +@cmd( + 'Run an arbitrary process in a new window/tab', + ' Prints out the id of the newly opened window. Any command line arguments' + ' are assumed to be the command line used to run in the new window, if none' + ' are provided, the default shell is run. For example:\n' + ':italic:`kitty @ launch --title Email mutt`', + options_spec=MATCH_TAB_OPTION + '\n\n' + '''\ +--no-response +type=bool-set +Do not print out the id of the newly created window. + + +--self +type=bool-set +If specified the tab containing the window this command is run in is used +instead of the active tab + ''' + '\n\n' + launch_options_spec(), + argspec='[CMD ...]' +) +def cmd_launch(global_opts, opts, args): + ''' + args+: The command line to run in the new window, as a list, use an empty list to run the default shell + match: The tab to open the new window in + window_title: Title for the new window + cwd: Working directory for the new window + env: List of environment varibles of the form NAME=VALUE + tab_title: Title for the new tab + type: The type of window to open + keep_focus: Boolean indicating whether the current window should retain focus or not + copy_colors: Boolean indicating whether to copy the colors from the current window + copy_cmdline: Boolean indicating whether to copy the cmdline from the current window + copy_env: Boolean indicating whether to copy the environ from the current window + location: Where in the tab to open the new window + allow_remote_control: Boolean indicating whether to allow remote control from the new window + stdin_source: Where to get stdin for thew process from + stdin_add_formatting: Boolean indicating whether to add formatting codes to stdin + stdin_add_line_wrap_markers: Boolean indicating whether to add line wrap markers to stdin + no_response: Boolean indicating whether to send back the window id + ''' + if opts.no_response: + global_opts.no_command_response = True + ans = {'args': args or []} + for attr, val in opts.__dict__.items(): + ans[attr] = val + return ans + + +def launch(boss, window, payload): + pg = cmd_launch.payload_get + default_opts = parse_launch_args()[0] + opts = {} + for key, default_value in default_opts.__dict__.items(): + opts[key] = payload.get(key, default_value) + opts = Namespace(opts) + match = pg(payload, 'match') + if match: + tabs = tuple(boss.match_tabs(match)) + if not tabs: + raise MatchError(match, 'tabs') + else: + tabs = [boss.active_tab] + if pg(payload, 'self') and window and window.tabref(): + tabs = [window.tabref()] + tab = tabs[0] + w = do_launch(boss, opts, pg(payload, 'args') or None, target_tab=tab) + return None if pg(payload, 'no_response') else str(w.id) +# }}} + + # focus_window {{{ @cmd( 'Focus the specified window',