Implement running foreground process even on unknown shells
This is not as nice because the environment wont have been setup by the shell before running the process, but it's the best we can do for an unknown shell.
This commit is contained in:
parent
1460a69ae9
commit
8451ad44b5
3 changed files with 30 additions and 27 deletions
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
from .constants import handled_signals, is_freebsd, is_macos, kitten_exe, kitty_base_dir, shell_path, terminfo_dir
|
||||
from .types import run_once
|
||||
from .utils import cmdline_for_hold, log_error, which
|
||||
from .utils import cmdline_for_hold, log_error, resolved_shell, which
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .window import CwdRequest
|
||||
|
|
@ -229,7 +229,8 @@ def __init__(
|
|||
hold: bool = False,
|
||||
pass_fds: tuple[int, ...] = (),
|
||||
remote_control_fd: int = -1,
|
||||
hold_after_ssh: bool = False
|
||||
hold_after_ssh: bool = False,
|
||||
startup_command_via_shell_integration: Sequence[str] = (),
|
||||
):
|
||||
self.is_clone_launch = is_clone_launch
|
||||
self.id = next(child_counter)
|
||||
|
|
@ -247,12 +248,13 @@ def __init__(
|
|||
self.cwd = os.path.abspath(cwd)
|
||||
self.stdin = stdin
|
||||
self.env = env or {}
|
||||
self.startup_command_via_shell_integration = startup_command_via_shell_integration
|
||||
self.final_env:dict[str, str] = {}
|
||||
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.hold = hold
|
||||
|
||||
def get_final_env(self) -> dict[str, str]:
|
||||
def get_final_env(self) -> tuple[dict[str, str], bool]:
|
||||
from kitty.options.utils import DELETE_ENV_VAR
|
||||
env = default_env().copy()
|
||||
opts = fast_data_types.get_options()
|
||||
|
|
@ -294,7 +296,15 @@ def get_final_env(self) -> dict[str, str]:
|
|||
self.is_clone_launch = '1' # free memory
|
||||
else:
|
||||
env.pop('KITTY_IS_CLONE_LAUNCH', None)
|
||||
return env
|
||||
must_run_startup_command_via_kitten = False
|
||||
if self.startup_command_via_shell_integration:
|
||||
from .shell_integration import join
|
||||
scmd = self.argv or resolved_shell(fast_data_types.get_options())
|
||||
try:
|
||||
env['KITTY_SI_RUN_COMMAND_AT_STARTUP'] = join(scmd[0], self.startup_command_via_shell_integration)
|
||||
except Exception:
|
||||
must_run_startup_command_via_kitten = True # unknown shell
|
||||
return env, must_run_startup_command_via_kitten
|
||||
|
||||
def fork(self) -> int | None:
|
||||
if self.forked:
|
||||
|
|
@ -312,13 +322,13 @@ def fork(self) -> int | None:
|
|||
os.set_inheritable(stdin_read_fd, True)
|
||||
else:
|
||||
stdin_read_fd = stdin_write_fd = -1
|
||||
self.final_env = self.get_final_env()
|
||||
self.final_env, must_run_startup_command_via_kitten = self.get_final_env()
|
||||
argv = list(self.argv)
|
||||
cwd = self.cwd
|
||||
pass_fds = self.pass_fds
|
||||
if self.remote_control_fd > -1:
|
||||
pass_fds += self.remote_control_fd,
|
||||
if self.should_run_via_run_shell_kitten:
|
||||
if self.should_run_via_run_shell_kitten or must_run_startup_command_via_kitten:
|
||||
# bash will only source ~/.bash_profile if it detects it is a login
|
||||
# shell (see the invocation section of the bash man page), which it
|
||||
# does if argv[0] is prefixed by a hyphen see
|
||||
|
|
@ -338,6 +348,8 @@ def fork(self) -> int | None:
|
|||
if ksi == 'invalid':
|
||||
ksi = 'enabled'
|
||||
argv = [kitten_exe(), 'run-shell', '--shell', shlex.join(argv), '--shell-integration', ksi]
|
||||
if must_run_startup_command_via_kitten:
|
||||
argv.extend(self.startup_command_via_shell_integration)
|
||||
if is_macos and not pass_fds and not opts.forward_stdio:
|
||||
# In addition for getlogin() to work we need to run the shell
|
||||
# via the /usr/bin/login wrapper, sigh.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
from .options.utils import env as parse_env
|
||||
from .tabs import Tab, TabManager
|
||||
from .types import LayerShellConfig, OverlayType, run_once
|
||||
from .utils import 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
|
||||
|
||||
|
||||
|
|
@ -776,19 +776,9 @@ def _launch(
|
|||
tab = tab_for_window(boss, opts, target_tab, next_to)
|
||||
watchers = load_watch_modules(opts.watcher)
|
||||
with Window.set_ignore_focus_changes_for_new_windows(opts.keep_focus):
|
||||
startup_command_env_added = False
|
||||
if startup_command_via_shell_integration:
|
||||
from .shell_integration import join
|
||||
try:
|
||||
scmd = kw.get('cmd') or resolved_shell(get_options())
|
||||
env = env or {}
|
||||
env['KITTY_SI_RUN_COMMAND_AT_STARTUP'] = join(scmd[0], startup_command_via_shell_integration)
|
||||
startup_command_env_added = True
|
||||
except Exception:
|
||||
pass # shell is not a known shell
|
||||
|
||||
new_window: Window = tab.new_window(
|
||||
env=env or None, watchers=watchers or None, is_clone_launch=is_clone_launch, next_to=next_to, **kw)
|
||||
env=env or None, watchers=watchers or None, is_clone_launch=is_clone_launch, next_to=next_to,
|
||||
startup_command_via_shell_integration=startup_command_via_shell_integration, **kw)
|
||||
if child_death_callback is not None:
|
||||
boss.monitor_pid(new_window.child.pid or 0, child_death_callback)
|
||||
if new_window.creation_spec:
|
||||
|
|
@ -798,10 +788,6 @@ def _launch(
|
|||
new_window.creation_spec = new_window.creation_spec._replace(spacing=tuple(opts.spacing))
|
||||
if opts.color:
|
||||
new_window.creation_spec = new_window.creation_spec._replace(colors=tuple(opts.color))
|
||||
if startup_command_env_added and new_window.creation_spec.env:
|
||||
def is_not_scmd(x: tuple[str, str]) -> bool:
|
||||
return x[0] != 'KITTY_SI_RUN_COMMAND_AT_STARTUP'
|
||||
new_window.creation_spec = new_window.creation_spec._replace(env=tuple(filter(is_not_scmd, new_window.creation_spec.env)))
|
||||
if spacing:
|
||||
patch_window_edges(new_window, spacing)
|
||||
tab.relayout()
|
||||
|
|
|
|||
|
|
@ -534,7 +534,8 @@ def launch_child(
|
|||
hold: bool = False,
|
||||
pass_fds: tuple[int, ...] = (),
|
||||
remote_control_fd: int = -1,
|
||||
hold_after_ssh: bool = False
|
||||
hold_after_ssh: bool = False,
|
||||
startup_command_via_shell_integration: Sequence[str] = (),
|
||||
) -> Child:
|
||||
check_for_suitability = True
|
||||
if cmd is None:
|
||||
|
|
@ -584,7 +585,9 @@ def launch_child(
|
|||
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, hold=hold, pass_fds=pass_fds, remote_control_fd=remote_control_fd, hold_after_ssh=hold_after_ssh)
|
||||
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,
|
||||
startup_command_via_shell_integration=startup_command_via_shell_integration)
|
||||
ans.fork()
|
||||
return ans
|
||||
|
||||
|
|
@ -623,7 +626,8 @@ def new_window(
|
|||
pass_fds: tuple[int, ...] = (),
|
||||
remote_control_fd: int = -1,
|
||||
next_to: Window | None = None,
|
||||
hold_after_ssh: bool = False
|
||||
hold_after_ssh: bool = False,
|
||||
startup_command_via_shell_integration: Sequence[str] = (),
|
||||
) -> Window:
|
||||
cs = WindowCreationSpec(
|
||||
use_shell=use_shell, cmd=cmd, has_stdin=bool(stdin), override_title=override_title, cwd_from=cwd_from,
|
||||
|
|
@ -637,7 +641,8 @@ def new_window(
|
|||
child = self.launch_child(
|
||||
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,
|
||||
hold=hold, pass_fds=pass_fds, remote_control_fd=remote_control_fd, hold_after_ssh=hold_after_ssh
|
||||
hold=hold, pass_fds=pass_fds, remote_control_fd=remote_control_fd, hold_after_ssh=hold_after_ssh,
|
||||
startup_command_via_shell_integration=startup_command_via_shell_integration,
|
||||
)
|
||||
window = Window(
|
||||
self, child, self.args, override_title=override_title,
|
||||
|
|
|
|||
Loading…
Reference in a new issue