From a1431b2c574c3e4aeaa54d03888722cb1e045a23 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Fri, 11 Nov 2022 18:05:24 -0800
Subject: [PATCH 01/35] 'Completions for nushell'

---
 nushell_completions.go             | 124 +++++++++++++++++++++++++
 nushell_completions.md             |   4 +
 nushell_completions_test.go        | 141 +++++++++++++++++++++++++++++
 site/content/completions/_index.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 00000000..6b944bd9
--- /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 00000000..e0e94eb1
--- /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 00000000..77bb00d5
--- /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/site/content/completions/_index.md b/site/content/completions/_index.md
index 02257ade..9cbde8e1 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.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 594faef23fa9b46685a50570bfd15c2175d440f1 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sat, 26 Nov 2022 14:39:29 -0800
Subject: [PATCH 02/35] Changed the nushell completion implementation to be a
 nushell external completer

---
 nushell_completions.go             | 128 +++++++++--------------------
 nushell_completions_test.go        |  61 ++------------
 site/content/completions/_index.md |  15 +++-
 3 files changed, 58 insertions(+), 146 deletions(-)

diff --git a/nushell_completions.go b/nushell_completions.go
index 6b944bd9..4363946f 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 77bb00d5..3e3c36de 100644
--- a/nushell_completions_test.go
+++ b/nushell_completions_test.go
@@ -22,13 +22,9 @@ import (
 )
 
 func TestGenNushellCompletion(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",
@@ -36,58 +32,17 @@ func TestGenNushellCompletion(t *testing.T) {
 		ValidArgs:  []string{"pod", "node", "service", "replicationcontroller"},
 		Run:        emptyRun,
 	}
-
 	rootCmd.AddCommand(getCmd)
 
 	buf := new(bytes.Buffer)
-	assertNoErr(t, rootCmd.GenNushellCompletion(buf, true))
+	assertNoErr(t, rootCmd.GenNushellCompletion(buf))
 	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")
+	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/site/content/completions/_index.md b/site/content/completions/_index.md
index 9cbde8e1..b8a56d4f 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.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 2f276e301446093e63850fbfef3c81d8f9ed7461 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 27 Nov 2022 13:46:13 -0800
Subject: [PATCH 03/35] 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 8fccdaf2..fee40e11 100644
--- a/completions.go
+++ b/completions.go
@@ -836,14 +836,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 {
@@ -876,7 +909,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 df153fcf..5ee3a00f 100644
--- a/completions_test.go
+++ b/completions_test.go
@@ -98,7 +98,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)
@@ -113,7 +114,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)
@@ -128,7 +130,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)
@@ -147,7 +150,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)
@@ -187,7 +191,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)
@@ -203,7 +208,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)
@@ -225,7 +231,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)
@@ -247,7 +254,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)
@@ -262,7 +270,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)
@@ -278,7 +287,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)
@@ -295,7 +305,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)
@@ -312,7 +323,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)
@@ -337,7 +349,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)
@@ -352,7 +365,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)
@@ -366,7 +380,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)
@@ -400,7 +415,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)
@@ -416,7 +432,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)
@@ -451,7 +468,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)
@@ -467,7 +485,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)
@@ -483,7 +502,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)
@@ -517,7 +537,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)
@@ -537,7 +558,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)
@@ -552,7 +574,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)
@@ -573,7 +596,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)
@@ -608,7 +632,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)
@@ -628,7 +653,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)
@@ -643,7 +669,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)
@@ -664,7 +691,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)
@@ -709,7 +737,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)
@@ -730,7 +759,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)
@@ -754,7 +784,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)
@@ -783,7 +814,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)
@@ -801,7 +833,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)
@@ -853,7 +886,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)
@@ -871,7 +905,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)
@@ -886,7 +921,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)
@@ -905,7 +941,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)
@@ -922,7 +959,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)
@@ -936,7 +974,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)
@@ -955,7 +994,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)
@@ -977,7 +1017,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)
@@ -995,7 +1036,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)
@@ -1033,7 +1075,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)
@@ -1047,7 +1090,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)
@@ -1061,7 +1105,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)
@@ -1075,7 +1120,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)
@@ -1089,7 +1135,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)
@@ -1103,7 +1150,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)
@@ -1117,7 +1165,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)
@@ -1151,7 +1200,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)
@@ -1164,7 +1214,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)
@@ -1178,7 +1229,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)
@@ -1192,7 +1244,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)
@@ -1206,7 +1259,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)
@@ -1220,7 +1274,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)
@@ -1233,7 +1288,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)
@@ -1275,7 +1331,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)
@@ -1299,7 +1356,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)
@@ -1314,7 +1372,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)
@@ -1341,7 +1400,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)
@@ -1372,7 +1432,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)
@@ -1387,7 +1448,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)
@@ -1401,7 +1463,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)
@@ -1417,7 +1480,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)
@@ -1431,7 +1495,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)
@@ -1445,7 +1510,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)
@@ -1472,7 +1538,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)
@@ -1487,7 +1554,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)
@@ -1501,7 +1569,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)
@@ -1625,7 +1694,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)
@@ -1641,7 +1711,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)
@@ -1658,7 +1729,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)
@@ -1674,7 +1746,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)
@@ -1705,7 +1778,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)
@@ -1720,7 +1794,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)
@@ -1734,7 +1809,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)
@@ -1750,7 +1826,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)
@@ -1764,7 +1841,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)
@@ -1778,7 +1856,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)
@@ -1817,7 +1896,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)
@@ -1833,7 +1913,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)
@@ -1849,7 +1930,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)
@@ -1868,7 +1950,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)
@@ -1884,7 +1967,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)
@@ -1900,7 +1984,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)
@@ -1916,7 +2001,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)
@@ -1932,7 +2018,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)
@@ -1948,7 +2035,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)
@@ -1964,7 +2052,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)
@@ -1982,7 +2071,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)
@@ -2001,7 +2091,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)
@@ -2036,7 +2127,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)
@@ -2188,7 +2280,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)
@@ -2204,7 +2297,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)
@@ -2221,7 +2315,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)
@@ -2237,7 +2332,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)
@@ -2265,7 +2361,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)
@@ -2280,7 +2377,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)
@@ -2307,7 +2405,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)
@@ -2323,7 +2422,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)
@@ -2338,7 +2438,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)
@@ -2375,7 +2476,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)
@@ -2393,7 +2495,8 @@ func TestCompleteHelp(t *testing.T) {
 		"completion",
 		"help", // "<program> 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)
@@ -2408,7 +2511,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)
@@ -2577,10 +2681,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)
@@ -2603,7 +2709,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)
@@ -2635,7 +2742,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)
@@ -2651,7 +2759,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)
@@ -2666,7 +2775,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)
@@ -2681,7 +2791,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)
@@ -2697,7 +2808,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)
@@ -2705,7 +2817,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
 	}
