diff --git a/.editorconfig b/.editorconfig index d305bd294..4e9bec6ce 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,6 +1,6 @@ root = true -[*.{sh,bash}] +[*.{sh,bash,elv}] indent_size = 2 indent_style = space diff --git a/src/shell-integration/elvish/lib/ghostty-integration.elv b/src/shell-integration/elvish/lib/ghostty-integration.elv index 4e95b251f..6d0d19f4f 100644 --- a/src/shell-integration/elvish/lib/ghostty-integration.elv +++ b/src/shell-integration/elvish/lib/ghostty-integration.elv @@ -38,6 +38,9 @@ { use str + # List of enabled shell integration features + var features = [(str:split ',' $E:GHOSTTY_SHELL_FEATURES)] + # helper used by `mark-*` functions fn set-prompt-state {|new| set-env __ghostty_prompt_state $new } @@ -98,93 +101,81 @@ (external sudo) $@args } - # SSH Integration - use str + fn ssh-integration {|@args| + var ssh-term = "xterm-256color" + var ssh-opts = [] - if (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-) { - fn ssh {|@args| - var ssh-term = "xterm-256color" - var ssh-opts = [] + # Configure environment variables for remote session + if (has-value $features ssh-env) { + set ssh-opts = (conj $ssh-opts ^ + -o "SetEnv COLORTERM=truecolor" ^ + -o "SendEnv TERM_PROGRAM TERM_PROGRAM_VERSION") + } - # Configure environment variables for remote session - if (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-env) { - set ssh-opts = (conj $ssh-opts - -o "SetEnv COLORTERM=truecolor" - -o "SendEnv TERM_PROGRAM TERM_PROGRAM_VERSION" - ) + if (has-value $features ssh-terminfo) { + var ssh-user = "" + var ssh-hostname = "" + + # Parse ssh config + for line [((external ssh) -G $@args)] { + var parts = [(str:fields $line)] + if (> (count $parts) 1) { + var ssh-key = $parts[0] + var ssh-value = $parts[1] + if (eq $ssh-key user) { + set ssh-user = $ssh-value + } elif (eq $ssh-key hostname) { + set ssh-hostname = $ssh-value } - - # Install terminfo on remote host if needed - if (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-terminfo) { - var ssh-user = "" - var ssh-hostname = "" - - # Parse ssh config - var ssh-config = (external ssh -G $@args 2>/dev/null | slurp) - for line (str:split "\n" $ssh-config) { - var parts = (str:split " " $line) - if (> (count $parts) 1) { - var ssh-key = $parts[0] - var ssh-value = $parts[1] - if (eq $ssh-key user) { - set ssh-user = $ssh-value - } elif (eq $ssh-key hostname) { - set ssh-hostname = $ssh-value - } - if (and (not-eq $ssh-user "") (not-eq $ssh-hostname "")) { - break - } - } - } - - if (not-eq $ssh-hostname "") { - var ssh-target = $ssh-user"@"$ssh-hostname - - # Check if terminfo is already cached - if (and (has-external ghostty) (bool ?(external ghostty +ssh-cache --host=$ssh-target >/dev/null 2>&1))) { - set ssh-term = "xterm-ghostty" - } elif (has-external infocmp) { - var ssh-terminfo = (external infocmp -0 -x xterm-ghostty 2>/dev/null | slurp) - - if (not-eq $ssh-terminfo "") { - echo "Setting up xterm-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" - - if (bool ?(echo $ssh-terminfo | 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 - ' 2>/dev/null)) { - set ssh-term = "xterm-ghostty" - set ssh-opts = (conj $ssh-opts -o ControlPath=$ssh-cpath) - - # Cache successful installation - if (has-external ghostty) { - external ghostty +ssh-cache --add=$ssh-target >/dev/null 2>&1 - } - } else { - echo "Warning: Failed to install terminfo." >&2 - } - } else { - echo "Warning: Could not generate terminfo data." >&2 - } - } else { - echo "Warning: ghostty command not available for cache management." >&2 - } - } + if (and (not-eq $ssh-user "") (not-eq $ssh-hostname "")) { + break } - - # Execute SSH with TERM environment variable - external E:TERM=$ssh-term ssh $@ssh-opts $@args + } } + + if (not-eq $ssh-hostname "") { + var ghostty = $E:GHOSTTY_BIN_DIR/"ghostty" + var ssh-target = $ssh-user"@"$ssh-hostname + + # Check if terminfo is already cached + if (bool ?($ghostty +ssh-cache --host=$ssh-target)) { + set ssh-term = "xterm-ghostty" + } elif (has-external infocmp) { + var ssh-terminfo = ((external infocmp) -0 -x xterm-ghostty 2>/dev/null | slurp) + + if (not-eq $ssh-terminfo "") { + echo "Setting up xterm-ghostty terminfo on "$ssh-hostname"..." >&2 + + use os + var ssh-cpath-dir = (os:temp-dir "ghostty-ssh-"$ssh-user".*") + var ssh-cpath = $ssh-cpath-dir"/socket" + + if (bool ?(echo $ssh-terminfo | (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 + ' 2>/dev/null)) { + set ssh-term = "xterm-ghostty" + set ssh-opts = (conj $ssh-opts -o ControlPath=$ssh-cpath) + + # Cache successful installation + $ghostty +ssh-cache --add=$ssh-target >/dev/null + } else { + echo "Warning: Failed to install terminfo." >&2 + } + } else { + echo "Warning: Could not generate terminfo data." >&2 + } + } else { + echo "Warning: ghostty command not available for cache management." >&2 + } + } + } + + with [E:TERM = $ssh-term] { + (external ssh) $@ssh-opts $@args + } } defer { @@ -196,8 +187,6 @@ set edit:after-readline = (conj $edit:after-readline $mark-output-start~) set edit:after-command = (conj $edit:after-command $mark-output-end~) - var features = [(str:split ',' $E:GHOSTTY_SHELL_FEATURES)] - if (has-value $features title) { set after-chdir = (conj $after-chdir {|_| report-pwd }) } @@ -210,4 +199,7 @@ if (and (has-value $features sudo) (not-eq "" $E:TERMINFO) (has-external sudo)) { edit:add-var sudo~ $sudo-with-terminfo~ } + if (and (str:contains $E:GHOSTTY_SHELL_FEATURES ssh-) (has-external ssh)) { + edit:add-var ssh~ $ssh-integration~ + } }