Repository: rsteube/carapace (go)

Issue:
support cmd.DisableFlagParsing
When `DisableFlagParsing` is true flags are not to be parsed but rather added to args and thus need to be container in `c.Args` as well.
Needed to create an `ActionInvokeCompletion` and pass args to [invoke-completion](https://github.com/rsteube/invoke-completion) (e.g. for an embedded git command or to bridge completion of a different shell).

Seen not to work with `dotfiles git commit -<TAB>`

Pull request:
support `cmd.DisableFlagParsing`
fix #318


Patch:
diff --git a/carapace.go b/carapace.go
index 8003424..5d1ef96 100644
--- a/carapace.go
+++ b/carapace.go
@@ -166,9 +166,9 @@ func addCompletionCommand(cmd *cobra.Command) {
 					case "_":
 						// TODO needs more cleanup and tests
 						var targetAction Action
-						if flag := lookupFlag(targetCmd, previous); flag != nil && flag.NoOptDefVal == "" { // previous arg is a flag and needs a value
+						if flag := lookupFlag(targetCmd, previous); !targetCmd.DisableFlagParsing && flag != nil && flag.NoOptDefVal == "" { // previous arg is a flag and needs a value
 							targetAction = storage.getFlag(targetCmd, flag.Name)
-						} else if strings.HasPrefix(current, "-") { // assume flag
+						} else if !targetCmd.DisableFlagParsing && strings.HasPrefix(current, "-") { // assume flag
 							if strings.Contains(current, "=") { // complete value for optarg flag
 								if flag := lookupFlag(targetCmd, current); flag != nil && flag.NoOptDefVal != "" {
 									a := storage.getFlag(targetCmd, flag.Name)
diff --git a/internal/common/traverse.go b/internal/common/traverse.go
index 325db98..5c7a79c 100644
--- a/internal/common/traverse.go
+++ b/internal/common/traverse.go
@@ -25,6 +25,10 @@ func TraverseLenient(cmd *cobra.Command, args []string) (*cobra.Command, []strin
 		return targetCmd, targetArgs, filterError(args, err)
 	}
 
+	if targetCmd.DisableFlagParsing {
+		return targetCmd, targetArgs, nil // TODO might need to consider logic below regarding parent command as well
+	}
+
 	err = targetCmd.ParseFlags(targetArgs)
 	for _, name := range append(targetCmd.Aliases, targetCmd.Name()) {
 		if len(args) > 0 &&


Test patch:
diff --git a/internal/common/traverse_test.go b/internal/common/traverse_test.go
index 5524704..075b65a 100644
--- a/internal/common/traverse_test.go
+++ b/internal/common/traverse_test.go
@@ -3,6 +3,7 @@ package common
 import (
 	"testing"
 
+	"github.com/rsteube/carapace/internal/assert"
 	"github.com/spf13/cobra"
 )
 
@@ -14,6 +15,11 @@ var testSubCmd = &cobra.Command{
 	Use: "sub",
 }
 
+var testSub2Cmd = &cobra.Command{
+	Use:                "sub2",
+	DisableFlagParsing: true,
+}
+
 var intVar int
 
 func init() {
@@ -28,12 +34,15 @@ func init() {
 	testSubCmd.Flags().StringP("substring", "s", "", "string flag")
 	testSubCmd.Flags().BoolP("subbool", "b", false, "bool flag")
 	testCmd.AddCommand(testSubCmd)
+
+	testCmd.AddCommand(testSub2Cmd)
 }
 
-func testTraverseLenient(t *testing.T, args ...string) {
-	if _, _, err := TraverseLenient(testCmd, args); err != nil {
+func testTraverseLenient(t *testing.T, args ...string) (targetCmd *cobra.Command, targetArgs []string, err error) {
+	if targetCmd, targetArgs, err = TraverseLenient(testCmd, args); err != nil {
 		t.Error(err.Error())
 	}
+	return
 }
 
 func TestNoArg(t *testing.T) {
@@ -45,45 +54,50 @@ func TestEmptyArg(t *testing.T) {
 }
 
 func TestLongFlagIncomplete(t *testing.T) {
-	testTraverseLenient(t, "test", "--stri")
+	testTraverseLenient(t, "--stri")
 }
 
 func TestLongFlagNoArg(t *testing.T) {
-	testTraverseLenient(t, "test", "--string")
+	testTraverseLenient(t, "--string")
 }
 
 func TestLongFlagEmptyArg(t *testing.T) {
-	testTraverseLenient(t, "test", "--string", "")
+	testTraverseLenient(t, "--string", "")
 }
 
 func TestShortFlagNoArg(t *testing.T) {
-	testTraverseLenient(t, "test", "-s")
+	testTraverseLenient(t, "-s")
 }
 
 func TestShortFlagEmptyArg(t *testing.T) {
-	testTraverseLenient(t, "test", "-s", "")
+	testTraverseLenient(t, "-s", "")
 }
 
 func TestShortFlagChainNoArg(t *testing.T) {
-	testTraverseLenient(t, "test", "-bs")
+	testTraverseLenient(t, "-bs")
 }
 
 func TestShortFlagChainEmptyArg(t *testing.T) {
-	testTraverseLenient(t, "test", "-bs", "")
+	testTraverseLenient(t, "-bs", "")
 }
 
 func TestIntEmptyArg(t *testing.T) {
-	testTraverseLenient(t, "test", "--int", "")
+	testTraverseLenient(t, "--int", "")
 }
 
 func TestIntVarEmptyArg(t *testing.T) {
-	testTraverseLenient(t, "test", "--intvar", "")
+	testTraverseLenient(t, "--intvar", "")
 }
 
 func TestIntSliceEmptyArg(t *testing.T) {
-	testTraverseLenient(t, "test", "--intslice", "")
+	testTraverseLenient(t, "--intslice", "")
 }
 
 func TestIntSliceIncompleteArg(t *testing.T) {
-	testTraverseLenient(t, "test", "--intslice", "1,")
+	testTraverseLenient(t, "--intslice", "1,")
+}
+
+func TestDisabledFlagParsing(t *testing.T) {
+	_, args, _ := testTraverseLenient(t, "sub2", "--arg")
+	assert.Equal(t, args[0], "--arg") // TODO test whole slice
 }