@@ -50,6 +50,18 @@ func handleArgs(args []string, origStderr io.Writer, updateCh <-chan *update.Upd
5050 }
5151 return true , cleanup , nil
5252
53+ case "completion" :
54+ if len (args ) < 2 {
55+ err := errors .New ("completion requires a shell: bash, zsh, or powershell" )
56+ fmt .Fprintf (os .Stderr , "completion: %v\n " , err )
57+ return true , cleanup , err
58+ }
59+ if cErr := runCompletion (os .Stdout , args [1 ]); cErr != nil {
60+ fmt .Fprintf (os .Stderr , "completion: %v\n " , cErr )
61+ return true , cleanup , cErr
62+ }
63+ return true , cleanup , nil
64+
5365 case "--demo" :
5466 c , demoErr := setupDemo ()
5567 if demoErr != nil {
@@ -99,6 +111,81 @@ func handleArgs(args []string, origStderr io.Writer, updateCh <-chan *update.Upd
99111 return false , cleanup , nil
100112}
101113
114+ func runCompletion (w io.Writer , shell string ) error {
115+ if w == nil {
116+ w = io .Discard
117+ }
118+ switch strings .ToLower (shell ) {
119+ case "bash" :
120+ fmt .Fprint (w , bashCompletionScript )
121+ case "zsh" :
122+ fmt .Fprint (w , zshCompletionScript )
123+ case "powershell" , "pwsh" :
124+ fmt .Fprint (w , powershellCompletionScript )
125+ default :
126+ return fmt .Errorf ("unsupported shell %q (want bash, zsh, or powershell)" , shell )
127+ }
128+ return nil
129+ }
130+
131+ const bashCompletionScript = `# bash completion for dispatch
132+ _dispatch_completion() {
133+ local cur="${COMP_WORDS[COMP_CWORD]}"
134+ local commands="help version update completion"
135+ local flags="-h --help -v --version --demo --clear-cache --reindex"
136+
137+ if [[ "${COMP_CWORD}" -eq 1 ]]; then
138+ COMPREPLY=( $(compgen -W "${commands} ${flags}" -- "${cur}") )
139+ return 0
140+ fi
141+
142+ if [[ "${COMP_WORDS[1]}" == "completion" ]]; then
143+ COMPREPLY=( $(compgen -W "bash zsh powershell" -- "${cur}") )
144+ return 0
145+ fi
146+ }
147+ complete -F _dispatch_completion dispatch disp
148+ `
149+
150+ const zshCompletionScript = `#compdef dispatch disp
151+ _dispatch_completion() {
152+ local -a commands shells flags
153+ commands=(help version update completion)
154+ shells=(bash zsh powershell)
155+ flags=(-h --help -v --version --demo --clear-cache --reindex)
156+
157+ if (( CURRENT == 2 )); then
158+ _describe -t commands 'dispatch command' commands || _describe -t flags 'dispatch flag' flags
159+ return
160+ fi
161+
162+ if [[ ${words[2]} == completion ]]; then
163+ _describe -t shells 'shell' shells
164+ return
165+ fi
166+ }
167+ _dispatch_completion "$@"
168+ `
169+
170+ const powershellCompletionScript = `# PowerShell completion for dispatch
171+ $script:DispatchCommands = @('help', 'version', 'update', 'completion')
172+ $script:DispatchFlags = @('-h', '--help', '-v', '--version', '--demo', '--clear-cache', '--reindex')
173+ $script:DispatchShells = @('bash', 'zsh', 'powershell')
174+
175+ Register-ArgumentCompleter -Native -CommandName dispatch, disp -ScriptBlock {
176+ param($wordToComplete, $commandAst, $cursorPosition)
177+ $tokens = @($commandAst.CommandElements | ForEach-Object { $_.ToString() })
178+ $values = if ($tokens.Count -ge 2 -and $tokens[1] -eq 'completion') {
179+ $script:DispatchShells
180+ } else {
181+ $script:DispatchCommands + $script:DispatchFlags
182+ }
183+ $values |
184+ Where-Object { $_ -like "$wordToComplete*" } |
185+ ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) }
186+ }
187+ `
188+
102189// setupLogRedirect opens the log file (if configured via DISPATCH_LOG) and
103190// redirects stderr to it. When no log file is configured, stderr is sent to
104191// os.DevNull to keep Bubble Tea's alt-screen clean. Returns the writer for
0 commit comments