diff --git a/action.go b/action.go index 83e057c2b..ca7ee4263 100644 --- a/action.go +++ b/action.go @@ -110,7 +110,7 @@ func (a Action) StyleF(f func(s string) string) Action { return ActionCallback(func(c Context) Action { invoked := a.Invoke(c) for index, v := range invoked.rawValues { - if v.Value != "ERR" && v.Value != "_" { + if !v.IsMessage() { invoked.rawValues[index].Style = f(v.Value) } } @@ -118,6 +118,32 @@ func (a Action) StyleF(f func(s string) string) Action { }) } +// Tag sets the tag. +// +// ActionValues("192.168.1.1", "127.0.0.1").Tag("interfaces"). +func (a Action) Tag(tag string) Action { + return a.TagF(func(value string) string { + return tag + }) +} + +// Tag sets the tag using a function. +// +// ActionValues("192.168.1.1", "127.0.0.1").TagF(func(value string) string { +// return "interfaces" +// }) +func (a Action) TagF(f func(value string) string) Action { + return ActionCallback(func(c Context) Action { + invoked := a.Invoke(c) + for index, v := range invoked.rawValues { + if !v.IsMessage() { + invoked.rawValues[index].Tag = f(v.Value) + } + } + return invoked.ToA() + }) +} + // Chdir changes the current working directory to the named directory during invocation. func (a Action) Chdir(dir string) Action { return ActionCallback(func(c Context) Action { @@ -136,7 +162,7 @@ func (a Action) Suppress(expr ...string) Action { invoked := a.Invoke(c) filter := false for _, rawValue := range invoked.rawValues { - if rawValue.Display == "ERR" { + if rawValue.IsMessage() && rawValue.Description != "" { for _, e := range expr { r, err := regexp.Compile(e) if err != nil { @@ -153,7 +179,7 @@ func (a Action) Suppress(expr ...string) Action { if filter { filtered := make([]common.RawValue, 0) for _, r := range invoked.rawValues { - if r.Display != "ERR" && r.Display != "_" { + if !r.IsMessage() { filtered = append(filtered, r) } } diff --git a/defaultActions_test.go b/defaultActions_test.go index 4cb069183..77538e430 100644 --- a/defaultActions_test.go +++ b/defaultActions_test.go @@ -17,17 +17,19 @@ func TestActionImport(t *testing.T) { "Value": "positional1", "Display": "positional1", "Description": "", - "Style": "" + "Style": "", + "Tag": "first" }, { "Value": "p1", "Display": "p1", "Description": "", - "Style": "" + "Style": "", + "Tag": "first" } ] }` - assertEqual(t, ActionValues("positional1", "p1").Invoke(Context{}), ActionImport([]byte(s)).Invoke(Context{})) + assertEqual(t, ActionValues("positional1", "p1").Tag("first").Invoke(Context{}), ActionImport([]byte(s)).Invoke(Context{})) } func TestActionFlags(t *testing.T) { diff --git a/example/cmd/action/os/os.go b/example/cmd/action/os/os.go index e655b96f7..00eac3bef 100644 --- a/example/cmd/action/os/os.go +++ b/example/cmd/action/os/os.go @@ -38,7 +38,7 @@ func ActionGroups() carapace.Action { } } return carapace.ActionValuesDescribed(groups...) - }) + }).Tag("groups") } // ActionKillSignals completes kill signals @@ -110,7 +110,7 @@ func ActionUsers() carapace.Action { } } return carapace.ActionValuesDescribed(users...) - }) + }).Tag("users") } // ActionUserGroup completes user:group diff --git a/example/cmd/batch.go b/example/cmd/batch.go index a2ac83ff4..d6a1e9168 100644 --- a/example/cmd/batch.go +++ b/example/cmd/batch.go @@ -17,9 +17,9 @@ func init() { carapace.Gen(batchCmd).PositionalCompletion( carapace.ActionCallback(func(c carapace.Context) carapace.Action { return carapace.Batch( - carapace.ActionValues("A", "B"), - carapace.ActionValues("C", "D"), - carapace.ActionValues("E", "F"), + carapace.ActionValues("A", "B").Tag("first"), + carapace.ActionValues("C", "D").Tag("second"), + carapace.ActionValues("E", "F").TagF(func(value string) string { return "third" }), ).Invoke(c).Merge().ToA() }), ) diff --git a/internal/common/value.go b/internal/common/value.go index 10158bea5..57c7a2201 100644 --- a/internal/common/value.go +++ b/internal/common/value.go @@ -11,8 +11,14 @@ import ( type RawValue struct { Value string Display string - Description string - Style string + Description string `json:",omitempty"` + Style string `json:",omitempty"` + Tag string `json:",omitempty"` +} + +// IsMessage checks if the value is a message (ActionMessage) +func (r RawValue) IsMessage() bool { + return r.Value == "ERR" || r.Value == "_" } // TrimmedDescription returns the trimmed description diff --git a/invokedAction_test.go b/invokedAction_test.go index d02d2884d..db36ee0db 100644 --- a/invokedAction_test.go +++ b/invokedAction_test.go @@ -28,15 +28,15 @@ func TestToMultiParts(t *testing.T) { _test("A/a:1", `{"Value":"A/a:1","Display":"1","Description":"one","Style":"green"}`, "/", ":") _test("A/a:1", `{"Value":"A/a:1","Display":"1","Description":"one","Style":"green"}`, ":", "/") _test("A/a:1", `{"Value":"A/a:1","Display":"a:1","Description":"one","Style":"green"}`, "/") - _test("A", `{"Value":"A/","Display":"A/","Description":"","Style":""}`, "/", ":") - _test("A", `{"Value":"A/","Display":"A/","Description":"","Style":""}`, "/") - _test("", `{"Value":"A/","Display":"A/","Description":"","Style":""}`, "/") - _test("A/", `{"Value":"A/a:","Display":"a:","Description":"","Style":""}`, "/", ":") + _test("A", `{"Value":"A/","Display":"A/"}`, "/", ":") + _test("A", `{"Value":"A/","Display":"A/"}`, "/") + _test("", `{"Value":"A/","Display":"A/"}`, "/") + _test("A/", `{"Value":"A/a:","Display":"a:"}`, "/", ":") _test("A/", `{"Value":"A/a:1","Display":"a:1","Description":"one","Style":"green"}`, "/") _test("B/", `{"Value":"B/c/","Display":"c/","Description":"withsuffix","Style":"underlined"}`, "/") - _test("B/c:5", `{"Value":"B/c:5:2/","Display":"c:5:2/","Description":"","Style":""}`, "/") - _test("B/c:5", `{"Value":"B/c:5:","Display":"5:","Description":"","Style":""}`, "/", ":") - _test("B/c:5", `{"Value":"B/c:5:","Display":"5:","Description":"","Style":""}`, ":", "/") + _test("B/c:5", `{"Value":"B/c:5:2/","Display":"c:5:2/"}`, "/") + _test("B/c:5", `{"Value":"B/c:5:","Display":"5:"}`, "/", ":") + _test("B/c:5", `{"Value":"B/c:5:","Display":"5:"}`, ":", "/") _test("C/d/1", `{"Value":"C/d/1()2","Display":"1()2","Description":"withbrackets","Style":"yellow"}`, "/") }