package gui import ( "fmt" "log" "strings" "unicode/utf8" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/constants" ) // Binding - a keybinding mapping a key and modifier to a handler. The keypress // is only handled if the given view has focus, or handled globally if the view // is "" type Binding struct { ViewName string Contexts []string Handler func() error Key interface{} // FIXME: find out how to get `gocui.Key | rune` Modifier gocui.Modifier Description string Alternative string Tag string // e.g. 'navigation'. Used for grouping things in the cheatsheet OpensMenu bool } // GetDisplayStrings returns the display string of a file func (b *Binding) GetDisplayStrings(isFocused bool) []string { return []string{GetKeyDisplay(b.Key), b.Description} } var keyMapReversed = map[gocui.Key]string{ gocui.KeyF1: "f1", gocui.KeyF2: "f2", gocui.KeyF3: "f3", gocui.KeyF4: "f4", gocui.KeyF5: "f5", gocui.KeyF6: "f6", gocui.KeyF7: "f7", gocui.KeyF8: "f8", gocui.KeyF9: "f9", gocui.KeyF10: "f10", gocui.KeyF11: "f11", gocui.KeyF12: "f12", gocui.KeyInsert: "insert", gocui.KeyDelete: "delete", gocui.KeyHome: "home", gocui.KeyEnd: "end", gocui.KeyPgup: "pgup", gocui.KeyPgdn: "pgdown", gocui.KeyArrowUp: "▲", gocui.KeyArrowDown: "▼", gocui.KeyArrowLeft: "◄", gocui.KeyArrowRight: "►", gocui.KeyTab: "tab", // ctrl+i gocui.KeyBacktab: "shift+tab", gocui.KeyEnter: "enter", // ctrl+m gocui.KeyAltEnter: "alt+enter", gocui.KeyEsc: "esc", // ctrl+[, ctrl+3 gocui.KeyBackspace: "backspace", // ctrl+h gocui.KeyCtrlSpace: "ctrl+space", // ctrl+~, ctrl+2 gocui.KeyCtrlSlash: "ctrl+/", // ctrl+_ gocui.KeySpace: "space", gocui.KeyCtrlA: "ctrl+a", gocui.KeyCtrlB: "ctrl+b", gocui.KeyCtrlC: "ctrl+c", gocui.KeyCtrlD: "ctrl+d", gocui.KeyCtrlE: "ctrl+e", gocui.KeyCtrlF: "ctrl+f", gocui.KeyCtrlG: "ctrl+g", gocui.KeyCtrlJ: "ctrl+j", gocui.KeyCtrlK: "ctrl+k", gocui.KeyCtrlL: "ctrl+l", gocui.KeyCtrlN: "ctrl+n", gocui.KeyCtrlO: "ctrl+o", gocui.KeyCtrlP: "ctrl+p", gocui.KeyCtrlQ: "ctrl+q", gocui.KeyCtrlR: "ctrl+r", gocui.KeyCtrlS: "ctrl+s", gocui.KeyCtrlT: "ctrl+t", gocui.KeyCtrlU: "ctrl+u", gocui.KeyCtrlV: "ctrl+v", gocui.KeyCtrlW: "ctrl+w", gocui.KeyCtrlX: "ctrl+x", gocui.KeyCtrlY: "ctrl+y", gocui.KeyCtrlZ: "ctrl+z", gocui.KeyCtrl4: "ctrl+4", // ctrl+\ gocui.KeyCtrl5: "ctrl+5", // ctrl+] gocui.KeyCtrl6: "ctrl+6", gocui.KeyCtrl8: "ctrl+8", } var keymap = map[string]interface{}{ "": gocui.KeyCtrlA, "": gocui.KeyCtrlB, "": gocui.KeyCtrlC, "": gocui.KeyCtrlD, "": gocui.KeyCtrlE, "": gocui.KeyCtrlF, "": gocui.KeyCtrlG, "": gocui.KeyCtrlH, "": gocui.KeyCtrlI, "": gocui.KeyCtrlJ, "": gocui.KeyCtrlK, "": gocui.KeyCtrlL, "": gocui.KeyCtrlM, "": gocui.KeyCtrlN, "": gocui.KeyCtrlO, "": gocui.KeyCtrlP, "": gocui.KeyCtrlQ, "": gocui.KeyCtrlR, "": gocui.KeyCtrlS, "": gocui.KeyCtrlT, "": gocui.KeyCtrlU, "": gocui.KeyCtrlV, "": gocui.KeyCtrlW, "": gocui.KeyCtrlX, "": gocui.KeyCtrlY, "": gocui.KeyCtrlZ, "": gocui.KeyCtrlTilde, "": gocui.KeyCtrl2, "": gocui.KeyCtrl3, "": gocui.KeyCtrl4, "": gocui.KeyCtrl5, "": gocui.KeyCtrl6, "": gocui.KeyCtrl7, "": gocui.KeyCtrl8, "": gocui.KeyCtrlSpace, "": gocui.KeyCtrlBackslash, "": gocui.KeyCtrlLsqBracket, "": gocui.KeyCtrlRsqBracket, "": gocui.KeyCtrlSlash, "": gocui.KeyCtrlUnderscore, "": gocui.KeyBackspace, "": gocui.KeyTab, "": gocui.KeyBacktab, "": gocui.KeyEnter, "": gocui.KeyAltEnter, "": gocui.KeyEsc, "": gocui.KeySpace, "": gocui.KeyF1, "": gocui.KeyF2, "": gocui.KeyF3, "": gocui.KeyF4, "": gocui.KeyF5, "": gocui.KeyF6, "": gocui.KeyF7, "": gocui.KeyF8, "": gocui.KeyF9, "": gocui.KeyF10, "": gocui.KeyF11, "": gocui.KeyF12, "": gocui.KeyInsert, "": gocui.KeyDelete, "": gocui.KeyHome, "": gocui.KeyEnd, "": gocui.KeyPgup, "": gocui.KeyPgdn, "": gocui.KeyArrowUp, "": gocui.KeyArrowDown, "": gocui.KeyArrowLeft, "": gocui.KeyArrowRight, } func (gui *Gui) getKeyDisplay(name string) string { key := gui.getKey(name) return GetKeyDisplay(key) } func GetKeyDisplay(key interface{}) string { keyInt := 0 switch key := key.(type) { case rune: keyInt = int(key) case gocui.Key: value, ok := keyMapReversed[key] if ok { return value } keyInt = int(key) } return fmt.Sprintf("%c", keyInt) } func (gui *Gui) getKey(key string) interface{} { runeCount := utf8.RuneCountInString(key) if runeCount > 1 { binding := keymap[strings.ToLower(key)] if binding == nil { log.Fatalf("Unrecognized key %s for keybinding. For permitted values see %s", strings.ToLower(key), constants.Links.Docs.CustomKeybindings) } else { return binding } } else if runeCount == 1 { return []rune(key)[0] } log.Fatal("Key empty for keybinding: " + strings.ToLower(key)) return nil } // GetInitialKeybindings is a function. func (gui *Gui) GetInitialKeybindings() []*Binding { config := gui.Config.GetUserConfig().Keybinding bindings := []*Binding{ { ViewName: "", Key: gui.getKey(config.Universal.Quit), Modifier: gocui.ModNone, Handler: gui.handleQuit, }, { ViewName: "", Key: gui.getKey(config.Universal.QuitWithoutChangingDirectory), Modifier: gocui.ModNone, Handler: gui.handleQuitWithoutChangingDirectory, }, { ViewName: "", Key: gui.getKey(config.Universal.QuitAlt1), Modifier: gocui.ModNone, Handler: gui.handleQuit, }, { ViewName: "", Key: gui.getKey(config.Universal.Return), Modifier: gocui.ModNone, Handler: gui.handleTopLevelReturn, }, { ViewName: "", Key: gui.getKey(config.Universal.OpenRecentRepos), Handler: gui.handleCreateRecentReposMenu, Alternative: "", Description: gui.Tr.SwitchRepo, }, { ViewName: "", Key: gui.getKey(config.Universal.ScrollUpMain), Handler: gui.scrollUpMain, Alternative: "fn+up", Description: gui.Tr.LcScrollUpMainPanel, }, { ViewName: "", Key: gui.getKey(config.Universal.ScrollDownMain), Handler: gui.scrollDownMain, Alternative: "fn+down", Description: gui.Tr.LcScrollDownMainPanel, }, { ViewName: "", Key: gui.getKey(config.Universal.ScrollUpMainAlt1), Modifier: gocui.ModNone, Handler: gui.scrollUpMain, }, { ViewName: "", Key: gui.getKey(config.Universal.ScrollDownMainAlt1), Modifier: gocui.ModNone, Handler: gui.scrollDownMain, }, { ViewName: "", Key: gui.getKey(config.Universal.ScrollUpMainAlt2), Modifier: gocui.ModNone, Handler: gui.scrollUpMain, }, { ViewName: "", Key: gui.getKey(config.Universal.ScrollDownMainAlt2), Modifier: gocui.ModNone, Handler: gui.scrollDownMain, }, { ViewName: "", Key: gui.getKey(config.Universal.CreateRebaseOptionsMenu), Handler: gui.handleCreateRebaseOptionsMenu, Description: gui.Tr.ViewMergeRebaseOptions, OpensMenu: true, }, { ViewName: "", Key: gui.getKey(config.Universal.CreatePatchOptionsMenu), Handler: gui.handleCreatePatchOptionsMenu, Description: gui.Tr.ViewPatchOptions, OpensMenu: true, }, { ViewName: "", Key: gui.getKey(config.Universal.PushFiles), Handler: gui.pushFiles, Description: gui.Tr.LcPush, }, { ViewName: "", Key: gui.getKey(config.Universal.PullFiles), Handler: gui.handlePullFiles, Description: gui.Tr.LcPull, }, { ViewName: "", Key: gui.getKey(config.Universal.Refresh), Handler: gui.handleRefresh, Description: gui.Tr.LcRefresh, }, { ViewName: "", Key: gui.getKey(config.Universal.OptionMenu), Handler: gui.handleCreateOptionsMenu, Description: gui.Tr.LcOpenMenu, OpensMenu: true, }, { ViewName: "", Key: gui.getKey(config.Universal.OptionMenuAlt1), Modifier: gocui.ModNone, Handler: gui.handleCreateOptionsMenu, }, { ViewName: "", Key: gocui.MouseMiddle, Modifier: gocui.ModNone, Handler: gui.handleCreateOptionsMenu, }, { ViewName: "", Key: gui.getKey(config.Universal.Undo), Handler: gui.reflogUndo, Description: gui.Tr.LcUndoReflog, }, { ViewName: "", Key: gui.getKey(config.Universal.Redo), Handler: gui.reflogRedo, Description: gui.Tr.LcRedoReflog, }, { ViewName: "status", Key: gui.getKey(config.Universal.Edit), Handler: gui.handleEditConfig, Description: gui.Tr.EditConfig, }, { ViewName: "", Key: gui.getKey(config.Universal.NextScreenMode), Handler: gui.nextScreenMode, Description: gui.Tr.LcNextScreenMode, }, { ViewName: "", Key: gui.getKey(config.Universal.PrevScreenMode), Handler: gui.prevScreenMode, Description: gui.Tr.LcPrevScreenMode, }, { ViewName: "status", Key: gui.getKey(config.Universal.OpenFile), Handler: gui.handleOpenConfig, Description: gui.Tr.OpenConfig, }, { ViewName: "status", Key: gui.getKey(config.Status.CheckForUpdate), Handler: gui.handleCheckForUpdate, Description: gui.Tr.LcCheckForUpdate, }, { ViewName: "status", Key: gui.getKey(config.Status.RecentRepos), Handler: gui.handleCreateRecentReposMenu, Description: gui.Tr.SwitchRepo, }, { ViewName: "status", Key: gui.getKey(config.Status.AllBranchesLogGraph), Handler: gui.handleShowAllBranchLogs, Description: gui.Tr.LcAllBranchesLogGraph, }, { ViewName: "files", Key: gui.getKey(""), Handler: gui.handleStatusFilterPressed, Description: gui.Tr.LcCommitFileFilter, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.CommitChanges), Handler: gui.handleCommitPress, Description: gui.Tr.CommitChanges, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.CommitChangesWithoutHook), Handler: gui.handleWIPCommitPress, Description: gui.Tr.LcCommitChangesWithoutHook, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.AmendLastCommit), Handler: gui.handleAmendCommitPress, Description: gui.Tr.AmendLastCommit, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.CommitChangesWithEditor), Handler: gui.handleCommitEditorPress, Description: gui.Tr.CommitChangesWithEditor, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), Handler: gui.handleFilePress, Description: gui.Tr.LcToggleStaged, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Remove), Handler: gui.handleCreateDiscardMenu, Description: gui.Tr.LcViewDiscardOptions, OpensMenu: true, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Edit), Handler: gui.handleFileEdit, Description: gui.Tr.LcEditFile, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.OpenFile), Handler: gui.handleFileOpen, Description: gui.Tr.LcOpenFile, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.IgnoreFile), Handler: gui.handleIgnoreFile, Description: gui.Tr.LcIgnoreFile, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.RefreshFiles), Handler: gui.handleRefreshFiles, Description: gui.Tr.LcRefreshFiles, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.StashAllChanges), Handler: gui.handleStashChanges, Description: gui.Tr.LcStashAllChanges, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.ViewStashOptions), Handler: gui.handleCreateStashMenu, Description: gui.Tr.LcViewStashOptions, OpensMenu: true, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.ToggleStagedAll), Handler: gui.handleStageAll, Description: gui.Tr.LcToggleStagedAll, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.ViewResetOptions), Handler: gui.handleCreateResetMenu, Description: gui.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleEnterFile, Description: gui.Tr.FileEnter, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.Fetch), Handler: gui.handleGitFetch, Description: gui.Tr.LcFetch, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.CopyToClipboard), Handler: gui.handleCopySelectedSideContextItemToClipboard, Description: gui.Tr.LcCopyFileNameToClipboard, }, { ViewName: "", Key: gui.getKey(config.Universal.ExecuteCustomCommand), Handler: gui.handleCustomCommand, Description: gui.Tr.LcExecuteCustomCommand, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ViewResetOptions), Handler: gui.handleCreateResetToUpstreamMenu, Description: gui.Tr.LcViewResetToUpstreamOptions, OpensMenu: true, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.ToggleTreeView), Handler: gui.handleToggleFileTreeView, Description: gui.Tr.LcToggleTreeView, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Files.OpenMergeTool), Handler: gui.handleOpenMergeTool, Description: gui.Tr.LcOpenMergeTool, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), Handler: gui.handleBranchPress, Description: gui.Tr.LcCheckout, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.CreatePullRequest), Handler: gui.handleCreatePullRequestPress, Description: gui.Tr.LcCreatePullRequest, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.ViewPullRequestOptions), Handler: gui.handleCreatePullRequestMenu, Description: gui.Tr.LcCreatePullRequestOptions, OpensMenu: true, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.CopyPullRequestURL), Handler: gui.handleCopyPullRequestURLPress, Description: gui.Tr.LcCopyPullRequestURL, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.CheckoutBranchByName), Handler: gui.handleCheckoutByName, Description: gui.Tr.LcCheckoutByName, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.ForceCheckoutBranch), Handler: gui.handleForceCheckout, Description: gui.Tr.LcForceCheckout, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.New), Handler: gui.handleNewBranchOffCurrentItem, Description: gui.Tr.LcNewBranch, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Remove), Handler: gui.handleDeleteBranch, Description: gui.Tr.LcDeleteBranch, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.RebaseBranch), Handler: gui.handleRebaseOntoLocalBranch, Description: gui.Tr.LcRebaseBranch, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.MergeIntoCurrentBranch), Handler: gui.handleMerge, Description: gui.Tr.LcMergeIntoCurrentBranch, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.ViewGitFlowOptions), Handler: gui.handleCreateGitFlowMenu, Description: gui.Tr.LcGitFlowOptions, OpensMenu: true, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.FastForward), Handler: gui.handleFastForward, Description: gui.Tr.FastForward, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ViewResetOptions), Handler: gui.handleCreateResetToBranchMenu, Description: gui.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.RenameBranch), Handler: gui.handleRenameBranch, Description: gui.Tr.LcRenameBranch, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.CopyToClipboard), Handler: gui.handleCopySelectedSideContextItemToClipboard, Description: gui.Tr.LcCopyBranchNameToClipboard, }, { ViewName: "branches", Contexts: []string{string(LOCAL_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleSwitchToSubCommits, Description: gui.Tr.LcViewCommits, }, { ViewName: "branches", Contexts: []string{string(TAGS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), Handler: gui.withSelectedTag(gui.handleCheckoutTag), Description: gui.Tr.LcCheckout, }, { ViewName: "branches", Contexts: []string{string(TAGS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Remove), Handler: gui.withSelectedTag(gui.handleDeleteTag), Description: gui.Tr.LcDeleteTag, }, { ViewName: "branches", Contexts: []string{string(TAGS_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.PushTag), Handler: gui.withSelectedTag(gui.handlePushTag), Description: gui.Tr.LcPushTag, }, { ViewName: "branches", Contexts: []string{string(TAGS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.New), Handler: gui.handleCreateTag, Description: gui.Tr.LcCreateTag, }, { ViewName: "branches", Contexts: []string{string(TAGS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ViewResetOptions), Handler: gui.withSelectedTag(gui.handleCreateResetToTagMenu), Description: gui.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "branches", Contexts: []string{string(TAGS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleSwitchToSubCommits, Description: gui.Tr.LcViewCommits, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Return), Handler: gui.handleRemoteBranchesEscape, Description: gui.Tr.ReturnToRemotesList, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ViewResetOptions), Handler: gui.handleCreateResetToRemoteBranchMenu, Description: gui.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleSwitchToSubCommits, Description: gui.Tr.LcViewCommits, }, { ViewName: "branches", Contexts: []string{string(REMOTES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.FetchRemote), Handler: gui.handleFetchRemote, Description: gui.Tr.LcFetchRemote, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.OpenLogMenu), Handler: gui.handleOpenLogMenu, Description: gui.Tr.LcOpenLogMenu, OpensMenu: true, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.SquashDown), Handler: gui.handleCommitSquashDown, Description: gui.Tr.LcSquashDown, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.RenameCommit), Handler: gui.handleRenameCommit, Description: gui.Tr.LcRenameCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.RenameCommitWithEditor), Handler: gui.handleRenameCommitEditor, Description: gui.Tr.LcRenameCommitEditor, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ViewResetOptions), Handler: gui.handleCreateCommitResetMenu, Description: gui.Tr.LcResetToThisCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.MarkCommitAsFixup), Handler: gui.handleCommitFixup, Description: gui.Tr.LcFixupCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CreateFixupCommit), Handler: gui.handleCreateFixupCommit, Description: gui.Tr.LcCreateFixupCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.SquashAboveCommits), Handler: gui.handleSquashAllAboveFixupCommits, Description: gui.Tr.LcSquashAboveCommits, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Remove), Handler: gui.handleCommitDelete, Description: gui.Tr.LcDeleteCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.MoveDownCommit), Handler: gui.handleCommitMoveDown, Description: gui.Tr.LcMoveDownCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.MoveUpCommit), Handler: gui.handleCommitMoveUp, Description: gui.Tr.LcMoveUpCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Edit), Handler: gui.handleCommitEdit, Description: gui.Tr.LcEditCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.AmendToCommit), Handler: gui.handleCommitAmendTo, Description: gui.Tr.LcAmendToCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.PickCommit), Handler: gui.handleCommitPick, Description: gui.Tr.LcPickCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.RevertCommit), Handler: gui.handleCommitRevert, Description: gui.Tr.LcRevertCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CherryPickCopy), Handler: gui.handleCopyCommit, Description: gui.Tr.LcCherryPickCopy, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.CopyToClipboard), Handler: gui.handleCopySelectedSideContextItemToClipboard, Description: gui.Tr.LcCopyCommitShaToClipboard, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CherryPickCopyRange), Handler: gui.handleCopyCommitRange, Description: gui.Tr.LcCherryPickCopyRange, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.PasteCommits), Handler: gui.HandlePasteCommits, Description: gui.Tr.LcPasteCommits, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleViewCommitFiles, Description: gui.Tr.LcViewCommitFiles, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CheckoutCommit), Handler: gui.handleCheckoutCommit, Description: gui.Tr.LcCheckoutCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.New), Modifier: gocui.ModNone, Handler: gui.handleNewBranchOffCurrentItem, Description: gui.Tr.LcCreateNewBranchFromCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.TagCommit), Handler: gui.handleTagCommit, Description: gui.Tr.LcTagCommit, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ResetCherryPick), Handler: gui.exitCherryPickingMode, Description: gui.Tr.LcResetCherryPick, }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CopyCommitMessageToClipboard), Handler: gui.handleCopySelectedCommitMessageToClipboard, Description: gui.Tr.LcCopyCommitMessageToClipboard, }, { ViewName: "commits", Contexts: []string{string(REFLOG_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleViewReflogCommitFiles, Description: gui.Tr.LcViewCommitFiles, }, { ViewName: "commits", Contexts: []string{string(REFLOG_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), Handler: gui.handleCheckoutReflogCommit, Description: gui.Tr.LcCheckoutCommit, }, { ViewName: "commits", Contexts: []string{string(REFLOG_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ViewResetOptions), Handler: gui.handleCreateReflogResetMenu, Description: gui.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "commits", Contexts: []string{string(REFLOG_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CherryPickCopy), Handler: gui.handleCopyCommit, Description: gui.Tr.LcCherryPickCopy, }, { ViewName: "commits", Contexts: []string{string(REFLOG_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CherryPickCopyRange), Handler: gui.handleCopyCommitRange, Description: gui.Tr.LcCherryPickCopyRange, }, { ViewName: "commits", Contexts: []string{string(REFLOG_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ResetCherryPick), Handler: gui.exitCherryPickingMode, Description: gui.Tr.LcResetCherryPick, }, { ViewName: "commits", Contexts: []string{string(REFLOG_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.CopyToClipboard), Handler: gui.handleCopySelectedSideContextItemToClipboard, Description: gui.Tr.LcCopyCommitShaToClipboard, }, { ViewName: "branches", Contexts: []string{string(SUB_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleViewSubCommitFiles, Description: gui.Tr.LcViewCommitFiles, }, { ViewName: "branches", Contexts: []string{string(SUB_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), Handler: gui.handleCheckoutSubCommit, Description: gui.Tr.LcCheckoutCommit, }, { ViewName: "branches", Contexts: []string{string(SUB_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ViewResetOptions), Handler: gui.handleCreateSubCommitResetMenu, Description: gui.Tr.LcViewResetOptions, OpensMenu: true, }, { ViewName: "branches", Contexts: []string{string(SUB_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.New), Handler: gui.handleNewBranchOffCurrentItem, Description: gui.Tr.LcNewBranch, }, { ViewName: "branches", Contexts: []string{string(SUB_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CherryPickCopy), Handler: gui.handleCopyCommit, Description: gui.Tr.LcCherryPickCopy, }, { ViewName: "branches", Contexts: []string{string(SUB_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.CherryPickCopyRange), Handler: gui.handleCopyCommitRange, Description: gui.Tr.LcCherryPickCopyRange, }, { ViewName: "branches", Contexts: []string{string(SUB_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Commits.ResetCherryPick), Handler: gui.exitCherryPickingMode, Description: gui.Tr.LcResetCherryPick, }, { ViewName: "branches", Contexts: []string{string(SUB_COMMITS_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.CopyToClipboard), Handler: gui.handleCopySelectedSideContextItemToClipboard, Description: gui.Tr.LcCopyCommitShaToClipboard, }, { ViewName: "stash", Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleViewStashFiles, Description: gui.Tr.LcViewStashFiles, }, { ViewName: "stash", Key: gui.getKey(config.Universal.Select), Handler: gui.handleStashApply, Description: gui.Tr.LcApply, }, { ViewName: "stash", Key: gui.getKey(config.Stash.PopStash), Handler: gui.handleStashPop, Description: gui.Tr.LcPop, }, { ViewName: "stash", Key: gui.getKey(config.Universal.Remove), Handler: gui.handleStashDrop, Description: gui.Tr.LcDrop, }, { ViewName: "stash", Key: gui.getKey(config.Universal.New), Handler: gui.handleNewBranchOffCurrentItem, Description: gui.Tr.LcNewBranch, }, { ViewName: "commitMessage", Key: gui.getKey(config.Universal.SubmitEditorText), Modifier: gocui.ModNone, Handler: gui.handleCommitConfirm, }, { ViewName: "commitMessage", Key: gui.getKey(config.Universal.Return), Modifier: gocui.ModNone, Handler: gui.handleCommitClose, }, { ViewName: "credentials", Key: gui.getKey(config.Universal.Confirm), Modifier: gocui.ModNone, Handler: gui.handleSubmitCredential, }, { ViewName: "credentials", Key: gui.getKey(config.Universal.Return), Modifier: gocui.ModNone, Handler: gui.handleCloseCredentialsView, }, { ViewName: "menu", Key: gui.getKey(config.Universal.Return), Handler: gui.handleMenuClose, Description: gui.Tr.LcCloseMenu, }, { ViewName: "information", Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleInfoClick, }, { ViewName: "commitFiles", Key: gui.getKey(config.Universal.CopyToClipboard), Handler: gui.handleCopySelectedSideContextItemToClipboard, Description: gui.Tr.LcCopyCommitFileNameToClipboard, }, { ViewName: "commitFiles", Key: gui.getKey(config.CommitFiles.CheckoutCommitFile), Handler: gui.handleCheckoutCommitFile, Description: gui.Tr.LcCheckoutCommitFile, }, { ViewName: "commitFiles", Key: gui.getKey(config.Universal.Remove), Handler: gui.handleDiscardOldFileChange, Description: gui.Tr.LcDiscardOldFileChange, }, { ViewName: "commitFiles", Key: gui.getKey(config.Universal.OpenFile), Handler: gui.handleOpenOldCommitFile, Description: gui.Tr.LcOpenFile, }, { ViewName: "commitFiles", Key: gui.getKey(config.Universal.Edit), Handler: gui.handleEditCommitFile, Description: gui.Tr.LcEditFile, }, { ViewName: "commitFiles", Key: gui.getKey(config.Universal.Select), Handler: gui.handleToggleFileForPatch, Description: gui.Tr.LcToggleAddToPatch, }, { ViewName: "commitFiles", Key: gui.getKey(config.Universal.GoInto), Handler: gui.handleEnterCommitFile, Description: gui.Tr.LcEnterFile, }, { ViewName: "commitFiles", Key: gui.getKey(config.Files.ToggleTreeView), Handler: gui.handleToggleCommitFileTreeView, Description: gui.Tr.LcToggleTreeView, }, { ViewName: "", Key: gui.getKey(config.Universal.FilteringMenu), Handler: gui.handleCreateFilteringMenuPanel, Description: gui.Tr.LcOpenFilteringMenu, OpensMenu: true, }, { ViewName: "", Key: gui.getKey(config.Universal.DiffingMenu), Handler: gui.handleCreateDiffingMenuPanel, Description: gui.Tr.LcOpenDiffingMenu, OpensMenu: true, }, { ViewName: "", Key: gui.getKey(config.Universal.DiffingMenuAlt), Handler: gui.handleCreateDiffingMenuPanel, Description: gui.Tr.LcOpenDiffingMenu, OpensMenu: true, }, { ViewName: "", Key: gui.getKey(config.Universal.ExtrasMenu), Handler: gui.handleCreateExtrasMenuPanel, Description: gui.Tr.LcOpenExtrasMenu, OpensMenu: true, }, { ViewName: "secondary", Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: gui.scrollUpSecondary, }, { ViewName: "secondary", Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: gui.scrollDownSecondary, }, { ViewName: "secondary", Contexts: []string{string(MAIN_NORMAL_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleMouseDownSecondary, }, { ViewName: "main", Contexts: []string{string(MAIN_NORMAL_CONTEXT_KEY)}, Key: gocui.MouseWheelDown, Handler: gui.scrollDownMain, Description: gui.Tr.ScrollDown, Alternative: "fn+up", }, { ViewName: "main", Contexts: []string{string(MAIN_NORMAL_CONTEXT_KEY)}, Key: gocui.MouseWheelUp, Handler: gui.scrollUpMain, Description: gui.Tr.ScrollUp, Alternative: "fn+down", }, { ViewName: "main", Contexts: []string{string(MAIN_NORMAL_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleMouseDownMain, }, { ViewName: "secondary", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleTogglePanelClick, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Return), Handler: gui.handleStagingEscape, Description: gui.Tr.ReturnToFilesPanel, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), Handler: gui.handleToggleStagedSelection, Description: gui.Tr.StageSelection, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Remove), Handler: gui.handleResetSelection, Description: gui.Tr.ResetSelection, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.TogglePanel), Handler: gui.handleTogglePanel, Description: gui.Tr.TogglePanel, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Return), Handler: gui.handleEscapePatchBuildingPanel, Description: gui.Tr.ExitLineByLineMode, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.OpenFile), Handler: gui.handleOpenFileAtLine, Description: gui.Tr.LcOpenFile, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevItem), Handler: gui.handleSelectPrevLine, Description: gui.Tr.PrevLine, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextItem), Handler: gui.handleSelectNextLine, Description: gui.Tr.NextLine, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: gui.handleSelectPrevLine, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: gui.handleSelectNextLine, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: gui.scrollUpMain, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: gui.scrollDownMain, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevBlock), Handler: gui.handleSelectPrevHunk, Description: gui.Tr.PrevHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevBlockAlt), Modifier: gocui.ModNone, Handler: gui.handleSelectPrevHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextBlock), Handler: gui.handleSelectNextHunk, Description: gui.Tr.NextHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextBlockAlt), Modifier: gocui.ModNone, Handler: gui.handleSelectNextHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.CopyToClipboard), Modifier: gocui.ModNone, Handler: gui.copySelectedToClipboard, Description: gui.Tr.LcCopySelectedTexToClipboard, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Edit), Handler: gui.handleLineByLineEdit, Description: gui.Tr.LcEditFile, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.OpenFile), Handler: gui.handleFileOpen, Description: gui.Tr.LcOpenFile, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextPage), Modifier: gocui.ModNone, Handler: gui.handleLineByLineNextPage, Description: gui.Tr.LcNextPage, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevPage), Modifier: gocui.ModNone, Handler: gui.handleLineByLinePrevPage, Description: gui.Tr.LcPrevPage, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GotoTop), Modifier: gocui.ModNone, Handler: gui.handleLineByLineGotoTop, Description: gui.Tr.LcGotoTop, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GotoBottom), Modifier: gocui.ModNone, Handler: gui.handleLineByLineGotoBottom, Description: gui.Tr.LcGotoBottom, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.StartSearch), Handler: func() error { return gui.handleOpenSearch("main") }, Description: gui.Tr.LcStartSearch, Tag: "navigation", }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), Handler: gui.handleToggleSelectionForPatch, Description: gui.Tr.ToggleSelectionForPatch, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Main.ToggleDragSelect), Handler: gui.handleToggleSelectRange, Description: gui.Tr.ToggleDragSelect, }, // Alias 'V' -> 'v' { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Main.ToggleDragSelectAlt), Handler: gui.handleToggleSelectRange, Description: gui.Tr.ToggleDragSelect, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Main.ToggleSelectHunk), Handler: gui.handleToggleSelectHunk, Description: gui.Tr.ToggleSelectHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleLBLMouseDown, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseLeft, Modifier: gocui.ModMotion, Handler: gui.handleMouseDrag, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: gui.scrollUpMain, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY)}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: gui.scrollDownMain, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY), string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.ScrollLeft), Handler: gui.scrollLeftMain, Description: gui.Tr.LcScrollLeft, }, { ViewName: "main", Contexts: []string{string(MAIN_PATCH_BUILDING_CONTEXT_KEY), string(MAIN_STAGING_CONTEXT_KEY), string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.ScrollRight), Handler: gui.scrollRightMain, Description: gui.Tr.LcScrollRight, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Files.CommitChanges), Handler: gui.handleCommitPress, Description: gui.Tr.CommitChanges, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Files.CommitChangesWithoutHook), Handler: gui.handleWIPCommitPress, Description: gui.Tr.LcCommitChangesWithoutHook, }, { ViewName: "main", Contexts: []string{string(MAIN_STAGING_CONTEXT_KEY)}, Key: gui.getKey(config.Files.CommitChangesWithEditor), Handler: gui.handleCommitEditorPress, Description: gui.Tr.CommitChangesWithEditor, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Return), Handler: gui.handleEscapeMerge, Description: gui.Tr.ReturnToFilesPanel, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Files.OpenMergeTool), Handler: gui.handleOpenMergeTool, Description: gui.Tr.LcOpenMergeTool, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), Handler: gui.handlePickHunk, Description: gui.Tr.PickHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Main.PickBothHunks), Handler: gui.handlePickAllHunks, Description: gui.Tr.PickAllHunks, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevBlock), Handler: gui.handleSelectPrevConflict, Description: gui.Tr.PrevConflict, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextBlock), Handler: gui.handleSelectNextConflict, Description: gui.Tr.NextConflict, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevItem), Handler: gui.handleSelectPrevConflictHunk, Description: gui.Tr.SelectPrevHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextItem), Handler: gui.handleSelectNextConflictHunk, Description: gui.Tr.SelectNextHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: gui.handleSelectPrevConflictHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: gui.handleSelectNextConflictHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevBlockAlt), Modifier: gocui.ModNone, Handler: gui.handleSelectPrevConflict, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextBlockAlt), Modifier: gocui.ModNone, Handler: gui.handleSelectNextConflict, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: gui.handleSelectPrevConflictHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: gui.handleSelectNextConflictHunk, }, { ViewName: "main", Contexts: []string{string(MAIN_MERGING_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Undo), Handler: gui.handlePopFileSnapshot, Description: gui.Tr.LcUndo, }, { ViewName: "branches", Contexts: []string{string(REMOTES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Modifier: gocui.ModNone, Handler: gui.handleRemoteEnter, }, { ViewName: "branches", Contexts: []string{string(REMOTES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.New), Handler: gui.handleAddRemote, Description: gui.Tr.LcAddNewRemote, }, { ViewName: "branches", Contexts: []string{string(REMOTES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Remove), Handler: gui.handleRemoveRemote, Description: gui.Tr.LcRemoveRemote, }, { ViewName: "branches", Contexts: []string{string(REMOTES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Edit), Handler: gui.handleEditRemote, Description: gui.Tr.LcEditRemote, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Select), // gonna use the exact same handler as the 'n' keybinding because everybody wants this to happen when they checkout a remote branch Handler: gui.handleNewBranchOffCurrentItem, Description: gui.Tr.LcCheckout, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.New), Handler: gui.handleNewBranchOffCurrentItem, Description: gui.Tr.LcNewBranch, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.MergeIntoCurrentBranch), Handler: gui.handleMergeRemoteBranch, Description: gui.Tr.LcMergeIntoCurrentBranch, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Remove), Handler: gui.handleDeleteRemoteBranch, Description: gui.Tr.LcDeleteBranch, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.RebaseBranch), Handler: gui.handleRebaseOntoRemoteBranch, Description: gui.Tr.LcRebaseBranch, }, { ViewName: "branches", Contexts: []string{string(REMOTE_BRANCHES_CONTEXT_KEY)}, Key: gui.getKey(config.Branches.SetUpstream), Handler: gui.handleSetBranchUpstream, Description: gui.Tr.LcSetUpstream, }, { ViewName: "status", Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleStatusClick, }, { ViewName: "search", Key: gui.getKey(config.Universal.Confirm), Modifier: gocui.ModNone, Handler: gui.handleSearch, }, { ViewName: "search", Key: gui.getKey(config.Universal.Return), Modifier: gocui.ModNone, Handler: gui.handleSearchEscape, }, { ViewName: "confirmation", Key: gui.getKey(config.Universal.PrevItem), Modifier: gocui.ModNone, Handler: gui.scrollUpConfirmationPanel, }, { ViewName: "confirmation", Key: gui.getKey(config.Universal.NextItem), Modifier: gocui.ModNone, Handler: gui.scrollDownConfirmationPanel, }, { ViewName: "confirmation", Key: gui.getKey(config.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: gui.scrollUpConfirmationPanel, }, { ViewName: "confirmation", Key: gui.getKey(config.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: gui.scrollDownConfirmationPanel, }, { ViewName: "menu", Key: gui.getKey(config.Universal.Select), Modifier: gocui.ModNone, Handler: gui.onMenuPress, }, { ViewName: "menu", Key: gui.getKey(config.Universal.Confirm), Modifier: gocui.ModNone, Handler: gui.onMenuPress, }, { ViewName: "menu", Key: gui.getKey(config.Universal.ConfirmAlt1), Modifier: gocui.ModNone, Handler: gui.onMenuPress, }, { ViewName: "files", Contexts: []string{string(SUBMODULES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.CopyToClipboard), Handler: gui.handleCopySelectedSideContextItemToClipboard, Description: gui.Tr.LcCopySubmoduleNameToClipboard, }, { ViewName: "files", Contexts: []string{string(SUBMODULES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.GoInto), Handler: gui.forSubmodule(gui.handleSubmoduleEnter), Description: gui.Tr.LcEnterSubmodule, }, { ViewName: "files", Contexts: []string{string(SUBMODULES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Remove), Handler: gui.forSubmodule(gui.handleResetRemoveSubmodule), Description: gui.Tr.LcViewResetAndRemoveOptions, OpensMenu: true, }, { ViewName: "files", Contexts: []string{string(SUBMODULES_CONTEXT_KEY)}, Key: gui.getKey(config.Submodules.Update), Handler: gui.forSubmodule(gui.handleUpdateSubmodule), Description: gui.Tr.LcSubmoduleUpdate, }, { ViewName: "files", Contexts: []string{string(SUBMODULES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.New), Handler: gui.handleAddSubmodule, Description: gui.Tr.LcAddSubmodule, }, { ViewName: "files", Contexts: []string{string(SUBMODULES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.Edit), Handler: gui.forSubmodule(gui.handleEditSubmoduleUrl), Description: gui.Tr.LcEditSubmoduleUrl, }, { ViewName: "files", Contexts: []string{string(SUBMODULES_CONTEXT_KEY)}, Key: gui.getKey(config.Submodules.Init), Handler: gui.forSubmodule(gui.handleSubmoduleInit), Description: gui.Tr.LcInitSubmodule, }, { ViewName: "files", Contexts: []string{string(SUBMODULES_CONTEXT_KEY)}, Key: gui.getKey(config.Submodules.BulkMenu), Handler: gui.handleBulkSubmoduleActionsMenu, Description: gui.Tr.LcViewBulkSubmoduleOptions, OpensMenu: true, }, { ViewName: "files", Contexts: []string{string(FILES_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.ToggleWhitespaceInDiffView), Handler: gui.toggleWhitespaceInDiffView, Description: gui.Tr.ToggleWhitespaceInDiffView, }, { ViewName: "extras", Key: gocui.MouseWheelUp, Handler: gui.scrollUpExtra, }, { ViewName: "extras", Key: gocui.MouseWheelDown, Handler: gui.scrollDownExtra, }, { ViewName: "extras", Key: gui.getKey(config.Universal.ExtrasMenu), Handler: gui.handleCreateExtrasMenuPanel, Description: gui.Tr.LcOpenExtrasMenu, OpensMenu: true, }, { ViewName: "extras", Tag: "navigation", Contexts: []string{string(COMMAND_LOG_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: gui.scrollUpExtra, }, { ViewName: "extras", Tag: "navigation", Contexts: []string{string(COMMAND_LOG_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.PrevItem), Modifier: gocui.ModNone, Handler: gui.scrollUpExtra, }, { ViewName: "extras", Tag: "navigation", Contexts: []string{string(COMMAND_LOG_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextItem), Modifier: gocui.ModNone, Handler: gui.scrollDownExtra, }, { ViewName: "extras", Tag: "navigation", Contexts: []string{string(COMMAND_LOG_CONTEXT_KEY)}, Key: gui.getKey(config.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: gui.scrollDownExtra, }, { ViewName: "extras", Tag: "navigation", Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: gui.handleFocusCommandLog, }, } for _, viewName := range []string{"status", "branches", "files", "commits", "commitFiles", "stash", "menu"} { bindings = append(bindings, []*Binding{ {ViewName: viewName, Key: gui.getKey(config.Universal.PrevBlock), Modifier: gocui.ModNone, Handler: gui.previousSideWindow}, {ViewName: viewName, Key: gui.getKey(config.Universal.NextBlock), Modifier: gocui.ModNone, Handler: gui.nextSideWindow}, {ViewName: viewName, Key: gui.getKey(config.Universal.PrevBlockAlt), Modifier: gocui.ModNone, Handler: gui.previousSideWindow}, {ViewName: viewName, Key: gui.getKey(config.Universal.NextBlockAlt), Modifier: gocui.ModNone, Handler: gui.nextSideWindow}, {ViewName: viewName, Key: gui.getKey(config.Universal.PrevBlockAlt2), Modifier: gocui.ModNone, Handler: gui.previousSideWindow}, {ViewName: viewName, Key: gui.getKey(config.Universal.NextBlockAlt2), Modifier: gocui.ModNone, Handler: gui.nextSideWindow}, }...) } // Appends keybindings to jump to a particular sideView using numbers windows := []string{"status", "files", "branches", "commits", "stash"} if len(config.Universal.JumpToBlock) != len(windows) { log.Fatal("Jump to block keybindings cannot be set. Exactly 5 keybindings must be supplied.") } else { for i, window := range windows { bindings = append(bindings, &Binding{ ViewName: "", Key: gui.getKey(config.Universal.JumpToBlock[i]), Modifier: gocui.ModNone, Handler: gui.goToSideWindow(window)}) } } for viewName := range gui.State.Contexts.initialViewTabContextMap() { bindings = append(bindings, []*Binding{ { ViewName: viewName, Key: gui.getKey(config.Universal.NextTab), Handler: gui.handleNextTab, Description: gui.Tr.LcNextTab, Tag: "navigation", }, { ViewName: viewName, Key: gui.getKey(config.Universal.PrevTab), Handler: gui.handlePrevTab, Description: gui.Tr.LcPrevTab, Tag: "navigation", }, }...) } bindings = append(bindings, gui.getListContextKeyBindings()...) return bindings } func (gui *Gui) keybindings() error { bindings := gui.GetCustomCommandKeybindings() bindings = append(bindings, gui.GetInitialKeybindings()...) for _, binding := range bindings { if err := gui.g.SetKeybinding(binding.ViewName, binding.Contexts, binding.Key, binding.Modifier, gui.wrappedHandler(binding.Handler)); err != nil { return err } } for viewName := range gui.State.Contexts.initialViewTabContextMap() { viewName := viewName tabClickCallback := func(tabIndex int) error { return gui.onViewTabClick(viewName, tabIndex) } if err := gui.g.SetTabClickBinding(viewName, tabClickCallback); err != nil { return err } } return nil }