From 741e28d01a95a6bafa442d3642774b0f3817ff7f Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Tue, 28 Aug 2018 20:07:13 +0200 Subject: [PATCH 01/47] move bindings to getKeybindings() --- pkg/gui/keybindings.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index c6decc24f..841c73f9b 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -12,7 +12,7 @@ type Binding struct { Modifier gocui.Modifier } -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}, @@ -89,6 +89,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 From 2416f585ce24227cc6ab49e19b29e45bb3aa2524 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Tue, 28 Aug 2018 20:13:01 +0200 Subject: [PATCH 02/47] initial help panel --- pkg/gui/files_panel.go | 1 + pkg/gui/help_panel.go | 68 +++++++++++++++++++++++++++++++++++++++++ pkg/gui/keybindings.go | 7 +++++ pkg/gui/view_helpers.go | 6 +++- pkg/i18n/english.go | 6 ++++ 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 pkg/gui/help_panel.go diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index a4c187c9c..e8bcf8112 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -185,6 +185,7 @@ func (gui *Gui) renderfilesOptions(g *gocui.Gui, file *commands.File) error { "e": gui.Tr.SLocalize("edit"), "a": gui.Tr.SLocalize("toggleStagedAll"), "PgUp/PgDn": gui.Tr.SLocalize("scroll"), + "H": gui.Tr.SLocalize("help"), } if gui.State.HasMergeConflicts { optionsMap["a"] = gui.Tr.SLocalize("abortMerge") diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go new file mode 100644 index 000000000..b9173fa88 --- /dev/null +++ b/pkg/gui/help_panel.go @@ -0,0 +1,68 @@ +package gui + +import ( + "github.com/jesseduffield/gocui" + "fmt" + "strings" +) + +func (gui *Gui) renderHelpOptions(g *gocui.Gui) error { + optionsMap := map[string]string{ + "esc/q": gui.Tr.SLocalize("close"), + "PgUp/PgDn": gui.Tr.SLocalize("scroll"), + } + return gui.renderOptionsMap(g, optionsMap) +} + +func (gui *Gui) scrollUpHelp(g *gocui.Gui, v *gocui.View) error { + mainView, _ := g.View("help") + ox, oy := mainView.Origin() + if oy >= 1 { + return mainView.SetOrigin(ox, oy-gui.Config.GetUserConfig().GetInt("gui.scrollHeight")) + } + return nil +} + +func (gui *Gui) scrollDownHelp(g *gocui.Gui, v *gocui.View) error { + mainView, _ := g.View("help") + ox, oy := mainView.Origin() + if oy < len(mainView.BufferLines()) { + return mainView.SetOrigin(ox, oy+gui.Config.GetUserConfig().GetInt("gui.scrollHeight")) + } + return nil +} + +func (gui *Gui) handleHelpClose(g *gocui.Gui, v *gocui.View) error { + g.SetViewOnBottom(v.Name()) + return gui.switchFocus(g, v, gui.getFilesView(g)) +} + +func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { + content := "" + curr := "" + bindings := gui.getKeybindings() + maxX, maxY := g.Size() + helpView, _ := g.SetView("help", 0, 0, maxX-1, maxY-2, 0) + helpView.Title = strings.Title(gui.Tr.SLocalize("help")) + + gui.renderHelpOptions(g) + + for _, binding := range bindings{ + if binding.Description != "" { + if curr != binding.ViewName { + curr = binding.ViewName + content += fmt.Sprintf("\n%s:\n", strings.Title(curr)) + } + content += fmt.Sprintf(" %s - %s\n", binding.KeyReadable, binding.Description) + } + } + + helpView.Write([]byte(content)) + + g.Update(func(g *gocui.Gui) error { + g.SetViewOnTop("help") + gui.switchFocus(g, v, helpView) + return nil + }) + return nil +} \ No newline at end of file diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 841c73f9b..e08fc62b4 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -10,6 +10,8 @@ type Binding struct { 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) getKeybindings() []Binding { @@ -24,6 +26,7 @@ func (gui *Gui) getKeybindings() []Binding { {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: "", Key: 'H', Modifier: gocui.ModNone, Handler: gui.handleHelp}, {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}, @@ -71,6 +74,10 @@ func (gui *Gui) getKeybindings() []Binding { {ViewName: "commitMessage", Key: gocui.KeyEnter, Modifier: gocui.ModNone, Handler: gui.handleCommitConfirm}, {ViewName: "commitMessage", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleCommitClose}, {ViewName: "commitMessage", Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.handleNewlineCommitMessage}, + {ViewName: "help", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleHelpClose}, + {ViewName: "help", Key: 'q', Modifier: gocui.ModNone, Handler: gui.handleHelpClose}, + {ViewName: "help", Key: gocui.KeyPgup, Modifier: gocui.ModNone, Handler: gui.scrollUpHelp}, + {ViewName: "help", Key: gocui.KeyPgdn, Modifier: gocui.ModNone, Handler: gui.scrollDownHelp}, } // Would make these keybindings global but that interferes with editing diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index fd810220b..9cebbf3c7 100644 --- a/pkg/gui/view_helpers.go +++ b/pkg/gui/view_helpers.go @@ -145,7 +145,11 @@ func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View) error { return err } g.Cursor = newView.Editable - return gui.newLineFocused(g, newView) + + if newView.Name() != "help" { + return gui.newLineFocused(g, newView) + } + return nil } func (gui *Gui) getItemPosition(v *gocui.View) int { diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 1d9e8b41e..1527b7faf 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -48,6 +48,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "navigate", Other: "navigate", + }, &i18n.Message{ + ID: "help", + Other: "help", }, &i18n.Message{ ID: "stashFiles", Other: "stash files", @@ -183,6 +186,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "CloseConfirm", Other: "{{.keyBindClose}}: close, {{.keyBindConfirm}}: confirm", + }, &i18n.Message{ + ID: "close", + Other: "close", }, &i18n.Message{ ID: "SureResetThisCommit", Other: "Are you sure you want to reset to this commit?", From 6a99d36ae1373618ce2296c711cf2bfb16f42e4e Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Wed, 29 Aug 2018 11:54:28 +0200 Subject: [PATCH 03/47] change key from 'H' to '?' --- pkg/gui/files_panel.go | 2 +- pkg/gui/keybindings.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index e8bcf8112..6fa9e450b 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -185,7 +185,7 @@ func (gui *Gui) renderfilesOptions(g *gocui.Gui, file *commands.File) error { "e": gui.Tr.SLocalize("edit"), "a": gui.Tr.SLocalize("toggleStagedAll"), "PgUp/PgDn": gui.Tr.SLocalize("scroll"), - "H": gui.Tr.SLocalize("help"), + "?": gui.Tr.SLocalize("help"), } if gui.State.HasMergeConflicts { optionsMap["a"] = gui.Tr.SLocalize("abortMerge") diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index e08fc62b4..9a21ec8b7 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -26,7 +26,7 @@ func (gui *Gui) getKeybindings() []Binding { {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: "", Key: 'H', Modifier: gocui.ModNone, Handler: gui.handleHelp}, + {ViewName: "", Key: '?', Modifier: gocui.ModNone, Handler: gui.handleHelp}, {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}, From 77623db1d0fc2d435b11098f2f50ad75b419c3ce Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Wed, 29 Aug 2018 11:56:28 +0200 Subject: [PATCH 04/47] apply fmt --- pkg/gui/files_panel.go | 2 +- pkg/gui/help_panel.go | 10 +++++----- pkg/gui/keybindings.go | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index 6fa9e450b..90f2b7e84 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -185,7 +185,7 @@ func (gui *Gui) renderfilesOptions(g *gocui.Gui, file *commands.File) error { "e": gui.Tr.SLocalize("edit"), "a": gui.Tr.SLocalize("toggleStagedAll"), "PgUp/PgDn": gui.Tr.SLocalize("scroll"), - "?": gui.Tr.SLocalize("help"), + "?": gui.Tr.SLocalize("help"), } if gui.State.HasMergeConflicts { optionsMap["a"] = gui.Tr.SLocalize("abortMerge") diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index b9173fa88..7fb6a69b5 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -1,14 +1,14 @@ package gui import ( - "github.com/jesseduffield/gocui" "fmt" + "github.com/jesseduffield/gocui" "strings" ) func (gui *Gui) renderHelpOptions(g *gocui.Gui) error { optionsMap := map[string]string{ - "esc/q": gui.Tr.SLocalize("close"), + "esc/q": gui.Tr.SLocalize("close"), "PgUp/PgDn": gui.Tr.SLocalize("scroll"), } return gui.renderOptionsMap(g, optionsMap) @@ -47,9 +47,9 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { gui.renderHelpOptions(g) - for _, binding := range bindings{ + for _, binding := range bindings { if binding.Description != "" { - if curr != binding.ViewName { + if curr != binding.ViewName { curr = binding.ViewName content += fmt.Sprintf("\n%s:\n", strings.Title(curr)) } @@ -65,4 +65,4 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { return nil }) return nil -} \ No newline at end of file +} diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 9a21ec8b7..bdc5daf5d 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -6,10 +6,10 @@ 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 } From 28a9594ef7f7dad70efa9470ed12e5d102f6c5df Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Wed, 29 Aug 2018 13:43:59 +0200 Subject: [PATCH 05/47] update help panel - delete scrolling ability - lines are now selectable - implemented handler execution when space is pressed - add example descriptions for status panel keybindings --- pkg/gui/files_panel.go | 2 +- pkg/gui/help_panel.go | 76 ++++++++++++++++++++++++----------------- pkg/gui/keybindings.go | 11 +++--- pkg/gui/view_helpers.go | 7 ++-- pkg/i18n/english.go | 3 ++ 5 files changed, 56 insertions(+), 43 deletions(-) diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index 90f2b7e84..cf98e8a44 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -185,7 +185,7 @@ func (gui *Gui) renderfilesOptions(g *gocui.Gui, file *commands.File) error { "e": gui.Tr.SLocalize("edit"), "a": gui.Tr.SLocalize("toggleStagedAll"), "PgUp/PgDn": gui.Tr.SLocalize("scroll"), - "?": gui.Tr.SLocalize("help"), + "?": gui.Tr.SLocalize("help"), //TODO make it visible for all panels, not only files } if gui.State.HasMergeConflicts { optionsMap["a"] = gui.Tr.SLocalize("abortMerge") diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index 7fb6a69b5..6ef8def7f 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -2,62 +2,74 @@ package gui import ( "fmt" - "github.com/jesseduffield/gocui" "strings" + + "github.com/jesseduffield/gocui" ) +var keys []Binding + +func (gui *Gui) handleHelpPress(g *gocui.Gui, v *gocui.View) error { + lineNumber := gui.getItemPosition(v) + err := gui.handleHelpClose(g, v) + if err != nil { + return err + } + return keys[lineNumber].Handler(g, v) +} + +func (gui *Gui) handleHelpSelect(g *gocui.Gui, v *gocui.View) error { + // doing nothing for now + // but it is needed for switch in newLineFocused + return nil +} + func (gui *Gui) renderHelpOptions(g *gocui.Gui) error { optionsMap := map[string]string{ - "esc/q": gui.Tr.SLocalize("close"), - "PgUp/PgDn": gui.Tr.SLocalize("scroll"), + "esc/q": gui.Tr.SLocalize("close"), + "↑ ↓": gui.Tr.SLocalize("navigate"), + "space": gui.Tr.SLocalize("execute"), } return gui.renderOptionsMap(g, optionsMap) } -func (gui *Gui) scrollUpHelp(g *gocui.Gui, v *gocui.View) error { - mainView, _ := g.View("help") - ox, oy := mainView.Origin() - if oy >= 1 { - return mainView.SetOrigin(ox, oy-gui.Config.GetUserConfig().GetInt("gui.scrollHeight")) - } - return nil -} - -func (gui *Gui) scrollDownHelp(g *gocui.Gui, v *gocui.View) error { - mainView, _ := g.View("help") - ox, oy := mainView.Origin() - if oy < len(mainView.BufferLines()) { - return mainView.SetOrigin(ox, oy+gui.Config.GetUserConfig().GetInt("gui.scrollHeight")) - } - return nil -} - func (gui *Gui) handleHelpClose(g *gocui.Gui, v *gocui.View) error { - g.SetViewOnBottom(v.Name()) - return gui.switchFocus(g, v, gui.getFilesView(g)) + // 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(v.Name()) + if err != nil { + return err + } + return gui.returnFocus(g, v) } func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { + // clear keys slice, so we don't have ghost elements + keys = keys[:0] content := "" - curr := "" bindings := gui.getKeybindings() maxX, maxY := g.Size() - helpView, _ := g.SetView("help", 0, 0, maxX-1, maxY-2, 0) + x := maxX * 3 / 4 + y := 5 + helpView, _ := g.SetView("help", maxX-x, y, x, maxY-y, 0) helpView.Title = strings.Title(gui.Tr.SLocalize("help")) gui.renderHelpOptions(g) for _, binding := range bindings { - if binding.Description != "" { - if curr != binding.ViewName { - curr = binding.ViewName - content += fmt.Sprintf("\n%s:\n", strings.Title(curr)) - } - content += fmt.Sprintf(" %s - %s\n", binding.KeyReadable, binding.Description) + if binding.ViewName == v.Name() && binding.Description != "" && binding.KeyReadable != "" { + content += fmt.Sprintf(" %s - %s\n", binding.KeyReadable, binding.Description) + keys = append(keys, binding) } } - helpView.Write([]byte(content)) + // for testing + /*content += "first\n" + content += "second\n" + content += "third\n" + */ + gui.renderString(g, "help", content) g.Update(func(g *gocui.Gui) error { g.SetViewOnTop("help") diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index bdc5daf5d..e8ddb68d5 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -27,9 +27,9 @@ func (gui *Gui) getKeybindings() []Binding { {ViewName: "", Key: 'p', Modifier: gocui.ModNone, Handler: gui.pullFiles}, {ViewName: "", Key: 'R', Modifier: gocui.ModNone, Handler: gui.handleRefresh}, {ViewName: "", Key: '?', Modifier: gocui.ModNone, Handler: gui.handleHelp}, - {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: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, KeyReadable: "e", Description: "edit config"}, + {ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig, KeyReadable: "o", Description: "open config"}, + {ViewName: "status", Key: 'u', Modifier: gocui.ModNone, Handler: gui.handleCheckForUpdate, KeyReadable: "u", Description: "check for update"}, {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}, @@ -76,13 +76,12 @@ func (gui *Gui) getKeybindings() []Binding { {ViewName: "commitMessage", Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.handleNewlineCommitMessage}, {ViewName: "help", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleHelpClose}, {ViewName: "help", Key: 'q', Modifier: gocui.ModNone, Handler: gui.handleHelpClose}, - {ViewName: "help", Key: gocui.KeyPgup, Modifier: gocui.ModNone, Handler: gui.scrollUpHelp}, - {ViewName: "help", Key: gocui.KeyPgdn, Modifier: gocui.ModNone, Handler: gui.scrollDownHelp}, + {ViewName: "help", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleHelpPress}, } // 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", "help"} { 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}, diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go index 9cebbf3c7..4cab2de08 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 "help": + return gui.handleHelpSelect(g, v) case "status": return gui.handleStatusSelect(g, v) case "files": @@ -146,10 +148,7 @@ func (gui *Gui) switchFocus(g *gocui.Gui, oldView, newView *gocui.View) error { } g.Cursor = newView.Editable - if newView.Name() != "help" { - return gui.newLineFocused(g, newView) - } - return nil + return gui.newLineFocused(g, newView) } func (gui *Gui) getItemPosition(v *gocui.View) int { diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 1527b7faf..c29138e42 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -51,6 +51,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "help", Other: "help", + }, &i18n.Message{ + ID: "execute", + Other: "execute", }, &i18n.Message{ ID: "stashFiles", Other: "stash files", From 8a01d11202eb9c3a037a0c9ab75c3e2afc64f375 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Wed, 29 Aug 2018 14:24:04 +0200 Subject: [PATCH 06/47] more error checks --- pkg/gui/help_panel.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index 6ef8def7f..4b3355c46 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -55,7 +55,9 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { helpView, _ := g.SetView("help", maxX-x, y, x, maxY-y, 0) helpView.Title = strings.Title(gui.Tr.SLocalize("help")) - gui.renderHelpOptions(g) + if err := gui.renderHelpOptions(g); err != nil { + return err + } for _, binding := range bindings { if binding.ViewName == v.Name() && binding.Description != "" && binding.KeyReadable != "" { @@ -69,12 +71,17 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { content += "second\n" content += "third\n" */ - gui.renderString(g, "help", content) + + if err := gui.renderString(g, "help", content); err != nil { + return err + } g.Update(func(g *gocui.Gui) error { - g.SetViewOnTop("help") - gui.switchFocus(g, v, helpView) - return nil + _, err := g.SetViewOnTop("help") + if err != nil { + return err + } + return gui.switchFocus(g, v, helpView) }) return nil } From 653d590157886b1fdefd91eafa25c063f7b6b66e Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Thu, 30 Aug 2018 13:39:11 +0200 Subject: [PATCH 07/47] help panel size from getConfirmationPanelDimensions --- pkg/gui/help_panel.go | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index 4b3355c46..81cc712b5 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -11,11 +11,14 @@ var keys []Binding func (gui *Gui) handleHelpPress(g *gocui.Gui, v *gocui.View) error { lineNumber := gui.getItemPosition(v) - err := gui.handleHelpClose(g, v) - if err != nil { - return err + if len(keys) > lineNumber { + err := gui.handleHelpClose(g, v) + if err != nil { + return err + } + return keys[lineNumber].Handler(g, v) } - return keys[lineNumber].Handler(g, v) + return nil } func (gui *Gui) handleHelpSelect(g *gocui.Gui, v *gocui.View) error { @@ -49,15 +52,6 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { keys = keys[:0] content := "" bindings := gui.getKeybindings() - maxX, maxY := g.Size() - x := maxX * 3 / 4 - y := 5 - helpView, _ := g.SetView("help", maxX-x, y, x, maxY-y, 0) - helpView.Title = strings.Title(gui.Tr.SLocalize("help")) - - if err := gui.renderHelpOptions(g); err != nil { - return err - } for _, binding := range bindings { if binding.ViewName == v.Name() && binding.Description != "" && binding.KeyReadable != "" { @@ -66,6 +60,15 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { } } + // y1-1 so there will not be an extra space at the end of panel + x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, content) + helpView, _ := g.SetView("help", x0, y0, x1, y1-1, 0) + helpView.Title = strings.Title(gui.Tr.SLocalize("help")) + + if err := gui.renderHelpOptions(g); err != nil { + return err + } + // for testing /*content += "first\n" content += "second\n" From cc3fa4b79d0623ea3046b2085a4db2f6f1a69db5 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Thu, 30 Aug 2018 13:45:11 +0200 Subject: [PATCH 08/47] make '?' key visible on every panel --- pkg/gui/branches_panel.go | 1 + pkg/gui/commits_panel.go | 1 + pkg/gui/files_panel.go | 2 +- pkg/gui/stash_panel.go | 1 + pkg/gui/status_panel.go | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index df4dcff78..61b8f1a2f 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -124,6 +124,7 @@ func (gui *Gui) renderBranchesOptions(g *gocui.Gui) error { "d": gui.Tr.SLocalize("deleteBranch"), "D": gui.Tr.SLocalize("forceDeleteBranch"), "← → ↑ ↓": gui.Tr.SLocalize("navigate"), + "?": gui.Tr.SLocalize("help"), }) } diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 0969692b6..2c1cc6178 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -65,6 +65,7 @@ func (gui *Gui) renderCommitsOptions(g *gocui.Gui) error { "g": gui.Tr.SLocalize("resetToThisCommit"), "f": gui.Tr.SLocalize("fixupCommit"), "← → ↑ ↓": gui.Tr.SLocalize("navigate"), + "?": gui.Tr.SLocalize("help"), }) } diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index cf98e8a44..90f2b7e84 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -185,7 +185,7 @@ func (gui *Gui) renderfilesOptions(g *gocui.Gui, file *commands.File) error { "e": gui.Tr.SLocalize("edit"), "a": gui.Tr.SLocalize("toggleStagedAll"), "PgUp/PgDn": gui.Tr.SLocalize("scroll"), - "?": gui.Tr.SLocalize("help"), //TODO make it visible for all panels, not only files + "?": gui.Tr.SLocalize("help"), } if gui.State.HasMergeConflicts { optionsMap["a"] = gui.Tr.SLocalize("abortMerge") diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go index 0c323e254..2c5e631cb 100644 --- a/pkg/gui/stash_panel.go +++ b/pkg/gui/stash_panel.go @@ -37,6 +37,7 @@ func (gui *Gui) renderStashOptions(g *gocui.Gui) error { "g": gui.Tr.SLocalize("pop"), "d": gui.Tr.SLocalize("drop"), "← → ↑ ↓": gui.Tr.SLocalize("navigate"), + "?": gui.Tr.SLocalize("help"), }) } diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go index 583d7805a..eb7f790f0 100644 --- a/pkg/gui/status_panel.go +++ b/pkg/gui/status_panel.go @@ -46,6 +46,7 @@ func (gui *Gui) renderStatusOptions(g *gocui.Gui) error { "o": gui.Tr.SLocalize("OpenConfig"), "e": gui.Tr.SLocalize("EditConfig"), "u": gui.Tr.SLocalize("CheckForUpdate"), + "?": gui.Tr.SLocalize("help"), }) } From 9ceaf5b9a9df52bb65632510f6403177a1c94e7e Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Thu, 30 Aug 2018 14:09:08 +0200 Subject: [PATCH 09/47] move descriptions to i18n --- pkg/gui/keybindings.go | 10 +++++----- pkg/i18n/english.go | 3 +++ 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index e8ddb68d5..c4a77e6c4 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -27,11 +27,11 @@ func (gui *Gui) getKeybindings() []Binding { {ViewName: "", Key: 'p', Modifier: gocui.ModNone, Handler: gui.pullFiles}, {ViewName: "", Key: 'R', Modifier: gocui.ModNone, Handler: gui.handleRefresh}, {ViewName: "", Key: '?', Modifier: gocui.ModNone, Handler: gui.handleHelp}, - {ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, KeyReadable: "e", Description: "edit config"}, - {ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig, KeyReadable: "o", Description: "open config"}, - {ViewName: "status", Key: 'u', Modifier: gocui.ModNone, Handler: gui.handleCheckForUpdate, KeyReadable: "u", Description: "check for update"}, - {ViewName: "files", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCommitPress}, - {ViewName: "files", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCommitEditorPress}, + {ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, KeyReadable: "e", Description: gui.Tr.SLocalize("EditConfig")}, + {ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig, KeyReadable: "o", Description: gui.Tr.SLocalize("OpenConfig")}, + {ViewName: "status", Key: 'u', Modifier: gocui.ModNone, Handler: gui.handleCheckForUpdate, KeyReadable: "u", Description: gui.Tr.SLocalize("CheckForUpdate")}, + {ViewName: "files", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCommitPress, KeyReadable: "c", Description: gui.Tr.SLocalize("CommitChanges")}, + {ViewName: "files", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCommitEditorPress, KeyReadable: "C", Description: gui.Tr.SLocalize("CommitChangesWithEditor")}, {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}, diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index c29138e42..83931ac73 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -42,6 +42,9 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "CommitChanges", Other: "commit changes", + }, &i18n.Message{ + ID: "CommitChangesWithEditor", + Other: "commit changes using git editor", }, &i18n.Message{ ID: "StatusTitle", Other: "Status", From 7ec5b6cc3064c51645ea4685452d0ce941038233 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 12:10:03 +0200 Subject: [PATCH 10/47] indent keybindings --- pkg/gui/keybindings.go | 382 ++++++++++++++++++++++++++++++++++------- 1 file changed, 321 insertions(+), 61 deletions(-) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index c4a77e6c4..b6f837f8e 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -16,67 +16,327 @@ type Binding struct { 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: "", Key: '?', Modifier: gocui.ModNone, Handler: gui.handleHelp}, - {ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, KeyReadable: "e", Description: gui.Tr.SLocalize("EditConfig")}, - {ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig, KeyReadable: "o", Description: gui.Tr.SLocalize("OpenConfig")}, - {ViewName: "status", Key: 'u', Modifier: gocui.ModNone, Handler: gui.handleCheckForUpdate, KeyReadable: "u", Description: gui.Tr.SLocalize("CheckForUpdate")}, - {ViewName: "files", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCommitPress, KeyReadable: "c", Description: gui.Tr.SLocalize("CommitChanges")}, - {ViewName: "files", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCommitEditorPress, KeyReadable: "C", Description: gui.Tr.SLocalize("CommitChangesWithEditor")}, - {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: "commitMessage", Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.handleNewlineCommitMessage}, - {ViewName: "help", Key: gocui.KeyEsc, Modifier: gocui.ModNone, Handler: gui.handleHelpClose}, - {ViewName: "help", Key: 'q', Modifier: gocui.ModNone, Handler: gui.handleHelpClose}, - {ViewName: "help", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleHelpPress}, + { + 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: "", + Key: '?', + Modifier: gocui.ModNone, + Handler: gui.handleHelp, + }, { + ViewName: "status", + Key: 'e', + Modifier: gocui.ModNone, + Handler: gui.handleEditConfig, + KeyReadable: "e", + Description: gui.Tr.SLocalize("EditConfig"), + }, { + ViewName: "status", + Key: 'o', + Modifier: gocui.ModNone, + Handler: gui.handleOpenConfig, + KeyReadable: "o", + Description: gui.Tr.SLocalize("OpenConfig"), + }, { + ViewName: "status", + Key: 'u', + Modifier: gocui.ModNone, + Handler: gui.handleCheckForUpdate, + KeyReadable: "u", + Description: gui.Tr.SLocalize("CheckForUpdate"), + }, { + ViewName: "files", + Key: 'c', + Modifier: gocui.ModNone, + Handler: gui.handleCommitPress, + KeyReadable: "c", + Description: gui.Tr.SLocalize("CommitChanges"), + }, { + ViewName: "files", + Key: 'C', + Modifier: gocui.ModNone, + Handler: gui.handleCommitEditorPress, + KeyReadable: "C", + Description: gui.Tr.SLocalize("CommitChangesWithEditor"), + }, { + 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: 's', + Modifier: gocui.ModNone, + Handler: gui.handleSublimeFileOpen, + }, { + ViewName: "files", + Key: 'v', + Modifier: gocui.ModNone, + Handler: gui.handleVsCodeFileOpen, + }, { + 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: '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: "commitMessage", + Key: gocui.KeyTab, + Modifier: gocui.ModNone, + Handler: gui.handleNewlineCommitMessage, + }, { + ViewName: "help", + Key: gocui.KeyEsc, + Modifier: gocui.ModNone, + Handler: gui.handleHelpClose, + }, { + ViewName: "help", + Key: 'q', + Modifier: gocui.ModNone, + Handler: gui.handleHelpClose, + }, { + ViewName: "help", + Key: gocui.KeySpace, + Modifier: gocui.ModNone, + Handler: gui.handleHelpPress, + }, } // Would make these keybindings global but that interferes with editing From 265d7e121ad5696fc9837eb98b913398cab6a08c Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 13:06:53 +0200 Subject: [PATCH 11/47] use Key if it's a rune, otherwise KeyReadable --- pkg/gui/help_panel.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index 81cc712b5..f463de624 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -54,8 +54,17 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { bindings := gui.getKeybindings() for _, binding := range bindings { - if binding.ViewName == v.Name() && binding.Description != "" && binding.KeyReadable != "" { - content += fmt.Sprintf(" %s - %s\n", binding.KeyReadable, binding.Description) + r, ok := binding.Key.(rune) + key := "" + + if ok { + key = string(r) + } else if binding.KeyReadable != "" { + key = binding.KeyReadable + } + + if key != "" && binding.ViewName == v.Name() && binding.Description != "" { + content += fmt.Sprintf(" %s - %s\n", key, binding.Description) keys = append(keys, binding) } } From e376de6d1a4a1033165ce38b2b9b9e3a98eefa1a Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 14:03:03 +0200 Subject: [PATCH 12/47] explicitly delete 'help' view --- pkg/gui/help_panel.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index f463de624..1a93d1c53 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -40,7 +40,7 @@ func (gui *Gui) handleHelpClose(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(v.Name()) + err := g.DeleteView("help") if err != nil { return err } From 90a4cada8228fee74694a66d97a40435ba4f2b1b Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 14:03:43 +0200 Subject: [PATCH 13/47] add missing descriptions --- pkg/gui/keybindings.go | 38 +++++++++++++++++++++++++++++--------- pkg/i18n/english.go | 23 +++++++++++++++++++++++ 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index b6f837f8e..0a6db141b 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -76,35 +76,30 @@ func (gui *Gui) getKeybindings() []Binding { Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig, - KeyReadable: "e", Description: gui.Tr.SLocalize("EditConfig"), }, { ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig, - KeyReadable: "o", Description: gui.Tr.SLocalize("OpenConfig"), }, { ViewName: "status", Key: 'u', Modifier: gocui.ModNone, Handler: gui.handleCheckForUpdate, - KeyReadable: "u", Description: gui.Tr.SLocalize("CheckForUpdate"), }, { ViewName: "files", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCommitPress, - KeyReadable: "c", Description: gui.Tr.SLocalize("CommitChanges"), }, { ViewName: "files", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCommitEditorPress, - KeyReadable: "C", Description: gui.Tr.SLocalize("CommitChangesWithEditor"), }, { ViewName: "files", @@ -112,25 +107,29 @@ func (gui *Gui) getKeybindings() []Binding { Modifier: gocui.ModNone, Handler: gui.handleFilePress, }, { - ViewName: "files", - Key: 'd', - Modifier: gocui.ModNone, - Handler: gui.handleFileRemove, + 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: 's', @@ -146,36 +145,43 @@ func (gui *Gui) getKeybindings() []Binding { 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, @@ -246,66 +252,80 @@ func (gui *Gui) getKeybindings() []Binding { 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: '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, diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 83931ac73..54bf213bf 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -354,6 +354,29 @@ func addEnglish(i18nObject *i18n.Bundle) error { }, &i18n.Message{ ID: "GitconfigParseErr", Other: `Gogit failed to parse your gitconfig file due to the presence of unquoted '\' characters. Removing these should fix the issue.`, + + // KEYBINDINGS DESCRIPTIONS + }, &i18n.Message{ + ID: "removeFile", + Other: `delete if untracked checkout if tracked (aka go away)`, + }, &i18n.Message{ + ID: "editFile", + Other: `edit file`, + }, &i18n.Message{ + ID: "openFile", + Other: `open file`, + }, &i18n.Message{ + ID: "ignoreFile", + Other: `add to .gitignore`, + }, &i18n.Message{ + ID: "refreshFiles", + Other: `refresh files`, + }, &i18n.Message{ + ID: "resetHard", + Other: `reset hard`, + }, &i18n.Message{ + ID: "mergeIntoCurrentBranch", + Other: `merge into currently checked out branch`, }, ) } From 20073d02939059c6ea4d7371f710448a50f0a7d5 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 14:17:45 +0200 Subject: [PATCH 14/47] don't panic "panic: runtime error: index out of range" when executing stash pop 'g' from help menu --- pkg/gui/stash_panel.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go index 2c5e631cb..dd7ecfeb9 100644 --- a/pkg/gui/stash_panel.go +++ b/pkg/gui/stash_panel.go @@ -27,7 +27,8 @@ 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] } From 314c8c279aa9b29649cc5d12b803d33f8a8bef96 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 14:20:45 +0200 Subject: [PATCH 15/47] apply fmt on keybindings --- pkg/gui/keybindings.go | 184 ++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 92 deletions(-) diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 0a6db141b..34c3e0f68 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -113,22 +113,22 @@ func (gui *Gui) getKeybindings() []Binding { Handler: gui.handleFileRemove, Description: gui.Tr.SLocalize("removeFile"), }, { - ViewName: "files", - Key: 'm', - Modifier: gocui.ModNone, - Handler: gui.handleSwitchToMerge, + 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, + 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, + ViewName: "files", + Key: 'o', + Modifier: gocui.ModNone, + Handler: gui.handleFileOpen, Description: gui.Tr.SLocalize("openFile"), }, { ViewName: "files", @@ -141,46 +141,46 @@ func (gui *Gui) getKeybindings() []Binding { Modifier: gocui.ModNone, Handler: gui.handleVsCodeFileOpen, }, { - ViewName: "files", - Key: 'i', - Modifier: gocui.ModNone, - Handler: gui.handleIgnoreFile, + 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, + 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, + 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, + 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, + 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, + 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, + ViewName: "files", + Key: 'D', + Modifier: gocui.ModNone, + Handler: gui.handleResetHard, Description: gui.Tr.SLocalize("resetHard"), }, { ViewName: "main", @@ -248,83 +248,83 @@ func (gui *Gui) getKeybindings() []Binding { Modifier: gocui.ModNone, Handler: gui.handleBranchPress, }, { - ViewName: "branches", - Key: 'c', - Modifier: gocui.ModNone, - Handler: gui.handleCheckoutByName, + 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, + 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, + 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, + 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, + 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, + 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, + 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, + ViewName: "commits", + Key: 'r', + Modifier: gocui.ModNone, + Handler: gui.handleRenameCommit, Description: gui.Tr.SLocalize("RenameCommit"), }, { - ViewName: "commits", - Key: 'g', - Modifier: gocui.ModNone, - Handler: gui.handleResetToCommit, + 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, + 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, + 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, + 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, + ViewName: "stash", + Key: 'd', + Modifier: gocui.ModNone, + Handler: gui.handleStashDrop, Description: gui.Tr.SLocalize("drop"), }, { ViewName: "commitMessage", From 5177e458efa8e647c34f7cee65450c68a5595784 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 15:02:12 +0200 Subject: [PATCH 16/47] use Fprint instead of renderString renderString is wrapping content because of that lines are being select wrong --- pkg/gui/help_panel.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index 1a93d1c53..02c601e8c 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -84,9 +84,7 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { content += "third\n" */ - if err := gui.renderString(g, "help", content); err != nil { - return err - } + fmt.Fprint(helpView, content) g.Update(func(g *gocui.Gui) error { _, err := g.SetViewOnTop("help") From 1fa55875e2487e9b5d9ec910a1b7a5da795333d9 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 15:04:26 +0200 Subject: [PATCH 17/47] remove testing content --- pkg/gui/help_panel.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index 02c601e8c..3c102f2dc 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -78,12 +78,6 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error { return err } - // for testing - /*content += "first\n" - content += "second\n" - content += "third\n" - */ - fmt.Fprint(helpView, content) g.Update(func(g *gocui.Gui) error { From 359636c1aa394bf8b619a7287f504e6afcf11470 Mon Sep 17 00:00:00 2001 From: Dawid Dziurla Date: Sat, 1 Sep 2018 16:50:22 +0200 Subject: [PATCH 18/47] add generate_cheatsheet script script is generating markdown document with small cheatsheet in selected language --- pkg/gui/help_panel.go | 26 ++++++++++++--------- pkg/gui/keybindings.go | 4 ++-- scripts/generate_cheatsheet.go | 41 ++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 scripts/generate_cheatsheet.go diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go index 3c102f2dc..ffb0628b7 100644 --- a/pkg/gui/help_panel.go +++ b/pkg/gui/help_panel.go @@ -47,23 +47,27 @@ func (gui *Gui) handleHelpClose(g *gocui.Gui, v *gocui.View) error { 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) handleHelp(g *gocui.Gui, v *gocui.View) error { // clear keys slice, so we don't have ghost elements keys = keys[:0] content := "" - bindings := gui.getKeybindings() + bindings := gui.GetKeybindings() for _, binding := range bindings { - r, ok := binding.Key.(rune) - key := "" - - if ok { - key = string(r) - } else if binding.KeyReadable != "" { - key = binding.KeyReadable - } - - if key != "" && binding.ViewName == v.Name() && binding.Description != "" { + if key := gui.GetKey(binding); key != "" && binding.ViewName == v.Name() && binding.Description != "" { content += fmt.Sprintf(" %s - %s\n", key, binding.Description) keys = append(keys, binding) } diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 34c3e0f68..034f907bf 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -14,7 +14,7 @@ type Binding struct { Description string } -func (gui *Gui) getKeybindings() []Binding { +func (gui *Gui) GetKeybindings() []Binding { bindings := []Binding{ { ViewName: "", @@ -379,7 +379,7 @@ func (gui *Gui) getKeybindings() []Binding { } func (gui *Gui) keybindings(g *gocui.Gui) error { - bindings := gui.getKeybindings() + bindings := gui.GetKeybindings() for _, binding := range bindings { if err := g.SetKeybinding(binding.ViewName, binding.Key, binding.Modifier, binding.Handler); err != nil { diff --git a/scripts/generate_cheatsheet.go b/scripts/generate_cheatsheet.go new file mode 100644 index 000000000..87ebe43c5 --- /dev/null +++ b/scripts/generate_cheatsheet.go @@ -0,0 +1,41 @@ +// run: +// LANG=en go run generate_cheatsheet.go +// to generate Keybindings_en.md file in current directory +// change LANG to generate cheatsheet in different language (if supported) + +package main + +import ( + "os" + "fmt" + "strings" + + "github.com/jesseduffield/lazygit/pkg/app" + "github.com/jesseduffield/lazygit/pkg/config" +) + +func main() { + appConfig, _ := config.NewAppConfig("", "", "", "", "", new(bool)) + a, _ := app.NewApp(appConfig) + lang := a.Tr.GetLanguage() + name := "Keybindings_" + lang + ".md" + bindings := a.Gui.GetKeybindings() + file, _ := os.Create(name) + current := "" + content := "" + + file.WriteString("# Lazygit " + a.Tr.SLocalize("help")) + + for _, binding := range bindings { + if key := a.Gui.GetKey(binding); key != "" && binding.Description != "" { + if binding.ViewName != current { + current = binding.ViewName + title := a.Tr.SLocalize(strings.Title(current) + "Title") + content = fmt.Sprintf("\n\n## %s\n
\n", title)
+				file.WriteString(content)
+			}
+			content = fmt.Sprintf("\t%s:\t%s\n", key, binding.Description)
+			file.WriteString(content)
+		}
+	}
+}

From b403b6e46d42dd7eb40b8b79e74ef8414d79773b Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Sat, 1 Sep 2018 16:56:43 +0200
Subject: [PATCH 19/47] better english string

---
 pkg/i18n/english.go | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 54bf213bf..116c2258b 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -354,11 +354,9 @@ func addEnglish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "GitconfigParseErr",
 			Other: `Gogit failed to parse your gitconfig file due to the presence of unquoted '\' characters. Removing these should fix the issue.`,
-
-			// KEYBINDINGS DESCRIPTIONS
 		}, &i18n.Message{
 			ID:    "removeFile",
-			Other: `delete if untracked checkout if tracked (aka go away)`,
+			Other: `delete if untracked / checkout if tracked (aka go away)`,
 		}, &i18n.Message{
 			ID:    "editFile",
 			Other: `edit file`,

From 323016aa012309f4b9d87ed2b39be26fda224070 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Sat, 1 Sep 2018 16:57:16 +0200
Subject: [PATCH 20/47] polish translation

---
 pkg/i18n/polish.go | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index 5364d3d8f..78bfacdd0 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -32,12 +32,21 @@ func addPolish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "CommitChanges",
 			Other: "commituj zmiany",
+		}, &i18n.Message{
+			ID:    "CommitChangesWithEditor",
+			Other: "commituj zmiany używając edytora z gita",
 		}, &i18n.Message{
 			ID:    "StatusTitle",
 			Other: "Status",
 		}, &i18n.Message{
 			ID:    "navigate",
 			Other: "nawiguj",
+		}, &i18n.Message{
+			ID:    "help",
+			Other: "pomoc",
+		}, &i18n.Message{
+			ID:    "execute",
+			Other: "wykonaj",
 		}, &i18n.Message{
 			ID:    "stashFiles",
 			Other: "przechowaj pliki",
@@ -164,6 +173,9 @@ func addPolish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "CloseConfirm",
 			Other: "{{.keyBindClose}}: zamknij, {{.keyBindConfirm}}: potwierdź",
+		}, &i18n.Message{
+			ID:    "close",
+			Other: "zamknij",
 		}, &i18n.Message{
 			ID:    "SureResetThisCommit",
 			Other: "Jesteś pewny, że chcesz zresetować ten commit?",
@@ -287,6 +299,27 @@ func addPolish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "MergeAborted",
 			Other: "Scalanie anulowane",
+		}, &i18n.Message{
+			ID:    "removeFile",
+			Other: `usuń jeśli nie śledzony / przełącz jeśli śledzony`,
+		}, &i18n.Message{
+			ID:    "editFile",
+			Other: `edytuj plik`,
+		}, &i18n.Message{
+			ID:    "openFile",
+			Other: `otwórz plik`,
+		}, &i18n.Message{
+			ID:    "ignoreFile",
+			Other: `dodaj do .gitignore`,
+		}, &i18n.Message{
+			ID:    "refreshFiles",
+			Other: `odśwież pliki`,
+		}, &i18n.Message{
+			ID:    "resetHard",
+			Other: `zresetuj twardo`,
+		}, &i18n.Message{
+			ID:    "mergeIntoCurrentBranch",
+			Other: `scal do obecnej gałęzi`,
 		},
 	)
 }

