mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-22 16:28:19 +02:00
feat: new option --hold-after-ssh to allow spawning a shell after a kitten ssh disconnection
new option to the launch command, the new shell will be in the directory that launched kitten ssh
This commit is contained in:
@@ -221,6 +221,7 @@ class Child:
|
|||||||
hold: bool = False,
|
hold: bool = False,
|
||||||
pass_fds: tuple[int, ...] = (),
|
pass_fds: tuple[int, ...] = (),
|
||||||
remote_control_fd: int = -1,
|
remote_control_fd: int = -1,
|
||||||
|
hold_after_ssh: bool = False
|
||||||
):
|
):
|
||||||
self.is_clone_launch = is_clone_launch
|
self.is_clone_launch = is_clone_launch
|
||||||
self.id = next(child_counter)
|
self.id = next(child_counter)
|
||||||
@@ -230,7 +231,7 @@ class Child:
|
|||||||
self.remote_control_fd = remote_control_fd
|
self.remote_control_fd = remote_control_fd
|
||||||
if cwd_from:
|
if cwd_from:
|
||||||
try:
|
try:
|
||||||
cwd = cwd_from.modify_argv_for_launch_with_cwd(self.argv, env) or cwd
|
cwd = cwd_from.modify_argv_for_launch_with_cwd(self.argv, env, hold_after_ssh=hold_after_ssh) or cwd
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
log_error(f'Failed to read cwd of {cwd_from} with error: {err}')
|
log_error(f'Failed to read cwd of {cwd_from} with error: {err}')
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -140,6 +140,8 @@ by the shell (needs :ref:`shell_integration` to work). The special value
|
|||||||
oldest foreground process associated with the currently active window rather
|
oldest foreground process associated with the currently active window rather
|
||||||
than the newest foreground process. Finally, the special value :code:`root`
|
than the newest foreground process. Finally, the special value :code:`root`
|
||||||
refers to the process that was originally started when the window was created.
|
refers to the process that was originally started when the window was created.
|
||||||
|
When running :code:`kitten ssh`, using :option:`--hold-after-ssh` will cause a shell
|
||||||
|
in the working directory that started the :code:`kitten ssh` to be opened after disconnecting.
|
||||||
|
|
||||||
|
|
||||||
--env
|
--env
|
||||||
@@ -393,6 +395,11 @@ and :option:`--config <kitty +kitten panel --config>`. Can be specified multiple
|
|||||||
For example, to create a desktop panel at the bottom of the screen two lines high::
|
For example, to create a desktop panel at the bottom of the screen two lines high::
|
||||||
|
|
||||||
launch --type os-panel --os-panel lines=2 --os-panel edge=bottom sh -c "echo; echo; echo hello; sleep 5s"
|
launch --type os-panel --os-panel lines=2 --os-panel edge=bottom sh -c "echo; echo; echo hello; sleep 5s"
|
||||||
|
|
||||||
|
|
||||||
|
--hold-after-ssh
|
||||||
|
type=bool-set
|
||||||
|
When using :option:`--cwd=current` from a kitten ssh session, after disconnecting from the session on the new window, a shell will spawn.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@@ -536,6 +543,7 @@ class LaunchKwds(TypedDict):
|
|||||||
stdin: bytes | None
|
stdin: bytes | None
|
||||||
hold: bool
|
hold: bool
|
||||||
bias: float | None
|
bias: float | None
|
||||||
|
hold_after_ssh: bool
|
||||||
|
|
||||||
|
|
||||||
def apply_colors(window: Window, spec: Sequence[str]) -> None:
|
def apply_colors(window: Window, spec: Sequence[str]) -> None:
|
||||||
@@ -636,6 +644,7 @@ def _launch(
|
|||||||
'stdin': None,
|
'stdin': None,
|
||||||
'hold': False,
|
'hold': False,
|
||||||
'bias': None,
|
'bias': None,
|
||||||
|
'hold_after_ssh': False
|
||||||
}
|
}
|
||||||
spacing = {}
|
spacing = {}
|
||||||
if opts.spacing:
|
if opts.spacing:
|
||||||
@@ -658,6 +667,11 @@ def _launch(
|
|||||||
kw['cwd_from'] = CwdRequest(source_window, CwdRequestType.root)
|
kw['cwd_from'] = CwdRequest(source_window, CwdRequestType.root)
|
||||||
else:
|
else:
|
||||||
kw['cwd'] = opts.cwd
|
kw['cwd'] = opts.cwd
|
||||||
|
if opts.hold_after_ssh:
|
||||||
|
if opts.cwd != 'current':
|
||||||
|
raise ValueError("--hold_after_ssh can only be supplied if --cwd=current is also supplied")
|
||||||
|
kw['hold_after_ssh'] = True
|
||||||
|
|
||||||
if opts.location != 'default':
|
if opts.location != 'default':
|
||||||
kw['location'] = opts.location
|
kw['location'] = opts.location
|
||||||
if opts.copy_colors and source_window:
|
if opts.copy_colors and source_window:
|
||||||
@@ -804,7 +818,7 @@ def clone_safe_opts() -> frozenset[str]:
|
|||||||
return frozenset((
|
return frozenset((
|
||||||
'window_title', 'tab_title', 'type', 'keep_focus', 'cwd', 'env', 'var', 'hold',
|
'window_title', 'tab_title', 'type', 'keep_focus', 'cwd', 'env', 'var', 'hold',
|
||||||
'location', 'os_window_class', 'os_window_name', 'os_window_title', 'os_window_state',
|
'location', 'os_window_class', 'os_window_name', 'os_window_title', 'os_window_state',
|
||||||
'logo', 'logo_position', 'logo_alpha', 'color', 'spacing', 'next_to',
|
'logo', 'logo_position', 'logo_alpha', 'color', 'spacing', 'next_to', 'hold_after_ssh'
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ class Launch(RemoteCommand):
|
|||||||
watcher/list.str: list of paths to watcher files
|
watcher/list.str: list of paths to watcher files
|
||||||
bias/float: The bias with which to create the new window in the current layout
|
bias/float: The bias with which to create the new window in the current layout
|
||||||
wait_for_child_to_exit/bool: Boolean indicating whether to wait and return child exit code
|
wait_for_child_to_exit/bool: Boolean indicating whether to wait and return child exit code
|
||||||
|
hold_after_ssh/bool: Boolean indicating whether to spawn a shell after exiting a kitten ssh opened by this launch, requires --cwd=current to also be supplied
|
||||||
'''
|
'''
|
||||||
|
|
||||||
short_desc = 'Run an arbitrary process in a new window/tab'
|
short_desc = 'Run an arbitrary process in a new window/tab'
|
||||||
|
|||||||
@@ -480,6 +480,7 @@ class Tab: # {{{
|
|||||||
hold: bool = False,
|
hold: bool = False,
|
||||||
pass_fds: tuple[int, ...] = (),
|
pass_fds: tuple[int, ...] = (),
|
||||||
remote_control_fd: int = -1,
|
remote_control_fd: int = -1,
|
||||||
|
hold_after_ssh: bool = False
|
||||||
) -> Child:
|
) -> Child:
|
||||||
check_for_suitability = True
|
check_for_suitability = True
|
||||||
if cmd is None:
|
if cmd is None:
|
||||||
@@ -529,7 +530,7 @@ class Tab: # {{{
|
|||||||
fenv['WINDOWID'] = str(pwid)
|
fenv['WINDOWID'] = str(pwid)
|
||||||
ans = Child(
|
ans = Child(
|
||||||
cmd, cwd or self.cwd, stdin, fenv, cwd_from, is_clone_launch=is_clone_launch,
|
cmd, cwd or self.cwd, stdin, fenv, cwd_from, is_clone_launch=is_clone_launch,
|
||||||
add_listen_on_env_var=add_listen_on_env_var, hold=hold, pass_fds=pass_fds, remote_control_fd=remote_control_fd)
|
add_listen_on_env_var=add_listen_on_env_var, hold=hold, pass_fds=pass_fds, remote_control_fd=remote_control_fd, hold_after_ssh=hold_after_ssh)
|
||||||
ans.fork()
|
ans.fork()
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@@ -568,11 +569,12 @@ class Tab: # {{{
|
|||||||
pass_fds: tuple[int, ...] = (),
|
pass_fds: tuple[int, ...] = (),
|
||||||
remote_control_fd: int = -1,
|
remote_control_fd: int = -1,
|
||||||
next_to: Window | None = None,
|
next_to: Window | None = None,
|
||||||
|
hold_after_ssh: bool = False
|
||||||
) -> Window:
|
) -> Window:
|
||||||
child = self.launch_child(
|
child = self.launch_child(
|
||||||
use_shell=use_shell, cmd=cmd, stdin=stdin, cwd_from=cwd_from, cwd=cwd, env=env,
|
use_shell=use_shell, cmd=cmd, stdin=stdin, cwd_from=cwd_from, cwd=cwd, env=env,
|
||||||
is_clone_launch=is_clone_launch, add_listen_on_env_var=False if allow_remote_control and remote_control_passwords else True,
|
is_clone_launch=is_clone_launch, add_listen_on_env_var=False if allow_remote_control and remote_control_passwords else True,
|
||||||
hold=hold, pass_fds=pass_fds, remote_control_fd=remote_control_fd,
|
hold=hold, pass_fds=pass_fds, remote_control_fd=remote_control_fd, hold_after_ssh=hold_after_ssh
|
||||||
)
|
)
|
||||||
window = Window(
|
window = Window(
|
||||||
self, child, self.args, override_title=override_title,
|
self, child, self.args, override_title=override_title,
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ class CwdRequest:
|
|||||||
return window.get_cwd_of_root_child() or ''
|
return window.get_cwd_of_root_child() or ''
|
||||||
return window.get_cwd_of_child(oldest=self.request_type is CwdRequestType.oldest) or ''
|
return window.get_cwd_of_child(oldest=self.request_type is CwdRequestType.oldest) or ''
|
||||||
|
|
||||||
def modify_argv_for_launch_with_cwd(self, argv: list[str], env: dict[str, str] | None=None) -> str:
|
def modify_argv_for_launch_with_cwd(self, argv: list[str], env: dict[str, str] | None=None, hold_after_ssh: bool = False) -> str:
|
||||||
window = self.window
|
window = self.window
|
||||||
if not window:
|
if not window:
|
||||||
return ''
|
return ''
|
||||||
@@ -166,9 +166,13 @@ class CwdRequest:
|
|||||||
run_shell = argv[0] == resolved_shell(get_options())[0]
|
run_shell = argv[0] == resolved_shell(get_options())[0]
|
||||||
server_args = [] if run_shell else list(argv)
|
server_args = [] if run_shell else list(argv)
|
||||||
from kittens.ssh.utils import set_cwd_in_cmdline, set_env_in_cmdline, set_server_args_in_cmdline
|
from kittens.ssh.utils import set_cwd_in_cmdline, set_env_in_cmdline, set_server_args_in_cmdline
|
||||||
argv[:] = ssh_kitten_cmdline
|
if ssh_kitten_cmdline and ssh_kitten_cmdline[0] == 'kitten':
|
||||||
if argv and argv[0] == 'kitten':
|
if hold_after_ssh:
|
||||||
argv[0] = kitten_exe()
|
argv[:] = [kitten_exe(), "run-shell", kitten_exe()] +ssh_kitten_cmdline[1:]
|
||||||
|
else:
|
||||||
|
argv[:] = [kitten_exe()]+ssh_kitten_cmdline[1:]
|
||||||
|
else:
|
||||||
|
argv[:] = ssh_kitten_cmdline
|
||||||
set_cwd_in_cmdline(reported_cwd, argv)
|
set_cwd_in_cmdline(reported_cwd, argv)
|
||||||
set_server_args_in_cmdline(server_args, argv, allocate_tty=not run_shell)
|
set_server_args_in_cmdline(server_args, argv, allocate_tty=not run_shell)
|
||||||
if env is not None:
|
if env is not None:
|
||||||
|
|||||||
Reference in New Issue
Block a user