From 65361d56c40375185a93ade78f55e42335b68598 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 29 Dec 2020 11:33:42 +0530 Subject: [PATCH] Use find_exe() for resolving editor as well Avoids having to exec the shell in most cases --- kittens/tui/images.py | 18 +----------------- kitty/main.py | 40 ++++++++++++++++++++++++++++------------ kitty/utils.py | 14 ++++++++++++++ 3 files changed, 43 insertions(+), 29 deletions(-) diff --git a/kittens/tui/images.py b/kittens/tui/images.py index cf78b1363..651edb026 100644 --- a/kittens/tui/images.py +++ b/kittens/tui/images.py @@ -14,11 +14,10 @@ from typing import ( Union ) -from kitty.constants import is_macos from kitty.typing import ( CompletedProcess, GRT_a, GRT_d, GRT_f, GRT_m, GRT_o, GRT_t, HandlerType ) -from kitty.utils import ScreenSize, fit_image +from kitty.utils import ScreenSize, find_exe, fit_image from .operations import cursor @@ -76,21 +75,6 @@ def identify(path: str) -> ImageData: return ImageData(parts[0].lower(), int(parts[1]), int(parts[2]), mode) -def find_exe(name: str) -> Optional[str]: - import shutil - ans = shutil.which(name) - if ans is None: - # In case PATH is messed up - if is_macos: - from kitty.utils import system_paths_on_macos - paths = system_paths_on_macos() - else: - paths = ['/usr/local/bin', '/opt/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin'] - path = os.pathsep.join(paths) + os.pathsep + os.defpath - ans = shutil.which(name, path=path) - return ans - - def convert( path: str, m: ImageData, available_width: int, available_height: int, diff --git a/kitty/main.py b/kitty/main.py index d1ec294bf..1a0bc39c6 100644 --- a/kitty/main.py +++ b/kitty/main.py @@ -31,8 +31,8 @@ from .options_stub import Options as OptionsStub from .os_window_size import initial_window_size_func from .session import get_os_window_sizing_data from .utils import ( - detach, expandvars, log_error, read_shell_environment, single_instance, - startup_notification_handler, unix_socket_paths + detach, expandvars, find_exe, log_error, read_shell_environment, + single_instance, startup_notification_handler, unix_socket_paths ) from .window import load_shader_programs @@ -112,6 +112,7 @@ def get_new_os_window_trigger(opts: OptionsStub) -> Optional[Tuple[int, bool, in new_os_window_shortcuts.append(k) if new_os_window_shortcuts: from .fast_data_types import cocoa_set_new_window_trigger + # Reverse list so that later defined keyboard shortcuts take priority over earlier defined ones for candidate in reversed(new_os_window_shortcuts): if cocoa_set_new_window_trigger(candidate[0], candidate[2]): @@ -214,20 +215,35 @@ def macos_cmdline(argv_args: List[str]) -> List[str]: return ans +def resolve_editor_cmd(editor: str, shell_env: Mapping[str, str]) -> Optional[str]: + import shlex + editor_cmd = shlex.split(editor) + editor_exe = (editor_cmd or ('',))[0] + if editor_exe and os.path.isabs(editor_exe): + return editor + if not editor_exe: + return None + if shell_env is os.environ: + q = find_exe(editor_exe) + if q: + editor_cmd[0] = q + editor = ' '.join(map(shlex.quote, editor_cmd)) + return editor + return None + if 'PATH' in shell_env: + import shlex + q = shutil.which(editor_exe, path=shell_env['PATH']) + if q: + editor_cmd[0] = q + editor = ' '.join(map(shlex.quote, editor_cmd)) + return editor + + def get_editor_from_env(shell_env: Mapping[str, str]) -> Optional[str]: for var in ('VISUAL', 'EDITOR'): editor = shell_env.get(var) if editor: - if 'PATH' in shell_env: - import shlex - editor_cmd = shlex.split(editor) - if not os.path.isabs(editor_cmd[0]): - q = shutil.which(editor_cmd[0], path=shell_env['PATH']) - if q: - editor_cmd[0] = q - editor = ' '.join(map(shlex.quote, editor_cmd)) - else: - editor = None + editor = resolve_editor_cmd(editor, shell_env) if editor: return editor diff --git a/kitty/utils.py b/kitty/utils.py index 3155dec70..eaf86f09f 100644 --- a/kitty/utils.py +++ b/kitty/utils.py @@ -537,6 +537,20 @@ def system_paths_on_macos() -> List[str]: return entries +def find_exe(name: str) -> Optional[str]: + import shutil + ans = shutil.which(name) + if ans is None: + # In case PATH is messed up + if is_macos: + paths = system_paths_on_macos() + else: + paths = ['/usr/local/bin', '/opt/bin', '/usr/bin', '/bin', '/usr/sbin', '/sbin'] + path = os.pathsep.join(paths) + os.pathsep + os.defpath + ans = shutil.which(name, path=path) + return ans + + def read_shell_environment(opts: Optional[Options] = None) -> Dict[str, str]: ans: Optional[Dict[str, str]] = getattr(read_shell_environment, 'ans', None) if ans is None: