1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-08-07 22:02:56 +03:00

refactor prompt opts

This commit is contained in:
Jesse Duffield
2020-11-28 13:35:58 +11:00
parent da3b0bf7c8
commit 5671ec5f58
12 changed files with 270 additions and 180 deletions

View File

@@ -207,7 +207,10 @@ func (gui *Gui) handleCheckoutRef(ref string, options handleCheckoutRefOptions)
} }
func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error {
return gui.prompt(gui.Tr.BranchName+":", "", func(response string) error { return gui.prompt(promptOpts{
title: gui.Tr.BranchName + ":",
showSuggestions: true,
handleConfirm: func(response string) error {
return gui.handleCheckoutRef(response, handleCheckoutRefOptions{ return gui.handleCheckoutRef(response, handleCheckoutRefOptions{
onRefNotFound: func(ref string) error { onRefNotFound: func(ref string) error {
@@ -220,7 +223,8 @@ func (gui *Gui) handleCheckoutByName(g *gocui.Gui, v *gocui.View) error {
}) })
}, },
}) })
}) }},
)
} }
func (gui *Gui) getCheckedOutBranch() *models.Branch { func (gui *Gui) getCheckedOutBranch() *models.Branch {
@@ -427,7 +431,9 @@ func (gui *Gui) handleRenameBranch(g *gocui.Gui, v *gocui.View) error {
// way to get it to show up in the reflog) // way to get it to show up in the reflog)
promptForNewName := func() error { promptForNewName := func() error {
return gui.prompt(gui.Tr.NewBranchNamePrompt+" "+branch.Name+":", "", func(newBranchName string) error { return gui.prompt(promptOpts{
title: gui.Tr.NewBranchNamePrompt + " " + branch.Name + ":",
handleConfirm: func(newBranchName string) error {
if err := gui.GitCommand.RenameBranch(branch.Name, newBranchName); err != nil { if err := gui.GitCommand.RenameBranch(branch.Name, newBranchName); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
@@ -438,6 +444,7 @@ func (gui *Gui) handleRenameBranch(g *gocui.Gui, v *gocui.View) error {
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
},
}) })
} }
@@ -483,7 +490,11 @@ func (gui *Gui) handleNewBranchOffCurrentItem() error {
// will set to the remote's existing name // will set to the remote's existing name
prefilledName = item.ID() prefilledName = item.ID()
} }
return gui.prompt(message, prefilledName, func(response string) error {
return gui.prompt(promptOpts{
title: message,
initialContent: prefilledName,
handleConfirm: func(response string) error {
if err := gui.GitCommand.NewBranch(response, item.ID()); err != nil { if err := gui.GitCommand.NewBranch(response, item.ID()); err != nil {
return err return err
} }
@@ -503,5 +514,6 @@ func (gui *Gui) handleNewBranchOffCurrentItem() error {
gui.State.Panels.Branches.SelectedLineIdx = 0 gui.State.Panels.Branches.SelectedLineIdx = 0
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
},
}) })
} }

View File

@@ -233,12 +233,16 @@ func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
return gui.prompt(gui.Tr.LcRenameCommit, message, func(response string) error { return gui.prompt(promptOpts{
title: gui.Tr.LcRenameCommit,
initialContent: message,
handleConfirm: func(response string) error {
if err := gui.GitCommand.RenameCommit(response); err != nil { if err := gui.GitCommand.RenameCommit(response); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
},
}) })
} }
@@ -517,11 +521,14 @@ func (gui *Gui) handleTagCommit(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCreateLightweightTag(commitSha string) error { func (gui *Gui) handleCreateLightweightTag(commitSha string) error {
return gui.prompt(gui.Tr.TagNameTitle, "", func(response string) error { return gui.prompt(promptOpts{
title: gui.Tr.TagNameTitle,
handleConfirm: func(response string) error {
if err := gui.GitCommand.CreateLightweightTag(response, commitSha); err != nil { if err := gui.GitCommand.CreateLightweightTag(response, commitSha); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{COMMITS, TAGS}}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC, scope: []int{COMMITS, TAGS}})
},
}) })
} }

View File

@@ -28,7 +28,7 @@ type createPopupPanelOpts struct {
// when handlersManageFocus is true, do not return from the confirmation context automatically. It's expected that the handlers will manage focus, whether that means switching to another context, or manually returning the context. // when handlersManageFocus is true, do not return from the confirmation context automatically. It's expected that the handlers will manage focus, whether that means switching to another context, or manually returning the context.
handlersManageFocus bool handlersManageFocus bool
showSuggestionsPanel bool showSuggestions bool
} }
type askOpts struct { type askOpts struct {
@@ -37,14 +37,14 @@ type askOpts struct {
handleConfirm func() error handleConfirm func() error
handleClose func() error handleClose func() error
handlersManageFocus bool handlersManageFocus bool
showSuggestionsPanel bool showSuggestions bool
} }
func (gui *Gui) createLoaderPanel(prompt string) error { type promptOpts struct {
return gui.createPopupPanel(createPopupPanelOpts{ title string
prompt: prompt, initialContent string
hasLoader: true, handleConfirm func(string) error
}) showSuggestions bool
} }
func (gui *Gui) ask(opts askOpts) error { func (gui *Gui) ask(opts askOpts) error {
@@ -54,17 +54,24 @@ func (gui *Gui) ask(opts askOpts) error {
handleConfirm: opts.handleConfirm, handleConfirm: opts.handleConfirm,
handleClose: opts.handleClose, handleClose: opts.handleClose,
handlersManageFocus: opts.handlersManageFocus, handlersManageFocus: opts.handlersManageFocus,
showSuggestionsPanel: opts.showSuggestionsPanel, showSuggestions: opts.showSuggestions,
}) })
} }
func (gui *Gui) prompt(title string, initialContent string, handleConfirm func(string) error) error { func (gui *Gui) prompt(opts promptOpts) error {
return gui.createPopupPanel(createPopupPanelOpts{ return gui.createPopupPanel(createPopupPanelOpts{
title: title, title: opts.title,
prompt: initialContent, prompt: opts.initialContent,
editable: true, editable: true,
handleConfirmPrompt: handleConfirm, handleConfirmPrompt: opts.handleConfirm,
showSuggestionsPanel: true, showSuggestions: opts.showSuggestions,
})
}
func (gui *Gui) createLoaderPanel(prompt string) error {
return gui.createPopupPanel(createPopupPanelOpts{
prompt: prompt,
hasLoader: true,
}) })
} }
@@ -173,7 +180,7 @@ func (gui *Gui) getConfirmationPanelDimensions(wrap bool, prompt string) (int, i
height/2 + panelHeight/2 height/2 + panelHeight/2
} }
func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, showSuggestionsPanel bool) (*gocui.View, error) { func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, showSuggestions bool) (*gocui.View, error) {
x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt) x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(true, prompt)
confirmationView, err := gui.g.SetView("confirmation", x0, y0, x1, y1, 0) confirmationView, err := gui.g.SetView("confirmation", x0, y0, x1, y1, 0)
if err != nil { if err != nil {
@@ -189,7 +196,7 @@ func (gui *Gui) prepareConfirmationPanel(title, prompt string, hasLoader bool, s
confirmationView.FgColor = theme.GocuiDefaultTextColor confirmationView.FgColor = theme.GocuiDefaultTextColor
} }
if showSuggestionsPanel { if showSuggestions {
suggestionsViewHeight := 11 suggestionsViewHeight := 11
suggestionsView, err := gui.g.SetView("suggestions", x0, y1, x1, y1+suggestionsViewHeight, 0) suggestionsView, err := gui.g.SetView("suggestions", x0, y1, x1, y1+suggestionsViewHeight, 0)
if err != nil { if err != nil {
@@ -215,7 +222,7 @@ func (gui *Gui) createPopupPanel(opts createPopupPanelOpts) error {
if view, _ := g.View("confirmation"); view != nil { if view, _ := g.View("confirmation"); view != nil {
gui.deleteConfirmationView() gui.deleteConfirmationView()
} }
confirmationView, err := gui.prepareConfirmationPanel(opts.title, opts.prompt, opts.hasLoader, opts.showSuggestionsPanel) confirmationView, err := gui.prepareConfirmationPanel(opts.title, opts.prompt, opts.hasLoader, opts.showSuggestions)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -98,15 +98,15 @@ func (gui *Gui) handleCustomCommandKeybinding(customCommand config.CustomCommand
return gui.surfaceError(err) return gui.surfaceError(err)
} }
return gui.prompt( return gui.prompt(promptOpts{
title, title: title,
initialValue, initialContent: initialValue,
func(str string) error { handleConfirm: func(str string) error {
promptResponses[idx] = str promptResponses[idx] = str
return wrappedF() return wrappedF()
}, },
) })
} }
case "menu": case "menu":
f = func() error { f = func() error {

View File

@@ -128,9 +128,12 @@ func (gui *Gui) handleCreateDiffingMenuPanel(g *gocui.Gui, v *gocui.View) error
{ {
displayString: gui.Tr.LcEnterRefToDiff, displayString: gui.Tr.LcEnterRefToDiff,
onPress: func() error { onPress: func() error {
return gui.prompt(gui.Tr.LcEnteRefName, "", func(response string) error { return gui.prompt(promptOpts{
title: gui.Tr.LcEnteRefName,
handleConfirm: func(response string) error {
gui.State.Modes.Diffing.Ref = strings.TrimSpace(response) gui.State.Modes.Diffing.Ref = strings.TrimSpace(response)
return gui.refreshSidePanels(refreshOptions{mode: ASYNC}) return gui.refreshSidePanels(refreshOptions{mode: ASYNC})
},
}) })
}, },
}, },

View File

@@ -496,7 +496,10 @@ func (gui *Gui) handlePullFiles(g *gocui.Gui, v *gocui.View) error {
} }
} }
return gui.prompt(gui.Tr.EnterUpstream, "origin/"+currentBranch.Name, func(upstream string) error { return gui.prompt(promptOpts{
title: gui.Tr.EnterUpstream,
initialContent: "origin/" + currentBranch.Name,
handleConfirm: func(upstream string) error {
if err := gui.GitCommand.SetUpstreamBranch(upstream); err != nil { if err := gui.GitCommand.SetUpstreamBranch(upstream); err != nil {
errorMessage := err.Error() errorMessage := err.Error()
if strings.Contains(errorMessage, "does not exist") { if strings.Contains(errorMessage, "does not exist") {
@@ -505,6 +508,7 @@ func (gui *Gui) handlePullFiles(g *gocui.Gui, v *gocui.View) error {
return gui.createErrorPanel(errorMessage) return gui.createErrorPanel(errorMessage)
} }
return gui.pullFiles(PullFilesOptions{}) return gui.pullFiles(PullFilesOptions{})
},
}) })
} }
@@ -610,8 +614,12 @@ func (gui *Gui) pushFiles(g *gocui.Gui, v *gocui.View) error {
if gui.GitCommand.PushToCurrent { if gui.GitCommand.PushToCurrent {
return gui.pushWithForceFlag(v, false, "", "--set-upstream") return gui.pushWithForceFlag(v, false, "", "--set-upstream")
} else { } else {
return gui.prompt(gui.Tr.EnterUpstream, "origin "+currentBranch.Name, func(response string) error { return gui.prompt(promptOpts{
title: gui.Tr.EnterUpstream,
initialContent: "origin " + currentBranch.Name,
handleConfirm: func(response string) error {
return gui.pushWithForceFlag(v, false, response, "") return gui.pushWithForceFlag(v, false, response, "")
},
}) })
} }
} else if currentBranch.Pullables == "0" { } else if currentBranch.Pullables == "0" {
@@ -662,9 +670,12 @@ func (gui *Gui) anyFilesWithMergeConflicts() bool {
} }
func (gui *Gui) handleCustomCommand(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCustomCommand(g *gocui.Gui, v *gocui.View) error {
return gui.prompt(gui.Tr.CustomCommand, "", func(command string) error { return gui.prompt(promptOpts{
title: gui.Tr.CustomCommand,
handleConfirm: func(command string) error {
gui.SubProcess = gui.OSCommand.RunCustomCommand(command) gui.SubProcess = gui.OSCommand.RunCustomCommand(command)
return gui.Errors.ErrSubProcess return gui.Errors.ErrSubProcess
},
}) })
} }

View File

@@ -41,9 +41,12 @@ func (gui *Gui) handleCreateFilteringMenuPanel(g *gocui.Gui, v *gocui.View) erro
menuItems = append(menuItems, &menuItem{ menuItems = append(menuItems, &menuItem{
displayString: gui.Tr.LcFilterPathOption, displayString: gui.Tr.LcFilterPathOption,
onPress: func() error { onPress: func() error {
return gui.prompt(gui.Tr.LcEnterFileName, "", func(response string) error { return gui.prompt(promptOpts{
title: gui.Tr.LcEnterFileName,
handleConfirm: func(response string) error {
gui.State.Modes.Filtering.Path = strings.TrimSpace(response) gui.State.Modes.Filtering.Path = strings.TrimSpace(response)
return gui.Errors.ErrRestart return gui.Errors.ErrRestart
},
}) })
}, },
}) })

View File

@@ -52,10 +52,14 @@ func (gui *Gui) handleCreateGitFlowMenu(g *gocui.Gui, v *gocui.View) error {
startHandler := func(branchType string) func() error { startHandler := func(branchType string) func() error {
return func() error { return func() error {
title := utils.ResolvePlaceholderString(gui.Tr.NewGitFlowBranchPrompt, map[string]string{"branchType": branchType}) title := utils.ResolvePlaceholderString(gui.Tr.NewGitFlowBranchPrompt, map[string]string{"branchType": branchType})
return gui.prompt(title, "", func(name string) error {
return gui.prompt(promptOpts{
title: title,
handleConfirm: func(name string) error {
subProcess := gui.OSCommand.PrepareSubProcess("git", "flow", branchType, "start", name) subProcess := gui.OSCommand.PrepareSubProcess("git", "flow", branchType, "start", name)
gui.SubProcess = subProcess gui.SubProcess = subProcess
return gui.Errors.ErrSubProcess return gui.Errors.ErrSubProcess
},
}) })
} }
} }

View File

@@ -85,14 +85,21 @@ func (gui *Gui) handleRemoteEnter() error {
} }
func (gui *Gui) handleAddRemote(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleAddRemote(g *gocui.Gui, v *gocui.View) error {
return gui.prompt(gui.Tr.LcNewRemoteName, "", func(remoteName string) error { return gui.prompt(promptOpts{
return gui.prompt(gui.Tr.LcNewRemoteUrl, "", func(remoteUrl string) error { title: gui.Tr.LcNewRemoteName,
handleConfirm: func(remoteName string) error {
return gui.prompt(promptOpts{
title: gui.Tr.LcNewRemoteUrl,
handleConfirm: func(remoteUrl string) error {
if err := gui.GitCommand.AddRemote(remoteName, remoteUrl); err != nil { if err := gui.GitCommand.AddRemote(remoteName, remoteUrl); err != nil {
return err return err
} }
return gui.refreshSidePanels(refreshOptions{scope: []int{REMOTES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{REMOTES}})
},
}) })
},
}) })
} }
func (gui *Gui) handleRemoveRemote(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleRemoveRemote(g *gocui.Gui, v *gocui.View) error {
@@ -127,7 +134,10 @@ func (gui *Gui) handleEditRemote(g *gocui.Gui, v *gocui.View) error {
}, },
) )
return gui.prompt(editNameMessage, remote.Name, func(updatedRemoteName string) error { return gui.prompt(promptOpts{
title: editNameMessage,
initialContent: remote.Name,
handleConfirm: func(updatedRemoteName string) error {
if updatedRemoteName != remote.Name { if updatedRemoteName != remote.Name {
if err := gui.GitCommand.RenameRemote(remote.Name, updatedRemoteName); err != nil { if err := gui.GitCommand.RenameRemote(remote.Name, updatedRemoteName); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
@@ -147,12 +157,17 @@ func (gui *Gui) handleEditRemote(g *gocui.Gui, v *gocui.View) error {
url = urls[0] url = urls[0]
} }
return gui.prompt(editUrlMessage, url, func(updatedRemoteUrl string) error { return gui.prompt(promptOpts{
title: editUrlMessage,
initialContent: url,
handleConfirm: func(updatedRemoteUrl string) error {
if err := gui.GitCommand.UpdateRemoteUrl(updatedRemoteName, updatedRemoteUrl); err != nil { if err := gui.GitCommand.UpdateRemoteUrl(updatedRemoteName, updatedRemoteUrl); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{BRANCHES, REMOTES}})
},
}) })
},
}) })
} }

View File

@@ -117,11 +117,15 @@ func (gui *Gui) handleStashSave(stashFunc func(message string) error) error {
if len(gui.trackedFiles()) == 0 && len(gui.stagedFiles()) == 0 { if len(gui.trackedFiles()) == 0 && len(gui.stagedFiles()) == 0 {
return gui.createErrorPanel(gui.Tr.NoTrackedStagedFilesStash) return gui.createErrorPanel(gui.Tr.NoTrackedStagedFilesStash)
} }
return gui.prompt(gui.Tr.StashChanges, "", func(stashComment string) error {
return gui.prompt(promptOpts{
title: gui.Tr.StashChanges,
handleConfirm: func(stashComment string) error {
if err := stashFunc(stashComment); err != nil { if err := stashFunc(stashComment); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }
return gui.refreshSidePanels(refreshOptions{scope: []int{STASH, FILES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{STASH, FILES}})
},
}) })
} }

View File

@@ -126,30 +126,47 @@ func (gui *Gui) resetSubmodule(submodule *models.SubmoduleConfig) error {
} }
func (gui *Gui) handleAddSubmodule() error { func (gui *Gui) handleAddSubmodule() error {
return gui.prompt(gui.Tr.LcNewSubmoduleUrl, "", func(submoduleUrl string) error { return gui.prompt(promptOpts{
title: gui.Tr.LcNewSubmoduleUrl,
handleConfirm: func(submoduleUrl string) error {
nameSuggestion := filepath.Base(strings.TrimSuffix(submoduleUrl, filepath.Ext(submoduleUrl))) nameSuggestion := filepath.Base(strings.TrimSuffix(submoduleUrl, filepath.Ext(submoduleUrl)))
return gui.prompt(gui.Tr.LcNewSubmoduleName, nameSuggestion, func(submoduleName string) error { return gui.prompt(promptOpts{
return gui.prompt(gui.Tr.LcNewSubmodulePath, submoduleName, func(submodulePath string) error { title: gui.Tr.LcNewSubmoduleName,
initialContent: nameSuggestion,
handleConfirm: func(submoduleName string) error {
return gui.prompt(promptOpts{
title: gui.Tr.LcNewSubmodulePath,
initialContent: submoduleName,
handleConfirm: func(submodulePath string) error {
return gui.WithWaitingStatus(gui.Tr.LcAddingSubmoduleStatus, func() error { return gui.WithWaitingStatus(gui.Tr.LcAddingSubmoduleStatus, func() error {
err := gui.GitCommand.SubmoduleAdd(submoduleName, submodulePath, submoduleUrl) err := gui.GitCommand.SubmoduleAdd(submoduleName, submodulePath, submoduleUrl)
gui.handleCredentialsPopup(err) gui.handleCredentialsPopup(err)
return gui.refreshSidePanels(refreshOptions{scope: []int{SUBMODULES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{SUBMODULES}})
}) })
},
}) })
},
}) })
},
}) })
} }
func (gui *Gui) handleEditSubmoduleUrl(submodule *models.SubmoduleConfig) error { func (gui *Gui) handleEditSubmoduleUrl(submodule *models.SubmoduleConfig) error {
return gui.prompt(fmt.Sprintf(gui.Tr.LcUpdateSubmoduleUrl, submodule.Name), submodule.Url, func(newUrl string) error { return gui.prompt(promptOpts{
title: fmt.Sprintf(gui.Tr.LcUpdateSubmoduleUrl, submodule.Name),
initialContent: submodule.Url,
handleConfirm: func(newUrl string) error {
return gui.WithWaitingStatus(gui.Tr.LcUpdatingSubmoduleUrlStatus, func() error { return gui.WithWaitingStatus(gui.Tr.LcUpdatingSubmoduleUrlStatus, func() error {
err := gui.GitCommand.SubmoduleUpdateUrl(submodule.Name, submodule.Path, newUrl) err := gui.GitCommand.SubmoduleUpdateUrl(submodule.Name, submodule.Path, newUrl)
gui.handleCredentialsPopup(err) gui.handleCredentialsPopup(err)
return gui.refreshSidePanels(refreshOptions{scope: []int{SUBMODULES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{SUBMODULES}})
}) })
},
}) })
} }

View File

@@ -97,18 +97,24 @@ func (gui *Gui) handlePushTag(g *gocui.Gui, v *gocui.View) error {
}, },
) )
return gui.prompt(title, "origin", func(response string) error { return gui.prompt(promptOpts{
title: title,
initialContent: "origin",
handleConfirm: func(response string) error {
return gui.WithWaitingStatus(gui.Tr.PushingTagStatus, func() error { return gui.WithWaitingStatus(gui.Tr.PushingTagStatus, func() error {
err := gui.GitCommand.PushTag(response, tag.Name, gui.promptUserForCredential) err := gui.GitCommand.PushTag(response, tag.Name, gui.promptUserForCredential)
gui.handleCredentialsPopup(err) gui.handleCredentialsPopup(err)
return nil return nil
}) })
},
}) })
} }
func (gui *Gui) handleCreateTag(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCreateTag(g *gocui.Gui, v *gocui.View) error {
return gui.prompt(gui.Tr.CreateTagTitle, "", func(tagName string) error { return gui.prompt(promptOpts{
title: gui.Tr.CreateTagTitle,
handleConfirm: func(tagName string) error {
// leaving commit SHA blank so that we're just creating the tag for the current commit // leaving commit SHA blank so that we're just creating the tag for the current commit
if err := gui.GitCommand.CreateLightweightTag(tagName, ""); err != nil { if err := gui.GitCommand.CreateLightweightTag(tagName, ""); err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
@@ -127,6 +133,7 @@ func (gui *Gui) handleCreateTag(g *gocui.Gui, v *gocui.View) error {
} }
}, },
}) })
},
}) })
} }