1515package cmd
1616
1717import (
18- "bytes"
1918 "fmt"
20- "io"
2119 "os"
2220 "os/exec"
2321 "regexp"
@@ -30,31 +28,10 @@ import (
3028
3129// NewCmdCompletion ucloud completion
3230func NewCmdCompletion () * cobra.Command {
33- var desc = `Description:
34- On macOS, using bash
35-
36- On macOS, you will need to install bash-completion support via Homebrew first:
37- $ ucloud completion
38- $ brew install bash-completion
39- Follow the “caveats” section of brew’s output to add the appropriate bash completion path to your local .bash_profile.
40- and then generate bash completion scripts for ucloud
41-
42- On Linux, using bash
43-
44- On Linux, you may need to install the bash-completion package which is not installed by default.
45- $ ucloud completion
46- $ yum install bash-completion or apt-get install bash-completion
47- and then genreate bash completion scripts for ucloud
48-
49- Using zsh
50- > ucloud completion
51-
52- Restart session after auto completion
53- `
5431 var completionCmd = & cobra.Command {
5532 Use : "completion" ,
56- Short : "Generates bash/zsh completion scripts " ,
57- Long : desc ,
33+ Short : "Turn on auto completion according to the prompt " ,
34+ Long : "Turn on auto completion according to the prompt" ,
5835 Run : func (cmd * cobra.Command , args []string ) {
5936 shell , ok := os .LookupEnv ("SHELL" )
6037 if ok {
@@ -73,32 +50,43 @@ func NewCmdCompletion() *cobra.Command {
7350 return completionCmd
7451}
7552
76- var darwinBash = `
77- Install bash-completion with command 'brew install bash-completion', and then append the following scripts to ~/.bash_profile
53+ func bashCompletion (cmd * cobra.Command ) {
54+ platform := runtime .GOOS
55+ if platform == "darwin" {
56+ fmt .Println (`Please append 'complete -C /usr/local/bin/ucloud ucloud' to file '~/.bash_profile'
57+ If the following scripts are included in '~/.bash_profile', please remove it. Those scripts used to auto complete words before ucloud cli v0.1.3"
7858
7959if [ -f $(brew --prefix)/etc/bash_completion ]; then
8060 . $(brew --prefix)/etc/bash_completion
8161fi
62+ source ~/.ucloud/ucloud.sh` )
8263
83- source ~/.ucloud/ucloud.sh
84- `
85-
86- var linuxBash = `
87- Ensure your have installed bash-completion, and then append the following scripts to ~/.bashrc
64+ } else if platform == "linux" {
65+ fmt .Println (`Please append 'complete -C /usr/local/bin/ucloud ucloud' to file '~/.bashrc'
66+ If the following scripts are included in '~/.bashrc', please remove it. Those scripts used to auto complete words before ucloud cli v0.1.3"
8867
8968if [ -f /etc/bash_completion ]; then
9069 . /etc/bash_completion
9170fi
9271
93- source ~/.ucloud/ucloud.sh
94- `
72+ source ~/.ucloud/ucloud.sh` )
73+ }
74+ }
75+
76+ func zshCompletion (cmd * cobra.Command ) {
77+ fmt .Println (`Please append the following scripts to file '~/.zshrc'.
78+ autoload -U +X bashcompinit && bashcompinit
79+ complete -F /usr/local/bin/ucloud ucloud` )
80+ fmt .Println ("If the following scripts are included in '~/.bash_profile' or '~/.bashrc', please remove it. The scripts used to auto complete words before ucloud cli v0.1.3" )
81+ fmt .Printf ("fpath=(~/%s $fpath)\n " , ConfigPath )
82+ fmt .Println ("autoload -U +X compinit && compinit" )
83+ }
9584
9685func getBashVersion () (version string , err error ) {
9786 lookupBashVersion := exec .Command ("bash" , "-version" )
9887 out , err := lookupBashVersion .Output ()
9988 if err != nil {
10089 Cxt .PrintErr (err )
101- fmt .Println (err )
10290 }
10391
10492 // Example
@@ -119,201 +107,3 @@ func getBashVersion() (version string, err error) {
119107 }
120108 return
121109}
122-
123- func bashCompletion (cmd * cobra.Command ) {
124- home := GetHomePath ()
125- shellPath := home + "/" + ConfigPath + "/ucloud.sh"
126- cmd .GenBashCompletionFile (shellPath )
127- fmt .Printf ("Completion scripts has been written to '~/%s/ucloud.sh'\n " , ConfigPath )
128-
129- platform := runtime .GOOS
130-
131- if platform == "darwin" {
132- fmt .Println (darwinBash )
133- } else if platform == "linux" {
134- fmt .Println (linuxBash )
135- }
136- }
137-
138- func zshCompletion (cmd * cobra.Command ) {
139- home := GetHomePath ()
140- shellPath := home + "/" + ConfigPath + "/_ucloud"
141- file , err := os .Create (shellPath )
142- if err != nil {
143- Cxt .PrintErr (err )
144- return
145- }
146- defer file .Close ()
147-
148- runCompletionZsh (file , cmd )
149- fmt .Printf ("Completion scripts was written to '~/%s/_ucloud'\n " , ConfigPath )
150-
151- scripts := fmt .Sprintf ("fpath=(~/%s $fpath)\n " , ConfigPath )
152- scripts += "autoload -U +X compinit && compinit"
153- fmt .Printf ("Please append the following scripts to your ~/.zshrc\n %s\n " , scripts )
154- }
155-
156- //参考自 k8s.io/kubernetes/pkg/kubectl/cmd/completion.go
157- func runCompletionZsh (out io.Writer , cmd * cobra.Command ) error {
158- zsh_head := "#compdef ucloud\n "
159-
160- out .Write ([]byte (zsh_head ))
161-
162- zsh_initialization := `
163- __ucloud_bash_source() {
164- alias shopt=':'
165- alias _expand=_bash_expand
166- alias _complete=_bash_comp
167- emulate -L sh
168- setopt kshglob noshglob braceexpand
169-
170- source "$@"
171- }
172-
173- __ucloud_type() {
174- # -t is not supported by zsh
175- if [ "$1" == "-t" ]; then
176- shift
177-
178- # fake Bash 4 to disable "complete -o nospace". Instead
179- # "compopt +-o nospace" is used in the code to toggle trailing
180- # spaces. We don't support that, but leave trailing spaces on
181- # all the time
182- if [ "$1" = "__ucloud_compopt" ]; then
183- echo builtin
184- return 0
185- fi
186- fi
187- type "$@"
188- }
189-
190- __ucloud_compgen() {
191- local completions w
192- completions=( $(compgen "$@") ) || return $?
193-
194- # filter by given word as prefix
195- while [[ "$1" = -* && "$1" != -- ]]; do
196- shift
197- shift
198- done
199- if [[ "$1" == -- ]]; then
200- shift
201- fi
202- for w in "${completions[@]}"; do
203- if [[ "${w}" = "$1"* ]]; then
204- echo "${w}"
205- fi
206- done
207- }
208-
209- __ucloud_compopt() {
210- true # don't do anything. Not supported by bashcompinit in zsh
211- }
212-
213- __ucloud_ltrim_colon_completions()
214- {
215- if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
216- # Remove colon-word prefix from COMPREPLY items
217- local colon_word=${1%${1##*:}}
218- local i=${#COMPREPLY[*]}
219- while [[ $((--i)) -ge 0 ]]; do
220- COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
221- done
222- fi
223- }
224-
225- __ucloud_get_comp_words_by_ref() {
226- cur="${COMP_WORDS[COMP_CWORD]}"
227- prev="${COMP_WORDS[${COMP_CWORD}-1]}"
228- words=("${COMP_WORDS[@]}")
229- cword=("${COMP_CWORD[@]}")
230- }
231-
232- __ucloud_filedir() {
233- local RET OLD_IFS w qw
234-
235- __ucloud_debug "_filedir $@ cur=$cur"
236- if [[ "$1" = \~* ]]; then
237- # somehow does not work. Maybe, zsh does not call this at all
238- eval echo "$1"
239- return 0
240- fi
241-
242- OLD_IFS="$IFS"
243- IFS=$'\n'
244- if [ "$1" = "-d" ]; then
245- shift
246- RET=( $(compgen -d) )
247- else
248- RET=( $(compgen -f) )
249- fi
250- IFS="$OLD_IFS"
251-
252- IFS="," __ucloud_debug "RET=${RET[@]} len=${#RET[@]}"
253-
254- for w in ${RET[@]}; do
255- if [[ ! "${w}" = "${cur}"* ]]; then
256- continue
257- fi
258- if eval "[[ \"\${w}\" = *.$1 || -d \"\${w}\" ]]"; then
259- qw="$(__ucloud_quote "${w}")"
260- if [ -d "${w}" ]; then
261- COMPREPLY+=("${qw}/")
262- else
263- COMPREPLY+=("${qw}")
264- fi
265- fi
266- done
267- }
268-
269- __ucloud_quote() {
270- if [[ $1 == \'* || $1 == \"* ]]; then
271- # Leave out first character
272- printf %q "${1:1}"
273- else
274- printf %q "$1"
275- fi
276- }
277-
278- autoload -U +X bashcompinit && bashcompinit
279-
280- # use word boundary patterns for BSD or GNU sed
281- LWORD='[[:<:]]'
282- RWORD='[[:>:]]'
283- if sed --help 2>&1 | grep -q GNU; then
284- LWORD='\<'
285- RWORD='\>'
286- fi
287-
288- __ucloud_convert_bash_to_zsh() {
289- sed \
290- -e 's/declare -F/whence -w/' \
291- -e 's/_get_comp_words_by_ref "\$@"/_get_comp_words_by_ref "\$*"/' \
292- -e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \
293- -e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \
294- -e 's/must_have_one_flag+=("\(--.*\)=")/must_have_one_flag+=("\1")/' \
295- -e "s/${LWORD}_filedir${RWORD}/__ucloud_filedir/g" \
296- -e "s/${LWORD}_get_comp_words_by_ref${RWORD}/__ucloud_get_comp_words_by_ref/g" \
297- -e "s/${LWORD}__ltrim_colon_completions${RWORD}/__ucloud_ltrim_colon_completions/g" \
298- -e "s/${LWORD}compgen${RWORD}/__ucloud_compgen/g" \
299- -e "s/${LWORD}compopt${RWORD}/__ucloud_compopt/g" \
300- -e "s/${LWORD}declare${RWORD}/builtin declare/g" \
301- -e "s/\\\$(type${RWORD}/\$(__ucloud_type/g" \
302- <<'BASH_COMPLETION_EOF'
303- `
304- out .Write ([]byte (zsh_initialization ))
305-
306- buf := new (bytes.Buffer )
307- cmd .GenBashCompletion (buf )
308- out .Write (buf .Bytes ())
309-
310- zsh_tail := `
311- BASH_COMPLETION_EOF
312- }
313-
314- __ucloud_bash_source <(__ucloud_convert_bash_to_zsh)
315- _complete ucloud 2>/dev/null
316- `
317- out .Write ([]byte (zsh_tail ))
318- return nil
319- }
0 commit comments