@@ -2,6 +2,7 @@ package cli
22
33import (
44 "context"
5+ "embed"
56 "fmt"
67 "sort"
78)
@@ -13,22 +14,39 @@ const (
1314 completionFlag = "--generate-shell-completion"
1415)
1516
16- var shellCompletions = map [string ]renderCompletionFunc {
17- "bash" : func (cmd * Command , appName string ) (string , error ) {
18- return genBashCompletion (appName ), nil
19- },
20- "zsh" : func (cmd * Command , appName string ) (string , error ) {
21- return genZshCompletion (appName ), nil
22- },
23- "fish" : func (c * Command , appName string ) (string , error ) {
24- return c .ToFishCompletion ()
25- },
26- "pwsh" : func (cmd * Command , appName string ) (string , error ) {
27- return genPwshCompletion (), nil
28- },
29- }
17+ type renderCompletion func (cmd * Command , appName string ) (string , error )
3018
31- type renderCompletionFunc func (cmd * Command , appName string ) (string , error )
19+ var (
20+ //go:embed autocomplete
21+ autoCompleteFS embed.FS
22+
23+ shellCompletions = map [string ]renderCompletion {
24+ "bash" : func (c * Command , appName string ) (string , error ) {
25+ b , err := autoCompleteFS .ReadFile ("autocomplete/bash_autocomplete" )
26+ if err != nil {
27+ return "" , fmt .Errorf ("read file: %w" , err )
28+ }
29+ return fmt .Sprintf (string (b ), appName ), nil
30+ },
31+ "zsh" : func (c * Command , appName string ) (string , error ) {
32+ b , err := autoCompleteFS .ReadFile ("autocomplete/zsh_autocomplete" )
33+ if err != nil {
34+ return "" , fmt .Errorf ("read file: %w" , err )
35+ }
36+ return fmt .Sprintf (string (b ), appName ), nil
37+ },
38+ "fish" : func (c * Command , appName string ) (string , error ) {
39+ return c .ToFishCompletion ()
40+ },
41+ "pwsh" : func (c * Command , appName string ) (string , error ) {
42+ b , err := autoCompleteFS .ReadFile ("autocomplete/powershell_autocomplete.ps1" )
43+ if err != nil {
44+ return "" , fmt .Errorf ("read file: %w" , err )
45+ }
46+ return string (b ), nil
47+ },
48+ }
49+ )
3250
3351func buildCompletionCommand (appName string ) * Command {
3452 return & Command {
@@ -70,86 +88,3 @@ func printShellCompletion(_ context.Context, cmd *Command, appName string) error
7088
7189 return nil
7290}
73-
74- func genBashCompletion (appName string ) string {
75- return fmt .Sprintf (`#!/usr/env/bin bash
76-
77- # This is a shell completion script auto-generated by https://github.com/urfave/cli for bash.
78-
79- # Macs have bash3 for which the bash-completion package doesn't include
80- # _init_completion. This is a minimal version of that function.
81- __%[1]s_init_completion() {
82- COMPREPLY=()
83- _get_comp_words_by_ref "$@" cur prev words cword
84- }
85-
86- __%[1]s_bash_autocomplete() {
87- if [[ "${COMP_WORDS[0]}" != "source" ]]; then
88- local cur opts base words
89- COMPREPLY=()
90- cur="${COMP_WORDS[COMP_CWORD]}"
91- if declare -F _init_completion >/dev/null 2>&1; then
92- _init_completion -n "=:" || return
93- else
94- __%[1]s_init_completion -n "=:" || return
95- fi
96- words=("${words[@]:0:$cword}")
97- if [[ "$cur" == "-"* ]]; then
98- requestComp="${words[*]} ${cur} --generate-shell-completion"
99- else
100- requestComp="${words[*]} --generate-shell-completion"
101- fi
102- opts=$(eval "${requestComp}" 2>/dev/null)
103- COMPREPLY=($(compgen -W "${opts}" -- ${cur}))
104- return 0
105- fi
106- }
107-
108- complete -o bashdefault -o default -o nospace -F __%[1]s_bash_autocomplete %[1]s
109- ` , appName )
110- }
111-
112- func genZshCompletion (appName string ) string {
113- return fmt .Sprintf (`#compdef %[1]s
114- compdef _%[1]s %[1]s
115-
116- # This is a shell completion script auto-generated by https://github.com/urfave/cli for zsh.
117-
118- _%[1]s() {
119- local -a opts # Declare a local array
120- local current
121- current=${words[-1]} # -1 means "the last element"
122- if [[ "$current" == "-"* ]]; then
123- # Current word starts with a hyphen, so complete flags/options
124- opts=("${(@f)$(${words[@]:0:#words[@]-1} ${current} --generate-shell-completion)}")
125- else
126- # Current word does not start with a hyphen, so complete subcommands
127- opts=("${(@f)$(${words[@]:0:#words[@]-1} --generate-shell-completion)}")
128- fi
129-
130- if [[ "${opts[1]}" != "" ]]; then
131- _describe 'values' opts
132- else
133- _files
134- fi
135- }
136-
137- # Don't run the completion function when being source-ed or eval-ed.
138- # See https://github.com/urfave/cli/issues/1874 for discussion.
139- if [ "$funcstack[1]" = "_%[1]s" ]; then
140- _%[1]s
141- fi
142- ` , appName )
143- }
144-
145- func genPwshCompletion () string {
146- return `$fn = $($MyInvocation.MyCommand.Name)
147- $name = $fn -replace "(.*)\.ps1$", '$1'
148- Register-ArgumentCompleter -Native -CommandName $name -ScriptBlock {
149- param($commandName, $wordToComplete, $cursorPosition)
150- $other = "$wordToComplete --generate-shell-completion"
151- Invoke-Expression $other | ForEach-Object {
152- [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
153- }
154- }`
155- }
0 commit comments