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,