diff --git a/docs/changelog.rst b/docs/changelog.rst index 1352441e2..dcb35c01f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -13,6 +13,10 @@ To update |kitty|, :doc:`follow the instructions `. - Add entries to the terminfo file for some user capabilities that are shared with XTerm (:pull:`3193`) +- The launch command now does more sophisticated resolving of executables to + run. The system-wide PATH is used first, then system specific default paths, + and finally the PATH inside the shell. + 0.19.3 [2020-12-19] ------------------- diff --git a/docs/launch.rst b/docs/launch.rst index fb848ec9a..f03717b25 100644 --- a/docs/launch.rst +++ b/docs/launch.rst @@ -93,6 +93,16 @@ in the window and ``window.id`` is the internal kitty ``id`` of the window. +Finding executables +----------------------- + +When you specify a command to run as just a name rather than an absolute path, +it is searched for in the system-wide ``PATH`` environment variable. Note that +this **may not** be the value of ``PATH`` inside a shell, as shell startup scripts +often change the value of this variable. If it is not found there, then a +system specific list of default paths is searched. If it is still not found, +then your shell is run and the value of ``PATH`` inside the shell is used. + Syntax reference ------------------ diff --git a/kitty/launch.py b/kitty/launch.py index a4edfca3d..ecf287724 100644 --- a/kitty/launch.py +++ b/kitty/launch.py @@ -8,12 +8,12 @@ from typing import Any, Dict, List, Optional, Sequence, Tuple from .boss import Boss from .child import Child -from .cli import parse_args, WATCHER_DEFINITION +from .cli import WATCHER_DEFINITION, parse_args from .cli_stub import LaunchCLIOptions from .constants import resolve_custom_file from .fast_data_types import set_clipboard_string from .tabs import Tab -from .utils import set_primary_selection +from .utils import find_exe, set_primary_selection, read_shell_environment from .window import Watchers, Window try: @@ -274,6 +274,14 @@ def launch(boss: Boss, opts: LaunchCLIOptions, args: List[str], target_tab: Opti elif x == '@active-kitty-window-id': x = str(active.id) final_cmd.append(x) + exe = find_exe(final_cmd[0]) + if not exe: + env = read_shell_environment(boss.opts) + if 'PATH' in env: + import shutil + exe = shutil.which(final_cmd[0], path=env['PATH']) + if exe: + final_cmd[0] = exe kw['cmd'] = final_cmd if opts.type == 'overlay' and active: kw['overlay_for'] = active.id