From 9f4bdb8eb81c890ff35c17a169cbfbed4df711dd Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Fri, 11 Nov 2022 18:05:24 -0800 Subject: [PATCH 01/16] 'Completions for nushell' --- nushell_completions.go | 124 +++++++++++++++++++++++++++++++ nushell_completions.md | 4 + nushell_completions_test.go | 141 ++++++++++++++++++++++++++++++++++++ shell_completions.md | 14 +++- 4 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 nushell_completions.go create mode 100644 nushell_completions.md create mode 100644 nushell_completions_test.go diff --git a/nushell_completions.go b/nushell_completions.go new file mode 100644 index 000000000..6b944bd9d --- /dev/null +++ b/nushell_completions.go @@ -0,0 +1,124 @@ +// Copyright 2013-2022 The Cobra Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cobra + +import ( + "bytes" + "fmt" + "io" + "os" + "regexp" + "strings" + + "github.com/spf13/pflag" +) + +var carrageReturnRE = regexp.MustCompile(`\r?\n`) + +func descriptionString(desc string) string { + // Remove any carriage returns, this will break the extern + desc = carrageReturnRE.ReplaceAllString(desc, " ") + + // Lets keep the descriptions short-ish + if len(desc) > 100 { + desc = desc[0:97] + "..." + } + return desc +} + +func GenNushellComp(c *Command, buf io.StringWriter, nameBuilder *strings.Builder, isRoot bool, includeDesc bool) { + processFlags := func(flags *pflag.FlagSet) { + flags.VisitAll(func(f *pflag.Flag) { + WriteStringAndCheck(buf, fmt.Sprintf("\t--%[1]s", f.Name)) + + if f.Shorthand != "" { + WriteStringAndCheck(buf, fmt.Sprintf("(-%[1]s)", f.Shorthand)) + } + + if includeDesc && f.Usage != "" { + desc := descriptionString(f.Usage) + WriteStringAndCheck(buf, fmt.Sprintf("\t# %[1]s", desc)) + } + + WriteStringAndCheck(buf, "\n") + + }) + } + + cmdName := c.Name() + // commands after root name will be like "git pull" + if !isRoot { + nameBuilder.WriteString(" ") + } + nameBuilder.WriteString(cmdName) + + // only create an extern block if there is something to put in it + if len(c.ValidArgs) > 0 || c.HasAvailableFlags() { + builderString := nameBuilder.String() + + // ensure there is a space before any previous content + // otherwise it will break descriptions + WriteStringAndCheck(buf, "\n") + + funcName := builderString + if !isRoot { + funcName = fmt.Sprintf("\"%[1]s\"", builderString) + } + + if includeDesc && c.Short != "" { + desc := descriptionString(c.Short) + WriteStringAndCheck(buf, fmt.Sprintf("# %[1]s\n", desc)) + } + WriteStringAndCheck(buf, fmt.Sprintf("export extern %[1]s [\n", funcName)) + + // valid args + for _, arg := range c.ValidArgs { + WriteStringAndCheck(buf, fmt.Sprintf("\t%[1]s?\n", arg)) + } + + processFlags(c.InheritedFlags()) + processFlags(c.LocalFlags()) + + // End extern statement + WriteStringAndCheck(buf, "]\n") + } + + // process sub commands + for _, child := range c.Commands() { + childBuilder := strings.Builder{} + childBuilder.WriteString(nameBuilder.String()) + GenNushellComp(child, buf, &childBuilder, false, includeDesc) + } + +} + +func (c *Command) GenNushellCompletion(w io.Writer, includeDesc bool) error { + var nameBuilder strings.Builder + buf := new(bytes.Buffer) + GenNushellComp(c, buf, &nameBuilder, true, includeDesc) + + _, err := buf.WriteTo(w) + return err +} + +func (c *Command) GenNushellCompletionFile(filename string, includeDesc bool) error { + outFile, err := os.Create(filename) + if err != nil { + return err + } + defer outFile.Close() + + return c.GenNushellCompletion(outFile, includeDesc) +} diff --git a/nushell_completions.md b/nushell_completions.md new file mode 100644 index 000000000..e0e94eb14 --- /dev/null +++ b/nushell_completions.md @@ -0,0 +1,4 @@ +## Generating Nushell Completions For Your cobra.Command + +Please refer to [Shell Completions](shell_completions.md) for details. + diff --git a/nushell_completions_test.go b/nushell_completions_test.go new file mode 100644 index 000000000..77bb00d55 --- /dev/null +++ b/nushell_completions_test.go @@ -0,0 +1,141 @@ +// Copyright 2013-2022 The Cobra Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cobra + +import ( + "bytes" + "log" + "os" + "testing" +) + +func TestGenNushellCompletion(t *testing.T) { + rootCmd := &Command{ + Use: "kubectl", + Run: emptyRun, + } + rootCmd.PersistentFlags().String("server", "s", "The address and port of the Kubernetes API server") + rootCmd.PersistentFlags().BoolP("skip-headers", "", false, "The address and port of the Kubernetes API serverIf true, avoid header prefixes in the log messages") + + getCmd := &Command{ + Use: "get", + Short: "Display one or many resources", + ArgAliases: []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"}, + ValidArgs: []string{"pod", "node", "service", "replicationcontroller"}, + Run: emptyRun, + } + + rootCmd.AddCommand(getCmd) + + buf := new(bytes.Buffer) + assertNoErr(t, rootCmd.GenNushellCompletion(buf, true)) + output := buf.String() + + // root command has no local options, it should not be displayed + checkOmit(t, output, "export extern kubectl") + + check(t, output, "export extern \"kubectl get\"") + check(t, output, "--server") + check(t, output, "--skip-headers") + check(t, output, "pod?") + check(t, output, "node?") + check(t, output, "service?") + check(t, output, "replicationcontroller?") + + check(t, output, "The address and port of the Kubernetes API serverIf true, avoid header prefixes in the log messages") + check(t, output, "The address and port of the Kubernetes API server") + check(t, output, "Display one or many resources") +} + +func TestGenNushellCompletionWithoutDesc(t *testing.T) { + rootCmd := &Command{ + Use: "kubectl", + Run: emptyRun, + } + rootCmd.PersistentFlags().String("server", "s", "The address and port of the Kubernetes API server") + rootCmd.PersistentFlags().BoolP("skip-headers", "", false, "The address and port of the Kubernetes API serverIf true, avoid header prefixes in the log messages") + + getCmd := &Command{ + Use: "get", + Short: "Display one or many resources", + ArgAliases: []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"}, + ValidArgs: []string{"pod", "node", "service", "replicationcontroller"}, + Run: emptyRun, + } + + rootCmd.AddCommand(getCmd) + + buf := new(bytes.Buffer) + assertNoErr(t, rootCmd.GenNushellCompletion(buf, false)) + output := buf.String() + + checkOmit(t, output, "The address and port of the Kubernetes API server") + checkOmit(t, output, "The address and port of the Kubernetes API serverIf true, avoid header prefixes in the log messages") + checkOmit(t, output, "Display one or many resources") +} + +func TestGenNushellCompletionFile(t *testing.T) { + err := os.Mkdir("./tmp", 0755) + if err != nil { + log.Fatal(err.Error()) + } + + defer os.RemoveAll("./tmp") + + rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun} + child := &Command{ + Use: "child", + ValidArgsFunction: validArgsFunc, + Run: emptyRun, + } + rootCmd.AddCommand(child) + + assertNoErr(t, rootCmd.GenNushellCompletionFile("./tmp/test", false)) +} + +func TestFailGenNushellCompletionFile(t *testing.T) { + err := os.Mkdir("./tmp", 0755) + if err != nil { + log.Fatal(err.Error()) + } + + defer os.RemoveAll("./tmp") + + f, _ := os.OpenFile("./tmp/test", os.O_CREATE, 0400) + defer f.Close() + + rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun} + child := &Command{ + Use: "child", + ValidArgsFunction: validArgsFunc, + Run: emptyRun, + } + rootCmd.AddCommand(child) + + got := rootCmd.GenNushellCompletionFile("./tmp/test", false) + if got == nil { + t.Error("should raise permission denied error") + } + + if os.Getenv("MSYSTEM") == "MINGW64" { + if got.Error() != "open ./tmp/test: Access is denied." { + t.Errorf("got: %s, want: %s", got.Error(), "open ./tmp/test: Access is denied.") + } + } else { + if got.Error() != "open ./tmp/test: permission denied" { + t.Errorf("got: %s, want: %s", got.Error(), "open ./tmp/test: permission denied") + } + } +} diff --git a/shell_completions.md b/shell_completions.md index 286c2525b..e0d6db459 100644 --- a/shell_completions.md +++ b/shell_completions.md @@ -6,6 +6,7 @@ The currently supported shells are: - Zsh - fish - PowerShell +- Nushell Cobra will automatically provide your program with a fully functional `completion` command, similarly to how it provides the `help` command. @@ -68,9 +69,18 @@ PowerShell: # To load completions for every new session, run: PS> %[1]s completion powershell > %[1]s.ps1 # and source this file from your PowerShell profile. + +Nushell: + + # To generate completions (replace YOUR_COMPLETION_DIR with actual path to save) + > %[1]s completion nushell | save /YOUR_COMPLETION_DIR/%[1]s-completions.nu + + # To load completions for each session, execute once (replace YOUR_COMPLETION_DIR with actual path): + > echo "use /YOUR_COMPLETION_DIR/%[1]s-completions.nu *" | save --append $nu.config-path + `,cmd.Root().Name()), DisableFlagsInUseLine: true, - ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, + ValidArgs: []string{"bash", "zsh", "fish", "powershell", "nushell"}, Args: cobra.MatchAll(cobra.ExactArgs(1), cobra.OnlyValidArgs), Run: func(cmd *cobra.Command, args []string) { switch args[0] { @@ -82,6 +92,8 @@ PowerShell: cmd.Root().GenFishCompletion(os.Stdout, true) case "powershell": cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) + case "nushell": + cmd.Root().GenNushellCompletion(os.Stdout, true) } }, } From e687d2e9e120a3661ff7378d04c5038492bc9d85 Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Sat, 26 Nov 2022 14:39:29 -0800 Subject: [PATCH 02/16] Changed the nushell completion implementation to be a nushell external completer --- nushell_completions.go | 128 +++++++++++------------------------- nushell_completions_test.go | 61 +++-------------- shell_completions.md | 15 +++-- 3 files changed, 58 insertions(+), 146 deletions(-) diff --git a/nushell_completions.go b/nushell_completions.go index 6b944bd9d..4363946ff 100644 --- a/nushell_completions.go +++ b/nushell_completions.go @@ -16,109 +16,59 @@ package cobra import ( "bytes" - "fmt" "io" "os" - "regexp" - "strings" - - "github.com/spf13/pflag" ) -var carrageReturnRE = regexp.MustCompile(`\r?\n`) - -func descriptionString(desc string) string { - // Remove any carriage returns, this will break the extern - desc = carrageReturnRE.ReplaceAllString(desc, " ") - - // Lets keep the descriptions short-ish - if len(desc) > 100 { - desc = desc[0:97] + "..." - } - return desc -} - -func GenNushellComp(c *Command, buf io.StringWriter, nameBuilder *strings.Builder, isRoot bool, includeDesc bool) { - processFlags := func(flags *pflag.FlagSet) { - flags.VisitAll(func(f *pflag.Flag) { - WriteStringAndCheck(buf, fmt.Sprintf("\t--%[1]s", f.Name)) - - if f.Shorthand != "" { - WriteStringAndCheck(buf, fmt.Sprintf("(-%[1]s)", f.Shorthand)) - } - - if includeDesc && f.Usage != "" { - desc := descriptionString(f.Usage) - WriteStringAndCheck(buf, fmt.Sprintf("\t# %[1]s", desc)) - } - - WriteStringAndCheck(buf, "\n") - - }) - } - - cmdName := c.Name() - // commands after root name will be like "git pull" - if !isRoot { - nameBuilder.WriteString(" ") - } - nameBuilder.WriteString(cmdName) - - // only create an extern block if there is something to put in it - if len(c.ValidArgs) > 0 || c.HasAvailableFlags() { - builderString := nameBuilder.String() - - // ensure there is a space before any previous content - // otherwise it will break descriptions - WriteStringAndCheck(buf, "\n") - - funcName := builderString - if !isRoot { - funcName = fmt.Sprintf("\"%[1]s\"", builderString) - } - - if includeDesc && c.Short != "" { - desc := descriptionString(c.Short) - WriteStringAndCheck(buf, fmt.Sprintf("# %[1]s\n", desc)) - } - WriteStringAndCheck(buf, fmt.Sprintf("export extern %[1]s [\n", funcName)) - - // valid args - for _, arg := range c.ValidArgs { - WriteStringAndCheck(buf, fmt.Sprintf("\t%[1]s?\n", arg)) - } - - processFlags(c.InheritedFlags()) - processFlags(c.LocalFlags()) - - // End extern statement - WriteStringAndCheck(buf, "]\n") - } - - // process sub commands - for _, child := range c.Commands() { - childBuilder := strings.Builder{} - childBuilder.WriteString(nameBuilder.String()) - GenNushellComp(child, buf, &childBuilder, false, includeDesc) - } - -} - -func (c *Command) GenNushellCompletion(w io.Writer, includeDesc bool) error { - var nameBuilder strings.Builder +func (c *Command) GenNushellCompletion(w io.Writer) error { buf := new(bytes.Buffer) - GenNushellComp(c, buf, &nameBuilder, true, includeDesc) + WriteStringAndCheck(buf, ` +# An external configurator that works with any cobra based +# command line application (e.g. kubectl, minikube) +let cobra_configurator = {|spans| + + let cmd = $spans.0 + + # 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 ' ') + + # 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) { + $'($cmd_args) ""' + } else { + $cmd_args + } + + # The full command to be executed + let full_cmd = $'($cmd) __complete ($cmd_args)' + + # Since nushell doesn't have anything like eval, execute in a subshell + let result = (do -i { nu -c $"'($full_cmd)'" } | complete) + + # Create a record with all completion related info. + # directive and directive_str are for posterity + let stdout_lines = ($result.stdout | lines) + let $completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+]*)\t?(.*)' | rename value description) + + let result = ({ + completions: $completions + directive_str: ($result.stderr) + directive: ($stdout_lines | last) + }) + + $result.completions +}`) _, err := buf.WriteTo(w) return err } -func (c *Command) GenNushellCompletionFile(filename string, includeDesc bool) error { +func (c *Command) GenNushellCompletionFile(filename string) error { outFile, err := os.Create(filename) if err != nil { return err } defer outFile.Close() - return c.GenNushellCompletion(outFile, includeDesc) + return c.GenNushellCompletion(outFile) } diff --git a/nushell_completions_test.go b/nushell_completions_test.go index 77bb00d55..3e3c36de0 100644 --- a/nushell_completions_test.go +++ b/nushell_completions_test.go @@ -22,51 +22,9 @@ import ( ) func TestGenNushellCompletion(t *testing.T) { - rootCmd := &Command{ - Use: "kubectl", - Run: emptyRun, - } - rootCmd.PersistentFlags().String("server", "s", "The address and port of the Kubernetes API server") - rootCmd.PersistentFlags().BoolP("skip-headers", "", false, "The address and port of the Kubernetes API serverIf true, avoid header prefixes in the log messages") - - getCmd := &Command{ - Use: "get", - Short: "Display one or many resources", - ArgAliases: []string{"pods", "nodes", "services", "replicationcontrollers", "po", "no", "svc", "rc"}, - ValidArgs: []string{"pod", "node", "service", "replicationcontroller"}, - Run: emptyRun, - } - - rootCmd.AddCommand(getCmd) - - buf := new(bytes.Buffer) - assertNoErr(t, rootCmd.GenNushellCompletion(buf, true)) - output := buf.String() - - // root command has no local options, it should not be displayed - checkOmit(t, output, "export extern kubectl") - - check(t, output, "export extern \"kubectl get\"") - check(t, output, "--server") - check(t, output, "--skip-headers") - check(t, output, "pod?") - check(t, output, "node?") - check(t, output, "service?") - check(t, output, "replicationcontroller?") - - check(t, output, "The address and port of the Kubernetes API serverIf true, avoid header prefixes in the log messages") - check(t, output, "The address and port of the Kubernetes API server") - check(t, output, "Display one or many resources") -} - -func TestGenNushellCompletionWithoutDesc(t *testing.T) { - rootCmd := &Command{ - Use: "kubectl", - Run: emptyRun, - } + rootCmd := &Command{Use: "kubectl", Run: emptyRun} rootCmd.PersistentFlags().String("server", "s", "The address and port of the Kubernetes API server") rootCmd.PersistentFlags().BoolP("skip-headers", "", false, "The address and port of the Kubernetes API serverIf true, avoid header prefixes in the log messages") - getCmd := &Command{ Use: "get", Short: "Display one or many resources", @@ -74,20 +32,17 @@ func TestGenNushellCompletionWithoutDesc(t *testing.T) { ValidArgs: []string{"pod", "node", "service", "replicationcontroller"}, Run: emptyRun, } - rootCmd.AddCommand(getCmd) buf := new(bytes.Buffer) - assertNoErr(t, rootCmd.GenNushellCompletion(buf, false)) + assertNoErr(t, rootCmd.GenNushellCompletion(buf)) output := buf.String() - checkOmit(t, output, "The address and port of the Kubernetes API server") - checkOmit(t, output, "The address and port of the Kubernetes API serverIf true, avoid header prefixes in the log messages") - checkOmit(t, output, "Display one or many resources") + check(t, output, "let full_cmd = $'($cmd) __complete ($cmd_args)'") } func TestGenNushellCompletionFile(t *testing.T) { - err := os.Mkdir("./tmp", 0755) + err := os.Mkdir("./tmp", 0o755) if err != nil { log.Fatal(err.Error()) } @@ -102,18 +57,18 @@ func TestGenNushellCompletionFile(t *testing.T) { } rootCmd.AddCommand(child) - assertNoErr(t, rootCmd.GenNushellCompletionFile("./tmp/test", false)) + assertNoErr(t, rootCmd.GenNushellCompletionFile("./tmp/test")) } func TestFailGenNushellCompletionFile(t *testing.T) { - err := os.Mkdir("./tmp", 0755) + err := os.Mkdir("./tmp", 0o755) if err != nil { log.Fatal(err.Error()) } defer os.RemoveAll("./tmp") - f, _ := os.OpenFile("./tmp/test", os.O_CREATE, 0400) + f, _ := os.OpenFile("./tmp/test", os.O_CREATE, 0o400) defer f.Close() rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun} @@ -124,7 +79,7 @@ func TestFailGenNushellCompletionFile(t *testing.T) { } rootCmd.AddCommand(child) - got := rootCmd.GenNushellCompletionFile("./tmp/test", false) + got := rootCmd.GenNushellCompletionFile("./tmp/test") if got == nil { t.Error("should raise permission denied error") } diff --git a/shell_completions.md b/shell_completions.md index e0d6db459..21fa22fb7 100644 --- a/shell_completions.md +++ b/shell_completions.md @@ -72,11 +72,18 @@ PowerShell: Nushell: - # To generate completions (replace YOUR_COMPLETION_DIR with actual path to save) - > %[1]s completion nushell | save /YOUR_COMPLETION_DIR/%[1]s-completions.nu + # 1. Copy the output of the command below: + > %[1]s completion nushell - # To load completions for each session, execute once (replace YOUR_COMPLETION_DIR with actual path): - > echo "use /YOUR_COMPLETION_DIR/%[1]s-completions.nu *" | save --append $nu.config-path + # 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. `,cmd.Root().Name()), DisableFlagsInUseLine: true, From 0e4db1bd14478e526004bf781c15af8aa2ca9bd2 Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Sun, 27 Nov 2022 13:46:13 -0800 Subject: [PATCH 03/16] 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 --- completions.go | 39 +++- completions_test.go | 425 ++++++++++++++++++++++++------------ nushell_completions.go | 51 +++-- nushell_completions_test.go | 2 +- 4 files changed, 358 insertions(+), 159 deletions(-) diff --git a/completions.go b/completions.go index e8a0206db..509c79606 100644 --- a/completions.go +++ b/completions.go @@ -798,14 +798,47 @@ to your powershell profile. return cmd.Root().GenPowerShellCompletion(out) } return cmd.Root().GenPowerShellCompletionWithDesc(out) - }, } if haveNoDescFlag { 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 { @@ -838,7 +871,7 @@ func CompDebug(msg string, printToStdErr bool) { // variable BASH_COMP_DEBUG_FILE to the path of some file to be used. if path := os.Getenv("BASH_COMP_DEBUG_FILE"); 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 { defer f.Close() WriteStringAndCheck(f, msg) diff --git a/completions_test.go b/completions_test.go index abac12e46..711b46829 100644 --- a/completions_test.go +++ b/completions_test.go @@ -95,7 +95,8 @@ func TestCmdNameCompletionInGo(t *testing.T) { "help", "secondChild", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -110,7 +111,8 @@ func TestCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "secondChild", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -125,7 +127,8 @@ func TestCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -144,7 +147,8 @@ func TestCmdNameCompletionInGo(t *testing.T) { "help\tHelp about any command", "secondChild", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -184,7 +188,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected := strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -200,7 +205,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -222,7 +228,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { "completion", "help", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -244,7 +251,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "childCmd2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -259,7 +267,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -275,7 +284,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -292,7 +302,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "childCmd2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -309,7 +320,8 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "childCmd2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -334,7 +346,8 @@ func TestValidArgsCompletionInGo(t *testing.T) { "two", "three", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -349,7 +362,8 @@ func TestValidArgsCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "one", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -363,7 +377,8 @@ func TestValidArgsCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -397,7 +412,8 @@ func TestValidArgsAndCmdCompletionInGo(t *testing.T) { "one", "two", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -413,7 +429,8 @@ func TestValidArgsAndCmdCompletionInGo(t *testing.T) { "thechild", "two", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -448,7 +465,8 @@ func TestValidArgsFuncAndCmdCompletionInGo(t *testing.T) { "one", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -464,7 +482,8 @@ func TestValidArgsFuncAndCmdCompletionInGo(t *testing.T) { "thechild", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -480,7 +499,8 @@ func TestValidArgsFuncAndCmdCompletionInGo(t *testing.T) { "thechild\tThe child command", "two\tThe second", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -514,7 +534,8 @@ func TestFlagNameCompletionInGo(t *testing.T) { "completion", "help", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -534,7 +555,8 @@ func TestFlagNameCompletionInGo(t *testing.T) { "--second", "-s", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -549,7 +571,8 @@ func TestFlagNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "--first", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -570,7 +593,8 @@ func TestFlagNameCompletionInGo(t *testing.T) { "--version", "-v", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -605,7 +629,8 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { "completion\tGenerate the autocompletion script for the specified shell", "help\tHelp about any command", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -625,7 +650,8 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { "--second\tsecond flag", "-s\tsecond flag", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -640,7 +666,8 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { expected = strings.Join([]string{ "--first\tfirst flag", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -661,7 +688,8 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { "--version\tversion for childCmd", "-v\tversion for childCmd", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -706,7 +734,8 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--second", "--slice", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -727,7 +756,8 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--help", "--slice", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -751,7 +781,8 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--second", "--slice", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -780,7 +811,8 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--slice", "-l", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -798,7 +830,8 @@ func TestFlagNameCompletionRepeat(t *testing.T) { expected = strings.Join([]string{ "-a", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -850,7 +883,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "-p", "realArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -868,7 +902,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "--requiredPersistent", "-p", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -883,7 +918,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "--release", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -902,7 +938,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "-s", "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -919,7 +956,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "--subRequired", "-s", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -933,7 +971,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "--subNotRequired", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -952,7 +991,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "-p", "realArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -974,7 +1014,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "-r", "realArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -992,7 +1033,8 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "realArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1030,7 +1072,8 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected := strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1044,7 +1087,8 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "log", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1058,7 +1102,8 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "yaml", "yml", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1072,7 +1117,8 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "yaml", "yml", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1086,7 +1132,8 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "yaml", "yml", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1100,7 +1147,8 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "yaml", "yml", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1114,7 +1162,8 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "txt", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1148,7 +1197,8 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected := strings.Join([]string{ ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1161,7 +1211,8 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1175,7 +1226,8 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "themes", ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1189,7 +1241,8 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "themes", ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1203,7 +1256,8 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "themes", ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1217,7 +1271,8 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "themes", ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1230,7 +1285,8 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1272,7 +1328,8 @@ func TestValidArgsFuncCmdContext(t *testing.T) { expected := strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1296,7 +1353,8 @@ func TestValidArgsFuncSingleCmd(t *testing.T) { "one", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1311,7 +1369,8 @@ func TestValidArgsFuncSingleCmd(t *testing.T) { expected = strings.Join([]string{ "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1338,7 +1397,8 @@ func TestValidArgsFuncSingleCmdInvalidArg(t *testing.T) { expected := strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1369,7 +1429,8 @@ func TestValidArgsFuncChildCmds(t *testing.T) { "one", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1384,7 +1445,8 @@ func TestValidArgsFuncChildCmds(t *testing.T) { expected = strings.Join([]string{ "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1398,7 +1460,8 @@ func TestValidArgsFuncChildCmds(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1414,7 +1477,8 @@ func TestValidArgsFuncChildCmds(t *testing.T) { "three", "four", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1428,7 +1492,8 @@ func TestValidArgsFuncChildCmds(t *testing.T) { expected = strings.Join([]string{ "three", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1442,7 +1507,8 @@ func TestValidArgsFuncChildCmds(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1469,7 +1535,8 @@ func TestValidArgsFuncAliases(t *testing.T) { "one", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1484,7 +1551,8 @@ func TestValidArgsFuncAliases(t *testing.T) { expected = strings.Join([]string{ "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1498,7 +1566,8 @@ func TestValidArgsFuncAliases(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1622,7 +1691,8 @@ func TestFlagCompletionInGo(t *testing.T) { "2", "10", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1638,7 +1708,8 @@ func TestFlagCompletionInGo(t *testing.T) { "1", "10", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1655,7 +1726,8 @@ func TestFlagCompletionInGo(t *testing.T) { "myfile.json", "file.xml", ":6", - "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1671,7 +1743,8 @@ func TestFlagCompletionInGo(t *testing.T) { "file.yaml", "file.xml", ":6", - "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1702,7 +1775,8 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { "one\tThe first", "two\tThe second", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1717,7 +1791,8 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { expected = strings.Join([]string{ "two\tThe second", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1731,7 +1806,8 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1747,7 +1823,8 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { "three\tThe third", "four\tThe fourth", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1761,7 +1838,8 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { expected = strings.Join([]string{ "three\tThe third", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1775,7 +1853,8 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1814,7 +1893,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--help\thelp for child", "--string\ttest string flag", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1830,7 +1910,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1846,7 +1927,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1865,7 +1947,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1881,7 +1964,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1897,7 +1981,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1913,7 +1998,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1929,7 +2015,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "arg1", "arg2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1945,7 +2032,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1961,7 +2049,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1979,7 +2068,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { expected = strings.Join([]string{ "--validarg", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1998,7 +2088,8 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "--toComp=ab", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2033,7 +2124,8 @@ func TestFlagCompletionWorksRootCommandAddedAfterFlags(t *testing.T) { expected := strings.Join([]string{ "myval", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2077,7 +2169,8 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) { "2\tThe second", "10\tThe tenth", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2093,7 +2186,8 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) { "1\tThe first", "10\tThe tenth", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2110,7 +2204,8 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) { "myfile.json\tJSON format", "file.xml\tXML format", ":6", - "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2126,7 +2221,8 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) { "file.yaml\tYAML format", "file.xml\tXML format", ":6", - "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2154,7 +2250,8 @@ func TestValidArgsNotValidArgsFunc(t *testing.T) { "one", "two", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2169,7 +2266,8 @@ func TestValidArgsNotValidArgsFunc(t *testing.T) { expected = strings.Join([]string{ "two", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2196,7 +2294,8 @@ func TestArgAliasesCompletionInGo(t *testing.T) { "two", "three", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2212,7 +2311,8 @@ func TestArgAliasesCompletionInGo(t *testing.T) { "two", "three", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2227,7 +2327,8 @@ func TestArgAliasesCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "trois", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2264,7 +2365,8 @@ func TestCompleteHelp(t *testing.T) { "completion", "help", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2282,7 +2384,8 @@ func TestCompleteHelp(t *testing.T) { "completion", "help", // " help help" is a valid command, so should be completed ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2297,7 +2400,8 @@ func TestCompleteHelp(t *testing.T) { expected = strings.Join([]string{ "child3", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2466,10 +2570,12 @@ func TestCompleteCompletion(t *testing.T) { expected := strings.Join([]string{ "bash", "fish", + "nushell", "powershell", "zsh", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2492,7 +2598,8 @@ func TestCompleteCompletion(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2524,7 +2631,8 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { "foo", "bar", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2540,7 +2648,8 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { "foo", "bar", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2555,7 +2664,8 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { expected = strings.Join([]string{ "works", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2570,7 +2680,8 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { expected = strings.Join([]string{ "works", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2586,7 +2697,8 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { "foo", "bar", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2594,7 +2706,6 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { } func TestCompleteWithDisableFlagParsing(t *testing.T) { - flagValidArgs := func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) { return []string{"--flag", "-f"}, ShellCompDirectiveNoFileComp } @@ -2629,7 +2740,8 @@ func TestCompleteWithDisableFlagParsing(t *testing.T) { "--flag", "-f", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2651,7 +2763,8 @@ func TestCompleteWithDisableFlagParsing(t *testing.T) { "--nonPersistent", "-n", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2680,7 +2793,8 @@ func TestCompleteWithRootAndLegacyArgs(t *testing.T) { "arg1", "arg2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2696,7 +2810,8 @@ func TestCompleteWithRootAndLegacyArgs(t *testing.T) { "arg1", "arg2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2723,7 +2838,8 @@ func TestFixedCompletions(t *testing.T) { "banana", "orange", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2769,7 +2885,8 @@ func TestCompletionForGroupedFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "flags in group suggested with - prefix", @@ -2782,7 +2899,8 @@ func TestCompletionForGroupedFlags(t *testing.T) { "--ingroup3", "--nogroup", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "when flag in group present, other flags in group suggested even without - prefix", @@ -2792,7 +2910,8 @@ func TestCompletionForGroupedFlags(t *testing.T) { "--ingroup3", "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "when all flags in group present, flags not suggested without - prefix", @@ -2800,7 +2919,8 @@ func TestCompletionForGroupedFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "group ignored if some flags not applicable", @@ -2810,7 +2930,8 @@ func TestCompletionForGroupedFlags(t *testing.T) { "completion", "help", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, } @@ -2869,7 +2990,8 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "flags in mutually exclusive group suggested with the - prefix", @@ -2882,7 +3004,8 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) { "--ingroup3", "--nogroup", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "when flag in mutually exclusive group present, other flags in group not suggested even with the - prefix", @@ -2893,7 +3016,8 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) { "-h", "--nogroup", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "group ignored if some flags not applicable", @@ -2904,7 +3028,8 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) { "--ingroup1", "--ingroup2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, } @@ -2986,70 +3111,80 @@ func TestCompletionCobraFlags(t *testing.T) { "--version", "-v", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after --help flag", args: []string{"--help", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after -h flag", args: []string{"-h", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after --version flag", args: []string{"--version", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after -v flag", args: []string{"-v", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after --help flag even with other completions", args: []string{"child", "--help", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after -h flag even with other completions", args: []string{"child", "-h", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after --version flag even with other completions", args: []string{"child", "--version", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after -v flag even with other completions", args: []string{"child", "-v", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "no completion after -v flag even with other flag completions", args: []string{"child", "-v", "-"}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "completion after --help flag when created by program", @@ -3057,7 +3192,8 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "completion after -h flag when created by program", @@ -3065,7 +3201,8 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "completion after --version flag when created by program", @@ -3073,7 +3210,8 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "completion after -v flag when created by program", @@ -3081,14 +3219,16 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "completion after --version when only -v flag was created by program", args: []string{"child3", "--version", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, { desc: "completion after -v flag when only -v flag was created by program", @@ -3096,7 +3236,8 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra3", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", "", + }, "\n"), }, } diff --git a/nushell_completions.go b/nushell_completions.go index 4363946ff..3b4e2c672 100644 --- a/nushell_completions.go +++ b/nushell_completions.go @@ -16,31 +16,39 @@ package cobra import ( "bytes" + "fmt" "io" "os" ) func (c *Command) GenNushellCompletion(w io.Writer) error { buf := new(bytes.Buffer) - WriteStringAndCheck(buf, ` + WriteStringAndCheck(buf, fmt.Sprintf(` # An external configurator that works with any cobra based # 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 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 let cmd_args = ($spans | skip 1 | str join ' ') # 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) ""' } else { $cmd_args } - # The full command to be executed - let full_cmd = $'($cmd) __complete ($cmd_args)' + # The full command to be executed with active help disable (Nushell does not support active help) + let full_cmd = $'($cmd)_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)' # Since nushell doesn't have anything like eval, execute in a subshell 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. # directive and directive_str are for posterity 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 = ({ - completions: $completions - directive_str: ($result.stderr) - directive: ($stdout_lines | last) - }) + # Add space at the end of each completion + let completions = if $directive != $ShellCompDirectiveNoSpace { + ($completions | each {|it| {value: $"($it.value) ", description: $it.description}}) + } 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) return err diff --git a/nushell_completions_test.go b/nushell_completions_test.go index 3e3c36de0..b82898aae 100644 --- a/nushell_completions_test.go +++ b/nushell_completions_test.go @@ -38,7 +38,7 @@ func TestGenNushellCompletion(t *testing.T) { assertNoErr(t, rootCmd.GenNushellCompletion(buf)) 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) { From 1c908e13f56c863dfded15576fa647b5d7c8ef90 Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Sun, 27 Nov 2022 13:55:50 -0800 Subject: [PATCH 04/16] Added nushell to the Use: line --- shell_completions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell_completions.md b/shell_completions.md index 21fa22fb7..6672578bd 100644 --- a/shell_completions.md +++ b/shell_completions.md @@ -29,7 +29,7 @@ and then modifying the generated `cmd/completion.go` file to look something like ```go var completionCmd = &cobra.Command{ - Use: "completion [bash|zsh|fish|powershell]", + Use: "completion [bash|zsh|fish|powershell|nushell]", Short: "Generate completion script", Long: fmt.Sprintf(`To load completions: From 95f2d8e38a23c0232d27654e4c37a88a01d3e10d Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Sun, 27 Nov 2022 15:06:59 -0800 Subject: [PATCH 05/16] Added a whitelist to add cobra apps to to prevent non-cobra apps from being excuted --- completions.go | 14 +++++- nushell_completions.go | 96 +++++++++++++++++++++++------------------- shell_completions.md | 14 +++++- 3 files changed, 77 insertions(+), 47 deletions(-) diff --git a/completions.go b/completions.go index 509c79606..5e6e80d4b 100644 --- a/completions.go +++ b/completions.go @@ -809,7 +809,7 @@ to your powershell profile. Short: fmt.Sprintf(shortDesc, "nushell"), Long: fmt.Sprintf(`Generate the autocompletion script for nushell. -To configure completions: +To configure the Nushell cobra external configurator for the first time: # 1. Copy the output of the command below: > %[1]s completion nushell @@ -822,7 +822,17 @@ To configure completions: # 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. + # 5. You will need to start a new shell or for this setup to take effect. + +If you have already setup the cobra external configurator: + + # 1. Edit the nushell config file: + > config nu + + # 2. Modify the cobra_apps varible to contain this application: + > let cobra_apps = [ "othercobraapp", "%[1]s" ] + + # 3. You will need to start a new shell or for this setup to take effect. `, c.Root().Name()), Args: NoArgs, diff --git a/nushell_completions.go b/nushell_completions.go index 3b4e2c672..568d3cb5e 100644 --- a/nushell_completions.go +++ b/nushell_completions.go @@ -24,64 +24,72 @@ import ( func (c *Command) GenNushellCompletion(w io.Writer) error { buf := new(bytes.Buffer) WriteStringAndCheck(buf, fmt.Sprintf(` + +# A list of cobra that completion will be attempted for. +# Add new apps to this list to enable completion for them. +let cobra_apps = ["%[1]s"] + # An external configurator that works with any cobra based # command line application (e.g. kubectl, minikube) 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 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 - let cmd_args = ($spans | skip 1 | str join ' ') + if not ($cobra_apps | where $it == $cmd | is-empty) { + let ShellCompDirectiveError = %[2]d + let ShellCompDirectiveNoSpace = %[3]d + let ShellCompDirectiveNoFileComp = %[4]d + let ShellCompDirectiveFilterFileExt = %[5]d + let ShellCompDirectiveFilterDirs = %[6]d + + let last_span = ($spans | last | str trim) - # If the last span entry was empty add "" to the end of the command args - let cmd_args = if ($last_span | is-empty) { - $'($cmd_args) ""' - } else { - $cmd_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 ' ') - # The full command to be executed with active help disable (Nushell does not support active help) - let full_cmd = $'($cmd)_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)' + # If the last span entry was empty add "" to the end of the command args + let cmd_args = if ($last_span | is-empty) { + $'($cmd_args) ""' + } else { + $cmd_args + } - # Since nushell doesn't have anything like eval, execute in a subshell - let result = (do -i { nu -c $"'($full_cmd)'" } | complete) + # The full command to be executed with active help disable (Nushell does not support active help) + let full_cmd = $'($cmd)_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)' - # Create a record with all completion related info. - # directive and directive_str are for posterity - let stdout_lines = ($result.stdout | lines) - let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int) - let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description) + # Since nushell doesn't have anything like eval, execute in a subshell + let result = (do -i { nu -c $"'($full_cmd)'" } | complete) - # Add space at the end of each completion - let completions = if $directive != $ShellCompDirectiveNoSpace { - ($completions | each {|it| {value: $"($it.value) ", description: $it.description}}) - } else { - $completions - } + # Create a record with all completion related info. + # directive and directive_str are for posterity + let stdout_lines = ($result.stdout | lines) + let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int) + let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description) - 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 + # Add space at the end of each completion + let completions = if $directive != $ShellCompDirectiveNoSpace { + ($completions | each {|it| {value: $"($it.value) ", description: $it.description}}) + } else { + $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 + } } else { - $completions + null } - } -`, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, +`, c.Name(), ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs)) _, err := buf.WriteTo(w) diff --git a/shell_completions.md b/shell_completions.md index 6672578bd..89198cc4b 100644 --- a/shell_completions.md +++ b/shell_completions.md @@ -72,6 +72,8 @@ PowerShell: Nushell: + # To configure the Nushell cobra external configurator for the first time: + # 1. Copy the output of the command below: > %[1]s completion nushell @@ -83,7 +85,17 @@ Nushell: # 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. + # 5. You will need to start a new shell or for this setup to take effect. + + # If you have already setup the cobra external configurator: + + # 1. Edit the nushell config file: + > config nu + + # 2. Modify the cobra_apps varible to contain this application: + > let cobra_apps = [ "othercobraapp", "%[1]s" ] + + # 3. You will need to start a new shell for this setup to take effect. `,cmd.Root().Name()), DisableFlagsInUseLine: true, From 4ad4930a12843bc131467a13c82f72099b6ce371 Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Mon, 28 Nov 2022 13:39:12 -0800 Subject: [PATCH 06/16] Incorporating pull request feedback - Fixing completion on full paths - Fixing completion with equals in flags - Fixing fuzzy search - Typos --- completions.go | 25 ++++++------------------- nushell_completions.go | 34 +++++++++++++++++++++------------- nushell_completions_test.go | 9 +++++---- shell_completions.md | 12 ++---------- 4 files changed, 34 insertions(+), 46 deletions(-) diff --git a/completions.go b/completions.go index 5e6e80d4b..4c86d0af2 100644 --- a/completions.go +++ b/completions.go @@ -809,39 +809,26 @@ to your powershell profile. Short: fmt.Sprintf(shortDesc, "nushell"), Long: fmt.Sprintf(`Generate the autocompletion script for nushell. -To configure the Nushell cobra external configurator for the first time: - +To configure the Nushell cobra external completer for the first time: # 1. Copy the output of the command below: - > %[1]s completion nushell - + > %[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 - + # 4. Change the config block's external_completer line to be external_completer: $cobra_completer # 5. You will need to start a new shell or for this setup to take effect. -If you have already setup the cobra external configurator: - +If you have already setup the cobra external completer: # 1. Edit the nushell config file: > config nu - # 2. Modify the cobra_apps varible to contain this application: > let cobra_apps = [ "othercobraapp", "%[1]s" ] - - # 3. You will need to start a new shell or for this setup to take effect. - + # 3. 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) + return cmd.Root().GenNushellCompletion(out, !noDesc) }, } if haveNoDescFlag { diff --git a/nushell_completions.go b/nushell_completions.go index 568d3cb5e..87c34a737 100644 --- a/nushell_completions.go +++ b/nushell_completions.go @@ -21,20 +21,20 @@ import ( "os" ) -func (c *Command) GenNushellCompletion(w io.Writer) error { +func (c *Command) GenNushellCompletion(w io.Writer, includeDesc bool) error { buf := new(bytes.Buffer) + name := c.Name() WriteStringAndCheck(buf, fmt.Sprintf(` - -# A list of cobra that completion will be attempted for. +# A list of cobra apps that completion will be attempted for. # Add new apps to this list to enable completion for them. let cobra_apps = ["%[1]s"] -# An external configurator that works with any cobra based +# An external completer that works with any cobra based # command line application (e.g. kubectl, minikube) let cobra_completer = {|spans| let cmd = $spans.0 - if not ($cobra_apps | where $it == $cmd | is-empty) { + if not ($cobra_apps | where $cmd =~ $it | is-empty) { let ShellCompDirectiveError = %[2]d let ShellCompDirectiveNoSpace = %[3]d let ShellCompDirectiveNoFileComp = %[4]d @@ -54,7 +54,7 @@ let cobra_completer = {|spans| } # The full command to be executed with active help disable (Nushell does not support active help) - let full_cmd = $'($cmd)_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)' + let full_cmd = $'%[7]s=0 ($cmd) __complete ($cmd_args)' # Since nushell doesn't have anything like eval, execute in a subshell let result = (do -i { nu -c $"'($full_cmd)'" } | complete) @@ -65,6 +65,14 @@ let cobra_completer = {|spans| let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int) let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description) + # filter completions that don't contain the last span, for fuzzy searches + let filtered = ($completions | where $it.value =~ $last_span) + let completions = if not ($filtered | is-empty) { + $filtered + } else { + $completions + } + # Add space at the end of each completion let completions = if $directive != $ShellCompDirectiveNoSpace { ($completions | each {|it| {value: $"($it.value) ", description: $it.description}}) @@ -72,9 +80,9 @@ let cobra_completer = {|spans| $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)" } + if $last_span =~ '=' { + # if the completion is of the form -n= return flag as part of the completion so that it doesn't get replaced + $completions | each {|it| $"($last_span | split row '=' | first)=($it.value)" } } else if $directive == $ShellCompDirectiveNoFileComp { # Allow empty results as this will stop file completion $completions @@ -89,19 +97,19 @@ let cobra_completer = {|spans| null } } -`, c.Name(), ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, - ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs)) +`, name, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, + ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name))) _, err := buf.WriteTo(w) return err } -func (c *Command) GenNushellCompletionFile(filename string) error { +func (c *Command) GenNushellCompletionFile(filename string, includeDesc bool) error { outFile, err := os.Create(filename) if err != nil { return err } defer outFile.Close() - return c.GenNushellCompletion(outFile) + return c.GenNushellCompletion(outFile, includeDesc) } diff --git a/nushell_completions_test.go b/nushell_completions_test.go index b82898aae..73fedd073 100644 --- a/nushell_completions_test.go +++ b/nushell_completions_test.go @@ -16,6 +16,7 @@ package cobra import ( "bytes" + "fmt" "log" "os" "testing" @@ -35,10 +36,10 @@ func TestGenNushellCompletion(t *testing.T) { rootCmd.AddCommand(getCmd) buf := new(bytes.Buffer) - assertNoErr(t, rootCmd.GenNushellCompletion(buf)) + assertNoErr(t, rootCmd.GenNushellCompletion(buf, true)) output := buf.String() - check(t, output, "let full_cmd = $'($cmd)_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)'") + check(t, output, fmt.Sprintf("let cobra_apps = [\"%[1]s\"]", rootCmd.Name())) } func TestGenNushellCompletionFile(t *testing.T) { @@ -57,7 +58,7 @@ func TestGenNushellCompletionFile(t *testing.T) { } rootCmd.AddCommand(child) - assertNoErr(t, rootCmd.GenNushellCompletionFile("./tmp/test")) + assertNoErr(t, rootCmd.GenNushellCompletionFile("./tmp/test", true)) } func TestFailGenNushellCompletionFile(t *testing.T) { @@ -79,7 +80,7 @@ func TestFailGenNushellCompletionFile(t *testing.T) { } rootCmd.AddCommand(child) - got := rootCmd.GenNushellCompletionFile("./tmp/test") + got := rootCmd.GenNushellCompletionFile("./tmp/test", true) if got == nil { t.Error("should raise permission denied error") } diff --git a/shell_completions.md b/shell_completions.md index 89198cc4b..48317664e 100644 --- a/shell_completions.md +++ b/shell_completions.md @@ -72,29 +72,21 @@ PowerShell: Nushell: - # To configure the Nushell cobra external configurator for the first time: - + # To configure the Nushell cobra external completer for the first time: # 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 or for this setup to take effect. - # If you have already setup the cobra external configurator: - + # If you have already setup the cobra external completer: # 1. Edit the nushell config file: > config nu - # 2. Modify the cobra_apps varible to contain this application: > let cobra_apps = [ "othercobraapp", "%[1]s" ] - # 3. You will need to start a new shell for this setup to take effect. `,cmd.Root().Name()), From f366bb2799d36fa1e00a3ad105c1c8b4b45af6f6 Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Thu, 15 Dec 2022 13:21:37 -0800 Subject: [PATCH 07/16] "fixing oddities with fuzzy searching and bug with active help" --- nushell_completions.go | 118 +++++++++++++++++++++++++++++++---------- 1 file changed, 89 insertions(+), 29 deletions(-) diff --git a/nushell_completions.go b/nushell_completions.go index 87c34a737..8f7c8568b 100644 --- a/nushell_completions.go +++ b/nushell_completions.go @@ -31,7 +31,7 @@ let cobra_apps = ["%[1]s"] # An external completer that works with any cobra based # command line application (e.g. kubectl, minikube) -let cobra_completer = {|spans| +let-env cobra_completer = {|spans| let cmd = $spans.0 if not ($cobra_apps | where $cmd =~ $it | is-empty) { @@ -43,44 +43,96 @@ let cobra_completer = {|spans| 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 - let cmd_args = ($spans | skip 1 | str join ' ') - - # If the last span entry was empty add "" to the end of the command args - let cmd_args = if ($last_span | is-empty) { - $'($cmd_args) ""' - } else { - $cmd_args + def exec_complete [ + --fuzzy, + spans: list + ] { + let params = { + last_span: ($spans | last | str trim), + spans: $spans + } + + # If there is an equals in the last span + # parse the span into two + let params = if $last_span =~ '=' { + let split = ($last_span | split row '=') + if ($split | length) > 1 { + { + last_span: ($split | last), + spans: ($spans | drop | append ($split | first) | append ($split | last)) + } + } else { + { + last_span: '', + spans: ($spans | drop | append ($split | first) | append '') + } + } + } else { + $params + } + + let last_span = $params.last_span + let spans = $params.spans + + # Drop the last param so we can fuzzy search on it + let spans = if $fuzzy { + $spans | drop + } else { + $spans + } + + # 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 ' ') + + # If the last span entry was empty add "" to the end of the command args + let cmd_args = if ($last_span | is-empty) or $fuzzy { + $'($cmd_args) ""' + } else { + $cmd_args + } + + # The full command to be executed with active help disable (Nushell does not support active help) + let full_cmd = $'COBRA_ACTIVE_HELP=0 ($cmd) __complete ($cmd_args)' + + # Since nushell doesn't have anything like eval, execute in a subshell + let result = (do -i { nu -c $"'($full_cmd)'" } | complete) + + # Create a record with all completion related info. + # directive and directive_str are for posterity + let stdout_lines = ($result.stdout | lines) + let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int) + let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description) + let completions = if $fuzzy { + $completions | where $it.value =~ $last_span + + } else { + ($completions | where {|it| $it.value | str starts-with $last_span }) + } + + { + directive: $directive, + completions: $completions + } } - # The full command to be executed with active help disable (Nushell does not support active help) - let full_cmd = $'%[7]s=0 ($cmd) __complete ($cmd_args)' - - # Since nushell doesn't have anything like eval, execute in a subshell - let result = (do -i { nu -c $"'($full_cmd)'" } | complete) - - # Create a record with all completion related info. - # directive and directive_str are for posterity - let stdout_lines = ($result.stdout | lines) - let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int) - let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description) - - # filter completions that don't contain the last span, for fuzzy searches - let filtered = ($completions | where $it.value =~ $last_span) - let completions = if not ($filtered | is-empty) { - $filtered + let result = (exec_complete $spans) + let result = if (not ($last_span | is-empty)) and ($result.completions | is-empty) { + exec_complete --fuzzy $spans } else { - $completions + $result } + let directive = $result.directive + let completions = $result.completions + # Add space at the end of each completion let completions = if $directive != $ShellCompDirectiveNoSpace { - ($completions | each {|it| {value: $"($it.value) ", description: $it.description}}) + $completions | each {|it| {value: $"($it.value) ", description: $it.description}} } else { $completions } - if $last_span =~ '=' { + let return_val = if $last_span =~ '=' { # if the completion is of the form -n= return flag as part of the completion so that it doesn't get replaced $completions | each {|it| $"($last_span | split row '=' | first)=($it.value)" } } else if $directive == $ShellCompDirectiveNoFileComp { @@ -93,12 +145,20 @@ let cobra_completer = {|spans| } else { $completions } + + $return_val } else { null } } + + + + + + `, name, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, - ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, activeHelpEnvVar(name))) + ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs)) _, err := buf.WriteTo(w) return err From fe8bf5e1bd1e1b7f57f88956e242db0c2673a94b Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Fri, 16 Dec 2022 09:32:22 -0800 Subject: [PATCH 08/16] "ignoring return value when directive is ShellComp#directiveFilterFileExt" --- nushell_completions.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nushell_completions.go b/nushell_completions.go index 8f7c8568b..c03ea8df5 100644 --- a/nushell_completions.go +++ b/nushell_completions.go @@ -31,7 +31,7 @@ let cobra_apps = ["%[1]s"] # An external completer that works with any cobra based # command line application (e.g. kubectl, minikube) -let-env cobra_completer = {|spans| +let cobra_completer = {|spans| let cmd = $spans.0 if not ($cobra_apps | where $cmd =~ $it | is-empty) { @@ -132,6 +132,14 @@ let-env cobra_completer = {|spans| $completions } + # Cobra returns a list of completions that are supported with this directive + # There is no way to currently support this in a nushell external completer + let completions = if $directive == $ShellCompDirectiveFilterFileExt { + [] + } else { + $completions + } + let return_val = if $last_span =~ '=' { # if the completion is of the form -n= return flag as part of the completion so that it doesn't get replaced $completions | each {|it| $"($last_span | split row '=' | first)=($it.value)" } From b3a1d72b8bbed37742b199e71df06afb3eaf5e36 Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Fri, 16 Dec 2022 09:50:05 -0800 Subject: [PATCH 09/16] "fixing completions that contain a /" --- nushell_completions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nushell_completions.go b/nushell_completions.go index c03ea8df5..fe9782d5a 100644 --- a/nushell_completions.go +++ b/nushell_completions.go @@ -101,7 +101,7 @@ let cobra_completer = {|spans| # directive and directive_str are for posterity let stdout_lines = ($result.stdout | lines) let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int) - let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=]*)\t?(.*)' | rename value description) + let completions = ($stdout_lines | drop | parse -r '([\w\-\.:\+\=\/]*)\t?(.*)' | rename value description) let completions = if $fuzzy { $completions | where $it.value =~ $last_span From cfee99c89234e44232d0261efecbd98535448935 Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Fri, 23 Dec 2022 20:30:18 -0800 Subject: [PATCH 10/16] "removing extra lines/whitespace" --- nushell_completions.go | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/nushell_completions.go b/nushell_completions.go index fe9782d5a..fb3c11563 100644 --- a/nushell_completions.go +++ b/nushell_completions.go @@ -31,7 +31,7 @@ let cobra_apps = ["%[1]s"] # An external completer that works with any cobra based # command line application (e.g. kubectl, minikube) -let cobra_completer = {|spans| +let cobra_completer = {|spans| let cmd = $spans.0 if not ($cobra_apps | where $cmd =~ $it | is-empty) { @@ -40,7 +40,6 @@ let cobra_completer = {|spans| let ShellCompDirectiveNoFileComp = %[4]d let ShellCompDirectiveFilterFileExt = %[5]d let ShellCompDirectiveFilterDirs = %[6]d - let last_span = ($spans | last | str trim) def exec_complete [ @@ -51,7 +50,6 @@ let cobra_completer = {|spans| last_span: ($spans | last | str trim), spans: $spans } - # If there is an equals in the last span # parse the span into two let params = if $last_span =~ '=' { @@ -66,7 +64,7 @@ let cobra_completer = {|spans| last_span: '', spans: ($spans | drop | append ($split | first) | append '') } - } + } } else { $params } @@ -82,7 +80,7 @@ let cobra_completer = {|spans| } # 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 let cmd_args = if ($last_span | is-empty) or $fuzzy { @@ -97,7 +95,7 @@ let cobra_completer = {|spans| # Since nushell doesn't have anything like eval, execute in a subshell let result = (do -i { nu -c $"'($full_cmd)'" } | complete) - # Create a record with all completion related info. + # Create a record with all completion related info. # directive and directive_str are for posterity let stdout_lines = ($result.stdout | lines) let directive = ($stdout_lines | last | str trim | str replace ":" "" | into int) @@ -110,7 +108,7 @@ let cobra_completer = {|spans| } { - directive: $directive, + directive: $directive, completions: $completions } } @@ -148,7 +146,7 @@ let cobra_completer = {|spans| $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 + # Return null if there are no completions or ShellCompDirectiveError null } else { $completions @@ -159,12 +157,6 @@ let cobra_completer = {|spans| null } } - - - - - - `, name, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp, ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs)) From 6e3abc68be861c4138d89a23d300d18860dbd875 Mon Sep 17 00:00:00 2001 From: Jack Wright <56345+ayax79@users.noreply.github.com> Date: Fri, 23 Dec 2022 20:31:30 -0800 Subject: [PATCH 11/16] Update completions.go Co-authored-by: Marc Khouzam --- completions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completions.go b/completions.go index 4c86d0af2..fd7785ec4 100644 --- a/completions.go +++ b/completions.go @@ -816,7 +816,7 @@ To configure the Nushell cobra external completer for the first time: > 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 or for this setup to take effect. + # 5. You will need to start a new shel for this setup to take effect. If you have already setup the cobra external completer: # 1. Edit the nushell config file: From 49d58810e67efc54e576e006742d4a6afcbebec4 Mon Sep 17 00:00:00 2001 From: Jack Wright <56345+ayax79@users.noreply.github.com> Date: Fri, 23 Dec 2022 20:31:38 -0800 Subject: [PATCH 12/16] Update completions.go Co-authored-by: Marc Khouzam --- completions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completions.go b/completions.go index fd7785ec4..d9b7c3e1e 100644 --- a/completions.go +++ b/completions.go @@ -821,7 +821,7 @@ To configure the Nushell cobra external completer for the first time: If you have already setup the cobra external completer: # 1. Edit the nushell config file: > config nu - # 2. Modify the cobra_apps varible to contain this application: + # 2. Modify the cobra_apps variable to contain this new application: > let cobra_apps = [ "othercobraapp", "%[1]s" ] # 3. You will need to start a new shell for this setup to take effect. `, c.Root().Name()), From 107986cb5e784bf7615f444f9ca2939e27192adc Mon Sep 17 00:00:00 2001 From: Jack Wright <56345+ayax79@users.noreply.github.com> Date: Fri, 23 Dec 2022 20:31:48 -0800 Subject: [PATCH 13/16] Update completions.go Co-authored-by: Marc Khouzam --- completions.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completions.go b/completions.go index d9b7c3e1e..c1154abb3 100644 --- a/completions.go +++ b/completions.go @@ -818,7 +818,7 @@ To configure the Nushell cobra external completer for the first time: # 4. Change the config block's external_completer line to be external_completer: $cobra_completer # 5. You will need to start a new shel for this setup to take effect. -If you have already setup the cobra external completer: +If you have already setup the cobra external completer for other Cobra-based applications: # 1. Edit the nushell config file: > config nu # 2. Modify the cobra_apps variable to contain this new application: From cb60acd3abbc5cff49784946583a47ea29a9518a Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Fri, 23 Dec 2022 20:39:54 -0800 Subject: [PATCH 14/16] "Added nushell to list of shell autompletes" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7cc726beb..f237c13ff 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Cobra provides: * Automatic help generation for commands and flags * Grouping help for subcommands * Automatic help flag recognition of `-h`, `--help`, etc. -* Automatically generated shell autocomplete for your application (bash, zsh, fish, powershell) +* Automatically generated shell autocomplete for your application (bash, zsh, fish, powershell, nushell) * Automatically generated man pages for your application * Command aliases so you can change things without breaking them * The flexibility to define your own help, usage, etc. From 303dd2517fff82f9603406c7ae4a6a6df17df07e Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Fri, 23 Dec 2022 20:40:17 -0800 Subject: [PATCH 15/16] "Reverted to old version without formatting changes and readded nushell" --- completions_test.go | 426 +++++++++++++++----------------------------- 1 file changed, 143 insertions(+), 283 deletions(-) diff --git a/completions_test.go b/completions_test.go index 711b46829..2b8a2beb6 100644 --- a/completions_test.go +++ b/completions_test.go @@ -95,8 +95,7 @@ func TestCmdNameCompletionInGo(t *testing.T) { "help", "secondChild", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -111,8 +110,7 @@ func TestCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "secondChild", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -127,8 +125,7 @@ func TestCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -147,8 +144,7 @@ func TestCmdNameCompletionInGo(t *testing.T) { "help\tHelp about any command", "secondChild", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -188,8 +184,7 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected := strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -205,8 +200,7 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -228,8 +222,7 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { "completion", "help", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -251,8 +244,7 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "childCmd2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -267,8 +259,7 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -284,8 +275,7 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -302,8 +292,7 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "childCmd2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -320,8 +309,7 @@ func TestNoCmdNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "childCmd2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -346,8 +334,7 @@ func TestValidArgsCompletionInGo(t *testing.T) { "two", "three", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -362,8 +349,7 @@ func TestValidArgsCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "one", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -377,8 +363,7 @@ func TestValidArgsCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -412,8 +397,7 @@ func TestValidArgsAndCmdCompletionInGo(t *testing.T) { "one", "two", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -429,8 +413,7 @@ func TestValidArgsAndCmdCompletionInGo(t *testing.T) { "thechild", "two", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -465,8 +448,7 @@ func TestValidArgsFuncAndCmdCompletionInGo(t *testing.T) { "one", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -482,8 +464,7 @@ func TestValidArgsFuncAndCmdCompletionInGo(t *testing.T) { "thechild", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -499,8 +480,7 @@ func TestValidArgsFuncAndCmdCompletionInGo(t *testing.T) { "thechild\tThe child command", "two\tThe second", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -534,8 +514,7 @@ func TestFlagNameCompletionInGo(t *testing.T) { "completion", "help", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -555,8 +534,7 @@ func TestFlagNameCompletionInGo(t *testing.T) { "--second", "-s", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -571,8 +549,7 @@ func TestFlagNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "--first", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -593,8 +570,7 @@ func TestFlagNameCompletionInGo(t *testing.T) { "--version", "-v", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -629,8 +605,7 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { "completion\tGenerate the autocompletion script for the specified shell", "help\tHelp about any command", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -650,8 +625,7 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { "--second\tsecond flag", "-s\tsecond flag", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -666,8 +640,7 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { expected = strings.Join([]string{ "--first\tfirst flag", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -688,8 +661,7 @@ func TestFlagNameCompletionInGoWithDesc(t *testing.T) { "--version\tversion for childCmd", "-v\tversion for childCmd", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -734,8 +706,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--second", "--slice", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -756,8 +727,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--help", "--slice", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -781,8 +751,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--second", "--slice", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -811,8 +780,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { "--slice", "-l", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -830,8 +798,7 @@ func TestFlagNameCompletionRepeat(t *testing.T) { expected = strings.Join([]string{ "-a", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -883,8 +850,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "-p", "realArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -902,8 +868,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "--requiredPersistent", "-p", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -918,8 +883,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "--release", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -938,8 +902,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "-s", "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -956,8 +919,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "--subRequired", "-s", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -971,8 +933,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "--subNotRequired", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -991,8 +952,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "-p", "realArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1014,8 +974,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { "-r", "realArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1033,8 +992,7 @@ func TestRequiredFlagNameCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "realArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1072,8 +1030,7 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected := strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1087,8 +1044,7 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "log", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1102,8 +1058,7 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "yaml", "yml", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1117,8 +1072,7 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "yaml", "yml", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1132,8 +1086,7 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "yaml", "yml", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1147,8 +1100,7 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "yaml", "yml", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1162,8 +1114,7 @@ func TestFlagFileExtFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "txt", ":8", - "Completion ended with directive: ShellCompDirectiveFilterFileExt", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterFileExt", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1197,8 +1148,7 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected := strings.Join([]string{ ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1211,8 +1161,7 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1226,8 +1175,7 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "themes", ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1241,8 +1189,7 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "themes", ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1256,8 +1203,7 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "themes", ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1271,8 +1217,7 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "themes", ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1285,8 +1230,7 @@ func TestFlagDirFilterCompletionInGo(t *testing.T) { expected = strings.Join([]string{ ":16", - "Completion ended with directive: ShellCompDirectiveFilterDirs", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveFilterDirs", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1328,8 +1272,7 @@ func TestValidArgsFuncCmdContext(t *testing.T) { expected := strings.Join([]string{ ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1353,8 +1296,7 @@ func TestValidArgsFuncSingleCmd(t *testing.T) { "one", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1369,8 +1311,7 @@ func TestValidArgsFuncSingleCmd(t *testing.T) { expected = strings.Join([]string{ "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1397,8 +1338,7 @@ func TestValidArgsFuncSingleCmdInvalidArg(t *testing.T) { expected := strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1429,8 +1369,7 @@ func TestValidArgsFuncChildCmds(t *testing.T) { "one", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1445,8 +1384,7 @@ func TestValidArgsFuncChildCmds(t *testing.T) { expected = strings.Join([]string{ "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1460,8 +1398,7 @@ func TestValidArgsFuncChildCmds(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1477,8 +1414,7 @@ func TestValidArgsFuncChildCmds(t *testing.T) { "three", "four", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1492,8 +1428,7 @@ func TestValidArgsFuncChildCmds(t *testing.T) { expected = strings.Join([]string{ "three", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1507,8 +1442,7 @@ func TestValidArgsFuncChildCmds(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1535,8 +1469,7 @@ func TestValidArgsFuncAliases(t *testing.T) { "one", "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1551,8 +1484,7 @@ func TestValidArgsFuncAliases(t *testing.T) { expected = strings.Join([]string{ "two", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1566,8 +1498,7 @@ func TestValidArgsFuncAliases(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1691,8 +1622,7 @@ func TestFlagCompletionInGo(t *testing.T) { "2", "10", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1708,8 +1638,7 @@ func TestFlagCompletionInGo(t *testing.T) { "1", "10", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1726,8 +1655,7 @@ func TestFlagCompletionInGo(t *testing.T) { "myfile.json", "file.xml", ":6", - "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1743,8 +1671,7 @@ func TestFlagCompletionInGo(t *testing.T) { "file.yaml", "file.xml", ":6", - "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1775,8 +1702,7 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { "one\tThe first", "two\tThe second", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1791,8 +1717,7 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { expected = strings.Join([]string{ "two\tThe second", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1806,8 +1731,7 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1823,8 +1747,7 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { "three\tThe third", "four\tThe fourth", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1838,8 +1761,7 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { expected = strings.Join([]string{ "three\tThe third", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1853,8 +1775,7 @@ func TestValidArgsFuncChildCmdsWithDesc(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1893,8 +1814,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--help\thelp for child", "--string\ttest string flag", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1910,8 +1830,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1927,8 +1846,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1947,8 +1865,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1964,8 +1881,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1981,8 +1897,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -1998,8 +1913,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2015,8 +1929,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "arg1", "arg2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2032,8 +1945,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2049,8 +1961,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "test", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2068,8 +1979,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { expected = strings.Join([]string{ "--validarg", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2088,8 +1998,7 @@ func TestFlagCompletionWithNotInterspersedArgs(t *testing.T) { "--validarg", "--toComp=ab", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2124,8 +2033,7 @@ func TestFlagCompletionWorksRootCommandAddedAfterFlags(t *testing.T) { expected := strings.Join([]string{ "myval", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2169,8 +2077,7 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) { "2\tThe second", "10\tThe tenth", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2186,8 +2093,7 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) { "1\tThe first", "10\tThe tenth", ":0", - "Completion ended with directive: ShellCompDirectiveDefault", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveDefault", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2204,8 +2110,7 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) { "myfile.json\tJSON format", "file.xml\tXML format", ":6", - "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2221,8 +2126,7 @@ func TestFlagCompletionInGoWithDesc(t *testing.T) { "file.yaml\tYAML format", "file.xml\tXML format", ":6", - "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2250,8 +2154,7 @@ func TestValidArgsNotValidArgsFunc(t *testing.T) { "one", "two", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2266,8 +2169,7 @@ func TestValidArgsNotValidArgsFunc(t *testing.T) { expected = strings.Join([]string{ "two", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2294,8 +2196,7 @@ func TestArgAliasesCompletionInGo(t *testing.T) { "two", "three", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2311,8 +2212,7 @@ func TestArgAliasesCompletionInGo(t *testing.T) { "two", "three", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2327,8 +2227,7 @@ func TestArgAliasesCompletionInGo(t *testing.T) { expected = strings.Join([]string{ "trois", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2365,8 +2264,7 @@ func TestCompleteHelp(t *testing.T) { "completion", "help", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2384,8 +2282,7 @@ func TestCompleteHelp(t *testing.T) { "completion", "help", // " help help" is a valid command, so should be completed ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2400,8 +2297,7 @@ func TestCompleteHelp(t *testing.T) { expected = strings.Join([]string{ "child3", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2570,12 +2466,11 @@ func TestCompleteCompletion(t *testing.T) { expected := strings.Join([]string{ "bash", "fish", - "nushell", + "nushell", "powershell", "zsh", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2598,8 +2493,7 @@ func TestCompleteCompletion(t *testing.T) { expected = strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2631,8 +2525,7 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { "foo", "bar", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2648,8 +2541,7 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { "foo", "bar", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2664,8 +2556,7 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { expected = strings.Join([]string{ "works", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2680,8 +2571,7 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { expected = strings.Join([]string{ "works", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2697,8 +2587,7 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { "foo", "bar", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2706,6 +2595,7 @@ func TestMultipleShorthandFlagCompletion(t *testing.T) { } func TestCompleteWithDisableFlagParsing(t *testing.T) { + flagValidArgs := func(cmd *Command, args []string, toComplete string) ([]string, ShellCompDirective) { return []string{"--flag", "-f"}, ShellCompDirectiveNoFileComp } @@ -2740,8 +2630,7 @@ func TestCompleteWithDisableFlagParsing(t *testing.T) { "--flag", "-f", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2763,8 +2652,7 @@ func TestCompleteWithDisableFlagParsing(t *testing.T) { "--nonPersistent", "-n", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2793,8 +2681,7 @@ func TestCompleteWithRootAndLegacyArgs(t *testing.T) { "arg1", "arg2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2810,8 +2697,7 @@ func TestCompleteWithRootAndLegacyArgs(t *testing.T) { "arg1", "arg2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2838,8 +2724,7 @@ func TestFixedCompletions(t *testing.T) { "banana", "orange", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n") + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n") if output != expected { t.Errorf("expected: %q, got: %q", expected, output) @@ -2885,8 +2770,7 @@ func TestCompletionForGroupedFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "flags in group suggested with - prefix", @@ -2899,8 +2783,7 @@ func TestCompletionForGroupedFlags(t *testing.T) { "--ingroup3", "--nogroup", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "when flag in group present, other flags in group suggested even without - prefix", @@ -2910,8 +2793,7 @@ func TestCompletionForGroupedFlags(t *testing.T) { "--ingroup3", "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "when all flags in group present, flags not suggested without - prefix", @@ -2919,8 +2801,7 @@ func TestCompletionForGroupedFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "group ignored if some flags not applicable", @@ -2930,8 +2811,7 @@ func TestCompletionForGroupedFlags(t *testing.T) { "completion", "help", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, } @@ -2990,8 +2870,7 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "subArg", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "flags in mutually exclusive group suggested with the - prefix", @@ -3004,8 +2883,7 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) { "--ingroup3", "--nogroup", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "when flag in mutually exclusive group present, other flags in group not suggested even with the - prefix", @@ -3016,8 +2894,7 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) { "-h", "--nogroup", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "group ignored if some flags not applicable", @@ -3028,8 +2905,7 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) { "--ingroup1", "--ingroup2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, } @@ -3111,80 +2987,70 @@ func TestCompletionCobraFlags(t *testing.T) { "--version", "-v", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after --help flag", args: []string{"--help", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after -h flag", args: []string{"-h", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after --version flag", args: []string{"--version", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after -v flag", args: []string{"-v", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after --help flag even with other completions", args: []string{"child", "--help", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after -h flag even with other completions", args: []string{"child", "-h", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after --version flag even with other completions", args: []string{"child", "--version", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after -v flag even with other completions", args: []string{"child", "-v", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "no completion after -v flag even with other flag completions", args: []string{"child", "-v", "-"}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "completion after --help flag when created by program", @@ -3192,8 +3058,7 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "completion after -h flag when created by program", @@ -3201,8 +3066,7 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "completion after --version flag when created by program", @@ -3210,8 +3074,7 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "completion after -v flag when created by program", @@ -3219,16 +3082,14 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra2", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "completion after --version when only -v flag was created by program", args: []string{"child3", "--version", ""}, expectedOutput: strings.Join([]string{ ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, { desc: "completion after -v flag when only -v flag was created by program", @@ -3236,8 +3097,7 @@ func TestCompletionCobraFlags(t *testing.T) { expectedOutput: strings.Join([]string{ "extra3", ":4", - "Completion ended with directive: ShellCompDirectiveNoFileComp", "", - }, "\n"), + "Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"), }, } From 3c8715a6d72efd04da8886ed347fb06cafddd9a6 Mon Sep 17 00:00:00 2001 From: Jack Wright Date: Tue, 27 Dec 2022 12:17:42 -0800 Subject: [PATCH 16/16] "fixed whitespace" --- completions_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/completions_test.go b/completions_test.go index 2b8a2beb6..818640e93 100644 --- a/completions_test.go +++ b/completions_test.go @@ -2466,7 +2466,7 @@ func TestCompleteCompletion(t *testing.T) { expected := strings.Join([]string{ "bash", "fish", - "nushell", + "nushell", "powershell", "zsh", ":4",