From 198b69e275b8f5db6eff5e71f02e86c8ae4e7b8c Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Thu, 21 Mar 2024 10:48:53 +0530 Subject: [PATCH] An option to set TERMINFO to the database directly instead of a path --- docs/changelog.rst | 5 +++++ docs/glossary.rst | 3 ++- kitty/child.py | 14 +++++++++++--- kitty/fast_data_types.pyi | 1 + kitty/options/definition.py | 12 ++++++++++++ kitty/options/parse.py | 8 ++++++++ kitty/options/types.py | 3 +++ 7 files changed, 42 insertions(+), 4 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 48b992982..556459780 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -47,6 +47,11 @@ rsync algorithm to speed up repeated transfers of large files. Detailed list of changes ------------------------------------- +0.33.2 [future] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- A new option :opt:`terminfo_type` to allow passing the terminfo database embedded into the :envvar:`TERMINFO` env var directly instead of via a file + 0.33.1 [2024-03-21] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/glossary.rst b/docs/glossary.rst index 486baadbb..3634c119a 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -164,7 +164,8 @@ Variables that kitty sets when running child programs .. envvar:: TERMINFO - Path to a directory containing the kitty terminfo database. + Path to a directory containing the kitty terminfo database. Or the terminfo + database itself encoded in base64. See :opt:`terminfo_type`. .. envvar:: KITTY_INSTALLATION_DIR diff --git a/kitty/child.py b/kitty/child.py index 4c16837b4..76fa2beb4 100644 --- a/kitty/child.py +++ b/kitty/child.py @@ -179,6 +179,11 @@ def getpid() -> str: return str(os.getpid()) +@run_once +def base64_terminfo_data() -> str: + return (b'b64:' + fast_data_types.base64_encode(fast_data_types.terminfo_data(), True)).decode('ascii') + + class ProcessDesc(TypedDict): cwd: Optional[str] pid: int @@ -242,9 +247,12 @@ class Child: # can use it to display the current directory name rather # than the resolved path env['PWD'] = self.cwd - tdir = checked_terminfo_dir() - if tdir: - env['TERMINFO'] = tdir + if opts.terminfo_type == 'path': + tdir = checked_terminfo_dir() + if tdir: + env['TERMINFO'] = tdir + elif opts.terminfo_type == 'direct': + env['TERMINFO'] = base64_terminfo_data() env['KITTY_INSTALLATION_DIR'] = kitty_base_dir if opts.forward_stdio: env['KITTY_STDIO_FORWARDED'] = '3' diff --git a/kitty/fast_data_types.pyi b/kitty/fast_data_types.pyi index 5ea4c4f66..395fd599f 100644 --- a/kitty/fast_data_types.pyi +++ b/kitty/fast_data_types.pyi @@ -1560,3 +1560,4 @@ def find_in_memoryview(buf: Union[bytes, memoryview, bytearray], chr: int) -> in def replace_c0_codes_except_nl_space_tab(text: str) -> str:... @overload def replace_c0_codes_except_nl_space_tab(text: Union[bytes, memoryview, bytearray]) -> bytes:... +def terminfo_data() -> bytes:... diff --git a/kitty/options/definition.py b/kitty/options/definition.py index 2632da17d..c43f02f47 100644 --- a/kitty/options/definition.py +++ b/kitty/options/definition.py @@ -3221,6 +3221,18 @@ created windows. ''' ) +opt('terminfo_type', 'path', choices=('path', 'direct', 'none'), + long_text=''' +The value of the :envvar:`TERMINFO` environment variable to set. This variable is +used by programs running in the terminal to search for terminfo databases. The default value +of :code:`path` causes kitty to set it to a filesystem location containing the +kitty terminfo database. A value of :code:`direct` means put the entire database into +the env var directly. This can be useful when connecting to containers, for example. But, +note that not all software supports this. A value of :code:`none` means do not touch the variable. +''' + ) + + opt('forward_stdio', 'no', option_type='to_bool', long_text=''' Forward STDOUT and STDERR of the kitty process to child processes as file descriptors 3 and 4. This is useful for debugging as it diff --git a/kitty/options/parse.py b/kitty/options/parse.py index 19515b32b..550bc40b4 100644 --- a/kitty/options/parse.py +++ b/kitty/options/parse.py @@ -1294,6 +1294,14 @@ class Parser: def term(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['term'] = str(val) + def terminfo_type(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: + val = val.lower() + if val not in self.choices_for_terminfo_type: + raise ValueError(f"The value {val} is not a valid choice for terminfo_type") + ans["terminfo_type"] = val + + choices_for_terminfo_type = frozenset(('path', 'direct', 'none')) + def text_composition_strategy(self, val: str, ans: typing.Dict[str, typing.Any]) -> None: ans['text_composition_strategy'] = str(val) diff --git a/kitty/options/types.py b/kitty/options/types.py index 1f48fed4a..bb5469bb5 100644 --- a/kitty/options/types.py +++ b/kitty/options/types.py @@ -31,6 +31,7 @@ choices_for_tab_bar_align = typing.Literal['left', 'center', 'right'] choices_for_tab_bar_style = typing.Literal['fade', 'hidden', 'powerline', 'separator', 'slant', 'custom'] choices_for_tab_powerline_style = typing.Literal['angled', 'round', 'slanted'] choices_for_tab_switch_strategy = typing.Literal['last', 'left', 'previous', 'right'] +choices_for_terminfo_type = typing.Literal['path', 'direct', 'none'] choices_for_undercurl_style = typing.Literal['thin-sparse', 'thin-dense', 'thick-sparse', 'thick-dense'] choices_for_underline_hyperlinks = typing.Literal['hover', 'always', 'never'] choices_for_window_logo_position = typing.Literal['top-left', 'top', 'top-right', 'left', 'center', 'right', 'bottom-left', 'bottom', 'bottom-right'] @@ -433,6 +434,7 @@ option_names = ( # {{{ 'tab_title_max_length', 'tab_title_template', 'term', + 'terminfo_type', 'text_composition_strategy', 'text_fg_override_threshold', 'touch_scroll_multiplier', @@ -591,6 +593,7 @@ class Options: tab_title_max_length: int = 0 tab_title_template: str = '{fmt.fg.red}{bell_symbol}{activity_symbol}{fmt.fg.tab}{title}' term: str = 'xterm-kitty' + terminfo_type: choices_for_terminfo_type = 'path' text_composition_strategy: str = 'platform' text_fg_override_threshold: float = 0.0 touch_scroll_multiplier: float = 1.0