mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 08:16:13 +03:00
fix: add client-side caching to eliminate redundant terminfo installations
- Cache known hosts with terminfo in $GHOSTTY_RESOURCES_DIR/terminfo_hosts - Skip installation step for cached hosts (single connection instead of two) - Use secure file permissions (600) and atomic writes - Extract SSH target safely from command arguments - Maintains full functionality while improving user experience on repeated connections
This commit is contained in:
@ -99,6 +99,66 @@ fi
|
|||||||
|
|
||||||
# SSH
|
# SSH
|
||||||
if [[ -n "$GHOSTTY_SSH_INTEGRATION" ]]; then
|
if [[ -n "$GHOSTTY_SSH_INTEGRATION" ]]; then
|
||||||
|
# Cache file for tracking hosts with terminfo installed
|
||||||
|
_ghostty_cache_file="${GHOSTTY_RESOURCES_DIR:-$HOME/.config/ghostty}/terminfo_hosts"
|
||||||
|
|
||||||
|
# Extract target host from SSH arguments
|
||||||
|
_ghostty_get_ssh_target() {
|
||||||
|
local target=""
|
||||||
|
local skip_next=false
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
if [[ "$skip_next" == "true" ]]; then
|
||||||
|
skip_next=false
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Skip flags that take arguments
|
||||||
|
if [[ "$arg" =~ ^-[bcDEeFIiJLlmOopQRSWw]$ ]]; then
|
||||||
|
skip_next=true
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Skip other flags
|
||||||
|
if [[ "$arg" =~ ^- ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This should be the target
|
||||||
|
target="$arg"
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$target"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if host has terminfo installed
|
||||||
|
_ghostty_host_has_terminfo() {
|
||||||
|
local target="$1"
|
||||||
|
[[ -f "$_ghostty_cache_file" ]] && grep -qFx "$target" "$_ghostty_cache_file" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add host to terminfo cache
|
||||||
|
_ghostty_cache_host() {
|
||||||
|
local target="$1"
|
||||||
|
local cache_dir
|
||||||
|
cache_dir="$(dirname "$_ghostty_cache_file")"
|
||||||
|
|
||||||
|
# Create cache directory if needed
|
||||||
|
[[ ! -d "$cache_dir" ]] && mkdir -p "$cache_dir"
|
||||||
|
|
||||||
|
# Atomic write to cache file
|
||||||
|
{
|
||||||
|
if [[ -f "$_ghostty_cache_file" ]]; then
|
||||||
|
cat "$_ghostty_cache_file"
|
||||||
|
fi
|
||||||
|
echo "$target"
|
||||||
|
} | sort -u > "$_ghostty_cache_file.tmp" && mv "$_ghostty_cache_file.tmp" "$_ghostty_cache_file"
|
||||||
|
|
||||||
|
# Secure permissions
|
||||||
|
chmod 600 "$_ghostty_cache_file" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
# Wrap `ssh` command to provide Ghostty SSH integration.
|
# Wrap `ssh` command to provide Ghostty SSH integration.
|
||||||
#
|
#
|
||||||
# This approach supports wrapping an `ssh` alias, but the alias definition
|
# This approach supports wrapping an `ssh` alias, but the alias definition
|
||||||
@ -153,21 +213,35 @@ if [[ -n "$GHOSTTY_SSH_INTEGRATION" ]]; then
|
|||||||
|
|
||||||
# Level: full - All features
|
# Level: full - All features
|
||||||
_ghostty_ssh_full() {
|
_ghostty_ssh_full() {
|
||||||
# Full integration: Two-step terminfo installation
|
local target
|
||||||
|
target="$(_ghostty_get_ssh_target "$@")"
|
||||||
|
|
||||||
|
# Check if we already know this host has terminfo
|
||||||
|
if [[ -n "$target" ]] && _ghostty_host_has_terminfo "$target"; then
|
||||||
|
# Direct connection with xterm-ghostty
|
||||||
|
local env_vars=("TERM=xterm-ghostty")
|
||||||
|
[[ -n "$GHOSTTY_SHELL_FEATURES" ]] && env_vars+=("GHOSTTY_SHELL_FEATURES=$GHOSTTY_SHELL_FEATURES")
|
||||||
|
env "${env_vars[@]}" ssh "$@"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Full integration: Install terminfo if needed
|
||||||
if builtin command -v infocmp >/dev/null 2>&1; then
|
if builtin command -v infocmp >/dev/null 2>&1; then
|
||||||
echo "Installing Ghostty terminfo on remote host..." >&2
|
# Install terminfo only if needed
|
||||||
|
if infocmp -x xterm-ghostty 2>/dev/null | builtin command ssh "$@" '
|
||||||
|
if ! infocmp xterm-ghostty >/dev/null 2>&1; then
|
||||||
|
echo "Installing Ghostty terminfo..." >&2
|
||||||
|
tic -x - 2>/dev/null
|
||||||
|
fi
|
||||||
|
'; then
|
||||||
|
echo "Connecting with full Ghostty support..." >&2
|
||||||
|
|
||||||
# Step 1: Install terminfo
|
# Cache this host for future connections
|
||||||
if infocmp -x xterm-ghostty 2>/dev/null | builtin command ssh "$@" 'tic -x - 2>/dev/null'; then
|
[[ -n "$target" ]] && _ghostty_cache_host "$target"
|
||||||
echo "Terminfo installed successfully. Connecting with full Ghostty support..." >&2
|
|
||||||
|
|
||||||
# Step 2: Connect with xterm-ghostty since we know terminfo is now available
|
# Connect with xterm-ghostty since terminfo is available
|
||||||
local env_vars=("TERM=xterm-ghostty")
|
local env_vars=("TERM=xterm-ghostty")
|
||||||
|
|
||||||
# Propagate Ghostty shell integration environment variables
|
|
||||||
[[ -n "$GHOSTTY_SHELL_FEATURES" ]] && env_vars+=("GHOSTTY_SHELL_FEATURES=$GHOSTTY_SHELL_FEATURES")
|
[[ -n "$GHOSTTY_SHELL_FEATURES" ]] && env_vars+=("GHOSTTY_SHELL_FEATURES=$GHOSTTY_SHELL_FEATURES")
|
||||||
|
|
||||||
# Normal SSH connection with Ghostty terminfo available
|
|
||||||
env "${env_vars[@]}" ssh "$@"
|
env "${env_vars[@]}" ssh "$@"
|
||||||
builtin return 0
|
builtin return 0
|
||||||
fi
|
fi
|
||||||
|
@ -98,6 +98,70 @@
|
|||||||
(external sudo) $@args
|
(external sudo) $@args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# SSH Integration
|
||||||
|
# Cache file for tracking hosts with terminfo installed
|
||||||
|
var ghostty-cache-file = (if (has-env GHOSTTY_RESOURCES_DIR) { put $E:GHOSTTY_RESOURCES_DIR"/terminfo_hosts" } else { put $E:HOME"/.config/ghostty/terminfo_hosts" })
|
||||||
|
|
||||||
|
# Extract target host from SSH arguments
|
||||||
|
fn ghostty-get-ssh-target {|@args|
|
||||||
|
var target = ""
|
||||||
|
var skip-next = $false
|
||||||
|
|
||||||
|
for arg $args {
|
||||||
|
if (eq $skip-next $true) {
|
||||||
|
set skip-next = $false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
# Skip flags that take arguments
|
||||||
|
if (re:match '^-[bcDEeFIiJLlmOopQRSWw]$' $arg) {
|
||||||
|
set skip-next = $true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
# Skip other flags
|
||||||
|
if (re:match '^-' $arg) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
# This should be the target
|
||||||
|
set target = $arg
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
put $target
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if host has terminfo installed
|
||||||
|
fn ghostty-host-has-terminfo {|target|
|
||||||
|
and (path:is-regular $ghostty-cache-file) ?(grep -qFx $target $ghostty-cache-file 2>/dev/null)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add host to terminfo cache
|
||||||
|
fn ghostty-cache-host {|target|
|
||||||
|
var cache-dir = (path:dir $ghostty-cache-file)
|
||||||
|
|
||||||
|
# Create cache directory if needed
|
||||||
|
if (not (path:is-dir $cache-dir)) {
|
||||||
|
mkdir -p $cache-dir
|
||||||
|
}
|
||||||
|
|
||||||
|
# Atomic write to cache file
|
||||||
|
var temp-file = $ghostty-cache-file".tmp"
|
||||||
|
|
||||||
|
{
|
||||||
|
if (path:is-regular $ghostty-cache-file) {
|
||||||
|
cat $ghostty-cache-file
|
||||||
|
}
|
||||||
|
echo $target
|
||||||
|
} | sort -u > $temp-file
|
||||||
|
|
||||||
|
mv $temp-file $ghostty-cache-file
|
||||||
|
|
||||||
|
# Secure permissions
|
||||||
|
?chmod 600 $ghostty-cache-file 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
fn ssh-with-ghostty-integration {|@args|
|
fn ssh-with-ghostty-integration {|@args|
|
||||||
if (has-env GHOSTTY_SSH_INTEGRATION) {
|
if (has-env GHOSTTY_SSH_INTEGRATION) {
|
||||||
if (eq "term-only" $E:GHOSTTY_SSH_INTEGRATION) {
|
if (eq "term-only" $E:GHOSTTY_SSH_INTEGRATION) {
|
||||||
@ -127,17 +191,17 @@
|
|||||||
fn ssh-basic {|@args|
|
fn ssh-basic {|@args|
|
||||||
# Level: basic - TERM fix + environment variable propagation
|
# Level: basic - TERM fix + environment variable propagation
|
||||||
var env-vars = []
|
var env-vars = []
|
||||||
|
|
||||||
# Fix TERM compatibility
|
# Fix TERM compatibility
|
||||||
if (eq "xterm-ghostty" $E:TERM) {
|
if (eq "xterm-ghostty" $E:TERM) {
|
||||||
set env-vars = (conj $env-vars TERM=xterm-256color)
|
set env-vars = (conj $env-vars TERM=xterm-256color)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Propagate Ghostty shell integration environment variables
|
# Propagate Ghostty shell integration environment variables
|
||||||
if (not-eq "" $E:GHOSTTY_SHELL_FEATURES) {
|
if (not-eq "" $E:GHOSTTY_SHELL_FEATURES) {
|
||||||
set env-vars = (conj $env-vars GHOSTTY_SHELL_FEATURES=$E:GHOSTTY_SHELL_FEATURES)
|
set env-vars = (conj $env-vars GHOSTTY_SHELL_FEATURES=$E:GHOSTTY_SHELL_FEATURES)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Execute with environment variables if any were set
|
# Execute with environment variables if any were set
|
||||||
if (> (count $env-vars) 0) {
|
if (> (count $env-vars) 0) {
|
||||||
(external env) $@env-vars ssh $@args
|
(external env) $@env-vars ssh $@args
|
||||||
@ -147,22 +211,47 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ssh-full {|@args|
|
fn ssh-full {|@args|
|
||||||
# Full integration: Two-step terminfo installation
|
var target = (ghostty-get-ssh-target $@args)
|
||||||
|
|
||||||
|
# Check if we already know this host has terminfo
|
||||||
|
if (and (not-eq "" $target) (ghostty-host-has-terminfo $target)) {
|
||||||
|
# Direct connection with xterm-ghostty
|
||||||
|
var env-vars = [TERM=xterm-ghostty]
|
||||||
|
|
||||||
|
# Propagate Ghostty shell integration environment variables
|
||||||
|
if (not-eq "" $E:GHOSTTY_SHELL_FEATURES) {
|
||||||
|
set env-vars = (conj $env-vars GHOSTTY_SHELL_FEATURES=$E:GHOSTTY_SHELL_FEATURES)
|
||||||
|
}
|
||||||
|
|
||||||
|
(external env) $@env-vars ssh $@args
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Full integration: Install terminfo if needed
|
||||||
if (has-external infocmp) {
|
if (has-external infocmp) {
|
||||||
echo "Installing Ghostty terminfo on remote host..." >&2
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
infocmp -x xterm-ghostty 2>/dev/null | (external ssh) $@args 'tic -x - 2>/dev/null'
|
# Install terminfo only if needed
|
||||||
echo "Terminfo installed successfully. Connecting with full Ghostty support..." >&2
|
infocmp -x xterm-ghostty 2>/dev/null | (external ssh) $@args '
|
||||||
|
if ! infocmp xterm-ghostty >/dev/null 2>&1; then
|
||||||
# Step 2: Connect with xterm-ghostty since we know terminfo is now available
|
echo "Installing Ghostty terminfo..." >&2
|
||||||
|
tic -x - 2>/dev/null
|
||||||
|
fi
|
||||||
|
'
|
||||||
|
echo "Connecting with full Ghostty support..." >&2
|
||||||
|
|
||||||
|
# Cache this host for future connections
|
||||||
|
if (not-eq "" $target) {
|
||||||
|
ghostty-cache-host $target
|
||||||
|
}
|
||||||
|
|
||||||
|
# Connect with xterm-ghostty since terminfo is available
|
||||||
var env-vars = [TERM=xterm-ghostty]
|
var env-vars = [TERM=xterm-ghostty]
|
||||||
|
|
||||||
# Propagate Ghostty shell integration environment variables
|
# Propagate Ghostty shell integration environment variables
|
||||||
if (not-eq "" $E:GHOSTTY_SHELL_FEATURES) {
|
if (not-eq "" $E:GHOSTTY_SHELL_FEATURES) {
|
||||||
set env-vars = (conj $env-vars GHOSTTY_SHELL_FEATURES=$E:GHOSTTY_SHELL_FEATURES)
|
set env-vars = (conj $env-vars GHOSTTY_SHELL_FEATURES=$E:GHOSTTY_SHELL_FEATURES)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Normal SSH connection with Ghostty terminfo available
|
# Normal SSH connection with Ghostty terminfo available
|
||||||
(external env) $@env-vars ssh $@args
|
(external env) $@env-vars ssh $@args
|
||||||
return
|
return
|
||||||
@ -170,15 +259,16 @@
|
|||||||
echo "Terminfo installation failed. Using basic integration." >&2
|
echo "Terminfo installation failed. Using basic integration." >&2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Fallback to basic integration
|
# Fallback to basic integration
|
||||||
ssh-basic $@args
|
ssh-basic $@args
|
||||||
}
|
}
|
||||||
|
|
||||||
# Register SSH integration if enabled
|
# Register SSH integration if enabled
|
||||||
if (and (has-env GHOSTTY_SSH_INTEGRATION) (has-external ssh)) {
|
if (and (has-env GHOSTTY_SSH_INTEGRATION) (has-external ssh)) {
|
||||||
edit:add-var ssh~ $ssh-with-ghostty-integration~
|
edit:add-var ssh~ $ssh-with-ghostty-integration~
|
||||||
}
|
}
|
||||||
|
|
||||||
defer {
|
defer {
|
||||||
mark-prompt-start
|
mark-prompt-start
|
||||||
report-pwd
|
report-pwd
|
||||||
|
@ -86,8 +86,68 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# SSH integration wrapper
|
# SSH integration
|
||||||
if test -n "$GHOSTTY_SSH_INTEGRATION"
|
if test -n "$GHOSTTY_SSH_INTEGRATION"
|
||||||
|
# Cache file for tracking hosts with terminfo installed
|
||||||
|
set -l _ghostty_cache_file (string join / (test -n "$GHOSTTY_RESOURCES_DIR"; and echo "$GHOSTTY_RESOURCES_DIR"; or echo "$HOME/.config/ghostty") "terminfo_hosts")
|
||||||
|
|
||||||
|
# Extract target host from SSH arguments
|
||||||
|
function _ghostty_get_ssh_target
|
||||||
|
set -l target ""
|
||||||
|
set -l skip_next false
|
||||||
|
|
||||||
|
for arg in $argv
|
||||||
|
if test "$skip_next" = "true"
|
||||||
|
set skip_next false
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
# Skip flags that take arguments
|
||||||
|
if string match -qr '^-[bcDEeFIiJLlmOopQRSWw]$' -- "$arg"
|
||||||
|
set skip_next true
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
# Skip other flags
|
||||||
|
if string match -q -- '-*' "$arg"
|
||||||
|
continue
|
||||||
|
end
|
||||||
|
|
||||||
|
# This should be the target
|
||||||
|
set target "$arg"
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
echo "$target"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check if host has terminfo installed
|
||||||
|
function _ghostty_host_has_terminfo
|
||||||
|
set -l target $argv[1]
|
||||||
|
test -f "$_ghostty_cache_file"; and grep -qFx "$target" "$_ghostty_cache_file" 2>/dev/null
|
||||||
|
end
|
||||||
|
|
||||||
|
# Add host to terminfo cache
|
||||||
|
function _ghostty_cache_host
|
||||||
|
set -l target $argv[1]
|
||||||
|
set -l cache_dir (dirname "$_ghostty_cache_file")
|
||||||
|
|
||||||
|
# Create cache directory if needed
|
||||||
|
test -d "$cache_dir"; or mkdir -p "$cache_dir"
|
||||||
|
|
||||||
|
# Atomic write to cache file
|
||||||
|
begin
|
||||||
|
if test -f "$_ghostty_cache_file"
|
||||||
|
cat "$_ghostty_cache_file"
|
||||||
|
end
|
||||||
|
echo "$target"
|
||||||
|
end | sort -u > "$_ghostty_cache_file.tmp"; and mv "$_ghostty_cache_file.tmp" "$_ghostty_cache_file"
|
||||||
|
|
||||||
|
# Secure permissions
|
||||||
|
chmod 600 "$_ghostty_cache_file" 2>/dev/null
|
||||||
|
end
|
||||||
|
|
||||||
|
# Wrap `ssh` command to provide Ghostty SSH integration.
|
||||||
function ssh -d "Wrap ssh to provide Ghostty SSH integration"
|
function ssh -d "Wrap ssh to provide Ghostty SSH integration"
|
||||||
switch "$GHOSTTY_SSH_INTEGRATION"
|
switch "$GHOSTTY_SSH_INTEGRATION"
|
||||||
case term-only
|
case term-only
|
||||||
@ -136,22 +196,38 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|||||||
|
|
||||||
# Level: full - All features
|
# Level: full - All features
|
||||||
function _ghostty_ssh_full
|
function _ghostty_ssh_full
|
||||||
# Full integration: Two-step terminfo installation
|
set -l target (_ghostty_get_ssh_target $argv)
|
||||||
if type -q infocmp
|
|
||||||
echo "Installing Ghostty terminfo on remote host..." >&2
|
|
||||||
|
|
||||||
# Step 1: Install terminfo
|
# Check if we already know this host has terminfo
|
||||||
if infocmp -x xterm-ghostty 2>/dev/null | ssh $argv 'tic -x - 2>/dev/null'
|
if test -n "$target"; and _ghostty_host_has_terminfo "$target"
|
||||||
echo "Terminfo installed successfully. Connecting with full Ghostty support..." >&2
|
# Direct connection with xterm-ghostty
|
||||||
|
set --local env_vars TERM=xterm-ghostty
|
||||||
# Step 2: Connect with xterm-ghostty since we know terminfo is now available
|
if test -n "$GHOSTTY_SHELL_FEATURES"
|
||||||
|
set --append env_vars GHOSTTY_SHELL_FEATURES="$GHOSTTY_SHELL_FEATURES"
|
||||||
|
end
|
||||||
|
env $env_vars ssh $argv
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
# Full integration: Install terminfo if needed
|
||||||
|
if type -q infocmp
|
||||||
|
# Install terminfo only if needed
|
||||||
|
if infocmp -x xterm-ghostty 2>/dev/null | ssh $argv '
|
||||||
|
if ! infocmp xterm-ghostty >/dev/null 2>&1
|
||||||
|
echo "Installing Ghostty terminfo..." >&2
|
||||||
|
tic -x - 2>/dev/null
|
||||||
|
end
|
||||||
|
'
|
||||||
|
echo "Connecting with full Ghostty support..." >&2
|
||||||
|
|
||||||
|
# Cache this host for future connections
|
||||||
|
test -n "$target"; and _ghostty_cache_host "$target"
|
||||||
|
|
||||||
|
# Connect with xterm-ghostty since terminfo is available
|
||||||
set --local env_vars TERM=xterm-ghostty
|
set --local env_vars TERM=xterm-ghostty
|
||||||
|
|
||||||
# Propagate Ghostty shell integration environment variables
|
|
||||||
if test -n "$GHOSTTY_SHELL_FEATURES"
|
if test -n "$GHOSTTY_SHELL_FEATURES"
|
||||||
set --append env_vars GHOSTTY_SHELL_FEATURES="$GHOSTTY_SHELL_FEATURES"
|
set --append env_vars GHOSTTY_SHELL_FEATURES="$GHOSTTY_SHELL_FEATURES"
|
||||||
end
|
end
|
||||||
|
|
||||||
env $env_vars ssh $argv
|
env $env_vars ssh $argv
|
||||||
builtin return 0
|
builtin return 0
|
||||||
end
|
end
|
||||||
@ -162,6 +238,7 @@ function __ghostty_setup --on-event fish_prompt -d "Setup ghostty integration"
|
|||||||
_ghostty_ssh_basic $argv
|
_ghostty_ssh_basic $argv
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Setup prompt marking
|
# Setup prompt marking
|
||||||
function __ghostty_mark_prompt_start --on-event fish_prompt --on-event fish_cancel --on-event fish_posterror
|
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.
|
# If we never got the output end event, then we need to send it now.
|
||||||
|
@ -243,9 +243,69 @@ _ghostty_deferred_init() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# SSH
|
# SSH
|
||||||
if [[ -n "$GHOSTTY_SSH_INTEGRATION" ]]; then
|
if [[ -n "$GHOSTTY_SSH_INTEGRATION" ]]; then
|
||||||
|
# Cache file for tracking hosts with terminfo installed
|
||||||
|
_ghostty_cache_file="${GHOSTTY_RESOURCES_DIR:-$HOME/.config/ghostty}/terminfo_hosts"
|
||||||
|
|
||||||
|
# Extract target host from SSH arguments
|
||||||
|
_ghostty_get_ssh_target() {
|
||||||
|
local target=""
|
||||||
|
local skip_next=false
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
if [[ "$skip_next" == "true" ]]; then
|
||||||
|
skip_next=false
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Skip flags that take arguments
|
||||||
|
if [[ "$arg" =~ ^-[bcDEeFIiJLlmOopQRSWw]$ ]]; then
|
||||||
|
skip_next=true
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Skip other flags
|
||||||
|
if [[ "$arg" =~ ^- ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# This should be the target
|
||||||
|
target="$arg"
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$target"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if host has terminfo installed
|
||||||
|
_ghostty_host_has_terminfo() {
|
||||||
|
local target="$1"
|
||||||
|
[[ -f "$_ghostty_cache_file" ]] && grep -qFx "$target" "$_ghostty_cache_file" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add host to terminfo cache
|
||||||
|
_ghostty_cache_host() {
|
||||||
|
local target="$1"
|
||||||
|
local cache_dir
|
||||||
|
cache_dir="$(dirname "$_ghostty_cache_file")"
|
||||||
|
|
||||||
|
# Create cache directory if needed
|
||||||
|
[[ ! -d "$cache_dir" ]] && mkdir -p "$cache_dir"
|
||||||
|
|
||||||
|
# Atomic write to cache file
|
||||||
|
{
|
||||||
|
if [[ -f "$_ghostty_cache_file" ]]; then
|
||||||
|
cat "$_ghostty_cache_file"
|
||||||
|
fi
|
||||||
|
echo "$target"
|
||||||
|
} | sort -u > "$_ghostty_cache_file.tmp" && mv "$_ghostty_cache_file.tmp" "$_ghostty_cache_file"
|
||||||
|
|
||||||
|
# Secure permissions
|
||||||
|
chmod 600 "$_ghostty_cache_file" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
# Wrap `ssh` command to provide Ghostty SSH integration
|
# Wrap `ssh` command to provide Ghostty SSH integration
|
||||||
ssh() {
|
ssh() {
|
||||||
case "$GHOSTTY_SSH_INTEGRATION" in
|
case "$GHOSTTY_SSH_INTEGRATION" in
|
||||||
@ -296,27 +356,41 @@ _ghostty_deferred_init() {
|
|||||||
|
|
||||||
# Level: full - All features
|
# Level: full - All features
|
||||||
_ghostty_ssh_full() {
|
_ghostty_ssh_full() {
|
||||||
# Full integration: Two-step terminfo installation
|
local target
|
||||||
|
target="$(_ghostty_get_ssh_target "$@")"
|
||||||
|
|
||||||
|
# Check if we already know this host has terminfo
|
||||||
|
if [[ -n "$target" ]] && _ghostty_host_has_terminfo "$target"; then
|
||||||
|
# Direct connection with xterm-ghostty
|
||||||
|
local env_vars=("TERM=xterm-ghostty")
|
||||||
|
[[ -n "$GHOSTTY_SHELL_FEATURES" ]] && env_vars+=("GHOSTTY_SHELL_FEATURES=$GHOSTTY_SHELL_FEATURES")
|
||||||
|
env "${env_vars[@]}" ssh "$@"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Full integration: Install terminfo if needed
|
||||||
if builtin command -v infocmp >/dev/null 2>&1; then
|
if builtin command -v infocmp >/dev/null 2>&1; then
|
||||||
echo "Installing Ghostty terminfo on remote host..." >&2
|
# Install terminfo only if needed
|
||||||
|
if infocmp -x xterm-ghostty 2>/dev/null | builtin command ssh "$@" '
|
||||||
# Step 1: Install terminfo
|
if ! infocmp xterm-ghostty >/dev/null 2>&1; then
|
||||||
if infocmp -x xterm-ghostty 2>/dev/null | builtin command ssh "$@" 'tic -x - 2>/dev/null'; then
|
echo "Installing Ghostty terminfo..." >&2
|
||||||
echo "Terminfo installed successfully. Connecting with full Ghostty support..." >&2
|
tic -x - 2>/dev/null
|
||||||
|
fi
|
||||||
# Step 2: Connect with xterm-ghostty since we know terminfo is now available
|
'; then
|
||||||
|
echo "Connecting with full Ghostty support..." >&2
|
||||||
|
|
||||||
|
# Cache this host for future connections
|
||||||
|
[[ -n "$target" ]] && _ghostty_cache_host "$target"
|
||||||
|
|
||||||
|
# Connect with xterm-ghostty since terminfo is available
|
||||||
local env_vars=("TERM=xterm-ghostty")
|
local env_vars=("TERM=xterm-ghostty")
|
||||||
|
|
||||||
# Propagate Ghostty shell integration environment variables
|
|
||||||
[[ -n "$GHOSTTY_SHELL_FEATURES" ]] && env_vars+=("GHOSTTY_SHELL_FEATURES=$GHOSTTY_SHELL_FEATURES")
|
[[ -n "$GHOSTTY_SHELL_FEATURES" ]] && env_vars+=("GHOSTTY_SHELL_FEATURES=$GHOSTTY_SHELL_FEATURES")
|
||||||
|
|
||||||
# Normal SSH connection with Ghostty terminfo available
|
|
||||||
env "${env_vars[@]}" ssh "$@"
|
env "${env_vars[@]}" ssh "$@"
|
||||||
builtin return 0
|
builtin return 0
|
||||||
fi
|
fi
|
||||||
echo "Terminfo installation failed. Using basic integration." >&2
|
echo "Terminfo installation failed. Using basic integration." >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Fallback to basic integration
|
# Fallback to basic integration
|
||||||
_ghostty_ssh_basic "$@"
|
_ghostty_ssh_basic "$@"
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user