diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2018-09-10 09:47:14 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-10 09:47:14 +1000 |
commit | 557461c01640c9e2182fb2a841f2a8179070cb18 (patch) | |
tree | 8c8cd54c0874deb6cad15bfad659a15043c19460 /pkg | |
parent | 24f15742d025eaf8a29b28bf5b426a9af8a33527 (diff) | |
parent | bea9971f9c26c5d07c11074362b73163425c07b7 (diff) |
Merge branch 'master' into add-tests-part-2
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/gui/branches_panel.go | 15 | ||||
-rw-r--r-- | pkg/gui/commits_panel.go | 14 | ||||
-rw-r--r-- | pkg/gui/files_panel.go | 26 | ||||
-rw-r--r-- | pkg/gui/gui.go | 10 | ||||
-rw-r--r-- | pkg/gui/keybindings.go | 415 | ||||
-rw-r--r-- | pkg/gui/menu_panel.go | 131 | ||||
-rw-r--r-- | pkg/gui/stash_panel.go | 10 | ||||
-rw-r--r-- | pkg/gui/status_panel.go | 6 | ||||
-rw-r--r-- | pkg/gui/view_helpers.go | 9 | ||||
-rw-r--r-- | pkg/i18n/dutch.go | 76 | ||||
-rw-r--r-- | pkg/i18n/english.go | 53 | ||||
-rw-r--r-- | pkg/i18n/polish.go | 82 |
12 files changed, 718 insertions, 129 deletions
diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index df4dcff78..26c3c5618 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -10,11 +10,11 @@ import ( ) func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error { - index := gui.getItemPosition(v) + index := gui.getItemPosition(gui.getBranchesView(g)) if index == 0 { return gui.createErrorPanel(g, gui.Tr.SLocalize("AlreadyCheckedOutBranch")) } - branch := gui.getSelectedBranch(v) + branch := gui.getSelectedBranch(gui.getBranchesView(g)) if err := gui.GitCommand.Checkout(branch.Name, false); err != nil { gui.createErrorPanel(g, err.Error()) } @@ -115,16 +115,7 @@ func (gui *Gui) getSelectedBranch(v *gocui.View) commands.Branch { } func (gui *Gui) renderBranchesOptions(g *gocui.Gui) error { - return gui.renderOptionsMap(g, map[string]string{ - "space": gui.Tr.SLocalize("checkout"), - "f": gui.Tr.SLocalize("forceCheckout"), - "m": gui.Tr.SLocalize("merge"), - "c": gui.Tr.SLocalize("checkoutByName"), - "n": gui.Tr.SLocalize("newBranch"), - "d": gui.Tr.SLocalize("deleteBranch"), - "D": gui.Tr.SLocalize("forceDeleteBranch"), - "← → ↑ ↓": gui.Tr.SLocalize("navigate"), - }) + return gui.renderGlobalOptions(g) } // may want to standardise how these select methods work diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 0969692b6..1c1662475 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -59,13 +59,7 @@ func (gui *Gui) handleResetToCommit(g *gocui.Gui, commitView *gocui.View) error } func (gui *Gui) renderCommitsOptions(g *gocui.Gui) error { - return gui.renderOptionsMap(g, map[string]string{ - "s": gui.Tr.SLocalize("squashDown"), - "r": gui.Tr.SLocalize("rename"), - "g": gui.Tr.SLocalize("resetToThisCommit"), - "f": gui.Tr.SLocalize("fixupCommit"), - "← → ↑ ↓": gui.Tr.SLocalize("navigate"), - }) + return gui.renderGlobalOptions(g) } func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error { @@ -140,10 +134,10 @@ func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error { - if gui.getItemPosition(v) != 0 { + if gui.getItemPosition(gui.getCommitsView(g)) != 0 { return gui.createErrorPanel(g, gui.Tr.SLocalize("OnlyRenameTopCommit")) } - gui.createPromptPanel(g, v, gui.Tr.SLocalize("RenameCommit"), func(g *gocui.Gui, v *gocui.View) error { + return gui.createPromptPanel(g, v, gui.Tr.SLocalize("renameCommit"), func(g *gocui.Gui, v *gocui.View) error { if err := gui.GitCommand.RenameCommit(v.Buffer()); err != nil { return gui.createErrorPanel(g, err.Error()) } @@ -156,7 +150,7 @@ func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleRenameCommitEditor(g *gocui.Gui, v *gocui.View) error { - if gui.getItemPosition(v) != 0 { + if gui.getItemPosition(gui.getCommitsView(g)) != 0 { return gui.createErrorPanel(g, gui.Tr.SLocalize("OnlyRenameTopCommit")) } diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index 1971b3453..bfcc938bb 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -172,31 +172,7 @@ func (gui *Gui) handleIgnoreFile(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) renderfilesOptions(g *gocui.Gui, file *commands.File) error { - optionsMap := map[string]string{ - "← → ↑ ↓": gui.Tr.SLocalize("navigate"), - "S": gui.Tr.SLocalize("stashFiles"), - "c": gui.Tr.SLocalize("CommitChanges"), - "o": gui.Tr.SLocalize("open"), - "i": gui.Tr.SLocalize("ignore"), - "d": gui.Tr.SLocalize("delete"), - "space": gui.Tr.SLocalize("toggleStaged"), - "R": gui.Tr.SLocalize("refresh"), - "t": gui.Tr.SLocalize("addPatch"), - "e": gui.Tr.SLocalize("edit"), - "a": gui.Tr.SLocalize("toggleStagedAll"), - "PgUp/PgDn": gui.Tr.SLocalize("scroll"), - } - if gui.State.HasMergeConflicts { - optionsMap["a"] = gui.Tr.SLocalize("abortMerge") - optionsMap["m"] = gui.Tr.SLocalize("resolveMergeConflicts") - } - if file == nil { - return gui.renderOptionsMap(g, optionsMap) - } - if file.Tracked { - optionsMap["d"] = gui.Tr.SLocalize("checkout") - } - return gui.renderOptionsMap(g, optionsMap) + return gui.renderGlobalOptions(g) } func (gui *Gui) handleFileSelect(g *gocui.Gui, v *gocui.View) error { diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 413e48202..e3cc61529 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -83,6 +83,7 @@ type guiState struct { EditHistory *stack.Stack Platform commands.Platform Updating bool + Keys []Binding } // NewGui builds a new gui handler @@ -346,6 +347,15 @@ func (gui *Gui) renderAppStatus(g *gocui.Gui) error { return nil } +func (gui *Gui) renderGlobalOptions(g *gocui.Gui) error { + return gui.renderOptionsMap(g, map[string]string{ + "PgUp/PgDn": gui.Tr.SLocalize("scroll"), + "← → ↑ ↓": gui.Tr.SLocalize("navigate"), + "esc/q": gui.Tr.SLocalize("close"), + "x": gui.Tr.SLocalize("menu"), + }) +} + func (gui *Gui) goEvery(g *gocui.Gui, interval time.Duration, function func(*gocui.Gui) error) { go func() { for range time.Tick(interval) { diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 494381749..c8ed7d3c8 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -6,75 +6,360 @@ import "github.com/jesseduffield/gocui" // is only handled if the given view has focus, or handled globally if the view // is "" type Binding struct { - ViewName string - Handler func(*gocui.Gui, *gocui.View) error - Key interface{} // FIXME: find out how to get `gocui.Key | rune` - Modifier gocui.Modifier + ViewName string + Handler func(*gocui.Gui, *gocui.View) error + Key interface{} // FIXME: find out how to get `gocui.Key | rune` + Modifier gocui.Modifier + KeyReadable string + Description string } -func (gui *Gui) keybindings(g *gocui.Gui) error { +func (gui *Gui) GetKeybindings() []Binding { bindings := []Binding{ - {ViewName: "", Key: 'q', Modifier: gocui.ModNone, Handler: gui.quit}, - {ViewName: "", Key: gocui.KeyCtrlC, Modifier: gocui.ModNone, Handler: gui.quit}, - {ViewName: "", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.quit}, - {ViewName: "", Key: gocui.KeyPgup, Modifier: gocui.ModNone, Handler: gui.scrollUpMain}, - {ViewName: "", Key: gocui.KeyPgdn, 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: 'P', Modifier: gocui.ModNone, Handler: gui.pushFiles}, - {ViewName: "", Key: 'p', Modifier: gocui.ModNone, Handler: gui.pullFiles}, - {ViewName: "", Key: 'R', Modifier: gocui.ModNone, Handler: gui.handleRefresh}, - {ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig}, - {ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig}, - {ViewName: "status", Key: 'u', Modifier: gocui.ModNone, Handler: gui.handleCheckForUpdate}, - {ViewName: "files", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCommitPress}, - {ViewName: "files", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCommitEditorPress}, - {ViewName: "files", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleFilePress}, - {ViewName: "files", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleFileRemove}, - {ViewName: "files", Key: 'm', Modifier: gocui.ModNone, Handler: gui.handleSwitchToMerge}, - {ViewName: "files", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleFileEdit}, - {ViewName: "files", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleFileOpen}, - {ViewName: "files", Key: 'i', Modifier: gocui.ModNone, Handler: gui.handleIgnoreFile}, - {ViewName: "files", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRefreshFiles}, - {ViewName: "files", Key: 'S', Modifier: gocui.ModNone, Handler: gui.handleStashSave}, - {ViewName: "files", Key: 'A', Modifier: gocui.ModNone, Handler: gui.handleAbortMerge}, - {ViewName: "files", Key: 'a', Modifier: gocui.ModNone, Handler: gui.handleStageAll}, - {ViewName: "files", Key: 't', Modifier: gocui.ModNone, Handler: gui.handleAddPatch}, - {ViewName: "files", Key: 'D', Modifier: gocui.ModNone, Handler: gui.handleResetHard}, - {ViewName: "main", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleEscapeMerge}, - {ViewName: "main", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handlePickHunk}, - {ViewName: "main", Key: 'b', Modifier: gocui.ModNone, Handler: gui.handlePickBothHunks}, - {ViewName: "main", Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.handleSelectPrevConflict}, - {ViewName: "main", Key: gocui.KeyArrowRight, Modifier: gocui.ModNone, Handler: gui.handleSelectNextConflict}, - {ViewName: "main", Key: gocui.KeyArrowUp, Modifier: gocui.ModNone, Handler: gui.handleSelectTop}, - {ViewName: "main", Key: gocui.KeyArrowDown, 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}, - {ViewName: "branches", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleBranchPress}, - {ViewName: "branches", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCheckoutByName}, - {ViewName: "branches", Key: 'F', Modifier: gocui.ModNone, Handler: gui.handleForceCheckout}, - {ViewName: "branches", Key: 'n', Modifier: gocui.ModNone, Handler: gui.handleNewBranch}, - {ViewName: "branches", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleDeleteBranch}, - {ViewName: "branches", Key: 'D', Modifier: gocui.ModNone, Handler: gui.handleForceDeleteBranch}, - {ViewName: "branches", Key: 'm', Modifier: gocui.ModNone, Handler: gui.handleMerge}, - {ViewName: "commits", Key: 's', Modifier: gocui.ModNone, Handler: gui.handleCommitSquashDown}, - {ViewName: "commits", Key: 'r', Modifier: gocui.ModNone, Handler: gui.handleRenameCommit}, - {ViewName: "commits", Key: 'R', Modifier: gocui.ModNone, Handler: gui.handleRenameCommitEditor}, - {ViewName: "commits", Key: 'g', Modifier: gocui.ModNone, Handler: gui.handleResetToCommit}, - {ViewName: "commits", Key: 'f', Modifier: gocui.ModNone, Handler: gui.handleCommitFixup}, - {ViewName: "stash", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleStashApply}, - {ViewName: "stash", Key: 'g', Modifier: gocui.ModNone, Handler: gui.handleStashPop}, - {ViewName: "stash", Key: 'd', Modifier: gocui.ModNone, Handler: gui.handleStashDrop}, - {ViewName: "commitMessage", Key: gocui.KeyEnter, Modifier: gocui.ModNone, Handler: gui.handleCommitConfirm}, - {ViewName: "commitMessage", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleCommitClose}, + { + ViewName: "", + Key: 'q', + Modifier: gocui.ModNone, + Handler: gui.quit, + }, { + ViewName: "", + Key: gocui.KeyCtrlC, + Modifier: gocui.ModNone, + Handler: gui.quit, + }, { + ViewName: "", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.quit, + }, { + ViewName: "", + Key: gocui.KeyPgup, + Modifier: gocui.ModNone, + Handler: gui.scrollUpMain, + }, { + ViewName: "", + Key: gocui.KeyPgdn, + 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: 'P', + Modifier: gocui.ModNone, + Handler: gui.pushFiles, + Description: gui.Tr.SLocalize("push"), + }, { + ViewName: "", + Key: 'p', + Modifier: gocui.ModNone, + Handler: gui.pullFiles, + 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.handleMenu, + }, { + 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: "files", + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.handleCommitPress, + Description: gui.Tr.SLocalize("CommitChanges"), + }, { + 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, + KeyReadable: "space", + Description: gui.Tr.SLocalize("toggleStaged"), + }, { + ViewName: "files", + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.handleFileRemove, + Description: gui.Tr.SLocalize("removeFile"), + }, { + ViewName: "files", + Key: 'm', + Modifier: gocui.ModNone, + Handler: gui.handleSwitchToMerge, + Description: gui.Tr.SLocalize("resolveMergeConflicts"), + }, { + 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.handleStashSave, + Description: gui.Tr.SLocalize("stashFiles"), + }, { + ViewName: "files", + Key: 'A', + Modifier: gocui.ModNone, + Handler: gui.handleAbortMerge, + Description: gui.Tr.SLocalize("abortMerge"), + }, { + ViewName: "files", + Key: 'a', + Modifier: gocui.ModNone, + Handler: gui.handleStageAll, + Description: gui.Tr.SLocalize("toggleStagedAll"), + }, { + ViewName: "files", + Key: 't', + Modifier: gocui.ModNone, + Handler: gui.handleAddPatch, + Description: gui.Tr.SLocalize("addPatch"), + }, { + ViewName: "files", + Key: 'D', + Modifier: gocui.ModNone, + Handler: gui.handleResetHard, + Description: gui.Tr.SLocalize("resetHard"), + }, { + ViewName: "main", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleEscapeMerge, + }, { + ViewName: "main", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handlePickHunk, + }, { + ViewName: "main", + Key: 'b', + Modifier: gocui.ModNone, + Handler: gui.handlePickBothHunks, + }, { + ViewName: "main", + Key: gocui.KeyArrowLeft, + Modifier: gocui.ModNone, + Handler: gui.handleSelectPrevConflict, + }, { + ViewName: "main", + Key: gocui.KeyArrowRight, + Modifier: gocui.ModNone, + Handler: gui.handleSelectNextConflict, + }, { + ViewName: "main", + Key: gocui.KeyArrowUp, + Modifier: gocui.ModNone, + Handler: gui.handleSelectTop, + }, { + ViewName: "main", + Key: gocui.KeyArrowDown, + 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, + }, { + ViewName: "branches", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleBranchPress, + KeyReadable: "space", + Description: gui.Tr.SLocalize("checkout"), + }, { + 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: 'D', + Modifier: gocui.ModNone, + Handler: gui.handleForceDeleteBranch, + Description: gui.Tr.SLocalize("forceDeleteBranch"), + }, { + ViewName: "branches", + Key: 'm', + Modifier: gocui.ModNone, + Handler: gui.handleMerge, + Description: gui.Tr.SLocalize("mergeIntoCurrentBranch"), + }, { + 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.handleResetToCommit, + Description: gui.Tr.SLocalize("resetToThisCommit"), + }, { + ViewName: "commits", + Key: 'f', + Modifier: gocui.ModNone, + Handler: gui.handleCommitFixup, + Description: gui.Tr.SLocalize("fixupCommit"), + }, { + ViewName: "stash", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleStashApply, + KeyReadable: "space", + 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: "menu", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleMenuClose, + }, { + ViewName: "menu", + Key: 'q', + Modifier: gocui.ModNone, + Handler: gui.handleMenuClose, + }, { + ViewName: "menu", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleMenuPress, + }, } // Would make these keybindings global but that interferes with editing // input in the confirmation panel - for _, viewName := range []string{"status", "files", "branches", "commits", "stash"} { + for _, viewName := range []string{"status", "files", "branches", "commits", "stash", "menu"} { bindings = append(bindings, []Binding{ {ViewName: viewName, Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.nextView}, {ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView}, @@ -88,6 +373,12 @@ func (gui *Gui) keybindings(g *gocui.Gui) error { }...) } + return bindings +} + +func (gui *Gui) keybindings(g *gocui.Gui) error { + bindings := gui.GetKeybindings() + for _, binding := range bindings { if err := g.SetKeybinding(binding.ViewName, binding.Key, binding.Modifier, binding.Handler); err != nil { return err diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go new file mode 100644 index 000000000..68041390d --- /dev/null +++ b/pkg/gui/menu_panel.go @@ -0,0 +1,131 @@ +package gui + +import ( + "fmt" + "strings" + + "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/utils" +) + +func (gui *Gui) handleMenuPress(g *gocui.Gui, v *gocui.View) error { + lineNumber := gui.getItemPosition(v) + if gui.State.Keys[lineNumber].Key == nil { + return nil + } + if len(gui.State.Keys) > lineNumber { + err := gui.handleMenuClose(g, v) + if err != nil { + return err + } + return gui.State.Keys[lineNumber].Handler(g, v) + } + return nil +} + +func (gui *Gui) handleMenuSelect(g *gocui.Gui, v *gocui.View) error { + // doing nothing for now + // but it is needed for switch in newLineFocused + return nil +} + +func (gui *Gui) renderMenuOptions(g *gocui.Gui) error { + optionsMap := map[string]string{ + "esc/q": gui.Tr.SLocalize("close"), + "↑ ↓": gui.Tr.SLocalize("navigate"), + "space": gui.Tr.SLocalize("execute"), + } + return gui.renderOptionsMap(g, optionsMap) +} + +func (gui *Gui) handleMenuClose(g *gocui.Gui, v *gocui.View) error { + // better to delete because for example after closing update confirmation panel, + // the focus isn't set back to any of panels and one is unable to even quit + //_, err := g.SetViewOnBottom(v.Name()) + err := g.DeleteView("menu") + if err != nil { + return err + } + return gui.returnFocus(g, v) +} + +func (gui *Gui) GetKey(binding Binding) string { + r, ok := binding.Key.(rune) + key := "" + + if ok { + key = string(r) + } else if binding.KeyReadable != "" { + key = binding.KeyReadable + } + + return key +} + +func (gui *Gui) GetMaxKeyLength(bindings []Binding) int { + max := 0 + for _, binding := range bindings { + keyLength := len(gui.GetKey(binding)) + if keyLength > max { + max = keyLength + } + } + return max +} + +func (gui *Gui) handleMenu(g *gocui.Gui, v *gocui.View) error { + var ( + contentGlobal, contentPanel []string + bindingsGlobal, bindingsPanel []Binding + ) + // clear keys slice, so we don't have ghost elements + gui.State.Keys = gui.State.Keys[:0] + bindings := gui.GetKeybindings() + padWidth := gui.GetMaxKeyLength(bindings) + + for _, binding := range bindings { + key := gui.GetKey(binding) + if key != "" && binding.Description != "" { + content := fmt.Sprintf("%s %s", utils.WithPadding(key, padWidth), binding.Description) + switch binding.ViewName { + case "": + contentGlobal = append(contentGlobal, content) + bindingsGlobal = append(bindingsGlobal, binding) + case v.Name(): + contentPanel = append(contentPanel, content) + bindingsPanel = append(bindingsPanel, binding) + } + } + } + + // append dummy element to have a separator between + // panel and global keybindings + contentPanel = append(contentPanel, "") + bindingsPanel = append(bindingsPanel, Binding{}) + + content := append(contentPanel, contentGlobal...) + gui.State.Keys = append(bindingsPanel, bindingsGlobal...) + // append newline at the end so the last line would be selectable + contentJoined := strings.Join(content, "\n") + "\n" + + // y1-1 so there will not be an extra space at the end of panel + x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, contentJoined) + menuView, _ := g.SetView("menu", x0, y0, x1, y1-1, 0) + menuView.Title = strings.Title(gui.Tr.SLocalize("menu")) + menuView.FgColor = gocui.ColorWhite + + if err := gui.renderMenuOptions(g); err != nil { + return err + } + + fmt.Fprint(menuView, contentJoined) + + g.Update(func(g *gocui.Gui) error { + _, err := g.SetViewOnTop("menu") + if err != nil { + return err + } + return gui.switchFocus(g, v, menuView) + }) + return nil +} diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go index 0c323e254..9ca07717b 100644 --- a/pkg/gui/stash_panel.go +++ b/pkg/gui/stash_panel.go @@ -27,17 +27,13 @@ func (gui *Gui) getSelectedStashEntry(v *gocui.View) *commands.StashEntry { if len(gui.State.StashEntries) == 0 { return nil } - lineNumber := gui.getItemPosition(v) + stashView, _ := gui.g.View("stash") + lineNumber := gui.getItemPosition(stashView) return &gui.State.StashEntries[lineNumber] } func (gui *Gui) renderStashOptions(g *gocui.Gui) error { - return gui.renderOptionsMap(g, map[string]string{ - "space": gui.Tr.SLocalize("apply"), - "g": gui.Tr.SLocalize("pop"), - "d": gui.Tr.SLocalize("drop"), - "← → ↑ ↓": gui.Tr.SLocalize("navigate"), - }) + return gui.renderGlobalOptions(g) } func (gui *Gui) handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error { diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go index 583d7805a..6948e9678 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/status_panel.go @@ -42,11 +42,7 @@ func (gui *Gui) refreshStatus(g *gocui.Gui) error { } func (gui *Gui) renderStatusOptions(g *gocui.Gui) error { - return gui.renderOptionsMap(g, map[string]string{ - "o": gui.Tr.SLocalize("OpenConfig"), - "e": gui.Tr.SLocalize("EditConfig"), - "u": gui.Tr.SLocalize("CheckForUpdate"), - }) + return gui.renderGlobalOptions(g) } func (gui *Gui) handleCheckForUpdate(g *gocui.Gui, v *gocui.View) error { diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 3a59945a5..7a5bd8874 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -82,6 +82,8 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error { mainView.SetOrigin(0, 0) switch v.Name() { + case "menu": + return gui.handleMenuSelect(g, v) case "status": return gui.handleStatusSelect(g, v) case "files": @@ -145,6 +147,7 @@ func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View) error { return err } g.Cursor = newView.Editable + return gui.newLineFocused(g, newView) } @@ -245,6 +248,7 @@ func (gui *Gui) renderOptionsMap(g *gocui.Gui, optionsMap map[string]string) err } // TODO: refactor properly +// i'm so sorry but had to add this getBranchesView func (gui *Gui) getFilesView(g *gocui.Gui) *gocui.View { v, _ := g.View("files") return v @@ -260,6 +264,11 @@ func (gui *Gui) getCommitMessageView(g *gocui.Gui) *gocui.View { return v } +func (gui *Gui) getBranchesView(g *gocui.Gui) *gocui.View { + v, _ := g.View("branches") + return v +} + func (gui *Gui) trimmedContent(v *gocui.View) string { return strings.TrimSpace(v.Buffer()) } diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go index 0ce156cd5..21330e55c 100644 --- a/pkg/i18n/dutch.go +++ b/pkg/i18n/dutch.go @@ -35,12 +35,24 @@ func addDutch(i18nObject *i18n.Bundle) error { ID: "CommitChanges", Other: "Commit Veranderingen", }, &i18n.Message{ + ID: "CommitChangesWithEditor", + Other: "commit changes using git editor",< |