Merge branch 'ksi' of https://github.com/page-down/kitty
This commit is contained in:
commit
d4d4e00f9d
@ -83,7 +83,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:
|
||||
|
||||
@ -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')
|
||||
|
||||
|
||||
@ -155,8 +155,19 @@ _ksi_main() {
|
||||
fi
|
||||
|
||||
if [[ "${_ksi_prompt[title]}" == "y" ]]; then
|
||||
if [[ -n "$SSH_TTY$SSH2_TTY" ]]; then
|
||||
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
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -107,14 +107,13 @@ 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
|
||||
@ -164,15 +163,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:
|
||||
@ -180,8 +170,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')
|
||||
@ -197,14 +187,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():
|
||||
|
||||
@ -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
|
||||
@ -95,17 +95,17 @@ 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")
|
||||
|
||||
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() {
|
||||
@ -203,43 +201,43 @@ 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);
|
||||
login_shell=$(echo $output | parse_passwd_record)
|
||||
if login_shell_is_ok; then return 0; fi
|
||||
fi
|
||||
fi
|
||||
return 1;
|
||||
return 1
|
||||
}
|
||||
|
||||
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);
|
||||
login_shell=$(echo $output | parse_passwd_record)
|
||||
if login_shell_is_ok; then return 0; fi
|
||||
fi
|
||||
fi
|
||||
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);
|
||||
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
|
||||
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)
|
||||
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,17 +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
|
||||
@ -290,7 +277,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"
|
||||
@ -308,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
|
||||
}
|
||||
|
||||
|
||||
@ -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}"
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user