-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updates completion system to current version suggested by cobra.
This adds completions for fish and powershell and shows the descriptions for commands and flags.
- Loading branch information
Showing
5 changed files
with
62 additions
and
367 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,227 +1,77 @@ | ||
package cmd | ||
|
||
import ( | ||
"bytes" | ||
"io" | ||
"os" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
var ( | ||
completionShells = map[string]func(out io.Writer, cmd *cobra.Command) error{ | ||
"bash": runCompletionBash, | ||
"zsh": runCompletionZsh, | ||
} | ||
) | ||
|
||
// NewCmdCompletion creates the `completion` command | ||
func NewCompletionCmd() *cobra.Command { | ||
shells := []string{} | ||
for s := range completionShells { | ||
shells = append(shells, s) | ||
} | ||
|
||
cmd := &cobra.Command{ | ||
Use: "completion SHELL", | ||
DisableFlagsInUseLine: true, | ||
Short: "Output shell completion code for the specified shell (bash or zsh)", | ||
|
||
RunE: func(cmd *cobra.Command, args []string) error { | ||
return RunCompletion(os.Stdout, cmd, args) | ||
}, | ||
ValidArgs: shells, | ||
} | ||
|
||
return cmd | ||
} | ||
|
||
// RunCompletion checks given arguments and executes command | ||
func RunCompletion(out io.Writer, cmd *cobra.Command, args []string) error { | ||
if len(args) == 0 { | ||
return errors.New("Shell not specified.") | ||
} | ||
if len(args) > 1 { | ||
return errors.New("Too many arguments. Expected only the shell type.") | ||
} | ||
run, found := completionShells[args[0]] | ||
if !found { | ||
return errors.Errorf("Unsupported shell type %q.", args[0]) | ||
} | ||
Use: "completion [bash|zsh|fish|powershell]", | ||
Short: "Generate completion script", | ||
Long: `To load completions: | ||
return run(out, cmd.Parent()) | ||
} | ||
Bash: | ||
func runCompletionBash(out io.Writer, cmd *cobra.Command) error { | ||
return cmd.GenBashCompletion(out) | ||
} | ||
$ source <(minikube-support completion bash) | ||
func runCompletionZsh(out io.Writer, cmd *cobra.Command) error { | ||
zshHead := "#compdef minikube-support\n" | ||
# To load completions for each session, execute once: | ||
# Linux: | ||
$ minikube-support completion bash > /etc/bash_completion.d/minikube-support | ||
# macOS: | ||
$ minikube-support completion bash > /usr/local/etc/bash_completion.d/minikube-support | ||
_, e := out.Write([]byte(zshHead)) | ||
if e != nil { | ||
return e | ||
} | ||
Zsh: | ||
zshInitialization := ` | ||
__minikube-support_bash_source() { | ||
alias shopt=':' | ||
alias _expand=_bash_expand | ||
alias _complete=_bash_comp | ||
emulate -L sh | ||
setopt kshglob noshglob braceexpand | ||
# If shell completion is not already enabled in your environment, | ||
# you will need to enable it. You can execute the following once: | ||
source "$@" | ||
} | ||
$ echo "autoload -U compinit; compinit" >> ~/.zshrc | ||
__minikube-support_type() { | ||
# -t is not supported by zsh | ||
if [ "$1" == "-t" ]; then | ||
shift | ||
# fake Bash 4 to disable "complete -o nospace". Instead | ||
# "compopt +-o nospace" is used in the code to toggle trailing | ||
# spaces. We don't support that, but leave trailing spaces on | ||
# all the time | ||
if [ "$1" = "__minikube-support_compopt" ]; then | ||
echo builtin | ||
return 0 | ||
fi | ||
fi | ||
type "$@" | ||
} | ||
# To load completions for each session, execute once: | ||
$ minikube-support completion zsh > "${fpath[1]}/_minikube-support" | ||
__minikube-support_compgen() { | ||
local completions w | ||
completions=( $(compgen "$@") ) || return $? | ||
# filter by given word as prefix | ||
while [[ "$1" = -* && "$1" != -- ]]; do | ||
shift | ||
shift | ||
done | ||
if [[ "$1" == -- ]]; then | ||
shift | ||
fi | ||
for w in "${completions[@]}"; do | ||
if [[ "${w}" = "$1"* ]]; then | ||
echo "${w}" | ||
fi | ||
done | ||
} | ||
# You will need to start a new shell for this setup to take effect. | ||
__minikube-support_compopt() { | ||
true # don't do anything. Not supported by bashcompinit in zsh | ||
} | ||
fish: | ||
__minikube-support_ltrim_colon_completions() | ||
{ | ||
if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then | ||
# Remove colon-word prefix from COMPREPLY items | ||
local colon_word=${1%${1##*:}} | ||
local i=${#COMPREPLY[*]} | ||
while [[ $((--i)) -ge 0 ]]; do | ||
COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"} | ||
done | ||
fi | ||
} | ||
$ minikube-support completion fish | source | ||
__minikube-support_get_comp_words_by_ref() { | ||
cur="${COMP_WORDS[COMP_CWORD]}" | ||
prev="${COMP_WORDS[${COMP_CWORD}-1]}" | ||
words=("${COMP_WORDS[@]}") | ||
cword=("${COMP_CWORD[@]}") | ||
} | ||
# To load completions for each session, execute once: | ||
$ minikube-support completion fish > ~/.config/fish/completions/minikube-support.fish | ||
__minikube-support_filedir() { | ||
local RET OLD_IFS w qw | ||
__minikube-support_debug "_filedir $@ cur=$cur" | ||
if [[ "$1" = \~* ]]; then | ||
# somehow does not work. Maybe, zsh does not call this at all | ||
eval echo "$1" | ||
return 0 | ||
fi | ||
OLD_IFS="$IFS" | ||
IFS=$'\n' | ||
if [ "$1" = "-d" ]; then | ||
shift | ||
RET=( $(compgen -d) ) | ||
else | ||
RET=( $(compgen -f) ) | ||
fi | ||
IFS="$OLD_IFS" | ||
IFS="," __minikube-support_debug "RET=${RET[@]} len=${#RET[@]}" | ||
for w in ${RET[@]}; do | ||
if [[ ! "${w}" = "${cur}"* ]]; then | ||
continue | ||
fi | ||
if eval "[[ \"\${w}\" = *.$1 || -d \"\${w}\" ]]"; then | ||
qw="$(__minikube-support_quote "${w}")" | ||
if [ -d "${w}" ]; then | ||
COMPREPLY+=("${qw}/") | ||
else | ||
COMPREPLY+=("${qw}") | ||
fi | ||
fi | ||
done | ||
} | ||
PowerShell: | ||
__minikube-support_quote() { | ||
if [[ $1 == \'* || $1 == \"* ]]; then | ||
# Leave out first character | ||
printf %q "${1:1}" | ||
else | ||
printf %q "$1" | ||
fi | ||
} | ||
PS> minikube-support completion powershell | Out-String | Invoke-Expression | ||
autoload -U +X bashcompinit && bashcompinit | ||
# use word boundary patterns for BSD or GNU sed | ||
LWORD='[[:<:]]' | ||
RWORD='[[:>:]]' | ||
if sed --help 2>&1 | grep -q GNU; then | ||
LWORD='\<' | ||
RWORD='\>' | ||
fi | ||
__minikube-support_convert_bash_to_zsh() { | ||
sed \ | ||
-e 's/declare -F/whence -w/' \ | ||
-e 's/_get_comp_words_by_ref "\$@"/_get_comp_words_by_ref "\$*"/' \ | ||
-e 's/local \([a-zA-Z0-9_]*\)=/local \1; \1=/' \ | ||
-e 's/flags+=("\(--.*\)=")/flags+=("\1"); two_word_flags+=("\1")/' \ | ||
-e 's/must_have_one_flag+=("\(--.*\)=")/must_have_one_flag+=("\1")/' \ | ||
-e "s/${LWORD}_filedir${RWORD}/__minikube-support_filedir/g" \ | ||
-e "s/${LWORD}_get_comp_words_by_ref${RWORD}/__minikube-support_get_comp_words_by_ref/g" \ | ||
-e "s/${LWORD}__ltrim_colon_completions${RWORD}/__minikube-support_ltrim_colon_completions/g" \ | ||
-e "s/${LWORD}compgen${RWORD}/__minikube-support_compgen/g" \ | ||
-e "s/${LWORD}compopt${RWORD}/__minikube-support_compopt/g" \ | ||
-e "s/${LWORD}declare${RWORD}/builtin declare/g" \ | ||
-e "s/\\\$(type${RWORD}/\$(__minikube-support_type/g" \ | ||
<<'BASH_COMPLETION_EOF' | ||
` | ||
_, _ = out.Write([]byte(zshInitialization)) | ||
buf := new(bytes.Buffer) | ||
e = cmd.GenBashCompletion(buf) | ||
if e != nil { | ||
return e | ||
# To load completions for every new session, run: | ||
PS> minikube-support completion powershell > minikube-support.ps1 | ||
# and source this file from your PowerShell profile. | ||
`, | ||
DisableFlagsInUseLine: true, | ||
ValidArgs: []string{"bash", "zsh", "fish", "powershell", "ps1"}, | ||
Args: cobra.ExactValidArgs(1), | ||
Run: func(cmd *cobra.Command, args []string) { | ||
switch args[0] { | ||
case "bash": | ||
_ = cmd.Root().GenBashCompletion(os.Stdout) | ||
case "zsh": | ||
_ = cmd.Root().GenZshCompletion(os.Stdout) | ||
case "fish": | ||
_ = cmd.Root().GenFishCompletion(os.Stdout, true) | ||
case "powershell": | ||
fallthrough | ||
case "ps1": | ||
_ = cmd.Root().GenPowerShellCompletion(os.Stdout) | ||
} | ||
}, | ||
} | ||
_, _ = out.Write(buf.Bytes()) | ||
|
||
zshTail := ` | ||
BASH_COMPLETION_EOF | ||
return cmd | ||
} | ||
|
||
__minikube-support_bash_source <(__minikube-support_convert_bash_to_zsh) | ||
_complete minikube-support 2>/dev/null | ||
` | ||
_, _ = out.Write([]byte(zshTail)) | ||
return nil | ||
func init() { | ||
rootCmd.AddCommand(NewCompletionCmd()) | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.