From 83b7c60246e96799b840700da2e9dcacf2067c4c Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Sat, 1 Sep 2018 16:57:41 +0200
Subject: [PATCH 21/47] add untranslated dutch strings

@mjarkk
---
 pkg/i18n/dutch.go | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index ff588b264..0abb41771 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -34,12 +34,21 @@ func addDutch(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "CommitChanges",
 			Other: "Commit Veranderingen",
+		}, &i18n.Message{
+			ID:    "CommitChangesWithEditor",
+			Other: "commit changes using git editor",
 		}, &i18n.Message{
 			ID:    "StatusTitle",
 			Other: "Status",
 		}, &i18n.Message{
 			ID:    "navigate",
 			Other: "navigeer",
+		}, &i18n.Message{
+			ID:    "help",
+			Other: "help",
+		}, &i18n.Message{
+			ID:    "execute",
+			Other: "execute",
 		}, &i18n.Message{
 			ID:    "stashFiles",
 			Other: "stash-bestanden",
@@ -172,6 +181,9 @@ func addDutch(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "CloseConfirm",
 			Other: "{{.keyBindClose}}: Sluiten, {{.keyBindConfirm}}: Bevestigen",
+		}, &i18n.Message{
+			ID:    "close",
+			Other: "close",
 		}, &i18n.Message{
 			ID:    "SureResetThisCommit",
 			Other: "Weet je het zeker dat je wil resetten naar deze commit?",
@@ -295,6 +307,27 @@ func addDutch(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "MergeAborted",
 			Other: "Merge afgebroken",
+		}, &i18n.Message{
+			ID:    "removeFile",
+			Other: `delete if untracked / checkout if tracked (aka go away)`,
+		}, &i18n.Message{
+			ID:    "editFile",
+			Other: `edit file`,
+		}, &i18n.Message{
+			ID:    "openFile",
+			Other: `open file`,
+		}, &i18n.Message{
+			ID:    "ignoreFile",
+			Other: `add to .gitignore`,
+		}, &i18n.Message{
+			ID:    "refreshFiles",
+			Other: `refresh files`,
+		}, &i18n.Message{
+			ID:    "resetHard",
+			Other: `reset hard`,
+		}, &i18n.Message{
+			ID:    "mergeIntoCurrentBranch",
+			Other: `merge into currently checked out branch`,
 		},
 	)
 }

