Add --init-completion flag to print completion code

This flag takes as input 'bash' or 'zsh' and generates the completion
code for the specified shell.
This commit is contained in:
Antoine Eiche 2016-07-21 21:01:59 +02:00
parent ee2e8aa5b2
commit 7640bef0eb
3 changed files with 50 additions and 0 deletions

6
app.go
View File

@ -138,6 +138,7 @@ func (a *App) Setup() {
if a.EnableBashCompletion { if a.EnableBashCompletion {
a.appendFlag(BashCompletionFlag) a.appendFlag(BashCompletionFlag)
a.appendFlag(InitCompletionFlag)
} }
if !a.HideVersion { if !a.HideVersion {
@ -176,6 +177,11 @@ func (a *App) Run(arguments []string) (err error) {
return nil return nil
} }
var done bool
if done, err = checkInitCompletion(context); done {
return nil
}
if err != nil { if err != nil {
if a.OnUsageError != nil { if a.OnUsageError != nil {
err := a.OnUsageError(context, err, false) err := a.OnUsageError(context, err, false)

View File

@ -27,6 +27,12 @@ var BashCompletionFlag = &BoolFlag{
Hidden: true, Hidden: true,
} }
// InitCompletionFlag generates completion code
var InitCompletionFlag = &StringFlag{
Name: "init-completion",
Usage: "generate completion code. Value must be 'bash' or 'zsh'",
}
// VersionFlag prints the version for the application // VersionFlag prints the version for the application
var VersionFlag = &BoolFlag{ var VersionFlag = &BoolFlag{
Name: "version", Name: "version",

38
help.go
View File

@ -286,3 +286,41 @@ func checkCommandCompletions(c *Context, name string) bool {
return false return false
} }
func checkInitCompletion(c *Context) (bool, error) {
if c.IsSet(InitCompletionFlag.Name) {
shell := c.String(InitCompletionFlag.Name)
progName := os.Args[0]
switch shell {
case "bash":
fmt.Print(bashCompletionCode(progName))
return true, nil
case "zsh":
fmt.Print(zshCompletionCode(progName))
return true, nil
default:
return false, fmt.Errorf("--init-completion value cannot be '%s'", shell)
}
}
return false, nil
}
func bashCompletionCode(progName string) string {
var template = `_cli_bash_autocomplete() {
local cur opts base;
COMPREPLY=();
cur="${COMP_WORDS[COMP_CWORD]}";
opts=$( ${COMP_WORDS[@]:0:$COMP_CWORD} --generate-bash-completion );
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) );
return 0;
};
complete -F _cli_bash_autocomplete %s`
return fmt.Sprintf(template, progName)
}
func zshCompletionCode(progName string) string {
var template = `autoload -U compinit && compinit;
autoload -U bashcompinit && bashcompinit;`
return template + "\n" + bashCompletionCode(progName)
}