mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-22 00:08:04 +02:00
Allow easily injecting env vars from the login shell config into the env in which kitty runs child processes
Fixes #9042
This commit is contained in:
@@ -137,6 +137,10 @@ Detailed list of changes
|
|||||||
0.43.2 [future]
|
0.43.2 [future]
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
- Allow kitty to read a specified set of environment variables from your
|
||||||
|
login shell at startup using the :opt:`env` directive in kitty.conf
|
||||||
|
(:iss:`9042`)
|
||||||
|
|
||||||
- Fix a regression in 0.43.0 that caused a black flicker when closing a tab in
|
- Fix a regression in 0.43.0 that caused a black flicker when closing a tab in
|
||||||
the presence of a background image (:iss:`9060`)
|
the presence of a background image (:iss:`9060`)
|
||||||
|
|
||||||
|
|||||||
10
docs/faq.rst
10
docs/faq.rst
@@ -480,6 +480,16 @@ related to localization, such as :envvar:`LANG`, ``LC_*`` and loading of
|
|||||||
configuration files such as ``XDG_*``, :envvar:`KITTY_CONFIG_DIRECTORY` and,
|
configuration files such as ``XDG_*``, :envvar:`KITTY_CONFIG_DIRECTORY` and,
|
||||||
most importantly, ``PATH`` to locate binaries.
|
most importantly, ``PATH`` to locate binaries.
|
||||||
|
|
||||||
|
The simplest way to fix this is to have kitty load the environment variables
|
||||||
|
from your shell configuration at startup using the :opt:`env` directive,
|
||||||
|
adding the following to :file:`kitty.conf`::
|
||||||
|
|
||||||
|
env read_from_login_shell=PATH LANG LC_* XDG_* EDITOR VISUAL
|
||||||
|
|
||||||
|
This works for POSIX compliant shells and the fish shell. Note that it
|
||||||
|
does add significantly to kitty startup time, so use only if really necessary.
|
||||||
|
This feature was added in version ``0.43.2``.
|
||||||
|
|
||||||
To see the environment variables that kitty sees, you can add the following
|
To see the environment variables that kitty sees, you can add the following
|
||||||
mapping to :file:`kitty.conf`::
|
mapping to :file:`kitty.conf`::
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ from .utils import (
|
|||||||
get_custom_window_icon,
|
get_custom_window_icon,
|
||||||
log_error,
|
log_error,
|
||||||
parse_os_window_state,
|
parse_os_window_state,
|
||||||
|
read_shell_environment,
|
||||||
safe_mtime,
|
safe_mtime,
|
||||||
startup_notification_handler,
|
startup_notification_handler,
|
||||||
)
|
)
|
||||||
@@ -478,6 +479,17 @@ def setup_environment(opts: Options, cli_opts: CLIOptions) -> None:
|
|||||||
from_config_file = True
|
from_config_file = True
|
||||||
if cli_opts.listen_on:
|
if cli_opts.listen_on:
|
||||||
cli_opts.listen_on = expand_listen_on(cli_opts.listen_on, from_config_file)
|
cli_opts.listen_on = expand_listen_on(cli_opts.listen_on, from_config_file)
|
||||||
|
if vars := opts.env.pop('read_from_login_shell', ''):
|
||||||
|
import fnmatch
|
||||||
|
import re
|
||||||
|
senv = read_shell_environment(opts)
|
||||||
|
patterns = tuple(re.compile(fnmatch.translate(x.strip())) for x in vars.split() if x.strip())
|
||||||
|
if patterns:
|
||||||
|
for k, v in senv.items():
|
||||||
|
for pat in patterns:
|
||||||
|
if pat.match(k) is not None:
|
||||||
|
opts.env[k] = v
|
||||||
|
break
|
||||||
env = opts.env.copy()
|
env = opts.env.copy()
|
||||||
ensure_kitty_in_path()
|
ensure_kitty_in_path()
|
||||||
ensure_kitten_in_path()
|
ensure_kitten_in_path()
|
||||||
|
|||||||
@@ -3254,7 +3254,9 @@ Changing this option by reloading the config is not supported.
|
|||||||
'''
|
'''
|
||||||
)
|
)
|
||||||
|
|
||||||
opt('+env', '',
|
opt(
|
||||||
|
'+env',
|
||||||
|
'',
|
||||||
option_type='env',
|
option_type='env',
|
||||||
add_to_default=False,
|
add_to_default=False,
|
||||||
long_text='''
|
long_text='''
|
||||||
@@ -3268,8 +3270,17 @@ recursively, for example::
|
|||||||
env VAR2=${HOME}/${VAR1}/b
|
env VAR2=${HOME}/${VAR1}/b
|
||||||
|
|
||||||
The value of :code:`VAR2` will be :code:`<path to home directory>/a/b`.
|
The value of :code:`VAR2` will be :code:`<path to home directory>/a/b`.
|
||||||
'''
|
|
||||||
)
|
Use the special
|
||||||
|
value :code:`read_from_login_shell` to have kitty read the specified variables from
|
||||||
|
your :opt:`login shell <shell>` configuration.
|
||||||
|
Useful if your shell startup files setup a bunch of environment variables that you want available to kitty and
|
||||||
|
in kitty session files. Each variable name is treated as a glob pattern to match. For example:
|
||||||
|
:code:`env read_from_login_shell=PATH LANG LC_* XDG_* EDITOR VISUAL`. Note that these variables are only
|
||||||
|
read after the configuration is fully processed, thus they are not available for recursive expansion and
|
||||||
|
they will override any variables set by other :opt:`env` directives.
|
||||||
|
''',
|
||||||
|
)
|
||||||
|
|
||||||
opt('+filter_notification', '', option_type='filter_notification', add_to_default=False, long_text='''
|
opt('+filter_notification', '', option_type='filter_notification', add_to_default=False, long_text='''
|
||||||
Specify rules to filter out notifications sent by applications running in kitty.
|
Specify rules to filter out notifications sent by applications running in kitty.
|
||||||
|
|||||||
@@ -748,12 +748,13 @@ def which(name: str, only_system: bool = False) -> str | None:
|
|||||||
def read_resolved_shell_environment(shell: tuple[str, ...]) -> MappingProxyType[str, str]:
|
def read_resolved_shell_environment(shell: tuple[str, ...]) -> MappingProxyType[str, str]:
|
||||||
import subprocess
|
import subprocess
|
||||||
cmdline = list(shell)
|
cmdline = list(shell)
|
||||||
if '-l' not in cmdline and '--login' not in shell:
|
if '-l' not in cmdline and '--login' not in cmdline:
|
||||||
cmdline += ['-l']
|
cmdline += ['-l']
|
||||||
if '-i' not in shell and '--interactive' not in shell:
|
if '-i' not in cmdline and '--interactive' not in cmdline:
|
||||||
cmdline += ['-i']
|
cmdline += ['-i']
|
||||||
is_fish = 'fish' in os.path.basename(cmdline[0]).lower()
|
q = os.path.basename(cmdline[0]).lower()
|
||||||
cmd = 'command env -0' if is_fish else 'builtin command env -0'
|
has_builtin = q in ('bash', 'zsh')
|
||||||
|
cmd = 'builtin command env -0' if has_builtin else 'command env -0'
|
||||||
ans: MappingProxyType[str, str] = MappingProxyType({})
|
ans: MappingProxyType[str, str] = MappingProxyType({})
|
||||||
|
|
||||||
from .child import openpty
|
from .child import openpty
|
||||||
@@ -764,7 +765,7 @@ def read_resolved_shell_environment(shell: tuple[str, ...]) -> MappingProxyType[
|
|||||||
cmdline + ['-c', cmd], stdout=slave, stdin=slave, stderr=slave, start_new_session=True, close_fds=True,
|
cmdline + ['-c', cmd], stdout=slave, stdin=slave, stderr=slave, start_new_session=True, close_fds=True,
|
||||||
preexec_fn=clear_handled_signals)
|
preexec_fn=clear_handled_signals)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
log_error('Could not find shell to read environment')
|
log_error(f'Could not find shell {cmdline[0]} to read environment')
|
||||||
return ans
|
return ans
|
||||||
with os.fdopen(master, 'rb') as stdout, os.fdopen(slave, 'wb'):
|
with os.fdopen(master, 'rb') as stdout, os.fdopen(slave, 'wb'):
|
||||||
raw = b''
|
raw = b''
|
||||||
@@ -781,7 +782,7 @@ def read_resolved_shell_environment(shell: tuple[str, ...]) -> MappingProxyType[
|
|||||||
if ret is not None:
|
if ret is not None:
|
||||||
break
|
break
|
||||||
if ret is None:
|
if ret is None:
|
||||||
log_error('Timed out waiting for shell to quit while reading shell environment')
|
log_error(f'Timed out waiting for shell {cmdline} to quit while reading shell environment')
|
||||||
p.kill()
|
p.kill()
|
||||||
elif ret == 0:
|
elif ret == 0:
|
||||||
while True:
|
while True:
|
||||||
@@ -800,7 +801,7 @@ def read_resolved_shell_environment(shell: tuple[str, ...]) -> MappingProxyType[
|
|||||||
env[k] = v
|
env[k] = v
|
||||||
ans = MappingProxyType(env)
|
ans = MappingProxyType(env)
|
||||||
else:
|
else:
|
||||||
log_error('Failed to run shell to read its environment')
|
log_error(f'Failed to run shell {cmdline} to read its environment')
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user