summaryrefslogtreecommitdiff
path: root/src/shell-integration
diff options
context:
space:
mode:
authorJason Rayne <yo@arcayne.dev>2025-07-05 13:02:35 -0700
committerJason Rayne <yo@arcayne.dev>2025-07-05 13:24:59 -0700
commita22074a85ca21ccae413e161766d6bf7f063c596 (patch)
tree59e9b1fe6325c423f90ca242dbf9c97464d23379 /src/shell-integration
parent5ec18f426c409273599d72a4b6f98055aff8e53b (diff)
fix: optimize SSH integration and improve error handling
- Replace dual-loop SSH config parsing with efficient single-pass case statement - Remove overly cautious timeout logic from cache checks for simplicity - Add base64 availability check with xterm-256color fallback when missing - Include hostname in terminfo setup messages for better UX - Maintain SendEnv/SetEnv dual approach for maximum OpenSSH compatibility (relying on SetEnv alone seems to drop some vars during my tests, despite them being explicitly included in AcceptEnv on the remote host)
Diffstat (limited to 'src/shell-integration')
-rw-r--r--src/shell-integration/bash/ghostty.bash195
-rw-r--r--src/shell-integration/elvish/lib/ghostty-integration.elv228
-rw-r--r--src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish190
-rw-r--r--src/shell-integration/zsh/ghostty-integration188
4 files changed, 380 insertions, 421 deletions
diff --git a/src/shell-integration/bash/ghostty.bash b/src/shell-integration/bash/ghostty.bash
index 8c4cd9e12..6016e9096 100644
--- a/src/shell-integration/bash/ghostty.bash
+++ b/src/shell-integration/bash/ghostty.bash
@@ -97,131 +97,116 @@ fi
# SSH Integration
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-(env|terminfo) ]]; then
- : "${GHOSTTY_SSH_CACHE_TIMEOUT:=5}"
- : "${GHOSTTY_SSH_CHECK_TIMEOUT:=3}"
-
- # SSH wrapper that preserves Ghostty features across remote connections
ssh() {
- local ssh_env=() ssh_opts=()
+ builtin local ssh_env ssh_opts ssh_exported_vars
+ ssh_env=()
+ ssh_opts=()
+ ssh_exported_vars=()
# Configure environment variables for remote session
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
- local -a ssh_env_vars=(
- "COLORTERM=truecolor"
- "TERM_PROGRAM=ghostty"
- )
- if [[ -n "$TERM_PROGRAM_VERSION" ]]; then
- ssh_env_vars+=("TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION")
- fi
+ ssh_opts+=(-o "SetEnv COLORTERM=truecolor")
- # Temporarily export variables for SSH transmission
- local -a ssh_exported_vars=()
- for ssh_v in "${ssh_env_vars[@]}"; do
- local ssh_var_name="${ssh_v%%=*}"
+ if [[ -n "${TERM_PROGRAM+x}" ]]; then
+ ssh_exported_vars+=("TERM_PROGRAM=${TERM_PROGRAM}")
+ else
+ ssh_exported_vars+=("TERM_PROGRAM")
+ fi
+ builtin export "TERM_PROGRAM=ghostty"
+ ssh_opts+=(-o "SendEnv TERM_PROGRAM")
- if [[ -n "${!ssh_var_name+x}" ]]; then
- ssh_exported_vars+=("$ssh_var_name=${!ssh_var_name}")
+ if [[ -n "$TERM_PROGRAM_VERSION" ]]; then
+ if [[ -n "${TERM_PROGRAM_VERSION+x}" ]]; then
+ ssh_exported_vars+=("TERM_PROGRAM_VERSION=${TERM_PROGRAM_VERSION}")
else
- ssh_exported_vars+=("$ssh_var_name")
+ ssh_exported_vars+=("TERM_PROGRAM_VERSION")
fi
+ ssh_opts+=(-o "SendEnv TERM_PROGRAM_VERSION")
+ fi
- builtin export "${ssh_v?}"
-
- # Use both SendEnv and SetEnv for maximum compatibility
- ssh_opts+=(-o "SendEnv $ssh_var_name")
- ssh_opts+=(-o "SetEnv $ssh_v")
- done
-
- ssh_env+=("${ssh_env_vars[@]}")
+ ssh_env+=(
+ "COLORTERM=truecolor"
+ "TERM_PROGRAM=ghostty"
+ )
+ if [[ -n "$TERM_PROGRAM_VERSION" ]]; then
+ ssh_env+=("TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION")
+ fi
fi
# Install terminfo on remote host if needed
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
builtin local ssh_config ssh_user ssh_hostname
ssh_config=$(builtin command ssh -G "$@" 2>/dev/null)
- ssh_user=$(echo "$ssh_config" | while IFS=' ' read -r ssh_key ssh_value; do
- [[ "$ssh_key" == "ssh_user" ]] && echo "$ssh_value" && break
- done)
- ssh_hostname=$(echo "$ssh_config" | while IFS=' ' read -r ssh_key ssh_value; do
- [[ "$ssh_key" == "hostname" ]] && echo "$ssh_value" && break
- done)
+
+ while IFS=' ' read -r ssh_key ssh_value; do
+ case "$ssh_key" in
+ user) ssh_user="$ssh_value" ;;
+ hostname) ssh_hostname="$ssh_value" ;;
+ esac
+ [[ -n "$ssh_user" && -n "$ssh_hostname" ]] && break
+ done <<< "$ssh_config"
+
ssh_target="${ssh_user}@${ssh_hostname}"
if [[ -n "$ssh_hostname" ]]; then
- # Detect timeout command (BSD compatibility)
- local ssh_timeout_cmd=""
- if command -v timeout >/dev/null 2>&1; then
- ssh_timeout_cmd="timeout"
- elif command -v gtimeout >/dev/null 2>&1; then
- ssh_timeout_cmd="gtimeout"
- fi
-
# Check if terminfo is already cached
- local ssh_cache_check_success=false
- if command -v ghostty >/dev/null 2>&1; then
- if [[ -n "$ssh_timeout_cmd" ]]; then
- $ssh_timeout_cmd "${GHOSTTY_SSH_CHECK_TIMEOUT}s" ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1 && ssh_cache_check_success=true
- else
- ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1 && ssh_cache_check_success=true
- fi
+ builtin local ssh_cache_check_success=false
+ if builtin command -v ghostty >/dev/null 2>&1; then
+ ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1 && ssh_cache_check_success=true
fi
if [[ "$ssh_cache_check_success" == "true" ]]; then
ssh_env+=(TERM=xterm-ghostty)
elif builtin command -v infocmp >/dev/null 2>&1; then
- builtin local ssh_terminfo
-
- # Generate terminfo data (BSD base64 compatibility)
- if base64 --help 2>&1 | grep -q GNU; then
- ssh_terminfo=$(infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 -w0 2>/dev/null)
+ if ! builtin command -v base64 >/dev/null 2>&1; then
+ builtin echo "Warning: base64 command not available for terminfo installation." >&2
+ ssh_env+=(TERM=xterm-256color)
else
- ssh_terminfo=$(infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 2>/dev/null | tr -d '\n')
- fi
-
- if [[ -n "$ssh_terminfo" ]]; then
- builtin echo "Setting up Ghostty terminfo on remote host..." >&2
- builtin local ssh_cpath_dir ssh_cpath
-
- ssh_cpath_dir=$(mktemp -d "/tmp/ghostty-ssh-$ssh_user.XXXXXX" 2>/dev/null) || ssh_cpath_dir="/tmp/ghostty-ssh-$ssh_user.$$"
- ssh_cpath="$ssh_cpath_dir/socket"
+ builtin local ssh_terminfo ssh_base64_decode_cmd
- local ssh_base64_decode_cmd
+ # BSD vs GNU base64 compatibility
if base64 --help 2>&1 | grep -q GNU; then
ssh_base64_decode_cmd="base64 -d"
+ ssh_terminfo=$(infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 -w0 2>/dev/null)
else
ssh_base64_decode_cmd="base64 -D"
+ ssh_terminfo=$(infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 2>/dev/null | tr -d '\n')
fi
- if builtin echo "$ssh_terminfo" | $ssh_base64_decode_cmd | builtin command ssh "${ssh_opts[@]}" -o ControlMaster=yes -o ControlPath="$ssh_cpath" -o ControlPersist=60s "$@" '
- infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
- command -v tic >/dev/null 2>&1 || exit 1
- mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
- exit 1
- ' 2>/dev/null; then
- builtin echo "Terminfo setup complete." >&2
- ssh_env+=(TERM=xterm-ghostty)
- ssh_opts+=(-o "ControlPath=$ssh_cpath")
-
- # Cache successful installation
- if [[ -n "$ssh_target" ]] && command -v ghostty >/dev/null 2>&1; then
- (
- set +m
- {
- if [[ -n "$ssh_timeout_cmd" ]]; then
- $ssh_timeout_cmd "${GHOSTTY_SSH_CACHE_TIMEOUT}s" ghostty +ssh-cache --add="$ssh_target" >/dev/null 2>&1 || true
- else
+ if [[ -n "$ssh_terminfo" ]]; then
+ builtin echo "Setting up Ghostty terminfo on $ssh_hostname..." >&2
+ builtin local ssh_cpath_dir ssh_cpath
+
+ ssh_cpath_dir=$(mktemp -d "/tmp/ghostty-ssh-$ssh_user.XXXXXX" 2>/dev/null) || ssh_cpath_dir="/tmp/ghostty-ssh-$ssh_user.$$"
+ ssh_cpath="$ssh_cpath_dir/socket"
+
+ if builtin echo "$ssh_terminfo" | $ssh_base64_decode_cmd | builtin command ssh "${ssh_opts[@]}" -o ControlMaster=yes -o ControlPath="$ssh_cpath" -o ControlPersist=60s "$@" '
+ infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
+ command -v tic >/dev/null 2>&1 || exit 1
+ mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
+ exit 1
+ ' 2>/dev/null; then
+ builtin echo "Terminfo setup complete on $ssh_hostname." >&2
+ ssh_env+=(TERM=xterm-ghostty)
+ ssh_opts+=(-o "ControlPath=$ssh_cpath")
+
+ # Cache successful installation
+ if [[ -n "$ssh_target" ]] && builtin command -v ghostty >/dev/null 2>&1; then
+ (
+ set +m
+ {
ghostty +ssh-cache --add="$ssh_target" >/dev/null 2>&1 || true
- fi
- } &
- )
+ } &
+ )
+ fi
+ else
+ builtin echo "Warning: Failed to install terminfo." >&2
+ ssh_env+=(TERM=xterm-256color)
fi
else
- builtin echo "Warning: Failed to install terminfo." >&2
+ builtin echo "Warning: Could not generate terminfo data." >&2
ssh_env+=(TERM=xterm-256color)
fi
- else
- builtin echo "Warning: Could not generate terminfo data." >&2
- ssh_env+=(TERM=xterm-256color)
fi
else
builtin echo "Warning: ghostty command not available for cache management." >&2
@@ -234,22 +219,30 @@ if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-(env|terminfo) ]]; then
fi
fi
- # Ensure TERM is set when using ssh-env feature
- if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
- local ssh_term_set=false
- for ssh_v in "${ssh_env[@]}"; do
- if [[ "$ssh_v" =~ ^TERM= ]]; then
- ssh_term_set=true
- break
- fi
- done
- if [[ "$ssh_term_set" == "false" && "$TERM" == "xterm-ghostty" ]]; then
- ssh_env+=(TERM=xterm-256color)
+ # Execute SSH with environment handling
+ builtin local ssh_term_override=""
+ for ssh_v in "${ssh_env[@]}"; do
+ if [[ "$ssh_v" =~ ^TERM=(.*)$ ]]; then
+ ssh_term_override="${BASH_REMATCH[1]}"
+ break
fi
+ done
+
+ if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env && -z "$ssh_term_override" ]]; then
+ ssh_env+=(TERM=xterm-256color)
+ ssh_term_override="xterm-256color"
fi
- builtin command ssh "${ssh_opts[@]}" "$@"
- local ssh_ret=$?
+ if [[ -n "$ssh_term_override" ]]; then
+ builtin local ssh_original_term="$TERM"
+ builtin export TERM="$ssh_term_override"
+ builtin command ssh "${ssh_opts[@]}" "$@"
+ local ssh_ret=$?
+ builtin export TERM="$ssh_original_term"
+ else
+ builtin command ssh "${ssh_opts[@]}" "$@"
+ local ssh_ret=$?
+ fi
# Restore original environment variables
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
diff --git a/src/shell-integration/elvish/lib/ghostty-integration.elv b/src/shell-integration/elvish/lib/ghostty-integration.elv
index 76fa7bafa..52d01e4fb 100644
--- a/src/shell-integration/elvish/lib/ghostty-integration.elv
+++ b/src/shell-integration/elvish/lib/ghostty-integration.elv
@@ -100,50 +100,41 @@
# SSH Integration
use str
- use re
if (or (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-env) (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-terminfo)) {
- var GHOSTTY_SSH_CACHE_TIMEOUT = (if (has-env GHOSTTY_SSH_CACHE_TIMEOUT) { echo $E:GHOSTTY_SSH_CACHE_TIMEOUT } else { echo 5 })
- var GHOSTTY_SSH_CHECK_TIMEOUT = (if (has-env GHOSTTY_SSH_CHECK_TIMEOUT) { echo $E:GHOSTTY_SSH_CHECK_TIMEOUT } else { echo 3 })
-
- # SSH wrapper that preserves Ghostty features across remote connections
fn ssh {|@args|
var ssh-env = []
var ssh-opts = []
+ var ssh-exported-vars = []
# Configure environment variables for remote session
if (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-env) {
- var ssh-env-vars = [
- COLORTERM=truecolor
- TERM_PROGRAM=ghostty
- ]
+ set ssh-opts = [$@ssh-opts -o "SetEnv COLORTERM=truecolor"]
- if (has-env TERM_PROGRAM_VERSION) {
- set ssh-env-vars = [$@ssh-env-vars TERM_PROGRAM_VERSION=$E:TERM_PROGRAM_VERSION]
+ if (has-env TERM_PROGRAM) {
+ set ssh-exported-vars = [$@ssh-exported-vars "TERM_PROGRAM="$E:TERM_PROGRAM]
+ } else {
+ set ssh-exported-vars = [$@ssh-exported-vars "TERM_PROGRAM"]
}
+ set-env TERM_PROGRAM ghostty
+ set ssh-opts = [$@ssh-opts -o "SendEnv TERM_PROGRAM"]
- # Store original values for restoration
- var ssh-exported-vars = []
- for ssh-v $ssh-env-vars {
- var ssh-var-name = (str:split &max=2 = $ssh-v)[0]
-
- if (has-env $ssh-var-name) {
- var original-value = (get-env $ssh-var-name)
- set ssh-exported-vars = [$@ssh-exported-vars $ssh-var-name=$original-value]
+ if (has-env TERM_PROGRAM_VERSION) {
+ if (has-env TERM_PROGRAM_VERSION) {
+ set ssh-exported-vars = [$@ssh-exported-vars "TERM_PROGRAM_VERSION="$E:TERM_PROGRAM_VERSION]
} else {
- set ssh-exported-vars = [$@ssh-exported-vars $ssh-var-name]
+ set ssh-exported-vars = [$@ssh-exported-vars "TERM_PROGRAM_VERSION"]
}
-
- # Export the variable
- var ssh-var-parts = (str:split &max=2 = $ssh-v)
- set-env $ssh-var-parts[0] $ssh-var-parts[1]
-
- # Use both SendEnv and SetEnv for maximum compatibility
- set ssh-opts = [$@ssh-opts -o "SendEnv "$ssh-var-name]
- set ssh-opts = [$@ssh-opts -o "SetEnv "$ssh-v]
+ set ssh-opts = [$@ssh-opts -o "SendEnv TERM_PROGRAM_VERSION"]
}
- set ssh-env = [$@ssh-env $@ssh-env-vars]
+ set ssh-env = [
+ "COLORTERM=truecolor"
+ "TERM_PROGRAM=ghostty"
+ ]
+ if (has-env TERM_PROGRAM_VERSION) {
+ set ssh-env = [$@ssh-env "TERM_PROGRAM_VERSION="$E:TERM_PROGRAM_VERSION]
+ }
}
# Install terminfo on remote host if needed
@@ -160,52 +151,28 @@
for line (str:split "\n" $ssh-config) {
var parts = (str:split " " $line)
- if (and (> (count $parts) 1) (eq $parts[0] user)) {
- set ssh-user = $parts[1]
- }
- if (and (> (count $parts) 1) (eq $parts[0] hostname)) {
- set ssh-hostname = $parts[1]
+ if (> (count $parts) 1) {
+ if (eq $parts[0] user) {
+ set ssh-user = $parts[1]
+ } elif (eq $parts[0] hostname) {
+ set ssh-hostname = $parts[1]
+ }
+ if (and (not-eq $ssh-user "") (not-eq $ssh-hostname "")) {
+ break
+ }
}
}
-
+
var ssh-target = $ssh-user"@"$ssh-hostname
if (not-eq $ssh-hostname "") {
- # Detect timeout command (BSD compatibility)
- var ssh-timeout-cmd = ""
- try {
- external timeout --help >/dev/null 2>&1
- set ssh-timeout-cmd = timeout
- } catch {
- try {
- external gtimeout --help >/dev/null 2>&1
- set ssh-timeout-cmd = gtimeout
- } catch {
- # no timeout command available
- }
- }
-
# Check if terminfo is already cached
var ssh-cache-check-success = $false
try {
- external ghostty --help >/dev/null 2>&1
- if (not-eq $ssh-timeout-cmd "") {
- try {
- external $ssh-timeout-cmd $GHOSTTY_SSH_CHECK_TIMEOUT"s" ghostty +ssh-cache --host=$ssh-target >/dev/null 2>&1
- set ssh-cache-check-success = $true
- } catch {
- # cache check failed
- }
- } else {
- try {
- external ghostty +ssh-cache --host=$ssh-target >/dev/null 2>&1
- set ssh-cache-check-success = $true
- } catch {
- # cache check failed
- }
- }
+ external ghostty +ssh-cache --host=$ssh-target >/dev/null 2>&1
+ set ssh-cache-check-success = $true
} catch {
- # ghostty not available
+ # cache check failed
}
if $ssh-cache-check-success {
@@ -213,74 +180,68 @@
} else {
try {
external infocmp --help >/dev/null 2>&1
-
- # Generate terminfo data (BSD base64 compatibility)
- var ssh-terminfo = ""
- try {
- var base64-help = (external base64 --help 2>&1 | slurp)
- if (str:contains $base64-help GNU) {
- set ssh-terminfo = (external infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | external base64 -w0 2>/dev/null | slurp)
- } else {
- set ssh-terminfo = (external infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | external base64 2>/dev/null | external tr -d '\n' | slurp)
- }
- } catch {
- set ssh-terminfo = ""
- }
- if (not-eq $ssh-terminfo "") {
- echo "Setting up Ghostty terminfo on remote host..." >&2
- var ssh-cpath-dir = ""
- try {
- set ssh-cpath-dir = (external mktemp -d "/tmp/ghostty-ssh-"$ssh-user".XXXXXX" 2>/dev/null | slurp)
- } catch {
- set ssh-cpath-dir = "/tmp/ghostty-ssh-"$ssh-user"."(randint 10000 99999)
- }
- var ssh-cpath = $ssh-cpath-dir"/socket"
+ try {
+ external base64 --help >/dev/null 2>&1
+ # Generate terminfo data (BSD base64 compatibility)
+ var ssh-terminfo = ""
var ssh-base64-decode-cmd = ""
try {
var base64-help = (external base64 --help 2>&1 | slurp)
if (str:contains $base64-help GNU) {
set ssh-base64-decode-cmd = "base64 -d"
+ set ssh-terminfo = (external infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | external base64 -w0 2>/dev/null | slurp)
} else {
set ssh-base64-decode-cmd = "base64 -D"
+ set ssh-terminfo = (external infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | external base64 2>/dev/null | external tr -d '\n' | slurp)
}
} catch {
- set ssh-base64-decode-cmd = "base64 -d"
+ set ssh-terminfo = ""
}
- var terminfo-install-success = $false
- try {
- echo $ssh-terminfo | external sh -c $ssh-base64-decode-cmd | external ssh $@ssh-opts -o ControlMaster=yes -o ControlPath=$ssh-cpath -o ControlPersist=60s $@args '
- infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
- command -v tic >/dev/null 2>&1 || exit 1
- mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
- exit 1
- ' >/dev/null 2>&1
- set terminfo-install-success = $true
- } catch {
- set terminfo-install-success = $false
- }
+ if (not-eq $ssh-terminfo "") {
+ echo "Setting up Ghostty terminfo on "$ssh-hostname"..." >&2
+ var ssh-cpath-dir = ""
+ try {
+ set ssh-cpath-dir = (external mktemp -d "/tmp/ghostty-ssh-"$ssh-user".XXXXXX" 2>/dev/null | slurp)
+ } catch {
+ set ssh-cpath-dir = "/tmp/ghostty-ssh-"$ssh-user"."(randint 10000 99999)
+ }
+ var ssh-cpath = $ssh-cpath-dir"/socket"
+
+ var terminfo-install-success = $false
+ try {
+ echo $ssh-terminfo | external sh -c $ssh-base64-decode-cmd | external ssh $@ssh-opts -o ControlMaster=yes -o ControlPath=$ssh-cpath -o ControlPersist=60s $@args '
+ infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
+ command -v tic >/dev/null 2>&1 || exit 1
+ mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
+ exit 1
+ ' >/dev/null 2>&1
+ set terminfo-install-success = $true
+ } catch {
+ set terminfo-install-success = $false
+ }
- if $terminfo-install-success {
- echo "Terminfo setup complete." >&2
- set ssh-env = [$@ssh-env TERM=xterm-ghostty]
- set ssh-opts = [$@ssh-opts -o ControlPath=$ssh-cpath]
+ if $terminfo-install-success {
+ echo "Terminfo setup complete on "$ssh-hostname"." >&2
+ set ssh-env = [$@ssh-env TERM=xterm-ghostty]
+ set ssh-opts = [$@ssh-opts -o ControlPath=$ssh-cpath]
- # Cache successful installation
- if (and (not-eq $ssh-target "") (has-external ghostty)) {
- if (not-eq $ssh-timeout-cmd "") {
- external $ssh-timeout-cmd $GHOSTTY_SSH_CACHE_TIMEOUT"s" ghostty +ssh-cache --add=$ssh-target >/dev/null 2>&1 &
- } else {
+ # Cache successful installation
+ if (and (not-eq $ssh-target "") (has-external ghostty)) {
external ghostty +ssh-cache --add=$ssh-target >/dev/null 2>&1 &
}
+ } else {
+ echo "Warning: Failed to install terminfo." >&2
+ set ssh-env = [$@ssh-env TERM=xterm-256color]
}
} else {
- echo "Warning: Failed to install terminfo." >&2
+ echo "Warning: Could not generate terminfo data." >&2
set ssh-env = [$@ssh-env TERM=xterm-256color]
}
- } else {
- echo "Warning: Could not generate terminfo data." >&2
+ } catch {
+ echo "Warning: base64 command not available for terminfo installation." >&2
set ssh-env = [$@ssh-env TERM=xterm-256color]
}
} catch {
@@ -295,25 +256,36 @@
}
}
- # Ensure TERM is set when using ssh-env feature
- if (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-env) {
- var ssh-term-set = $false
- for ssh-v $ssh-env {
- if (str:has-prefix $ssh-v TERM=) {
- set ssh-term-set = $true
- break
- }
- }
- if (and (not $ssh-term-set) (eq $E:TERM xterm-ghostty)) {
- set ssh-env = [$@ssh-env TERM=xterm-256color]
+ # Execute SSH with environment handling
+ var ssh-term-override = ""
+ for ssh-v $ssh-env {
+ if (str:has-prefix $ssh-v TERM=) {
+ set ssh-term-override = (str:trim-prefix $ssh-v TERM=)
+ break
}
}
+ if (and (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-env) (eq $ssh-term-override "")) {
+ set ssh-env = [$@ssh-env TERM=xterm-256color]
+ set ssh-term-override = xterm-256color
+ }
+
var ssh-ret = 0
- try {
- external ssh $@ssh-opts $@args
- } catch e {
- set ssh-ret = $e[reason][exit-status]
+ if (not-eq $ssh-term-override "") {
+ var ssh-original-term = $E:TERM
+ set-env TERM $ssh-term-override
+ try {
+ external ssh $@ssh-opts $@args
+ } catch e {
+ set ssh-ret = $e[reason][exit-status]
+ }
+ set-env TERM $ssh-original-term
+ } else {
+ try {
+ external ssh $@ssh-opts $@args
+ } catch e {
+ set ssh-ret = $e[reason][exit-status]
+ }
}
# Restore original environment variables
diff --git a/src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish b/src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish
index 7dc121919..332675264 100644
--- a/src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish
+++ b/src/shell-integration/fish/vendor_conf.d/ghostty-shell-integration.fish
@@ -86,132 +86,119 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
end
end
- # SSH Integration for Fish Shell
+ # SSH Integration
if string match -q '*ssh-env*' -- "$GHOSTTY_SHELL_FEATURES"; or string match -q '*ssh-terminfo*' -- "$GHOSTTY_SHELL_FEATURES"
- set -g GHOSTTY_SSH_CACHE_TIMEOUT (test -n "$GHOSTTY_SSH_CACHE_TIMEOUT"; and echo $GHOSTTY_SSH_CACHE_TIMEOUT; or echo 5)
- set -g GHOSTTY_SSH_CHECK_TIMEOUT (test -n "$GHOSTTY_SSH_CHECK_TIMEOUT"; and echo $GHOSTTY_SSH_CHECK_TIMEOUT; or echo 3)
-
- # SSH wrapper that preserves Ghostty features across remote connections
function ssh --wraps=ssh --description "SSH wrapper with Ghostty integration"
set -l ssh_env
set -l ssh_opts
+ set -l ssh_exported_vars
# Configure environment variables for remote session
if string match -q '*ssh-env*' -- "$GHOSTTY_SHELL_FEATURES"
- set -l ssh_env_vars \
- "COLORTERM=truecolor" \
- "TERM_PROGRAM=ghostty"
-
- if test -n "$TERM_PROGRAM_VERSION"
- set -a ssh_env_vars "TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION"
+ set -a ssh_opts -o "SetEnv COLORTERM=truecolor"
+
+ if set -q TERM_PROGRAM
+ set -a ssh_exported_vars "TERM_PROGRAM=$TERM_PROGRAM"
+ else
+ set -a ssh_exported_vars "TERM_PROGRAM"
end
+ set -gx TERM_PROGRAM ghostty
+ set -a ssh_opts -o "SendEnv TERM_PROGRAM"
- # Store original values for restoration
- set -l ssh_exported_vars
- for ssh_v in $ssh_env_vars
- set -l ssh_var_name (string split -m1 '=' -- $ssh_v)[1]
-
- if set -q $ssh_var_name
- set -a ssh_exported_vars "$ssh_var_name="(eval echo \$$ssh_var_name)
+ if test -n "$TERM_PROGRAM_VERSION"
+ if set -q TERM_PROGRAM_VERSION
+ set -a ssh_exported_vars "TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION"
else
- set -a ssh_exported_vars $ssh_var_name
+ set -a ssh_exported_vars "TERM_PROGRAM_VERSION"
end
-
- # Export the variable
- set -gx (string split -m1 '=' -- $ssh_v)
-
- # Use both SendEnv and SetEnv for maximum compatibility
- set -a ssh_opts -o "SendEnv $ssh_var_name"
- set -a ssh_opts -o "SetEnv $ssh_v"
+ set -a ssh_opts -o "SendEnv TERM_PROGRAM_VERSION"
end
- set -a ssh_env $ssh_env_vars
+ set -a ssh_env "COLORTERM=truecolor"
+ set -a ssh_env "TERM_PROGRAM=ghostty"
+ if test -n "$TERM_PROGRAM_VERSION"
+ set -a ssh_env "TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION"
+ end
end
# Install terminfo on remote host if needed
if string match -q '*ssh-terminfo*' -- "$GHOSTTY_SHELL_FEATURES"
set -l ssh_config (command ssh -G $argv 2>/dev/null)
- set -l ssh_user (echo $ssh_config | while read -l ssh_key ssh_value
- test "$ssh_key" = "user"; and echo $ssh_value; and break
- end)
- set -l ssh_hostname (echo $ssh_config | while read -l ssh_key ssh_value
- test "$ssh_key" = "hostname"; and echo $ssh_value; and break
- end)
+ set -l ssh_user
+ set -l ssh_hostname
+
+ for line in $ssh_config
+ set -l parts (string split ' ' -- $line)
+ if test (count $parts) -ge 2
+ switch $parts[1]
+ case user
+ set ssh_user $parts[2]
+ case hostname
+ set ssh_hostname $parts[2]
+ end
+ if test -n "$ssh_user"; and test -n "$ssh_hostname"
+ break
+ end
+ end
+ end
+
set -l ssh_target "$ssh_user@$ssh_hostname"
if test -n "$ssh_hostname"
- # Detect timeout command (BSD compatibility)
- set -l ssh_timeout_cmd
- if command -v timeout >/dev/null 2>&1
- set ssh_timeout_cmd timeout
- else if command -v gtimeout >/dev/null 2>&1
- set ssh_timeout_cmd gtimeout
- end
-
# Check if terminfo is already cached
set -l ssh_cache_check_success false
if command -v ghostty >/dev/null 2>&1
- if test -n "$ssh_timeout_cmd"
- if $ssh_timeout_cmd "$GHOSTTY_SSH_CHECK_TIMEOUT"s ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1
- set ssh_cache_check_success true
- end
- else
- if ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1
- set ssh_cache_check_success true
- end
+ if ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1
+ set ssh_cache_check_success true
end
end
if test "$ssh_cache_check_success" = "true"
set -a ssh_env TERM=xterm-ghostty
else if command -v infocmp >/dev/null 2>&1
- # Generate terminfo data (BSD base64 compatibility)
- set -l ssh_terminfo
- if base64 --help 2>&1 | grep -q GNU
- set ssh_terminfo (infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 -w0 2>/dev/null)
+ if not command -v base64 >/dev/null 2>&1
+ echo "Warning: base64 command not available for terminfo installation." >&2
+ set -a ssh_env TERM=xterm-256color
else
- set ssh_terminfo (infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 2>/dev/null | tr -d '\n')
- end
-
- if test -n "$ssh_terminfo"
- echo "Setting up Ghostty terminfo on remote host..." >&2
- set -l ssh_cpath_dir (mktemp -d "/tmp/ghostty-ssh-$ssh_user.XXXXXX" 2>/dev/null; or echo "/tmp/ghostty-ssh-$ssh_user."(random))
- set -l ssh_cpath "$ssh_cpath_dir/socket"
-
+ set -l ssh_terminfo
set -l ssh_base64_decode_cmd
+
+ # BSD vs GNU base64 compatibility
if base64 --help 2>&1 | grep -q GNU
set ssh_base64_decode_cmd "base64 -d"
+ set ssh_terminfo (infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 -w0 2>/dev/null)
else
set ssh_base64_decode_cmd "base64 -D"
+ set ssh_terminfo (infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 2>/dev/null | tr -d '\n')
end
- if echo "$ssh_terminfo" | eval $ssh_base64_decode_cmd | command ssh $ssh_opts -o ControlMaster=yes -o ControlPath="$ssh_cpath" -o ControlPersist=60s $argv '
- infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
- command -v tic >/dev/null 2>&1 || exit 1
- mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
- exit 1
- ' 2>/dev/null
- echo "Terminfo setup complete." >&2
- set -a ssh_env TERM=xterm-ghostty
- set -a ssh_opts -o "ControlPath=$ssh_cpath"
-
- # Cache successful installation
- if test -n "$ssh_target"; and command -v ghostty >/dev/null 2>&1
- fish -c "
- if test -n '$ssh_timeout_cmd'
- $ssh_timeout_cmd '$GHOSTTY_SSH_CACHE_TIMEOUT's ghostty +ssh-cache --add='$ssh_target' >/dev/null 2>&1; or true
- else
- ghostty +ssh-cache --add='$ssh_target' >/dev/null 2>&1; or true
- end
- " &
+ if test -n "$ssh_terminfo"
+ echo "Setting up Ghostty terminfo on $ssh_hostname..." >&2
+ set -l ssh_cpath_dir (mktemp -d "/tmp/ghostty-ssh-$ssh_user.XXXXXX" 2>/dev/null; or echo "/tmp/ghostty-ssh-$ssh_user."(random))
+ set -l ssh_cpath "$ssh_cpath_dir/socket"
+
+ if echo "$ssh_terminfo" | eval $ssh_base64_decode_cmd | command ssh $ssh_opts -o ControlMaster=yes -o ControlPath="$ssh_cpath" -o ControlPersist=60s $argv '
+ infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
+ command -v tic >/dev/null 2>&1 || exit 1
+ mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
+ exit 1
+ ' 2>/dev/null
+ echo "Terminfo setup complete on $ssh_hostname." >&2
+ set -a ssh_env TERM=xterm-ghostty
+ set -a ssh_opts -o "ControlPath=$ssh_cpath"
+
+ # Cache successful installation
+ if test -n "$ssh_target"; and command -v ghostty >/dev/null 2>&1
+ fish -c "ghostty +ssh-cache --add='$ssh_target' >/dev/null 2>&1; or true" &
+ end
+ else
+ echo "Warning: Failed to install terminfo." >&2
+ set -a ssh_env TERM=xterm-256color
end
else
- echo "Warning: Failed to install terminfo." >&2
+ echo "Warning: Could not generate terminfo data." >&2
set -a ssh_env TERM=xterm-256color
end
- else
- echo "Warning: Could not generate terminfo data." >&2
- set -a ssh_env TERM=xterm-256color
end
else
echo "Warning: ghostty command not available for cache management." >&2
@@ -224,22 +211,31 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
end
end
- # Ensure TERM is set when using ssh-env feature
- if string match -q '*ssh-env*' -- "$GHOSTTY_SHELL_FEATURES"
- set -l ssh_term_set false
- for ssh_v in $ssh_env
- if string match -q 'TERM=*' -- $ssh_v
- set ssh_term_set true
- break
- end
- end
- if test "$ssh_term_set" = "false"; and test "$TERM" = "xterm-ghostty"
- set -a ssh_env TERM=xterm-256color
+ # Execute SSH with environment handling
+ set -l ssh_term_override
+ for ssh_v in $ssh_env
+ if string match -q 'TERM=*' -- $ssh_v
+ set ssh_term_override (string replace 'TERM=' '' -- $ssh_v)
+ break
end
end
- command ssh $ssh_opts $argv
- set -l ssh_ret $status
+ if string match -q '*ssh-env*' -- "$GHOSTTY_SHELL_FEATURES"; and test -z "$ssh_term_override"
+ set -a ssh_env TERM=xterm-256color
+ set ssh_term_override xterm-256color
+ end
+
+ set -l ssh_ret
+ if test -n "$ssh_term_override"
+ set -l ssh_original_term "$TERM"
+ set -gx TERM "$ssh_term_override"
+ command ssh $ssh_opts $argv
+ set ssh_ret $status
+ set -gx TERM "$ssh_original_term"
+ else
+ command ssh $ssh_opts $argv
+ set ssh_ret $status
+ end
# Restore original environment variables
if string match -q '*ssh-env*' -- "$GHOSTTY_SHELL_FEATURES"
diff --git a/src/shell-integration/zsh/ghostty-integration b/src/shell-integration/zsh/ghostty-integration
index 9f78e9a89..40ee58b49 100644
--- a/src/shell-integration/zsh/ghostty-integration
+++ b/src/shell-integration/zsh/ghostty-integration
@@ -244,132 +244,116 @@ _ghostty_deferred_init() {
}
fi
- # SSH Integration
+# SSH Integration
if [[ "$GHOSTTY_SHELL_FEATURES" =~ (ssh-env|ssh-terminfo) ]]; then
- : "${GHOSTTY_SSH_CACHE_TIMEOUT:=5}"
- : "${GHOSTTY_SSH_CHECK_TIMEOUT:=3}"
-
- # SSH wrapper that preserves Ghostty features across remote connections
ssh() {
emulate -L zsh
setopt local_options no_glob_subst
-
- local -a ssh_env ssh_opts
+
+ local ssh_env ssh_opts ssh_exported_vars
+ ssh_env=()
+ ssh_opts=()
+ ssh_exported_vars=()
# Configure environment variables for remote session
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
- local -a ssh_env_vars=(
- "COLORTERM=truecolor"
- "TERM_PROGRAM=ghostty"
- )
- [[ -n "$TERM_PROGRAM_VERSION" ]] && ssh_env_vars+=("TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION")
+ ssh_opts+=(-o "SetEnv COLORTERM=truecolor")
- # Temporarily export variables for SSH transmission
- local -a ssh_exported_vars=()
- local ssh_v ssh_var_name
- for ssh_v in "${ssh_env_vars[@]}"; do
- ssh_var_name="${ssh_v%%=*}"
+ if [[ -n "${TERM_PROGRAM+x}" ]]; then
+ ssh_exported_vars+=("TERM_PROGRAM=${TERM_PROGRAM}")
+ else
+ ssh_exported_vars+=("TERM_PROGRAM")
+ fi
+ export "TERM_PROGRAM=ghostty"
+ ssh_opts+=(-o "SendEnv TERM_PROGRAM")
- if [[ -n "${(P)ssh_var_name+x}" ]]; then
- ssh_exported_vars+=("$ssh_var_name=${(P)ssh_var_name}")
+ if [[ -n "$TERM_PROGRAM_VERSION" ]]; then
+ if [[ -n "${TERM_PROGRAM_VERSION+x}" ]]; then
+ ssh_exported_vars+=("TERM_PROGRAM_VERSION=${TERM_PROGRAM_VERSION}")
else
- ssh_exported_vars+=("$ssh_var_name")
+ ssh_exported_vars+=("TERM_PROGRAM_VERSION")
fi
+ ssh_opts+=(-o "SendEnv TERM_PROGRAM_VERSION")
+ fi
- export "${ssh_v}"
-
- # Use both SendEnv and SetEnv for maximum compatibility
- ssh_opts+=(-o "SendEnv $ssh_var_name")
- ssh_opts+=(-o "SetEnv $ssh_v")
- done
-
- ssh_env+=("${ssh_env_vars[@]}")
+ ssh_env+=(
+ "COLORTERM=truecolor"
+ "TERM_PROGRAM=ghostty"
+ )
+ [[ -n "$TERM_PROGRAM_VERSION" ]] && ssh_env+=("TERM_PROGRAM_VERSION=$TERM_PROGRAM_VERSION")
fi
# Install terminfo on remote host if needed
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
- local ssh_config ssh_user ssh_hostname ssh_target
+ local ssh_config ssh_user ssh_hostname
ssh_config=$(command ssh -G "$@" 2>/dev/null)
- ssh_user=$(printf '%s\n' "${(@f)ssh_config}" | while IFS=' ' read -r ssh_key ssh_value; do
- [[ "$ssh_key" == "user" ]] && printf '%s\n' "$ssh_value" && break
- done)
- ssh_hostname=$(printf '%s\n' "${(@f)ssh_config}" | while IFS=' ' read -r ssh_key ssh_value; do
- [[ "$ssh_key" == "hostname" ]] && printf '%s\n' "$ssh_value" && break
- done)
+
+ while IFS=' ' read -r ssh_key ssh_value; do
+ case "$ssh_key" in
+ user) ssh_user="$ssh_value" ;;
+ hostname) ssh_hostname="$ssh_value" ;;
+ esac
+ [[ -n "$ssh_user" && -n "$ssh_hostname" ]] && break
+ done <<< "$ssh_config"
+
ssh_target="${ssh_user}@${ssh_hostname}"
if [[ -n "$ssh_hostname" ]]; then
- # Detect timeout command (BSD compatibility)
- local ssh_timeout_cmd=""
- if (( $+commands[timeout] )); then
- ssh_timeout_cmd="timeout"
- elif (( $+commands[gtimeout] )); then
- ssh_timeout_cmd="gtimeout"
- fi
-
# Check if terminfo is already cached
local ssh_cache_check_success=false
if (( $+commands[ghostty] )); then
- if [[ -n "$ssh_timeout_cmd" ]]; then
- $ssh_timeout_cmd "${GHOSTTY_SSH_CHECK_TIMEOUT}s" ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1 && ssh_cache_check_success=true
- else
- ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1 && ssh_cache_check_success=true
- fi
+ ghostty +ssh-cache --host="$ssh_target" >/dev/null 2>&1 && ssh_cache_check_success=true
fi
if [[ "$ssh_cache_check_success" == "true" ]]; then
ssh_env+=(TERM=xterm-ghostty)
elif (( $+commands[infocmp] )); then
- local ssh_terminfo
-
- # Generate terminfo data (BSD base64 compatibility)
- if base64 --help 2>&1 | grep -q GNU; then
- ssh_terminfo=$(infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 -w0 2>/dev/null)
+ if ! (( $+commands[base64] )); then
+ print "Warning: base64 command not available for terminfo installation." >&2
+ ssh_env+=(TERM=xterm-256color)
else
- ssh_terminfo=$(infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 2>/dev/null | tr -d '\n')
- fi
-
- if [[ -n "$ssh_terminfo" ]]; then
- print "Setting up Ghostty terminfo on remote host..." >&2
- local ssh_cpath_dir ssh_cpath
+ local ssh_terminfo ssh_base64_decode_cmd
- ssh_cpath_dir=$(mktemp -d "/tmp/ghostty-ssh-$ssh_user.XXXXXX" 2>/dev/null) || ssh_cpath_dir="/tmp/ghostty-ssh-$ssh_user.$$"
- ssh_cpath="$ssh_cpath_dir/socket"
-
- local ssh_base64_decode_cmd
+ # BSD vs GNU base64 compatibility
if base64 --help 2>&1 | grep -q GNU; then
ssh_base64_decode_cmd="base64 -d"
+ ssh_terminfo=$(infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 -w0 2>/dev/null)
else
ssh_base64_decode_cmd="base64 -D"
+ ssh_terminfo=$(infocmp -0 -Q2 -q xterm-ghostty 2>/dev/null | base64 2>/dev/null | tr -d '\n')
fi
- if print "$ssh_terminfo" | $ssh_base64_decode_cmd | command ssh "${ssh_opts[@]}" -o ControlMaster=yes -o ControlPath="$ssh_cpath" -o ControlPersist=60s "$@" '
- infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
- command -v tic >/dev/null 2>&1 || exit 1
- mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
- exit 1
- ' 2>/dev/null; then
- print "Terminfo setup complete." >&2
- ssh_env+=(TERM=xterm-ghostty)
- ssh_opts+=(-o "ControlPath=$ssh_cpath")
-
- # Cache successful installation
- if [[ -n "$ssh_target" ]] && (( $+commands[ghostty] )); then
- {
- if [[ -n "$ssh_timeout_cmd" ]]; then
- $ssh_timeout_cmd "${GHOSTTY_SSH_CACHE_TIMEOUT}s" ghostty +ssh-cache --add="$ssh_target" >/dev/null 2>&1 || true
- else
+ if [[ -n "$ssh_terminfo" ]]; then
+ print "Setting up Ghostty terminfo on $ssh_hostname..." >&2
+ local ssh_cpath_dir ssh_cpath
+
+ ssh_cpath_dir=$(mktemp -d "/tmp/ghostty-ssh-$ssh_user.XXXXXX" 2>/dev/null) || ssh_cpath_dir="/tmp/ghostty-ssh-$ssh_user.$$"
+ ssh_cpath="$ssh_cpath_dir/socket"
+
+ if print "$ssh_terminfo" | $ssh_base64_decode_cmd | command ssh "${ssh_opts[@]}" -o ControlMaster=yes -o ControlPath="$ssh_cpath" -o ControlPersist=60s "$@" '
+ infocmp xterm-ghostty >/dev/null 2>&1 && exit 0
+ command -v tic >/dev/null 2>&1 || exit 1
+ mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && exit 0
+ exit 1
+ ' 2>/dev/null; then
+ print "Terminfo setup complete on $ssh_hostname." >&2
+ ssh_env+=(TERM=xterm-ghostty)
+ ssh_opts+=(-o "ControlPath=$ssh_cpath")
+
+ # Cache successful installation
+ if [[ -n "$ssh_target" ]] && (( $+commands[ghostty] )); then
+ {
ghostty +ssh-cache --add="$ssh_target" >/dev/null 2>&1 || true
- fi
- } &!
+ } &!
+ fi
+ else
+ print "Warning: Failed to install terminfo." >&2
+ ssh_env+=(TERM=xterm-256color)
fi
else
- print "Warning: Failed to install terminfo." >&2
+ print "Warning: Could not generate terminfo data." >&2
ssh_env+=(TERM=xterm-256color)
fi
- else
- print "Warning: Could not generate terminfo data." >&2
- ssh_env+=(TERM=xterm-256color)
fi
else
print "Warning: ghostty command not available for cache management." >&2
@@ -380,21 +364,35 @@ _ghostty_deferred_init() {
fi
fi
- # Ensure TERM is set when using ssh-env feature
- if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
- local ssh_term_set=false ssh_v
- for ssh_v in "${ssh_env[@]}"; do
- [[ "$ssh_v" =~ ^TERM= ]] && ssh_term_set=true && break
- done
- [[ "$ssh_term_set" == "false" && "$TERM" == "xterm-ghostty" ]] && ssh_env+=(TERM=xterm-256color)
+ # Execute SSH with environment handling
+ local ssh_term_override=""
+ local ssh_v
+ for ssh_v in "${ssh_env[@]}"; do
+ if [[ "$ssh_v" =~ ^TERM=(.*)$ ]]; then
+ ssh_term_override="${match[1]}"
+ break
+ fi
+ done
+
+ if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env && -z "$ssh_term_override" ]]; then
+ ssh_env+=(TERM=xterm-256color)
+ ssh_term_override="xterm-256color"
fi
- command ssh "${ssh_opts[@]}" "$@"
- local ssh_ret=$?
+ local ssh_ret
+ if [[ -n "$ssh_term_override" ]]; then
+ local ssh_original_term="$TERM"
+ export TERM="$ssh_term_override"
+ command ssh "${ssh_opts[@]}" "$@"
+ ssh_ret=$?
+ export TERM="$ssh_original_term"
+ else
+ command ssh "${ssh_opts[@]}" "$@"
+ ssh_ret=$?
+ fi
# Restore original environment variables
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
- local ssh_v
for ssh_v in "${ssh_exported_vars[@]}"; do
if [[ "$ssh_v" == *=* ]]; then
export "${ssh_v}"