Move implementation of --hold into Child

DRYer. Also fixed use of --hold with launch --cwd=current
This commit is contained in:
Kovid Goyal 2024-01-06 13:14:48 +05:30
parent 1e249035c7
commit e656a75d5e
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 26 additions and 20 deletions

View File

@ -11,7 +11,7 @@ import kitty.fast_data_types as fast_data_types
from .constants import handled_signals, is_freebsd, is_macos, kitten_exe, kitty_base_dir, shell_path, terminfo_dir from .constants import handled_signals, is_freebsd, is_macos, kitten_exe, kitty_base_dir, shell_path, terminfo_dir
from .types import run_once from .types import run_once
from .utils import log_error, which from .utils import cmdline_for_hold, log_error, which
try: try:
from typing import TypedDict from typing import TypedDict
@ -200,6 +200,7 @@ class Child:
cwd_from: Optional['CwdRequest'] = None, cwd_from: Optional['CwdRequest'] = None,
is_clone_launch: str = '', is_clone_launch: str = '',
add_listen_on_env_var: bool = True, add_listen_on_env_var: bool = True,
hold: bool = False,
): ):
self.is_clone_launch = is_clone_launch self.is_clone_launch = is_clone_launch
self.add_listen_on_env_var = add_listen_on_env_var self.add_listen_on_env_var = add_listen_on_env_var
@ -217,6 +218,7 @@ class Child:
self.final_env:Dict[str, str] = {} self.final_env:Dict[str, str] = {}
self.is_default_shell = bool(self.argv and self.argv[0] == shell_path) self.is_default_shell = bool(self.argv and self.argv[0] == shell_path)
self.should_run_via_run_shell_kitten = is_macos and self.is_default_shell self.should_run_via_run_shell_kitten = is_macos and self.is_default_shell
self.hold = hold
def get_final_env(self) -> Dict[str, str]: def get_final_env(self) -> Dict[str, str]:
from kitty.options.utils import DELETE_ENV_VAR from kitty.options.utils import DELETE_ENV_VAR
@ -309,11 +311,14 @@ class Child:
argv.append('--cwd=' + cwd) argv.append('--cwd=' + cwd)
cwd = os.path.expanduser('~') cwd = os.path.expanduser('~')
argv = ['/usr/bin/login', '-f', '-l', '-p', user] + argv argv = ['/usr/bin/login', '-f', '-l', '-p', user] + argv
self.final_exe = which(argv[0]) or argv[0] self.final_exe = final_exe = which(argv[0]) or argv[0]
self.final_argv0 = argv[0] self.final_argv0 = argv[0]
if self.hold:
argv = cmdline_for_hold(argv)
final_exe = argv[0]
env = tuple(f'{k}={v}' for k, v in self.final_env.items()) env = tuple(f'{k}={v}' for k, v in self.final_env.items())
pid = fast_data_types.spawn( pid = fast_data_types.spawn(
self.final_exe, cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd, final_exe, cwd, tuple(argv), env, master, slave, stdin_read_fd, stdin_write_fd,
ready_read_fd, ready_write_fd, tuple(handled_signals), kitten_exe(), opts.forward_stdio) ready_read_fd, ready_write_fd, tuple(handled_signals), kitten_exe(), opts.forward_stdio)
os.close(slave) os.close(slave)
self.pid = pid self.pid = pid

View File

