Change summary
dot_config/private_fish/functions/__zmx_choose_session.fish | 49 +
dot_config/private_fish/functions/__zmx_format_sessions.fish | 16
dot_config/private_fish/functions/zmx-remote-install.fish | 159 ++++++
dot_config/private_fish/functions/zmx-select.fish | 11
dot_config/private_fish/functions/zssh-select.fish | 41 +
dot_config/private_fish/functions/zssh.fish | 42 +
6 files changed, 318 insertions(+)
Detailed changes
@@ -0,0 +1,49 @@
+function __zmx_choose_session --description "Choose or create a zmx session name with fzf"
+ argparse 'p/preview=' -- $argv
+ or return 1
+
+ if not type -q fzf
+ echo "__zmx_choose_session: fzf is not installed or not on PATH" >&2
+ return 127
+ end
+
+ set -l preview_command 'zmx history {1}'
+ if set -q _flag_preview
+ set preview_command $_flag_preview
+ end
+
+ set -l display
+ read -lz display
+
+ set -l output_file (mktemp)
+ begin
+ if test -n "$display"
+ printf "%s" $display
+ end
+ end | fzf \
+ --print-query \
+ --expect=ctrl-n \
+ --height=80% \
+ --reverse \
+ --prompt="zmx> " \
+ --header="Enter: select | Ctrl-N: create new" \
+ --preview=$preview_command \
+ --preview-window=right:60%:follow \
+ >$output_file
+
+ set -l fzf_status $status
+ set -l query (sed -n '1p' $output_file)
+ set -l key (sed -n '2p' $output_file)
+ set -l selected (sed -n '3p' $output_file)
+ rm -f $output_file
+
+ if test "$key" = ctrl-n; and test -n "$query"
+ echo $query
+ else if test $fzf_status -eq 0; and test -n "$selected"
+ string split -f1 ' ' -- $selected
+ else if test -n "$query"
+ echo $query
+ else
+ return 130
+ end
+end
@@ -0,0 +1,16 @@
+function __zmx_format_sessions --description "Format zmx list output for fzf"
+ while read -l line
+ set -l fields (string split \t -- $line)
+
+ if test (count $fields) -lt 5
+ continue
+ end
+
+ set -l name (string replace -r '^session_name=' '' -- $fields[1])
+ set -l pid (string replace -r '^pid=' '' -- $fields[2])
+ set -l clients (string replace -r '^clients=' '' -- $fields[3])
+ set -l dir (string replace -r '^started_in=' '' -- $fields[5])
+
+ printf "%-20s pid:%-8s clients:%-2s %s\n" $name $pid $clients $dir
+ end
+end
@@ -0,0 +1,159 @@
+function zmx-remote-install --description "Install zmx on a remote host by streaming a locally downloaded release tarball"
+ argparse 'h/help' 'upgrade-only' 'v/version=' -- $argv
+ or return 1
+
+ if set -q _flag_help; or test (count $argv) -ne 1
+ echo "Usage: zmx-remote-install [--upgrade-only] [--version VERSION] [user@]host"
+ echo "Example: zmx-remote-install hel1"
+ echo "By default, installs the active local zmx version."
+ echo "With --upgrade-only, only upgrades an existing remote zmx that is older than local."
+ return 0
+ end
+
+ set -l destination $argv[1]
+ set -l desired_version
+
+ if set -q _flag_version
+ set desired_version $_flag_version
+ else if type -q zmx
+ set desired_version (zmx version | awk 'NR == 1 {print $2}')
+ else if type -q mise
+ set desired_version (mise exec -- zmx version | awk 'NR == 1 {print $2}')
+ end
+
+ if test -z "$desired_version"
+ echo "zmx-remote-install: could not determine local zmx version from zmx or mise" >&2
+ return 1
+ end
+
+ mkdir -p "$HOME/.ssh/controlmasters"
+
+ set -l remote_version (command ssh \
+ -o ControlMaster=auto \
+ -o ControlPersist=10m \
+ -o ControlPath="$HOME/.ssh/controlmasters/%C" \
+ $destination \
+ "sh -c 'PATH=\"\$HOME/.local/bin:\$PATH\"; if command -v zmx >/dev/null 2>&1; then zmx version | awk \"NR == 1 {print \\\$2}\"; fi'")
+ or return $status
+
+ if test -z "$remote_version"
+ if set -q _flag_upgrade_only
+ return 0
+ end
+
+ echo "Remote zmx is not installed; installing local zmx $desired_version..." >&2
+ else if test "$remote_version" = "$desired_version"
+ return 0
+ else
+ if not type -q semver
+ echo "zmx-remote-install: semver is required to compare local zmx $desired_version with remote zmx $remote_version" >&2
+ return 1
+ end
+
+ if not semver "$desired_version" >/dev/null 2>&1; or not semver "$remote_version" >/dev/null 2>&1
+ echo "zmx-remote-install: cannot compare local zmx $desired_version with remote zmx $remote_version; refusing to sidegrade" >&2
+ return 1
+ end
+
+ if not semver -r ">$remote_version" "$desired_version" >/dev/null 2>&1
+ return 0
+ end
+
+ echo "Remote zmx is $remote_version; upgrading to local zmx $desired_version..." >&2
+ end
+
+ set -l remote_platform (command ssh \
+ -o ControlMaster=auto \
+ -o ControlPersist=10m \
+ -o ControlPath="$HOME/.ssh/controlmasters/%C" \
+ $destination \
+ "sh -c 'printf \"%s %s\\n\" \"\$(uname -s)\" \"\$(uname -m)\"'")
+ or return $status
+
+ set -l remote_os (string split ' ' -- $remote_platform)[1]
+ set -l remote_arch (string split ' ' -- $remote_platform)[2]
+ set -l zmx_os
+ set -l zmx_arch
+
+ switch $remote_os
+ case Linux
+ set zmx_os linux
+ case Darwin
+ set zmx_os macos
+ case '*'
+ echo "zmx-remote-install: unsupported remote OS '$remote_os'" >&2
+ return 2
+ end
+
+ switch $remote_arch
+ case x86_64 amd64
+ set zmx_arch x86_64
+ case aarch64 arm64
+ set zmx_arch aarch64
+ case '*'
+ echo "zmx-remote-install: unsupported remote architecture '$remote_arch'" >&2
+ return 2
+ end
+
+ set -l archive "zmx-$desired_version-$zmx_os-$zmx_arch.tar.gz"
+ set -l base_url "https://zmx.sh/a"
+ set -l temp_dir (mktemp -d)
+ set -l archive_path "$temp_dir/$archive"
+ set -l checksum_path "$archive_path.sha256"
+
+ if test -z "$temp_dir"
+ echo "zmx-remote-install: failed to create a temporary directory" >&2
+ return 1
+ end
+
+ echo "Downloading $archive..." >&2
+ if not curl -fsSL "$base_url/$archive" -o "$archive_path"
+ rm -rf $temp_dir
+ return 1
+ end
+
+ if curl -fsSL "$base_url/$archive.sha256" -o "$checksum_path"
+ set -l expected (awk '{print $1}' "$checksum_path")
+ set -l actual
+
+ if type -q sha256sum
+ set actual (sha256sum "$archive_path" | awk '{print $1}')
+ else if type -q shasum
+ set actual (shasum -a 256 "$archive_path" | awk '{print $1}')
+ else
+ echo "zmx-remote-install: no local sha256sum or shasum found; refusing to install unverified archive" >&2
+ rm -rf $temp_dir
+ return 1
+ end
+
+ if test "$expected" != "$actual"
+ echo "zmx-remote-install: checksum verification failed for $archive" >&2
+ rm -rf $temp_dir
+ return 1
+ end
+ else
+ echo "zmx-remote-install: could not download checksum for $archive; refusing to install unverified archive" >&2
+ rm -rf $temp_dir
+ return 1
+ end
+
+ echo "Installing zmx $desired_version on $destination..." >&2
+ if not command ssh \
+ -o ControlMaster=auto \
+ -o ControlPersist=10m \
+ -o ControlPath="$HOME/.ssh/controlmasters/%C" \
+ $destination \
+ "sh -c 'mkdir -p \"\$HOME/.local/bin\" && tmp=\$(mktemp \"\$HOME/.local/bin/.zmx.XXXXXX\") && tar -xOzf - zmx > \"\$tmp\" && chmod 755 \"\$tmp\" && mv \"\$tmp\" \"\$HOME/.local/bin/zmx\"'" <"$archive_path"
+ rm -rf $temp_dir
+ return 1
+ end
+
+ rm -rf $temp_dir
+
+ command ssh \
+ -o ControlMaster=auto \
+ -o ControlPersist=10m \
+ -o ControlPath="$HOME/.ssh/controlmasters/%C" \
+ $destination \
+ "sh -c 'PATH=\"\$HOME/.local/bin:\$PATH\"; zmx version'"
+end
@@ -0,0 +1,11 @@
+function zmx-select --description "Fuzzy-find or create a zmx session"
+ if not type -q zmx
+ echo "zmx-select: zmx is not installed or not on PATH" >&2
+ return 127
+ end
+
+ set -l session_name (zmx list 2>/dev/null | __zmx_format_sessions | __zmx_choose_session --preview 'zmx history {1}')
+ or return $status
+
+ zmx attach $session_name
+end
@@ -0,0 +1,41 @@
+function zssh-select --description "Fuzzy-find or create a zmx session on a remote host"
+ argparse 'h/help' 'install' -- $argv
+ or return 1
+
+ if set -q _flag_help; or test (count $argv) -ne 1
+ echo "Usage: zssh-select [--install] [user@]host"
+ echo "Example: zssh-select hel1"
+ return 0
+ end
+
+ set -l destination $argv[1]
+
+ if not string match -qr '^[A-Za-z0-9._@:%+-]+$' -- $destination
+ echo "zssh-select: destination contains characters that cannot be safely used in the preview command" >&2
+ return 2
+ end
+
+ mkdir -p "$HOME/.ssh/controlmasters"
+
+ if set -q _flag_install
+ zmx-remote-install $destination
+ or return $status
+ else
+ zmx-remote-install --upgrade-only $destination
+ or return $status
+ end
+
+ set -l remote_list (command ssh \
+ -o ControlMaster=auto \
+ -o ControlPersist=10m \
+ -o ControlPath="$HOME/.ssh/controlmasters/%C" \
+ $destination \
+ "sh -c 'PATH=\"\$HOME/.local/bin:\$PATH\"; command -v zmx >/dev/null 2>&1 || { echo \"zssh-select: zmx is not installed on the remote host or is not on PATH; retry with zssh-select --install\" >&2; exit 127; }; zmx list 2>/dev/null'")
+ or return $status
+
+ set -l preview_command "ssh -o ControlMaster=auto -o ControlPersist=10m -o ControlPath=$HOME/.ssh/controlmasters/%C $destination 'sh -c '\''PATH=\"\$HOME/.local/bin:\$PATH\"; zmx history {1}'\'' '"
+ set -l session_name (printf '%s\n' $remote_list | __zmx_format_sessions | __zmx_choose_session --preview $preview_command)
+ or return $status
+
+ zssh $destination $session_name
+end
@@ -0,0 +1,42 @@
+function zssh --description "SSH to a host and attach to a remote zmx session"
+ argparse 'h/help' 'install' -- $argv
+ or return 1
+
+ if set -q _flag_help; or test (count $argv) -lt 1
+ echo "Usage: zssh [--install] [user@]host [session]"
+ echo "Example: zssh devbox term"
+ return 0
+ end
+
+ set -l destination $argv[1]
+ set -l session main
+
+ if test (count $argv) -ge 2
+ set session $argv[2]
+ end
+
+ if not string match -qr '^[A-Za-z0-9._:-]+$' -- $session
+ echo "zssh: session names may only contain letters, numbers, dots, underscores, colons, and hyphens" >&2
+ return 2
+ end
+
+ mkdir -p "$HOME/.ssh/controlmasters"
+
+ if set -q _flag_install
+ zmx-remote-install $destination
+ or return $status
+ else
+ zmx-remote-install --upgrade-only $destination
+ or return $status
+ end
+
+ set -l remote_command "sh -c 'PATH=\"\$HOME/.local/bin:\$PATH\"; command -v zmx >/dev/null 2>&1 || { echo \"zssh: zmx is not installed on the remote host or is not on PATH; retry with zssh --install\" >&2; exit 127; }; exec zmx attach \"\$1\"' sh '$session'"
+
+ command ssh \
+ -o ControlMaster=auto \
+ -o ControlPersist=10m \
+ -o ControlPath="$HOME/.ssh/controlmasters/%C" \
+ -o RequestTTY=yes \
+ -o RemoteCommand="$remote_command" \
+ $destination
+end