@@ -2,6 +2,7 @@ package cli
2
2
3
3
import (
4
4
"context"
5
+ "embed"
5
6
"fmt"
6
7
"sort"
7
8
)
@@ -13,22 +14,39 @@ const (
13
14
completionFlag = "--generate-shell-completion"
14
15
)
15
16
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 )
30
18
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
+ )
32
50
33
51
func buildCompletionCommand (appName string ) * Command {
34
52
return & Command {
@@ -70,86 +88,3 @@ func printShellCompletion(_ context.Context, cmd *Command, appName string) error
70
88
71
89
return nil
72
90
}
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