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?",