mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-09 13:45:26 +02:00
When resolving scrollback pager if it is not present in system PATH try using shell PATH
This commit is contained in:
@@ -10,7 +10,7 @@ from contextlib import contextmanager, suppress
|
||||
|
||||
from .borders import load_borders_program
|
||||
from .boss import Boss
|
||||
from .child import set_default_env, openpty, remove_blocking
|
||||
from .child import set_default_env
|
||||
from .cli import create_opts, parse_args
|
||||
from .config import cached_values_for, initial_window_size_func
|
||||
from .constants import (
|
||||
@@ -18,15 +18,15 @@ from .constants import (
|
||||
is_wayland, kitty_exe, logo_data_file
|
||||
)
|
||||
from .fast_data_types import (
|
||||
GLFW_IBEAM_CURSOR, create_os_window, free_font_data,
|
||||
glfw_init, glfw_terminate, load_png_data, set_custom_cursor,
|
||||
set_default_window_icon, set_options
|
||||
GLFW_IBEAM_CURSOR, create_os_window, free_font_data, glfw_init,
|
||||
glfw_terminate, load_png_data, set_custom_cursor, set_default_window_icon,
|
||||
set_options
|
||||
)
|
||||
from .fonts.box_drawing import set_scale
|
||||
from .fonts.render import set_font_family
|
||||
from .utils import (
|
||||
detach, log_error, single_instance, startup_notification_handler,
|
||||
unix_socket_paths
|
||||
detach, log_error, read_shell_environment, single_instance,
|
||||
startup_notification_handler, unix_socket_paths
|
||||
)
|
||||
from .window import load_shader_programs
|
||||
|
||||
@@ -200,55 +200,6 @@ def macos_cmdline(argv_args):
|
||||
return ans
|
||||
|
||||
|
||||
def read_shell_environment(opts=None):
|
||||
if not hasattr(read_shell_environment, 'ans'):
|
||||
ans = read_shell_environment.ans = {}
|
||||
import subprocess
|
||||
from .session import resolved_shell
|
||||
shell = resolved_shell(opts)
|
||||
master, slave = openpty()
|
||||
remove_blocking(master)
|
||||
try:
|
||||
p = subprocess.Popen(shell + ['-l', '-c', 'env'], stdout=slave, stdin=slave, stderr=slave, start_new_session=True, close_fds=True)
|
||||
except FileNotFoundError:
|
||||
log_error('Could not find shell to read environment')
|
||||
return ans
|
||||
with os.fdopen(master, 'rb') as stdout, os.fdopen(slave, 'wb'):
|
||||
raw = b''
|
||||
from subprocess import TimeoutExpired
|
||||
from time import monotonic
|
||||
start_time = monotonic()
|
||||
while monotonic() - start_time < 1.5:
|
||||
try:
|
||||
ret = p.wait(0.01)
|
||||
except TimeoutExpired:
|
||||
ret = None
|
||||
with suppress(Exception):
|
||||
raw += stdout.read()
|
||||
if ret is not None:
|
||||
break
|
||||
if p.returncode is None:
|
||||
log_error('Timed out waiting for shell to quit while reading shell environment')
|
||||
p.kill()
|
||||
elif p.returncode == 0:
|
||||
while True:
|
||||
try:
|
||||
x = stdout.read()
|
||||
except Exception:
|
||||
break
|
||||
if not x:
|
||||
break
|
||||
raw += x
|
||||
raw = raw.decode('utf-8', 'replace')
|
||||
for line in raw.splitlines():
|
||||
k, v = line.partition('=')[::2]
|
||||
if k and v:
|
||||
ans[k] = v
|
||||
else:
|
||||
log_error('Failed to run shell to read its environment')
|
||||
return read_shell_environment.ans
|
||||
|
||||
|
||||
def get_editor_from_env(shell_env):
|
||||
for var in ('VISUAL', 'EDITOR'):
|
||||
editor = shell_env.get(var)
|
||||
|
||||
@@ -7,9 +7,9 @@ import sys
|
||||
from collections import namedtuple
|
||||
|
||||
from .config_data import to_layout_names
|
||||
from .constants import kitty_exe, shell_path
|
||||
from .constants import kitty_exe
|
||||
from .layout import all_layouts
|
||||
from .utils import log_error
|
||||
from .utils import log_error, resolved_shell
|
||||
|
||||
WindowSizeOpts = namedtuple(
|
||||
'WindowSizeOpts', 'initial_window_width initial_window_height window_margin_width window_padding_width remember_window_size')
|
||||
@@ -74,15 +74,6 @@ class Session:
|
||||
self.tabs[-1].cwd = val
|
||||
|
||||
|
||||
def resolved_shell(opts=None):
|
||||
ans = getattr(opts, 'shell', '.')
|
||||
if ans == '.':
|
||||
ans = [shell_path]
|
||||
else:
|
||||
ans = shlex.split(ans)
|
||||
return ans
|
||||
|
||||
|
||||
def parse_session(raw, opts, default_title=None):
|
||||
|
||||
def finalize_session(ans):
|
||||
|
||||
@@ -16,9 +16,8 @@ from .fast_data_types import (
|
||||
x11_window_id
|
||||
)
|
||||
from .layout import create_layout_object_for, evict_cached_layouts
|
||||
from .session import resolved_shell
|
||||
from .tab_bar import TabBar, TabBarData
|
||||
from .utils import log_error
|
||||
from .utils import log_error, resolved_shell
|
||||
from .window import Window
|
||||
|
||||
SpecialWindowInstance = namedtuple('SpecialWindow', 'cmd stdin override_title cwd_from cwd overlay_for env')
|
||||
|
||||
@@ -10,11 +10,11 @@ import os
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
from time import monotonic
|
||||
from contextlib import suppress
|
||||
from time import monotonic
|
||||
|
||||
from .constants import (
|
||||
appname, is_macos, is_wayland, supports_primary_selection
|
||||
appname, is_macos, is_wayland, shell_path, supports_primary_selection
|
||||
)
|
||||
from .rgb import Color, to_color
|
||||
|
||||
@@ -452,3 +452,62 @@ def func_name(f):
|
||||
if hasattr(f, 'func') and hasattr(f.func, '__name__'):
|
||||
return f.func.__name__
|
||||
return str(f)
|
||||
|
||||
|
||||
def resolved_shell(opts=None):
|
||||
ans = getattr(opts, 'shell', '.')
|
||||
if ans == '.':
|
||||
ans = [shell_path]
|
||||
else:
|
||||
import shlex
|
||||
ans = shlex.split(ans)
|
||||
return ans
|
||||
|
||||
|
||||
def read_shell_environment(opts=None):
|
||||
if not hasattr(read_shell_environment, 'ans'):
|
||||
from .child import openpty, remove_blocking
|
||||
ans = read_shell_environment.ans = {}
|
||||
import subprocess
|
||||
shell = resolved_shell(opts)
|
||||
master, slave = openpty()
|
||||
remove_blocking(master)
|
||||
try:
|
||||
p = subprocess.Popen(shell + ['-l', '-c', 'env'], stdout=slave, stdin=slave, stderr=slave, start_new_session=True, close_fds=True)
|
||||
except FileNotFoundError:
|
||||
log_error('Could not find shell to read environment')
|
||||
return ans
|
||||
with os.fdopen(master, 'rb') as stdout, os.fdopen(slave, 'wb'):
|
||||
raw = b''
|
||||
from subprocess import TimeoutExpired
|
||||
from time import monotonic
|
||||
start_time = monotonic()
|
||||
while monotonic() - start_time < 1.5:
|
||||
try:
|
||||
ret = p.wait(0.01)
|
||||
except TimeoutExpired:
|
||||
ret = None
|
||||
with suppress(Exception):
|
||||
raw += stdout.read()
|
||||
if ret is not None:
|
||||
break
|
||||
if p.returncode is None:
|
||||
log_error('Timed out waiting for shell to quit while reading shell environment')
|
||||
p.kill()
|
||||
elif p.returncode == 0:
|
||||
while True:
|
||||
try:
|
||||
x = stdout.read()
|
||||
except Exception:
|
||||
break
|
||||
if not x:
|
||||
break
|
||||
raw += x
|
||||
raw = raw.decode('utf-8', 'replace')
|
||||
for line in raw.splitlines():
|
||||
k, v = line.partition('=')[::2]
|
||||
if k and v:
|
||||
ans[k] = v
|
||||
else:
|
||||
log_error('Failed to run shell to read its environment')
|
||||
return read_shell_environment.ans
|
||||
|
||||
@@ -29,7 +29,8 @@ from .rgb import to_color
|
||||
from .terminfo import get_capabilities
|
||||
from .utils import (
|
||||
color_as_int, get_primary_selection, load_shaders, open_cmd, open_url,
|
||||
parse_color_set, sanitize_title, set_primary_selection
|
||||
parse_color_set, read_shell_environment, sanitize_title,
|
||||
set_primary_selection
|
||||
)
|
||||
|
||||
|
||||
@@ -541,6 +542,14 @@ class Window:
|
||||
text = self.as_text(as_ansi=True, add_history=True, add_wrap_markers=True)
|
||||
data = self.pipe_data(text, has_wrap_markers=True)
|
||||
cmd = [x.replace('INPUT_LINE_NUMBER', str(data['input_line_number'])) for x in self.opts.scrollback_pager]
|
||||
import shutil
|
||||
exe = shutil.which(cmd[0])
|
||||
if not os.path.isabs(cmd[0]) and not exe:
|
||||
env = read_shell_environment(self.opts)
|
||||
if env and 'PATH' in env:
|
||||
exe = shutil.which(cmd[0], path=env['PATH'])
|
||||
if exe:
|
||||
cmd[0] = exe
|
||||
get_boss().display_scrollback(self, data['text'], cmd)
|
||||
|
||||
def paste_bytes(self, text):
|
||||
|
||||
Reference in New Issue
Block a user