From 36874be45b800c5a63a11f1677a63569010feb44 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Sat, 1 Sep 2018 17:01:13 +0200
Subject: [PATCH 22/47] apply very important fmt

---
 scripts/generate_cheatsheet.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/generate_cheatsheet.go b/scripts/generate_cheatsheet.go
index 87ebe43c5..434f56bdd 100644
--- a/scripts/generate_cheatsheet.go
+++ b/scripts/generate_cheatsheet.go
@@ -6,8 +6,8 @@
 package main
 
 import (
-	"os"
 	"fmt"
+	"os"
 	"strings"
 
 	"github.com/jesseduffield/lazygit/pkg/app"

From b5827b7d8085769e22f1af8f21612641edcf3aaa Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Mon, 3 Sep 2018 17:57:03 +0200
Subject: [PATCH 23/47] merge conflict effect fix

---
 pkg/gui/keybindings.go | 16 ++++++----------
 pkg/i18n/english.go    |  3 +++
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 034f907bf..598465fc5 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -130,16 +130,6 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Modifier:    gocui.ModNone,
 			Handler:     gui.handleFileOpen,
 			Description: gui.Tr.SLocalize("openFile"),
-		}, {
-			ViewName: "files",
-			Key:      's',
-			Modifier: gocui.ModNone,
-			Handler:  gui.handleSublimeFileOpen,
-		}, {
-			ViewName: "files",
-			Key:      'v',
-			Modifier: gocui.ModNone,
-			Handler:  gui.handleVsCodeFileOpen,
 		}, {
 			ViewName:    "files",
 			Key:         'i',
@@ -295,6 +285,12 @@ func (gui *Gui) GetKeybindings() []Binding {
 			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',
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 116c2258b..b6847a2b4 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -237,6 +237,9 @@ func addEnglish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "RenameCommit",
 			Other: "Rename Commit",
+		}, &i18n.Message{
+			ID:    "RenameCommitEditor",
+			Other: "Rename Commit with editor",
 		}, &i18n.Message{
 			ID:    "PotentialErrInGetselectedCommit",
 			Other: "potential error in getSelected Commit (mismatched ui and state)",

From 59f50010b64339908e511b6a6af0a07aed6680e7 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Mon, 3 Sep 2018 18:01:07 +0200
Subject: [PATCH 24/47] apply fmt again

---
 pkg/gui/keybindings.go | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 598465fc5..c2f53f7ee 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -285,11 +285,11 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Modifier:    gocui.ModNone,
 			Handler:     gui.handleRenameCommit,
 			Description: gui.Tr.SLocalize("RenameCommit"),
-		},{
-			ViewName: "commits",
-			Key: 'R',
-			Modifier: gocui.ModNone,
-			Handler: gui.handleRenameCommitEditor,
+		}, {
+			ViewName:    "commits",
+			Key:         'R',
+			Modifier:    gocui.ModNone,
+			Handler:     gui.handleRenameCommitEditor,
 			Description: gui.Tr.SLocalize("RenameCommitEditor"),
 		}, {
 			ViewName:    "commits",

From c49e4dc287701af125674f91ea917e36cd973dce Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Mon, 3 Sep 2018 18:07:38 +0200
Subject: [PATCH 25/47] get item position from correct panel

---
 pkg/gui/commits_panel.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 2c1cc6178..605566505 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -141,7 +141,7 @@ 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 {
@@ -157,7 +157,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"))
 	}
 

From 230a5afa4cda31198611751534c839f1bf87b873 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Mon, 3 Sep 2018 18:16:54 +0200
Subject: [PATCH 26/47] remove capitalization of keybindings descriptions

---
 pkg/gui/commits_panel.go |  2 +-
 pkg/gui/keybindings.go   |  6 +++---
 pkg/gui/status_panel.go  |  2 +-
 pkg/i18n/dutch.go        |  4 ++--
 pkg/i18n/english.go      | 12 ++++++------
 pkg/i18n/polish.go       |  4 ++--
 6 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 605566505..5074968b3 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -144,7 +144,7 @@ func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
 	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 {
+	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())
 		}
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index c2f53f7ee..9d5dc27ff 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -88,7 +88,7 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Key:         'u',
 			Modifier:    gocui.ModNone,
 			Handler:     gui.handleCheckForUpdate,
-			Description: gui.Tr.SLocalize("CheckForUpdate"),
+			Description: gui.Tr.SLocalize("checkForUpdate"),
 		}, {
 			ViewName:    "files",
 			Key:         'c',
@@ -284,13 +284,13 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Key:         'r',
 			Modifier:    gocui.ModNone,
 			Handler:     gui.handleRenameCommit,
-			Description: gui.Tr.SLocalize("RenameCommit"),
+			Description: gui.Tr.SLocalize("renameCommit"),
 		}, {
 			ViewName:    "commits",
 			Key:         'R',
 			Modifier:    gocui.ModNone,
 			Handler:     gui.handleRenameCommitEditor,
-			Description: gui.Tr.SLocalize("RenameCommitEditor"),
+			Description: gui.Tr.SLocalize("renameCommitEditor"),
 		}, {
 			ViewName:    "commits",
 			Key:         'g',
diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go
index eb7f790f0..0e00b1835 100644
--- a/pkg/gui/status_panel.go
+++ b/pkg/gui/status_panel.go
@@ -45,7 +45,7 @@ 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"),
+		"u": gui.Tr.SLocalize("checkForUpdate"),
 		"?": gui.Tr.SLocalize("help"),
 	})
 }
diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index 0abb41771..28ba9f7c2 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -224,8 +224,8 @@ func addDutch(i18nObject *i18n.Bundle) error {
 			ID:    "OnlyRenameTopCommit",
 			Other: "Je kan alleen de bovenste commit hernoemen",
 		}, &i18n.Message{
-			ID:    "RenameCommit",
-			Other: "Hernoem Commit",
+			ID:    "renameCommit",
+			Other: "hernoem commit",
 		}, &i18n.Message{
 			ID:    "PotentialErrInGetselectedCommit",
 			Other: "Er is mogelijk een error in getSelected Commit (geen match tussen ui en state)",
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index b6847a2b4..8b0d266f3 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -235,11 +235,11 @@ func addEnglish(i18nObject *i18n.Bundle) error {
 			ID:    "OnlyRenameTopCommit",
 			Other: "Can only rename topmost commit",
 		}, &i18n.Message{
-			ID:    "RenameCommit",
-			Other: "Rename Commit",
+			ID:    "renameCommit",
+			Other: "rename commit",
 		}, &i18n.Message{
-			ID:    "RenameCommitEditor",
-			Other: "Rename Commit with editor",
+			ID:    "renameCommitEditor",
+			Other: "rename commit with editor",
 		}, &i18n.Message{
 			ID:    "PotentialErrInGetselectedCommit",
 			Other: "potential error in getSelected Commit (mismatched ui and state)",
@@ -334,8 +334,8 @@ func addEnglish(i18nObject *i18n.Bundle) error {
 			ID:    "ForcePushPrompt",
 			Other: "Your branch has diverged from the remote branch. Press 'esc' to cancel, or 'enter' to force push.",
 		}, &i18n.Message{
-			ID:    "CheckForUpdate",
-			Other: "Check for update",
+			ID:    "checkForUpdate",
+			Other: "check for update",
 		}, &i18n.Message{
 			ID:    "CheckingForUpdates",
 			Other: "Checking for updates...",
diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index 78bfacdd0..a9734d74c 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -216,8 +216,8 @@ func addPolish(i18nObject *i18n.Bundle) error {
 			ID:    "OnlyRenameTopCommit",
 			Other: "Można przmianować tylko najwyższy commit",
 		}, &i18n.Message{
-			ID:    "RenameCommit",
-			Other: "Przemianuj commit",
+			ID:    "renameCommit",
+			Other: "przemianuj commit",
 		}, &i18n.Message{
 			ID:    "PotentialErrInGetselectedCommit",
 			Other: "potencjalny błąd w getSelected Commit (niedopasowane ui i stan)",

From a2073528f468b0f9022c800125863b3a4b8b214b Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Mon, 3 Sep 2018 18:33:38 +0200
Subject: [PATCH 27/47] add missing untranslated dutch strings

@mjarkk
---
 pkg/i18n/dutch.go | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index 28ba9f7c2..daaa47fd1 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -226,6 +226,9 @@ func addDutch(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "renameCommit",
 			Other: "hernoem commit",
+		}, &i18n.Message{
+			ID:    "renameCommitEditor",
+			Other: "rename commit with editor",
 		}, &i18n.Message{
 			ID:    "PotentialErrInGetselectedCommit",
 			Other: "Er is mogelijk een error in getSelected Commit (geen match tussen ui en state)",
@@ -307,6 +310,39 @@ func addDutch(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "MergeAborted",
 			Other: "Merge afgebroken",
+		}, &i18n.Message{
+			ID:    "OpenConfig",
+			Other: "open config file",
+		}, &i18n.Message{
+			ID:    "EditConfig",
+			Other: "edit config file",
+		}, &i18n.Message{
+			ID:    "ForcePush",
+			Other: "Force push",
+		}, &i18n.Message{
+			ID:    "ForcePushPrompt",
+			Other: "Your branch has diverged from the remote branch. Press 'esc' to cancel, or 'enter' to force push.",
+		}, &i18n.Message{
+			ID:    "checkForUpdate",
+			Other: "check for update",
+		}, &i18n.Message{
+			ID:    "CheckingForUpdates",
+			Other: "Checking for updates...",
+		}, &i18n.Message{
+			ID:    "OnLatestVersionErr",
+			Other: "You already have the latest version",
+		}, &i18n.Message{
+			ID:    "MajorVersionErr",
+			Other: "New version ({{.newVersion}}) has non-backwards compatible changes compared to the current version ({{.currentVersion}})",
+		}, &i18n.Message{
+			ID:    "CouldNotFindBinaryErr",
+			Other: "Could not find any binary at {{.url}}",
+		}, &i18n.Message{
+			ID:    "AnonymousReportingTitle",
+			Other: "Help make lazygit better",
+		}, &i18n.Message{
+			ID:    "AnonymousReportingPrompt",
+			Other: "Would you like to enable anonymous reporting data to help improve lazygit? (enter/esc)",
 		}, &i18n.Message{
 			ID:    "removeFile",
 			Other: `delete if untracked / checkout if tracked (aka go away)`,

From 93e88ea8fea32b77365fee600ea745618f6256d3 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Mon, 3 Sep 2018 18:34:04 +0200
Subject: [PATCH 28/47] add missing translated polish strings

---
 pkg/i18n/polish.go | 42 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index a9734d74c..795c3b4fa 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -143,6 +143,9 @@ func addPolish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "DeleteBranchMessage",
 			Other: "Jesteś pewien, że chcesz usunąć gałąź {{.selectedBranchName}} ?",
+		}, &i18n.Message{
+			ID:    "ForceDeleteBranchMessage",
+			Other: "Na pewno wymusić usunięcie gałęzi {{.selectedBranchName}}?",
 		}, &i18n.Message{
 			ID:    "CantMergeBranchIntoItself",
 			Other: "Nie możesz scalić gałęzi do samej siebie",
@@ -161,6 +164,9 @@ func addPolish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "deleteBranch",
 			Other: "usuń gałąź",
+		}, &i18n.Message{
+			ID:    "forceDeleteBranch",
+			Other: "usuń gałąź (wymuś)",
 		}, &i18n.Message{
 			ID:    "NoBranchesThisRepo",
 			Other: "Brak gałęzi dla tego repozytorium",
@@ -218,6 +224,9 @@ func addPolish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "renameCommit",
 			Other: "przemianuj commit",
+		}, &i18n.Message{
+			ID:    "renameCommitEditor",
+			Other: "przemianuj commit w edytorze",
 		}, &i18n.Message{
 			ID:    "PotentialErrInGetselectedCommit",
 			Other: "potencjalny błąd w getSelected Commit (niedopasowane ui i stan)",
@@ -299,6 +308,39 @@ func addPolish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "MergeAborted",
 			Other: "Scalanie anulowane",
+		}, &i18n.Message{
+			ID:    "OpenConfig",
+			Other: "otwórz plik konfiguracyjny",
+		}, &i18n.Message{
+			ID:    "EditConfig",
+			Other: "edytuj plik konfiguracyjny",
+		}, &i18n.Message{
+			ID:    "ForcePush",
+			Other: "Wymuś wypchnięcie",
+		}, &i18n.Message{
+			ID:    "ForcePushPrompt",
+			Other: "Twoja gałąź rozeszła się z gałęzią zdalną. Wciśnij 'esc' aby anulować lub 'enter' aby wymusić wypchnięcie.",
+		}, &i18n.Message{
+			ID:    "checkForUpdate",
+			Other: "sprawdź aktualizacje",
+		}, &i18n.Message{
+			ID:    "CheckingForUpdates",
+			Other: "Sprawdzanie aktualizacji...",
+		}, &i18n.Message{
+			ID:    "OnLatestVersionErr",
+			Other: "Już posiadasz najnowszą wersję",
+		}, &i18n.Message{
+			ID:    "MajorVersionErr",
+			Other: "Nowa wersja ({{.newVersion}}) posiada niekompatybilne zmiany w porównaniu do obecnej wersji ({{.currentVersion}})",
+		}, &i18n.Message{
+			ID:    "CouldNotFindBinaryErr",
+			Other: "Nie można znaleźć pliku binarnego w {{.url}}",
+		}, &i18n.Message{
+			ID:    "AnonymousReportingTitle",
+			Other: "Help make lazygit better",
+		}, &i18n.Message{
+			ID:    "AnonymousReportingPrompt",
+			Other: "Włączyć anonimowe raportowanie błędów w celu pomocy w usprawnianiu lazygita (enter/esc)?",
 		}, &i18n.Message{
 			ID:    "removeFile",
 			Other: `usuń jeśli nie śledzony / przełącz jeśli śledzony`,

From bf8514f5e2fa5182fadbee08f1348b0e5021b3aa Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Mon, 3 Sep 2018 18:44:56 +0200
Subject: [PATCH 29/47] helperize spaces

---
 pkg/gui/keybindings.go | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 9d5dc27ff..29caa9a26 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -102,10 +102,12 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Handler:     gui.handleCommitEditorPress,
 			Description: gui.Tr.SLocalize("CommitChangesWithEditor"),
 		}, {
-			ViewName: "files",
-			Key:      gocui.KeySpace,
-			Modifier: gocui.ModNone,
-			Handler:  gui.handleFilePress,
+			ViewName:    "files",
+			Key:         gocui.KeySpace,
+			Modifier:    gocui.ModNone,
+			Handler:     gui.handleFilePress,
+			KeyReadable: "space",
+			Description: gui.Tr.SLocalize("toggleStaged"),
 		}, {
 			ViewName:    "files",
 			Key:         'd',
@@ -233,10 +235,12 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Modifier: gocui.ModNone,
 			Handler:  gui.handlePopFileSnapshot,
 		}, {
-			ViewName: "branches",
-			Key:      gocui.KeySpace,
-			Modifier: gocui.ModNone,
-			Handler:  gui.handleBranchPress,
+			ViewName:    "branches",
+			Key:         gocui.KeySpace,
+			Modifier:    gocui.ModNone,
+			Handler:     gui.handleBranchPress,
+			KeyReadable: "space",
+			Description: gui.Tr.SLocalize("checkout"),
 		}, {
 			ViewName:    "branches",
 			Key:         'c',

From 67d99a24ea2686be562e8edfb650da5d90c5a68c Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Mon, 3 Sep 2018 18:45:52 +0200
Subject: [PATCH 30/47] get selected branch from correct panel

---
 pkg/gui/branches_panel.go | 4 ++--
 pkg/gui/view_helpers.go   | 6 ++++++
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index 61b8f1a2f..b56f189ce 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())
 	}
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index 4cab2de08..5f2630204 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -248,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
@@ -263,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())
 }

From f29c81fb5c3bacb0ba3c0bf3ba090a36a2381a9c Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Tue, 4 Sep 2018 15:25:02 +0200
Subject: [PATCH 31/47] add getMaxKeyLength

---
 pkg/gui/help_panel.go | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go
index ffb0628b7..958014432 100644
--- a/pkg/gui/help_panel.go
+++ b/pkg/gui/help_panel.go
@@ -5,6 +5,7 @@ import (
 	"strings"
 
 	"github.com/jesseduffield/gocui"
+	"github.com/jesseduffield/lazygit/pkg/utils"
 )
 
 var keys []Binding
@@ -60,15 +61,27 @@ func (gui *Gui) GetKey(binding Binding) string {
 	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) handleHelp(g *gocui.Gui, v *gocui.View) error {
 	// clear keys slice, so we don't have ghost elements
 	keys = keys[:0]
 	content := ""
 	bindings := gui.GetKeybindings()
+	padWidth := gui.getMaxKeyLength(bindings)
 
 	for _, binding := range bindings {
 		if key := gui.GetKey(binding); key != "" && binding.ViewName == v.Name() && binding.Description != "" {
-			content += fmt.Sprintf(" %s - %s\n", key, binding.Description)
+			content += fmt.Sprintf("%s  %s\n", utils.WithPadding(key, padWidth), binding.Description)
 			keys = append(keys, binding)
 		}
 	}

From 7b84c162f420aff8acb330004baec665415afc93 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Tue, 4 Sep 2018 15:25:54 +0200
Subject: [PATCH 32/47] set help panel fgcolor to white

---
 pkg/gui/help_panel.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go
index 958014432..1d734409f 100644
--- a/pkg/gui/help_panel.go
+++ b/pkg/gui/help_panel.go
@@ -90,6 +90,7 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error {
 	x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, content)
 	helpView, _ := g.SetView("help", x0, y0, x1, y1-1, 0)
 	helpView.Title = strings.Title(gui.Tr.SLocalize("help"))
+	helpView.FgColor = gocui.ColorWhite
 
 	if err := gui.renderHelpOptions(g); err != nil {
 		return err

From cbafadd48e7d4ccbdb8b50dc32fa4f570c4b6434 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Tue, 4 Sep 2018 15:29:43 +0200
Subject: [PATCH 33/47] move keys slice to guiState struct

---
 pkg/gui/gui.go        |  1 +
 pkg/gui/help_panel.go | 10 ++++------
 2 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 2a68bce71..74cfd06a6 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
diff --git a/pkg/gui/help_panel.go b/pkg/gui/help_panel.go
index 1d734409f..2bc8dcb41 100644
--- a/pkg/gui/help_panel.go
+++ b/pkg/gui/help_panel.go
@@ -8,16 +8,14 @@ import (
 	"github.com/jesseduffield/lazygit/pkg/utils"
 )
 
-var keys []Binding
-
 func (gui *Gui) handleHelpPress(g *gocui.Gui, v *gocui.View) error {
 	lineNumber := gui.getItemPosition(v)
-	if len(keys) > lineNumber {
+	if len(gui.State.Keys) > lineNumber {
 		err := gui.handleHelpClose(g, v)
 		if err != nil {
 			return err
 		}
-		return keys[lineNumber].Handler(g, v)
+		return gui.State.Keys[lineNumber].Handler(g, v)
 	}
 	return nil
 }
@@ -74,7 +72,7 @@ func (gui *Gui) getMaxKeyLength(bindings []Binding) int {
 
 func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error {
 	// clear keys slice, so we don't have ghost elements
-	keys = keys[:0]
+	gui.State.Keys = gui.State.Keys[:0]
 	content := ""
 	bindings := gui.GetKeybindings()
 	padWidth := gui.getMaxKeyLength(bindings)
@@ -82,7 +80,7 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error {
 	for _, binding := range bindings {
 		if key := gui.GetKey(binding); key != "" && binding.ViewName == v.Name() && binding.Description != "" {
 			content += fmt.Sprintf("%s  %s\n", utils.WithPadding(key, padWidth), binding.Description)
-			keys = append(keys, binding)
+			gui.State.Keys = append(gui.State.Keys, binding)
 		}
 	}
 

From 97ad4a1643f1ef83b151d78314b9c6bcb50adbfe Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Tue, 4 Sep 2018 15:40:29 +0200
Subject: [PATCH 34/47] delete options

---
 pkg/gui/branches_panel.go |  7 -------
 pkg/gui/commits_panel.go  |  4 ----
 pkg/gui/files_panel.go    | 12 +-----------
 pkg/gui/stash_panel.go    |  3 ---
 pkg/gui/status_panel.go   |  3 ---
 5 files changed, 1 insertion(+), 28 deletions(-)

diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index b56f189ce..74ee14b06 100644
--- a/pkg/gui/branches_panel.go
+++ b/pkg/gui/branches_panel.go
@@ -116,13 +116,6 @@ 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"),
 		"?":       gui.Tr.SLocalize("help"),
 	})
diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 5074968b3..9e8eb681a 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -60,10 +60,6 @@ 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"),
 		"?":       gui.Tr.SLocalize("help"),
 	})
diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go
index 90f2b7e84..43a88c6d2 100644
--- a/pkg/gui/files_panel.go
+++ b/pkg/gui/files_panel.go
@@ -173,18 +173,8 @@ 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"),
+		"← → ↑ ↓":   gui.Tr.SLocalize("navigate"),
 		"?":         gui.Tr.SLocalize("help"),
 	}
 	if gui.State.HasMergeConflicts {
diff --git a/pkg/gui/stash_panel.go b/pkg/gui/stash_panel.go
index dd7ecfeb9..33f42e5f6 100644
--- a/pkg/gui/stash_panel.go
+++ b/pkg/gui/stash_panel.go
@@ -34,9 +34,6 @@ func (gui *Gui) getSelectedStashEntry(v *gocui.View) *commands.StashEntry {
 
 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"),
 		"?":       gui.Tr.SLocalize("help"),
 	})
diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go
index 0e00b1835..96eb2d52e 100644
--- a/pkg/gui/status_panel.go
+++ b/pkg/gui/status_panel.go
@@ -43,9 +43,6 @@ 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"),
 		"?": gui.Tr.SLocalize("help"),
 	})
 }

