main zmx / src / completions.zig
Benjamin Pollack  ·  2026-05-12
  1const std = @import("std");
  2
  3pub const Shell = enum {
  4    bash,
  5    zsh,
  6    fish,
  7    nu,
  8
  9    pub fn fromString(s: []const u8) ?Shell {
 10        if (std.mem.eql(u8, s, "bash")) return .bash;
 11        if (std.mem.eql(u8, s, "zsh")) return .zsh;
 12        if (std.mem.eql(u8, s, "fish")) return .fish;
 13        if (std.mem.eql(u8, s, "nu")) return .nu;
 14
 15        return null;
 16    }
 17
 18    pub fn getCompletionScript(self: Shell) []const u8 {
 19        return switch (self) {
 20            .bash => bash_completions,
 21            .zsh => zsh_completions,
 22            .fish => fish_completions,
 23            .nu => nu_completions,
 24        };
 25    }
 26};
 27
 28const bash_completions =
 29    \\_zmx_completions() {
 30    \\  local cur prev words cword
 31    \\  COMPREPLY=()
 32    \\  cur="${COMP_WORDS[COMP_CWORD]}"
 33    \\  prev="${COMP_WORDS[COMP_CWORD-1]}"
 34    \\
 35    \\  local commands="attach run send detach list completions kill history version help"
 36    \\
 37    \\  if [[ $COMP_CWORD -eq 1 ]]; then
 38    \\    COMPREPLY=($(compgen -W "$commands" -- "$cur"))
 39    \\    return 0
 40    \\  fi
 41    \\
 42    \\  case "$prev" in
 43    \\    attach|run|send|kill|history)
 44    \\      local sessions=$(zmx list --short 2>/dev/null | tr '\n' ' ')
 45    \\      COMPREPLY=($(compgen -W "$sessions" -- "$cur"))
 46    \\      ;;
 47    \\    completions)
 48    \\      COMPREPLY=($(compgen -W "bash zsh fish" -- "$cur"))
 49    \\      ;;
 50    \\    list)
 51    \\      COMPREPLY=($(compgen -W "--short" -- "$cur"))
 52    \\      ;;
 53    \\    *)
 54    \\      ;;
 55    \\  esac
 56    \\}
 57    \\
 58    \\complete -o bashdefault -o default -F _zmx_completions zmx
 59;
 60
 61const zsh_completions =
 62    \\#compdef zmx
 63    \\_zmx() {
 64    \\  local context state state_descr line
 65    \\  typeset -A opt_args
 66    \\
 67    \\  _arguments -C \
 68    \\    '1: :->commands' \
 69    \\    '2: :->args' \
 70    \\    '*: :->trailing' \
 71    \\    && return 0
 72    \\
 73    \\  case $state in
 74    \\    commands)
 75    \\      local -a commands
 76    \\      commands=(
 77    \\        'attach:Attach to session, creating if needed'
 78    \\        'run:Send command without attaching'
 79    \\        'send:Send raw input to session PTY'
 80    \\        'detach:Detach all clients from current session'
 81    \\        'list:List active sessions'
 82    \\        'completions:Shell completion scripts'
 83    \\        'kill:Kill a session'
 84    \\        'history:Output session scrollback'
 85    \\        'version:Show version'
 86    \\        'help:Show help message'
 87    \\      )
 88    \\      _describe 'command' commands
 89    \\      ;;
 90    \\    args)
 91    \\      case $words[2] in
 92    \\        attach|a|kill|k|run|r|send|s|history|hi)
 93    \\          _zmx_sessions
 94    \\          ;;
 95    \\        completions|c)
 96    \\          _values 'shell' 'bash' 'zsh' 'fish'
 97    \\          ;;
 98    \\        list|l)
 99    \\          _values 'options' '--short'
