From a7041cf492cb24bfd2bbaed0df5d91a943b78ca0 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sat, 27 Apr 2024 22:18:57 +0200 Subject: [PATCH] Allow editing a custom command from the suggestions list by pressing 'e' For custom commands it is useful to select an earlier command and have it copied to the prompt for further editing. This can be done by hitting 'e' now. For other types of suggestion panels we don't enable this behavior, as you can't create arbitrary new items there that don't already exist as a suggestion. --- pkg/gui/context/suggestions_context.go | 2 ++ pkg/gui/controllers/custom_command_action.go | 1 + .../helpers/confirmation_helper.go | 2 ++ pkg/gui/controllers/suggestions_controller.go | 15 +++++++++ pkg/gui/popup/popup_handler.go | 1 + pkg/gui/types/common.go | 2 ++ pkg/integration/components/prompt_driver.go | 9 ++++++ .../tests/custom_commands/edit_history.go | 31 +++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + 9 files changed, 64 insertions(+) create mode 100644 pkg/integration/tests/custom_commands/edit_history.go diff --git a/pkg/gui/context/suggestions_context.go b/pkg/gui/context/suggestions_context.go index 7b657121a..c741cc769 100644 --- a/pkg/gui/context/suggestions_context.go +++ b/pkg/gui/context/suggestions_context.go @@ -20,6 +20,8 @@ type SuggestionsContextState struct { OnDeleteSuggestion func() error AsyncHandler *tasks.AsyncHandler + AllowEditSuggestion bool + // FindSuggestions will take a string that the user has typed into a prompt // and return a slice of suggestions which match that string. FindSuggestions func(string) []*types.Suggestion diff --git a/pkg/gui/controllers/custom_command_action.go b/pkg/gui/controllers/custom_command_action.go index 3225867d9..39777e70a 100644 --- a/pkg/gui/controllers/custom_command_action.go +++ b/pkg/gui/controllers/custom_command_action.go @@ -18,6 +18,7 @@ func (self *CustomCommandAction) Call() error { return self.c.Prompt(types.PromptOpts{ Title: self.c.Tr.CustomCommand, FindSuggestionsFunc: self.GetCustomCommandsHistorySuggestionsFunc(), + AllowEditSuggestion: true, HandleConfirm: func(command string) error { if self.shouldSaveCommand(command) { self.c.GetAppState().CustomCommandsHistory = utils.Limit( diff --git a/pkg/gui/controllers/helpers/confirmation_helper.go b/pkg/gui/controllers/helpers/confirmation_helper.go index 0e5e54109..e4b76ce40 100644 --- a/pkg/gui/controllers/helpers/confirmation_helper.go +++ b/pkg/gui/controllers/helpers/confirmation_helper.go @@ -223,6 +223,8 @@ func (self *ConfirmationHelper) CreatePopupPanel(ctx goContext.Context, opts typ return err } + self.c.Contexts().Suggestions.State.AllowEditSuggestion = opts.AllowEditSuggestion + self.c.State().GetRepoState().SetCurrentPopupOpts(&opts) return self.c.PushContext(self.c.Contexts().Confirmation) diff --git a/pkg/gui/controllers/suggestions_controller.go b/pkg/gui/controllers/suggestions_controller.go index 4491cfe35..655c7465b 100644 --- a/pkg/gui/controllers/suggestions_controller.go +++ b/pkg/gui/controllers/suggestions_controller.go @@ -49,6 +49,21 @@ func (self *SuggestionsController) GetKeybindings(opts types.KeybindingsOpts) [] return self.context().State.OnDeleteSuggestion() }, }, + { + Key: opts.GetKey(opts.Config.Universal.Edit), + Handler: func() error { + if self.context().State.AllowEditSuggestion { + if selectedItem := self.c.Contexts().Suggestions.GetSelected(); selectedItem != nil { + self.c.Contexts().Confirmation.GetView().TextArea.Clear() + self.c.Contexts().Confirmation.GetView().TextArea.TypeString(selectedItem.Value) + self.c.Contexts().Confirmation.GetView().RenderTextArea() + self.c.Contexts().Suggestions.RefreshSuggestions() + return self.c.ReplaceContext(self.c.Contexts().Confirmation) + } + } + return nil + }, + }, } return bindings diff --git a/pkg/gui/popup/popup_handler.go b/pkg/gui/popup/popup_handler.go index ac003e943..3f71644d3 100644 --- a/pkg/gui/popup/popup_handler.go +++ b/pkg/gui/popup/popup_handler.go @@ -111,6 +111,7 @@ func (self *PopupHandler) Prompt(opts types.PromptOpts) error { HandleClose: opts.HandleClose, HandleDeleteSuggestion: opts.HandleDeleteSuggestion, FindSuggestionsFunc: opts.FindSuggestionsFunc, + AllowEditSuggestion: opts.AllowEditSuggestion, Mask: opts.Mask, }) } diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go index 39378484b..d50173078 100644 --- a/pkg/gui/types/common.go +++ b/pkg/gui/types/common.go @@ -176,6 +176,7 @@ type CreatePopupPanelOpts struct { FindSuggestionsFunc func(string) []*Suggestion Mask bool + AllowEditSuggestion bool } type ConfirmOpts struct { @@ -193,6 +194,7 @@ type PromptOpts struct { InitialContent string FindSuggestionsFunc func(string) []*Suggestion HandleConfirm func(string) error + AllowEditSuggestion bool // CAPTURE THIS HandleClose func() error HandleDeleteSuggestion func(int) error diff --git a/pkg/integration/components/prompt_driver.go b/pkg/integration/components/prompt_driver.go index d1cce878c..a19c29aa4 100644 --- a/pkg/integration/components/prompt_driver.go +++ b/pkg/integration/components/prompt_driver.go @@ -91,3 +91,12 @@ func (self *PromptDriver) DeleteSuggestion(matcher *TextMatcher) *PromptDriver { self.t.press(self.t.keys.Universal.Remove) return self } + +func (self *PromptDriver) EditSuggestion(matcher *TextMatcher) *PromptDriver { + self.t.press(self.t.keys.Universal.TogglePanel) + self.t.Views().Suggestions(). + IsFocused(). + NavigateToLine(matcher) + self.t.press(self.t.keys.Universal.Edit) + return self +} diff --git a/pkg/integration/tests/custom_commands/edit_history.go b/pkg/integration/tests/custom_commands/edit_history.go new file mode 100644 index 000000000..c6999b1f2 --- /dev/null +++ b/pkg/integration/tests/custom_commands/edit_history.go @@ -0,0 +1,31 @@ +package custom_commands + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var EditHistory = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Edit an entry from the custom commands history", + ExtraCmdArgs: []string{}, + Skip: false, + SetupRepo: func(shell *Shell) {}, + SetupConfig: func(cfg *config.AppConfig) {}, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.GlobalPress(keys.Universal.ExecuteCustomCommand) + t.ExpectPopup().Prompt(). + Title(Equals("Custom command:")). + Type("echo x"). + Confirm() + + t.GlobalPress(keys.Universal.ExecuteCustomCommand) + t.ExpectPopup().Prompt(). + Title(Equals("Custom command:")). + Type("ec"). + SuggestionLines( + Equals("echo x"), + ). + EditSuggestion(Equals("echo x")). + InitialText(Equals("echo x")) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index eae6a5f7b..7084fd99b 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -106,6 +106,7 @@ var tests = []*components.IntegrationTest{ custom_commands.CheckForConflicts, custom_commands.ComplexCmdAtRuntime, custom_commands.DeleteFromHistory, + custom_commands.EditHistory, custom_commands.FormPrompts, custom_commands.History, custom_commands.MenuFromCommand,