Skip to content

Commit 78879d1

Browse files
rsteubemaxlandon
andcommitted
expose ActionCommands
Co-authored-by: maxlandon <[email protected]>
1 parent 737173a commit 78879d1

File tree

13 files changed

+313
-54
lines changed

13 files changed

+313
-54
lines changed

defaultActions.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/rsteube/carapace/internal/common"
1313
"github.com/rsteube/carapace/internal/config"
14+
"github.com/rsteube/carapace/internal/env"
1415
"github.com/rsteube/carapace/internal/export"
1516
"github.com/rsteube/carapace/internal/man"
1617
"github.com/rsteube/carapace/pkg/match"
@@ -480,3 +481,36 @@ func ActionPositional(cmd *cobra.Command) Action {
480481
return a.Invoke(c).ToA()
481482
})
482483
}
484+
485+
// ActionCommands completes (sub)commands of given command.
486+
// `Context.Args` is used to traverse the command tree further down. Use `Action.Shift` to avoid this.
487+
//
488+
// carapace.Gen(helpCmd).PositionalAnyCompletion(
489+
// carapace.ActionCommands(rootCmd),
490+
// )
491+
func ActionCommands(cmd *cobra.Command) Action {
492+
return ActionCallback(func(c Context) Action {
493+
if len(c.Args) > 0 {
494+
for _, subCommand := range cmd.Commands() {
495+
for _, name := range append(subCommand.Aliases, subCommand.Name()) {
496+
if name == c.Args[0] { // cmd.Find is too lenient
497+
return ActionCommands(subCommand).Shift(1)
498+
}
499+
}
500+
}
501+
return ActionMessage("unknown subcommand %#v for %#v", c.Args[0], cmd.Name())
502+
}
503+
504+
batch := Batch()
505+
for _, subcommand := range cmd.Commands() {
506+
if (!subcommand.Hidden || env.Hidden()) && subcommand.Deprecated == "" {
507+
group := common.Group{Cmd: subcommand}
508+
batch = append(batch, ActionStyledValuesDescribed(subcommand.Name(), subcommand.Short, group.Style()).Tag(group.Tag()))
509+
for _, alias := range subcommand.Aliases {
510+
batch = append(batch, ActionStyledValuesDescribed(alias, subcommand.Short, group.Style()).Tag(group.Tag()))
511+
}
512+
}
513+
}
514+
return batch.ToA()
515+
})
516+
}

docs/src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
- [ToMultiPartsA](./carapace/invokedAction/toMultiPartsA.md)
5656
- [DefaultActions](./carapace/defaultActions.md)
5757
- [ActionCallback](./carapace/defaultActions/actionCallback.md)
58+
- [ActionCommands](./carapace/defaultActions/actionCommands.md)
5859
- [ActionDirectories](./carapace/defaultActions/actionDirectories.md)
5960
- [ActionExecCommand](./carapace/defaultActions/actionExecCommand.md)
6061
- [ActionExecCommandE](./carapace/defaultActions/actionExecCommandE.md)

docs/src/carapace/defaultActions/actionCommands.cast

Lines changed: 92 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# ActionCommands
2+
3+
[`ActionCommands`] completes (sub)commands of given command.
4+
5+
> `Context.Args` is used to traverse the command tree further down.
6+
> Use [Shift](../action/shift.md) to avoid this.
7+
8+
9+
```go
10+
carapace.Gen(helpCmd).PositionalAnyCompletion(
11+
carapace.ActionCommands(cmd),
12+
)
13+
```
14+
15+
![](./actionCommands.cast)
16+
17+
[`ActionCommands`]:https://pkg.go.dev/github.com/rsteube/carapace#ActionCommands