@@ -2738,7 +2849,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)
@@ -2760,7 +2872,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)
@@ -2789,7 +2902,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)
@@ -2805,7 +2919,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)
@@ -2832,7 +2947,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)
@@ -2878,7 +2994,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",
@@ -2891,7 +3008,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",
@@ -2901,7 +3019,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",
@@ -2909,7 +3028,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",
@@ -2919,7 +3039,8 @@ func TestCompletionForGroupedFlags(t *testing.T) {
 				"completion",
 				"help",
 				":4",
-				"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"),
+				"Completion ended with directive: ShellCompDirectiveNoFileComp", "",
+			}, "\n"),
 		},
 	}
 
@@ -3076,7 +3197,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",
@@ -3089,7 +3211,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",
@@ -3100,7 +3223,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",
@@ -3111,7 +3235,8 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) {
 				"--ingroup1",
 				"--ingroup2",
 				":4",
-				"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"),
+				"Completion ended with directive: ShellCompDirectiveNoFileComp", "",
+			}, "\n"),
 		},
 	}
 
@@ -3215,70 +3340,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",
@@ -3286,7 +3421,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",
@@ -3294,7 +3430,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",
@@ -3302,7 +3439,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",
@@ -3310,14 +3448,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",
@@ -3325,7 +3465,8 @@ func TestCompletionCobraFlags(t *testing.T) {
 			expectedOutput: strings.Join([]string{
 				"extra3",
 				":4",
-				"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"),
+				"Completion ended with directive: ShellCompDirectiveNoFileComp", "",
+			}, "\n"),
 		},
 		{
 			desc: "no completion for --help/-h and --version/-v flags when DisableFlagParsing=true",
diff --git a/nushell_completions.go b/nushell_completions.go
index 4363946f..3b4e2c67 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 3e3c36de..b82898aa 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 1324e0c3160764624058582d7bf0a1995b055143 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 27 Nov 2022 13:55:50 -0800
Subject: [PATCH 04/35] Added nushell to the Use: line

---
 site/content/completions/_index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index b8a56d4f..dc4515a0 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.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 37ac7454fb5d5f5a785783faa27cdf8723b4e6a5 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 27 Nov 2022 15:06:59 -0800
Subject: [PATCH 05/35] Added a whitelist to add cobra apps to to prevent
 non-cobra apps from being excuted

---
 completions.go                     |  14 +++-
 nushell_completions.go             | 104 ++++++++++++++++-------------
 site/content/completions/_index.md |  14 +++-
 3 files changed, 81 insertions(+), 51 deletions(-)

diff --git a/completions.go b/completions.go
index fee40e11..55a23fad 100644
--- a/completions.go
+++ b/completions.go
@@ -847,7 +847,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 
@@ -860,7 +860,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 3b4e2c67..568d3cb5 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) ""'
+    # 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
+    }
+
+    # 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)
+
+    # 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)
+
+    # 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 {
-    $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)
-
-  # 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)
-
-  # 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
   }
-
 }
-`, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
+`, c.Name(), ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
 		ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
 
 	_, err := buf.WriteTo(w)
diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index dc4515a0..f03ae6c9 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.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 fa746d4d5a3915cca2f7746d723af4d0f3f706fa Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Mon, 28 Nov 2022 13:39:12 -0800
Subject: [PATCH 06/35] 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 ++++----
 site/content/completions/_index.md | 12 ++---------
 4 files changed, 34 insertions(+), 46 deletions(-)

diff --git a/completions.go b/completions.go
index 55a23fad..f53e164f 100644
--- a/completions.go
+++ b/completions.go
@@ -847,39 +847,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 568d3cb5..87c34a73 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 b82898aa..73fedd07 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/site/content/completions/_index.md b/site/content/completions/_index.md
index f03ae6c9..2f598c7c 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.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 d86bac4e347bed145414216f883af83d5c66aad1 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Thu, 15 Dec 2022 13:21:37 -0800
Subject: [PATCH 07/35] "fixing oddities with fuzzy searching and bug with
 active help"

---
 nushell_completions.go | 116 +++++++++++++++++++++++++++++++----------
 1 file changed, 88 insertions(+), 28 deletions(-)

diff --git a/nushell_completions.go b/nushell_completions.go
index 87c34a73..8f7c8568 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 ' ') 
+    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
+      }
 
-    # 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
+      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 247e8e6b55e341dc50169d9968cb1645da67955c Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Fri, 16 Dec 2022 09:32:22 -0800
Subject: [PATCH 08/35] "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 8f7c8568..c03ea8df 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 3b016843b92be4440241751e24722117fecca57a Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Fri, 16 Dec 2022 09:50:05 -0800
Subject: [PATCH 09/35] "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 c03ea8df..fe9782d5 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 4c4bde658648de59a25b1a0700804b2d6e0ea5b8 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Fri, 23 Dec 2022 20:30:18 -0800
Subject: [PATCH 10/35] "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 fe9782d5..fb3c1156 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 3bfdd6421fd61838db3b9630cfe2379416fcc0bf 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/35] Update completions.go

Co-authored-by: Marc Khouzam <marc.khouzam@gmail.com>
---
 completions.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/completions.go b/completions.go
index f53e164f..5e4dc262 100644
--- a/completions.go
+++ b/completions.go
@@ -854,7 +854,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 ead0ff3e53f67d6e13cc40841b31573534a7a6a6 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/35] Update completions.go

Co-authored-by: Marc Khouzam <marc.khouzam@gmail.com>
---
 completions.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/completions.go b/completions.go
index 5e4dc262..6a81cd51 100644
--- a/completions.go
+++ b/completions.go
@@ -859,7 +859,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 8cb972847673951daf5aa09377d108ca4ab8af19 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/35] Update completions.go

Co-authored-by: Marc Khouzam <marc.khouzam@gmail.com>
---
 completions.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/completions.go b/completions.go