@ -16,7 +16,7 @@ from .fast_data_types import add_timer, get_boss, get_options, get_os_window_tit
from .options.utils import env as parse_env from .options.utils import env as parse_env
from .tabs import Tab, TabManager from .tabs import Tab, TabManager
from .types import OverlayType, run_once from .types import OverlayType, run_once
from .utils import cmdline_for_hold, get_editor, log_error, resolve_custom_file, resolved_shell, which from .utils import get_editor, log_error, resolve_custom_file, which
from .window import CwdRequest, CwdRequestType, Watchers, Window from .window import CwdRequest, CwdRequestType, Watchers, Window
try: try:
@ -423,6 +423,7 @@ class LaunchKwds(TypedDict):
cmd: Optional[List[str]] cmd: Optional[List[str]]
overlay_for: Optional[int] overlay_for: Optional[int]
stdin: Optional[bytes] stdin: Optional[bytes]
hold: bool
def apply_colors(window: Window, spec: Sequence[str]) -> None: def apply_colors(window: Window, spec: Sequence[str]) -> None:
@ -504,7 +505,8 @@ def _launch(
'marker': opts.marker or None, 'marker': opts.marker or None,
'cmd': None, 'cmd': None,
'overlay_for': None, 'overlay_for': None,
'stdin': None 'stdin': None,
'hold': False,
} }
spacing = {} spacing = {}
if opts.spacing: if opts.spacing:
@ -607,11 +609,7 @@ def _launch(
else: else:
set_primary_selection(stdin) set_primary_selection(stdin)
else: else:
if opts.hold: kw['hold'] = opts.hold
cmd = kw['cmd'] or resolved_shell()
if not os.path.isabs(cmd[0]):
cmd[0] = which(cmd[0]) or cmd[0]
kw['cmd'] = cmdline_for_hold(cmd)
if force_target_tab: if force_target_tab:
tab = target_tab tab = target_tab
else: else:

View File

@ -14,7 +14,7 @@ from .options.types import Options
from .options.utils import resize_window, to_layout_names, window_size from .options.utils import resize_window, to_layout_names, window_size
from .os_window_size import WindowSize, WindowSizeData, WindowSizes from .os_window_size import WindowSize, WindowSizeData, WindowSizes
from .typing import SpecialWindowInstance from .typing import SpecialWindowInstance
from .utils import cmdline_for_hold, expandvars, log_error, resolve_custom_file, resolved_shell, shlex_split, which from .utils import expandvars, log_error, resolve_custom_file, resolved_shell, shlex_split
if TYPE_CHECKING: if TYPE_CHECKING:
from .launch import LaunchSpec from .launch import LaunchSpec
@ -237,11 +237,8 @@ def create_sessions(
ans.tabs[-1].layout = current_layout ans.tabs[-1].layout = current_layout
if special_window is None: if special_window is None:
cmd = args.args if args and args.args else resolved_shell(opts) cmd = args.args if args and args.args else resolved_shell(opts)
if args and args.hold:
cmd[0] = which(cmd[0]) or cmd[0]
cmd = cmdline_for_hold(cmd)
from kitty.tabs import SpecialWindow from kitty.tabs import SpecialWindow
cwd: Optional[str] = args.directory if respect_cwd and args else None cwd: Optional[str] = args.directory if respect_cwd and args else None
special_window = SpecialWindow(cmd, cwd_from=cwd_from, cwd=cwd) special_window = SpecialWindow(cmd, cwd_from=cwd_from, cwd=cwd, hold=bool(args and args.hold))
ans.add_special_window(special_window) ans.add_special_window(special_window)
yield ans yield ans

View File

@ -95,6 +95,7 @@ class SpecialWindowInstance(NamedTuple):
env: Optional[Dict[str, str]] env: Optional[Dict[str, str]]
watchers: Optional[Watchers] watchers: Optional[Watchers]
overlay_behind: bool overlay_behind: bool
hold: bool
def SpecialWindow( def SpecialWindow(
@ -106,9 +107,10 @@ def SpecialWindow(
overlay_for: Optional[int] = None, overlay_for: Optional[int] = None,
env: Optional[Dict[str, str]] = None, env: Optional[Dict[str, str]] = None,
watchers: Optional[Watchers] = None, watchers: Optional[Watchers] = None,
overlay_behind: bool = False overlay_behind: bool = False,
hold: bool = False,
) -> SpecialWindowInstance: ) -> SpecialWindowInstance:
return SpecialWindowInstance(cmd, stdin, override_title, cwd_from, cwd, overlay_for, env, watchers, overlay_behind) return SpecialWindowInstance(cmd, stdin, override_title, cwd_from, cwd, overlay_for, env, watchers, overlay_behind, hold)
def add_active_id_to_history(items: Deque[int], item_id: int, maxlen: int = 64) -> None: def add_active_id_to_history(items: Deque[int], item_id: int, maxlen: int = 64) -> None:
@ -440,6 +442,7 @@ class Tab: # {{{
env: Optional[Dict[str, str]] = None, env: Optional[Dict[str, str]] = None,
is_clone_launch: str = '', is_clone_launch: str = '',
add_listen_on_env_var: bool = True, add_listen_on_env_var: bool = True,
hold: bool = False,
) -> Child: ) -> Child:
check_for_suitability = True check_for_suitability = True
if cmd is None: if cmd is None:
@ -487,7 +490,7 @@ class Tab: # {{{
pwid = platform_window_id(self.os_window_id) pwid = platform_window_id(self.os_window_id)
if pwid is not None: if pwid is not None:
fenv['WINDOWID'] = str(pwid) fenv['WINDOWID'] = str(pwid)
ans = Child(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) ans = Child(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)
ans.fork() ans.fork()
return ans return ans
@ -514,10 +517,12 @@ class Tab: # {{{
overlay_behind: bool = False, overlay_behind: bool = False,
is_clone_launch: str = '', is_clone_launch: str = '',
remote_control_passwords: Optional[Dict[str, Sequence[str]]] = None, remote_control_passwords: Optional[Dict[str, Sequence[str]]] = None,
hold: 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,
) )
window = Window( window = Window(
self, child, self.args, override_title=override_title, self, child, self.args, override_title=override_title,
@ -547,7 +552,8 @@ class Tab: # {{{
override_title=special_window.override_title, override_title=special_window.override_title,
cwd_from=special_window.cwd_from, cwd=special_window.cwd, overlay_for=special_window.overlay_for, cwd_from=special_window.cwd_from, cwd=special_window.cwd, overlay_for=special_window.overlay_for,
env=special_window.env, location=location, copy_colors_from=copy_colors_from, env=special_window.env, location=location, copy_colors_from=copy_colors_from,
allow_remote_control=allow_remote_control, watchers=special_window.watchers, overlay_behind=special_window.overlay_behind allow_remote_control=allow_remote_control, watchers=special_window.watchers, overlay_behind=special_window.overlay_behind,
hold=special_window.hold,
) )
@ac('win', 'Close all windows in the tab other than the currently active window') @ac('win', 'Close all windows in the tab other than the currently active window')