From bd8a4e79a7254f2bbb08327b09c877f84724c72d Mon Sep 17 00:00:00 2001 From: matryer Date: Fri, 19 Mar 2021 10:09:18 +0000 Subject: [PATCH] supported nesting with separators - addresses #648 --- pkg/plugins/parse.go | 34 +++++++++++++++++++++----- pkg/plugins/parse_test.go | 51 +++++++++++++++++++++++++++++++++------ 2 files changed, 72 insertions(+), 13 deletions(-) diff --git a/pkg/plugins/parse.go b/pkg/plugins/parse.go index 82b033490..5118cbfea 100644 --- a/pkg/plugins/parse.go +++ b/pkg/plugins/parse.go @@ -9,6 +9,11 @@ import ( "github.com/pkg/errors" ) +const ( + nesting = "--" + separator = "---" +) + // parseOutput parses the output of a plugin run, and returns the // Items. func (p *Plugin) parseOutput(ctx context.Context, filename string, r io.Reader) (Items, error) { @@ -49,28 +54,31 @@ func (p *Plugin) parseOutput(ctx context.Context, filename string, r io.Reader) err: err, } } - if !captureExpanded && strings.TrimSpace(text) == "---" { + if !captureExpanded && strings.TrimSpace(text) == separator { // first --- means end of cycle items, // start collecting expanded items now captureExpanded = true continue } + + text, isSeparator := parseSeparator(text) + for !strings.HasPrefix(text, depthPrefix) { // drop a level ancestorItems = ancestorItems[:len(ancestorItems)-1] - depthPrefix = strings.TrimPrefix(depthPrefix, "--") + depthPrefix = strings.TrimPrefix(depthPrefix, nesting) } - if strings.HasPrefix(text, depthPrefix+"--") { + if strings.HasPrefix(text, depthPrefix+nesting) { // if this is a separator in the submenu, // then don't treat it as a another submenu. - if strings.TrimPrefix(text, depthPrefix) != "---" { + if strings.TrimPrefix(text, depthPrefix) != separator { // increase a level ancestorItems = append(ancestorItems, previousItem) - depthPrefix += "--" + depthPrefix += nesting } } text = strings.TrimPrefix(text, depthPrefix) - if captureExpanded && strings.TrimSpace(text) == "---" { + if captureExpanded && isSeparator { params.Separator = true separatorItem := &Item{ Plugin: p, @@ -119,3 +127,17 @@ func (p *Plugin) parseOutput(ctx context.Context, filename string, r io.Reader) } return items, nil } + +func parseSeparator(src string) (string, bool) { + text := strings.TrimSpace(src) + if text == separator { + return "", true + } + for strings.HasPrefix(text, nesting) { + text = strings.TrimPrefix(text, nesting) + if text == separator { + return src[:len(src)-3], true + } + } + return src, false +} diff --git a/pkg/plugins/parse_test.go b/pkg/plugins/parse_test.go index ef149256e..71d069e90 100644 --- a/pkg/plugins/parse_test.go +++ b/pkg/plugins/parse_test.go @@ -165,22 +165,59 @@ b ----e ------- ----f +----- +--g --- -g` +h` + p := &Plugin{} items, err := p.parseOutput(context.Background(), "nesting.txt", strings.NewReader(src)) is.NoErr(err) - is.Equal(len(items.ExpandedItems), 2) + is.Equal(len(items.ExpandedItems), 3) + + // root items is.Equal(items.ExpandedItems[0].Text, "b") - is.Equal(len(items.ExpandedItems[0].Items), 4) + is.Equal(items.ExpandedItems[1].Params.Separator, true) + is.Equal(items.ExpandedItems[2].Text, "h") + + // b submenu + is.Equal(len(items.ExpandedItems[0].Items), 5) is.Equal(items.ExpandedItems[0].Items[0].Text, "c") is.Equal(items.ExpandedItems[0].Items[1].Params.Separator, true) // should be separator is.Equal(items.ExpandedItems[0].Items[2].Text, "d") + is.Equal(items.ExpandedItems[0].Items[3].Params.Separator, true) + is.Equal(items.ExpandedItems[0].Items[4].Text, "g") + + // d submenu + is.Equal(len(items.ExpandedItems[0].Items[2].Items), 3) + is.Equal(items.ExpandedItems[0].Items[2].Items[0].Text, "e") + is.Equal(items.ExpandedItems[0].Items[2].Items[1].Params.Separator, true) + is.Equal(items.ExpandedItems[0].Items[2].Items[2].Text, "f") + +} + +func TestParseSeparator(t *testing.T) { + is := is.New(t) + + text, isSep := parseSeparator("no") + is.Equal(isSep, false) + is.Equal(text, "no") + + text, isSep = parseSeparator(separator) + is.Equal(isSep, true) + is.Equal(text, "") + + text, isSep = parseSeparator(nesting + separator) + is.Equal(isSep, true) + is.Equal(text, nesting) + + text, isSep = parseSeparator(nesting + nesting + separator) + is.Equal(isSep, true) + is.Equal(text, nesting+nesting) - // is.Equal(len(items.ExpandedItems[0].Items[2].Items), 3) - // is.Equal(items.ExpandedItems[0].Items[2].Items[0].Text, "e") - // is.Equal(items.ExpandedItems[0].Items[2].Items[1].Params.Separator, true) - // is.Equal(items.ExpandedItems[0].Items[2].Items[2].Text, "f") + text, isSep = parseSeparator(nesting + nesting + "item") + is.Equal(isSep, false) + is.Equal(text, nesting+nesting+"item") }