100    \\          ;;
101    \\      esac
102    \\      ;;
103    \\    trailing)
104    \\      # Additional args for commands like 'attach' or 'run'
105    \\      ;;
106    \\  esac
107    \\}
108    \\
109    \\_zmx_sessions() {
110    \\  local -a sessions
111    \\
112    \\  local local_sessions=$(zmx list --short 2>/dev/null)
113    \\  if [[ -n "$local_sessions" ]]; then
114    \\    sessions+=(${(f)local_sessions})
115    \\  fi
116    \\
117    \\  _describe 'local session' sessions
118    \\}
119    \\
120    \\compdef _zmx zmx
121;
122
123const fish_completions =
124    \\complete -c zmx -f
125    \\
126    \\# zmx flags
127    \\complete -c zmx -x -n '__fish_is_nth_token 1' -s v -l version -d 'Show version'
128    \\complete -c zmx -x -n '__fish_is_nth_token 1' -s h -d 'Show help message'
129    \\
130    \\# zmx subcommands
131    \\complete -c zmx -n "__fish_is_nth_token 1" -a attach -d 'Attach to session, creating if needed'
132    \\complete -c zmx -n "__fish_is_nth_token 1" -a run -d 'Send command without attaching'
133    \\complete -c zmx -n "__fish_is_nth_token 1" -a send -d 'Send raw input to session PTY'
134    \\complete -c zmx -n "__fish_is_nth_token 1" -a write -d 'Write stdin to file_path through the session'
135    \\complete -c zmx -n "__fish_is_nth_token 1" -a detach -d 'Detach all clients (ctrl+\ for current client)'
136    \\complete -c zmx -n "__fish_is_nth_token 1" -a list -d 'List active sessions'
137    \\complete -c zmx -n "__fish_is_nth_token 1" -a kill -d 'Kill session and all attached clients'
138    \\complete -c zmx -n "__fish_is_nth_token 1" -a history -d 'Output session scrollback'
139    \\complete -c zmx -n "__fish_is_nth_token 1" -a wait -d 'Wait for session tasks to complete'
140    \\complete -c zmx -n "__fish_is_nth_token 1" -a tail -d 'Follow session output'
141    \\complete -c zmx -n "__fish_is_nth_token 1" -a completions -d 'Shell completions (bash, zsh, fish)'
142    \\complete -c zmx -n "__fish_is_nth_token 1" -a version -d 'Show version'
143    \\complete -c zmx -n "__fish_is_nth_token 1" -a help -d 'Show help message'
144    \\
145    \\# Complete session names and shells
146    \\complete -c zmx -n "__fish_is_nth_token 2; and __fish_seen_subcommand_from a attach r run s send wr write hi history" -a '(zmx list --short 2>/dev/null)' -d 'Session name'
147    \\complete -c zmx -n "not __fish_is_nth_token 1; and __fish_seen_subcommand_from k kill w wait t tail" -a '(zmx list --short 2>/dev/null)' -d 'Session name'
148    \\
149    \\complete -c zmx -n "__fish_is_nth_token 2; and __fish_seen_subcommand_from c completions" -a 'bash zsh fish' -d Shell
150    \\
151    \\# Subcommand flags
152    \\complete -c zmx -n "__fish_seen_subcommand_from r run" -s d -d 'Detach from the calling terminal; use `wait` to track its status'
153    \\complete -c zmx -n "__fish_seen_subcommand_from r run" -l fish -d 'Required when the session runs fish shell'
154    \\complete -c zmx -n "__fish_seen_subcommand_from l list" -l short -d 'Short output'
155    \\complete -c zmx -n "__fish_seen_subcommand_from k kill" -l force -d 'Force kill'
156    \\complete -c zmx -n "__fish_seen_subcommand_from hi history" -l vt -d 'History format for escape sequences'
157    \\complete -c zmx -n "__fish_seen_subcommand_from hi history" -l html -d 'History format for escape sequences'
158;
159
160const nu_completions =
161    \\def "nu-complete zmx sessions" [] {
162    \\    zmx list --short | lines
163    \\}
164    \\
165    \\def "nu-complete zmx complete" [] {
166    \\    [bash fish nu zsh]
167    \\}
168    \\
169    \\export extern "zmx attach" [
170    \\    name: string@"nu-complete zmx sessions"
171    \\    ...rest: string
172    \\]
173    \\
174    \\export extern "zmx run" [
175    \\    name: string@"nu-complete zmx sessions"
176    \\    -d
177    \\    --fish
178    \\    ...rest: string
179    \\]
180    \\
181    \\export extern "zmx write" [
182    \\    name: string@"nu-complete zmx sessions"
183    \\    path: path
184    \\]
185    \\
186    \\export extern "zmx kill" [
187    \\    --force
188    \\    name: string@"nu-complete zmx sessions"
189    \\]
190    \\
191    \\export extern "zmx detach" []
192    \\export extern "zmx list" [--short]
193    \\export extern "zmx history" [name: string@"nu-complete zmx sessions", --vt, --html]
194    \\export extern "zmx wait" [...sessions: string@"nu-complete zmx sessions"]
195    \\export extern "zmx tail" [...sessions: string@"nu-complete zmx sessions"]
196    \\export extern "zmx version" []
197    \\export extern "completions" [shell: string@"nu-complete zmx complete"]
198    \\export extern "zmx help" []
199;