example/cmd/action.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ func init() {
2121
rootCmd.AddCommand(actionCmd)
2222

2323
actionCmd.Flags().String("callback", "", "ActionCallback()")
24+
actionCmd.Flags().String("commands", "", "ActionCommands()")
2425
actionCmd.Flags().String("directories", "", "ActionDirectories()")
2526
actionCmd.Flags().String("execcommand", "", "ActionExecCommand()")
2627
actionCmd.Flags().String("execcommandE", "", "ActionExecCommand()")
@@ -48,6 +49,7 @@ func init() {
4849
}
4950
return carapace.ActionMessage("values flag is not set")
5051
}),
52+
"commands": carapace.ActionCommands(rootCmd).Split(),
5153
"directories": carapace.ActionDirectories(),
5254
"execcommand": carapace.ActionExecCommand("git", "remote")(func(output []byte) carapace.Action {
5355
lines := strings.Split(string(output), "\n")

example/cmd/action_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,44 @@ func TestAction(t *testing.T) {
2424
Expect(carapace.ActionMessage("values flag is not set").
2525
Usage("ActionCallback()"))
2626

27+
s.Run("action", "--commands", "s").
28+
Expect(carapace.ActionValuesDescribed(
29+
"special", "",
30+
"subcommand", "subcommand example",
31+
).Suffix(" ").
32+
NoSpace().
33+
Tag("other commands").
34+
Usage("ActionCommands()"))
35+
36+
s.Run("action", "--commands", "subcommand ").
37+
Expect(carapace.Batch(
38+
carapace.ActionValuesDescribed(
39+
"a1", "subcommand with alias",
40+
"a2", "subcommand with alias",
41+
"alias", "subcommand with alias",
42+
).Tag("other commands"),
43+
carapace.ActionValuesDescribed(
44+
"group", "subcommand with group",
45+
).Style(style.Blue).Tag("group commands"),
46+
).ToA().
47+
Prefix("subcommand ").
48+
Suffix(" ").
49+
NoSpace().
50+
Usage("ActionCommands()"))
51+
52+
s.Run("action", "--commands", "subcommand unknown ").
53+
Expect(carapace.ActionMessage(`unknown subcommand "unknown" for "subcommand"`).NoSpace().
54+
Usage("ActionCommands()"))
55+
56+
s.Run("action", "--commands", "subcommand hidden ").
57+
Expect(carapace.ActionValuesDescribed(
58+
"visible", "visible subcommand of a hidden command",
59+
).Prefix("subcommand hidden ").
60+
Suffix(" ").
61+
NoSpace().
62+
Tag("commands").
63+
Usage("ActionCommands()"))
64+
2765
s.Run("action", "--values", "first", "--callback", "").
2866
Expect(carapace.ActionMessage("values flag is set to: 'first'").
2967
Usage("ActionCallback()"))

example/cmd/subcommand.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package cmd
2+
3+
import (
4+
"github.com/rsteube/carapace"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
var subcommandCmd = &cobra.Command{
9+
Use: "subcommand",
10+
Short: "subcommand example",
11+
Run: func(cmd *cobra.Command, args []string) {},
12+
}
13+
14+
func init() {
15+
carapace.Gen(subcommandCmd).Standalone()
16+
17+
subcommandCmd.AddGroup(
18+
&cobra.Group{ID: "group", Title: ""},
19+
)
20+
21+
rootCmd.AddCommand(subcommandCmd)
22+
}

example/cmd/subcommand_alias.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package cmd
2+
3+
import (
4+
"github.com/rsteube/carapace"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
var subcommand_aliasCmd = &cobra.Command{
9+
Use: "alias",
10+
Short: "subcommand with alias",
11+
Aliases: []string{"a1", "a2"},
12+
Run: func(cmd *cobra.Command, args []string) {},
13+
}
14+
15+
func init() {
16+
carapace.Gen(subcommand_aliasCmd).Standalone()
17+
18+
subcommandCmd.AddCommand(subcommand_aliasCmd)
19+
}

example/cmd/subcommand_group.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package cmd
2+
3+
import (
4+
"github.com/rsteube/carapace"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
var subcommand_groupCmd = &cobra.Command{
9+
Use: "group",
10+
Short: "subcommand with group",
11+
GroupID: "group",
12+
Run: func(cmd *cobra.Command, args []string) {},
13+
}
14+
15+
func init() {
16+
carapace.Gen(subcommand_groupCmd).Standalone()
17+
18+
subcommandCmd.AddCommand(subcommand_groupCmd)
19+
}

example/cmd/subcommand_hidden.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package cmd
2+
3+
import (
4+
"github.com/rsteube/carapace"
5+
"github.com/spf13/cobra"
6+
)
7+
8+
var subcommand_hiddenCmd = &cobra.Command{
9+
Use: "hidden",
10+
Short: "hidden subcommand",
11+
Hidden: true,
12+
Run: func(cmd *cobra.Command, args []string) {},
13+
}
14+
15+
func init() {
16+
carapace.Gen(subcommand_hiddenCmd).Standalone()
17+
18+
subcommandCmd.AddCommand(subcommand_hiddenCmd)
19+
}

0 commit comments

Comments
 (0)