From e21f739f4fbef045c90ab44365105c2d04334a72 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Tue, 4 Sep 2018 16:07:31 +0200
Subject: [PATCH 35/47] add renderGlobalOptions

render only global options for all panels
---
 pkg/gui/branches_panel.go |  5 +----
 pkg/gui/commits_panel.go  |  5 +----
 pkg/gui/files_panel.go    | 17 +----------------
 pkg/gui/gui.go            | 12 ++++++++++++
 pkg/gui/stash_panel.go    |  5 +----
 pkg/gui/status_panel.go   |  4 +---
 pkg/i18n/english.go       |  6 ++++++
 7 files changed, 23 insertions(+), 31 deletions(-)

diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go
index 74ee14b06..26c3c5618 100644
--- a/pkg/gui/branches_panel.go
+++ b/pkg/gui/branches_panel.go
@@ -115,10 +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{
-		"← → ↑ ↓": gui.Tr.SLocalize("navigate"),
-		"?":       gui.Tr.SLocalize("help"),
-	})
+	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 9e8eb681a..06b8490a9 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -59,10 +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{
-		"← → ↑ ↓": gui.Tr.SLocalize("navigate"),
-		"?":       gui.Tr.SLocalize("help"),
-	})
+	return gui.renderGlobalOptions(g)
 }
 
 func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go
index 43a88c6d2..52366304b 100644
--- a/pkg/gui/files_panel.go
+++ b/pkg/gui/files_panel.go
@@ -172,22 +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{
-		"PgUp/PgDn": gui.Tr.SLocalize("scroll"),
-		"← → ↑ ↓":   gui.Tr.SLocalize("navigate"),
-		"?":         gui.Tr.SLocalize("help"),
-	}
-	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 74cfd06a6..bd5d5fd2c 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -348,6 +348,18 @@ 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{
+		"R":         gui.Tr.SLocalize("refresh"),
+		"p":         gui.Tr.SLocalize("pull"),
+		"P":         gui.Tr.SLocalize("push"),
+		"PgUp/PgDn": gui.Tr.SLocalize("scroll"),
+		"← → ↑ ↓":   gui.Tr.SLocalize("navigate"),
+		"esc/q":     gui.Tr.SLocalize("close"),
+		"?":         gui.Tr.SLocalize("help"),
+	})
+}
+
 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/stash_panel.go b/pkg/gui/stash_panel.go
index 33f42e5f6..9ca07717b 100644
--- a/pkg/gui/stash_panel.go
+++ b/pkg/gui/stash_panel.go
@@ -33,10 +33,7 @@ func (gui *Gui) getSelectedStashEntry(v *gocui.View) *commands.StashEntry {
 }
 
 func (gui *Gui) renderStashOptions(g *gocui.Gui) error {
-	return gui.renderOptionsMap(g, map[string]string{
-		"← → ↑ ↓": gui.Tr.SLocalize("navigate"),
-		"?":       gui.Tr.SLocalize("help"),
-	})
+	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 96eb2d52e..6948e9678 100644
--- a/pkg/gui/status_panel.go
+++ b/pkg/gui/status_panel.go
@@ -42,9 +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{
-		"?": gui.Tr.SLocalize("help"),
-	})
+	return gui.renderGlobalOptions(g)
 }
 
 func (gui *Gui) handleCheckForUpdate(g *gocui.Gui, v *gocui.View) error {
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 8b0d266f3..5dcb9d544 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -78,6 +78,12 @@ func addEnglish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "refresh",
 			Other: "refresh",
+		}, &i18n.Message{
+			ID:    "push",
+			Other: "push",
+		}, &i18n.Message{
+			ID:    "pull",
+			Other: "pull",
 		}, &i18n.Message{
 			ID:    "addPatch",
 			Other: "add patch",

From 557009e660e3203dce62624599c173e25f086465 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Wed, 5 Sep 2018 11:12:11 +0200
Subject: [PATCH 36/47] help -> menu

---
 pkg/gui/gui.go                           |  2 +-
 pkg/gui/keybindings.go                   | 16 +++++++-------
 pkg/gui/{help_panel.go => menu_panel.go} | 28 ++++++++++++------------
 pkg/gui/view_helpers.go                  |  4 ++--
 pkg/i18n/dutch.go                        |  4 ++--
 pkg/i18n/english.go                      |  4 ++--
 pkg/i18n/polish.go                       |  2 +-
 scripts/generate_cheatsheet.go           |  2 +-
 8 files changed, 31 insertions(+), 31 deletions(-)
 rename pkg/gui/{help_panel.go => menu_panel.go} (74%)

diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index bd5d5fd2c..c9beb36eb 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -356,7 +356,7 @@ func (gui *Gui) renderGlobalOptions(g *gocui.Gui) error {
 		"PgUp/PgDn": gui.Tr.SLocalize("scroll"),
 		"← → ↑ ↓":   gui.Tr.SLocalize("navigate"),
 		"esc/q":     gui.Tr.SLocalize("close"),
-		"?":         gui.Tr.SLocalize("help"),
+		"?":         gui.Tr.SLocalize("menu"),
 	})
 }
 
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 29caa9a26..0ca82d3c6 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -70,7 +70,7 @@ func (gui *Gui) GetKeybindings() []Binding {
 			ViewName: "",
 			Key:      '?',
 			Modifier: gocui.ModNone,
-			Handler:  gui.handleHelp,
+			Handler:  gui.handleMenu,
 		}, {
 			ViewName:    "status",
 			Key:         'e',
@@ -342,26 +342,26 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Modifier: gocui.ModNone,
 			Handler:  gui.handleNewlineCommitMessage,
 		}, {
-			ViewName: "help",
+			ViewName: "menu",
 			Key:      gocui.KeyEsc,
 			Modifier: gocui.ModNone,
-			Handler:  gui.handleHelpClose,
+			Handler:  gui.handleMenuClose,
 		}, {
-			ViewName: "help",
+			ViewName: "menu",
 			Key:      'q',
 			Modifier: gocui.ModNone,
-			Handler:  gui.handleHelpClose,
+			Handler:  gui.handleMenuClose,
 		}, {
-			ViewName: "help",
+			ViewName: "menu",
 			Key:      gocui.KeySpace,
 			Modifier: gocui.ModNone,
-			Handler:  gui.handleHelpPress,
+			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", "help"} {
+	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},
diff --git a/pkg/gui/help_panel.go b/pkg/gui/menu_panel.go
similarity index 74%
rename from pkg/gui/help_panel.go
rename to pkg/gui/menu_panel.go
index 2bc8dcb41..fa276e8c4 100644
--- a/pkg/gui/help_panel.go
+++ b/pkg/gui/menu_panel.go
@@ -8,10 +8,10 @@ import (
 	"github.com/jesseduffield/lazygit/pkg/utils"
 )
 
