diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2023-05-29 22:52:16 +1000 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2023-05-29 22:52:16 +1000 |
commit | 1de876ed4d1e5f95b70e109c2f05f722ef88b46e (patch) | |
tree | 20d6334398688b7da5e9d623bc29cb4795498d20 /pkg/gui/services | |
parent | 036a1ea519885ae9962c0ba2d90f642874cabd89 (diff) |
Support using command output directly in menuFromCommand custom command prompt
The menuFromCommand option is a little complicated, so I'm adding an easy way to just use the command output directly,
where each line becomes a suggestion, as-is.
Now that we support suggestions in the input prompt, there's less of a need for menuFromCommand, but it probably still
serves some purpose.
In future I want to support this filter/valueFormat/labelFormat thing for suggestions too. I would like to think a little more
about the interface though: is using a regex like we currently do really the simplest approach?
Diffstat (limited to 'pkg/gui/services')
-rw-r--r-- | pkg/gui/services/custom_commands/handler_creator.go | 2 | ||||
-rw-r--r-- | pkg/gui/services/custom_commands/menu_generator.go | 57 | ||||
-rw-r--r-- | pkg/gui/services/custom_commands/menu_generator_test.go | 32 |
3 files changed, 66 insertions, 25 deletions
diff --git a/pkg/gui/services/custom_commands/handler_creator.go b/pkg/gui/services/custom_commands/handler_creator.go index 8e6700f72..4dc6bc86e 100644 --- a/pkg/gui/services/custom_commands/handler_creator.go +++ b/pkg/gui/services/custom_commands/handler_creator.go @@ -210,7 +210,7 @@ func (self *HandlerCreator) menuPromptFromCommand(prompt *config.CustomCommandPr return self.c.Error(err) } - menuItems := slices.Map(candidates, func(candidate *commandMenuEntry) *types.MenuItem { + menuItems := slices.Map(candidates, func(candidate *commandMenuItem) *types.MenuItem { return &types.MenuItem{ LabelColumns: []string{candidate.label}, OnPress: func() error { diff --git a/pkg/gui/services/custom_commands/menu_generator.go b/pkg/gui/services/custom_commands/menu_generator.go index 5bec1db91..4a73fe433 100644 --- a/pkg/gui/services/custom_commands/menu_generator.go +++ b/pkg/gui/services/custom_commands/menu_generator.go @@ -22,12 +22,41 @@ func NewMenuGenerator(c *common.Common) *MenuGenerator { return &MenuGenerator{c: c} } -type commandMenuEntry struct { +type commandMenuItem struct { label string value string } -func (self *MenuGenerator) call(commandOutput, filter, valueFormat, labelFormat string) ([]*commandMenuEntry, error) { +func (self *MenuGenerator) call(commandOutput, filter, valueFormat, labelFormat string) ([]*commandMenuItem, error) { + menuItemFromLine, err := self.getMenuItemFromLinefn(filter, valueFormat, labelFormat) + if err != nil { + return nil, err + } + + menuItems := []*commandMenuItem{} + for _, line := range strings.Split(commandOutput, "\n") { + if line == "" { + continue + } + + menuItem, err := menuItemFromLine(line) + if err != nil { + return nil, err + } + menuItems = append(menuItems, menuItem) + } + + return menuItems, nil +} + +func (self *MenuGenerator) getMenuItemFromLinefn(filter string, valueFormat string, labelFormat string) (func(line string) (*commandMenuItem, error), error) { + if filter == "" && valueFormat == "" && labelFormat == "" { + // showing command output lines as-is in suggestions panel + return func(line string) (*commandMenuItem, error) { + return &commandMenuItem{label: line, value: line}, nil + }, nil + } + regex, err := regexp.Compile(filter) if err != nil { return nil, errors.New("unable to parse filter regex, error: " + err.Error()) @@ -51,37 +80,25 @@ func (self *MenuGenerator) call(commandOutput, filter, valueFormat, labelFormat labelTemplate = valueTemplate } - candidates := []*commandMenuEntry{} - for _, line := range strings.Split(commandOutput, "\n") { - if line == "" { - continue - } - - candidate, err := self.generateMenuCandidate( + return func(line string) (*commandMenuItem, error) { + return self.generateMenuItem( line, regex, valueTemplate, labelTemplate, ) - if err != nil { - return nil, err - } - - candidates = append(candidates, candidate) - } - - return candidates, err + }, nil } -func (self *MenuGenerator) generateMenuCandidate( +func (self *MenuGenerator) generateMenuItem( line string, regex *regexp.Regexp, valueTemplate *TrimmerTemplate, labelTemplate *TrimmerTemplate, -) (*commandMenuEntry, error) { +) (*commandMenuItem, error) { tmplData := self.parseLine(line, regex) - entry := &commandMenuEntry{} + entry := &commandMenuItem{} var err error entry.value, err = valueTemplate.execute(tmplData) diff --git a/pkg/gui/services/custom_commands/menu_generator_test.go b/pkg/gui/services/custom_commands/menu_generator_test.go index 7dd3e58e8..c17f7e93a 100644 --- a/pkg/gui/services/custom_commands/menu_generator_test.go +++ b/pkg/gui/services/custom_commands/menu_generator_test.go @@ -14,7 +14,7 @@ func TestMenuGenerator(t *testing.T) { filter string valueFormat string labelFormat string - test func([]*commandMenuEntry, error) + test func([]*commandMenuItem, error) } scenarios := []scenario{ @@ -24,7 +24,7 @@ func TestMenuGenerator(t *testing.T) { "(?P<remote>[a-z_]+)/(?P<branch>.*)", "{{ .branch }}", "Remote: {{ .remote }}", - func(actualEntry []*commandMenuEntry, err error) { + func(actualEntry []*commandMenuItem, err error) { assert.NoError(t, err) assert.EqualValues(t, "pr-1", actualEntry[0].value) assert.EqualValues(t, "Remote: upstream", actualEntry[0].label) @@ -36,7 +36,7 @@ func TestMenuGenerator(t *testing.T) { "(?P<remote>[a-z]*)/(?P<branch>.*)", "{{ .branch }}|{{ .remote }}", "", - func(actualEntry []*commandMenuEntry, err error) { + func(actualEntry []*commandMenuItem, err error) { assert.NoError(t, err) assert.EqualValues(t, "pr-1|upstream", actualEntry[0].value) assert.EqualValues(t, "pr-1|upstream", actualEntry[0].label) @@ -48,12 +48,36 @@ func TestMenuGenerator(t *testing.T) { "(?P<remote>[a-z]*)/(?P<branch>.*)", "{{ .group_2 }}|{{ .group_1 }}", "Remote: {{ .group_1 }}", - func(actualEntry []*commandMenuEntry, err error) { + func(actualEntry []*commandMenuItem, err error) { assert.NoError(t, err) assert.EqualValues(t, "pr-1|upstream", actualEntry[0].value) assert.EqualValues(t, "Remote: upstream", actualEntry[0].label) }, }, + { + "No named groups", + "upstream/pr-1", + "([a-z]*)/(.*)", + "{{ .group_2 }}|{{ .group_1 }}", + "Remote: {{ .group_1 }}", + func(actualEntry []*commandMenuItem, err error) { + assert.NoError(t, err) + assert.EqualValues(t, "pr-1|upstream", actualEntry[0].value) + assert.EqualValues(t, "Remote: upstream", actualEntry[0].label) + }, + }, + { + "No filter", + "upstream/pr-1", + "", + "", + "", + func(actualEntry []*commandMenuItem, err error) { + assert.NoError(t, err) + assert.EqualValues(t, "upstream/pr-1", actualEntry[0].value) + assert.EqualValues(t, "upstream/pr-1", actualEntry[0].label) + }, + }, } for _, s := range scenarios { |