Skip to content

Commit

Permalink
Add suggestionsPreset to custom commands system
Browse files Browse the repository at this point in the history
  • Loading branch information
jesseduffield committed May 29, 2023
1 parent 8e6967c commit 16fa22a
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/Custom_Command_Keybindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ The permitted prompt fields are:
| type | one of 'input', 'menu', or 'confirm' | yes |
| title | the title to display in the popup panel | no |
| initialValue | (only applicable to 'input' prompts) the initial value to appear in the text box | no |
| suggestionsPreset | (only applicable to 'input prompts'. Shows suggestions as the value is typed. One of 'files', 'branches', 'remotes', 'remoteBranches', refs'. | no |
| body | (only applicable to 'confirm' prompts) the immutable body text to appear in the text box | no |
| options | (only applicable to 'menu' prompts) the options to display in the menu | no |
| command | (only applicable to 'menuFromCommand' prompts) the command to run to generate | yes |
Expand Down
3 changes: 2 additions & 1 deletion pkg/config/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,8 @@ type CustomCommandPrompt struct {
Title string `yaml:"title"`

// this only apply to input prompts
InitialValue string `yaml:"initialValue"`
InitialValue string `yaml:"initialValue"`
SuggestionsPreset string `yaml:"suggestionsPreset"`

// this only applies to confirm prompts
Body string `yaml:"body"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/gui/services/custom_commands/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func NewClient(
helpers *helpers.Helpers,
) *Client {
sessionStateLoader := NewSessionStateLoader(c, helpers.Refs)
handlerCreator := NewHandlerCreator(c, sessionStateLoader)
handlerCreator := NewHandlerCreator(c, sessionStateLoader, helpers.Suggestions)
keybindingCreator := NewKeybindingCreator(c)
customCommands := c.UserConfig.CustomCommands

Expand Down
35 changes: 33 additions & 2 deletions pkg/gui/services/custom_commands/handler_creator.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package custom_commands

import (
"fmt"
"strings"
"text/template"

Expand All @@ -18,11 +19,13 @@ type HandlerCreator struct {
sessionStateLoader *SessionStateLoader
resolver *Resolver
menuGenerator *MenuGenerator
suggestionsHelper *helpers.SuggestionsHelper
}

func NewHandlerCreator(
c *helpers.HelperCommon,
sessionStateLoader *SessionStateLoader,
suggestionsHelper *helpers.SuggestionsHelper,
) *HandlerCreator {
resolver := NewResolver(c.Common)
menuGenerator := NewMenuGenerator(c.Common)
Expand All @@ -32,6 +35,7 @@ func NewHandlerCreator(
sessionStateLoader: sessionStateLoader,
resolver: resolver,
menuGenerator: menuGenerator,
suggestionsHelper: suggestionsHelper,
}
}

Expand Down Expand Up @@ -104,15 +108,42 @@ func (self *HandlerCreator) call(customCommand config.CustomCommand) func() erro
}

func (self *HandlerCreator) inputPrompt(prompt *config.CustomCommandPrompt, wrappedF func(string) error) error {
var findSuggestionsFn func(string) []*types.Suggestion
if prompt.SuggestionsPreset != "" {
var err error
findSuggestionsFn, err = self.getPresetSuggestionsFn(prompt.SuggestionsPreset)
if err != nil {
return err
}
}

return self.c.Prompt(types.PromptOpts{
Title: prompt.Title,
InitialContent: prompt.InitialValue,
Title: prompt.Title,
InitialContent: prompt.InitialValue,
FindSuggestionsFunc: findSuggestionsFn,
HandleConfirm: func(str string) error {
return wrappedF(str)
},
})
}

func (self *HandlerCreator) getPresetSuggestionsFn(preset string) (func(string) []*types.Suggestion, error) {
switch preset {
case "files":
return self.suggestionsHelper.GetFilePathSuggestionsFunc(), nil
case "branches":
return self.suggestionsHelper.GetBranchNameSuggestionsFunc(), nil
case "remotes":
return self.suggestionsHelper.GetRemoteSuggestionsFunc(), nil
case "remoteBranches":
return self.suggestionsHelper.GetRemoteBranchesSuggestionsFunc("/"), nil
case "refs":
return self.suggestionsHelper.GetRefsSuggestionsFunc(), nil
default:
return nil, fmt.Errorf("Unknown value for suggestionsPreset in custom command: %s. Valid values: files, branches, remotes, remoteBranches, refs", preset)
}
}

func (self *HandlerCreator) menuPrompt(prompt *config.CustomCommandPrompt, wrappedF func(string) error) error {
menuItems := slices.Map(prompt.Options, func(option config.CustomCommandMenuOption) *types.MenuItem {
return &types.MenuItem{
Expand Down
5 changes: 5 additions & 0 deletions pkg/gui/services/custom_commands/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ func (self *Resolver) resolvePrompt(
return nil, err
}

result.SuggestionsPreset, err = resolveTemplate(prompt.SuggestionsPreset)
if err != nil {
return nil, err
}

result.Body, err = resolveTemplate(prompt.Body)
if err != nil {
return nil, err
Expand Down
64 changes: 64 additions & 0 deletions pkg/integration/tests/custom_commands/suggestions_preset.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package custom_commands

import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)

var SuggestionsPreset = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Using a custom command that uses a suggestions preset in a prompt step",
ExtraCmdArgs: []string{},
Skip: false,
SetupRepo: func(shell *Shell) {
shell.NewBranch("branch-one")
shell.EmptyCommit("blah")
shell.NewBranch("branch-two")
shell.EmptyCommit("blah")
shell.NewBranch("branch-three")
shell.EmptyCommit("blah")
shell.NewBranch("branch-four")
shell.EmptyCommit("blah")
},
SetupConfig: func(cfg *config.AppConfig) {
cfg.UserConfig.CustomCommands = []config.CustomCommand{
{
Key: "a",
Context: "localBranches",
Command: `git checkout {{.Form.Branch}}`,
Prompts: []config.CustomCommandPrompt{
{
Key: "Branch",
Type: "input",
Title: "Enter a branch name",
SuggestionsPreset: "branches",
},
},
},
}
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Branches().
Focus().
Lines(
Contains("branch-four").IsSelected(),
Contains("branch-three"),
Contains("branch-two"),
Contains("branch-one"),
).
Press("a")

t.ExpectPopup().Prompt().
Title(Equals("Enter a branch name")).
Type("three").
SuggestionLines(Contains("branch-three")).
ConfirmFirstSuggestion()

t.Views().Branches().
Lines(
Contains("branch-three").IsSelected(),
Contains("branch-four"),
Contains("branch-two"),
Contains("branch-one"),
)
},
})
1 change: 1 addition & 0 deletions pkg/integration/tests/test_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ var tests = []*components.IntegrationTest{
custom_commands.MenuFromCommandsOutput,
custom_commands.MultiplePrompts,
custom_commands.OmitFromHistory,
custom_commands.SuggestionsPreset,
diff.Diff,
diff.DiffAndApplyPatch,
diff.DiffCommits,
Expand Down

0 comments on commit 16fa22a

Please sign in to comment.