mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-05-13 16:37:27 +00:00
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 @@ 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 .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 @@ class 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] = (),
|
||||
):
|
||||
self.is_clone_launch = is_clone_launch
|
||||
self.id = next(child_counter)
|
||||
|
|
@ -247,12 +248,13 @@ class Child:
|
|||
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 @@ class Child:
|
|||
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 @@ class Child:
|
|||
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 @@ class Child:
|
|||
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 .fast_data_types import add_timer, get_boss, get_options, get_os_window_tit
|
|||
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 @@ class Tab: # {{{
|
|||
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 @@ class Tab: # {{{
|
|||
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 @@ class Tab: # {{{
|
|||
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 @@ class Tab: # {{{
|
|||
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…
Add table
Add a link
Reference in a new issue