Dont set the EDITOR env var in child processes

It isnt really needed, since the various kittens dont rely on it
anymore, instead calling get_editor() to get the path to the editor.
Has the nice side-effect of not needing to run the shell at startup
to read its environment. Now the shell is only run if the user calls
the edit config file kitten. Fixes #3426
This commit is contained in:
Kovid Goyal 2021-03-29 11:56:48 +05:30
parent 4edbe0ea4f
commit 1e6fe7785a
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 62 additions and 50 deletions

View File

@ -866,7 +866,7 @@ class Boss:
confpath = prepare_config_file_for_editing() confpath = prepare_config_file_for_editing()
# On macOS vim fails to handle SIGWINCH if it occurs early, so add a # On macOS vim fails to handle SIGWINCH if it occurs early, so add a
# small delay. # small delay.
cmd = [kitty_exe(), '+runpy', 'import os, sys, time; time.sleep(0.05); os.execvp(sys.argv[1], sys.argv[1:])'] + get_editor() + [confpath] cmd = [kitty_exe(), '+runpy', 'import os, sys, time; time.sleep(0.05); os.execvp(sys.argv[1], sys.argv[1:])'] + get_editor(self.opts) + [confpath]
self.new_os_window(*cmd) self.new_os_window(*cmd)
def get_output(self, source_window: Window, num_lines: Optional[int] = 1) -> str: def get_output(self, source_window: Window, num_lines: Optional[int] = 1) -> str:

View File

@ -852,3 +852,10 @@ def create_opts(args: CLIOptions, debug_config: bool = False, accumulate_bad_lin
print('Running under:', green('Wayland' if is_wayland(opts) else 'X11')) print('Running under:', green('Wayland' if is_wayland(opts) else 'X11'))
compare_opts(opts) compare_opts(opts)
return opts return opts
def create_default_opts() -> OptionsStub:
from .config import load_config
config = tuple(resolve_config(SYSTEM_CONF, defconf, ()))
opts = load_config(*config)
return opts

View File

@ -7,7 +7,7 @@ import os
import shutil import shutil
import sys import sys
from contextlib import contextmanager, suppress from contextlib import contextmanager, suppress
from typing import Dict, Generator, List, Mapping, Optional, Sequence from typing import Dict, Generator, List, Optional, Sequence
from .borders import load_borders_program from .borders import load_borders_program
from .boss import Boss from .boss import Boss
@ -32,8 +32,8 @@ from .os_window_size import initial_window_size_func
from .session import get_os_window_sizing_data from .session import get_os_window_sizing_data
from .types import SingleKey from .types import SingleKey
from .utils import ( from .utils import (
detach, expandvars, find_exe, log_error, read_shell_environment, detach, expandvars, log_error, single_instance,
single_instance, startup_notification_handler, unix_socket_paths startup_notification_handler, unix_socket_paths
) )
from .window import load_shader_programs from .window import load_shader_programs
@ -225,39 +225,6 @@ def macos_cmdline(argv_args: List[str]) -> List[str]:
return ans 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
def patched(exe: str) -> str:
editor_cmd[0] = exe
return ' '.join(map(shlex.quote, editor_cmd))
if shell_env is os.environ:
q = find_exe(editor_exe)
if q:
return patched(q)
elif 'PATH' in shell_env:
import shlex
q = shutil.which(editor_exe, path=shell_env['PATH'])
if q:
return patched(q)
def get_editor_from_env(shell_env: Mapping[str, str]) -> Optional[str]:
for var in ('VISUAL', 'EDITOR'):
editor = shell_env.get(var)
if editor:
editor = resolve_editor_cmd(editor, shell_env)
if editor:
return editor
def expand_listen_on(listen_on: str, from_config_file: bool) -> str: def expand_listen_on(listen_on: str, from_config_file: bool) -> str:
listen_on = expandvars(listen_on) listen_on = expandvars(listen_on)
if '{kitty_pid}' not in listen_on and from_config_file: if '{kitty_pid}' not in listen_on and from_config_file:
@ -275,15 +242,6 @@ def expand_listen_on(listen_on: str, from_config_file: bool) -> str:
def setup_environment(opts: OptionsStub, cli_opts: CLIOptions) -> None: def setup_environment(opts: OptionsStub, cli_opts: CLIOptions) -> None:
if opts.editor == '.':
editor = get_editor_from_env(os.environ)
if not editor:
shell_env = read_shell_environment(opts)
editor = get_editor_from_env(shell_env)
if editor:
os.environ['EDITOR'] = editor
else:
os.environ['EDITOR'] = opts.editor
from_config_file = False from_config_file = False
if not cli_opts.listen_on and opts.listen_on.startswith('unix:'): if not cli_opts.listen_on and opts.listen_on.startswith('unix:'):
cli_opts.listen_on = opts.listen_on cli_opts.listen_on = opts.listen_on

View File

@ -462,12 +462,49 @@ def natsort_ints(iterable: Iterable[str]) -> List[str]:
return sorted(iterable, key=alphanum_key) return sorted(iterable, key=alphanum_key)
@run_once def resolve_editor_cmd(editor: str, shell_env: Mapping[str, str]) -> Optional[str]:
def get_editor() -> List[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
def patched(exe: str) -> str:
editor_cmd[0] = exe
return ' '.join(map(shlex.quote, editor_cmd))
if shell_env is os.environ:
q = find_exe(editor_exe)
if q:
return patched(q)
elif 'PATH' in shell_env:
import shutil
q = shutil.which(editor_exe, path=shell_env['PATH'])
if q:
return patched(q)
def get_editor_from_env(env: Mapping[str, str]) -> Optional[str]:
for var in ('VISUAL', 'EDITOR'):
editor = env.get(var)
if editor:
editor = resolve_editor_cmd(editor, env)
if editor:
return editor
def get_editor_from_env_vars(opts: Optional[Options] = None) -> List[str]:
import shlex import shlex
import shutil import shutil
for ans in (os.environ.get('VISUAL'), os.environ.get('EDITOR'), 'vim',
'nvim', 'vi', 'emacs', 'kak', 'micro', 'nano', 'vis'): editor = get_editor_from_env(os.environ)
if not editor:
shell_env = read_shell_environment(opts)
editor = get_editor_from_env(shell_env)
for ans in (editor, 'vim', 'nvim', 'vi', 'emacs', 'kak', 'micro', 'nano', 'vis'):
if ans and shutil.which(shlex.split(ans)[0]): if ans and shutil.which(shlex.split(ans)[0]):
break break
else: else:
@ -475,6 +512,16 @@ def get_editor() -> List[str]:
return shlex.split(ans) return shlex.split(ans)
def get_editor(opts: Optional[Options] = None) -> List[str]:
if opts is None:
from .cli import create_default_opts
opts = create_default_opts()
if opts.editor == '.':
return get_editor_from_env_vars()
import shlex
return shlex.split(opts.editor)
def is_path_in_temp_dir(path: str) -> bool: def is_path_in_temp_dir(path: str) -> bool:
if not path: if not path:
return False return False