From df9e893cbebe77e8db9d111559c7bea474923e5a Mon Sep 17 00:00:00 2001 From: pagedown Date: Mon, 7 Mar 2022 11:24:18 +0800 Subject: [PATCH 1/7] Explicitly use builtin and command --- shell-integration/ssh/bootstrap.sh | 4 ++-- shell-integration/zsh/kitty-integration | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/shell-integration/ssh/bootstrap.sh b/shell-integration/ssh/bootstrap.sh index 44a688c5c..18966988b 100644 --- a/shell-integration/ssh/bootstrap.sh +++ b/shell-integration/ssh/bootstrap.sh @@ -203,7 +203,7 @@ parse_passwd_record() { using_getent() { cmd=$(command -v getent) if [ -n "$cmd" ]; then - output=$($cmd passwd $USER 2>/dev/null) + output=$(command $cmd passwd $USER 2>/dev/null) if [ $? = 0 ]; then login_shell=$(echo $output | parse_passwd_record); if login_shell_is_ok; then return 0; fi @@ -215,7 +215,7 @@ using_getent() { using_id() { cmd=$(command -v id) if [ -n "$cmd" ]; then - output=$($cmd -P $USER 2>/dev/null) + output=$(command $cmd -P $USER 2>/dev/null) if [ $? = 0 ]; then login_shell=$(echo $output | parse_passwd_record); if login_shell_is_ok; then return 0; fi diff --git a/shell-integration/zsh/kitty-integration b/shell-integration/zsh/kitty-integration index a2d615547..6b37a0876 100644 --- a/shell-integration/zsh/kitty-integration +++ b/shell-integration/zsh/kitty-integration @@ -55,9 +55,9 @@ builtin typeset -gi _ksi_state # _ksi_deferred_init. typeset -gi _ksi_fd { - zmodload zsh/system && (( $+builtins[sysopen] )) && { - { [[ -w $TTY ]] && sysopen -o cloexec -wu _ksi_fd -- $TTY } || - { [[ -w /dev/tty ]] && sysopen -o cloexec -wu _ksi_fd -- /dev/tty } + builtin zmodload zsh/system && (( $+builtins[sysopen] )) && { + { [[ -w $TTY ]] && builtin sysopen -o cloexec -wu _ksi_fd -- $TTY } || + { [[ -w /dev/tty ]] && builtin sysopen -o cloexec -wu _ksi_fd -- /dev/tty } } } 2>/dev/null || (( _ksi_fd = 1 )) @@ -87,7 +87,7 @@ _ksi_deferred_init() { # Recognized options: no-cursor, no-title, no-prompt-mark, no-complete. builtin local -a opt opt=(${(s: :)KITTY_SHELL_INTEGRATION}) - unset KITTY_SHELL_INTEGRATION + builtin unset KITTY_SHELL_INTEGRATION # The directory where kitty-integration is located: /.../shell-integration/zsh. builtin local self_dir="${functions_source[_ksi_deferred_init]:A:h}" From 3095e7a25650fe6f82dd7d60c6eb0f14b00003d4 Mon Sep 17 00:00:00 2001 From: pagedown Date: Mon, 7 Mar 2022 11:25:22 +0800 Subject: [PATCH 2/7] Remove trailing semicolons --- shell-integration/ssh/bootstrap.sh | 53 ++++++++++++++---------------- 1 file changed, 25 insertions(+), 28 deletions(-) diff --git a/shell-integration/ssh/bootstrap.sh b/shell-integration/ssh/bootstrap.sh index 18966988b..1cc0fbf98 100644 --- a/shell-integration/ssh/bootstrap.sh +++ b/shell-integration/ssh/bootstrap.sh @@ -81,7 +81,7 @@ if [ -z "$HOSTNAME" ]; then if [ -z "$hostname" ]; then hostname=$(command hostnamectl hostname 2> /dev/null) if [ -z "$hostname" ]; then - hostname="_"; + hostname="_" fi fi else @@ -100,12 +100,12 @@ init_tty && trap 'cleanup_on_bootstrap_exit' EXIT record_separator=$(printf "\036") mv_files_and_dirs() { - cwd="$PWD"; - cd "$1"; + cwd="$PWD" + cd "$1" command find . -type d -exec mkdir -p "$2/{}" ";" command find . -type l -exec sh -c "tgt=\$(command readlink -n \"{}\"); command ln -sf \"\$tgt\" \"$2/{}\"; command rm -f \"{}\"" ";" command find . -type f -exec mv "{}" "$2/{}" ";" - cd "$cwd"; + cd "$cwd" } compile_terminfo() { @@ -130,18 +130,18 @@ untar_and_read_env() { # extract the tar file atomically, in the sense that any file from the # tarfile is only put into place after it has been fully written to disk - tdir=$(command mktemp -d "$HOME/.kitty-ssh-kitten-untar-XXXXXXXXXXXX"); - [ $? = 0 ] || die "Creating temp directory failed"; - read_n_bytes_from_tty "$1" | command base64 -d | command tar xjf - --no-same-owner -C "$tdir"; - data_file="$tdir/data.sh"; - [ -f "$data_file" ] && . "$data_file"; + tdir=$(command mktemp -d "$HOME/.kitty-ssh-kitten-untar-XXXXXXXXXXXX") + [ $? = 0 ] || die "Creating temp directory failed" + read_n_bytes_from_tty "$1" | command base64 -d | command tar xjf - --no-same-owner -C "$tdir" + data_file="$tdir/data.sh" + [ -f "$data_file" ] && . "$data_file" data_dir="$HOME/$KITTY_SSH_KITTEN_DATA_DIR" compile_terminfo "$tdir/home" mv_files_and_dirs "$tdir/home" "$HOME" [ -e "$tdir/root" ] && mv_files_and_dirs "$tdir/root" "" - command rm -rf "$tdir"; - [ -z "KITTY_SSH_KITTEN_DATA_DIR" ] && die "Failed to read SSH data from tty"; - unset KITTY_SSH_KITTEN_DATA_DIR; + command rm -rf "$tdir" + [ -z "KITTY_SSH_KITTEN_DATA_DIR" ] && die "Failed to read SSH data from tty" + unset KITTY_SSH_KITTEN_DATA_DIR } read_record() { @@ -175,17 +175,15 @@ if [ "$tty_ok" = "y" ]; then printf "\r\033[K" > /dev/tty fi shell_integration_dir="$data_dir/shell-integration" - [ -f "$HOME/.terminfo/kitty.terminfo" ] || die "Incomplete extraction of ssh data"; - + [ -f "$HOME/.terminfo/kitty.terminfo" ] || die "Incomplete extraction of ssh data" fi - login_shell_is_ok() { if [ -z "$login_shell" -o ! -x "$login_shell" ]; then return 1; fi case "$login_shell" in *sh) return 0; esac - return 1; + return 1 } detect_python() { @@ -193,7 +191,7 @@ detect_python() { if [ -z "$python" ]; then python=$(command -v python2); fi if [ -z "$python" ]; then python=$(command -v python); fi if [ -z "$python" -o ! -x "$python" ]; then return 1; fi - return 0; + return 0 } parse_passwd_record() { @@ -205,11 +203,11 @@ using_getent() { if [ -n "$cmd" ]; then output=$(command $cmd passwd $USER 2>/dev/null) if [ $? = 0 ]; then - login_shell=$(echo $output | parse_passwd_record); + login_shell=$(echo $output | parse_passwd_record) if login_shell_is_ok; then return 0; fi fi fi - return 1; + return 1 } using_id() { @@ -217,29 +215,29 @@ using_id() { if [ -n "$cmd" ]; then output=$(command $cmd -P $USER 2>/dev/null) if [ $? = 0 ]; then - login_shell=$(echo $output | parse_passwd_record); + login_shell=$(echo $output | parse_passwd_record) if login_shell_is_ok; then return 0; fi fi fi - return 1; + return 1 } using_passwd() { if [ -f "/etc/passwd" -a -r "/etc/passwd" ]; then output=$(command grep "^$USER:" /etc/passwd 2>/dev/null) if [ $? = 0 ]; then - login_shell=$(echo $output | parse_passwd_record); + login_shell=$(echo $output | parse_passwd_record) if login_shell_is_ok; then return 0; fi fi fi - return 1; + return 1 } using_python() { if detect_python; then output=$(command $python -c "import pwd, os; print(pwd.getpwuid(os.geteuid()).pw_shell)") if [ $? = 0 ]; then - login_shell=$output; + login_shell=$output if login_shell_is_ok; then return 0; fi fi fi @@ -250,14 +248,14 @@ execute_with_python() { if detect_python; then exec $python -c "import os; os.execlp('$login_shell', '-' '$shell_name')" fi - return 1; + return 1 } if [ -n "$KITTY_LOGIN_SHELL" ]; then login_shell="$KITTY_LOGIN_SHELL" unset KITTY_LOGIN_SHELL else - using_getent || using_id || using_python || using_passwd || die "Could not detect login shell"; + using_getent || using_id || using_python || using_passwd || die "Could not detect login shell" fi shell_name=$(command basename $login_shell) @@ -272,7 +270,6 @@ if [ "$tty_ok" = "n" ]; then fi fi - exec_bash_with_integration() { export ENV="$shell_integration_dir/bash/kitty.bash" export KITTY_BASH_INJECT="1" @@ -333,7 +330,7 @@ case "$KITTY_SHELL_INTEGRATION" in (*) # not blank q=$(printf "%s" "$KITTY_SHELL_INTEGRATION" | command grep '\bno-rc\b') - if [ -z "$q" ]; then + if [ -z "$q" ]; then exec_with_shell_integration # exec failed, unset unset KITTY_SHELL_INTEGRATION From 397fbe7ad32cb455a17a44e3868f2d3582e7c998 Mon Sep 17 00:00:00 2001 From: pagedown Date: Mon, 7 Mar 2022 11:30:12 +0800 Subject: [PATCH 3/7] Avoid unnecessary which and fix typos --- kittens/ssh/main.py | 2 +- shell-integration/ssh/bootstrap.py | 23 +++++++++++------------ shell-integration/ssh/bootstrap.sh | 4 ++-- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/kittens/ssh/main.py b/kittens/ssh/main.py index f36b0d056..3f736fd53 100644 --- a/kittens/ssh/main.py +++ b/kittens/ssh/main.py @@ -73,7 +73,7 @@ def make_tarfile(ssh_opts: SSHOptions, base_env: Dict[str, str]) -> bytes: def filter_from_globs(*pats: str) -> Callable[[tarfile.TarInfo], Optional[tarfile.TarInfo]]: def filter(tarinfo: tarfile.TarInfo) -> Optional[tarfile.TarInfo]: for junk_dir in ('.DS_Store', '__pycache__'): - for pat in (f'*/{junk_dir}', '*/{junk_dir}/*'): + for pat in (f'*/{junk_dir}', f'*/{junk_dir}/*'): if fnmatch.fnmatch(tarinfo.name, pat): return None for pat in pats: diff --git a/shell-integration/ssh/bootstrap.py b/shell-integration/ssh/bootstrap.py index f170a2cec..450e82f7c 100644 --- a/shell-integration/ssh/bootstrap.py +++ b/shell-integration/ssh/bootstrap.py @@ -103,21 +103,20 @@ def move(src, base_dest): def compile_terminfo(base): - if not shutil.which('tic'): + tic = shutil.which('tic') + if not tic: return tname = '.terminfo' if os.path.exists('/usr/share/misc/terminfo.cdb'): tname += '.cdb' os.environ['TERMINFO'] = os.path.join(HOME, tname) - tic = shutil.which('tic') - if tic: - cp = subprocess.run( - [tic, '-x', '-o', os.path.join(base, tname), os.path.join(base, '.terminfo', 'kitty.terminfo')], - stdout=subprocess.PIPE, stderr=subprocess.STDOUT - ) - if cp.returncode != 0: - sys.stderr.buffer.write(cp.stdout) - raise SystemExit('Failed to compile the terminfo database') + cp = subprocess.run( + [tic, '-x', '-o', os.path.join(base, tname), os.path.join(base, '.terminfo', 'kitty.terminfo')], + stdout=subprocess.PIPE, stderr=subprocess.STDOUT + ) + if cp.returncode != 0: + sys.stderr.buffer.write(cp.stdout) + raise SystemExit('Failed to compile the terminfo database') def get_data(): @@ -176,8 +175,8 @@ def exec_zsh_with_integration(): os.environ.pop('KITTY_ORIG_ZDOTDIR', None) # ensure this is not propagated else: os.environ['KITTY_ORIG_ZDOTDIR'] = zdotdir - # dont prevent zsh-new-user from running - for q in '.zshrc .zshenv .zprofile .zlogin'.split(): + # dont prevent zsh-newuser-install from running + for q in ('.zshrc', '.zshenv', '.zprofile', '.zlogin'): if os.path.exists(os.path.join(HOME, q)): os.environ['ZDOTDIR'] = shell_integration_dir + '/zsh' os.execlp(login_shell, os.path.basename(login_shell), '-l') diff --git a/shell-integration/ssh/bootstrap.sh b/shell-integration/ssh/bootstrap.sh index 1cc0fbf98..885e90ff5 100644 --- a/shell-integration/ssh/bootstrap.sh +++ b/shell-integration/ssh/bootstrap.sh @@ -95,7 +95,7 @@ if [ -z "$USER" ]; then USER=$(command whoami 2> /dev/null); fi # ask for the SSH data leading_data="" -init_tty && trap 'cleanup_on_bootstrap_exit' EXIT +init_tty && trap "cleanup_on_bootstrap_exit" EXIT [ "$tty_ok" = "y" ] && dcs_to_kitty "ssh" "id="REQUEST_ID":hostname="$hostname":pwfile="PASSWORD_FILENAME":user="$USER":pw="DATA_PASSWORD"" record_separator=$(printf "\036") @@ -287,7 +287,7 @@ exec_zsh_with_integration() { else export KITTY_ORIG_ZDOTDIR="$zdotdir" fi - # dont prevent zsh-new-user from running + # dont prevent zsh-newuser-install from running if [ -f "$zdotdir/.zshrc" -o -f "$zdotdir/.zshenv" -o -f "$zdotdir/.zprofile" -o -f "$zdotdir/.zlogin" ]; then export ZDOTDIR="$shell_integration_dir/zsh" exec "$login_shell" "-l" From 43fd8cb13cef88dec638b2c67c02b09940c62941 Mon Sep 17 00:00:00 2001 From: pagedown Date: Mon, 7 Mar 2022 11:36:52 +0800 Subject: [PATCH 4/7] Unify exec function definition order --- shell-integration/ssh/bootstrap.py | 22 ++++++++-------- shell-integration/ssh/bootstrap.sh | 42 +++++++++++++++--------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/shell-integration/ssh/bootstrap.py b/shell-integration/ssh/bootstrap.py index 450e82f7c..a0efeb852 100644 --- a/shell-integration/ssh/bootstrap.py +++ b/shell-integration/ssh/bootstrap.py @@ -159,15 +159,6 @@ def get_data(): move(tdir + '/root', '/') -def exec_bash_with_integration(): - os.environ['ENV'] = os.path.join(shell_integration_dir, 'bash', 'kitty.bash') - os.environ['KITTY_BASH_INJECT'] = '1' - if not os.environ.get('HISTFILE'): - os.environ['HISTFILE'] = os.path.join(HOME, '.bash_history') - os.environ['KITTY_BASH_UNEXPORT_HISTFILE'] = '1' - os.execlp(login_shell, os.path.basename('login_shell'), '--posix') - - def exec_zsh_with_integration(): zdotdir = os.environ.get('ZDOTDIR') or '' if not zdotdir: @@ -192,14 +183,23 @@ def exec_fish_with_integration(): os.execlp(login_shell, os.path.basename(login_shell), '-l') +def exec_bash_with_integration(): + os.environ['ENV'] = os.path.join(shell_integration_dir, 'bash', 'kitty.bash') + os.environ['KITTY_BASH_INJECT'] = '1' + if not os.environ.get('HISTFILE'): + os.environ['HISTFILE'] = os.path.join(HOME, '.bash_history') + os.environ['KITTY_BASH_UNEXPORT_HISTFILE'] = '1' + os.execlp(login_shell, os.path.basename('login_shell'), '--posix') + + def exec_with_shell_integration(): shell_name = os.path.basename(login_shell).lower() - if shell_name == 'bash': - exec_bash_with_integration() if shell_name == 'zsh': exec_zsh_with_integration() if shell_name == 'fish': exec_fish_with_integration() + if shell_name == 'bash': + exec_bash_with_integration() def main(): diff --git a/shell-integration/ssh/bootstrap.sh b/shell-integration/ssh/bootstrap.sh index 885e90ff5..39aedfd51 100644 --- a/shell-integration/ssh/bootstrap.sh +++ b/shell-integration/ssh/bootstrap.sh @@ -222,22 +222,22 @@ using_id() { return 1 } -using_passwd() { - if [ -f "/etc/passwd" -a -r "/etc/passwd" ]; then - output=$(command grep "^$USER:" /etc/passwd 2>/dev/null) +using_python() { + if detect_python; then + output=$(command $python -c "import pwd, os; print(pwd.getpwuid(os.geteuid()).pw_shell)") if [ $? = 0 ]; then - login_shell=$(echo $output | parse_passwd_record) + login_shell=$output if login_shell_is_ok; then return 0; fi fi fi return 1 } -using_python() { - if detect_python; then - output=$(command $python -c "import pwd, os; print(pwd.getpwuid(os.geteuid()).pw_shell)") +using_passwd() { + if [ -f "/etc/passwd" -a -r "/etc/passwd" ]; then + output=$(command grep "^$USER:" /etc/passwd 2>/dev/null) if [ $? = 0 ]; then - login_shell=$output + login_shell=$(echo $output | parse_passwd_record) if login_shell_is_ok; then return 0; fi fi fi @@ -270,16 +270,6 @@ if [ "$tty_ok" = "n" ]; then fi fi -exec_bash_with_integration() { - export ENV="$shell_integration_dir/bash/kitty.bash" - export KITTY_BASH_INJECT="1" - if [ -z "$HISTFILE" ]; then - export HISTFILE="$HOME/.bash_history" - export KITTY_BASH_UNEXPORT_HISTFILE="1" - fi - exec "$login_shell" "--posix" -} - exec_zsh_with_integration() { zdotdir="$ZDOTDIR" if [ -z "$zdotdir" ]; then @@ -305,17 +295,27 @@ exec_fish_with_integration() { exec "$login_shell" "-l" } +exec_bash_with_integration() { + export ENV="$shell_integration_dir/bash/kitty.bash" + export KITTY_BASH_INJECT="1" + if [ -z "$HISTFILE" ]; then + export HISTFILE="$HOME/.bash_history" + export KITTY_BASH_UNEXPORT_HISTFILE="1" + fi + exec "$login_shell" "--posix" +} + exec_with_shell_integration() { case "$shell_name" in "zsh") exec_zsh_with_integration ;; - "bash") - exec_bash_with_integration - ;; "fish") exec_fish_with_integration ;; + "bash") + exec_bash_with_integration + ;; esac } From 817ac829682c5cc7cdfab862596bb9b659e7e24a Mon Sep 17 00:00:00 2001 From: pagedown Date: Mon, 7 Mar 2022 12:00:55 +0800 Subject: [PATCH 5/7] Detect SSH sessions without affecting performance Exclude local runs by KITTY_PID. Check KITTY_WINDOW_ID to detect connections via ssh kitten. Check SSH via who -m with the integration manually installed and sudo. --- shell-integration/bash/kitty.bash | 11 ++++++++++- shell-integration/zsh/kitty-integration | 13 +++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/shell-integration/bash/kitty.bash b/shell-integration/bash/kitty.bash index edd5f6874..4e4deb2a8 100644 --- a/shell-integration/bash/kitty.bash +++ b/shell-integration/bash/kitty.bash @@ -155,8 +155,17 @@ _ksi_main() { fi if [[ "${_ksi_prompt[title]}" == "y" ]]; then - if [[ -n "$SSH_TTY$SSH2_TTY" ]]; then + if [[ -n "$KITTY_PID" ]]; then + # kitty running locally + elif [[ -n "$SSH_TTY" || -n "$SSH2_TTY$KITTY_WINDOW_ID" ]]; then + # connected to most SSH servers + # or use ssh kitten to connected to some SSH servers that do not set SSH_TTY _ksi_prompt[hostname_prefix]="\h: "; + elif [[ -n "$(builtin command -v who)" ]]; then + # the shell integration script is installed manually on the remote system + # the environment variables are cleared after sudo + # OpenSSH's sshd creates entries in utmp for every login so use those + [[ "$(builtin command who -m 2> /dev/null)" =~ "\([a-fA-F.:0-9]+\)$" ]] && _ksi_prompt[hostname_prefix]="\h: "; fi # see https://www.gnu.org/software/bash/manual/html_node/Controlling-the-Prompt.html#Controlling-the-Prompt # we use suffix here because some distros add title setting to their bashrc files by default diff --git a/shell-integration/zsh/kitty-integration b/shell-integration/zsh/kitty-integration index 6b37a0876..131a9b072 100644 --- a/shell-integration/zsh/kitty-integration +++ b/shell-integration/zsh/kitty-integration @@ -233,8 +233,17 @@ _ksi_deferred_init() { # (LF becomes \n, etc.). This isn't necessary in precmd because (%) does it # for us. builtin local is_ssh_session="n" - if [[ -n "$SSH_TTY$SSH2_TTY" ]]; then - is_ssh_session="y"; + if [[ -n "$KITTY_PID" ]]; then + # kitty running locally + elif [[ -n "$SSH_TTY" || -n "$SSH2_TTY$KITTY_WINDOW_ID" ]]; then + # connected to most SSH servers + # or use ssh kitten to connected to some SSH servers that do not set SSH_TTY + is_ssh_session="y" + elif [[ -n "$(builtin command -v who)" ]]; then + # the shell integration script is installed manually on the remote system + # the environment variables are cleared after sudo + # OpenSSH's sshd creates entries in utmp for every login so use those + [[ "$(builtin command who -m 2> /dev/null)" =~ "\([a-fA-F.:0-9]+\)$" ]] && is_ssh_session="y" fi if [[ "$is_ssh_session" == "y" ]]; then From 1b68e41db4addf9041b9bc463398180117b6977e Mon Sep 17 00:00:00 2001 From: pagedown Date: Mon, 7 Mar 2022 12:12:52 +0800 Subject: [PATCH 6/7] Remove the fish integration prompt end B prompt marking Currently kitty does not use the B prompt marking. This is consistent with the zsh and bash implementations. Improve compatibility with most user configurations. --- kitty_tests/shell_integration.py | 10 +--------- .../vendor_conf.d/kitty-shell-integration.fish | 17 +---------------- 2 files changed, 2 insertions(+), 25 deletions(-) diff --git a/kitty_tests/shell_integration.py b/kitty_tests/shell_integration.py index b9c6c8b1c..9002ef90e 100644 --- a/kitty_tests/shell_integration.py +++ b/kitty_tests/shell_integration.py @@ -213,16 +213,8 @@ function _set_status_prompt; function fish_prompt; echo -n "$pipestatus $status pty.write_to_child('i') pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_BEAM) pty.send_cmd_to_child('_set_key default') - - # pipestatus - pty.send_cmd_to_child('clear;false|true|false') - pty.send_cmd_to_child('echo $pipestatus $status') - pty.wait_till(lambda: pty.screen_contents().count(right_prompt) == 2) - self.ae(pty.last_cmd_output(), '1 0 1 1') - pty.send_cmd_to_child('_set_status_prompt') - pty.send_cmd_to_child('false|true|false') pty.wait_till(lambda: pty.screen_contents().count(right_prompt) == 4) - self.assertTrue(str(pty.screen.line(pty.screen.cursor.y)).startswith(f'1 0 1 1 {fish_prompt}')) + pty.wait_till(lambda: pty.screen.cursor.shape == CURSOR_BEAM) pty.send_cmd_to_child('exit') diff --git a/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish b/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish index 9efa1fa0e..e2ffc0e3f 100644 --- a/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish +++ b/shell-integration/fish/vendor_conf.d/kitty-shell-integration.fish @@ -19,7 +19,7 @@ end status is-interactive || exit 0 not functions -q __ksi_schedule || exit 0 -# Check fish version 3.3.0+ efficiently and fallback to check the last working version 3.2.0, exit on outdated versions. +# Check fish version 3.3.0+ efficiently and fallback to check the minimum working version 3.2.0, exit on outdated versions. # "Warning: Update fish to version 3.3.0+ to enable kitty shell integration.\n" set -q fish_killring || set -q status_generation || string match -qnv "3.1.*" "$version" or echo -en "\eP@kitty-print|V2FybmluZzogVXBkYXRlIGZpc2ggdG8gdmVyc2lvbiAzLjMuMCsgdG8gZW5hYmxlIGtpdHR5IHNoZWxsIGludGVncmF0aW9uLgo=\e\\" && exit 0 || exit 0 @@ -80,21 +80,6 @@ function __ksi_schedule --on-event fish_prompt -d "Setup kitty integration after end __ksi_mark_prompt_start - functions -c fish_prompt __ksi_original_fish_prompt - function fish_prompt - # fish trims one trailing newline from the output of fish_prompt, so - # we need to do the same. See https://github.com/kovidgoyal/kitty/issues/4032 - # op is a list because fish splits on newlines in command substitution - set --local op (__ksi_original_fish_prompt) - # print all but last element of the list, each followed by a new line - set -q op[2] - and printf '%s\n' $op[1..-2] - # print the last component without a newline - printf '%s' $op[-1] - set --global __ksi_prompt_state prompt-end - echo -en "\e]133;B\a" - end - function __ksi_mark_output_start --on-event fish_preexec set --global __ksi_prompt_state pre-exec echo -en "\e]133;C\a" From 5f3d90e411d63d6381148c88a21897bb9a2205d1 Mon Sep 17 00:00:00 2001 From: pagedown Date: Mon, 7 Mar 2022 12:39:49 +0800 Subject: [PATCH 7/7] ... --- shell-integration/bash/kitty.bash | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/shell-integration/bash/kitty.bash b/shell-integration/bash/kitty.bash index 4e4deb2a8..b50e48c25 100644 --- a/shell-integration/bash/kitty.bash +++ b/shell-integration/bash/kitty.bash @@ -155,17 +155,19 @@ _ksi_main() { fi if [[ "${_ksi_prompt[title]}" == "y" ]]; then - if [[ -n "$KITTY_PID" ]]; then - # kitty running locally - elif [[ -n "$SSH_TTY" || -n "$SSH2_TTY$KITTY_WINDOW_ID" ]]; then - # connected to most SSH servers - # or use ssh kitten to connected to some SSH servers that do not set SSH_TTY - _ksi_prompt[hostname_prefix]="\h: "; - elif [[ -n "$(builtin command -v who)" ]]; then - # the shell integration script is installed manually on the remote system - # the environment variables are cleared after sudo - # OpenSSH's sshd creates entries in utmp for every login so use those - [[ "$(builtin command who -m 2> /dev/null)" =~ "\([a-fA-F.:0-9]+\)$" ]] && _ksi_prompt[hostname_prefix]="\h: "; + if [[ -z "$KITTY_PID" ]]; then + if [[ -n "$SSH_TTY" || -n "$SSH2_TTY$KITTY_WINDOW_ID" ]]; then + # connected to most SSH servers + # or use ssh kitten to connected to some SSH servers that do not set SSH_TTY + _ksi_prompt[hostname_prefix]="\h: "; + else + if [[ -n "$(builtin command -v who)" && "$(builtin command who -m 2> /dev/null)" =~ "\([a-fA-F.:0-9]+\)$" ]]; then + # the shell integration script is installed manually on the remote system + # the environment variables are cleared after sudo + # OpenSSH's sshd creates entries in utmp for every login so use those + _ksi_prompt[hostname_prefix]="\h: "; + fi + fi fi # see https://www.gnu.org/software/bash/manual/html_node/Controlling-the-Prompt.html#Controlling-the-Prompt # we use suffix here because some distros add title setting to their bashrc files by default