index 6a81cd51..f6924ba7 100644
--- a/completions.go
+++ b/completions.go
@@ -856,7 +856,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 1a69a83abcae278ed9bd54cb7420b21111dc3492 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Fri, 23 Dec 2022 20:39:54 -0800
Subject: [PATCH 14/35] "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 0fb0373c..6ffa0cfb 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 f963733c4e903a77f648a7bf9af5708a21e01be7 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Fri, 23 Dec 2022 20:40:17 -0800
Subject: [PATCH 15/35] "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 5ee3a00f..d423b162 100644
--- a/completions_test.go
+++ b/completions_test.go
@@ -98,8 +98,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)
@@ -114,8 +113,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)
@@ -130,8 +128,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)
@@ -150,8 +147,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)
@@ -191,8 +187,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)
@@ -208,8 +203,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)
@@ -231,8 +225,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)
@@ -254,8 +247,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)
@@ -270,8 +262,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)
@@ -287,8 +278,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)
@@ -305,8 +295,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)
@@ -323,8 +312,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)
@@ -349,8 +337,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)
@@ -365,8 +352,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)
@@ -380,8 +366,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)
@@ -415,8 +400,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)
@@ -432,8 +416,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)
@@ -468,8 +451,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)
@@ -485,8 +467,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)
@@ -502,8 +483,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)
@@ -537,8 +517,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)
@@ -558,8 +537,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)
@@ -574,8 +552,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)
@@ -596,8 +573,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)
@@ -632,8 +608,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)
@@ -653,8 +628,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)
@@ -669,8 +643,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)
@@ -691,8 +664,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)
@@ -737,8 +709,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)
@@ -759,8 +730,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)
@@ -784,8 +754,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)
@@ -814,8 +783,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)
@@ -833,8 +801,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)
@@ -886,8 +853,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)
@@ -905,8 +871,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)
@@ -921,8 +886,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)
@@ -941,8 +905,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)
@@ -959,8 +922,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)
@@ -974,8 +936,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)
@@ -994,8 +955,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)
@@ -1017,8 +977,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)
@@ -1036,8 +995,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)
@@ -1075,8 +1033,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)
@@ -1090,8 +1047,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)
@@ -1105,8 +1061,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)
@@ -1120,8 +1075,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)
@@ -1135,8 +1089,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)
@@ -1150,8 +1103,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)
@@ -1165,8 +1117,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)
@@ -1200,8 +1151,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)
@@ -1214,8 +1164,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)
@@ -1229,8 +1178,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)
@@ -1244,8 +1192,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)
@@ -1259,8 +1206,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)
@@ -1274,8 +1220,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)
@@ -1288,8 +1233,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)
@@ -1331,8 +1275,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)
@@ -1356,8 +1299,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)
@@ -1372,8 +1314,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)
@@ -1400,8 +1341,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)
@@ -1432,8 +1372,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)
@@ -1448,8 +1387,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)
@@ -1463,8 +1401,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)
@@ -1480,8 +1417,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)
@@ -1495,8 +1431,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)
@@ -1510,8 +1445,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)
@@ -1538,8 +1472,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)
@@ -1554,8 +1487,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)
@@ -1569,8 +1501,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)
@@ -1694,8 +1625,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)
@@ -1711,8 +1641,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)
@@ -1729,8 +1658,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)
@@ -1746,8 +1674,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)
@@ -1778,8 +1705,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)
@@ -1794,8 +1720,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)
@@ -1809,8 +1734,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)
@@ -1826,8 +1750,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)
@@ -1841,8 +1764,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)
@@ -1856,8 +1778,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)
@@ -1896,8 +1817,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)
@@ -1913,8 +1833,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)
@@ -1930,8 +1849,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)
@@ -1950,8 +1868,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)
@@ -1967,8 +1884,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)
@@ -1984,8 +1900,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)
@@ -2001,8 +1916,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)
@@ -2018,8 +1932,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)
@@ -2035,8 +1948,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)
@@ -2052,8 +1964,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)
@@ -2071,8 +1982,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)
@@ -2091,8 +2001,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)
@@ -2127,8 +2036,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)
@@ -2280,8 +2188,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)
@@ -2297,8 +2204,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)
@@ -2315,8 +2221,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)
@@ -2332,8 +2237,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)
@@ -2361,8 +2265,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)
@@ -2377,8 +2280,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)
@@ -2405,8 +2307,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)
@@ -2422,8 +2323,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)
@@ -2438,8 +2338,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)
@@ -2476,8 +2375,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)
@@ -2495,8 +2393,7 @@ func TestCompleteHelp(t *testing.T) {
 		"completion",
 		"help", // "<program> 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)
@@ -2511,8 +2408,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)
@@ -2681,12 +2577,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)
@@ -2709,8 +2604,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)
@@ -2742,8 +2636,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)
@@ -2759,8 +2652,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)
@@ -2775,8 +2667,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)
@@ -2791,8 +2682,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)
@@ -2808,8 +2698,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)
@@ -2817,6 +2706,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
 	}
@@ -2849,8 +2739,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)
@@ -2872,8 +2761,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)
@@ -2902,8 +2790,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)
@@ -2919,8 +2806,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)
@@ -2947,8 +2833,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)
@@ -2994,8 +2879,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",
@@ -3008,8 +2892,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",
@@ -3019,8 +2902,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",
@@ -3028,8 +2910,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",
@@ -3039,8 +2920,7 @@ func TestCompletionForGroupedFlags(t *testing.T) {
 				"completion",
 				"help",
 				":4",
-				"Completion ended with directive: ShellCompDirectiveNoFileComp", "",
-			}, "\n"),
+				"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"),
 		},
 	}
 
@@ -3197,8 +3077,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",
@@ -3211,8 +3090,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",
@@ -3223,8 +3101,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",
@@ -3235,8 +3112,7 @@ func TestCompletionForMutuallyExclusiveFlags(t *testing.T) {
 				"--ingroup1",
 				"--ingroup2",
 				":4",
-				"Completion ended with directive: ShellCompDirectiveNoFileComp", "",
-			}, "\n"),
+				"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"),
 		},
 	}
 