-func (gui *Gui) handleHelpPress(g *gocui.Gui, v *gocui.View) error {
+func (gui *Gui) handleMenuPress(g *gocui.Gui, v *gocui.View) error {
 	lineNumber := gui.getItemPosition(v)
 	if len(gui.State.Keys) > lineNumber {
-		err := gui.handleHelpClose(g, v)
+		err := gui.handleMenuClose(g, v)
 		if err != nil {
 			return err
 		}
@@ -20,13 +20,13 @@ func (gui *Gui) handleHelpPress(g *gocui.Gui, v *gocui.View) error {
 	return nil
 }
 
-func (gui *Gui) handleHelpSelect(g *gocui.Gui, v *gocui.View) error {
+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) renderHelpOptions(g *gocui.Gui) error {
+func (gui *Gui) renderMenuOptions(g *gocui.Gui) error {
 	optionsMap := map[string]string{
 		"esc/q": gui.Tr.SLocalize("close"),
 		"↑ ↓":   gui.Tr.SLocalize("navigate"),
@@ -35,11 +35,11 @@ func (gui *Gui) renderHelpOptions(g *gocui.Gui) error {
 	return gui.renderOptionsMap(g, optionsMap)
 }
 
-func (gui *Gui) handleHelpClose(g *gocui.Gui, v *gocui.View) error {
+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("help")
+	err := g.DeleteView("menu")
 	if err != nil {
 		return err
 	}
@@ -70,7 +70,7 @@ func (gui *Gui) getMaxKeyLength(bindings []Binding) int {
 	return max
 }
 
-func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error {
+func (gui *Gui) handleMenu(g *gocui.Gui, v *gocui.View) error {
 	// clear keys slice, so we don't have ghost elements
 	gui.State.Keys = gui.State.Keys[:0]
 	content := ""
@@ -86,22 +86,22 @@ func (gui *Gui) handleHelp(g *gocui.Gui, v *gocui.View) error {
 
 	// y1-1 so there will not be an extra space at the end of panel
 	x0, y0, x1, y1 := gui.getConfirmationPanelDimensions(g, content)
-	helpView, _ := g.SetView("help", x0, y0, x1, y1-1, 0)
-	helpView.Title = strings.Title(gui.Tr.SLocalize("help"))
-	helpView.FgColor = gocui.ColorWhite
+	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.renderHelpOptions(g); err != nil {
+	if err := gui.renderMenuOptions(g); err != nil {
 		return err
 	}
 
-	fmt.Fprint(helpView, content)
+	fmt.Fprint(menuView, content)
 
 	g.Update(func(g *gocui.Gui) error {
-		_, err := g.SetViewOnTop("help")
+		_, err := g.SetViewOnTop("menu")
 		if err != nil {
 			return err
 		}
-		return gui.switchFocus(g, v, helpView)
+		return gui.switchFocus(g, v, menuView)
 	})
 	return nil
 }
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index 5f2630204..88b74d12e 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -82,8 +82,8 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
 	mainView.SetOrigin(0, 0)
 
 	switch v.Name() {
-	case "help":
-		return gui.handleHelpSelect(g, v)
+	case "menu":
+		return gui.handleMenuSelect(g, v)
 	case "status":
 		return gui.handleStatusSelect(g, v)
 	case "files":
diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index daaa47fd1..cbdccbf2a 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -44,8 +44,8 @@ func addDutch(i18nObject *i18n.Bundle) error {
 			ID:    "navigate",
 			Other: "navigeer",
 		}, &i18n.Message{
-			ID:    "help",
-			Other: "help",
+			ID:    "menu",
+			Other: "menu",
 		}, &i18n.Message{
 			ID:    "execute",
 			Other: "execute",
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 5dcb9d544..471a75b6f 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -52,8 +52,8 @@ func addEnglish(i18nObject *i18n.Bundle) error {
 			ID:    "navigate",
 			Other: "navigate",
 		}, &i18n.Message{
-			ID:    "help",
-			Other: "help",
+			ID:    "menu",
+			Other: "menu",
 		}, &i18n.Message{
 			ID:    "execute",
 			Other: "execute",
diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index 795c3b4fa..f99890c15 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -42,7 +42,7 @@ func addPolish(i18nObject *i18n.Bundle) error {
 			ID:    "navigate",
 			Other: "nawiguj",
 		}, &i18n.Message{
-			ID:    "help",
+			ID:    "menu",
 			Other: "pomoc",
 		}, &i18n.Message{
 			ID:    "execute",
diff --git a/scripts/generate_cheatsheet.go b/scripts/generate_cheatsheet.go
index 434f56bdd..2c18e5f03 100644
--- a/scripts/generate_cheatsheet.go
+++ b/scripts/generate_cheatsheet.go
@@ -24,7 +24,7 @@ func main() {
 	current := ""
 	content := ""
 
-	file.WriteString("# Lazygit " + a.Tr.SLocalize("help"))
+	file.WriteString("# Lazygit " + a.Tr.SLocalize("menu"))
 
 	for _, binding := range bindings {
 		if key := a.Gui.GetKey(binding); key != "" && binding.Description != "" {

From 906f8e252e43c1dbd2303fb90de660a2181e5f32 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Wed, 5 Sep 2018 13:01:21 +0200
Subject: [PATCH 37/47] include global keybindings in menu

---
 pkg/gui/gui.go                 |  3 ---
 pkg/gui/keybindings.go         |  3 +++
 pkg/gui/menu_panel.go          | 15 ++++++++++++---
 pkg/i18n/dutch.go              |  3 +++
 pkg/i18n/english.go            |  3 +++
 pkg/i18n/polish.go             |  3 +++
 scripts/generate_cheatsheet.go | 13 ++++++++++---
 7 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index c9beb36eb..5642e0901 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -350,9 +350,6 @@ func (gui *Gui) renderAppStatus(g *gocui.Gui) error {
 
 func (gui *Gui) renderGlobalOptions(g *gocui.Gui) error {
 	return gui.renderOptionsMap(g, map[string]string{
-		"R":         gui.Tr.SLocalize("refresh"),
-		"p":         gui.Tr.SLocalize("pull"),
-		"P":         gui.Tr.SLocalize("push"),
 		"PgUp/PgDn": gui.Tr.SLocalize("scroll"),
 		"← → ↑ ↓":   gui.Tr.SLocalize("navigate"),
 		"esc/q":     gui.Tr.SLocalize("close"),
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 0ca82d3c6..9202d7a1d 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -56,16 +56,19 @@ func (gui *Gui) GetKeybindings() []Binding {
 			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:      '?',
diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go
index fa276e8c4..1bd02eeb2 100644
--- a/pkg/gui/menu_panel.go
+++ b/pkg/gui/menu_panel.go
@@ -10,6 +10,9 @@ import (
 
 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 {
@@ -59,7 +62,7 @@ func (gui *Gui) GetKey(binding Binding) string {
 	return key
 }
 
-func (gui *Gui) getMaxKeyLength(bindings []Binding) int {
+func (gui *Gui) GetMaxKeyLength(bindings []Binding) int {
 	max := 0
 	for _, binding := range bindings {
 		keyLength := len(gui.GetKey(binding))
@@ -74,11 +77,17 @@ func (gui *Gui) handleMenu(g *gocui.Gui, v *gocui.View) error {
 	// clear keys slice, so we don't have ghost elements
 	gui.State.Keys = gui.State.Keys[:0]
 	content := ""
+	current := ""
 	bindings := gui.GetKeybindings()
-	padWidth := gui.getMaxKeyLength(bindings)
+	padWidth := gui.GetMaxKeyLength(bindings)
 
 	for _, binding := range bindings {
-		if key := gui.GetKey(binding); key != "" && binding.ViewName == v.Name() && binding.Description != "" {
+		if key := gui.GetKey(binding); key != "" && (binding.ViewName == v.Name() || binding.ViewName == "") && binding.Description != "" {
+			if binding.ViewName != current {
+				content += "\n"
+				gui.State.Keys = append(gui.State.Keys, Binding{})
+				current = binding.ViewName
+			}
 			content += fmt.Sprintf("%s  %s\n", utils.WithPadding(key, padWidth), binding.Description)
 			gui.State.Keys = append(gui.State.Keys, binding)
 		}
diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go
index cbdccbf2a..7a3ba16b0 100644
--- a/pkg/i18n/dutch.go
+++ b/pkg/i18n/dutch.go
@@ -40,6 +40,9 @@ func addDutch(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "StatusTitle",
 			Other: "Status",
+		}, &i18n.Message{
+			ID:    "GlobalTitle",
+			Other: "Global",
 		}, &i18n.Message{
 			ID:    "navigate",
 			Other: "navigeer",
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 471a75b6f..c92d5510a 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -48,6 +48,9 @@ func addEnglish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "StatusTitle",
 			Other: "Status",
+		}, &i18n.Message{
+			ID:    "GlobalTitle",
+			Other: "Global",
 		}, &i18n.Message{
 			ID:    "navigate",
 			Other: "navigate",
diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index f99890c15..cb190d246 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -38,6 +38,9 @@ func addPolish(i18nObject *i18n.Bundle) error {
 		}, &i18n.Message{
 			ID:    "StatusTitle",
 			Other: "Status",
+		}, &i18n.Message{
+			ID:    "GlobalTitle",
+			Other: "Globalne",
 		}, &i18n.Message{
 			ID:    "navigate",
 			Other: "nawiguj",
diff --git a/scripts/generate_cheatsheet.go b/scripts/generate_cheatsheet.go
index 2c18e5f03..95012e2a4 100644
--- a/scripts/generate_cheatsheet.go
+++ b/scripts/generate_cheatsheet.go
@@ -12,6 +12,7 @@ import (
 
 	"github.com/jesseduffield/lazygit/pkg/app"
 	"github.com/jesseduffield/lazygit/pkg/config"
+	"github.com/jesseduffield/lazygit/pkg/utils"
 )
 
 func main() {
@@ -20,9 +21,11 @@ func main() {
 	lang := a.Tr.GetLanguage()
 	name := "Keybindings_" + lang + ".md"
 	bindings := a.Gui.GetKeybindings()
+	padWidth := a.Gui.GetMaxKeyLength(bindings)
 	file, _ := os.Create(name)
-	current := ""
+	current := "v"
 	content := ""
+	title := ""
 
 	file.WriteString("# Lazygit " + a.Tr.SLocalize("menu"))
 
@@ -30,11 +33,15 @@ func main() {
 		if key := a.Gui.GetKey(binding); key != "" && binding.Description != "" {
 			if binding.ViewName != current {
 				current = binding.ViewName
-				title := a.Tr.SLocalize(strings.Title(current) + "Title")
+				if current == "" {
+					title = a.Tr.SLocalize("GlobalTitle")
+				} else {
+					title = a.Tr.SLocalize(strings.Title(current) + "Title")
+				}
 				content = fmt.Sprintf("
\n\n## %s\n
\n", title)
 				file.WriteString(content)
 			}
-			content = fmt.Sprintf("\t%s:\t%s\n", key, binding.Description)
+			content = fmt.Sprintf("\t%s%s  %s\n", key, strings.TrimPrefix(utils.WithPadding(key, padWidth), key), binding.Description)
 			file.WriteString(content)
 		}
 	}

From 34d1648bd315e6710e6466bb820dba4de425b629 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Wed, 5 Sep 2018 13:23:06 +0200
Subject: [PATCH 38/47] fmt strikes again

---
 pkg/gui/keybindings.go | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 9202d7a1d..9d8cfcdbb 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -52,22 +52,22 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Modifier: gocui.ModNone,
 			Handler:  gui.scrollDownMain,
 		}, {
-			ViewName: "",
-			Key:      'P',
-			Modifier: gocui.ModNone,
-			Handler:  gui.pushFiles,
+			ViewName:    "",
+			Key:         'P',
+			Modifier:    gocui.ModNone,
+			Handler:     gui.pushFiles,
 			Description: gui.Tr.SLocalize("push"),
 		}, {
-			ViewName: "",
-			Key:      'p',
-			Modifier: gocui.ModNone,
-			Handler:  gui.pullFiles,
+			ViewName:    "",
+			Key:         'p',
+			Modifier:    gocui.ModNone,
+			Handler:     gui.pullFiles,
 			Description: gui.Tr.SLocalize("pull"),
 		}, {
-			ViewName: "",
-			Key:      'R',
-			Modifier: gocui.ModNone,
-			Handler:  gui.handleRefresh,
+			ViewName:    "",
+			Key:         'R',
+			Modifier:    gocui.ModNone,
+			Handler:     gui.handleRefresh,
 			Description: gui.Tr.SLocalize("refresh"),
 		}, {
 			ViewName: "",

From 4188786749c512370d278849beef7998b72b171a Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Wed, 5 Sep 2018 15:20:34 +0200
Subject: [PATCH 39/47] update pl translation

---
 pkg/i18n/polish.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/i18n/polish.go b/pkg/i18n/polish.go
index cb190d246..0e3702f43 100644
--- a/pkg/i18n/polish.go
+++ b/pkg/i18n/polish.go
@@ -46,7 +46,7 @@ func addPolish(i18nObject *i18n.Bundle) error {
 			Other: "nawiguj",
 		}, &i18n.Message{
 			ID:    "menu",
-			Other: "pomoc",
+			Other: "menu",
 		}, &i18n.Message{
 			ID:    "execute",
 			Other: "wykonaj",

From 08395ae76ca811f1d60d1af42ee1f29eaa269de5 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Wed, 5 Sep 2018 15:45:20 +0200
Subject: [PATCH 40/47] workaround to include menu keybinding in cheatsheet

---
 scripts/generate_cheatsheet.go | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/scripts/generate_cheatsheet.go b/scripts/generate_cheatsheet.go
index 95012e2a4..863089014 100644
--- a/scripts/generate_cheatsheet.go
+++ b/scripts/generate_cheatsheet.go
@@ -30,7 +30,7 @@ func main() {
 	file.WriteString("# Lazygit " + a.Tr.SLocalize("menu"))
 
 	for _, binding := range bindings {
-		if key := a.Gui.GetKey(binding); key != "" && binding.Description != "" {
+		if key := a.Gui.GetKey(binding); key != "" && (binding.Description != "" || key == "?") {
 			if binding.ViewName != current {
 				current = binding.ViewName
 				if current == "" {
@@ -41,6 +41,12 @@ func main() {
 				content = fmt.Sprintf("
\n\n## %s\n
\n", title)
 				file.WriteString(content)
 			}
+			// workaround to include menu keybinding in cheatsheet
+			// could not add this Description field directly to keybindings.go,
+			// because then menu key would be displayed in menu itself and that is undesirable
+			if key == "?" {
+				binding.Description = a.Tr.SLocalize("menu")
+			}
 			content = fmt.Sprintf("\t%s%s  %s\n", key, strings.TrimPrefix(utils.WithPadding(key, padWidth), key), binding.Description)
 			file.WriteString(content)
 		}

From db2e2160a9578868d4c38d47ae61dc26c6965179 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Wed, 5 Sep 2018 15:55:24 +0200
Subject: [PATCH 41/47] change menu keybinding from ? to x

---
 pkg/gui/gui.go                 | 2 +-
 pkg/gui/keybindings.go         | 2 +-
 scripts/generate_cheatsheet.go | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 5642e0901..c27b77da3 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -353,7 +353,7 @@ func (gui *Gui) renderGlobalOptions(g *gocui.Gui) error {
 		"PgUp/PgDn": gui.Tr.SLocalize("scroll"),
 		"← → ↑ ↓":   gui.Tr.SLocalize("navigate"),
 		"esc/q":     gui.Tr.SLocalize("close"),
-		"?":         gui.Tr.SLocalize("menu"),
+		"x":         gui.Tr.SLocalize("menu"),
 	})
 }
 
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index 9d8cfcdbb..7f07893b7 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -71,7 +71,7 @@ func (gui *Gui) GetKeybindings() []Binding {
 			Description: gui.Tr.SLocalize("refresh"),
 		}, {
 			ViewName: "",
-			Key:      '?',
+			Key:      'x',
 			Modifier: gocui.ModNone,
 			Handler:  gui.handleMenu,
 		}, {
diff --git a/scripts/generate_cheatsheet.go b/scripts/generate_cheatsheet.go
index 863089014..cfa6d92ad 100644
--- a/scripts/generate_cheatsheet.go
+++ b/scripts/generate_cheatsheet.go
@@ -30,7 +30,7 @@ func main() {
 	file.WriteString("# Lazygit " + a.Tr.SLocalize("menu"))
 
 	for _, binding := range bindings {
-		if key := a.Gui.GetKey(binding); key != "" && (binding.Description != "" || key == "?") {
+		if key := a.Gui.GetKey(binding); key != "" && (binding.Description != "" || key == "x") {
 			if binding.ViewName != current {
 				current = binding.ViewName
 				if current == "" {
@@ -44,7 +44,7 @@ func main() {
 			// workaround to include menu keybinding in cheatsheet
 			// could not add this Description field directly to keybindings.go,
 			// because then menu key would be displayed in menu itself and that is undesirable
-			if key == "?" {
+			if key == "x" {
 				binding.Description = a.Tr.SLocalize("menu")
 			}
 			content = fmt.Sprintf("\t%s%s  %s\n", key, strings.TrimPrefix(utils.WithPadding(key, padWidth), key), binding.Description)

From ba6dedfb22d544ae6f972b1983fe3e2768fc0ee9 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Fri, 7 Sep 2018 14:19:16 +0200
Subject: [PATCH 42/47] rewrite some of menu panel logic

panel keybindings are now on top and
global keybindings are below separated with empty newline
---
 pkg/gui/menu_panel.go | 37 ++++++++++++++++++++++++++-----------
 1 file changed, 26 insertions(+), 11 deletions(-)

diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go
index 1bd02eeb2..5e642abe9 100644
--- a/pkg/gui/menu_panel.go
+++ b/pkg/gui/menu_panel.go
@@ -74,27 +74,42 @@ func (gui *Gui) GetMaxKeyLength(bindings []Binding) int {
 }
 
 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]
-	content := ""
-	current := ""
 	bindings := gui.GetKeybindings()
 	padWidth := gui.GetMaxKeyLength(bindings)
 
 	for _, binding := range bindings {
-		if key := gui.GetKey(binding); key != "" && (binding.ViewName == v.Name() || binding.ViewName == "") && binding.Description != "" {
-			if binding.ViewName != current {
-				content += "\n"
-				gui.State.Keys = append(gui.State.Keys, Binding{})
-				current = binding.ViewName
+		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)
 			}
-			content += fmt.Sprintf("%s  %s\n", utils.WithPadding(key, padWidth), binding.Description)
-			gui.State.Keys = append(gui.State.Keys, 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, content)
+	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
@@ -103,7 +118,7 @@ func (gui *Gui) handleMenu(g *gocui.Gui, v *gocui.View) error {
 		return err
 	}
 
-	fmt.Fprint(menuView, content)
+	fmt.Fprint(menuView, contentJoined)
 
 	g.Update(func(g *gocui.Gui) error {
 		_, err := g.SetViewOnTop("menu")

From 9cef98f779f5f000370a537825c561ebac9d7539 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Fri, 7 Sep 2018 14:23:08 +0200
Subject: [PATCH 43/47] ladies and gentlemen...

this is fmt number x+1
---
 pkg/gui/menu_panel.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go
index 5e642abe9..68041390d 100644
--- a/pkg/gui/menu_panel.go
+++ b/pkg/gui/menu_panel.go
@@ -75,7 +75,7 @@ func (gui *Gui) GetMaxKeyLength(bindings []Binding) int {
 
 func (gui *Gui) handleMenu(g *gocui.Gui, v *gocui.View) error {
 	var (
-		contentGlobal, contentPanel []string
+		contentGlobal, contentPanel   []string
 		bindingsGlobal, bindingsPanel []Binding
 	)
 	// clear keys slice, so we don't have ghost elements

From e80371fc6f1dbbf826fcf97626eaa4bc445736f9 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Fri, 7 Sep 2018 14:41:01 +0200
Subject: [PATCH 44/47] satisfy golangci

---
 pkg/gui/commits_panel.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go
index 06b8490a9..1c1662475 100644
--- a/pkg/gui/commits_panel.go
+++ b/pkg/gui/commits_panel.go
@@ -137,7 +137,7 @@ func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
 	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())
 		}

From a8866b158b00a2c49ca953f98cdb392896de1608 Mon Sep 17 00:00:00 2001
From: Glenn Vriesman 
Date: Sat, 8 Sep 2018 14:25:33 +0200
Subject: [PATCH 45/47] REPO: Added and modified some ignore statements

---
 .gitignore | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/.gitignore b/.gitignore
index f759e8a06..589b0bc4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,13 +3,8 @@
 # Logs
 *.log
 
-# Extras
-extra/lgit.rb
-
-# Notes
-notes/go.notes
-TODO.notes
-TODO.md
+# Hidden
+.*
 
 # Tests
 test/repos/repo
@@ -17,3 +12,9 @@ coverage.txt
 
 # Binaries
 lazygit
+
+# Exceptions
+!.gitignore
+!.goreleaser.yml
+!.circleci/
+!.github/
\ No newline at end of file

From 63e400647a1ad5a643e314b4d87047c2eeee8859 Mon Sep 17 00:00:00 2001
From: Dawid Dziurla 
Date: Sun, 9 Sep 2018 10:47:13 +0200
Subject: [PATCH 46/47] shorter english string

---
 pkg/i18n/english.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 677fa295b..4f009c075 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -368,7 +368,7 @@ func addEnglish(i18nObject *i18n.Bundle) error {
 			Other: `Gogit failed to parse your gitconfig file due to the presence of unquoted '\' characters. Removing these should fix the issue.`,
 		}, &i18n.Message{
 			ID:    "removeFile",
-			Other: `delete if untracked / checkout if tracked (aka go away)`,
+			Other: `delete if untracked / checkout if tracked`,
 		}, &i18n.Message{
 			ID:    "editFile",
 			Other: `edit file`,

From 700f8c7e796ccfca1bb31c830d960204b2daba26 Mon Sep 17 00:00:00 2001
From: Glenn Vriesman 
Date: Sun, 9 Sep 2018 13:37:38 +0200
Subject: [PATCH 47/47] REPO: Added TODO entries to the gitignore for jesse

---
 .gitignore | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/.gitignore b/.gitignore
index 589b0bc4a..e87f09a89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,12 @@
 # Hidden
 .*
 
+# TODO
+TODO.*
+
+# Notes
+*.notes
+
 # Tests
 test/repos/repo
 coverage.txt