diff --git a/pkg/gui/commit_files_panel.go b/pkg/gui/commit_files_panel.go index 9f7420075..7fa57f53a 100644 --- a/pkg/gui/commit_files_panel.go +++ b/pkg/gui/commit_files_panel.go @@ -208,7 +208,7 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error { } } - if err := gui.changeContext("patch-building"); err != nil { + if err := gui.changeMainViewsContext("patch-building"); err != nil { return err } if err := gui.switchFocus(gui.g, gui.getCommitFilesView(), gui.getMainView()); err != nil { diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index d47394b75..cb459a52d 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -111,7 +111,7 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error { if g.CurrentView() == v { gui.handleCommitSelect(g, v) } - if g.CurrentView() == gui.getCommitFilesView() || (g.CurrentView() == gui.getMainView() || gui.State.Context == "patch-building") { + if g.CurrentView() == gui.getCommitFilesView() || (g.CurrentView() == gui.getMainView() || gui.State.MainContext == "patch-building") { return gui.refreshCommitFilesView() } return nil diff --git a/pkg/gui/confirmation_panel.go b/pkg/gui/confirmation_panel.go index f9e2dbfbd..db0bf7bdc 100644 --- a/pkg/gui/confirmation_panel.go +++ b/pkg/gui/confirmation_panel.go @@ -153,10 +153,10 @@ func (gui *Gui) setKeyBindings(g *gocui.Gui, handleConfirm, handleClose func(*go if err := gui.renderString(g, "options", actions); err != nil { return err } - if err := g.SetKeybinding("confirmation", gocui.KeyEnter, gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm, returnFocusOnClose)); err != nil { + if err := g.SetKeybinding("confirmation", nil, gocui.KeyEnter, gocui.ModNone, gui.wrappedConfirmationFunction(handleConfirm, returnFocusOnClose)); err != nil { return err } - return g.SetKeybinding("confirmation", gocui.KeyEsc, gocui.ModNone, gui.wrappedConfirmationFunction(handleClose, returnFocusOnClose)) + return g.SetKeybinding("confirmation", nil, gocui.KeyEsc, gocui.ModNone, gui.wrappedConfirmationFunction(handleClose, returnFocusOnClose)) } func (gui *Gui) createMessagePanel(g *gocui.Gui, currentView *gocui.View, title, prompt string) error { diff --git a/pkg/gui/context.go b/pkg/gui/context.go index be4b4dea9..6424a8707 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -1,45 +1,20 @@ package gui -func (gui *Gui) changeContext(context string) error { - oldContext := gui.State.Context - - if gui.State.Context == context { +// changeContext is a helper function for when we want to change a 'main' context +// which currently just means a context that affects both the main and secondary views +// other views can have their context changed directly but this function helps +// keep the main and secondary views in sync +func (gui *Gui) changeMainViewsContext(context string) error { + if gui.State.MainContext == context { return nil } - contextMap := gui.GetContextMap() - - oldBindings := contextMap[oldContext] - for _, binding := range oldBindings { - if err := gui.g.DeleteKeybinding(binding.ViewName, binding.Key, binding.Modifier); err != nil { - return err - } + switch context { + case "normal", "patch-building", "staging", "merging": + gui.getMainView().Context = context + gui.getSecondaryView().Context = context } - bindings := contextMap[context] - for _, binding := range bindings { - if err := gui.g.SetKeybinding(binding.ViewName, binding.Key, binding.Modifier, binding.Handler); err != nil { - return err - } - } - - gui.State.Context = context - return nil -} - -func (gui *Gui) setInitialContext() error { - contextMap := gui.GetContextMap() - - initialContext := "normal" - - bindings := contextMap[initialContext] - for _, binding := range bindings { - if err := gui.g.SetKeybinding(binding.ViewName, binding.Key, binding.Modifier, binding.Handler); err != nil { - return err - } - } - - gui.State.Context = initialContext - + gui.State.MainContext = context return nil } diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index ae3328eed..0205a193b 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -216,7 +216,7 @@ func (gui *Gui) enterFile(forceSecondaryFocused bool, selectedLineIdx int) error if file.HasMergeConflicts { return gui.createErrorPanel(gui.g, gui.Tr.SLocalize("FileStagingRequirements")) } - if err := gui.changeContext("staging"); err != nil { + if err := gui.changeMainViewsContext("staging"); err != nil { return err } if err := gui.switchFocus(gui.g, gui.getFilesView(), gui.getMainView()); err != nil { @@ -510,7 +510,7 @@ func (gui *Gui) handleSwitchToMerge(g *gocui.Gui, v *gocui.View) error { if !file.HasInlineMergeConflicts { return gui.createErrorPanel(g, gui.Tr.SLocalize("FileNoMergeCons")) } - if err := gui.changeContext("merging"); err != nil { + if err := gui.changeMainViewsContext("merging"); err != nil { return err } if err := gui.switchFocus(g, v, gui.getMainView()); err != nil { diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index f7a6d1b68..9ad461bc7 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -167,7 +167,7 @@ type guiState struct { Updating bool Panels *panelStates WorkingTreeState string // one of "merging", "rebasing", "normal" - Context string // important not to set this value directly but to use gui.changeContext("new context") + MainContext string // used to keep the main and secondary views' contexts in sync CherryPickedCommits []*commands.Commit SplitMainPanel bool RetainOriginalDir bool @@ -315,11 +315,11 @@ func (gui *Gui) onFocusLost(v *gocui.View, newView *gocui.View) error { } case "main": // if we have lost focus to a first-class panel, we need to do some cleanup - if err := gui.changeContext("normal"); err != nil { + if err := gui.changeMainViewsContext("normal"); err != nil { return err } case "commitFiles": - if gui.State.Context != "patch-building" { + if gui.State.MainContext != "patch-building" { if _, err := gui.g.SetViewOnBottom(v.Name()); err != nil { return err } @@ -582,7 +582,7 @@ func (gui *Gui) layout(g *gocui.Gui) error { } // doing this here because it'll only happen once - if err := gui.loadNewRepo(); err != nil { + if err := gui.onInitialViewsCreation(); err != nil { return err } } @@ -627,6 +627,14 @@ func (gui *Gui) layout(g *gocui.Gui) error { return gui.resizeCurrentPopupPanel(g) } +func (gui *Gui) onInitialViewsCreation() error { + if err := gui.changeMainViewsContext("normal"); err != nil { + return err + } + + return gui.loadNewRepo() +} + func (gui *Gui) loadNewRepo() error { gui.Updater.CheckForNewUpdate(gui.onBackgroundUpdateCheckFinish, false) if err := gui.updateRecentRepoList(); err != nil { diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index a31a8123b..c6f5294c4 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -9,6 +9,7 @@ import ( // is "" type Binding struct { ViewName string + Contexts []string Handler func(*gocui.Gui, *gocui.View) error Key interface{} // FIXME: find out how to get `gocui.Key | rune` Modifier gocui.Modifier @@ -73,116 +74,137 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Key: 'q', Modifier: gocui.ModNone, Handler: gui.handleQuit, - }, { + }, + { ViewName: "", Key: 'Q', Modifier: gocui.ModNone, Handler: gui.handleQuitWithoutChangingDirectory, - }, { + }, + { ViewName: "", Key: gocui.KeyCtrlC, Modifier: gocui.ModNone, Handler: gui.handleQuit, - }, { + }, + { ViewName: "", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleQuit, - }, { + }, + { ViewName: "", Key: gocui.KeyPgup, Modifier: gocui.ModNone, Handler: gui.scrollUpMain, Alternative: "fn+up", - }, { + }, + { ViewName: "", Key: gocui.KeyPgdn, Modifier: gocui.ModNone, Handler: gui.scrollDownMain, Alternative: "fn+down", - }, { + }, + { ViewName: "", Key: 'K', Modifier: gocui.ModNone, Handler: gui.scrollUpMain, - }, { + }, + { ViewName: "", Key: 'J', Modifier: gocui.ModNone, Handler: gui.scrollDownMain, - }, { + }, + { ViewName: "", Key: gocui.KeyCtrlU, Modifier: gocui.ModNone, Handler: gui.scrollUpMain, - }, { + }, + { ViewName: "", Key: gocui.KeyCtrlD, Modifier: gocui.ModNone, Handler: gui.scrollDownMain, - }, { + }, + { ViewName: "", Key: 'm', Modifier: gocui.ModNone, Handler: gui.handleCreateRebaseOptionsMenu, Description: gui.Tr.SLocalize("ViewMergeRebaseOptions"), - }, { + }, + { ViewName: "", Key: 'P', Modifier: gocui.ModNone, Handler: gui.pushFiles, Description: gui.Tr.SLocalize("push"), - }, { + }, + { ViewName: "", Key: 'p', Modifier: gocui.ModNone, Handler: gui.handlePullFiles, Description: gui.Tr.SLocalize("pull"), - }, { + }, + { ViewName: "", Key: 'R', Modifier: gocui.ModNone, Handler: gui.handleRefresh, Description: gui.Tr.SLocalize("refresh"), - }, { + }, + { ViewName: "", Key: 'x', Modifier: gocui.ModNone, Handler: gui.handleCreateOptionsMenu, - }, { + }, + { ViewName: "", Key: '?', Modifier: gocui.ModNone, Handler: gui.handleCreateOptionsMenu, - }, { + }, + { ViewName: "", Key: gocui.MouseMiddle, Modifier: gocui.ModNone, Handler: gui.handleCreateOptionsMenu, - }, { + }, + { ViewName: "", Key: gocui.KeyCtrlP, Modifier: gocui.ModNone, Handler: gui.handleCreatePatchOptionsMenu, - }, { + }, + { ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, Description: gui.Tr.SLocalize("EditConfig"), - }, { + }, + { ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig, Description: gui.Tr.SLocalize("OpenConfig"), - }, { + }, + { ViewName: "status", Key: 'u', Modifier: gocui.ModNone, Handler: gui.handleCheckForUpdate, Description: gui.Tr.SLocalize("checkForUpdate"), - }, { + }, + { ViewName: "status", Key: 's', Modifier: gocui.ModNone, @@ -202,330 +224,386 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Modifier: gocui.ModNone, Handler: gui.handleWIPCommitPress, Description: gui.Tr.SLocalize("commitChangesWithoutHook"), - }, { + }, + { ViewName: "files", Key: 'A', Modifier: gocui.ModNone, Handler: gui.handleAmendCommitPress, Description: gui.Tr.SLocalize("AmendLastCommit"), - }, { + }, + { ViewName: "files", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCommitEditorPress, Description: gui.Tr.SLocalize("CommitChangesWithEditor"), - }, { + }, + { ViewName: "files", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleFilePress, Description: gui.Tr.SLocalize("toggleStaged"), - }, { + }, + { ViewName: "files", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleCreateDiscardMenu, Description: gui.Tr.SLocalize("viewDiscardOptions"), - }, { + }, + { ViewName: "files", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleFileEdit, Description: gui.Tr.SLocalize("editFile"), - }, { + }, + { ViewName: "files", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleFileOpen, Description: gui.Tr.SLocalize("openFile"), - }, { + }, + { ViewName: "files", Key: 'i', Modifier: gocui.ModNone, Handler: gui.handleIgnoreFile, Description: gui.Tr.SLocalize("ignoreFile"), - }, { + }, + { ViewName: "files", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRefreshFiles, Description: gui.Tr.SLocalize("refreshFiles"), - }, { + }, + { ViewName: "files", Key: 's', Modifier: gocui.ModNone, Handler: gui.handleStashChanges, Description: gui.Tr.SLocalize("stashAllChanges"), - }, { + }, + { ViewName: "files", Key: 'S', Modifier: gocui.ModNone, Handler: gui.handleCreateStashMenu, Description: gui.Tr.SLocalize("viewStashOptions"), - }, { + }, + { ViewName: "files", Key: 'a', Modifier: gocui.ModNone, Handler: gui.handleStageAll, Description: gui.Tr.SLocalize("toggleStagedAll"), - }, { + }, + { ViewName: "files", Key: 'D', Modifier: gocui.ModNone, Handler: gui.handleCreateResetMenu, Description: gui.Tr.SLocalize("viewResetOptions"), - }, { + }, + { ViewName: "files", Key: gocui.KeyEnter, Modifier: gocui.ModNone, Handler: gui.handleEnterFile, Description: gui.Tr.SLocalize("StageLines"), - }, { + }, + { ViewName: "files", Key: 'f', Modifier: gocui.ModNone, Handler: gui.handleGitFetch, Description: gui.Tr.SLocalize("fetch"), - }, { + }, + { ViewName: "files", Key: 'X', Modifier: gocui.ModNone, Handler: gui.handleCustomCommand, Description: gui.Tr.SLocalize("executeCustomCommand"), - }, { + }, + { ViewName: "branches", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleBranchPress, Description: gui.Tr.SLocalize("checkout"), - }, { + }, + { ViewName: "branches", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleCreatePullRequestPress, Description: gui.Tr.SLocalize("createPullRequest"), - }, { + }, + { ViewName: "branches", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCheckoutByName, Description: gui.Tr.SLocalize("checkoutByName"), - }, { + }, + { ViewName: "branches", Key: 'F', Modifier: gocui.ModNone, Handler: gui.handleForceCheckout, Description: gui.Tr.SLocalize("forceCheckout"), - }, { + }, + { ViewName: "branches", Key: 'n', Modifier: gocui.ModNone, Handler: gui.handleNewBranch, Description: gui.Tr.SLocalize("newBranch"), - }, { + }, + { ViewName: "branches", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleDeleteBranch, Description: gui.Tr.SLocalize("deleteBranch"), - }, { + }, + { ViewName: "branches", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRebase, Description: gui.Tr.SLocalize("rebaseBranch"), - }, { + }, + { ViewName: "branches", Key: 'M', Modifier: gocui.ModNone, Handler: gui.handleMerge, Description: gui.Tr.SLocalize("mergeIntoCurrentBranch"), - }, { + }, + { ViewName: "branches", Key: 'f', Modifier: gocui.ModNone, Handler: gui.handleFastForward, Description: gui.Tr.SLocalize("FastForward"), - }, { + }, + { ViewName: "commits", Key: 's', Modifier: gocui.ModNone, Handler: gui.handleCommitSquashDown, Description: gui.Tr.SLocalize("squashDown"), - }, { + }, + { ViewName: "commits", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRenameCommit, Description: gui.Tr.SLocalize("renameCommit"), - }, { + }, + { ViewName: "commits", Key: 'R', Modifier: gocui.ModNone, Handler: gui.handleRenameCommitEditor, Description: gui.Tr.SLocalize("renameCommitEditor"), - }, { + }, + { ViewName: "commits", Key: 'g', Modifier: gocui.ModNone, Handler: gui.handleCreateCommitResetMenu, Description: gui.Tr.SLocalize("resetToThisCommit"), - }, { + }, + { ViewName: "commits", Key: 'f', Modifier: gocui.ModNone, Handler: gui.handleCommitFixup, Description: gui.Tr.SLocalize("fixupCommit"), - }, { + }, + { ViewName: "commits", Key: 'F', Modifier: gocui.ModNone, Handler: gui.handleCreateFixupCommit, Description: gui.Tr.SLocalize("createFixupCommit"), - }, { + }, + { ViewName: "commits", Key: 'S', Modifier: gocui.ModNone, Handler: gui.handleSquashAllAboveFixupCommits, Description: gui.Tr.SLocalize("squashAboveCommits"), - }, { + }, + { ViewName: "commits", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleCommitDelete, Description: gui.Tr.SLocalize("deleteCommit"), - }, { + }, + { ViewName: "commits", Key: gocui.KeyCtrlJ, Modifier: gocui.ModNone, Handler: gui.handleCommitMoveDown, Description: gui.Tr.SLocalize("moveDownCommit"), - }, { + }, + { ViewName: "commits", Key: gocui.KeyCtrlK, Modifier: gocui.ModNone, Handler: gui.handleCommitMoveUp, Description: gui.Tr.SLocalize("moveUpCommit"), - }, { + }, + { ViewName: "commits", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleCommitEdit, Description: gui.Tr.SLocalize("editCommit"), - }, { + }, + { ViewName: "commits", Key: 'A', Modifier: gocui.ModNone, Handler: gui.handleCommitAmendTo, Description: gui.Tr.SLocalize("amendToCommit"), - }, { + }, + { ViewName: "commits", Key: 'p', Modifier: gocui.ModNone, Handler: gui.handleCommitPick, Description: gui.Tr.SLocalize("pickCommit"), - }, { + }, + { ViewName: "commits", Key: 't', Modifier: gocui.ModNone, Handler: gui.handleCommitRevert, Description: gui.Tr.SLocalize("revertCommit"), - }, { + }, + { ViewName: "commits", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCopyCommit, Description: gui.Tr.SLocalize("cherryPickCopy"), - }, { + }, + { ViewName: "commits", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCopyCommitRange, Description: gui.Tr.SLocalize("cherryPickCopyRange"), - }, { + }, + { ViewName: "commits", Key: 'v', Modifier: gocui.ModNone, Handler: gui.HandlePasteCommits, Description: gui.Tr.SLocalize("pasteCommits"), - }, { + }, + { ViewName: "commits", Key: gocui.KeyEnter, Modifier: gocui.ModNone, Handler: gui.handleSwitchToCommitFilesPanel, Description: gui.Tr.SLocalize("viewCommitFiles"), - }, { + }, + { ViewName: "commits", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleToggleDiffCommit, Description: gui.Tr.SLocalize("CommitsDiff"), - }, { + }, + { ViewName: "stash", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleStashApply, Description: gui.Tr.SLocalize("apply"), - }, { + }, + { ViewName: "stash", Key: 'g', Modifier: gocui.ModNone, Handler: gui.handleStashPop, Description: gui.Tr.SLocalize("pop"), - }, { + }, + { ViewName: "stash", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleStashDrop, Description: gui.Tr.SLocalize("drop"), - }, { + }, + { ViewName: "commitMessage", Key: gocui.KeyEnter, Modifier: gocui.ModNone, Handler: gui.handleCommitConfirm, - }, { + }, + { ViewName: "commitMessage", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleCommitClose, - }, { + }, + { ViewName: "credentials", Key: gocui.KeyEnter, Modifier: gocui.ModNone, Handler: gui.handleSubmitCredential, - }, { + }, + { ViewName: "credentials", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleCloseCredentialsView, - }, { + }, + { ViewName: "menu", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleMenuClose, - }, { + }, + { ViewName: "menu", Key: 'q', Modifier: gocui.ModNone, Handler: gui.handleMenuClose, - }, { + }, + { ViewName: "information", Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleDonate, - }, { + }, + { ViewName: "commitFiles", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleSwitchToCommitsPanel, Description: gui.Tr.SLocalize("goBack"), - }, { + }, + { ViewName: "commitFiles", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCheckoutCommitFile, Description: gui.Tr.SLocalize("checkoutCommitFile"), - }, { + }, + { ViewName: "commitFiles", Key: 'd', Modifier: gocui.ModNone, @@ -565,6 +643,341 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Modifier: gocui.ModNone, Handler: gui.scrollDownSecondary, }, + { + ViewName: "secondary", + Contexts: []string{"normal"}, + Key: gocui.MouseLeft, + Modifier: gocui.ModNone, + Handler: gui.handleMouseDownSecondary, + }, + { + ViewName: "main", + Contexts: []string{"normal"}, + Key: gocui.MouseWheelDown, + Modifier: gocui.ModNone, + Handler: gui.scrollDownMain, + Description: gui.Tr.SLocalize("ScrollDown"), + Alternative: "fn+up", + }, + { + ViewName: "main", + Contexts: []string{"normal"}, + Key: gocui.MouseWheelUp, + Modifier: gocui.ModNone, + Handler: gui.scrollUpMain, + Description: gui.Tr.SLocalize("ScrollUp"), + Alternative: "fn+down", + }, + { + ViewName: "main", + Contexts: []string{"normal"}, + Key: gocui.MouseLeft, + Modifier: gocui.ModNone, + Handler: gui.handleMouseDownMain, + }, + { + ViewName: "secondary", + Contexts: []string{"staging"}, + Key: gocui.MouseLeft, + Modifier: gocui.ModNone, + Handler: gui.handleTogglePanelClick, + }, + { + ViewName: "main", + Contexts: []string{"staging"}, + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleStagingEscape, + Description: gui.Tr.SLocalize("ReturnToFilesPanel"), + }, + { + ViewName: "main", + Contexts: []string{"staging"}, + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleStageSelection, + Description: gui.Tr.SLocalize("StageSelection"), + }, + { + ViewName: "main", + Contexts: []string{"staging"}, + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.handleResetSelection, + Description: gui.Tr.SLocalize("ResetSelection"), + }, + { + ViewName: "main", + Contexts: []string{"staging"}, + Key: gocui.KeyTab, + Modifier: gocui.ModNone, + Handler: gui.handleTogglePanel, + Description: gui.Tr.SLocalize("TogglePanel"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building"}, + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleEscapePatchBuildingPanel, + Description: gui.Tr.SLocalize("ExitLineByLineMode"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.KeyArrowUp, + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevLine, + Description: gui.Tr.SLocalize("PrevLine"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.KeyArrowDown, + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextLine, + Description: gui.Tr.SLocalize("NextLine"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: 'k', + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevLine, + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: 'j', + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextLine, + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.MouseWheelUp, + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevLine, + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.MouseWheelDown, + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextLine, + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.KeyArrowLeft, + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevHunk, + Description: gui.Tr.SLocalize("PrevHunk"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.KeyArrowRight, + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextHunk, + Description: gui.Tr.SLocalize("NextHunk"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: 'h', + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevHunk, + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: 'l', + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextHunk, + }, + { + ViewName: "main", + Contexts: []string{"staging"}, + Key: 'e', + Modifier: gocui.ModNone, + Handler: gui.handleFileEdit, + Description: gui.Tr.SLocalize("editFile"), + }, + { + ViewName: "main", + Contexts: []string{"staging"}, + Key: 'o', + Modifier: gocui.ModNone, + Handler: gui.handleFileOpen, + Description: gui.Tr.SLocalize("openFile"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building"}, + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleAddSelectionToPatch, + Description: gui.Tr.SLocalize("StageSelection"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building"}, + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.handleRemoveSelectionFromPatch, + Description: gui.Tr.SLocalize("ResetSelection"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: 'v', + Modifier: gocui.ModNone, + Handler: gui.handleToggleSelectRange, + Description: gui.Tr.SLocalize("ToggleDragSelect"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: 'a', + Modifier: gocui.ModNone, + Handler: gui.handleToggleSelectHunk, + Description: gui.Tr.SLocalize("ToggleSelectHunk"), + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.MouseLeft, + Modifier: gocui.ModNone, + Handler: gui.handleMouseDown, + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.MouseLeft, + Modifier: gocui.ModMotion, + Handler: gui.handleMouseDrag, + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.MouseWheelUp, + Modifier: gocui.ModNone, + Handler: gui.handleMouseScrollUp, + }, + { + ViewName: "main", + Contexts: []string{"patch-building", "staging"}, + Key: gocui.MouseWheelDown, + Modifier: gocui.ModNone, + Handler: gui.handleMouseScrollDown, + }, + { + ViewName: "main", + Contexts: []string{"merging"}, + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleEscapeMerge, + Description: gui.Tr.SLocalize("ReturnToFilesPanel"), + }, + { + ViewName: "main", + Contexts: []string{"merging"}, + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handlePickHunk, + Description: gui.Tr.SLocalize("PickHunk"), + }, + { + ViewName: "main", + Contexts: []string{"merging"}, + Key: 'b', + Modifier: gocui.ModNone, + Handler: gui.handlePickBothHunks, + Description: gui.Tr.SLocalize("PickBothHunks"), + }, + { + ViewName: "main", + Contexts: []string{"merging"}, + Key: gocui.KeyArrowLeft, + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevConflict, + Description: gui.Tr.SLocalize("PrevConflict"), + }, + { + ViewName: "main", + Contexts: []string{"merging"}, + Key: gocui.KeyArrowRight, + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextConflict, + Description: gui.Tr.SLocalize("NextConflict"), + }, + { + ViewName: "main", + Contexts: []string{"merging"}, + Key: gocui.KeyArrowUp, + Modifier: gocui.ModNone, + Handler: gui.handleSelectTop, + Description: gui.Tr.SLocalize("SelectTop"), + }, + { + ViewName: "main", + Contexts: []string{"merging"}, + Key: gocui.KeyArrowDown, + Modifier: gocui.ModNone, + Handler: gui.handleSelectBottom, + Description: gui.Tr.SLocalize("SelectBottom"), + }, + { + ViewName: "main", + Contexts: []string{"mergin"}, + Key: gocui.MouseWheelUp, + Modifier: gocui.ModNone, + Handler: gui.handleSelectTop, + }, + { + ViewName: "main", + Contexts: []string{"mergin"}, + Key: gocui.MouseWheelDown, + Modifier: gocui.ModNone, + Handler: gui.handleSelectBottom, + }, + { + ViewName: "main", + Contexts: []string{"mergin"}, + Key: 'h', + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevConflict, + }, + { + ViewName: "main", + Contexts: []string{"mergin"}, + Key: 'l', + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextConflict, + }, + { + ViewName: "main", + Contexts: []string{"mergin"}, + Key: 'k', + Modifier: gocui.ModNone, + Handler: gui.handleSelectTop, + }, + { + ViewName: "main", + Contexts: []string{"mergin"}, + Key: 'j', + Modifier: gocui.ModNone, + Handler: gui.handleSelectBottom, + }, + { + ViewName: "main", + Contexts: []string{"merging"}, + Key: 'z', + Modifier: gocui.ModNone, + Handler: gui.handlePopFileSnapshot, + Description: gui.Tr.SLocalize("Undo"), + }, } for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "stash", "menu"} { @@ -611,26 +1024,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { return bindings } -// GetCurrentKeybindings gets the list of keybindings given the current context -func (gui *Gui) GetCurrentKeybindings() []*Binding { - bindings := gui.GetInitialKeybindings() - currentContext := gui.State.Context - contextBindings := gui.GetContextMap()[currentContext] - - return append(bindings, contextBindings...) -} - func (gui *Gui) keybindings(g *gocui.Gui) error { bindings := gui.GetInitialKeybindings() for _, binding := range bindings { - if err := g.SetKeybinding(binding.ViewName, binding.Key, binding.Modifier, binding.Handler); err != nil { + if err := g.SetKeybinding(binding.ViewName, binding.Contexts, binding.Key, binding.Modifier, binding.Handler); err != nil { return err } } - if err := gui.setInitialContext(); err != nil { - return err - } if err := g.SetTabClickBinding("branches", gui.onBranchesTabClick); err != nil { return err @@ -638,345 +1039,3 @@ func (gui *Gui) keybindings(g *gocui.Gui) error { return nil } - -func (gui *Gui) GetContextMap() map[string][]*Binding { - return map[string][]*Binding{ - "normal": { - { - ViewName: "secondary", - Key: gocui.MouseLeft, - Modifier: gocui.ModNone, - Handler: gui.handleMouseDownSecondary, - }, - { - ViewName: "main", - Key: gocui.MouseWheelDown, - Modifier: gocui.ModNone, - Handler: gui.scrollDownMain, - Description: gui.Tr.SLocalize("ScrollDown"), - Alternative: "fn+up", - }, { - ViewName: "main", - Key: gocui.MouseWheelUp, - Modifier: gocui.ModNone, - Handler: gui.scrollUpMain, - Description: gui.Tr.SLocalize("ScrollUp"), - Alternative: "fn+down", - }, { - ViewName: "main", - Key: gocui.MouseLeft, - Modifier: gocui.ModNone, - Handler: gui.handleMouseDownMain, - }, - }, - "staging": { - { - ViewName: "secondary", - Key: gocui.MouseLeft, - Modifier: gocui.ModNone, - Handler: gui.handleTogglePanelClick, - }, - { - ViewName: "main", - Key: gocui.KeyEsc, - Modifier: gocui.ModNone, - Handler: gui.handleStagingEscape, - Description: gui.Tr.SLocalize("ReturnToFilesPanel"), - }, { - ViewName: "main", - Key: gocui.KeyArrowUp, - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevLine, - Description: gui.Tr.SLocalize("PrevLine"), - }, { - ViewName: "main", - Key: gocui.KeyArrowDown, - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextLine, - Description: gui.Tr.SLocalize("NextLine"), - }, { - ViewName: "main", - Key: 'k', - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevLine, - }, { - ViewName: "main", - Key: 'j', - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextLine, - }, { - ViewName: "main", - Key: gocui.KeyArrowLeft, - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevHunk, - Description: gui.Tr.SLocalize("PrevHunk"), - }, { - ViewName: "main", - Key: gocui.KeyArrowRight, - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextHunk, - Description: gui.Tr.SLocalize("NextHunk"), - }, { - ViewName: "main", - Key: 'h', - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevHunk, - }, { - ViewName: "main", - Key: 'l', - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextHunk, - }, { - ViewName: "main", - Key: gocui.KeySpace, - Modifier: gocui.ModNone, - Handler: gui.handleStageSelection, - Description: gui.Tr.SLocalize("StageSelection"), - }, { - ViewName: "main", - Key: 'd', - Modifier: gocui.ModNone, - Handler: gui.handleResetSelection, - Description: gui.Tr.SLocalize("ResetSelection"), - }, { - ViewName: "main", - Key: 'v', - Modifier: gocui.ModNone, - Handler: gui.handleToggleSelectRange, - Description: gui.Tr.SLocalize("ToggleDragSelect"), - }, { - ViewName: "main", - Key: 'a', - Modifier: gocui.ModNone, - Handler: gui.handleToggleSelectHunk, - Description: gui.Tr.SLocalize("ToggleSelectHunk"), - }, { - ViewName: "main", - Key: gocui.KeyTab, - Modifier: gocui.ModNone, - Handler: gui.handleTogglePanel, - Description: gui.Tr.SLocalize("TogglePanel"), - }, { - ViewName: "main", - Key: gocui.MouseLeft, - Modifier: gocui.ModNone, - Handler: gui.handleMouseDown, - }, { - ViewName: "main", - Key: gocui.MouseLeft, - Modifier: gocui.ModMotion, - Handler: gui.handleMouseDrag, - }, { - ViewName: "main", - Key: gocui.MouseWheelUp, - Modifier: gocui.ModNone, - Handler: gui.handleMouseScrollUp, - }, { - ViewName: "main", - Key: gocui.MouseWheelDown, - Modifier: gocui.ModNone, - Handler: gui.handleMouseScrollDown, - }, - }, - "patch-building": { - { - ViewName: "main", - Key: gocui.KeyEsc, - Modifier: gocui.ModNone, - Handler: gui.handleEscapePatchBuildingPanel, - Description: gui.Tr.SLocalize("ExitLineByLineMode"), - }, { - ViewName: "main", - Key: gocui.KeyArrowUp, - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevLine, - Description: gui.Tr.SLocalize("PrevLine"), - }, { - ViewName: "main", - Key: gocui.KeyArrowDown, - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextLine, - Description: gui.Tr.SLocalize("NextLine"), - }, { - ViewName: "main", - Key: 'k', - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevLine, - }, { - ViewName: "main", - Key: 'j', - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextLine, - }, { - ViewName: "main", - Key: gocui.MouseWheelUp, - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevLine, - }, { - ViewName: "main", - Key: gocui.MouseWheelDown, - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextLine, - }, { - ViewName: "main", - Key: gocui.KeyArrowLeft, - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevHunk, - Description: gui.Tr.SLocalize("PrevHunk"), - }, { - ViewName: "main", - Key: gocui.KeyArrowRight, - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextHunk, - Description: gui.Tr.SLocalize("NextHunk"), - }, { - ViewName: "main", - Key: 'h', - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevHunk, - }, { - ViewName: "main", - Key: 'l', - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextHunk, - }, { - ViewName: "main", - Key: gocui.KeySpace, - Modifier: gocui.ModNone, - Handler: gui.handleAddSelectionToPatch, - Description: gui.Tr.SLocalize("StageSelection"), - }, { - ViewName: "main", - Key: 'd', - Modifier: gocui.ModNone, - Handler: gui.handleRemoveSelectionFromPatch, - Description: gui.Tr.SLocalize("ResetSelection"), - }, { - ViewName: "main", - Key: 'v', - Modifier: gocui.ModNone, - Handler: gui.handleToggleSelectRange, - Description: gui.Tr.SLocalize("ToggleDragSelect"), - }, { - ViewName: "main", - Key: 'a', - Modifier: gocui.ModNone, - Handler: gui.handleToggleSelectHunk, - Description: gui.Tr.SLocalize("ToggleSelectHunk"), - }, { - ViewName: "main", - Key: gocui.MouseLeft, - Modifier: gocui.ModNone, - Handler: gui.handleMouseDown, - }, { - ViewName: "main", - Key: gocui.MouseLeft, - Modifier: gocui.ModMotion, - Handler: gui.handleMouseDrag, - }, { - ViewName: "main", - Key: gocui.MouseWheelUp, - Modifier: gocui.ModNone, - Handler: gui.handleMouseScrollUp, - }, { - ViewName: "main", - Key: gocui.MouseWheelDown, - Modifier: gocui.ModNone, - Handler: gui.handleMouseScrollDown, - }, - }, - "merging": { - { - ViewName: "main", - Key: gocui.KeyEsc, - Modifier: gocui.ModNone, - Handler: gui.handleEscapeMerge, - Description: gui.Tr.SLocalize("ReturnToFilesPanel"), - }, { - ViewName: "main", - Key: gocui.KeySpace, - Modifier: gocui.ModNone, - Handler: gui.handlePickHunk, - Description: gui.Tr.SLocalize("PickHunk"), - }, { - ViewName: "main", - Key: 'b', - Modifier: gocui.ModNone, - Handler: gui.handlePickBothHunks, - Description: gui.Tr.SLocalize("PickBothHunks"), - }, { - ViewName: "main", - Key: gocui.KeyArrowLeft, - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevConflict, - Description: gui.Tr.SLocalize("PrevConflict"), - }, { - ViewName: "main", - Key: gocui.KeyArrowRight, - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextConflict, - Description: gui.Tr.SLocalize("NextConflict"), - }, { - ViewName: "main", - Key: gocui.KeyArrowUp, - Modifier: gocui.ModNone, - Handler: gui.handleSelectTop, - Description: gui.Tr.SLocalize("SelectTop"), - }, { - ViewName: "main", - Key: gocui.KeyArrowDown, - Modifier: gocui.ModNone, - Handler: gui.handleSelectBottom, - Description: gui.Tr.SLocalize("SelectBottom"), - }, { - ViewName: "main", - Key: gocui.MouseWheelUp, - Modifier: gocui.ModNone, - Handler: gui.handleSelectTop, - }, { - ViewName: "main", - Key: gocui.MouseWheelDown, - Modifier: gocui.ModNone, - Handler: gui.handleSelectBottom, - }, { - ViewName: "main", - Key: 'h', - Modifier: gocui.ModNone, - Handler: gui.handleSelectPrevConflict, - }, { - ViewName: "main", - Key: 'l', - Modifier: gocui.ModNone, - Handler: gui.handleSelectNextConflict, - }, { - ViewName: "main", - Key: 'k', - Modifier: gocui.ModNone, - Handler: gui.handleSelectTop, - }, { - ViewName: "main", - Key: 'j', - Modifier: gocui.ModNone, - Handler: gui.handleSelectBottom, - }, { - ViewName: "main", - Key: 'z', - Modifier: gocui.ModNone, - Handler: gui.handlePopFileSnapshot, - Description: gui.Tr.SLocalize("Undo"), - }, { - ViewName: "main", - Key: 'e', - Modifier: gocui.ModNone, - Handler: gui.handleFileEdit, - Description: gui.Tr.SLocalize("editFile"), - }, { - ViewName: "main", - Key: 'o', - Modifier: gocui.ModNone, - Handler: gui.handleFileOpen, - Description: gui.Tr.SLocalize("openFile"), - }, - }, - } -} diff --git a/pkg/gui/line_by_line_panel.go b/pkg/gui/line_by_line_panel.go index 5aeaeeba2..8c46fd134 100644 --- a/pkg/gui/line_by_line_panel.go +++ b/pkg/gui/line_by_line_panel.go @@ -226,7 +226,7 @@ func (gui *Gui) refreshMainView() error { var includedLineIndices []int // I'd prefer not to have knowledge of contexts using this file but I'm not sure // how to get around this - if gui.State.Context == "patch-building" { + if gui.State.MainContext == "patch-building" { filename := gui.State.CommitFiles[gui.State.Panels.CommitFiles.SelectedLine].Name includedLineIndices = gui.GitCommand.PatchManager.GetFileIncLineIndices(filename) } diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go index f15b99d76..17be7bea8 100644 --- a/pkg/gui/menu_panel.go +++ b/pkg/gui/menu_panel.go @@ -87,7 +87,7 @@ func (gui *Gui) createMenu(title string, items interface{}, itemCount int, handl for _, key := range []gocui.Key{gocui.KeySpace, gocui.KeyEnter, 'y'} { _ = gui.g.DeleteKeybinding("menu", key, gocui.ModNone) - if err := gui.g.SetKeybinding("menu", key, gocui.ModNone, wrappedHandlePress); err != nil { + if err := gui.g.SetKeybinding("menu", nil, key, gocui.ModNone, wrappedHandlePress); err != nil { return err } } diff --git a/pkg/gui/options_menu_panel.go b/pkg/gui/options_menu_panel.go index dfd354839..85a25677e 100644 --- a/pkg/gui/options_menu_panel.go +++ b/pkg/gui/options_menu_panel.go @@ -6,6 +6,7 @@ import ( "github.com/go-errors/errors" "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/utils" ) func (gui *Gui) getBindings(v *gocui.View) []*Binding { @@ -13,7 +14,7 @@ func (gui *Gui) getBindings(v *gocui.View) []*Binding { bindingsGlobal, bindingsPanel []*Binding ) - bindings := gui.GetCurrentKeybindings() + bindings := gui.GetInitialKeybindings() for _, binding := range bindings { if binding.GetKey() != "" && binding.Description != "" { @@ -21,7 +22,9 @@ func (gui *Gui) getBindings(v *gocui.View) []*Binding { case "": bindingsGlobal = append(bindingsGlobal, binding) case v.Name(): - bindingsPanel = append(bindingsPanel, binding) + if len(binding.Contexts) == 0 || utils.IncludesString(binding.Contexts, v.Context) { + bindingsPanel = append(bindingsPanel, binding) + } } } } diff --git a/pkg/gui/patch_building_panel.go b/pkg/gui/patch_building_panel.go index bc400cd24..8a3d5db89 100644 --- a/pkg/gui/patch_building_panel.go +++ b/pkg/gui/patch_building_panel.go @@ -88,7 +88,7 @@ func (gui *Gui) handleRemoveSelectionFromPatch(g *gocui.Gui, v *gocui.View) erro func (gui *Gui) handleEscapePatchBuildingPanel(g *gocui.Gui, v *gocui.View) error { gui.State.Panels.LineByLine = nil - gui.changeContext("normal") + gui.changeMainViewsContext("normal") if gui.GitCommand.PatchManager.IsEmpty() { gui.GitCommand.PatchManager.Reset() diff --git a/pkg/gui/patch_options_panel.go b/pkg/gui/patch_options_panel.go index 009faa83d..00801a203 100644 --- a/pkg/gui/patch_options_panel.go +++ b/pkg/gui/patch_options_panel.go @@ -67,7 +67,7 @@ func (gui *Gui) validateNormalWorkingTreeState() (bool, error) { } func (gui *Gui) returnFocusFromLineByLinePanelIfNecessary() error { - if gui.State.Context == "patch-building" { + if gui.State.MainContext == "patch-building" { return gui.handleEscapePatchBuildingPanel(gui.g, nil) } return nil diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index ec1b3f647..a8e4872e1 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -117,7 +117,7 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error { case "credentials": return gui.handleCredentialsViewFocused(g, v) case "main": - if gui.State.Context == "merging" { + if gui.State.MainContext == "merging" { return gui.refreshMergePanel() } v.Highlight = false @@ -406,7 +406,7 @@ func (gui *Gui) renderPanelOptions() error { case "menu": return gui.renderMenuOptions() case "main": - if gui.State.Context == "merging" { + if gui.State.MainContext == "merging" { return gui.renderMergeOptions() } }