@@ -3340,80 +3216,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",
@@ -3421,8 +3287,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",
@@ -3430,8 +3295,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",
@@ -3439,8 +3303,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",
@@ -3448,16 +3311,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",
@@ -3465,8 +3326,7 @@ func TestCompletionCobraFlags(t *testing.T) {
 			expectedOutput: strings.Join([]string{
 				"extra3",
 				":4",
-				"Completion ended with directive: ShellCompDirectiveNoFileComp", "",
-			}, "\n"),
+				"Completion ended with directive: ShellCompDirectiveNoFileComp", ""}, "\n"),
 		},
 		{
 			desc: "no completion for --help/-h and --version/-v flags when DisableFlagParsing=true",

From 29af015b5749d98e9d5b4f4896f6229e72b1c933 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Tue, 27 Dec 2022 12:17:42 -0800
Subject: [PATCH 16/35] "fixed whitespace"

---
 completions_test.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/completions_test.go b/completions_test.go
index d423b162..718f55d8 100644
--- a/completions_test.go
+++ b/completions_test.go
@@ -2577,7 +2577,7 @@ func TestCompleteCompletion(t *testing.T) {
 	expected := strings.Join([]string{
 		"bash",
 		"fish",
-    "nushell",
+		"nushell",
 		"powershell",
 		"zsh",
 		":4",

From e7abbf39a39676e2745c099a99e9c52c1fdcfdae Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Wed, 27 Nov 2024 21:05:56 -0800
Subject: [PATCH 17/35] rewriting nushell implementation

---
 nushell_completions.go | 189 ++++++++++++++++-------------------------
 1 file changed, 71 insertions(+), 118 deletions(-)

diff --git a/nushell_completions.go b/nushell_completions.go
index fb3c1156..7df265d4 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -23,141 +23,94 @@ import (
 
 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 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 completer that works with any cobra based
 # command line application (e.g. kubectl, minikube)
 let cobra_completer = {|spans|
-  let cmd = $spans.0
+	let ShellCompDirectiveError = %[1]d
+	let ShellCompDirectiveNoSpace = %[2]d
+	let ShellCompDirectiveNoFileComp = %[3]d
+	let ShellCompDirectiveFilterFileExt = %[4]d
+	let ShellCompDirectiveFilterDirs = %[5]d
 
-  if not ($cobra_apps | where $cmd =~ $it | 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)
+	let cmd = $spans | first 
+	let rest = $spans | skip
 
-    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
-      }
+	def exec_complete [
+		spans: list<string>
+	] {
+		# This will catch the stderr message related to the directive and any other errors,
+		# such as the command not being a cobra based command
+		let result = do --ignore-errors { cobra_active_help=0 run-external $cmd "__complete" ...$spans | complete }
 
-      let last_span = $params.last_span
-      let spans = $params.spans
+		if $result != null and $result.exit_code == 0 {
+			let completions = $result.stdout | lines
 
-      # Drop the last param so we can fuzzy search on it
-      let spans = if $fuzzy {
-        $spans | drop
-      } else {
-        $spans
-      }
+			# the directive is the last line
+			let directive = do -i { $completions | last | str replace ':' '' | into int }
 
-      # 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 completions = $completions | drop | each { |it| 
+				# the first word is the command, the rest is the description
+				let words = $it | split row -r '\s{1}'
 
-      # 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
-      }
+				# If the last span contains a hypen and equals, attach it to the name
+				let last_span = $spans | last
+				let words = if ($last_span =~ '^-') and ($last_span =~ '=$') {
+					$words | each {|it| $"($last_span)($it)" }
+				} else {
+					$words
+				}
 
-      # 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)'
+				{value: ($words | first | str trim), description: ($words | skip | str join ' ')}
+			}
 
-      # Since nushell doesn't have anything like eval, execute in a subshell
-      let result = (do -i { nu -c $"'($full_cmd)'" } | complete)
+			{completions: $completions, directive: $directive}
+		} else {
+			{completions: [], directive: -1}
+		}
+	}
 
-      # 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
+	if (not ($rest | is-empty)) {
+		let result = exec_complete $rest
+		let completions = $result.completions
+		let directive = $result.directive
 
-      } else {
-        ($completions | where {|it| $it.value | str starts-with $last_span })
-      }
+		# Add space at the end of each completion
+		let completions = if $directive != $ShellCompDirectiveNoSpace {
+		  $completions | each {|it| {value: $"($it.value) ", description: $it.description}}
+		} else {
+		  $completions
+		}
 
-      {
-        directive: $directive,
-        completions: $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 result = (exec_complete $spans)
-    let result = if (not ($last_span | is-empty)) and ($result.completions | is-empty) {
-      exec_complete --fuzzy $spans
-    } else {
-      $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}}
-    } else {
-      $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)" }
-    } 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
-    }
-
-    $return_val
-  } else {
-    null
-  }
+		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
+		}
+			
+		if ($completions | is-empty) {
+			null
+		} else {
+			$completions
+		}
+	} else {
+		null
+	}
 }
-`, name, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
+`, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
 		ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
 
 	_, err := buf.WriteTo(w)

From 7eac0e11ae2a70b3f5463377b7b96980fff694a3 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sat, 30 Nov 2024 13:32:05 -0800
Subject: [PATCH 18/35] Format with spaces instead of tabs

---
 nushell_completions.go | 172 ++++++++++++++++++++---------------------
 1 file changed, 85 insertions(+), 87 deletions(-)

diff --git a/nushell_completions.go b/nushell_completions.go
index 7df265d4..702f0b26 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -15,114 +15,112 @@
 package cobra
 
 import (
-	"bytes"
-	"fmt"
-	"io"
-	"os"
+    "bytes"
+    "fmt"
+    "io"
+    "os"
 )
 
 func (c *Command) GenNushellCompletion(w io.Writer, includeDesc bool) error {
-	buf := new(bytes.Buffer)
-	WriteStringAndCheck(buf, fmt.Sprintf(`
-# An external completer that works with any cobra based
-# command line application (e.g. kubectl, minikube)
+    buf := new(bytes.Buffer)
+    WriteStringAndCheck(buf, fmt.Sprintf(`
 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 ShellCompDirectiveError = %[1]d
+    let ShellCompDirectiveNoSpace = %[2]d
+    let ShellCompDirectiveNoFileComp = %[3]d
+    let ShellCompDirectiveFilterFileExt = %[4]d
+    let ShellCompDirectiveFilterDirs = %[5]d
 
-	let cmd = $spans | first 
-	let rest = $spans | skip
+    let cmd = $spans | first 
+    let rest = $spans | skip
 
-	def exec_complete [
-		spans: list<string>
-	] {
-		# This will catch the stderr message related to the directive and any other errors,
-		# such as the command not being a cobra based command
-		let result = do --ignore-errors { cobra_active_help=0 run-external $cmd "__complete" ...$spans | complete }
+    def exec_complete [
+        spans: list<string>
+    ] {
+        # This will catch the stderr message related to the directive and any other errors,
+        # such as the command not being a cobra based command
+        let result = do --ignore-errors { cobra_active_help=0 run-external $cmd "__complete" ...$spans | complete }
 
-		if $result != null and $result.exit_code == 0 {
-			let completions = $result.stdout | lines
+        if $result != null and $result.exit_code == 0 {
+            let completions = $result.stdout | lines
 
-			# the directive is the last line
-			let directive = do -i { $completions | last | str replace ':' '' | into int }
+            # the directive is the last line
+            let directive = do -i { $completions | last | str replace ':' '' | into int }
 
-			let completions = $completions | drop | each { |it| 
-				# the first word is the command, the rest is the description
-				let words = $it | split row -r '\s{1}'
+            let completions = $completions | drop | each { |it| 
+                # the first word is the command, the rest is the description
+                let words = $it | split row -r '\s{1}'
 
-				# If the last span contains a hypen and equals, attach it to the name
-				let last_span = $spans | last
-				let words = if ($last_span =~ '^-') and ($last_span =~ '=$') {
-					$words | each {|it| $"($last_span)($it)" }
-				} else {
-					$words
-				}
+                # If the last span contains a hypen and equals, attach it to the name
+                let last_span = $spans | last
+                let words = if ($last_span =~ '^-') and ($last_span =~ '=$') {
+                    $words | each {|it| $"($last_span)($it)" }
+                } else {
+                    $words
+                }
 
-				{value: ($words | first | str trim), description: ($words | skip | str join ' ')}
-			}
+                {value: ($words | first | str trim), description: ($words | skip | str join ' ')}
+            }
 
-			{completions: $completions, directive: $directive}
-		} else {
-			{completions: [], directive: -1}
-		}
-	}
+            {completions: $completions, directive: $directive}
+        } else {
+            {completions: [], directive: -1}
+        }
+    }
 
-	if (not ($rest | is-empty)) {
-		let result = exec_complete $rest
-		let completions = $result.completions
-		let directive = $result.directive
+    if (not ($rest | is-empty)) {
+        let result = exec_complete $rest
+        let completions = $result.completions
+        let directive = $result.directive
 
-		# Add space at the end of each completion
-		let completions = if $directive != $ShellCompDirectiveNoSpace {
-		  $completions | each {|it| {value: $"($it.value) ", description: $it.description}}
-		} else {
-		  $completions
-		}
+        # Add space at the end of each completion
+        let completions = if $directive != $ShellCompDirectiveNoSpace {
+          $completions | each {|it| {value: $"($it.value) ", description: $it.description}}
+        } else {
+          $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
-		}
+        # 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
+        }
 
-		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
-		}
-			
-		if ($completions | is-empty) {
-			null
-		} else {
-			$completions
-		}
-	} else {
-		null
-	}
+        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
+        }
+            
+        if ($completions | is-empty) {
+            null
+        } else {
+            $completions
+        }
+    } else {
+        null
+    }
 }
 `, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
-		ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
+        ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
 
-	_, err := buf.WriteTo(w)
-	return err
+    _, 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()
+    outFile, err := os.Create(filename)
+    if err != nil {
+        return err
+    }
+    defer outFile.Close()
 
-	return c.GenNushellCompletion(outFile, includeDesc)
+    return c.GenNushellCompletion(outFile, includeDesc)
 }

From 8b4aa590bbde4d231f28e3d3fe45443c804b07bb Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sat, 30 Nov 2024 13:34:39 -0800
Subject: [PATCH 19/35] Added new directive to the list of directives for
 posterity.

---
 nushell_completions.go | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/nushell_completions.go b/nushell_completions.go
index 702f0b26..e908fc6a 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -30,6 +30,7 @@ let cobra_completer = {|spans|
     let ShellCompDirectiveNoFileComp = %[3]d
     let ShellCompDirectiveFilterFileExt = %[4]d
     let ShellCompDirectiveFilterDirs = %[5]d
+    let ShellCompDirectiveKeepOrder = %[6]d
 
     let cmd = $spans | first 
     let rest = $spans | skip
@@ -109,7 +110,7 @@ let cobra_completer = {|spans|
     }
 }
 `, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
