feat: add SSH integration wrapper for shell integration

- Implements opt-in SSH wrapper following sudo pattern
- Supports term_only, basic, and full integration levels
- Fixes xterm-ghostty TERM compatibility on remote systems
- Propagates shell integration environment variables
- Allows for automatic installation of terminfo if desired
- Addresses GitHub discussions #5892 and #4156
This commit is contained in:
Jason Rayne
2025-06-13 16:11:46 -07:00
parent fa47db5363
commit 142e07c502
9 changed files with 496 additions and 372 deletions

View File

@@ -15,8 +15,10 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# We need to be in interactive mode to proceed.
if [[ "$-" != *i* ]] ; then builtin return; fi
# We need to be in interactive mode and we need to have the Ghostty
# resources dir set which also tells us we're running in Ghostty.
if [[ "$-" != *i* ]]; then builtin return; fi
if [ -z "$GHOSTTY_RESOURCES_DIR" ]; then builtin return; fi
# When automatic shell integration is active, we were started in POSIX
# mode and need to manually recreate the bash startup sequence.
@@ -43,7 +45,10 @@ if [ -n "$GHOSTTY_BASH_INJECT" ]; then
if [[ $__ghostty_bash_flags != *"--noprofile"* ]]; then
[ -r /etc/profile ] && builtin source "/etc/profile"
for __ghostty_rcfile in "$HOME/.bash_profile" "$HOME/.bash_login" "$HOME/.profile"; do
[ -r "$__ghostty_rcfile" ] && { builtin source "$__ghostty_rcfile"; break; }
[ -r "$__ghostty_rcfile" ] && {
builtin source "$__ghostty_rcfile"
break
}
done
fi
else
@@ -55,7 +60,10 @@ if [ -n "$GHOSTTY_BASH_INJECT" ]; then
# Void Linux uses /etc/bash/bashrc
# Nixos uses /etc/bashrc
for __ghostty_rcfile in /etc/bash.bashrc /etc/bash/bashrc /etc/bashrc; do
[ -r "$__ghostty_rcfile" ] && { builtin source "$__ghostty_rcfile"; break; }
[ -r "$__ghostty_rcfile" ] && {
builtin source "$__ghostty_rcfile"
break
}
done
if [[ -z "$GHOSTTY_BASH_RCFILE" ]]; then GHOSTTY_BASH_RCFILE="$HOME/.bashrc"; fi
[ -r "$GHOSTTY_BASH_RCFILE" ] && builtin source "$GHOSTTY_BASH_RCFILE"
@@ -88,15 +96,105 @@ if [[ "$GHOSTTY_SHELL_FEATURES" == *"sudo"* && -n "$TERMINFO" ]]; then
fi
done
if [[ "$sudo_has_sudoedit_flags" == "yes" ]]; then
builtin command sudo "$@";
builtin command sudo "$@"
else
builtin command sudo TERMINFO="$TERMINFO" "$@";
builtin command sudo TERMINFO="$TERMINFO" "$@"
fi
}
fi
if [[ -n "$GHOSTTY_SSH_INTEGRATION" && "$GHOSTTY_SSH_INTEGRATION" != "off" ]]; then
# Wrap `ssh` command to provide Ghostty SSH integration.
#
# This approach supports wrapping an `ssh` alias, but the alias definition
# must come _after_ this function is defined. Otherwise, the alias expansion
# will take precedence over this function, and it won't be wrapped.
function ssh {
case "$GHOSTTY_SSH_INTEGRATION" in
"term_only")
_ghostty_ssh_term_only "$@"
;;
"basic")
_ghostty_ssh_basic "$@"
;;
"full")
_ghostty_ssh_full "$@"
;;
*)
# Unknown level, fall back to basic
_ghostty_ssh_basic "$@"
;;
esac
}
# Level: term_only - Just fix TERM compatibility
_ghostty_ssh_term_only() {
if [[ "$TERM" == "xterm-ghostty" ]]; then
TERM=xterm-256color command ssh "$@"
else
command ssh "$@"
fi
}
# Level: basic - TERM fix + environment variable propagation
_ghostty_ssh_basic() {
local env_vars=()
# Fix TERM compatibility
if [[ "$TERM" == "xterm-ghostty" ]]; then
env_vars+=("TERM=xterm-256color")
fi
# Propagate Ghostty shell integration environment variables
[[ -n "$GHOSTTY_SHELL_FEATURES" ]] && env_vars+=("GHOSTTY_SHELL_FEATURES=$GHOSTTY_SHELL_FEATURES")
[[ -n "$GHOSTTY_RESOURCES_DIR" ]] && env_vars+=("GHOSTTY_RESOURCES_DIR=$GHOSTTY_RESOURCES_DIR")
# Execute with environment variables if any were set
if [[ ${#env_vars[@]} -gt 0 ]]; then
env "${env_vars[@]}" ssh "$@"
else
builtin command ssh "$@"
fi
}
# Level: full - All features
_ghostty_ssh_full() {
# Full integration: Two-step terminfo installation
if command -v infocmp >/dev/null 2>&1; then
echo "Installing Ghostty terminfo on remote host..." >&2
# Step 1: Install terminfo using the same approach that works manually
# This requires authentication but is quick and reliable
if infocmp -x xterm-ghostty 2>/dev/null | command ssh "$@" 'mkdir -p ~/.terminfo/x 2>/dev/null && tic -x -o ~/.terminfo /dev/stdin 2>/dev/null'; then
echo "Terminfo installed successfully. Connecting with full Ghostty support..." >&2
# Step 2: Connect with xterm-ghostty since we know terminfo is now available
local env_vars=()
# Use xterm-ghostty since we just installed it
env_vars+=("TERM=xterm-ghostty")
# Propagate Ghostty shell integration environment variables
[[ -n "$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR" ]] && env_vars+=("GHOSTTY_SHELL_INTEGRATION_NO_CURSOR=$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR")
[[ -n "$GHOSTTY_SHELL_INTEGRATION_NO_SUDO" ]] && env_vars+=("GHOSTTY_SHELL_INTEGRATION_NO_SUDO=$GHOSTTY_SHELL_INTEGRATION_NO_SUDO")
[[ -n "$GHOSTTY_SHELL_INTEGRATION_NO_TITLE" ]] && env_vars+=("GHOSTTY_SHELL_INTEGRATION_NO_TITLE=$GHOSTTY_SHELL_INTEGRATION_NO_TITLE")
# Normal SSH connection with Ghostty terminfo available
env "${env_vars[@]}" ssh "$@"
return 0
else
echo "Terminfo installation failed. Using basic integration." >&2
fi
fi
# Fallback to basic integration
_ghostty_ssh_basic "$@"
}
fi
# Import bash-preexec, safe to do multiple times
builtin source "$(dirname -- "${BASH_SOURCE[0]}")/bash-preexec.sh"
builtin source "$GHOSTTY_RESOURCES_DIR/shell-integration/bash/bash-preexec.sh"
# This is set to 1 when we're executing a command so that we don't
# send prompt marks multiple times.
@@ -104,68 +202,68 @@ _ghostty_executing=""
_ghostty_last_reported_cwd=""
function __ghostty_precmd() {
local ret="$?"
if test "$_ghostty_executing" != "0"; then
_GHOSTTY_SAVE_PS0="$PS0"
_GHOSTTY_SAVE_PS1="$PS1"
_GHOSTTY_SAVE_PS2="$PS2"
local ret="$?"
if test "$_ghostty_executing" != "0"; then
_GHOSTTY_SAVE_PS0="$PS0"
_GHOSTTY_SAVE_PS1="$PS1"
_GHOSTTY_SAVE_PS2="$PS2"
# Marks
PS1=$PS1'\[\e]133;B\a\]'
PS2=$PS2'\[\e]133;B\a\]'
# Marks
PS1=$PS1'\[\e]133;B\a\]'
PS2=$PS2'\[\e]133;B\a\]'
# bash doesn't redraw the leading lines in a multiline prompt so
# mark the last line as a secondary prompt (k=s) to prevent the
# preceding lines from being erased by ghostty after a resize.
if [[ "${PS1}" == *"\n"* || "${PS1}" == *$'\n'* ]]; then
PS1=$PS1'\[\e]133;A;k=s\a\]'
fi
# Cursor
if [[ "$GHOSTTY_SHELL_FEATURES" == *"cursor"* ]]; then
PS1=$PS1'\[\e[5 q\]'
PS0=$PS0'\[\e[0 q\]'
fi
# Title (working directory)
if [[ "$GHOSTTY_SHELL_FEATURES" == *"title"* ]]; then
PS1=$PS1'\[\e]2;\w\a\]'
fi
# bash doesn't redraw the leading lines in a multiline prompt so
# mark the last line as a secondary prompt (k=s) to prevent the
# preceding lines from being erased by ghostty after a resize.
if [[ "${PS1}" == *"\n"* || "${PS1}" == *$'\n'* ]]; then
PS1=$PS1'\[\e]133;A;k=s\a\]'
fi
if test "$_ghostty_executing" != ""; then
# End of current command. Report its status.
builtin printf "\e]133;D;%s;aid=%s\a" "$ret" "$BASHPID"
# Cursor
if [[ "$GHOSTTY_SHELL_FEATURES" == *"cursor"* ]]; then
PS1=$PS1'\[\e[5 q\]'
PS0=$PS0'\[\e[0 q\]'
fi
# unfortunately bash provides no hooks to detect cwd changes
# in particular this means cwd reporting will not happen for a
# command like cd /test && cat. PS0 is evaluated before cd is run.
if [[ "$_ghostty_last_reported_cwd" != "$PWD" ]]; then
_ghostty_last_reported_cwd="$PWD"
builtin printf "\e]7;kitty-shell-cwd://%s%s\a" "$HOSTNAME" "$PWD"
# Title (working directory)
if [[ "$GHOSTTY_SHELL_FEATURES" == *"title"* ]]; then
PS1=$PS1'\[\e]2;\w\a\]'
fi
fi
# Fresh line and start of prompt.
builtin printf "\e]133;A;aid=%s\a" "$BASHPID"
_ghostty_executing=0
if test "$_ghostty_executing" != ""; then
# End of current command. Report its status.
builtin printf "\e]133;D;%s;aid=%s\a" "$ret" "$BASHPID"
fi
# unfortunately bash provides no hooks to detect cwd changes
# in particular this means cwd reporting will not happen for a
# command like cd /test && cat. PS0 is evaluated before cd is run.
if [[ "$_ghostty_last_reported_cwd" != "$PWD" ]]; then
_ghostty_last_reported_cwd="$PWD"
builtin printf "\e]7;kitty-shell-cwd://%s%s\a" "$HOSTNAME" "$PWD"
fi
# Fresh line and start of prompt.
builtin printf "\e]133;A;aid=%s\a" "$BASHPID"
_ghostty_executing=0
}
function __ghostty_preexec() {
builtin local cmd="$1"
builtin local cmd="$1"
PS0="$_GHOSTTY_SAVE_PS0"
PS1="$_GHOSTTY_SAVE_PS1"
PS2="$_GHOSTTY_SAVE_PS2"
PS0="$_GHOSTTY_SAVE_PS0"
PS1="$_GHOSTTY_SAVE_PS1"
PS2="$_GHOSTTY_SAVE_PS2"
# Title (current command)
if [[ -n $cmd && "$GHOSTTY_SHELL_FEATURES" == *"title"* ]]; then
builtin printf "\e]2;%s\a" "${cmd//[[:cntrl:]]}"
fi
# Title (current command)
if [[ -n $cmd && "$GHOSTTY_SHELL_FEATURES" == *"title"* ]]; then
builtin printf "\e]2;%s\a" "${cmd//[[:cntrl:]]/}"
fi
# End of input, start of output.
builtin printf "\e]133;C;\a"
_ghostty_executing=1
# End of input, start of output.
builtin printf "\e]133;C;\a"
_ghostty_executing=1
}
preexec_functions+=(__ghostty_preexec)

View File

@@ -98,6 +98,107 @@
(external sudo) $@args
}
fn ssh-with-ghostty-integration {|@args|
if (and (has-env GHOSTTY_SSH_INTEGRATION) (not-eq "" $E:GHOSTTY_SSH_INTEGRATION) (not-eq "off" $E:GHOSTTY_SSH_INTEGRATION)) {
if (eq "term_only" $E:GHOSTTY_SSH_INTEGRATION) {
ssh-term-only $@args
} elif (eq "basic" $E:GHOSTTY_SSH_INTEGRATION) {
ssh-basic $@args
} elif (eq "full" $E:GHOSTTY_SSH_INTEGRATION) {
ssh-full $@args
} else {
# Unknown level, fall back to basic
ssh-basic $@args
}
} else {
(external ssh) $@args
}
}
fn ssh-term-only {|@args|
# Level: term_only - Just fix TERM compatibility
if (eq "xterm-ghostty" $E:TERM) {
TERM=xterm-256color (external ssh) $@args
} else {
(external ssh) $@args
}
}
fn ssh-basic {|@args|
# Level: basic - TERM fix + environment variable propagation
var env-vars = []
# Fix TERM compatibility
if (eq "xterm-ghostty" $E:TERM) {
set env-vars = [$@env-vars TERM=xterm-256color]
}
# Propagate Ghostty shell integration environment variables
if (has-env GHOSTTY_SHELL_FEATURES) {
if (not-eq "" $E:GHOSTTY_SHELL_FEATURES) {
set env-vars = [$@env-vars GHOSTTY_SHELL_FEATURES=$E:GHOSTTY_SHELL_FEATURES]
}
}
if (has-env GHOSTTY_RESOURCES_DIR) {
if (not-eq "" $E:GHOSTTY_RESOURCES_DIR) {
set env-vars = [$@env-vars GHOSTTY_RESOURCES_DIR=$E:GHOSTTY_RESOURCES_DIR]
}
}
# Execute with environment variables if any were set
if (> (count $env-vars) 0) {
(external env) $@env-vars ssh $@args
} else {
(external ssh) $@args
}
}
fn ghostty-ssh-full {|@args|
# Full integration: Two-step terminfo installation
if (has-external infocmp) {
echo "Installing Ghostty terminfo on remote host..." >&2
# Step 1: Install terminfo using the same approach that works manually
# This requires authentication but is quick and reliable
try {
infocmp -x xterm-ghostty 2>/dev/null | command ssh $@args 'mkdir -p ~/.terminfo/x 2>/dev/null && tic -x -o ~/.terminfo /dev/stdin 2>/dev/null'
echo "Terminfo installed successfully. Connecting with full Ghostty support..." >&2
# Step 2: Connect with xterm-ghostty since we know terminfo is now available
var env-vars = []
# Use xterm-ghostty since we just installed it
set env-vars = [$@env-vars TERM=xterm-ghostty]
# Propagate Ghostty shell integration environment variables
if (has-env GHOSTTY_SHELL_INTEGRATION_NO_CURSOR) {
set env-vars = [$@env-vars GHOSTTY_SHELL_INTEGRATION_NO_CURSOR=$E:GHOSTTY_SHELL_INTEGRATION_NO_CURSOR]
}
if (has-env GHOSTTY_SHELL_INTEGRATION_NO_SUDO) {
set env-vars = [$@env-vars GHOSTTY_SHELL_INTEGRATION_NO_SUDO=$E:GHOSTTY_SHELL_INTEGRATION_NO_SUDO]
}
if (has-env GHOSTTY_SHELL_INTEGRATION_NO_TITLE) {
set env-vars = [$@env-vars GHOSTTY_SHELL_INTEGRATION_NO_TITLE=$E:GHOSTTY_SHELL_INTEGRATION_NO_TITLE]
}
# Normal SSH connection with Ghostty terminfo available
env $@env-vars ssh $@args
return
} catch e {
echo "Terminfo installation failed. Using basic integration." >&2
}
}
# Fallback to basic integration
ghostty-ssh-basic $@args
}
# Register SSH integration if enabled
if (and (has-env GHOSTTY_SSH_INTEGRATION) (not-eq "" $E:GHOSTTY_SSH_INTEGRATION) (not-eq "off" $E:GHOSTTY_SSH_INTEGRATION) (has-external ssh)) {
edit:add-var ssh~ $ssh-with-ghostty-integration~
}
defer {
mark-prompt-start
report-pwd

View File

@@ -63,14 +63,14 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
# When using sudo shell integration feature, ensure $TERMINFO is set
# and `sudo` is not already a function or alias
if contains sudo $features; and test -n "$TERMINFO"; and test "file" = (type -t sudo 2> /dev/null; or echo "x")
if contains sudo $features; and test -n "$TERMINFO"; and test file = (type -t sudo 2> /dev/null; or echo "x")
# Wrap `sudo` command to ensure Ghostty terminfo is preserved
function sudo -d "Wrap sudo to preserve terminfo"
set --function sudo_has_sudoedit_flags "no"
set --function sudo_has_sudoedit_flags no
for arg in $argv
# Check if argument is '-e' or '--edit' (sudoedit flags)
if string match -q -- "-e" "$arg"; or string match -q -- "--edit" "$arg"
set --function sudo_has_sudoedit_flags "yes"
if string match -q -- -e "$arg"; or string match -q -- --edit "$arg"
set --function sudo_has_sudoedit_flags yes
break
end
# Check if argument is neither an option nor a key-value pair
@@ -78,7 +78,7 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
break
end
end
if test "$sudo_has_sudoedit_flags" = "yes"
if test "$sudo_has_sudoedit_flags" = yes
command sudo $argv
else
command sudo TERMINFO="$TERMINFO" $argv
@@ -86,6 +86,99 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
end
end
# SSH integration wrapper
if test -n "$GHOSTTY_SSH_INTEGRATION"; and test "$GHOSTTY_SSH_INTEGRATION" != off
function ssh -d "Wrap ssh to provide Ghostty SSH integration"
switch "$GHOSTTY_SSH_INTEGRATION"
case term_only
_ghostty_ssh_term_only $argv
case basic
_ghostty_ssh_basic $argv
case full
_ghostty_ssh_full $argv
case "*"
# Unknown level, fall back to basic
_ghostty_ssh_basic $argv
end
end
# Level: term_only - Just fix TERM compatibility
function _ghostty_ssh_term_only -d "SSH with TERM compatibility fix"
if test "$TERM" = xterm-ghostty
TERM=xterm-256color command ssh $argv
else
command ssh $argv
end
end
# Level: basic - TERM fix + environment variable propagation
function _ghostty_ssh_basic -d "SSH with TERM fix and environment propagation"
# Build environment variables to propagate
set --local env_vars
# Fix TERM compatibility
if test "$TERM" = xterm-ghostty
set env_vars $env_vars TERM=xterm-256color
end
# Propagate Ghostty shell integration environment variables
if test -n "$GHOSTTY_SHELL_FEATURES"
set env_vars $env_vars GHOSTTY_SHELL_FEATURES="$GHOSTTY_SHELL_FEATURES"
end
if test -n "$GHOSTTY_RESOURCES_DIR"
set env_vars $env_vars GHOSTTY_RESOURCES_DIR="$GHOSTTY_RESOURCES_DIR"
end
# Execute with environment variables if any were set
if test (count $env_vars) -gt 0
env $env_vars ssh $argv
else
command ssh $argv
end
end
# Level: full - All features
function _ghostty_ssh_full
# Full integration: Two-step terminfo installation
if command -v infocmp >/dev/null 2>&1
echo "Installing Ghostty terminfo on remote host..." >&2
# Step 1: Install terminfo using the same approach that works manually
# This requires authentication but is quick and reliable
if infocmp -x xterm-ghostty 2>/dev/null | command ssh $argv 'mkdir -p ~/.terminfo/x 2>/dev/null && tic -x -o ~/.terminfo /dev/stdin 2>/dev/null'
echo "Terminfo installed successfully. Connecting with full Ghostty support..." >&2
# Step 2: Connect with xterm-ghostty since we know terminfo is now available
set -l env_vars
# Use xterm-ghostty since we just installed it
set -a env_vars TERM=xterm-ghostty
# Propagate Ghostty shell integration environment variables
if set -q GHOSTTY_SHELL_INTEGRATION_NO_CURSOR
set -a env_vars GHOSTTY_SHELL_INTEGRATION_NO_CURSOR=$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR
end
if set -q GHOSTTY_SHELL_INTEGRATION_NO_SUDO
set -a env_vars GHOSTTY_SHELL_INTEGRATION_NO_SUDO=$GHOSTTY_SHELL_INTEGRATION_NO_SUDO
end
if set -q GHOSTTY_SHELL_INTEGRATION_NO_TITLE
set -a env_vars GHOSTTY_SHELL_INTEGRATION_NO_TITLE=$GHOSTTY_SHELL_INTEGRATION_NO_TITLE
end
# Normal SSH connection with Ghostty terminfo available
env $env_vars ssh $argv
return 0
else
echo "Terminfo installation failed. Using basic integration." >&2
end
end
# Fallback to basic integration
_ghostty_ssh_basic $argv
end
end
# Setup prompt marking
function __ghostty_mark_prompt_start --on-event fish_prompt --on-event fish_cancel --on-event fish_posterror
# If we never got the output end event, then we need to send it now.

View File

@@ -243,6 +243,87 @@ _ghostty_deferred_init() {
fi
}
fi
# SSH
if [[ -n "$GHOSTTY_SSH_INTEGRATION" && "$GHOSTTY_SSH_INTEGRATION" != "off" ]]; then
# Wrap `ssh` command to provide Ghostty SSH integration
ssh() {
case "$GHOSTTY_SSH_INTEGRATION" in
"term_only")
_ghostty_ssh_term_only "$@"
;;
"basic")
_ghostty_ssh_basic "$@"
;;
"full")
_ghostty_ssh_full "$@"
;;
*)
# Unknown level, fall back to basic
_ghostty_ssh_basic "$@"
;;
esac
}
# Level: term_only - Just fix TERM compatibility
_ghostty_ssh_term_only() {
if [[ "$TERM" == "xterm-ghostty" ]]; then
TERM=xterm-256color builtin command ssh "$@"
else
builtin command ssh "$@"
fi
}
# Level: basic - TERM fix + environment variable propagation
_ghostty_ssh_basic() {
# Fix TERM compatibility and propagate key environment variables
if [[ "$TERM" == "xterm-ghostty" ]]; then
TERM=xterm-256color \
GHOSTTY_SHELL_FEATURES="${GHOSTTY_SHELL_FEATURES}" \
GHOSTTY_RESOURCES_DIR="${GHOSTTY_RESOURCES_DIR}" \
builtin command ssh "$@"
else
GHOSTTY_SHELL_FEATURES="${GHOSTTY_SHELL_FEATURES}" \
GHOSTTY_RESOURCES_DIR="${GHOSTTY_RESOURCES_DIR}" \
builtin command ssh "$@"
fi
}
# Level: full - All features
_ghostty_ssh_full() {
# Full integration: Two-step terminfo installation
if command -v infocmp >/dev/null 2>&1; then
echo "Installing Ghostty terminfo on remote host..." >&2
# Step 1: Install terminfo using the same approach that works manually
# This requires authentication but is quick and reliable
if infocmp -x xterm-ghostty 2>/dev/null | command ssh "$@" 'mkdir -p ~/.terminfo/x 2>/dev/null && tic -x -o ~/.terminfo /dev/stdin 2>/dev/null'; then
echo "Terminfo installed successfully. Connecting with full Ghostty support..." >&2
# Step 2: Connect with xterm-ghostty since we know terminfo is now available
local env_vars=()
# Use xterm-ghostty since we just installed it
env_vars+=("TERM=xterm-ghostty")
# Propagate Ghostty shell integration environment variables
[[ -n "$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR" ]] && env_vars+=("GHOSTTY_SHELL_INTEGRATION_NO_CURSOR=$GHOSTTY_SHELL_INTEGRATION_NO_CURSOR")
[[ -n "$GHOSTTY_SHELL_INTEGRATION_NO_SUDO" ]] && env_vars+=("GHOSTTY_SHELL_INTEGRATION_NO_SUDO=$GHOSTTY_SHELL_INTEGRATION_NO_SUDO")
[[ -n "$GHOSTTY_SHELL_INTEGRATION_NO_TITLE" ]] && env_vars+=("GHOSTTY_SHELL_INTEGRATION_NO_TITLE=$GHOSTTY_SHELL_INTEGRATION_NO_TITLE")
# Normal SSH connection with Ghostty terminfo available
env "${env_vars[@]}" ssh "$@"
return 0
else
echo "Terminfo installation failed. Using basic integration." >&2
fi
fi
# Fallback to basic integration
_ghostty_ssh_basic "$@"
}
fi
# Some zsh users manually run `source ~/.zshrc` in order to apply rc file
# changes to the current shell. This is a terrible practice that breaks many