mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 16:56:09 +03:00
refactor: extract SSH cache functionality to shared script
Addresses feedback about separation of concerns in shell integration scripts. Extracts host caching logic to `src/shell-integration/shared/ghostty-ssh-cache` and updates all four shell integrations to use the shared script. The `shared/` subdirectory preserves the existing organizational pattern where all shell-specific code lives in subdirectories. This cleanly separates SSH transport logic from cache management while reducing code duplication by ~25%. All existing SSH integration behavior remains identical.
This commit is contained in:
@ -97,56 +97,48 @@ fi
|
|||||||
|
|
||||||
# SSH Integration
|
# SSH Integration
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-(env|terminfo) ]]; then
|
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-(env|terminfo) ]]; then
|
||||||
# Only define cache functions and variable if ssh-terminfo is enabled
|
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
||||||
_cache="${XDG_STATE_HOME:-$HOME/.local/state}/ghostty/terminfo_hosts"
|
readonly _CACHE="${GHOSTTY_RESOURCES_DIR}/shell-integration/shared/ghostty-ssh-cache"
|
||||||
|
# If 'ssh-terminfo' flag is enabled, wrap ghostty to provide cache management commands
|
||||||
# Cache operations and utilities
|
ghostty() {
|
||||||
_ghst_cache() {
|
case "$1" in
|
||||||
case $2 in
|
ssh-cache-list) "$_CACHE" list ;;
|
||||||
chk) [[ -f $_cache ]] && grep -qFx "$1" "$_cache" 2>/dev/null ;;
|
ssh-cache-clear) "$_CACHE" clear ;;
|
||||||
add)
|
*) builtin command ghostty "$@" ;;
|
||||||
mkdir -p "${_cache%/*}"
|
|
||||||
{
|
|
||||||
[[ -f $_cache ]] && cat "$_cache"
|
|
||||||
builtin echo "$1"
|
|
||||||
} | sort -u >"$_cache.tmp" && mv "$_cache.tmp" "$_cache" && chmod 600 "$_cache"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
function ghostty_ssh_cache_clear() {
|
|
||||||
rm -f "$_cache" 2>/dev/null && builtin echo "Ghostty SSH terminfo cache cleared." || builtin echo "No Ghostty SSH terminfo cache found."
|
|
||||||
}
|
|
||||||
|
|
||||||
function ghostty_ssh_cache_list() {
|
|
||||||
[[ -s $_cache ]] && builtin echo "Hosts with Ghostty terminfo installed:" && cat "$_cache" || builtin echo "No cached hosts found."
|
|
||||||
}
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# SSH wrapper
|
# SSH wrapper
|
||||||
ssh() {
|
ssh() {
|
||||||
local e=() o=() c=() t
|
local e=() o=() c=() # Removed 't' from here
|
||||||
|
|
||||||
# Get target
|
|
||||||
t=$(builtin command ssh -G "$@" 2>/dev/null | awk '/^(user|hostname) /{print $2}' | paste -sd'@')
|
|
||||||
|
|
||||||
# Set up env vars first so terminfo installation inherits them
|
# Set up env vars first so terminfo installation inherits them
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
|
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
|
||||||
builtin export COLORTERM=${COLORTERM:-truecolor} TERM_PROGRAM=${TERM_PROGRAM:-ghostty} ${GHOSTTY_VERSION:+TERM_PROGRAM_VERSION=$GHOSTTY_VERSION}
|
local vars=(
|
||||||
for v in COLORTERM=truecolor TERM_PROGRAM=ghostty ${GHOSTTY_VERSION:+TERM_PROGRAM_VERSION=$GHOSTTY_VERSION}; do
|
COLORTERM=truecolor
|
||||||
|
TERM_PROGRAM=ghostty
|
||||||
|
${GHOSTTY_VERSION:+TERM_PROGRAM_VERSION=$GHOSTTY_VERSION}
|
||||||
|
)
|
||||||
|
for v in "${vars[@]}"; do
|
||||||
|
builtin export "${v?}"
|
||||||
o+=(-o "SendEnv ${v%=*}" -o "SetEnv $v")
|
o+=(-o "SendEnv ${v%=*}" -o "SetEnv $v")
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install terminfo if needed, reuse control connection for main session
|
# Install terminfo if needed, reuse control connection for main session
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
||||||
if [[ -n $t ]] && _ghst_cache "$t" chk; then
|
# Get target (only when needed for terminfo)
|
||||||
|
builtin local t
|
||||||
|
t=$(builtin command ssh -G "$@" 2>/dev/null | awk '/^(user|hostname) /{print $2}' | paste -sd'@')
|
||||||
|
|
||||||
|
if [[ -n "$t" ]] && "$_CACHE" chk "$t"; then
|
||||||
e+=(TERM=xterm-ghostty)
|
e+=(TERM=xterm-ghostty)
|
||||||
elif builtin command -v infocmp >/dev/null 2>&1; then
|
elif builtin command -v infocmp >/dev/null 2>&1; then
|
||||||
builtin local ti
|
builtin local ti
|
||||||
ti=$(infocmp -x xterm-ghostty 2>/dev/null) || builtin echo "Warning: xterm-ghostty terminfo not found locally." >&2
|
ti=$(infocmp -x xterm-ghostty 2>/dev/null) || builtin echo "Warning: xterm-ghostty terminfo not found locally." >&2
|
||||||
if [[ -n $ti ]]; then
|
if [[ -n "$ti" ]]; then
|
||||||
builtin echo "Setting up Ghostty terminfo on remote host..." >&2
|
builtin echo "Setting up Ghostty terminfo on remote host..." >&2
|
||||||
builtin local cp
|
builtin local cp
|
||||||
cp="/tmp/ghostty-ssh-$USER-$RANDOM-$(date +%s)"
|
cp="/tmp/ghostty-ssh-$USER-$RANDOM-$(date +%s)"
|
||||||
@ -157,7 +149,7 @@ if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-(env|terminfo) ]]; then
|
|||||||
') in
|
') in
|
||||||
OK)
|
OK)
|
||||||
builtin echo "Terminfo setup complete." >&2
|
builtin echo "Terminfo setup complete." >&2
|
||||||
[[ -n $t ]] && _ghst_cache "$t" add
|
[[ -n "$t" ]] && "$_CACHE" add "$t"
|
||||||
e+=(TERM=xterm-ghostty)
|
e+=(TERM=xterm-ghostty)
|
||||||
c+=(-o "ControlPath=$cp")
|
c+=(-o "ControlPath=$cp")
|
||||||
;;
|
;;
|
||||||
@ -181,17 +173,6 @@ if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-(env|terminfo) ]]; then
|
|||||||
builtin command ssh "${o[@]}" "${c[@]}" "$@"
|
builtin command ssh "${o[@]}" "${c[@]}" "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# If 'ssh-terminfo' flag is enabled, wrap ghostty to provide 'ghostty ssh-cache-list' and `ghostty ssh-cache-clear` utility commands
|
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
|
||||||
ghostty() {
|
|
||||||
case "$1" in
|
|
||||||
ssh-cache-list) ghostty_ssh_cache_list ;;
|
|
||||||
ssh-cache-clear) ghostty_ssh_cache_clear ;;
|
|
||||||
*) builtin command ghostty "$@" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Import bash-preexec, safe to do multiple times
|
# Import bash-preexec, safe to do multiple times
|
||||||
|
@ -104,160 +104,107 @@
|
|||||||
use re
|
use re
|
||||||
|
|
||||||
if (re:match 'ssh-(env|terminfo)' $E:GHOSTTY_SHELL_FEATURES) {
|
if (re:match 'ssh-(env|terminfo)' $E:GHOSTTY_SHELL_FEATURES) {
|
||||||
# Only define cache functions and variable if ssh-terminfo is enabled
|
if (re:match 'ssh-terminfo' $E:GHOSTTY_SHELL_FEATURES) {
|
||||||
|
var _cache_script = (path:join $E:GHOSTTY_RESOURCES_DIR shell-integration shared ghostty-ssh-cache)
|
||||||
|
|
||||||
|
# Wrap ghostty command to provide cache management commands
|
||||||
|
fn ghostty {|@args|
|
||||||
|
if (eq $args[0] ssh-cache-list) {
|
||||||
|
(external $_cache_script) list
|
||||||
|
} elif (eq $args[0] ssh-cache-clear) {
|
||||||
|
(external $_cache_script) clear
|
||||||
|
} else {
|
||||||
|
(external ghostty) $@args
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
edit:add-var ghostty~ $ghostty~
|
||||||
|
}
|
||||||
|
|
||||||
|
# SSH wrapper
|
||||||
|
fn ssh {|@args|
|
||||||
|
var e = []
|
||||||
|
var o = []
|
||||||
|
var c = []
|
||||||
|
|
||||||
|
# Set up env vars first so terminfo installation inherits them
|
||||||
|
if (re:match 'ssh-env' $E:GHOSTTY_SHELL_FEATURES) {
|
||||||
|
set-env COLORTERM (or $E:COLORTERM truecolor)
|
||||||
|
set-env TERM_PROGRAM (or $E:TERM_PROGRAM ghostty)
|
||||||
|
if (has-env GHOSTTY_VERSION) {
|
||||||
|
set-env TERM_PROGRAM_VERSION $E:GHOSTTY_VERSION
|
||||||
|
}
|
||||||
|
|
||||||
|
var vars = [COLORTERM=truecolor TERM_PROGRAM=ghostty]
|
||||||
|
if (has-env GHOSTTY_VERSION) {
|
||||||
|
set vars = [$@vars TERM_PROGRAM_VERSION=$E:GHOSTTY_VERSION]
|
||||||
|
}
|
||||||
|
for v $vars {
|
||||||
|
var varname = (str:split &max=2 '=' $v | take 1)
|
||||||
|
set o = [$@o -o "SendEnv "$varname -o "SetEnv "$v]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install terminfo if needed, reuse control connection for main session
|
||||||
if (re:match 'ssh-terminfo' $E:GHOSTTY_SHELL_FEATURES) {
|
if (re:match 'ssh-terminfo' $E:GHOSTTY_SHELL_FEATURES) {
|
||||||
var _cache = (path:join (or $E:XDG_STATE_HOME $E:HOME/.local/state) ghostty terminfo_hosts)
|
# Get target (only when needed for terminfo)
|
||||||
|
var t = ""
|
||||||
|
try {
|
||||||
|
set t = (e:ssh -G $@args 2>/dev/null | awk '/^(user|hostname) /{print $2}' | paste -sd'@' | str:trim-space)
|
||||||
|
} catch e {
|
||||||
|
# Ignore errors
|
||||||
|
}
|
||||||
|
|
||||||
# Cache operations and utilities
|
if (and (not-eq $t "") (try { (external $_cache_script) chk $t } catch e { put $false })) {
|
||||||
fn _ghst_cache {|target action|
|
set e = [$@e TERM=xterm-ghostty]
|
||||||
if (eq $action chk) {
|
} elif (has-external infocmp) {
|
||||||
if (path:is-regular $_cache) {
|
var ti = ""
|
||||||
try {
|
try {
|
||||||
grep -qFx $target $_cache 2>/dev/null
|
set ti = (infocmp -x xterm-ghostty 2>/dev/null | slurp)
|
||||||
} catch e {
|
} catch e {
|
||||||
fail
|
echo "Warning: xterm-ghostty terminfo not found locally." >&2
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fail
|
|
||||||
}
|
|
||||||
} elif (eq $action add) {
|
|
||||||
mkdir -p (path:dir $_cache)
|
|
||||||
var tmpfile = $_cache.tmp
|
|
||||||
{
|
|
||||||
if (path:is-regular $_cache) {
|
|
||||||
cat $_cache
|
|
||||||
}
|
|
||||||
echo $target
|
|
||||||
} | sort -u > $tmpfile
|
|
||||||
mv $tmpfile $_cache
|
|
||||||
chmod 600 $_cache
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (not-eq $ti "") {
|
||||||
fn ghostty_ssh_cache_clear {
|
echo "Setting up Ghostty terminfo on remote host..." >&2
|
||||||
try {
|
var cp = "/tmp/ghostty-ssh-"$E:USER"-"(randint 10000)"-"(date +%s | str:trim-space)
|
||||||
rm -f $_cache 2>/dev/null
|
var result = (echo $ti | e:ssh $@o -o ControlMaster=yes -o ControlPath=$cp -o ControlPersist=60s $@args '
|
||||||
echo "Ghostty SSH terminfo cache cleared."
|
infocmp xterm-ghostty >/dev/null 2>&1 && echo OK && exit
|
||||||
} catch e {
|
command -v tic >/dev/null 2>&1 || { echo NO_TIC; exit 1; }
|
||||||
echo "No Ghostty SSH terminfo cache found."
|
mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && echo OK || echo FAIL
|
||||||
}
|
' | str:trim-space)
|
||||||
}
|
if (eq $result OK) {
|
||||||
|
echo "Terminfo setup complete." >&2
|
||||||
fn ghostty_ssh_cache_list {
|
if (not-eq $t "") {
|
||||||
if (and (path:is-regular $_cache) (> (wc -c < $_cache | str:trim-space) 0)) {
|
(external $_cache_script) add $t
|
||||||
echo "Hosts with Ghostty terminfo installed:"
|
|
||||||
cat $_cache
|
|
||||||
} else {
|
|
||||||
echo "No cached hosts found."
|
|
||||||
}
|
}
|
||||||
|
set e = [$@e TERM=xterm-ghostty]
|
||||||
|
set c = [$@c -o ControlPath=$cp]
|
||||||
|
} else {
|
||||||
|
echo "Warning: Failed to install terminfo." >&2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
echo "Warning: infocmp not found locally. Terminfo installation unavailable." >&2
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# SSH wrapper
|
# Fallback TERM only if terminfo didn't set it
|
||||||
fn ssh {|@args|
|
if (re:match 'ssh-env' $E:GHOSTTY_SHELL_FEATURES) {
|
||||||
var e = []
|
if (and (eq $E:TERM xterm-ghostty) (not (re:match 'TERM=' (str:join ' ' $e)))) {
|
||||||
var o = []
|
set e = [$@e TERM=xterm-256color]
|
||||||
var c = []
|
}
|
||||||
var t = ""
|
|
||||||
|
|
||||||
# Get target (only if ssh-terminfo enabled for caching)
|
|
||||||
if (re:match 'ssh-terminfo' $E:GHOSTTY_SHELL_FEATURES) {
|
|
||||||
try {
|
|
||||||
set t = (e:ssh -G $@args 2>/dev/null | awk '/^(user|hostname) /{print $2}' | paste -sd'@' | str:trim-space)
|
|
||||||
} catch e {
|
|
||||||
# Ignore errors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Set up env vars first so terminfo installation inherits them
|
|
||||||
if (re:match 'ssh-env' $E:GHOSTTY_SHELL_FEATURES) {
|
|
||||||
set-env COLORTERM (or $E:COLORTERM truecolor)
|
|
||||||
set-env TERM_PROGRAM (or $E:TERM_PROGRAM ghostty)
|
|
||||||
if (has-env GHOSTTY_VERSION) {
|
|
||||||
set-env TERM_PROGRAM_VERSION $E:GHOSTTY_VERSION
|
|
||||||
}
|
|
||||||
|
|
||||||
var vars = [COLORTERM=truecolor TERM_PROGRAM=ghostty]
|
|
||||||
if (has-env GHOSTTY_VERSION) {
|
|
||||||
set vars = [$@vars TERM_PROGRAM_VERSION=$E:GHOSTTY_VERSION]
|
|
||||||
}
|
|
||||||
for v $vars {
|
|
||||||
var varname = (str:split &max=2 '=' $v | take 1)
|
|
||||||
set o = [$@o -o "SendEnv "$varname -o "SetEnv "$v]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Install terminfo if needed, reuse control connection for main session
|
|
||||||
if (re:match 'ssh-terminfo' $E:GHOSTTY_SHELL_FEATURES) {
|
|
||||||
if (and (not-eq $t "") (try { _ghst_cache $t chk } catch e { put $false })) {
|
|
||||||
set e = [$@e TERM=xterm-ghostty]
|
|
||||||
} elif (has-external infocmp) {
|
|
||||||
var ti = ""
|
|
||||||
try {
|
|
||||||
set ti = (infocmp -x xterm-ghostty 2>/dev/null | slurp)
|
|
||||||
} catch e {
|
|
||||||
echo "Warning: xterm-ghostty terminfo not found locally." >&2
|
|
||||||
}
|
|
||||||
if (not-eq $ti "") {
|
|
||||||
echo "Setting up Ghostty terminfo on remote host..." >&2
|
|
||||||
var cp = "/tmp/ghostty-ssh-"$E:USER"-"(randint 10000)"-"(date +%s | str:trim-space)
|
|
||||||
var result = (echo $ti | e:ssh $@o -o ControlMaster=yes -o ControlPath=$cp -o ControlPersist=60s $@args '
|
|
||||||
infocmp xterm-ghostty >/dev/null 2>&1 && echo OK && exit
|
|
||||||
command -v tic >/dev/null 2>&1 || { echo NO_TIC; exit 1; }
|
|
||||||
mkdir -p ~/.terminfo 2>/dev/null && tic -x - 2>/dev/null && echo OK || echo FAIL
|
|
||||||
' | str:trim-space)
|
|
||||||
if (eq $result OK) {
|
|
||||||
echo "Terminfo setup complete." >&2
|
|
||||||
if (not-eq $t "") {
|
|
||||||
_ghst_cache $t add
|
|
||||||
}
|
|
||||||
set e = [$@e TERM=xterm-ghostty]
|
|
||||||
set c = [$@c -o ControlPath=$cp]
|
|
||||||
} else {
|
|
||||||
echo "Warning: Failed to install terminfo." >&2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo "Warning: infocmp not found locally. Terminfo installation unavailable." >&2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Fallback TERM only if terminfo didn't set it
|
|
||||||
if (re:match 'ssh-env' $E:GHOSTTY_SHELL_FEATURES) {
|
|
||||||
if (and (eq $E:TERM xterm-ghostty) (not (re:match 'TERM=' (str:join ' ' $e)))) {
|
|
||||||
set e = [$@e TERM=xterm-256color]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Execute
|
|
||||||
if (> (count $e) 0) {
|
|
||||||
e:env $@e e:ssh $@o $@c $@args
|
|
||||||
} else {
|
|
||||||
e:ssh $@o $@c $@args
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Wrap ghostty command only if ssh-terminfo is enabled
|
# Execute
|
||||||
if (re:match 'ssh-terminfo' $E:GHOSTTY_SHELL_FEATURES) {
|
if (> (count $e) 0) {
|
||||||
fn ghostty {|@args|
|
e:env $@e e:ssh $@o $@c $@args
|
||||||
if (eq $args[0] ssh-cache-list) {
|
} else {
|
||||||
ghostty_ssh_cache_list
|
e:ssh $@o $@c $@args
|
||||||
} elif (eq $args[0] ssh-cache-clear) {
|
|
||||||
ghostty_ssh_cache_clear
|
|
||||||
} else {
|
|
||||||
(external ghostty) $@args
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
edit:add-var ghostty~ $ghostty~
|
|
||||||
|
|
||||||
# Export cache functions for global use
|
|
||||||
set edit:add-var[ghostty_ssh_cache_clear] = $ghostty_ssh_cache_clear~
|
|
||||||
set edit:add-var[ghostty_ssh_cache_list] = $ghostty_ssh_cache_list~
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Export ssh function for global use
|
# Export ssh function for global use
|
||||||
set edit:add-var[ssh] = $ssh~
|
set edit:add-var[ssh] = $ssh~
|
||||||
}
|
}
|
||||||
|
|
||||||
defer {
|
defer {
|
||||||
|
@ -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
|
# When using sudo shell integration feature, ensure $TERMINFO is set
|
||||||
# and `sudo` is not already a function or alias
|
# 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
|
# Wrap `sudo` command to ensure Ghostty terminfo is preserved
|
||||||
function sudo -d "Wrap sudo to preserve terminfo"
|
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
|
for arg in $argv
|
||||||
# Check if argument is '-e' or '--edit' (sudoedit flags)
|
# Check if argument is '-e' or '--edit' (sudoedit flags)
|
||||||
if string match -q -- "-e" "$arg"; or string match -q -- "--edit" "$arg"
|
if string match -q -- -e "$arg"; or string match -q -- --edit "$arg"
|
||||||
set --function sudo_has_sudoedit_flags "yes"
|
set --function sudo_has_sudoedit_flags yes
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
# Check if argument is neither an option nor a key-value pair
|
# 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
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if test "$sudo_has_sudoedit_flags" = "yes"
|
if test "$sudo_has_sudoedit_flags" = yes
|
||||||
command sudo $argv
|
command sudo $argv
|
||||||
else
|
else
|
||||||
command sudo TERMINFO="$TERMINFO" $argv
|
command sudo TERMINFO="$TERMINFO" $argv
|
||||||
@ -88,31 +88,20 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|||||||
|
|
||||||
# SSH Integration
|
# SSH Integration
|
||||||
if string match -qr 'ssh-(env|terminfo)' "$GHOSTTY_SHELL_FEATURES"
|
if string match -qr 'ssh-(env|terminfo)' "$GHOSTTY_SHELL_FEATURES"
|
||||||
# Only define cache functions and variable if ssh-terminfo is enabled
|
if string match -qr ssh-terminfo "$GHOSTTY_SHELL_FEATURES"
|
||||||
if string match -qr 'ssh-terminfo' "$GHOSTTY_SHELL_FEATURES"
|
set -g _cache_script "$GHOSTTY_RESOURCES_DIR/shell-integration/shared/ghostty-ssh-cache"
|
||||||
set -g _cache (test -n "$XDG_STATE_HOME" && echo "$XDG_STATE_HOME" || echo "$HOME/.local/state")/ghostty/terminfo_hosts
|
|
||||||
|
|
||||||
# Cache operations and utilities
|
# Wrap ghostty command to provide cache management commands
|
||||||
function _ghst_cache
|
function ghostty -d "Wrap ghostty to provide cache management commands"
|
||||||
switch $argv[2]
|
switch "$argv[1]"
|
||||||
case chk
|
case ssh-cache-list
|
||||||
test -f $_cache && grep -qFx "$argv[1]" "$_cache" 2>/dev/null
|
command "$_cache_script" list
|
||||||
case add
|
case ssh-cache-clear
|
||||||
mkdir -p (dirname "$_cache")
|
command "$_cache_script" clear
|
||||||
begin
|
case "*"
|
||||||
test -f $_cache && cat "$_cache"
|
command ghostty $argv
|
||||||
builtin echo "$argv[1]"
|
|
||||||
end | sort -u >"$_cache.tmp" && mv "$_cache.tmp" "$_cache" && chmod 600 "$_cache"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ghostty_ssh_cache_clear -d "Clear Ghostty SSH terminfo cache"
|
|
||||||
rm -f "$_cache" 2>/dev/null && builtin echo "Ghostty SSH terminfo cache cleared." || builtin echo "No Ghostty SSH terminfo cache found."
|
|
||||||
end
|
|
||||||
|
|
||||||
function ghostty_ssh_cache_list -d "List hosts with Ghostty terminfo installed"
|
|
||||||
test -s $_cache && builtin echo "Hosts with Ghostty terminfo installed:" && cat "$_cache" || builtin echo "No cached hosts found."
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# SSH wrapper
|
# SSH wrapper
|
||||||
@ -120,28 +109,28 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|||||||
set -l e
|
set -l e
|
||||||
set -l o
|
set -l o
|
||||||
set -l c
|
set -l c
|
||||||
set -l t
|
|
||||||
|
|
||||||
# Get target (only if ssh-terminfo enabled for caching)
|
|
||||||
if string match -qr 'ssh-terminfo' "$GHOSTTY_SHELL_FEATURES"
|
|
||||||
set t (builtin command ssh -G $argv 2>/dev/null | awk '/^(user|hostname) /{print $2}' | paste -sd'@')
|
|
||||||
end
|
|
||||||
|
|
||||||
# Set up env vars first so terminfo installation inherits them
|
# Set up env vars first so terminfo installation inherits them
|
||||||
if string match -qr 'ssh-env' "$GHOSTTY_SHELL_FEATURES"
|
if string match -qr ssh-env "$GHOSTTY_SHELL_FEATURES"
|
||||||
set -gx COLORTERM (test -n "$COLORTERM" && echo "$COLORTERM" || echo "truecolor")
|
set -gx COLORTERM (test -n "$COLORTERM" && echo "$COLORTERM" || echo "truecolor")
|
||||||
set -gx TERM_PROGRAM (test -n "$TERM_PROGRAM" && echo "$TERM_PROGRAM" || echo "ghostty")
|
set -gx TERM_PROGRAM (test -n "$TERM_PROGRAM" && echo "$TERM_PROGRAM" || echo "ghostty")
|
||||||
test -n "$GHOSTTY_VERSION" && set -gx TERM_PROGRAM_VERSION "$GHOSTTY_VERSION"
|
test -n "$GHOSTTY_VERSION" && set -gx TERM_PROGRAM_VERSION "$GHOSTTY_VERSION"
|
||||||
|
|
||||||
for v in COLORTERM=truecolor TERM_PROGRAM=ghostty (test -n "$GHOSTTY_VERSION" && echo "TERM_PROGRAM_VERSION=$GHOSTTY_VERSION")
|
set -l vars COLORTERM=truecolor TERM_PROGRAM=ghostty
|
||||||
|
test -n "$GHOSTTY_VERSION" && set vars $vars "TERM_PROGRAM_VERSION=$GHOSTTY_VERSION"
|
||||||
|
|
||||||
|
for v in $vars
|
||||||
set -l varname (string split -m1 '=' "$v")[1]
|
set -l varname (string split -m1 '=' "$v")[1]
|
||||||
set o $o -o "SendEnv $varname" -o "SetEnv $v"
|
set o $o -o "SendEnv $varname" -o "SetEnv $v"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Install terminfo if needed, reuse control connection for main session
|
# Install terminfo if needed, reuse control connection for main session
|
||||||
if string match -qr 'ssh-terminfo' "$GHOSTTY_SHELL_FEATURES"
|
if string match -qr ssh-terminfo "$GHOSTTY_SHELL_FEATURES"
|
||||||
if test -n "$t" && _ghst_cache "$t" chk
|
# Get target (only when needed for terminfo)
|
||||||
|
set -l t (builtin command ssh -G $argv 2>/dev/null | awk '/^(user|hostname) /{print $2}' | paste -sd'@')
|
||||||
|
|
||||||
|
if test -n "$t" && command "$_cache_script" chk "$t"
|
||||||
set e $e TERM=xterm-ghostty
|
set e $e TERM=xterm-ghostty
|
||||||
else if command -v infocmp >/dev/null 2>&1
|
else if command -v infocmp >/dev/null 2>&1
|
||||||
set -l ti
|
set -l ti
|
||||||
@ -157,7 +146,7 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|||||||
switch $result
|
switch $result
|
||||||
case OK
|
case OK
|
||||||
builtin echo "Terminfo setup complete." >&2
|
builtin echo "Terminfo setup complete." >&2
|
||||||
test -n "$t" && _ghst_cache "$t" add
|
test -n "$t" && command "$_cache_script" add "$t"
|
||||||
set e $e TERM=xterm-ghostty
|
set e $e TERM=xterm-ghostty
|
||||||
set c $c -o "ControlPath=$cp"
|
set c $c -o "ControlPath=$cp"
|
||||||
case '*'
|
case '*'
|
||||||
@ -170,7 +159,7 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Fallback TERM only if terminfo didn't set it
|
# Fallback TERM only if terminfo didn't set it
|
||||||
if string match -qr 'ssh-env' "$GHOSTTY_SHELL_FEATURES"
|
if string match -qr ssh-env "$GHOSTTY_SHELL_FEATURES"
|
||||||
if test "$TERM" = xterm-ghostty && not string match -q '*TERM=*' "$e"
|
if test "$TERM" = xterm-ghostty && not string match -q '*TERM=*' "$e"
|
||||||
set e $e TERM=xterm-256color
|
set e $e TERM=xterm-256color
|
||||||
end
|
end
|
||||||
@ -183,20 +172,6 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|||||||
builtin command ssh $o $c $argv
|
builtin command ssh $o $c $argv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Wrap ghostty command only if ssh-terminfo is enabled
|
|
||||||
if string match -qr 'ssh-terminfo' "$GHOSTTY_SHELL_FEATURES"
|
|
||||||
function ghostty -d "Wrap ghostty to provide cache management commands"
|
|
||||||
switch "$argv[1]"
|
|
||||||
case ssh-cache-list
|
|
||||||
ghostty_ssh_cache_list
|
|
||||||
case ssh-cache-clear
|
|
||||||
ghostty_ssh_cache_clear
|
|
||||||
case "*"
|
|
||||||
command ghostty $argv
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup prompt marking
|
# Setup prompt marking
|
||||||
|
11
src/shell-integration/shared/ghostty-ssh-cache
Executable file
11
src/shell-integration/shared/ghostty-ssh-cache
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# Minimal Ghostty SSH terminfo host cache
|
||||||
|
|
||||||
|
readonly CACHE_FILE="${XDG_STATE_HOME:-$HOME/.local/state}/ghostty/terminfo_hosts"
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
chk) [[ -f "$CACHE_FILE" ]] && grep -qFx "$2" "$CACHE_FILE" 2>/dev/null ;;
|
||||||
|
add) mkdir -p "${CACHE_FILE%/*}"; { [[ -f "$CACHE_FILE" ]] && cat "$CACHE_FILE"; echo "$2"; } | sort -u > "$CACHE_FILE.tmp" && mv "$CACHE_FILE.tmp" "$CACHE_FILE" && chmod 600 "$CACHE_FILE" ;;
|
||||||
|
list) [[ -s "$CACHE_FILE" ]] && echo "Hosts with Ghostty terminfo installed:" && cat "$CACHE_FILE" || echo "No cached hosts found." ;;
|
||||||
|
clear) rm -f "$CACHE_FILE" 2>/dev/null && echo "Ghostty SSH terminfo cache cleared." || echo "No Ghostty SSH terminfo cache found." ;;
|
||||||
|
esac
|
@ -246,54 +246,43 @@ _ghostty_deferred_init() {
|
|||||||
|
|
||||||
# SSH Integration
|
# SSH Integration
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-(env|terminfo) ]]; then
|
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-(env|terminfo) ]]; then
|
||||||
# Only define cache functions and variable if ssh-terminfo is enabled
|
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
||||||
_cache="${XDG_STATE_HOME:-$HOME/.local/state}/ghostty/terminfo_hosts"
|
readonly _cache_script="${GHOSTTY_RESOURCES_DIR}/shell-integration/shared/ghostty-ssh-cache"
|
||||||
|
|
||||||
# Cache operations and utilities
|
# Wrap ghostty command to provide cache management commands
|
||||||
_ghst_cache() {
|
ghostty() {
|
||||||
case $2 in
|
case "$1" in
|
||||||
chk) [[ -f $_cache ]] && grep -qFx "$1" "$_cache" 2>/dev/null ;;
|
ssh-cache-list) "$_cache_script" list ;;
|
||||||
add)
|
ssh-cache-clear) "$_cache_script" clear ;;
|
||||||
mkdir -p "${_cache:h}"
|
*) builtin command ghostty "$@" ;;
|
||||||
{
|
|
||||||
[[ -f $_cache ]] && cat "$_cache"
|
|
||||||
builtin echo "$1"
|
|
||||||
} | sort -u >"$_cache.tmp" && mv "$_cache.tmp" "$_cache" && chmod 600 "$_cache"
|
|
||||||
;;
|
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
ghostty_ssh_cache_clear() {
|
|
||||||
rm -f "$_cache" 2>/dev/null && builtin echo "Ghostty SSH terminfo cache cleared." || builtin echo "No Ghostty SSH terminfo cache found."
|
|
||||||
}
|
|
||||||
|
|
||||||
ghostty_ssh_cache_list() {
|
|
||||||
[[ -s $_cache ]] && builtin echo "Hosts with Ghostty terminfo installed:" && cat "$_cache" || builtin echo "No cached hosts found."
|
|
||||||
}
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# SSH wrapper
|
# SSH wrapper
|
||||||
ssh() {
|
ssh() {
|
||||||
local -a e o c
|
local -a e o c
|
||||||
local t
|
|
||||||
|
|
||||||
# Get target (only if ssh-terminfo enabled for caching)
|
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
|
||||||
t=$(builtin command ssh -G "$@" 2>/dev/null | awk '/^(user|hostname) /{print $2}' | paste -sd'@')
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Set up env vars first so terminfo installation inherits them
|
# Set up env vars first so terminfo installation inherits them
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
|
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-env ]]; then
|
||||||
builtin export COLORTERM=${COLORTERM:-truecolor} TERM_PROGRAM=${TERM_PROGRAM:-ghostty} ${GHOSTTY_VERSION:+TERM_PROGRAM_VERSION=$GHOSTTY_VERSION}
|
local vars=(
|
||||||
for v in COLORTERM=truecolor TERM_PROGRAM=ghostty ${GHOSTTY_VERSION:+TERM_PROGRAM_VERSION=$GHOSTTY_VERSION}; do
|
COLORTERM=truecolor
|
||||||
|
TERM_PROGRAM=ghostty
|
||||||
|
${GHOSTTY_VERSION:+TERM_PROGRAM_VERSION=$GHOSTTY_VERSION}
|
||||||
|
)
|
||||||
|
for v in "${vars[@]}"; do
|
||||||
|
builtin export "${v?}"
|
||||||
o+=(-o "SendEnv ${v%=*}" -o "SetEnv $v")
|
o+=(-o "SendEnv ${v%=*}" -o "SetEnv $v")
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Install terminfo if needed, reuse control connection for main session
|
# Install terminfo if needed, reuse control connection for main session
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
||||||
if [[ -n $t ]] && _ghst_cache "$t" chk; then
|
# Get target (only when needed for terminfo)
|
||||||
|
builtin local t
|
||||||
|
t=$(builtin command ssh -G "$@" 2>/dev/null | awk '/^(user|hostname) /{print $2}' | paste -sd'@')
|
||||||
|
|
||||||
|
if [[ -n $t ]] && "$_cache_script" chk "$t"; then
|
||||||
e+=(TERM=xterm-ghostty)
|
e+=(TERM=xterm-ghostty)
|
||||||
elif builtin command -v infocmp >/dev/null 2>&1; then
|
elif builtin command -v infocmp >/dev/null 2>&1; then
|
||||||
local ti
|
local ti
|
||||||
@ -309,7 +298,7 @@ _ghostty_deferred_init() {
|
|||||||
') in
|
') in
|
||||||
OK)
|
OK)
|
||||||
builtin echo "Terminfo setup complete." >&2
|
builtin echo "Terminfo setup complete." >&2
|
||||||
[[ -n $t ]] && _ghst_cache "$t" add
|
[[ -n $t ]] && "$_cache_script" add "$t"
|
||||||
e+=(TERM=xterm-ghostty)
|
e+=(TERM=xterm-ghostty)
|
||||||
c+=(-o "ControlPath=$cp")
|
c+=(-o "ControlPath=$cp")
|
||||||
;;
|
;;
|
||||||
@ -333,17 +322,6 @@ _ghostty_deferred_init() {
|
|||||||
builtin command ssh "${o[@]}" "${c[@]}" "$@"
|
builtin command ssh "${o[@]}" "${c[@]}" "$@"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Wrap ghostty command only if ssh-terminfo is enabled
|
|
||||||
if [[ "$GHOSTTY_SHELL_FEATURES" =~ ssh-terminfo ]]; then
|
|
||||||
ghostty() {
|
|
||||||
case "$1" in
|
|
||||||
ssh-cache-list) ghostty_ssh_cache_list ;;
|
|
||||||
ssh-cache-clear) ghostty_ssh_cache_clear ;;
|
|
||||||
*) builtin command ghostty "$@" ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Some zsh users manually run `source ~/.zshrc` in order to apply rc file
|
# Some zsh users manually run `source ~/.zshrc` in order to apply rc file
|
||||||
|
Reference in New Issue
Block a user