-        ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs))
+        ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder))
 
     _, err := buf.WriteTo(w)
     return err

From 70067196037b693592732beaebbf1ae25f60bb22 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sat, 30 Nov 2024 13:57:31 -0800
Subject: [PATCH 20/35] fixing formatting

---
 nushell_completions.go             | 32 +++++++++++++++---------------
 nushell_completions_test.go        | 12 +++++++++++
 site/content/completions/_index.md | 22 +++++++++-----------
 3 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/nushell_completions.go b/nushell_completions.go
index e908fc6a..d6cc274f 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -15,15 +15,15 @@
 package cobra
 
 import (
-    "bytes"
-    "fmt"
-    "io"
-    "os"
+	"bytes"
+	"fmt"
+	"io"
+	"os"
 )
 
 func (c *Command) GenNushellCompletion(w io.Writer, includeDesc bool) error {
-    buf := new(bytes.Buffer)
-    WriteStringAndCheck(buf, fmt.Sprintf(`
+	buf := new(bytes.Buffer)
+	WriteStringAndCheck(buf, fmt.Sprintf(`
 let cobra_completer = {|spans|
     let ShellCompDirectiveError = %[1]d
     let ShellCompDirectiveNoSpace = %[2]d
@@ -40,7 +40,7 @@ let cobra_completer = {|spans|
     ] {
         # This will catch the stderr message related to the directive and any other errors,
         # such as the command not being a cobra based command
-        let result = do --ignore-errors { cobra_active_help=0 run-external $cmd "__complete" ...$spans | complete }
+        let result = do --ignore-errors { COBRA_ACTIVE_HELP=0 run-external $cmd "__complete" ...$spans | complete }
 
         if $result != null and $result.exit_code == 0 {
             let completions = $result.stdout | lines
@@ -110,18 +110,18 @@ let cobra_completer = {|spans|
     }
 }
 `, ShellCompDirectiveError, ShellCompDirectiveNoSpace, ShellCompDirectiveNoFileComp,
-        ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder))
+		ShellCompDirectiveFilterFileExt, ShellCompDirectiveFilterDirs, ShellCompDirectiveKeepOrder))
 
-    _, err := buf.WriteTo(w)
-    return err
+	_, 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()
+	outFile, err := os.Create(filename)
+	if err != nil {
+		return err
+	}
+	defer outFile.Close()
 
-    return c.GenNushellCompletion(outFile, includeDesc)
+	return c.GenNushellCompletion(outFile, includeDesc)
 }
diff --git a/nushell_completions_test.go b/nushell_completions_test.go
index 73fedd07..1901540a 100644
--- a/nushell_completions_test.go
+++ b/nushell_completions_test.go
@@ -95,3 +95,15 @@ func TestFailGenNushellCompletionFile(t *testing.T) {
 		}
 	}
 }
+
+func TestNushellCompletionNoActiveHelp(t *testing.T) {
+	c := &Command{Use: "c", Run: emptyRun}
+
+	buf := new(bytes.Buffer)
+	assertNoErr(t, c.GenNushellCompletion(buf, true))
+	output := buf.String()
+
+	// check that active help is being disabled
+	activeHelpVar := activeHelpGlobalEnvVar
+	check(t, output, fmt.Sprintf("%s=0", activeHelpVar))
+}
diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index 2f598c7c..f64d6e4b 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.md
@@ -73,21 +73,17 @@ PowerShell:
 Nushell:
   
   # 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 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.
+  # 2. Copy the completer to at the end of the file.
+  # 3. Add a section like the following below the cobra_completer:
+    $env.config.completions.external = {
+        enable: true
+        max_results: 100
+        completer: $cobra_completer
+    }
+
+NOTE: This completer will work for all cobra based commands. More information can be found in the [External Completions](https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. Information on setting up more than external completer can be found [Multiple completer](https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) of the Nushell cookbook.
 
 `,cmd.Root().Name()),
 	DisableFlagsInUseLine: true,

From 982ba402cbbaca8d19e75d48482ebdd2bdba5e9a Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sat, 30 Nov 2024 13:59:41 -0800
Subject: [PATCH 21/35] fix tests

---
 nushell_completions_test.go | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/nushell_completions_test.go b/nushell_completions_test.go
index 1901540a..3958a134 100644
--- a/nushell_completions_test.go
+++ b/nushell_completions_test.go
@@ -37,9 +37,6 @@ func TestGenNushellCompletion(t *testing.T) {
 
 	buf := new(bytes.Buffer)
 	assertNoErr(t, rootCmd.GenNushellCompletion(buf, true))
-	output := buf.String()
-
-	check(t, output, fmt.Sprintf("let cobra_apps = [\"%[1]s\"]", rootCmd.Name()))
 }
 
 func TestGenNushellCompletionFile(t *testing.T) {

From 59726e2b0f5408cbb74dadd55e9e314d64617210 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sat, 30 Nov 2024 14:06:56 -0800
Subject: [PATCH 22/35] fixed a typo

---
 site/content/completions/_index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index f64d6e4b..25e2ab66 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.md
@@ -83,7 +83,7 @@ Nushell:
         completer: $cobra_completer
     }
 
-NOTE: This completer will work for all cobra based commands. More information can be found in the [External Completions](https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. Information on setting up more than external completer can be found [Multiple completer](https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) of the Nushell cookbook.
+NOTE: This completer will work for all cobra based commands. More information can be found in the [External Completions](https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. Information on setting up more than one external completer can be found [Multiple completer](https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) of the Nushell cookbook.
 
 `,cmd.Root().Name()),
 	DisableFlagsInUseLine: true,

From 18d7a29987b12444a4de87f74faac3495316ac5c Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sat, 30 Nov 2024 14:58:44 -0800
Subject: [PATCH 23/35] more documentation tweaks

---
 site/content/completions/_index.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index 25e2ab66..13cd3fb3 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.md
@@ -76,14 +76,14 @@ Nushell:
   # 1. Edit the nushell config file:
   > config nu
   # 2. Copy the completer to at the end of the file.
-  # 3. Add a section like the following below the cobra_completer:
+  # 3. Add a section like the following below at the end of the file:
     $env.config.completions.external = {
         enable: true
         max_results: 100
         completer: $cobra_completer
     }
 
-NOTE: This completer will work for all cobra based commands. More information can be found in the [External Completions](https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. Information on setting up more than one external completer can be found [Multiple completer](https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) of the Nushell cookbook.
+NOTE: This completer will work for all cobra based commands. More information can be found in the [External Completions](https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. Information on setting up more than one external completer can be found in the [Multiple completer](https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
 
 `,cmd.Root().Name()),
 	DisableFlagsInUseLine: true,

From 2f80e0879fa87eb2f62821d92d2961b3b09059b6 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sat, 30 Nov 2024 15:01:06 -0800
Subject: [PATCH 24/35] changed from being markdown, as I don't think the docs
 here are markdown

---
 site/content/completions/_index.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index 13cd3fb3..5573fd82 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.md
@@ -83,7 +83,7 @@ Nushell:
         completer: $cobra_completer
     }
 
-NOTE: This completer will work for all cobra based commands. More information can be found in the [External Completions](https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. Information on setting up more than one external completer can be found in the [Multiple completer](https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
+NOTE: This completer will work for all cobra based commands. More information can be found in the External Completions (https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. Information on setting up more than one external completer can be found in the Multiple completer (https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
 
 `,cmd.Root().Name()),
 	DisableFlagsInUseLine: true,

From 1886f6baad5e45867d36c337cf0cf6c1729093b0 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 1 Dec 2024 18:27:49 -0800
Subject: [PATCH 25/35] minor formatting tweak

---
 nushell_completions.go | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/nushell_completions.go b/nushell_completions.go
index d6cc274f..0fd02ea5 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -76,28 +76,28 @@ let cobra_completer = {|spans|
 
         # 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
+            $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
+            $completions
         }
 
         if $directive == $ShellCompDirectiveNoFileComp {
-          # Allow empty results as this will stop file completion
-          $completions
+            # 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
+            # Not returning null causes file completions to break
+            # Return null if there are no completions or ShellCompDirectiveError
+             null
+          } else {
+            $completions
         }
             
         if ($completions | is-empty) {

From ddb39920b4f1fbd51ba6fa0da663391cb8dbe438 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 1 Dec 2024 18:44:56 -0800
Subject: [PATCH 26/35] More documentation work for nushell

---
 completions.go                                | 25 +++++++++----------
 nushell_completions.md                        |  4 ---
 site/content/completions/_index.md            |  4 ++-
 .../completions/nushell_completions.md        |  3 +++
 4 files changed, 18 insertions(+), 18 deletions(-)
 delete mode 100644 nushell_completions.md
 create mode 100644 site/content/completions/nushell_completions.md

diff --git a/completions.go b/completions.go
index f6924ba7..a3d16bc2 100644
--- a/completions.go
+++ b/completions.go
@@ -848,21 +848,20 @@ to your powershell profile.
 		Long: fmt.Sprintf(`Generate the autocompletion script for nushell.
 
 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 shel for this setup to take effect.
-
-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:
-  > let cobra_apps = [ "othercobraapp", "%[1]s" ]
-  # 3. You will need to start a new shell for this setup to take effect.
-`, c.Root().Name()),
+  # 2. Copy the completer to at the end of the file.
+  # 3. Add a section like the following below at the end of the file:
+    $env.config.completions.external = {
+        enable: true
+        max_results: 100
+        completer: $cobra_completer
+    }
+
+NOTE: This completer will work for all cobra based commands.
+More information can be found in the External Completions (https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book.
+Information on setting up more than one external completer can be found in the Multiple completer (https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
+`),
 		Args:              NoArgs,
 		ValidArgsFunction: NoFileCompletions,
 		RunE: func(cmd *Command, args []string) error {
diff --git a/nushell_completions.md b/nushell_completions.md
deleted file mode 100644
index e0e94eb1..00000000
--- a/nushell_completions.md
+++ /dev/null
@@ -1,4 +0,0 @@
-## Generating Nushell Completions For Your cobra.Command
-
-Please refer to [Shell Completions](shell_completions.md) for details.
-
diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index 5573fd82..8ab4ca08 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.md
@@ -83,7 +83,9 @@ Nushell:
         completer: $cobra_completer
     }
 
-NOTE: This completer will work for all cobra based commands. More information can be found in the External Completions (https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. Information on setting up more than one external completer can be found in the Multiple completer (https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
+NOTE: This completer will work for all cobra based commands. 
+More information can be found in the External Completions (https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. 
+Information on setting up more than one external completer can be found in the Multiple completer (https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
 
 `,cmd.Root().Name()),
 	DisableFlagsInUseLine: true,
diff --git a/site/content/completions/nushell_completions.md b/site/content/completions/nushell_completions.md
new file mode 100644
index 00000000..3bd8065d
--- /dev/null
+++ b/site/content/completions/nushell_completions.md
@@ -0,0 +1,3 @@
+## Generating Nushell Completions For Your cobra.Command
+
+Please refer to [Shell Completions](_index.md#nushell-completions) for details.

From 470ca0a62845725bff62f8fd5823b477266f722c Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 1 Dec 2024 20:05:18 -0800
Subject: [PATCH 27/35] Added a comment at the beginning to remain consistent
 with other shells.

---
 nushell_completions.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/nushell_completions.go b/nushell_completions.go
index 0fd02ea5..85236525 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -23,6 +23,7 @@ import (
 
 func (c *Command) GenNushellCompletion(w io.Writer, includeDesc bool) error {
 	buf := new(bytes.Buffer)
+	WriteStringAndCheck(buf, "# nushell completion -*- shell-script -*- \n")
 	WriteStringAndCheck(buf, fmt.Sprintf(`
 let cobra_completer = {|spans|
     let ShellCompDirectiveError = %[1]d

From 93a41331ec907f11a4e1f882fa01eedaba581516 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 1 Dec 2024 20:05:39 -0800
Subject: [PATCH 28/35] tmpfile handling changes

---
 nushell_completions_test.go | 32 ++++++++++++--------------------
 1 file changed, 12 insertions(+), 20 deletions(-)

diff --git a/nushell_completions_test.go b/nushell_completions_test.go
index 3958a134..d86e8ede 100644
--- a/nushell_completions_test.go
+++ b/nushell_completions_test.go
@@ -16,9 +16,11 @@ package cobra
 
 import (
 	"bytes"
+	"errors"
 	"fmt"
 	"log"
 	"os"
+	"path/filepath"
 	"testing"
 )
 
@@ -40,12 +42,12 @@ func TestGenNushellCompletion(t *testing.T) {
 }
 
 func TestGenNushellCompletionFile(t *testing.T) {
-	err := os.Mkdir("./tmp", 0o755)
+	tmpFile, err := os.CreateTemp("", "cobra-test")
 	if err != nil {
 		log.Fatal(err.Error())
 	}
 
-	defer os.RemoveAll("./tmp")
+	defer os.RemoveAll(tmpFile.Name())
 
 	rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
 	child := &Command{
@@ -55,18 +57,18 @@ func TestGenNushellCompletionFile(t *testing.T) {
 	}
 	rootCmd.AddCommand(child)
 
-	assertNoErr(t, rootCmd.GenNushellCompletionFile("./tmp/test", true))
+	assertNoErr(t, rootCmd.GenNushellCompletionFile(tmpFile.Name(), true))
 }
 
 func TestFailGenNushellCompletionFile(t *testing.T) {
-	err := os.Mkdir("./tmp", 0o755)
+	tmpDir, err := os.MkdirTemp("", "cobra-test")
 	if err != nil {
-		log.Fatal(err.Error())
+		t.Fatal(err.Error())
 	}
 
-	defer os.RemoveAll("./tmp")
+	defer os.RemoveAll(tmpDir)
 
-	f, _ := os.OpenFile("./tmp/test", os.O_CREATE, 0o400)
+	f, _ := os.OpenFile(filepath.Join(tmpDir, "test"), os.O_CREATE, 0400)
 	defer f.Close()
 
 	rootCmd := &Command{Use: "root", Args: NoArgs, Run: emptyRun}
@@ -77,19 +79,9 @@ func TestFailGenNushellCompletionFile(t *testing.T) {
 	}
 	rootCmd.AddCommand(child)
 
-	got := rootCmd.GenNushellCompletionFile("./tmp/test", true)
-	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")
-		}
+	got := rootCmd.GenFishCompletionFile(f.Name(), false)
+	if !errors.Is(got, os.ErrPermission) {
+		t.Errorf("got: %s, want: %s", got.Error(), os.ErrPermission.Error())
 	}
 }
 

From e0ac28fad8c28424920e93ba37695cd67d9bc514 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 8 Dec 2024 19:33:48 -0800
Subject: [PATCH 29/35] fix fish reference

---
 nushell_completions_test.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/nushell_completions_test.go b/nushell_completions_test.go
index d86e8ede..db58cbd2 100644
--- a/nushell_completions_test.go
+++ b/nushell_completions_test.go
@@ -79,7 +79,7 @@ func TestFailGenNushellCompletionFile(t *testing.T) {
 	}
 	rootCmd.AddCommand(child)
 
-	got := rootCmd.GenFishCompletionFile(f.Name(), false)
+	got := rootCmd.GenNushellCompletionFile(f.Name(), false)
 	if !errors.Is(got, os.ErrPermission) {
 		t.Errorf("got: %s, want: %s", got.Error(), os.ErrPermission.Error())
 	}

From 14e642ede90211776346674e1e66593b1a82364a Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 8 Dec 2024 19:35:50 -0800
Subject: [PATCH 30/35] fixed bad grammar mistake

---
 completions.go                     | 2 +-
 site/content/completions/_index.md | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/completions.go b/completions.go
index a3d16bc2..67cee18b 100644
--- a/completions.go
+++ b/completions.go
@@ -850,7 +850,7 @@ to your powershell profile.
 To configure the Nushell cobra external completer for the first time:
   # 1. Edit the nushell config file:
   > config nu
-  # 2. Copy the completer to at the end of the file.
+  # 2. Copy the completer to the end of the file.
   # 3. Add a section like the following below at the end of the file:
     $env.config.completions.external = {
         enable: true
diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index 8ab4ca08..25f04fbd 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.md
@@ -75,7 +75,7 @@ Nushell:
   # To configure the Nushell cobra external completer for the first time:
   # 1. Edit the nushell config file:
   > config nu
-  # 2. Copy the completer to at the end of the file.
+  # 2. Copy the completer to the end of the file.
   # 3. Add a section like the following below at the end of the file:
     $env.config.completions.external = {
         enable: true

From d728bbb91e1a0905f9bb8eb20b6a63f2e2e9cbba Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 8 Dec 2024 19:38:47 -0800
Subject: [PATCH 31/35] Nushell instructions tweak

---
 completions.go                     | 4 ++--
 site/content/completions/_index.md | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/completions.go b/completions.go
index 67cee18b..5d67196d 100644
--- a/completions.go
+++ b/completions.go
@@ -850,7 +850,7 @@ to your powershell profile.
 To configure the Nushell cobra external completer for the first time:
   # 1. Edit the nushell config file:
   > config nu
-  # 2. Copy the completer to the end of the file.
+  # 2. Copy the output of %[1]s completion nushell to the end of the file.
   # 3. Add a section like the following below at the end of the file:
     $env.config.completions.external = {
         enable: true
@@ -861,7 +861,7 @@ To configure the Nushell cobra external completer for the first time:
 NOTE: This completer will work for all cobra based commands.
 More information can be found in the External Completions (https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book.
 Information on setting up more than one external completer can be found in the Multiple completer (https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
-`),
+`, c.Root().Name()),
 		Args:              NoArgs,
 		ValidArgsFunction: NoFileCompletions,
 		RunE: func(cmd *Command, args []string) error {
diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index 25f04fbd..1006020b 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.md
@@ -75,7 +75,7 @@ Nushell:
   # To configure the Nushell cobra external completer for the first time:
   # 1. Edit the nushell config file:
   > config nu
-  # 2. Copy the completer to the end of the file.
+  # 2. Copy the output of %[1]s completion nushell to the end of the file.
   # 3. Add a section like the following below at the end of the file:
     $env.config.completions.external = {
         enable: true

From 52185bed6e0016f343afd14f57bf7ed6311ec2a4 Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 8 Dec 2024 19:44:45 -0800
Subject: [PATCH 32/35] tweaking extra completion instructions

---
 completions.go                     | 9 ++++++---
 site/content/completions/_index.md | 9 ++++++---
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/completions.go b/completions.go
index 5d67196d..1e5a4f50 100644
--- a/completions.go
+++ b/completions.go
@@ -858,9 +858,12 @@ To configure the Nushell cobra external completer for the first time:
         completer: $cobra_completer
     }
 
-NOTE: This completer will work for all cobra based commands.
-More information can be found in the External Completions (https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book.
-Information on setting up more than one external completer can be found in the Multiple completer (https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
+This completer will work for all cobra based commands. 
+More information can be found in the External Completions section of the Nushell book: 
+https://www.nushell.sh/book/custom_completions.html#external-completions
+
+Information on setting up more than one external completer can be found in the Multiple completer section of the Nushell cookbook:
+https://www.nushell.sh/cookbook/external_completers.html#multiple-completer
 `, c.Root().Name()),
 		Args:              NoArgs,
 		ValidArgsFunction: NoFileCompletions,
diff --git a/site/content/completions/_index.md b/site/content/completions/_index.md
index 1006020b..3548478f 100644
--- a/site/content/completions/_index.md
+++ b/site/content/completions/_index.md
@@ -83,9 +83,12 @@ Nushell:
         completer: $cobra_completer
     }
 
-NOTE: This completer will work for all cobra based commands. 
-More information can be found in the External Completions (https://www.nushell.sh/book/custom_completions.html#custom-descriptions) section of the Nushell book. 
-Information on setting up more than one external completer can be found in the Multiple completer (https://www.nushell.sh/cookbook/external_completers.html#multiple-completer) section of the Nushell cookbook.
+This completer will work for all cobra based commands. 
+More information can be found in the External Completions section of the Nushell book: 
+https://www.nushell.sh/book/custom_completions.html#external-completions
+
+Information on setting up more than one external completer can be found in the Multiple completer section of the Nushell cookbook:
+https://www.nushell.sh/cookbook/external_completers.html#multiple-completer
 
 `,cmd.Root().Name()),
 	DisableFlagsInUseLine: true,

From 1df1dbd552ef4686e1c85afc1a74f1611bb603ec Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 8 Dec 2024 20:34:38 -0800
Subject: [PATCH 33/35] cobra logging command

---
 nushell_completions.go | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/nushell_completions.go b/nushell_completions.go
index 85236525..7a8962db 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -36,6 +36,15 @@ let cobra_completer = {|spans|
     let cmd = $spans | first 
     let rest = $spans | skip
 
+    def cobra_log [message] {
+        let file = do -i {$env | get NUSHELL_COMP_DEBUG_FILE}
+        if $file != null {
+            echo $"($message)\n" | save $file --append
+        }
+    }
+
+    cobra_log $"External Completer called for cmd ($cmd)"
+
     def exec_complete [
         spans: list<string>
     ] {

From da1bab975725502baebef6f04066721f8e52b1cb Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Wed, 11 Dec 2024 17:22:41 -0800
Subject: [PATCH 34/35] Fixed the ShellCompDirectiveNoFileComp case

---
 nushell_completions.go | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/nushell_completions.go b/nushell_completions.go
index 7a8962db..d1740d1d 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -109,12 +109,6 @@ let cobra_completer = {|spans|
           } else {
             $completions
         }
-            
-        if ($completions | is-empty) {
-            null
-        } else {
-            $completions
-        }
     } else {
         null
     }

From ae37156f634973d59186b69de0623c866f77415b Mon Sep 17 00:00:00 2001
From: Jack Wright <ayax79@gmail.com>
Date: Sun, 29 Dec 2024 13:23:29 -0800
Subject: [PATCH 35/35] Removing unused includeDesc parameter

---
 completions.go              | 2 +-
 nushell_completions.go      | 6 +++---
 nushell_completions_test.go | 8 ++++----
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/completions.go b/completions.go
index 1e5a4f50..9bee0a6c 100644
--- a/completions.go
+++ b/completions.go
@@ -868,7 +868,7 @@ https://www.nushell.sh/cookbook/external_completers.html#multiple-completer
 		Args:              NoArgs,
 		ValidArgsFunction: NoFileCompletions,
 		RunE: func(cmd *Command, args []string) error {
-			return cmd.Root().GenNushellCompletion(out, !noDesc)
+			return cmd.Root().GenNushellCompletion(out)
 		},
 	}
 	if haveNoDescFlag {
diff --git a/nushell_completions.go b/nushell_completions.go
index d1740d1d..830ffe4d 100644
--- a/nushell_completions.go
+++ b/nushell_completions.go
@@ -21,7 +21,7 @@ import (
 	"os"
 )
 
-func (c *Command) GenNushellCompletion(w io.Writer, includeDesc bool) error {
+func (c *Command) GenNushellCompletion(w io.Writer) error {
 	buf := new(bytes.Buffer)
 	WriteStringAndCheck(buf, "# nushell completion -*- shell-script -*- \n")
 	WriteStringAndCheck(buf, fmt.Sprintf(`
@@ -120,12 +120,12 @@ let cobra_completer = {|spans|
 	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 db58cbd2..41a98f46 100644
--- a/nushell_completions_test.go
+++ b/nushell_completions_test.go
@@ -38,7 +38,7 @@ func TestGenNushellCompletion(t *testing.T) {
 	rootCmd.AddCommand(getCmd)
 
 	buf := new(bytes.Buffer)
-	assertNoErr(t, rootCmd.GenNushellCompletion(buf, true))
+	assertNoErr(t, rootCmd.GenNushellCompletion(buf))
 }
 
 func TestGenNushellCompletionFile(t *testing.T) {
@@ -57,7 +57,7 @@ func TestGenNushellCompletionFile(t *testing.T) {
 	}
 	rootCmd.AddCommand(child)
 
-	assertNoErr(t, rootCmd.GenNushellCompletionFile(tmpFile.Name(), true))
+	assertNoErr(t, rootCmd.GenNushellCompletionFile(tmpFile.Name()))
 }
 
 func TestFailGenNushellCompletionFile(t *testing.T) {
@@ -79,7 +79,7 @@ func TestFailGenNushellCompletionFile(t *testing.T) {
 	}
 	rootCmd.AddCommand(child)
 
-	got := rootCmd.GenNushellCompletionFile(f.Name(), false)
+	got := rootCmd.GenNushellCompletionFile(f.Name())
 	if !errors.Is(got, os.ErrPermission) {
 		t.Errorf("got: %s, want: %s", got.Error(), os.ErrPermission.Error())
 	}
@@ -89,7 +89,7 @@ func TestNushellCompletionNoActiveHelp(t *testing.T) {
 	c := &Command{Use: "c", Run: emptyRun}
 
 	buf := new(bytes.Buffer)
-	assertNoErr(t, c.GenNushellCompletion(buf, true))
+	assertNoErr(t, c.GenNushellCompletion(buf))
 	output := buf.String()
 
 	// check that active help is being disabled