summaryrefslogtreecommitdiffstats
path: root/pkg/gui/services
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2023-05-29 22:52:16 +1000
committerJesse Duffield <jessedduffield@gmail.com>2023-05-29 22:52:16 +1000
commit1de876ed4d1e5f95b70e109c2f05f722ef88b46e (patch)
tree20d6334398688b7da5e9d623bc29cb4795498d20 /pkg/gui/services
parent036a1ea519885ae9962c0ba2d90f642874cabd89 (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.go2
-rw-r--r--pkg/gui/services/custom_commands/menu_generator.go57
-rw-r--r--pkg/gui/services/custom_commands/menu_generator_test.go32
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 {