diff --git a/pkg/gui/controllers/diffing_menu_action.go b/pkg/gui/controllers/diffing_menu_action.go index a53ad65e5..3ae5903d9 100644 --- a/pkg/gui/controllers/diffing_menu_action.go +++ b/pkg/gui/controllers/diffing_menu_action.go @@ -2,7 +2,6 @@ package controllers import ( "fmt" - "strings" "github.com/jesseduffield/lazygit/pkg/gui/modes/diffing" "github.com/jesseduffield/lazygit/pkg/gui/types" @@ -38,7 +37,7 @@ func (self *DiffingMenuAction) Call() error { Title: self.c.Tr.EnterRefName, FindSuggestionsFunc: self.c.Helpers().Suggestions.GetRefsSuggestionsFunc(), HandleConfirm: func(response string) error { - self.c.Modes().Diffing.Ref = strings.TrimSpace(response) + self.c.Modes().Diffing.Ref = response self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) return nil }, diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go index 0289936de..d9477db4a 100644 --- a/pkg/gui/controllers/files_controller.go +++ b/pkg/gui/controllers/files_controller.go @@ -1211,6 +1211,7 @@ func (self *FilesController) handleStashSave(stashFunc func(message string) erro self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.STASH, types.FILES}}) return nil }, + AllowEmptyInput: true, }) return nil diff --git a/pkg/gui/controllers/filtering_menu_action.go b/pkg/gui/controllers/filtering_menu_action.go index 2ed072676..01a236f7a 100644 --- a/pkg/gui/controllers/filtering_menu_action.go +++ b/pkg/gui/controllers/filtering_menu_action.go @@ -2,7 +2,6 @@ package controllers import ( "fmt" - "strings" "github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers" "github.com/jesseduffield/lazygit/pkg/gui/types" @@ -66,7 +65,7 @@ func (self *FilteringMenuAction) Call() error { FindSuggestionsFunc: self.c.Helpers().Suggestions.GetFilePathSuggestionsFunc(), Title: self.c.Tr.EnterFileName, HandleConfirm: func(response string) error { - return self.setFilteringPath(strings.TrimSpace(response)) + return self.setFilteringPath(response) }, }) @@ -82,7 +81,7 @@ func (self *FilteringMenuAction) Call() error { FindSuggestionsFunc: self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc(), Title: self.c.Tr.EnterAuthor, HandleConfirm: func(response string) error { - return self.setFilteringAuthor(strings.TrimSpace(response)) + return self.setFilteringAuthor(response) }, }) diff --git a/pkg/gui/controllers/helpers/confirmation_helper.go b/pkg/gui/controllers/helpers/confirmation_helper.go index 1599d5e86..b1c334914 100644 --- a/pkg/gui/controllers/helpers/confirmation_helper.go +++ b/pkg/gui/controllers/helpers/confirmation_helper.go @@ -24,7 +24,33 @@ func NewConfirmationHelper(c *HelperCommon) *ConfirmationHelper { // This file is for the rendering of confirmation panels along with setting and handling associated // keybindings. +func (self *ConfirmationHelper) closeAndCallConfirmationFunction(cancel goContext.CancelFunc, function func() error) error { + cancel() + + self.c.Context().Pop() + + if function != nil { + if err := function(); err != nil { + return err + } + } + + return nil +} + func (self *ConfirmationHelper) wrappedConfirmationFunction(cancel goContext.CancelFunc, function func() error) func() error { + return func() error { + return self.closeAndCallConfirmationFunction(cancel, function) + } +} + +func (self *ConfirmationHelper) wrappedPromptConfirmationFunction( + cancel goContext.CancelFunc, + function func(string) error, + getResponse func() string, + allowEmptyInput bool, + preserveWhitespace bool, +) func() error { return func() error { if self.c.GocuiGui().IsPasting { // The user is pasting multi-line text into a prompt; we don't want to handle the @@ -34,24 +60,20 @@ func (self *ConfirmationHelper) wrappedConfirmationFunction(cancel goContext.Can return nil } - cancel() - - self.c.Context().Pop() - - if function != nil { - if err := function(); err != nil { - return err - } + response := getResponse() + if !preserveWhitespace { + response = strings.TrimSpace(response) } - return nil - } -} + if response == "" && !allowEmptyInput { + self.c.ErrorToast(self.c.Tr.PromptInputCannotBeEmptyToast) + return nil + } -func (self *ConfirmationHelper) wrappedPromptConfirmationFunction(cancel goContext.CancelFunc, function func(string) error, getResponse func() string) func() error { - return self.wrappedConfirmationFunction(cancel, func() error { - return function(getResponse()) - }) + return self.closeAndCallConfirmationFunction(cancel, func() error { + return function(response) + }) + } } func (self *ConfirmationHelper) DeactivateConfirmation() { @@ -229,12 +251,15 @@ func (self *ConfirmationHelper) setConfirmationKeyBindings(cancel goContext.Canc func (self *ConfirmationHelper) setPromptKeyBindings(cancel goContext.CancelFunc, opts types.CreatePopupPanelOpts) { onConfirm := self.wrappedPromptConfirmationFunction(cancel, opts.HandleConfirmPrompt, - func() string { return self.c.Views().Prompt.TextArea.GetContent() }) + func() string { return self.c.Views().Prompt.TextArea.GetContent() }, + opts.AllowEmptyInput, opts.PreserveWhitespace) onSuggestionConfirm := self.wrappedPromptConfirmationFunction( cancel, opts.HandleConfirmPrompt, self.getSelectedSuggestionValue, + opts.AllowEmptyInput, + opts.PreserveWhitespace, ) onClose := self.wrappedConfirmationFunction(cancel, opts.HandleClose) diff --git a/pkg/gui/controllers/helpers/credentials_helper.go b/pkg/gui/controllers/helpers/credentials_helper.go index 0783e65f2..2d3654887 100644 --- a/pkg/gui/controllers/helpers/credentials_helper.go +++ b/pkg/gui/controllers/helpers/credentials_helper.go @@ -41,6 +41,7 @@ func (self *CredentialsHelper) PromptUserForCredential(passOrUname oscommands.Cr return nil }, + AllowEmptyInput: true, }) return nil diff --git a/pkg/gui/controllers/helpers/worktree_helper.go b/pkg/gui/controllers/helpers/worktree_helper.go index ea889781e..671743fe6 100644 --- a/pkg/gui/controllers/helpers/worktree_helper.go +++ b/pkg/gui/controllers/helpers/worktree_helper.go @@ -130,23 +130,21 @@ func (self *WorktreeHelper) NewWorktreeCheckout(base string, canCheckoutBase boo return f() }, + AllowEmptyInput: true, }) return nil } - // prompt for the new branch name where a blank means we just check out the branch + // prompt for the new branch name self.c.Prompt(types.PromptOpts{ Title: self.c.Tr.NewBranchName, HandleConfirm: func(branchName string) error { - if branchName == "" { - return errors.New(self.c.Tr.BranchNameCannotBeBlank) - } - opts.Branch = branchName return f() }, + AllowEmptyInput: false, }) return nil diff --git a/pkg/gui/controllers/shell_command_action.go b/pkg/gui/controllers/shell_command_action.go index 185f74893..114c7fcb1 100644 --- a/pkg/gui/controllers/shell_command_action.go +++ b/pkg/gui/controllers/shell_command_action.go @@ -19,6 +19,7 @@ func (self *ShellCommandAction) Call() error { Title: self.c.Tr.ShellCommand, FindSuggestionsFunc: self.GetShellCommandsHistorySuggestionsFunc(), AllowEditSuggestion: true, + PreserveWhitespace: true, HandleConfirm: func(command string) error { if self.shouldSaveCommand(command) { self.c.GetAppState().ShellCommandsHistory = utils.Limit( diff --git a/pkg/gui/controllers/stash_controller.go b/pkg/gui/controllers/stash_controller.go index 889bc0872..87f84d7ea 100644 --- a/pkg/gui/controllers/stash_controller.go +++ b/pkg/gui/controllers/stash_controller.go @@ -209,6 +209,7 @@ func (self *StashController) handleRenameStashEntry(stashEntry *models.StashEntr self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.STASH}}) return nil }, + AllowEmptyInput: true, }) return nil diff --git a/pkg/gui/popup/popup_handler.go b/pkg/gui/popup/popup_handler.go index d8ce654b4..d8824016f 100644 --- a/pkg/gui/popup/popup_handler.go +++ b/pkg/gui/popup/popup_handler.go @@ -139,6 +139,8 @@ func (self *PopupHandler) Prompt(opts types.PromptOpts) { HandleDeleteSuggestion: opts.HandleDeleteSuggestion, FindSuggestionsFunc: opts.FindSuggestionsFunc, AllowEditSuggestion: opts.AllowEditSuggestion, + AllowEmptyInput: opts.AllowEmptyInput, + PreserveWhitespace: opts.PreserveWhitespace, Mask: opts.Mask, }) } diff --git a/pkg/gui/services/custom_commands/handler_creator.go b/pkg/gui/services/custom_commands/handler_creator.go index 73e68c3b3..04899b004 100644 --- a/pkg/gui/services/custom_commands/handler_creator.go +++ b/pkg/gui/services/custom_commands/handler_creator.go @@ -125,6 +125,8 @@ func (self *HandlerCreator) inputPrompt(prompt *config.CustomCommandPrompt, wrap HandleConfirm: func(str string) error { return wrappedF(str) }, + AllowEmptyInput: true, + PreserveWhitespace: true, }) return nil diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go index 905a9b65d..2afe4f7d3 100644 --- a/pkg/gui/types/common.go +++ b/pkg/gui/types/common.go @@ -172,6 +172,8 @@ type CreatePopupPanelOpts struct { FindSuggestionsFunc func(string) []*Suggestion Mask bool AllowEditSuggestion bool + AllowEmptyInput bool + PreserveWhitespace bool } type ConfirmOpts struct { @@ -190,6 +192,8 @@ type PromptOpts struct { FindSuggestionsFunc func(string) []*Suggestion HandleConfirm func(string) error AllowEditSuggestion bool + AllowEmptyInput bool + PreserveWhitespace bool // CAPTURE THIS HandleClose func() error HandleDeleteSuggestion func(int) error diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index cb070b892..c9ca03275 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -618,6 +618,7 @@ type TranslationSet struct { MustStashTitle string ConfirmationTitle string PromptTitle string + PromptInputCannotBeEmptyToast string PrevPage string NextPage string GotoTop string @@ -861,7 +862,6 @@ type TranslationSet struct { NewWorktreePath string NewWorktreeBase string RemoveWorktreeTooltip string - BranchNameCannotBeBlank string NewBranchName string NewBranchNameLeaveBlank string ViewWorktreeOptions string @@ -1713,6 +1713,7 @@ func EnglishTranslationSet() *TranslationSet { MustStashTitle: "Must stash", ConfirmationTitle: "Confirmation panel", PromptTitle: "Input prompt", + PromptInputCannotBeEmptyToast: "Empty input is not allowed", PrevPage: "Previous page", NextPage: "Next page", GotoTop: "Scroll to top", @@ -1954,7 +1955,6 @@ func EnglishTranslationSet() *TranslationSet { NewWorktreePath: "New worktree path", NewWorktreeBase: "New worktree base ref", RemoveWorktreeTooltip: "Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory.", - BranchNameCannotBeBlank: "Branch name cannot be blank", NewBranchName: "New branch name", NewBranchNameLeaveBlank: "New branch name (leave blank to checkout {{.default}})", ViewWorktreeOptions: "View worktree options",