main zmx / src / completions.zig
Mohamad Yahia  ·  2026-09-06
  1const std = @import("std");
  2
  3pub const Shell = enum {
  4    bash,
  5    zsh,
  6    fish,
  7    nu,
  8    yash,
  9
 10    pub fn fromString(s: []const u8) ?Shell {
 11        if (std.mem.eql(u8, s, "bash")) return .bash;
 12        if (std.mem.eql(u8, s, "zsh")) return .zsh;
 13        if (std.mem.eql(u8, s, "fish")) return .fish;
 14        if (std.mem.eql(u8, s, "nu")) return .nu;
 15        if (std.mem.eql(u8, s, "yash")) return .yash;
 16
 17        return null;
 18    }
 19
 20    pub fn getCompletionScript(self: Shell) []const u8 {
 21        return switch (self) {
 22            .bash => bash_completions,
 23            .zsh => zsh_completions,
 24            .fish => fish_completions,
 25            .nu => nu_completions,
 26            .yash => yash_completions,
 27        };
 28    }
 29};
 30
 31const bash_completions =
 32    \\_zmx_completions() {
 33    \\  local cur prev words cword
 34    \\  COMPREPLY=()
 35    \\  cur="${COMP_WORDS[COMP_CWORD]}"
 36    \\  prev="${COMP_WORDS[COMP_CWORD-1]}"
 37    \\
 38    \\  local commands="attach run send print write detach list kill history get set clear print-env wait tail completions version help"
 39    \\
 40    \\  if [[ $COMP_CWORD -eq 1 ]]; then
 41    \\    COMPREPLY=($(compgen -W "$commands" -- "$cur"))
 42    \\    return 0
 43    \\  fi
 44    \\
 45    \\  case "$prev" in
 46    \\    attach|run|send|print|write|kill|get|set|clear|print-env|wait|tail)
 47    \\      local sessions=$(zmx list --short 2>/dev/null | tr '\n' ' ')
 48    \\      COMPREPLY=($(compgen -W "$sessions" -- "$cur"))
 49    \\      ;;
 50    \\    history)
 51    \\      local sessions=$(zmx list --short 2>/dev/null | tr '\n' ' ')
 52    \\      COMPREPLY=($(compgen -W "--screen --scrollback --vt --html $sessions" -- "$cur"))
 53    \\      ;;
 54    \\    completions)
 55    \\      COMPREPLY=($(compgen -W "bash zsh fish nu yash" -- "$cur"))
 56    \\      ;;
 57    \\    list)
 58    \\      COMPREPLY=($(compgen -W "--short" -- "$cur"))
 59    \\      ;;
 60    \\    *)
 61    \\      ;;
 62    \\  esac
 63    \\}
 64    \\
 65    \\complete -o bashdefault -o default -F _zmx_completions zmx
 66;
 67
 68const zsh_completions =
 69    \\#compdef zmx
 70    \\_zmx() {
 71    \\  local context state state_descr line
 72    \\  typeset -A opt_args
 73    \\
 74    \\  _arguments -C \
 75    \\    '1: :->commands' \
 76    \\    '2: :->args' \
 77    \\    '*: :->trailing' \
 78    \\    && return 0
 79    \\
 80    \\  case $state in
 81    \\    commands)
 82    \\      local -a commands
 83    \\      commands=(
 84    \\        'attach:Attach to session, creating if needed'
 85    \\        'run:Send command without attaching'
 86    \\        'send:Send raw input to session PTY'
 87    \\        'print:Inject text into session display'
 88    \\        'write:Write stdin to file_path through the session'
 89    \\        'detach:Detach all clients from current session'
 90    \\        'list:List active sessions'
 91    \\        'kill:Kill a session'
 92    \\        'history:Output session scrollback'
 93    \\        'wait:Wait for session tasks to complete'
 94    \\        'tail:Follow session output'
 95    \\        'completions:Shell completion scripts'
 96    \\        'get:Get session labels'
 97    \\        'set:Set session labels'
 98    \\        'clear:Clear all session labels'
 99    \\        'print-env:Print tracked environment variables'
100    \\        'version:Show version'
101    \\        'help:Show help message'
102    \\      )
103    \\      _describe 'command' commands
104    \\      ;;
105    \\    args)
106    \\      case $words[2] in
107    \\        attach|a|kill|k|run|r|send|s|print|p|write|wr|get|g|set|clear|print-env|wait|w|tail|t)
108    \\          _zmx_sessions
109    \\          ;;
110    \\        history|hi)
111    \\          _zmx_sessions
112    \\          _values 'options' '--screen' '--scrollback' '--vt' '--html'
113    \\          ;;
114    \\        completions|c)
115    \\          _values 'shell' 'bash' 'zsh' 'fish' 'nu' 'yash'
116    \\          ;;
117    \\        list|l)
118    \\          _values 'options' '--short'
119    \\          ;;
120    \\      esac
121    \\      ;;
122    \\    trailing)
123    \\      # Additional args for commands like 'attach' or 'run'
124    \\      ;;
125    \\  esac
126    \\}
127    \\
128    \\_zmx_sessions() {
129    \\  local -a sessions
130    \\
131    \\  local local_sessions=$(zmx list --short 2>/dev/null)
132    \\  if [[ -n "$local_sessions" ]]; then
133    \\    sessions+=(${(f)local_sessions})
134    \\  fi
135    \\
136    \\  _describe 'local session' sessions
137    \\}
138    \\
139    \\compdef _zmx zmx
140;
141
142const fish_completions =
143    \\complete -c zmx -f
144    \\
145    \\# zmx flags
146    \\complete -c zmx -x -n '__fish_is_nth_token 1' -s v -l version -d 'Show version'
147    \\complete -c zmx -x -n '__fish_is_nth_token 1' -s h -d 'Show help message'
148    \\
149    \\# zmx subcommands
150    \\complete -c zmx -n "__fish_is_nth_token 1" -a attach -d 'Attach to session, creating if needed'
151    \\complete -c zmx -n "__fish_is_nth_token 1" -a run -d 'Send command without attaching'
152    \\complete -c zmx -n "__fish_is_nth_token 1" -a send -d 'Send raw input to session PTY'
153    \\complete -c zmx -n "__fish_is_nth_token 1" -a print -d 'Inject text into session display'
154    \\complete -c zmx -n "__fish_is_nth_token 1" -a write -d 'Write stdin to file_path through the session'
155    \\complete -c zmx -n "__fish_is_nth_token 1" -a detach -d 'Detach all clients (ctrl+\ for current client)'
156    \\complete -c zmx -n "__fish_is_nth_token 1" -a list -d 'List active sessions'
157    \\complete -c zmx -n "__fish_is_nth_token 1" -a kill -d 'Kill session and all attached clients'
158    \\complete -c zmx -n "__fish_is_nth_token 1" -a history -d 'Output session scrollback'
159    \\complete -c zmx -n "__fish_is_nth_token 1" -a wait -d 'Wait for session tasks to complete'
160    \\complete -c zmx -n "__fish_is_nth_token 1" -a tail -d 'Follow session output'
161    \\complete -c zmx -n "__fish_is_nth_token 1" -a completions -d 'Shell completions (bash, zsh, fish, nu, yash)'
162    \\complete -c zmx -n "__fish_is_nth_token 1" -a version -d 'Show version'
163    \\complete -c zmx -n "__fish_is_nth_token 1" -a get -d 'Get session labels'
164    \\complete -c zmx -n "__fish_is_nth_token 1" -a set -d 'Set session labels'
165    \\complete -c zmx -n "__fish_is_nth_token 1" -a clear -d 'Clear all session labels'
166    \\complete -c zmx -n "__fish_is_nth_token 1" -a print-env -d 'Print tracked environment variables'
167    \\complete -c zmx -n "__fish_is_nth_token 1" -a help -d 'Show help message'
168    \\
169    \\# Complete session names and shells
170    \\complete -c zmx -n "__fish_is_nth_token 2; and __fish_seen_subcommand_from a attach r run s send p print wr write hi history g get se set cl clear print-env" -a '(zmx list --short 2>/dev/null)' -d 'Session name'
171    \\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'
172    \\
173    \\complete -c zmx -n "__fish_is_nth_token 2; and __fish_seen_subcommand_from c completions" -a 'bash zsh fish nu yash' -d Shell
174    \\
175    \\# Subcommand flags
176    \\complete -c zmx -n "__fish_seen_subcommand_from a attach" -l labels -d 'Apply "key=value ..." labels as the session is created' -r
177    \\complete -c zmx -n "__fish_seen_subcommand_from r run" -s d -d 'Detach from the calling terminal; use `wait` to track its status'
178    \\complete -c zmx -n "__fish_seen_subcommand_from r run" -l fish -d 'Required when the session runs fish shell'
179    \\complete -c zmx -n "__fish_seen_subcommand_from l list" -l short -d 'Short output'
180    \\complete -c zmx -n "__fish_seen_subcommand_from k kill" -l force -d 'Force kill'
181    \\complete -c zmx -n "__fish_seen_subcommand_from hi history" -l vt -d 'History format for escape sequences'
182    \\complete -c zmx -n "__fish_seen_subcommand_from hi history" -l html -d 'History format for escape sequences'
183    \\complete -c zmx -n "__fish_seen_subcommand_from hi history" -l screen -d 'Output only the active screen'
184    \\complete -c zmx -n "__fish_seen_subcommand_from hi history" -l scrollback -d 'Rows of scrollback to add above the screen' -r
185    \\complete -c zmx -n "__fish_seen_subcommand_from print-env" -s s -l shell -d 'Output POSIX export/unset commands for eval'
186;
187
188const nu_completions =
189    \\def "nu-complete zmx sessions" [] {
190    \\    zmx list --short | lines
191    \\}
192    \\
193    \\def "nu-complete zmx complete" [] {
194    \\    [bash fish nu yash zsh]
195    \\}
196    \\
197    \\export extern "zmx attach" [
198    \\    name: string@"nu-complete zmx sessions"
199    \\    --labels: string
200    \\    ...rest: string
201    \\]
202    \\
203    \\export extern "zmx run" [
204    \\    name: string@"nu-complete zmx sessions"
205    \\    -d
206    \\    --fish
207    \\    ...rest: string
208    \\]
209    \\
210    \\export extern "zmx send" [
211    \\    name: string@"nu-complete zmx sessions"
212    \\    text: string
213    \\]
214    \\
215    \\export extern "zmx print" [
216    \\    name: string@"nu-complete zmx sessions"
217    \\    text: string
218    \\]
219    \\
220    \\export extern "zmx write" [
221    \\    name: string@"nu-complete zmx sessions"
222    \\    path: path
223    \\]
224    \\
225    \\export extern "zmx kill" [
226    \\    --force
227    \\    name: string@"nu-complete zmx sessions"
228    \\]
229    \\
230    \\export extern "zmx detach" []
231    \\export extern "zmx list" [--short]
232    \\export extern "zmx history" [name: string@"nu-complete zmx sessions", --vt, --html, --screen, --scrollback: int]
233    \\export extern "zmx wait" [...sessions: string@"nu-complete zmx sessions"]
234    \\export extern "zmx tail" [...sessions: string@"nu-complete zmx sessions"]
235    \\export extern "zmx version" []
236    \\export extern "completions" [shell: string@"nu-complete zmx complete"]
237    \\export extern "zmx get" [
238    \\    name?: string@"nu-complete zmx sessions"
239    \\]
240    \\
241    \\export extern "zmx set" [
242    \\    name?: string@"nu-complete zmx sessions"
243    \\    ...pairs: string
244    \\]
245    \\
246    \\export extern "zmx clear" [
247    \\    name?: string@"nu-complete zmx sessions"
248    \\]
249    \\
250    \\export extern "zmx print-env" [
251    \\    name: string@"nu-complete zmx sessions"
252    \\    key?: string
253    \\    --shell(-s)
254    \\]
255    \\
256    \\export extern "zmx help" []
257;
258
259const yash_completions =
260    \\function completion/zmx {
261    \\    typeset OPTIONS ARGOPT PREFIX
262    \\    OPTIONS=( #>#
263    \\        "v --version; show version"
264    \\        "h; show help"
265    \\    ) #<#
266    \\
267    \\    command -f completion//parseoptions -e
268    \\    case $ARGOPT in
269    \\    (-)
270    \\        command -f completion//completeoptions
271    \\        ;;
272    \\    ("")
273    \\        if [ ${WORDS[#]} -le 1 ]; then
274    \\            command -f completion/zmx::completecmd
275    \\        else
276    \\            typeset zmxcmd="${WORDS[2]}"
277    \\            case $zmxcmd in
278    \\            (a|attach)
279    \\                command -f completion/zmx::attach:arg
280    \\                ;;
281    \\            (r|run)
282    \\                command -f completion/zmx::run:arg
283    \\                ;;
284    \\            (s|send)
285    \\                command -f completion/zmx::send:arg
286    \\                ;;
287    \\            (p|print)
288    \\                command -f completion/zmx::print:arg
289    \\                ;;
290    \\            (wr|write)
291    \\                command -f completion/zmx::write:arg
292    \\                ;;
293    \\            (d|detach)
294    \\                ;;
295    \\            (l|ls|list)
296    \\                command -f completion/zmx::list:arg
297    \\                ;;
298    \\            (g|get)
299    \\                command -f completion/zmx::get:arg
300    \\                ;;
301    \\            (set)
302    \\                command -f completion/zmx::set:arg
303    \\                ;;
304    \\            (cl|clear)
305    \\                command -f completion/zmx::clear:arg
306    \\                ;;
307    \\            (print-env)
308    \\                command -f completion/zmx::print-env:arg
309    \\                ;;
310    \\            (k|kill)
311    \\                command -f completion/zmx::kill:arg
312    \\                ;;
313    \\            (hi|history)
314    \\                command -f completion/zmx::history:arg
315    \\                ;;
316    \\            (w|wait)
317    \\                command -f completion/zmx::wait:arg
318    \\                ;;
319    \\            (t|tail)
320    \\                command -f completion/zmx::tail:arg
321    \\                ;;
322    \\            (c|completions)
323    \\                command -f completion/zmx::completions:arg
324    \\                ;;
325    \\            esac
326    \\        fi
327    \\        ;;
328    \\    esac
329    \\}
330    \\
331    \\function completion/zmx::completecmd {
332    \\    complete -P "$PREFIX" -D "Attach to session, creating if needed" attach a
333    \\    complete -P "$PREFIX" -D "Send command without attaching" run r
334    \\    complete -P "$PREFIX" -D "Send raw input to session PTY" send s
335    \\    complete -P "$PREFIX" -D "Inject text into session display" print p
336    \\    complete -P "$PREFIX" -D "Write stdin to file_path through the session" write wr
337    \\    complete -P "$PREFIX" -D "Detach all clients from current session" detach d
338    \\    complete -P "$PREFIX" -D "List active sessions" list ls l
339    \\    complete -P "$PREFIX" -D "Get session labels" get g
340    \\    complete -P "$PREFIX" -D "Set session labels" set
341    \\    complete -P "$PREFIX" -D "Clear all session labels" clear cl
342    \\    complete -P "$PREFIX" -D "Print tracked environment variables" print-env
343    \\    complete -P "$PREFIX" -D "Kill session and all attached clients" kill k
344    \\    complete -P "$PREFIX" -D "Output session scrollback" history hi
345    \\    complete -P "$PREFIX" -D "Wait for session tasks to complete" wait w
346    \\    complete -P "$PREFIX" -D "Follow session output" tail t
347    \\    complete -P "$PREFIX" -D "Shell completion scripts" completions c
348    \\    complete -P "$PREFIX" -D "Show version" version v
349    \\    complete -P "$PREFIX" -D "Show help message" help h
350    \\}
351    \\
352    \\function completion/zmx::sessions {
353    \\    typeset sessions
354    \\    typeset IFS='
355    \\'
356    \\    sessions=($(zmx list --short 2>/dev/null))
357    \\    if [ ${sessions[#]} -gt 0 ]; then
358    \\        complete -P "$PREFIX" -- "$sessions"
359    \\    fi
360    \\}
361    \\
362    \\function completion/zmx::attach:arg {
363    \\    OPTIONS=( #>#
364    \\        "--labels:; apply labels as session is created"
365    \\    ) #<#
366    \\    command -f completion//parseoptions -en
367    \\    case $ARGOPT in
368    \\    (-)
369    \\        command -f completion//completeoptions
370    \\        ;;
371    \\    (--labels)
372    \\        ;;
373    \\    (*)
374    \\        command -f completion//getoperands
375    \\        if [ ${WORDS[#]} -eq 1 ]; then
376    \\            command -f completion/zmx::sessions
377    \\        else
378    \\            complete -P "$PREFIX" -c
379    \\        fi
380    \\        ;;
381    \\    esac
382    \\}
383    \\
384    \\function completion/zmx::run:arg {
385    \\    OPTIONS=( #>#
386    \\        "d; detach from calling terminal"
387    \\        "--fish; session runs fish shell"
388    \\    ) #<#
389    \\    command -f completion//parseoptions -en
390    \\    case $ARGOPT in
391    \\    (-)
392    \\        command -f completion//completeoptions
393    \\        ;;
394    \\    (*)
395    \\        command -f completion//getoperands
396    \\        if [ ${WORDS[#]} -eq 1 ]; then
397    \\            command -f completion/zmx::sessions
398    \\        else
399    \\            complete -P "$PREFIX" -c
400    \\        fi
401    \\        ;;
402    \\    esac
403    \\}
404    \\
405    \\function completion/zmx::send:arg {
406    \\    command -f completion//getoperands
407    \\    if [ ${WORDS[#]} -eq 1 ]; then
408    \\        command -f completion/zmx::sessions
409    \\    fi
410    \\}
411    \\
412    \\function completion/zmx::print:arg {
413    \\    command -f completion//getoperands
414    \\    if [ ${WORDS[#]} -eq 1 ]; then
415    \\        command -f completion/zmx::sessions
416    \\    fi
417    \\}
418    \\
419    \\function completion/zmx::write:arg {
420    \\    command -f completion//getoperands
421    \\    if [ ${WORDS[#]} -eq 1 ]; then
422    \\        command -f completion/zmx::sessions
423    \\    elif [ ${WORDS[#]} -eq 2 ]; then
424    \\        complete -P "$PREFIX" -f
425    \\    fi
426    \\}
427    \\
428    \\function completion/zmx::list:arg {
429    \\    OPTIONS=( #>#
430    \\        "--short; short output"
431    \\    ) #<#
432    \\    command -f completion//parseoptions -en
433    \\    case $ARGOPT in
434    \\    (-)
435    \\        command -f completion//completeoptions
436    \\        ;;
437    \\    esac
438    \\}
439    \\
440    \\function completion/zmx::get:arg {
441    \\    command -f completion//getoperands
442    \\    if [ ${WORDS[#]} -eq 1 ]; then
443    \\        complete -P "$PREFIX" -D "Current session" .
444    \\        command -f completion/zmx::sessions
445    \\    fi
446    \\}
447    \\
448    \\function completion/zmx::set:arg {
449    \\    command -f completion//getoperands
450    \\    if [ ${WORDS[#]} -eq 1 ]; then
451    \\        complete -P "$PREFIX" -D "Current session" .
452    \\        command -f completion/zmx::sessions
453    \\    fi
454    \\}
455    \\
456    \\function completion/zmx::clear:arg {
457    \\    command -f completion//getoperands
458    \\    if [ ${WORDS[#]} -eq 1 ]; then
459    \\        complete -P "$PREFIX" -D "Current session" .
460    \\        command -f completion/zmx::sessions
461    \\    fi
462    \\}
463    \\
464    \\function completion/zmx::print-env:arg {
465    \\    OPTIONS=( #>#
466    \\        "s --shell; output POSIX export/unset commands for eval"
467    \\    ) #<#
468    \\    command -f completion//parseoptions -en
469    \\    case $ARGOPT in
470    \\    (-)
471    \\        command -f completion//completeoptions
472    \\        ;;
473    \\    (*)
474    \\        command -f completion//getoperands
475    \\        if [ ${WORDS[#]} -eq 1 ]; then
476    \\            complete -P "$PREFIX" -D "Current session" .
477    \\            command -f completion/zmx::sessions
478    \\        fi
479    \\        ;;
480    \\    esac
481    \\}
482    \\
483    \\function completion/zmx::kill:arg {
484    \\    OPTIONS=( #>#
485    \\        "--force; force kill"
486    \\    ) #<#
487    \\    command -f completion//parseoptions -en
488    \\    case $ARGOPT in
489    \\    (-)
490    \\        command -f completion//completeoptions
491    \\        ;;
492    \\    (*)
493    \\        command -f completion/zmx::sessions
494    \\        ;;
495    \\    esac
496    \\}
497    \\
498    \\function completion/zmx::history:arg {
499    \\    OPTIONS=( #>#
500    \\        "--vt; history format with escape sequences"
501    \\        "--html; history format in HTML"
502    \\    ) #<#
503    \\    command -f completion//parseoptions -en
504    \\    case $ARGOPT in
505    \\    (-)
506    \\        command -f completion//completeoptions
507    \\        ;;
508    \\    (*)
509    \\        command -f completion//getoperands
510    \\        if [ ${WORDS[#]} -eq 1 ]; then
511    \\            command -f completion/zmx::sessions
512    \\        fi
513    \\        ;;
514    \\    esac
515    \\}
516    \\
517    \\function completion/zmx::wait:arg {
518    \\    command -f completion//getoperands
519    \\    command -f completion/zmx::sessions
520    \\}
521    \\
522    \\function completion/zmx::tail:arg {
523    \\    command -f completion//getoperands
524    \\    command -f completion/zmx::sessions
525    \\}
526    \\
527    \\function completion/zmx::completions:arg {
528    \\    command -f completion//getoperands
529    \\    if [ ${WORDS[#]} -eq 1 ]; then
530    \\        complete -P "$PREFIX" -- bash zsh fish nu yash
531    \\    fi
532    \\}
533;