Allow deleting environment vars from the child environment using env

This commit is contained in:
Kovid Goyal 2021-09-16 08:43:17 +05:30
parent 69dc09489b
commit 66e2e60ac4
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
7 changed files with 37 additions and 14 deletions

View File

@ -40,6 +40,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
- hints kitten: Fix a regression that caused using the default open program
to trigger open actions instead of running the program (:iss:`3968`)
- Allow deleting environment variables in :opt:`env` by specifying
just the variable name, without a value
0.23.1 [2021-08-17]
----------------------

View File

@ -13,7 +13,7 @@ from typing import (
import kitty.fast_data_types as fast_data_types
from .constants import is_macos, shell_path, terminfo_dir
from .constants import is_macos, shell_path, terminfo_dir, delete_env_var
from .types import run_once
try:
@ -232,6 +232,7 @@ class Child:
from .shell_integration import get_supported_shell_name
if get_supported_shell_name(self.argv[0]):
env['KITTY_SHELL_INTEGRATION'] = opts.shell_integration
env = {k: v for k, v in env.items() if v is not delete_env_var}
return env
def fork(self) -> Optional[int]:

View File

@ -21,10 +21,18 @@ class Version(NamedTuple):
patch: int
class SentinelString(str):
def __new__(cls, val: str) -> 'SentinelString':
ans: SentinelString = str.__new__(cls, val)
return ans
appname: str = 'kitty'
kitty_face = '🐱'
version: Version = Version(0, 23, 1)
str_version: str = '.'.join(map(str, version))
delete_env_var = SentinelString('_delete_this_env_var_')
_plat = sys.platform.lower()
is_macos: bool = 'darwin' in _plat
if getattr(sys, 'frozen', False):

View File

@ -17,6 +17,7 @@ from .tabs import Tab
from .types import run_once
from .utils import find_exe, read_shell_environment, set_primary_selection
from .window import Watchers, Window
from .options.utils import env as parse_env
try:
from typing import TypedDict
@ -69,8 +70,9 @@ The working directory for the newly launched child. Use the special value
--env
type=list
Environment variables to set in the child process. Can be specified multiple
times to set different environment variables.
Syntax: :italic:`name=value`.
times to set different environment variables. Syntax: :code:`name=value`.
Using :code:`name=` will set to empty string and just :code:`name` will
remove the environment variable.
--copy-colors
@ -193,9 +195,8 @@ def get_env(opts: LaunchCLIOptions, active_child: Child) -> Dict[str, str]:
if opts.copy_env and active_child:
env.update(active_child.foreground_environ)
for x in opts.env:
parts = x.split('=', 1)
if len(parts) == 2:
env[parts[0]] = parts[1]
for k, v in parse_env(x, env):
env[k] = v
return env

View File

@ -2518,7 +2518,9 @@ environment variables are expanded recursively, so if you use::
env MYVAR1=a
env MYVAR2=${MYVAR1}/${HOME}/b
The value of MYVAR2 will be :code:`a/<path to home directory>/b`.
The value of MYVAR2 will be :code:`a/<path to home directory>/b`. Using
:code:`VAR=` will set it to the empty string and using just :code:`VAR`
will delete the variable from the child process' environment.
'''
)

View File

@ -16,7 +16,7 @@ from kitty.conf.utils import (
KeyAction, key_func, positive_float, positive_int, python_string, to_bool,
to_cmdline, to_color, uniq, unit_float
)
from kitty.constants import config_dir, is_macos
from kitty.constants import config_dir, is_macos, delete_env_var
from kitty.fast_data_types import CURSOR_BEAM, CURSOR_BLOCK, CURSOR_UNDERLINE
from kitty.fonts import FontFeature
from kitty.key_names import (
@ -731,10 +731,17 @@ def font_features(val: str) -> Iterable[Tuple[str, Tuple[FontFeature, ...]]]:
def env(val: str, current_val: Dict[str, str]) -> Iterable[Tuple[str, str]]:
key, val = val.partition('=')[::2]
key, val = key.strip(), val.strip()
if key:
yield key, expandvars(val, current_val)
val = val.strip()
if val:
if '=' in val:
key, v = val.split('=', 1)
key, v = key.strip(), v.strip()
if key:
if v:
v = expandvars(v, current_val)
yield key, v
else:
yield val, delete_env_var
def kitten_alias(val: str) -> Iterable[Tuple[str, List[str]]]:

View File

@ -5,6 +5,7 @@
from . import BaseTest
from kitty.utils import log_error
from kitty.constants import delete_env_var
class TestConfParsing(BaseTest):
@ -48,8 +49,8 @@ class TestConfParsing(BaseTest):
self.assertFalse(bad_lines)
opts = p('pointer_shape_when_grabbed XXX', bad_line_num=1)
self.ae(opts.pointer_shape_when_grabbed, defaults.pointer_shape_when_grabbed)
opts = p('env A=1', 'env B=x$A', 'clear_all_shortcuts y', 'kitten_alias a b --moo', 'map f1 kitten a')
self.ae(opts.env, {'A': '1', 'B': 'x1'})
opts = p('env A=1', 'env B=x$A', 'env C=', 'env D', 'clear_all_shortcuts y', 'kitten_alias a b --moo', 'map f1 kitten a')
self.ae(opts.env, {'A': '1', 'B': 'x1', 'C': '', 'D': delete_env_var})
ka = tuple(opts.keymap.values())[0]
self.ae(ka.args, ('b', '--moo'))
opts = p('kitty_mod alt')