From 287e3489fde52a08b82c18e224e411a73f3911ca Mon Sep 17 00:00:00 2001 From: rsteube Date: Thu, 11 Jan 2024 00:58:02 +0100 Subject: [PATCH] InvokedAction: private composition --- action.go | 38 ++++++++++++++--------------- action_test.go | 24 +++++++++---------- compat.go | 8 +++---- invokedAction.go | 62 ++++++++++++++++++++++++------------------------ storage.go | 8 +++---- 5 files changed, 70 insertions(+), 70 deletions(-) diff --git a/action.go b/action.go index 865e9a79f..d428ff807 100644 --- a/action.go +++ b/action.go @@ -46,7 +46,7 @@ func (a Action) Cache(timeout time.Duration, keys ...pkgcache.Key) Action { } invokedAction := (Action{callback: cachedCallback}).Invoke(c) - if invokedAction.meta.Messages.IsEmpty() { + if invokedAction.action.meta.Messages.IsEmpty() { if cacheFile, err := cache.File(file, line, keys...); err == nil { // regenerate as cache keys might have changed due to invocation _ = cache.Write(cacheFile, invokedAction.export()) } @@ -122,7 +122,7 @@ func (a Action) Invoke(c Context) InvokedAction { if a.rawValues == nil && a.callback != nil { result := a.callback(c).Invoke(c) - result.meta.Merge(a.meta) + result.action.meta.Merge(a.meta) return result } return InvokedAction{a} @@ -154,7 +154,7 @@ func (a Action) MultiPartsP(delimiter string, pattern string, f func(placeholder staticMatches := make(map[int]bool) path: - for index, value := range invoked.rawValues { + for index, value := range invoked.action.rawValues { segments := strings.Split(value.Value, delimiter) segment: for index, segment := range segments { @@ -185,7 +185,7 @@ func (a Action) MultiPartsP(delimiter string, pattern string, f func(placeholder // store segment as path matched so far and this is currently being completed if len(segments) == (len(c.Parts) + 1) { - matchedSegments[segments[len(c.Parts)]] = invoked.rawValues[index] + matchedSegments[segments[len(c.Parts)]] = invoked.action.rawValues[index] } else { matchedSegments[segments[len(c.Parts)]+delimiter] = common.RawValue{} } @@ -200,8 +200,8 @@ func (a Action) MultiPartsP(delimiter string, pattern string, f func(placeholder } actions = append(actions, ActionCallback(func(c Context) Action { invoked := f(trimmedKey, matchedData).Invoke(c).Suffix(suffix) - for index := range invoked.rawValues { - invoked.rawValues[index].Display += suffix + for index := range invoked.action.rawValues { + invoked.action.rawValues[index].Display += suffix } return invoked.ToA() })) @@ -211,7 +211,7 @@ func (a Action) MultiPartsP(delimiter string, pattern string, f func(placeholder } a := Batch(actions...).ToA() - a.meta.Merge(invoked.meta) + a.meta.Merge(invoked.action.meta) return a }) }) @@ -310,19 +310,19 @@ func (a Action) split(pipelines bool) Action { } invoked := a.Invoke(c) - for index, value := range invoked.rawValues { - if !invoked.meta.Nospace.Matches(value.Value) || strings.Contains(value.Value, " ") { // TODO special characters + for index, value := range invoked.action.rawValues { + if !invoked.action.meta.Nospace.Matches(value.Value) || strings.Contains(value.Value, " ") { // TODO special characters switch tokens.CurrentToken().State { case shlex.QUOTING_ESCAPING_STATE: - invoked.rawValues[index].Value = fmt.Sprintf(`"%v"`, strings.ReplaceAll(value.Value, `"`, `\"`)) + invoked.action.rawValues[index].Value = fmt.Sprintf(`"%v"`, strings.ReplaceAll(value.Value, `"`, `\"`)) case shlex.QUOTING_STATE: - invoked.rawValues[index].Value = fmt.Sprintf(`'%v'`, strings.ReplaceAll(value.Value, `'`, `'"'"'`)) + invoked.action.rawValues[index].Value = fmt.Sprintf(`'%v'`, strings.ReplaceAll(value.Value, `'`, `'"'"'`)) default: - invoked.rawValues[index].Value = strings.Replace(value.Value, ` `, `\ `, -1) + invoked.action.rawValues[index].Value = strings.Replace(value.Value, ` `, `\ `, -1) } } - if !invoked.meta.Nospace.Matches(value.Value) { - invoked.rawValues[index].Value += " " + if !invoked.action.meta.Nospace.Matches(value.Value) { + invoked.action.rawValues[index].Value += " " } } return invoked.Prefix(prefix).ToA().NoSpace() @@ -346,8 +346,8 @@ func (a Action) Style(s string) Action { func (a Action) StyleF(f func(s string, sc style.Context) string) Action { return ActionCallback(func(c Context) Action { invoked := a.Invoke(c) - for index, v := range invoked.rawValues { - invoked.rawValues[index].Style = f(v.Value, c) + for index, v := range invoked.action.rawValues { + invoked.action.rawValues[index].Style = f(v.Value, c) } return invoked.ToA() }) @@ -379,7 +379,7 @@ func (a Action) Suffix(suffix string) Action { func (a Action) Suppress(expr ...string) Action { return ActionCallback(func(c Context) Action { invoked := a.Invoke(c) - if err := invoked.meta.Messages.Suppress(expr...); err != nil { + if err := invoked.action.meta.Messages.Suppress(expr...); err != nil { return ActionMessage(err.Error()) } return invoked.ToA() @@ -403,8 +403,8 @@ func (a Action) Tag(tag string) Action { func (a Action) TagF(f func(s string) string) Action { return ActionCallback(func(c Context) Action { invoked := a.Invoke(c) - for index, v := range invoked.rawValues { - invoked.rawValues[index].Tag = f(v.Value) + for index, v := range invoked.action.rawValues { + invoked.action.rawValues[index].Tag = f(v.Value) } return invoked.ToA() }) diff --git a/action_test.go b/action_test.go index 1c67c56fc..0cd9f7c99 100644 --- a/action_test.go +++ b/action_test.go @@ -18,24 +18,24 @@ func init() { } func assertEqual(t *testing.T, expected, actual InvokedAction) { - sort.Sort(common.ByValue(expected.rawValues)) - sort.Sort(common.ByValue(actual.rawValues)) + sort.Sort(common.ByValue(expected.action.rawValues)) + sort.Sort(common.ByValue(actual.action.rawValues)) - e, _ := json.MarshalIndent(expected.rawValues, "", " ") - a, _ := json.MarshalIndent(actual.rawValues, "", " ") + e, _ := json.MarshalIndent(expected.action.rawValues, "", " ") + a, _ := json.MarshalIndent(actual.action.rawValues, "", " ") assert.Equal(t, string(e), string(a)) - eMeta, _ := json.MarshalIndent(expected.meta, "", " ") - aMeta, _ := json.MarshalIndent(actual.meta, "", " ") + eMeta, _ := json.MarshalIndent(expected.action.meta, "", " ") + aMeta, _ := json.MarshalIndent(actual.action.meta, "", " ") assert.Equal(t, string(eMeta), string(aMeta)) } func assertNotEqual(t *testing.T, expected, actual InvokedAction) { - sort.Sort(common.ByValue(expected.rawValues)) - sort.Sort(common.ByValue(actual.rawValues)) + sort.Sort(common.ByValue(expected.action.rawValues)) + sort.Sort(common.ByValue(actual.action.rawValues)) - e, _ := json.MarshalIndent(expected.rawValues, "", " ") - a, _ := json.MarshalIndent(actual.rawValues, "", " ") + e, _ := json.MarshalIndent(expected.action.rawValues, "", " ") + a, _ := json.MarshalIndent(actual.action.rawValues, "", " ") if string(e) == string(a) { t.Errorf("should differ:\n%v", a) @@ -89,7 +89,7 @@ func TestSkipCache(t *testing.T) { if !a.meta.Messages.IsEmpty() { t.Fatal("uninvoked action should not contain messages") } - if a.Invoke(Context{}).meta.Messages.IsEmpty() { + if a.Invoke(Context{}).action.meta.Messages.IsEmpty() { t.Fatal("invoked action should contain messages") } } @@ -108,7 +108,7 @@ func TestNoSpace(t *testing.T) { if a.meta.Nospace.Matches("x") { t.Fatal("uninvoked nospace should not match") } - if !a.Invoke(Context{}).meta.Nospace.Matches("x") { + if !a.Invoke(Context{}).action.meta.Nospace.Matches("x") { t.Fatal("invoked nospace should match") } } diff --git a/compat.go b/compat.go index 3568c407a..6321e2c60 100644 --- a/compat.go +++ b/compat.go @@ -41,8 +41,8 @@ func registerFlagCompletion(cmd *cobra.Command) { } func cobraValuesFor(action InvokedAction) []string { - result := make([]string, len(action.rawValues)) - for index, r := range action.rawValues { + result := make([]string, len(action.action.rawValues)) + for index, r := range action.action.rawValues { if r.Description != "" { result[index] = fmt.Sprintf("%v\t%v", r.Value, r.Description) } else { @@ -54,8 +54,8 @@ func cobraValuesFor(action InvokedAction) []string { func cobraDirectiveFor(action InvokedAction) cobra.ShellCompDirective { directive := cobra.ShellCompDirectiveNoFileComp - for _, val := range action.rawValues { - if action.meta.Nospace.Matches(val.Value) { + for _, val := range action.action.rawValues { + if action.action.meta.Nospace.Matches(val.Value) { directive = directive | cobra.ShellCompDirectiveNoSpace break } diff --git a/invokedAction.go b/invokedAction.go index e99c6e634..922139280 100644 --- a/invokedAction.go +++ b/invokedAction.go @@ -11,20 +11,20 @@ import ( // InvokedAction is a logical alias for an Action whose (nested) callback was invoked. type InvokedAction struct { - Action + action Action } -func (a InvokedAction) export() export.Export { - return export.Export{Meta: a.meta, Values: a.rawValues} +func (ia InvokedAction) export() export.Export { + return export.Export{Meta: ia.action.meta, Values: ia.action.rawValues} } // Filter filters given values. // // a := carapace.ActionValues("A", "B", "C").Invoke(c) // b := a.Filter([]string{"B"}) // ["A", "C"] -func (a InvokedAction) Filter(values ...string) InvokedAction { - a.rawValues = a.rawValues.Filter(values...) - return a +func (ia InvokedAction) Filter(values ...string) InvokedAction { + ia.action.rawValues = ia.action.rawValues.Filter(values...) + return ia } // Merge merges InvokedActions (existing values are overwritten) @@ -32,47 +32,47 @@ func (a InvokedAction) Filter(values ...string) InvokedAction { // a := carapace.ActionValues("A", "B").Invoke(c) // b := carapace.ActionValues("B", "C").Invoke(c) // c := a.Merge(b) // ["A", "B", "C"] -func (a InvokedAction) Merge(others ...InvokedAction) InvokedAction { - for _, other := range append([]InvokedAction{a}, others...) { - a.rawValues = append(a.rawValues, other.rawValues...) - a.meta.Merge(other.meta) +func (ia InvokedAction) Merge(others ...InvokedAction) InvokedAction { + for _, other := range append([]InvokedAction{ia}, others...) { + ia.action.rawValues = append(ia.action.rawValues, other.action.rawValues...) + ia.action.meta.Merge(other.action.meta) } - a.rawValues = a.rawValues.Unique() - return a + ia.action.rawValues = ia.action.rawValues.Unique() + return ia } // Prefix adds a prefix to values (only the ones inserted, not the display values) // // carapace.ActionValues("melon", "drop", "fall").Invoke(c).Prefix("water") -func (a InvokedAction) Prefix(prefix string) InvokedAction { - for index, val := range a.rawValues { - a.rawValues[index].Value = prefix + val.Value +func (ia InvokedAction) Prefix(prefix string) InvokedAction { + for index, val := range ia.action.rawValues { + ia.action.rawValues[index].Value = prefix + val.Value } - return a + return ia } // Retain retains given values. // // a := carapace.ActionValues("A", "B", "C").Invoke(c) // b := a.Retain([]string{"A", "C"}) // ["A", "C"] -func (a InvokedAction) Retain(values ...string) InvokedAction { - a.rawValues = a.rawValues.Retain(values...) - return a +func (ia InvokedAction) Retain(values ...string) InvokedAction { + ia.action.rawValues = ia.action.rawValues.Retain(values...) + return ia } // Suffix adds a suffx to values (only the ones inserted, not the display values) // // carapace.ActionValues("apple", "melon", "orange").Invoke(c).Suffix("juice") -func (a InvokedAction) Suffix(suffix string) InvokedAction { - for index, val := range a.rawValues { - a.rawValues[index].Value = val.Value + suffix +func (ia InvokedAction) Suffix(suffix string) InvokedAction { + for index, val := range ia.action.rawValues { + ia.action.rawValues[index].Value = val.Value + suffix } - return a + return ia } // ToA casts an InvokedAction to Action. -func (a InvokedAction) ToA() Action { - return a.Action +func (ia InvokedAction) ToA() Action { + return ia.action } func tokenize(s string, dividers ...string) []string { @@ -95,12 +95,12 @@ func tokenize(s string, dividers ...string) []string { // // a := carapace.ActionValues("A/B/C", "A/C", "B/C", "C").Invoke(c) // b := a.ToMultiPartsA("/") // completes segments separately (first one is ["A/", "B/", "C"]) -func (a InvokedAction) ToMultiPartsA(dividers ...string) Action { +func (ia InvokedAction) ToMultiPartsA(dividers ...string) Action { return ActionCallback(func(c Context) Action { splittedCV := tokenize(c.Value, dividers...) uniqueVals := make(map[string]common.RawValue) - for _, val := range a.rawValues { + for _, val := range ia.action.rawValues { if match.HasPrefix(val.Value, c.Value) { if splitted := tokenize(val.Value, dividers...); len(splitted) >= len(splittedCV) { v := strings.Join(splitted[:len(splittedCV)], "") @@ -145,14 +145,14 @@ func (a InvokedAction) ToMultiPartsA(dividers ...string) Action { }) } -func (a InvokedAction) value(shell string, value string) string { - return _shell.Value(shell, value, a.meta, a.rawValues) +func (ia InvokedAction) value(shell string, value string) string { + return _shell.Value(shell, value, ia.action.meta, ia.action.rawValues) } func init() { common.FromInvokedAction = func(i interface{}) (common.Meta, common.RawValues) { - if a, ok := i.(InvokedAction); ok { - return a.meta, a.rawValues + if invoked, ok := i.(InvokedAction); ok { + return invoked.action.meta, invoked.action.rawValues } return common.Meta{}, nil } diff --git a/storage.go b/storage.go index b937885e2..e1106a487 100644 --- a/storage.go +++ b/storage.go @@ -103,8 +103,8 @@ func (s _storage) getFlag(cmd *cobra.Command, name string) Action { return ActionCallback(func(c Context) Action { // TODO verify order of execution is correct invoked := a.Invoke(c) - if invoked.meta.Usage == "" { - invoked.meta.Usage = flag.Usage + if invoked.action.meta.Usage == "" { + invoked.action.meta.Usage = flag.Usage } return invoked.ToA() }) @@ -177,8 +177,8 @@ func (s _storage) getPositional(cmd *cobra.Command, index int) Action { return ActionCallback(func(c Context) Action { invoked := a.Invoke(c) - if invoked.meta.Usage == "" && len(strings.Fields(cmd.Use)) > 1 { - invoked.meta.Usage = cmd.Use + if invoked.action.meta.Usage == "" && len(strings.Fields(cmd.Use)) > 1 { + invoked.action.meta.Usage = cmd.Use } return invoked.ToA() })