Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cobra bridge #920

Merged
merged 1 commit into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ caraparse/caraparse
docs/book
example/cmd/_test_files/*.txt
example/example
example-nonposix/example-nonposix
integration.cov
unit.cov
.vscode
4 changes: 2 additions & 2 deletions carapace.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func (c Carapace) PositionalCompletion(action ...Action) {

// PositionalAnyCompletion defines completion for any positional arguments not already defined.
func (c Carapace) PositionalAnyCompletion(action Action) {
storage.get(c.cmd).positionalAny = action
storage.get(c.cmd).positionalAny = &action
}

// DashCompletion defines completion for positional arguments after dash (`--`) using a list of Actions.
Expand All @@ -67,7 +67,7 @@ func (c Carapace) DashCompletion(action ...Action) {

// DashAnyCompletion defines completion for any positional arguments after dash (`--`) not already defined.
func (c Carapace) DashAnyCompletion(action Action) {
storage.get(c.cmd).dashAny = action
storage.get(c.cmd).dashAny = &action
}

// FlagCompletion defines completion for flags using a map consisting of name and Action.
Expand Down
60 changes: 58 additions & 2 deletions compat.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package carapace

import (
"fmt"
"strings"

"github.com/spf13/cobra"
"github.com/spf13/pflag"
Expand All @@ -10,17 +11,27 @@ import (
func registerValidArgsFunction(cmd *cobra.Command) {
if cmd.ValidArgsFunction == nil {
cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
action := storage.getPositional(cmd, len(args)).Invoke(Context{Args: args, Value: toComplete})
action := Action{}.Invoke(Context{Args: args, Value: toComplete}) // TODO just IvokedAction{} ok?
if storage.hasPositional(cmd, len(args)) {
action = storage.getPositional(cmd, len(args)).Invoke(Context{Args: args, Value: toComplete})
}
return cobraValuesFor(action), cobraDirectiveFor(action)
}
}
}

func registerFlagCompletion(cmd *cobra.Command) {
cmd.LocalFlags().VisitAll(func(f *pflag.Flag) {
if !storage.hasFlag(cmd, f.Name) {
return // skip if not defined in carapace
}
if _, ok := cmd.GetFlagCompletionFunc(f.Name); ok {
return // skip if already defined in cobra
}

err := cmd.RegisterFlagCompletionFunc(f.Name, func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
a := storage.getFlag(cmd, f.Name)
action := a.Invoke(Context{Args: args, Value: toComplete})
action := a.Invoke(Context{Args: args, Value: toComplete}) // TODO cmd might differ for persistentflags and either way args or cmd will be wrong
return cobraValuesFor(action), cobraDirectiveFor(action)
})
if err != nil {
Expand Down Expand Up @@ -51,3 +62,48 @@ func cobraDirectiveFor(action InvokedAction) cobra.ShellCompDirective {
}
return directive
}

type compDirective cobra.ShellCompDirective

func (d compDirective) matches(cobraDirective cobra.ShellCompDirective) bool {
return d&compDirective(cobraDirective) != 0
}

func (d compDirective) ToA(values ...string) Action {
var action Action
switch {
case d.matches(cobra.ShellCompDirectiveError):
return ActionMessage("an error occured")
case d.matches(cobra.ShellCompDirectiveFilterDirs):
switch len(values) {
case 0:
action = ActionDirectories()
default:
action = ActionDirectories().Chdir(values[0])
}
case d.matches(cobra.ShellCompDirectiveFilterFileExt):
extensions := make([]string, 0)
for _, v := range values {
extensions = append(extensions, "."+v)
}
return ActionFiles(extensions...)
case len(values) == 0 && !d.matches(cobra.ShellCompDirectiveNoFileComp):
action = ActionFiles()
default:
vals := make([]string, 0)
for _, v := range values {
if splitted := strings.SplitN(v, "\t", 2); len(splitted) == 2 {
vals = append(vals, splitted[0], splitted[1])
} else {
vals = append(vals, splitted[0], "")
}
}
action = ActionValuesDescribed(vals...)
}

if d.matches(cobra.ShellCompDirectiveNoSpace) {
action = action.NoSpace()
}

return action
}
4 changes: 2 additions & 2 deletions compat_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package carapace

import (
"io/ioutil"
"io"
"os"
"strings"
"testing"
Expand Down Expand Up @@ -54,7 +54,7 @@ func TestRegisterFlagCompletion(t *testing.T) {
_ = cmd.Execute()

w.Close()
out, _ := ioutil.ReadAll(r)
out, _ := io.ReadAll(r)
os.Stdout = rescueStdout

if lines := strings.Split(string(out), "\n"); lines[0] != "1\tone" {
Expand Down
2 changes: 2 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/rsteube/carapace/pkg/util"
"github.com/rsteube/carapace/third_party/github.com/drone/envsubst"
"github.com/rsteube/carapace/third_party/golang.org/x/sys/execabs"
"github.com/spf13/cobra"
)

// Context provides information during completion.
Expand All @@ -28,6 +29,7 @@ type Context struct {
Dir string

mockedReplies map[string]string
cmd *cobra.Command // needed for ActionCobra
}

// NewContext creates a new context for given arguments.
Expand Down
21 changes: 20 additions & 1 deletion defaultActions.go
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,11 @@ func ActionPositional(cmd *cobra.Command) Action {
c.Args = cmd.Flags().Args()
entry := storage.get(cmd)

a := entry.positionalAny
var a Action
if entry.positionalAny != nil {
a = *entry.positionalAny
}

if index := len(c.Args); index < len(entry.positional) {
a = entry.positional[len(c.Args)]
}
Expand Down Expand Up @@ -514,3 +518,18 @@ func ActionCommands(cmd *cobra.Command) Action {
return batch.ToA()
})
}

// ActionCora bridges given cobra completion function.
func ActionCobra(f func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective)) Action {
return ActionCallback(func(c Context) Action {
switch {
case f == nil:
return ActionValues()
case c.cmd == nil: // ensure cmd is never nil even if context does not contain one
LOG.Print("cmd is nil [ActionCobra]")
c.cmd = &cobra.Command{Use: "_carapace_actioncobra", Hidden: true, Deprecated: "dummy command for ActionCobra"}
}
values, directive := f(c.cmd, c.cmd.Flags().Args(), c.Value)
return compDirective(directive).ToA(values...)
})
}
1 change: 1 addition & 0 deletions docs/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
- [ToMultiPartsA](./carapace/invokedAction/toMultiPartsA.md)
- [DefaultActions](./carapace/defaultActions.md)
- [ActionCallback](./carapace/defaultActions/actionCallback.md)
- [ActionCobra](./carapace/defaultActions/actionCobra.md)
- [ActionCommands](./carapace/defaultActions/actionCommands.md)
- [ActionDirectories](./carapace/defaultActions/actionDirectories.md)
- [ActionExecCommand](./carapace/defaultActions/actionExecCommand.md)
Expand Down
50 changes: 50 additions & 0 deletions docs/src/carapace/defaultActions/actionCobra.cast
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{"version": 2, "width": 108, "height": 24, "timestamp": 1701100000, "env": {"SHELL": "elvish", "TERM": "tmux-256color"}}
[0.122617, "o", "\u001b[?7h\u001b[7m⏎\u001b[m \r \r\u001b[?7l\u001b[?2004h\u001b[?25l\r???> ???> \r\u001b[5C\u001b[?25h"]
[0.123322, "o", "\u001b[?25l\r\u001b[5C\u001b[K\r\u001b[5C\u001b[?25h"]
[0.139511, "o", "\u001b[?25l\r\r\u001b[5C\u001b[?25h"]
[0.139635, "o", "\u001b[?25l\r\u001b[K\r\n\u001b[0;1;36mcarapace/example\u001b[0;m on \u001b[0;1;35m cobra-bridge\u001b[0;m \u001b[0;1;31m[$!?]\u001b[0;m via \u001b[0;1;36m🐹 v1.21.4 \r\n\u001b[0;1;37mesh\u001b[0;m \u001b[0;1;32m❯\u001b[0;m \r\u001b[6C\u001b[?25h"]
[0.456695, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[0;32me\u001b[0;m\r\u001b[7C\u001b[?25h"]
[0.457047, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.457406, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.476703, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.476774, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[0.661672, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;31mex\u001b[0;m\r\u001b[8C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[8C\u001b[?25h"]
[0.756942, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexa\u001b[0;m\r\u001b[9C\u001b[?25h"]
[0.757869, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[9C\u001b[?25h"]
[0.758057, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[9C\u001b[?25h"]
[0.915507, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;31mexam\u001b[0;m\r\u001b[10C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[10C\u001b[?25h"]
[0.972819, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[10C\u001b[0;31mp\u001b[0;m\r\u001b[11C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[11C\u001b[?25h"]
[1.088957, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[11C\u001b[0;31ml\u001b[0;m\r\u001b[12C\u001b[?25h"]
[1.242635, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexample\u001b[0;m\r\u001b[13C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[13C\u001b[?25h"]
[1.318984, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[13C \r\u001b[14C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[14C\u001b[?25h"]
[1.421313, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[14Ca\r\u001b[15C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[15C\u001b[?25h"]
[1.565644, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[15Cc\r\u001b[16C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[16C\u001b[?25h"]
[1.789857, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[16Ct\r\u001b[17C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[17C\u001b[?25h"]
[1.861419, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[17Ci\r\u001b[18C\u001b[?25h"]
[1.861572, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[18C\u001b[?25h"]
[1.953279, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[18Co\r\u001b[19C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[19C\u001b[?25h"]
[2.001547, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[19Cn\r\u001b[20C\u001b[?25h"]
[2.001701, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[20C\u001b[?25h"]
[2.133981, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[20C \r\u001b[21C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[21C\u001b[?25h"]
[2.297596, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[21C-\r\u001b[22C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[22C\u001b[?25h"]
[2.449595, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[22C-\r\u001b[23C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[23C\u001b[?25h"]
[2.665291, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[23Cc\r\u001b[24C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[24C\u001b[?25h"]
[2.769879, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[24Co\r\u001b[25C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[25C\u001b[?25h"]
[2.920473, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[21C\u001b[K\u001b[0;4m--cobra \r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7;34m--cobra\u001b[0;2;7m (ActionCobra())\u001b[0;m \u001b[0;34m--commands\u001b[0;2m (ActionCommands())\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[3.679034, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[21C\u001b[K--cobra \r\n\u001b[J\u001b[A\r\u001b[29C\u001b[?25h"]
[4.167667, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[29C\u001b[0;4mone\r\n\u001b[0;1;37;45m COMPLETING argument \u001b[0;m \r\n\u001b[0;7mone\u001b[0;m two\u001b[1A\r\u001b[22C\u001b[?25h"]
[5.054262, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[29C\u001b[K\u001b[0;4mtwo\r\n\r\n\u001b[0;m\u001b[Kone \u001b[0;7mtwo\u001b[0;m\u001b[1A\r\u001b[22C\u001b[?25h"]
[6.629692, "o", "\u001b[?25l\u001b[3A\r\r\n\r\n\u001b[29C\u001b[Ktwo\r\n\u001b[J\u001b[A\r\u001b[32C\u001b[?25h"]
[6.629826, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[32C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[32C\u001b[?25h"]
[7.230671, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\r\u001b[6C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[7.231617, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[7.25196, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[6C\u001b[?25h"]
[7.471051, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[0;32me\u001b[0;m\r\u001b[7C\u001b[?25h"]
[7.471209, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[7C\u001b[?25h"]
[7.684061, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;31mex\u001b[0;m\r\u001b[8C\u001b[?25h"]
[7.684762, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[8C\u001b[?25h"]
[7.688565, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[8C\u001b[?25h"]
[7.688621, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[8C\u001b[?25h"]
[7.816432, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[8C\u001b[0;31mi\u001b[0;m\r\u001b[9C\u001b[?25h"]
[7.907227, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\u001b[6C\u001b[K\u001b[0;32mexit\u001b[0;m\r\u001b[10C\u001b[?25h\u001b[?25l\u001b[2A\r\r\n\r\n\r\u001b[10C\u001b[?25h"]
[8.0253, "o", "\u001b[?25l\u001b[2A\r\r\n\r\n\r\n\r\u001b[?25h\u001b[?7h\u001b[?2004l\r"]
13 changes: 13 additions & 0 deletions docs/src/carapace/defaultActions/actionCobra.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# ActionCobra

[`ActionCobra`] bridges given cobra completion function.

```go
carapace.ActionCobra(func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"one", "two"}, cobra.ShellCompDirectiveNoSpace
})
```

![](./actionCobra.cast)

[`ActionCobra`]:https://pkg.go.dev/github.com/rsteube/carapace#ActionCobra
4 changes: 4 additions & 0 deletions example/cmd/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func init() {
rootCmd.AddCommand(actionCmd)

actionCmd.Flags().String("callback", "", "ActionCallback()")
actionCmd.Flags().String("cobra", "", "ActionCobra()")
actionCmd.Flags().String("commands", "", "ActionCommands()")
actionCmd.Flags().String("directories", "", "ActionDirectories()")
actionCmd.Flags().String("execcommand", "", "ActionExecCommand()")
Expand Down Expand Up @@ -49,6 +50,9 @@ func init() {
}
return carapace.ActionMessage("values flag is not set")
}),
"cobra": carapace.ActionCobra(func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"one", "two"}, cobra.ShellCompDirectiveNoSpace
}),
"commands": carapace.ActionCommands(rootCmd).Split(),
"directories": carapace.ActionDirectories(),
"execcommand": carapace.ActionExecCommand("git", "remote")(func(output []byte) carapace.Action {
Expand Down
7 changes: 7 additions & 0 deletions example/cmd/action_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ func TestAction(t *testing.T) {
Expect(carapace.ActionMessage("values flag is not set").
Usage("ActionCallback()"))

s.Run("action", "--cobra", "").
Expect(carapace.ActionValues(
"one",
"two",
).NoSpace().
Usage("ActionCobra()"))

s.Run("action", "--commands", "s").
Expect(carapace.ActionValuesDescribed(
"special", "",
Expand Down
87 changes: 87 additions & 0 deletions example/cmd/compat.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package cmd

import (
"fmt"

"github.com/rsteube/carapace"
"github.com/spf13/cobra"
)

var compatCmd = &cobra.Command{
Use: "compat",
Short: "",
Run: func(cmd *cobra.Command, args []string) {},
}

func init() {
carapace.Gen(compatCmd).Standalone()

compatCmd.Flags()

compatCmd.Flags().String("error", "", "ShellCompDirectiveError")
compatCmd.Flags().String("nospace", "", "ShellCompDirectiveNoSpace")
compatCmd.Flags().String("nofilecomp", "", "ShellCompDirectiveNoFileComp")
compatCmd.Flags().String("filterfileext", "", "ShellCompDirectiveFilterFileExt")
compatCmd.Flags().String("filterdirs", "", "ShellCompDirectiveFilterDirs")
compatCmd.Flags().String("filterdirs-chdir", "", "ShellCompDirectiveFilterDirs")
compatCmd.Flags().String("keeporder", "", "ShellCompDirectiveKeepOrder")
compatCmd.Flags().String("default", "", "ShellCompDirectiveDefault")

compatCmd.Flags().String("unset", "", "no completions defined")
compatCmd.PersistentFlags().String("persistent-compat", "", "persistent flag defined with cobra")

rootCmd.AddCommand(compatCmd)

_ = compatCmd.RegisterFlagCompletionFunc("error", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveError
})
_ = compatCmd.RegisterFlagCompletionFunc("nospace", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"one", "two"}, cobra.ShellCompDirectiveNoSpace
})
_ = compatCmd.RegisterFlagCompletionFunc("nofilecomp", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveNoFileComp
})

_ = compatCmd.RegisterFlagCompletionFunc("filterfileext", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"mod", "sum"}, cobra.ShellCompDirectiveFilterFileExt
})

_ = compatCmd.RegisterFlagCompletionFunc("filterdirs", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveFilterDirs
})

_ = compatCmd.RegisterFlagCompletionFunc("filterdirs-chdir", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"subdir"}, cobra.ShellCompDirectiveFilterDirs
})

_ = compatCmd.RegisterFlagCompletionFunc("keeporder", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"one", "three", "two"}, cobra.ShellCompDirectiveKeepOrder
})

_ = compatCmd.RegisterFlagCompletionFunc("default", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return nil, cobra.ShellCompDirectiveDefault
})

_ = compatCmd.RegisterFlagCompletionFunc("persistent-compat", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{
fmt.Sprintf("args: %#v toComplete: %#v", args, toComplete),
"alternative",
}, cobra.ShellCompDirectiveNoFileComp
})

compatCmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
switch len(args) {
case 0:
return []string{"p1", "positional1"}, cobra.ShellCompDirectiveDefault
case 1:
return nil, cobra.ShellCompDirectiveDefault
case 2:
return []string{
fmt.Sprintf("args: %#v toComplete: %#v", args, toComplete),
"alternative",
}, cobra.ShellCompDirectiveNoFileComp
default:
return nil, cobra.ShellCompDirectiveNoFileComp
}
}
}
18 changes: 18 additions & 0 deletions example/cmd/compat_sub.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package cmd

import (
"github.com/rsteube/carapace"
"github.com/spf13/cobra"
)

var compat_subCmd = &cobra.Command{
Use: "sub",
Short: "",
Run: func(cmd *cobra.Command, args []string) {},
}

func init() {
carapace.Gen(compat_subCmd).Standalone()

compatCmd.AddCommand(compat_subCmd)
}
Loading
Loading