Commit 878a8b0

Eric Bower  ·  2026-09-19 19:29:33 -0400 EDT
parent a82544a
feat(completions): yash
5 files changed,  +322, -9
+4, -0
......@@ -4,6 +4,10 @@ Use spec: https://common-changelog.org/
44
55 ## Staged
66
7+### Added
8+
9+- Completions for [`yash`](https://magicant.github.io/yash/)
10+
711 ## v0.8.1 - 2026-09-05
812
913 ### Fixed
+27, -1
......@@ -116,7 +116,7 @@ Commands:
116116 [hi]story <name> [--vt|--html] Output session scrollback
117117 [w]ait <name>... Wait for session tasks to complete
118118 [t]ail <name>... Follow session output
119- [c]ompletions <shell> Shell completions (bash, zsh, fish, nu)
119+ [c]ompletions <shell> Shell completions (bash, zsh, fish, nu, yash)
120120 [v]ersion Show version and metadata (socket dir, log dir)
121121 [h]elp Show this help
122122 ```
......@@ -335,6 +335,32 @@ if type -q zmx
335335 end
336336 ```
337337
338+### yash
339+
340+Add this to your `~/.config/yash/rc`:
341+
342+```sh
343+if command -v zmx > /dev/null 2>&1; then
344+ eval "$(zmx completions yash)"
345+fi
346+```
347+
348+Or save as an autoloaded script in your completion directory:
349+
350+```sh
351+zmx completions yash > ~/.config/yash/completion/zmx
352+```
353+
354+### nu
355+
356+Add this to your Nushell config (`config.nu`):
357+
358+```nu
359+use ("~/.cache/zmx/completions.nu" | path expand)
360+# Or generate dynamically:
361+zmx completions nu | save -f ~/.cache/zmx/completions.nu
362+```
363+
338364 ## session picker
339365
340366 You can add an interactive session picker to your shell that lets you fuzzy-find existing sessions, preview their scrollback history, or create new ones -- all from a single prompt. This is especially useful for remote SSH workflows: add it to your shell startup so that connecting to a machine immediately presents the picker.
+284, -5
......@@ -5,12 +5,14 @@ pub const Shell = enum {
55 zsh,
66 fish,
77 nu,
8+ yash,
89
910 pub fn fromString(s: []const u8) ?Shell {
1011 if (std.mem.eql(u8, s, "bash")) return .bash;
1112 if (std.mem.eql(u8, s, "zsh")) return .zsh;
1213 if (std.mem.eql(u8, s, "fish")) return .fish;
1314 if (std.mem.eql(u8, s, "nu")) return .nu;
15+ if (std.mem.eql(u8, s, "yash")) return .yash;
1416
1517 return null;
1618 }
......@@ -21,6 +23,7 @@ pub const Shell = enum {
2123 .zsh => zsh_completions,
2224 .fish => fish_completions,
2325 .nu => nu_completions,
26+ .yash => yash_completions,
2427 };
2528 }
2629 };
......@@ -45,7 +48,7 @@ const bash_completions =
4548 \\ COMPREPLY=($(compgen -W "$sessions" -- "$cur"))
4649 \\ ;;
4750 \\ completions)
48- \\ COMPREPLY=($(compgen -W "bash zsh fish nu" -- "$cur"))
51+ \\ COMPREPLY=($(compgen -W "bash zsh fish nu yash" -- "$cur"))
4952 \\ ;;
5053 \\ list)
5154 \\ COMPREPLY=($(compgen -W "--short" -- "$cur"))
......@@ -101,7 +104,7 @@ const zsh_completions =
101104 \\ _zmx_sessions
102105 \\ ;;
103106 \\ completions|c)
104- \\ _values 'shell' 'bash' 'zsh' 'fish' 'nu'
107+ \\ _values 'shell' 'bash' 'zsh' 'fish' 'nu' 'yash'
105108 \\ ;;
106109 \\ list|l)
107110 \\ _values 'options' '--short'
......@@ -147,7 +150,7 @@ const fish_completions =
147150 \\complete -c zmx -n "__fish_is_nth_token 1" -a history -d 'Output session scrollback'
148151 \\complete -c zmx -n "__fish_is_nth_token 1" -a wait -d 'Wait for session tasks to complete'
149152 \\complete -c zmx -n "__fish_is_nth_token 1" -a tail -d 'Follow session output'
150- \\complete -c zmx -n "__fish_is_nth_token 1" -a completions -d 'Shell completions (bash, zsh, fish, nu)'
153+ \\complete -c zmx -n "__fish_is_nth_token 1" -a completions -d 'Shell completions (bash, zsh, fish, nu, yash)'
151154 \\complete -c zmx -n "__fish_is_nth_token 1" -a version -d 'Show version'
152155 \\complete -c zmx -n "__fish_is_nth_token 1" -a get -d 'Get session labels'
153156 \\complete -c zmx -n "__fish_is_nth_token 1" -a set -d 'Set session labels'
......@@ -159,7 +162,7 @@ const fish_completions =
159162 \\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'
160163 \\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'
161164 \\
162- \\complete -c zmx -n "__fish_is_nth_token 2; and __fish_seen_subcommand_from c completions" -a 'bash zsh fish nu' -d Shell
165+ \\complete -c zmx -n "__fish_is_nth_token 2; and __fish_seen_subcommand_from c completions" -a 'bash zsh fish nu yash' -d Shell
163166 \\
164167 \\# Subcommand flags
165168 \\complete -c zmx -n "__fish_seen_subcommand_from a attach" -l labels -d 'Apply "key=value ..." labels as the session is created' -r
......@@ -178,7 +181,7 @@ const nu_completions =
178181 \\}
179182 \\
180183 \\def "nu-complete zmx complete" [] {
181- \\ [bash fish nu zsh]
184+ \\ [bash fish nu yash zsh]
182185 \\}
183186 \\
184187 \\export extern "zmx attach" [
......@@ -242,3 +245,279 @@ const nu_completions =
242245 \\
243246 \\export extern "zmx help" []
244247 ;
248+
249+const yash_completions =
250+ \\function completion/zmx {
251+ \\ typeset OPTIONS ARGOPT PREFIX
252+ \\ OPTIONS=( #>#
253+ \\ "v --version; show version"
254+ \\ "h; show help"
255+ \\ ) #<#
256+ \\
257+ \\ command -f completion//parseoptions -e
258+ \\ case $ARGOPT in
259+ \\ (-)
260+ \\ command -f completion//completeoptions
261+ \\ ;;
262+ \\ ("")
263+ \\ if [ ${WORDS[#]} -le 1 ]; then
264+ \\ command -f completion/zmx::completecmd
265+ \\ else
266+ \\ typeset zmxcmd="${WORDS[2]}"
267+ \\ case $zmxcmd in
268+ \\ (a|attach)
269+ \\ command -f completion/zmx::attach:arg
270+ \\ ;;
271+ \\ (r|run)
272+ \\ command -f completion/zmx::run:arg
273+ \\ ;;
274+ \\ (s|send)
275+ \\ command -f completion/zmx::send:arg
276+ \\ ;;
277+ \\ (p|print)
278+ \\ command -f completion/zmx::print:arg
279+ \\ ;;
280+ \\ (wr|write)
281+ \\ command -f completion/zmx::write:arg
282+ \\ ;;
283+ \\ (d|detach)
284+ \\ ;;
285+ \\ (l|ls|list)
286+ \\ command -f completion/zmx::list:arg
287+ \\ ;;
288+ \\ (g|get)
289+ \\ command -f completion/zmx::get:arg
290+ \\ ;;
291+ \\ (set)
292+ \\ command -f completion/zmx::set:arg
293+ \\ ;;
294+ \\ (cl|clear)
295+ \\ command -f completion/zmx::clear:arg
296+ \\ ;;
297+ \\ (print-env)
298+ \\ command -f completion/zmx::print-env:arg
299+ \\ ;;
300+ \\ (k|kill)
301+ \\ command -f completion/zmx::kill:arg
302+ \\ ;;
303+ \\ (hi|history)
304+ \\ command -f completion/zmx::history:arg
305+ \\ ;;
306+ \\ (w|wait)
307+ \\ command -f completion/zmx::wait:arg
308+ \\ ;;
309+ \\ (t|tail)
310+ \\ command -f completion/zmx::tail:arg
311+ \\ ;;
312+ \\ (c|completions)
313+ \\ command -f completion/zmx::completions:arg
314+ \\ ;;
315+ \\ esac
316+ \\ fi
317+ \\ ;;
318+ \\ esac
319+ \\}
320+ \\
321+ \\function completion/zmx::completecmd {
322+ \\ complete -P "$PREFIX" -D "Attach to session, creating if needed" attach a
323+ \\ complete -P "$PREFIX" -D "Send command without attaching" run r
324+ \\ complete -P "$PREFIX" -D "Send raw input to session PTY" send s
325+ \\ complete -P "$PREFIX" -D "Inject text into session display" print p
326+ \\ complete -P "$PREFIX" -D "Write stdin to file_path through the session" write wr
327+ \\ complete -P "$PREFIX" -D "Detach all clients from current session" detach d
328+ \\ complete -P "$PREFIX" -D "List active sessions" list ls l
329+ \\ complete -P "$PREFIX" -D "Get session labels" get g
330+ \\ complete -P "$PREFIX" -D "Set session labels" set
331+ \\ complete -P "$PREFIX" -D "Clear all session labels" clear cl
332+ \\ complete -P "$PREFIX" -D "Print tracked environment variables" print-env
333+ \\ complete -P "$PREFIX" -D "Kill session and all attached clients" kill k
334+ \\ complete -P "$PREFIX" -D "Output session scrollback" history hi
335+ \\ complete -P "$PREFIX" -D "Wait for session tasks to complete" wait w
336+ \\ complete -P "$PREFIX" -D "Follow session output" tail t
337+ \\ complete -P "$PREFIX" -D "Shell completion scripts" completions c
338+ \\ complete -P "$PREFIX" -D "Show version" version v
339+ \\ complete -P "$PREFIX" -D "Show help message" help h
340+ \\}
341+ \\
342+ \\function completion/zmx::sessions {
343+ \\ typeset sessions
344+ \\ typeset IFS='
345+ \\'
346+ \\ sessions=($(zmx list --short 2>/dev/null))
347+ \\ if [ ${sessions[#]} -gt 0 ]; then
348+ \\ complete -P "$PREFIX" -- "$sessions"
349+ \\ fi
350+ \\}
351+ \\
352+ \\function completion/zmx::attach:arg {
353+ \\ OPTIONS=( #>#
354+ \\ "--labels:; apply labels as session is created"
355+ \\ ) #<#
356+ \\ command -f completion//parseoptions -en
357+ \\ case $ARGOPT in
358+ \\ (-)
359+ \\ command -f completion//completeoptions
360+ \\ ;;
361+ \\ (--labels)
362+ \\ ;;
363+ \\ (*)
364+ \\ command -f completion//getoperands
365+ \\ if [ ${WORDS[#]} -eq 1 ]; then
366+ \\ command -f completion/zmx::sessions
367+ \\ else
368+ \\ complete -P "$PREFIX" -c
369+ \\ fi
370+ \\ ;;
371+ \\ esac
372+ \\}
373+ \\
374+ \\function completion/zmx::run:arg {
375+ \\ OPTIONS=( #>#
376+ \\ "d; detach from calling terminal"
377+ \\ "--fish; session runs fish shell"
378+ \\ ) #<#
379+ \\ command -f completion//parseoptions -en
380+ \\ case $ARGOPT in
381+ \\ (-)
382+ \\ command -f completion//completeoptions
383+ \\ ;;
384+ \\ (*)
385+ \\ command -f completion//getoperands
386+ \\ if [ ${WORDS[#]} -eq 1 ]; then
387+ \\ command -f completion/zmx::sessions
388+ \\ else
389+ \\ complete -P "$PREFIX" -c
390+ \\ fi
391+ \\ ;;
392+ \\ esac
393+ \\}
394+ \\
395+ \\function completion/zmx::send:arg {
396+ \\ command -f completion//getoperands
397+ \\ if [ ${WORDS[#]} -eq 1 ]; then
398+ \\ command -f completion/zmx::sessions
399+ \\ fi
400+ \\}
401+ \\
402+ \\function completion/zmx::print:arg {
403+ \\ command -f completion//getoperands
404+ \\ if [ ${WORDS[#]} -eq 1 ]; then
405+ \\ command -f completion/zmx::sessions
406+ \\ fi
407+ \\}
408+ \\
409+ \\function completion/zmx::write:arg {
410+ \\ command -f completion//getoperands
411+ \\ if [ ${WORDS[#]} -eq 1 ]; then
412+ \\ command -f completion/zmx::sessions
413+ \\ elif [ ${WORDS[#]} -eq 2 ]; then
414+ \\ complete -P "$PREFIX" -f
415+ \\ fi
416+ \\}
417+ \\
418+ \\function completion/zmx::list:arg {
419+ \\ OPTIONS=( #>#
420+ \\ "--short; short output"
421+ \\ ) #<#
422+ \\ command -f completion//parseoptions -en
423+ \\ case $ARGOPT in
424+ \\ (-)
425+ \\ command -f completion//completeoptions
426+ \\ ;;
427+ \\ esac
428+ \\}
429+ \\
430+ \\function completion/zmx::get:arg {
431+ \\ command -f completion//getoperands
432+ \\ if [ ${WORDS[#]} -eq 1 ]; then
433+ \\ complete -P "$PREFIX" -D "Current session" .
434+ \\ command -f completion/zmx::sessions
435+ \\ fi
436+ \\}
437+ \\
438+ \\function completion/zmx::set:arg {
439+ \\ command -f completion//getoperands
440+ \\ if [ ${WORDS[#]} -eq 1 ]; then
441+ \\ complete -P "$PREFIX" -D "Current session" .
442+ \\ command -f completion/zmx::sessions
443+ \\ fi
444+ \\}
445+ \\
446+ \\function completion/zmx::clear:arg {
447+ \\ command -f completion//getoperands
448+ \\ if [ ${WORDS[#]} -eq 1 ]; then
449+ \\ complete -P "$PREFIX" -D "Current session" .
450+ \\ command -f completion/zmx::sessions
451+ \\ fi
452+ \\}
453+ \\
454+ \\function completion/zmx::print-env:arg {
455+ \\ OPTIONS=( #>#
456+ \\ "s --shell; output POSIX export/unset commands for eval"
457+ \\ ) #<#
458+ \\ command -f completion//parseoptions -en
459+ \\ case $ARGOPT in
460+ \\ (-)
461+ \\ command -f completion//completeoptions
462+ \\ ;;
463+ \\ (*)
464+ \\ command -f completion//getoperands
465+ \\ if [ ${WORDS[#]} -eq 1 ]; then
466+ \\ complete -P "$PREFIX" -D "Current session" .
467+ \\ command -f completion/zmx::sessions
468+ \\ fi
469+ \\ ;;
470+ \\ esac
471+ \\}
472+ \\
473+ \\function completion/zmx::kill:arg {
474+ \\ OPTIONS=( #>#
475+ \\ "--force; force kill"
476+ \\ ) #<#
477+ \\ command -f completion//parseoptions -en
478+ \\ case $ARGOPT in
479+ \\ (-)
480+ \\ command -f completion//completeoptions
481+ \\ ;;
482+ \\ (*)
483+ \\ command -f completion/zmx::sessions
484+ \\ ;;
485+ \\ esac
486+ \\}
487+ \\
488+ \\function completion/zmx::history:arg {
489+ \\ OPTIONS=( #>#
490+ \\ "--vt; history format with escape sequences"
491+ \\ "--html; history format in HTML"
492+ \\ ) #<#
493+ \\ command -f completion//parseoptions -en
494+ \\ case $ARGOPT in
495+ \\ (-)
496+ \\ command -f completion//completeoptions
497+ \\ ;;
498+ \\ (*)
499+ \\ command -f completion//getoperands
500+ \\ if [ ${WORDS[#]} -eq 1 ]; then
501+ \\ command -f completion/zmx::sessions
502+ \\ fi
503+ \\ ;;
504+ \\ esac
505+ \\}
506+ \\
507+ \\function completion/zmx::wait:arg {
508+ \\ command -f completion//getoperands
509+ \\ command -f completion/zmx::sessions
510+ \\}
511+ \\
512+ \\function completion/zmx::tail:arg {
513+ \\ command -f completion//getoperands
514+ \\ command -f completion/zmx::sessions
515+ \\}
516+ \\
517+ \\function completion/zmx::completions:arg {
518+ \\ command -f completion//getoperands
519+ \\ if [ ${WORDS[#]} -eq 1 ]; then
520+ \\ complete -P "$PREFIX" -- bash zsh fish nu yash
521+ \\ fi
522+ \\}
523+;
+3, -3
......@@ -114,13 +114,13 @@ pub fn main(init: std.process.Init) !void {
114114 return labelClear(gpa, io, &cfg, sesh);
115115 } else if (std.mem.eql(u8, cmd, "completions") or std.mem.eql(u8, cmd, "c")) {
116116 const arg = args.next() orelse {
117- return printError(io, "completions requires a shell argument (bash, zsh, fish, nu)", .{});
117+ return printError(io, "completions requires a shell argument (bash, zsh, fish, nu, yash)", .{});
118118 };
119119 if (std.mem.eql(u8, arg, "--help") or std.mem.eql(u8, arg, "-h")) {
120120 return help(io);
121121 }
122122 const shell = completions.Shell.fromString(arg) orelse {
123- return printError(io, "unknown shell \"{s}\" (valid: bash, zsh, fish, nu)", .{arg});
123+ return printError(io, "unknown shell \"{s}\" (valid: bash, zsh, fish, nu, yash)", .{arg});
124124 };
125125 return printCompletions(io, shell);
126126 } else if (std.mem.eql(u8, cmd, "detach") or std.mem.eql(u8, cmd, "d")) {
......@@ -524,7 +524,7 @@ fn help(io: std.Io) !void {
524524 \\ [hi]story <name> [--vt|--html] Output session scrollback
525525 \\ [w]ait <name>... Wait for session tasks to complete
526526 \\ [t]ail <name>... Follow session output
527- \\ [c]ompletions <shell> Shell completions (bash, zsh, fish, nu)
527+ \\ [c]ompletions <shell> Shell completions (bash, zsh, fish, nu, yash)
528528 \\ [v]ersion Show version and metadata (socket dir, log dir)
529529 \\ [h]elp Show this help
530530 \\
+4, -0
......@@ -140,6 +140,10 @@ load test_helper
140140 run "$ZMX" completions bash
141141 [ "$status" -eq 0 ]
142142 [[ "$output" == *"_zmx_completions"* ]]
143+
144+ run "$ZMX" completions yash
145+ [ "$status" -eq 0 ]
146+ [[ "$output" == *"completion/zmx"* ]]
143147 }
144148
145149 @test "completions --help exits zero" {