From 51cb0e0844d7cf9e4bebb97c2a972bf49dc69ae5 Mon Sep 17 00:00:00 2001 From: rsteube Date: Sun, 30 Jul 2023 21:00:59 +0200 Subject: [PATCH] ActionMultiParts: fix c.Parts for empty dividier --- defaultActions.go | 37 ++++++++++++++++++++++++++++------ example/cmd/action.go | 11 ++++++++++ example/cmd/multiparts.go | 9 +++++++++ example/cmd/multiparts_test.go | 29 ++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 6 deletions(-) diff --git a/defaultActions.go b/defaultActions.go index 2b66c42ed..80104ac46 100644 --- a/defaultActions.go +++ b/defaultActions.go @@ -219,20 +219,45 @@ func ActionMultiParts(sep string, callback func(c Context) Action) Action { // ActionMultiPartsN is like ActionMultiParts but limits the number of parts to `n`. func ActionMultiPartsN(sep string, n int, callback func(c Context) Action) Action { return ActionCallback(func(c Context) Action { + if n == 0 { // TODO more validation checks + return ActionMessage("invalid value for n: %v", n) + } + splitted := strings.SplitN(c.Value, sep, n) prefix := "" c.Parts = []string{} switch { case len(sep) == 0: - prefix = c.Value - c.Value = "" - case len(splitted) > 1: - c.Value = splitted[len(splitted)-1] - c.Parts = splitted[:len(splitted)-1] - prefix = strings.Join(c.Parts, sep) + sep + switch { + case n < 0: + prefix = c.Value + c.Value = "" + c.Parts = splitted + default: + prefix = c.Value + if n-1 < len(prefix) { + prefix = c.Value[:n-1] + c.Value = c.Value[n-1:] + } else { + c.Value = "" + } + c.Parts = strings.Split(prefix, "") + } + default: + if len(splitted) > 1 { + c.Value = splitted[len(splitted)-1] + c.Parts = splitted[:len(splitted)-1] + prefix = strings.Join(c.Parts, sep) + sep + } } + LOG.Println("-----") + LOG.Printf("splitted: %#v", splitted) + LOG.Printf("c.Parts: %#v", c.Parts) + LOG.Printf("c.Value: %#v", c.Value) + LOG.Printf("prefix: %#v", prefix) + nospace := '*' if runes := []rune(sep); len(runes) > 0 { nospace = runes[len(runes)-1] diff --git a/example/cmd/action.go b/example/cmd/action.go index 45852d601..4500a5b3c 100644 --- a/example/cmd/action.go +++ b/example/cmd/action.go @@ -33,6 +33,7 @@ func init() { actionCmd.Flags().String("multiparts", "", "ActionMultiParts()") actionCmd.Flags().String("multiparts-nested", "", "ActionMultiParts(...ActionMultiParts...)") actionCmd.Flags().String("multipartsn", "", "ActionMultiPartsN()") + actionCmd.Flags().String("multipartsn-empty", "", "ActionMultiPartsN()") actionCmd.Flags().String("styles", "", "ActionStyles()") actionCmd.Flags().String("styleconfig", "", "ActionStyleConfig()") actionCmd.Flags().String("styled-values", "", "ActionStyledValues()") @@ -146,6 +147,16 @@ func init() { return carapace.ActionMessage("should never happen") } }), + "multipartsn-empty": carapace.ActionMultiPartsN("", 2, func(c carapace.Context) carapace.Action { + switch len(c.Parts) { + case 0: + return carapace.ActionValues("a", "b") + case 1: + return carapace.ActionValues("c", "d", "e").UniqueList("") + default: + return carapace.ActionMessage("should never happen") + } + }), "styles": carapace.ActionStyles(), "styleconfig": carapace.ActionStyleConfig(), "styled-values": carapace.ActionStyledValues( diff --git a/example/cmd/multiparts.go b/example/cmd/multiparts.go index 8e554ed8d..aa2c5ece1 100644 --- a/example/cmd/multiparts.go +++ b/example/cmd/multiparts.go @@ -21,6 +21,7 @@ func init() { multipartsCmd.Flags().String("dotdotdot", "", "multiparts with ... as divider") multipartsCmd.Flags().String("equals", "", "multiparts with = as divider") multipartsCmd.Flags().String("none", "", "multiparts without divider") + multipartsCmd.Flags().String("none-two", "", "multiparts without divider limited to 2") multipartsCmd.Flags().String("slash", "", "multiparts with / as divider") rootCmd.AddCommand(multipartsCmd) @@ -35,6 +36,14 @@ func init() { "none": carapace.ActionMultiParts("", func(c carapace.Context) carapace.Action { return carapace.ActionValuesDescribed("a", "first", "b", "second", "c", "third", "d", "fourth").Invoke(c).Filter(c.Parts).ToA() }), + "none-two": carapace.ActionMultiPartsN("", 2, func(c carapace.Context) carapace.Action { + switch len(c.Parts) { + case 0: + return carapace.ActionValues("a", "b") + default: + return carapace.ActionValues("a", "b", "c", "d").UniqueList("") + } + }), "slash": actionMultipartsTest("/"), }) diff --git a/example/cmd/multiparts_test.go b/example/cmd/multiparts_test.go index b24b9d132..9bafb9c5e 100644 --- a/example/cmd/multiparts_test.go +++ b/example/cmd/multiparts_test.go @@ -8,6 +8,7 @@ import ( "github.com/rsteube/carapace/pkg/style" ) +// TODO rename func TestMultiparts(t *testing.T) { sandbox.Package(t, "github.com/rsteube/carapace/example")(func(s *sandbox.Sandbox) { s.Files( @@ -75,5 +76,33 @@ func TestMultiparts(t *testing.T) { StyleF(style.ForPath). Prefix("VALUE=one,FILE="). NoSpace(',', '/', '=')) + + s.Run("multiparts", "--none-two", ""). + Expect(carapace.ActionValues("a", "b"). + NoSpace(). + Usage("multiparts without divider limited to 2")) + + s.Run("multiparts", "--none-two", ""). + Expect(carapace.ActionValues("a", "b"). + NoSpace(). + Usage("multiparts without divider limited to 2")) + + s.Run("multiparts", "--none-two", "a"). + Expect(carapace.ActionValues("a", "b", "c", "d"). + Prefix("a"). + NoSpace(). + Usage("multiparts without divider limited to 2")) + + s.Run("multiparts", "--none-two", "ab"). + Expect(carapace.ActionValues("a", "c", "d"). + Prefix("ab"). + NoSpace(). + Usage("multiparts without divider limited to 2")) + + s.Run("multiparts", "--none-two", "abc"). + Expect(carapace.ActionValues("a", "d"). + Prefix("abc"). + NoSpace(). + Usage("multiparts without divider limited to 2")) }) }