summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2018-09-10 09:47:14 +1000
committerGitHub <noreply@github.com>2018-09-10 09:47:14 +1000
commit557461c01640c9e2182fb2a841f2a8179070cb18 (patch)
tree8c8cd54c0874deb6cad15bfad659a15043c19460 /pkg
parent24f15742d025eaf8a29b28bf5b426a9af8a33527 (diff)
parentbea9971f9c26c5d07c11074362b73163425c07b7 (diff)
Merge branch 'master' into add-tests-part-2
Diffstat (limited to 'pkg')
-rw-r--r--pkg/gui/branches_panel.go15
-rw-r--r--pkg/gui/commits_panel.go14
-rw-r--r--pkg/gui/files_panel.go26
-rw-r--r--pkg/gui/gui.go10
-rw-r--r--pkg/gui/keybindings.go415
-rw-r--r--pkg/gui/menu_panel.go131
-rw-r--r--pkg/gui/stash_panel.go10
-rw-r--r--pkg/gui/status_panel.go6
-rw-r--r--pkg/gui/view_helpers.go9
-rw-r--r--pkg/i18n/dutch.go76
-rw-r--r--pkg/i18n/english.go53
-rw-r--r--pkg/i18n/polish.go82
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",<