mirror of
https://github.com/spf13/cobra
synced 2024-12-29 15:57:10 +00:00
Incorporating pull request feedback.
- Renamed completer to be cobra_completer to match docs - Added whitespace after each completion - Implemented ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp - Disabled active help as it isn't supported by nushell - Added nushell to the default completion command
This commit is contained in:
parent
594faef23f
commit
2f276e3014
4 changed files with 358 additions and 159 deletions
|
@ -836,14 +836,47 @@ to your powershell profile.
|
||||||
return cmd.Root().GenPowerShellCompletion(out)
|
return cmd.Root().GenPowerShellCompletion(out)
|
||||||
}
|
}
|
||||||
return cmd.Root().GenPowerShellCompletionWithDesc(out)
|
return cmd.Root().GenPowerShellCompletionWithDesc(out)
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if haveNoDescFlag {
|
if haveNoDescFlag {
|
||||||
powershell.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
|
powershell.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
|
||||||
}
|
}
|
||||||
|
|
||||||
completionCmd.AddCommand(bash, zsh, fish, powershell)
|
nushell := &Command{
|
||||||
|
Use: "nushell",
|
||||||
|
Short: fmt.Sprintf(shortDesc, "nushell"),
|
||||||
|
Long: fmt.Sprintf(`Generate the autocompletion script for nushell.
|
||||||
|
|
||||||
|
To configure completions:
|
||||||
|
|
||||||
|
# 1. Copy the output of the command below:
|
||||||
|
> %[1]s completion nushell
|
||||||
|
|
||||||
|
# 2. Edit the nushell config file:
|
||||||
|
> config nu
|
||||||
|
|
||||||
|
# 3. Paste above the "let-env config" line.
|
||||||
|
|
||||||
|
# 4. Change the config block's external_completer line to be
|
||||||
|
external_completer: $cobra_completer
|
||||||
|
|
||||||
|
# 5. You will need to start a new shell for this setup to take effect.
|
||||||
|
|
||||||
|
`, c.Root().Name()),
|
||||||
|
Args: NoArgs,
|
||||||
|
ValidArgsFunction: NoFileCompletions,
|
||||||
|
RunE: func(cmd *Command, args []string) error {
|
||||||
|
if noDesc {
|
||||||
|
return cmd.Root().GenPowerShellCompletion(out)
|
||||||
|
}
|
||||||
|
return cmd.Root().GenPowerShellCompletionWithDesc(out)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if haveNoDescFlag {
|
||||||
|
nushell.Flags().BoolVar(&noDesc, compCmdNoDescFlagName, compCmdNoDescFlagDefault, compCmdNoDescFlagDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
completionCmd.AddCommand(bash, zsh, fish, powershell, nushell)
|
||||||
}
|
}
|
||||||
|
|
||||||
func findFlag(cmd *Command, name string) *pflag.Flag {
|
func findFlag(cmd *Command, name string) *pflag.Flag {
|
||||||
|
@ -876,7 +909,7 @@ func CompDebug(msg string, printToStdErr bool) {
|
||||||
// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.
|
// variable BASH_COMP_DEBUG_FILE to the path of some file to be used.
|
||||||
if path := os.Getenv("BASH_COMP_DEBUG_FILE"); path != "" {
|
if path := os.Getenv("BASH_COMP_DEBUG_FILE"); path != "" {
|
||||||
f, err := os.OpenFile(path,
|
f, err := os.OpenFile(path,
|
||||||
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
WriteStringAndCheck(f, msg)
|
WriteStringAndCheck(f, msg)
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,31 +16,39 @@ package cobra
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *Command) GenNushellCompletion(w io.Writer) error {
|
func (c *Command) GenNushellCompletion(w io.Writer) error {
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
WriteStringAndCheck(buf, `
|
WriteStringAndCheck(buf, fmt.Sprintf(`
|
||||||
# An external configurator that works with any cobra based
|
# An external configurator that works with any cobra based
|
||||||
# command line application (e.g. kubectl, minikube)
|
# command line application (e.g. kubectl, minikube)
|
||||||
let cobra_configurator = {|spans|
|
let cobra_completer = {|spans|
|
||||||
|
|
||||||
|
let ShellCompDirectiveError = %[1]d
|
||||||
|
let ShellCompDirectiveNoSpace = %[2]d
|
||||||
|
let ShellCompDirectiveNoFileComp = %[3]d
|
||||||
|
let ShellCompDirectiveFilterFileExt = %[4]d
|
||||||
|
let ShellCompDirectiveFilterDirs = %[5]d
|
||||||
|
|
||||||
let cmd = $spans.0
|
let cmd = $spans.0
|
||||||
|
let last_span = ($spans | last | str trim)
|
||||||
|
|
||||||
# skip the first entry in the span (the command) and join the rest of the span to create __complete args
|
# skip the first entry in the span (the command) and join the rest of the span to create __complete args
|
||||||
let cmd_args = ($spans | skip 1 | str join ' ')
|
let cmd_args = ($spans | skip 1 | str join ' ')
|
||||||
|
|
||||||
# If the last span entry was empty add "" to the end of the command args
|
# If the last span entry was empty add "" to the end of the command args
|
||||||
let cmd_args = if ($spans | last | str trim | is-empty) {
|
let cmd_args = if ($last_span | is-empty) {
|
||||||
$'($cmd_args) ""'
|
$'($cmd_args) ""'
|
||||||
} else {
|
} else {
|
||||||
$cmd_args
|
$cmd_args
|
||||||
}
|
}
|
||||||
|
|
||||||
# The full command to be executed
|
# The full command to be executed with active help disable (Nushell does not support active help)
|
||||||
let full_cmd = $'($cmd) __complete ($cmd_args)'
|
let full_cmd = $'($cmd)_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)'
|
||||||
|
|
||||||
# Since nushell doesn't have anything like eval, execute in a subshell
|
# Since nushell doesn't have anything like eval, execute in a subshell
|
||||||
let result = (do -i { nu -c $"'($full_cmd)'" } | complete)
|
let result = (do -i { nu -c $"'($full_cmd)'" } | complete)
|
||||||
|
@ -48,16 +56,33 @@ let cobra_configurator = {|spans|
|
||||||
# Create a record with all completion related info.
|
# Create a record with all completion related info.
|
||||||
# directive and directive_str are for posterity
|
# directive and directive_str are for posterity
|
||||||
let stdout_lines = ($result.stdout | lines)
|
let stdout_lines = ($result.stdout | lines)
|
||||||
let $completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+]*)\t?(.*)' | rename value description)
|
let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int)
|
||||||
|
let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description)
|
||||||
|
|
||||||
let result = ({
|
# Add space at the end of each completion
|
||||||
completions: $completions
|
let completions = if $directive != $ShellCompDirectiveNoSpace {
|
||||||
directive_str: ($result.stderr)
|
($completions | each {|it| {value: $"($it.value) ", description: $it.description}})
|
||||||
directive: ($stdout_lines | last)
|
} else {
|
||||||
})
|
$completions
|
||||||
|
}
|
||||||
|
|
||||||
$result.completions
|
if $last_span =~ '=$' {
|
||||||
}`)
|
# return flag as part of the completion so that it doesn't get replaced
|
||||||
|
$completions | each {|it| $"($last_span)($it.value)" }
|
||||||
|
} else if $directive == $ShellCompDirectiveNoFileComp {
|
||||||
|
# Allow empty results as this will stop file completion
|
||||||
|
$completions
|
||||||
|
} else if ($completions | is-empty) or $directive == $ShellCompDirectiveError {
|
||||||
|
# Not returning null causes file completions to break
|
||||||
|
# Return null if there are no completions or ShellCompDirectiveError
|
||||||
|
null
|
||||||
|
} else {
|
||||||
|
$completions
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
`, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
|
||||||
|
ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
|
||||||
|
|
||||||
_, err := buf.WriteTo(w)
|
_, err := buf.WriteTo(w)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -38,7 +38,7 @@ func TestGenNushellCompletion(t *testing.T) {
|
||||||
assertNoErr(t, rootCmd.GenNushellCompletion(buf))
|
assertNoErr(t, rootCmd.GenNushellCompletion(buf))
|
||||||
output := buf.String()
|
output := buf.String()
|
||||||
|
|
||||||
check(t, output, "let full_cmd = $'($cmd) __complete ($cmd_args)'")
|
check(t, output, "let full_cmd = $'($cmd)_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)'")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGenNushellCompletionFile(t *testing.T) {
|
func TestGenNushellCompletionFile(t *testing.T) {
|
||||||
|
|
Loading…
Reference in a new issue