Shell integration: Dont modify ~/.zshrc

Instead use the ZDOTDIR env var to load the shell integration code
This commit is contained in:
Kovid Goyal 2021-11-27 07:19:59 +05:30
parent a3370a1d18
commit f6e0eb4005
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
5 changed files with 45 additions and 18 deletions

View File

@ -189,8 +189,10 @@ update-checking
./setup.py linux-package --update-check-interval=0
shell-integration
|kitty| by default installs its :ref:`shell_integration` files into the user's
rc files. For a package, it might make more sense to distribute the shell
|kitty| by default injects its :ref:`shell_integration` code into the user's
shell using environment variables or (for bash only) modifying
the user's :file:`~/.bashrc` file.
For a package, it might make more sense to distribute the shell
integration scripts into the system-wide shell vendor locations. The
shell integration files are found in the :file:`shell-integration`
directory. Copy them to the system wide shell vendor locations for each
@ -198,5 +200,5 @@ shell-integration
./setup.py linux-package --shell-integration=enabled\ no-rc
This will prevent kitty from modifying the user's shell rc files to load
This will prevent kitty from modifying the user's shell environment to load
the integration scripts.

View File

@ -51,7 +51,7 @@ disabled
turn off all shell integration
no-rc
dont modify the shell's rc files to enable integration. Useful if you prefer
dont modify the shell's launch environment to enable integration. Useful if you prefer
to :ref:`manually enable integration <manual_shell_integration>`.
no-cursor
@ -116,17 +116,23 @@ define the following in :file:`kitty.conf`:
How it works
-----------------
At startup kitty detects if the shell you have configured (either system wide
At startup, kitty detects if the shell you have configured (either system wide
or in kitty.conf) is a supported shell. If so, kitty injects some shell specific
code into the shell, to enable shell integration. How it does so varies for
different shells.
.. tab:: bash/zsh
.. tab:: zsh
For these shells, kitty adds a couple of lines to
the bottom of the shell's rc files (in an atomic manner) to load the shell
integration code.
For zsh, kitty sets the ``ZDOTDIR`` environment variable to make zsh load
kitty's :file:`.zshenv` which in turn loads the shell integration code then
restores the original value of ``ZDOTDIR`` and finally sources the original
:file:`.zshenv`. The remainder of zsh's startup process proceeds as normal.
.. tab:: bash
For bash, kitty adds a couple of lines to the bottom of :file:`~/.bashrc`
(in an atomic manner) to load the shell integration code.
.. tab:: fish
@ -178,9 +184,12 @@ code used for each shell below:
Manual shell integration
----------------------------
If you do not want to rely on kitty's automatic shell integration or if you
want to setup shell integration for a remote system over SSH, in
:file:`kitty.conf` set:
The automatic shell integration is designed to be minimally intrusive, as such
it wont work for sub-shells, terminal multiplexers, containers, remote systems, etc.
For such systems, you should setup manual shell integration by adding some code
to your shells startup files to load the shell integration script.
First, in :file:`kitty.conf` set:
.. code-block:: conf
@ -203,7 +212,7 @@ Then in your shell's rc file, add the lines:
if [[ ! -z "$KITTY_INSTALLATION_DIR" ]]; then
export KITTY_SHELL_INTEGRATION="enabled"
source "$KITTY_INSTALLATION_DIR/shell-integration/kitty.zsh"
source "$KITTY_INSTALLATION_DIR/shell-integration/zsh/kitty.zsh"
fi
.. tab:: fish

View File

@ -49,10 +49,7 @@ def setup_integration(shell_name: str, rc_path: str, template: str = posix_templ
def setup_zsh_integration(env: Dict[str, str]) -> None:
base = os.environ.get('ZDOTDIR', os.path.expanduser('~'))
rc = os.path.join(base, '.zshrc')
if os.path.exists(rc): # dont prevent zsh-newuser-install from running
setup_integration('zsh', rc)
pass # this is handled in the zsh env modifier
def setup_bash_integration(env: Dict[str, str]) -> None:
@ -74,13 +71,23 @@ def setup_fish_env(env: Dict[str, str]) -> None:
env['XDG_DATA_DIRS'] = os.pathsep.join(dirs)
def setup_zsh_env(env: Dict[str, str]) -> None:
zdotdir = os.environ.get('ZDOTDIR')
base = zdotdir or os.path.expanduser('~')
if zdotdir is not None:
env['KITTY_ORIG_ZDOTDIR'] = zdotdir
env['KITTY_ZSH_BASE'] = base
env['ZDOTDIR'] = os.path.join(shell_integration_dir, 'zsh')
SUPPORTED_SHELLS = {
'zsh': setup_zsh_integration,
'bash': setup_bash_integration,
'fish': setup_fish_integration,
}
ENV_MODIFIERS = {
'fish': setup_fish_env
'fish': setup_fish_env,
'zsh': setup_zsh_env,
}

View File

@ -0,0 +1,9 @@
if [[ -o interactive && -v ZDOTDIR && -r "$ZDOTDIR/kitty.zsh" ]]; then source "$ZDOTDIR/kitty.zsh"; fi
if [[ -v KITTY_ORIG_ZDOTDIR ]]; then
export ZDOTDIR="$KITTY_ORIG_ZDOTDIR"
unset KITTY_ORIG_ZDOTDIR
else
unset ZDOTDIR
fi
if [[ -v KITTY_ZSH_BASE && -r "$KITTY_ZSH_BASE/.zshenv" ]]; then source "$KITTY_ZSH_BASE/.zshenv"; fi
unset KITTY_ZSH_BASE