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;