summaryrefslogtreecommitdiff
path: root/src/shell-integration
diff options
context:
space:
mode:
authorJon Parise <jon@indelible.org>2025-07-09 21:44:32 -0400
committerJon Parise <jon@indelible.org>2025-07-09 22:19:13 -0400
commit5cdfe3d70e40fb7f4b2f0ed5ed710ab7d887ae01 (patch)
tree7d6bb3dd3bea0381159b2ff7227d08d9027a0454 /src/shell-integration
parentd0c5191aef39ce90e96a7f4b53070b9d26d58b7f (diff)
elvish: revise the ssh integration
The previous implementation wasn't quite working. This revision reworks it in a few ways: - Fix various syntax issues - Redirect the `ssh` command to our 'ssh-integration' function - Locate the `ghostty` binary using $GHOSTTY_BIN_DIR - Use os:temp-dir to create our temporary directory Also, consistently use 2-space indents, which is the Elvish standard.
Diffstat (limited to 'src/shell-integration')
-rw-r--r--src/shell-integration/elvish/lib/ghostty-integration.elv160
1 files changed, 76 insertions, 84 deletions
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 (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"
- )
- }
+ # 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")
+ }
- # 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 (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
+ }
+ 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~
+ }
}