From ccd80a0e4b87af6d9ada5895c2135736665a9387 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Tue, 2 Nov 2021 21:16:00 +1100 Subject: [PATCH] add menu options for log stuff --- docs/Config.md | 3 +- pkg/commands/loading_commits.go | 16 ++++++- pkg/config/user_config.go | 4 +- pkg/gui/commits_panel.go | 85 +++++++++++++++++++++++++++++++++ pkg/gui/gui.go | 2 + pkg/gui/keybindings.go | 8 ++++ pkg/gui/menu_panel.go | 13 ++++- pkg/gui/options_menu_panel.go | 6 ++- pkg/i18n/english.go | 12 +++++ 9 files changed, 143 insertions(+), 6 deletions(-) diff --git a/docs/Config.md b/docs/Config.md index a43bd273f..5630516ac 100644 --- a/docs/Config.md +++ b/docs/Config.md @@ -62,7 +62,7 @@ git: # extra args passed to `git merge`, e.g. --no-ff args: '' log: - # one of date-order, reverse, author-date-order, topo-order. + # one of date-order, author-date-order, topo-order. # topo-order makes it easier to read the git log graph, but commits may not # appear chronologically. See https://git-scm.com/docs/git-log#_commit_ordering order: 'topo-order' @@ -201,6 +201,7 @@ keybinding: checkoutCommit: '' resetCherryPick: '' copyCommitMessageToClipboard: '' + openLogMenu: '' stash: popStash: 'g' commitFiles: diff --git a/pkg/commands/loading_commits.go b/pkg/commands/loading_commits.go index a9553c7c0..204e4c9da 100644 --- a/pkg/commands/loading_commits.go +++ b/pkg/commands/loading_commits.go @@ -37,7 +37,12 @@ type CommitListBuilder struct { } // NewCommitListBuilder builds a new commit list builder -func NewCommitListBuilder(log *logrus.Entry, gitCommand *GitCommand, osCommand *oscommands.OSCommand, tr *i18n.TranslationSet) *CommitListBuilder { +func NewCommitListBuilder( + log *logrus.Entry, + gitCommand *GitCommand, + osCommand *oscommands.OSCommand, + tr *i18n.TranslationSet, +) *CommitListBuilder { return &CommitListBuilder{ Log: log, GitCommand: gitCommand, @@ -88,6 +93,8 @@ type GetCommitsOptions struct { FilterPath string IncludeRebaseCommits bool RefName string // e.g. "HEAD" or "my_branch" + // determines if we show the whole git graph i.e. pass the '--all' flag + All bool } func (c *CommitListBuilder) MergeRebasingCommits(commits []*models.Commit) ([]*models.Commit, error) { @@ -407,12 +414,17 @@ func (c *CommitListBuilder) getLogCmd(opts GetCommitsOptions) *exec.Cmd { config := c.GitCommand.Config.GetUserConfig().Git.Log orderFlag := "--" + config.Order + allFlag := "" + if opts.All { + allFlag = " --all" + } return c.OSCommand.ExecutableFromString( fmt.Sprintf( - "git log %s %s --oneline %s %s --abbrev=%d %s", + "git log %s %s %s --oneline %s %s --abbrev=%d %s", c.OSCommand.Quote(opts.RefName), orderFlag, + allFlag, prettyFormat, limitFlag, 20, diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 2d391b5fb..f9a2e8656 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -86,7 +86,7 @@ type MergingConfig struct { } type LogConfig struct { - Order string `yaml:"order"` // one of date-order, reverse, author-date-order, topo-order + Order string `yaml:"order"` // one of date-order, author-date-order, topo-order ShowGraph string `yaml:"showGraph"` // one of always, never, when-maximised } @@ -237,6 +237,7 @@ type KeybindingCommitsConfig struct { CheckoutCommit string `yaml:"checkoutCommit"` ResetCherryPick string `yaml:"resetCherryPick"` CopyCommitMessageToClipboard string `yaml:"copyCommitMessageToClipboard"` + OpenLogMenu string `yaml:"openLogMenu"` } type KeybindingStashConfig struct { @@ -492,6 +493,7 @@ func GetDefaultConfig() *UserConfig { CheckoutCommit: "", ResetCherryPick: "", CopyCommitMessageToClipboard: "", + OpenLogMenu: "", }, Stash: KeybindingStashConfig{ PopStash: "g", diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 7185f1695..77558ab8e 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -125,6 +125,7 @@ func (gui *Gui) refreshCommitsWithLimit() error { FilterPath: gui.State.Modes.Filtering.GetPath(), IncludeRebaseCommits: true, RefName: "HEAD", + All: gui.State.ShowWholeGitGraph, }, ) if err != nil { @@ -670,3 +671,87 @@ func (gui *Gui) handleCopySelectedCommitMessageToClipboard() error { return nil } + +func (gui *Gui) handleOpenLogMenu() error { + return gui.createMenu(gui.Tr.LogMenuTitle, []*menuItem{ + { + displayString: gui.Tr.ToggleShowGitGraphAll, + onPress: func() error { + gui.State.ShowWholeGitGraph = !gui.State.ShowWholeGitGraph + + if gui.State.ShowWholeGitGraph { + gui.State.Panels.Commits.LimitCommits = false + } + + return gui.WithWaitingStatus(gui.Tr.LcLoadingCommits, func() error { + return gui.refreshSidePanels(refreshOptions{mode: SYNC, scope: []RefreshableView{COMMITS}}) + }) + }, + }, + { + displayString: gui.Tr.ShowGitGraph, + opensMenu: true, + onPress: func() error { + onSelect := func(value string) { + gui.Config.GetUserConfig().Git.Log.ShowGraph = value + gui.render() + } + return gui.createMenu(gui.Tr.LogMenuTitle, []*menuItem{ + { + displayString: "always", + onPress: func() error { + onSelect("always") + return nil + }, + }, + { + displayString: "never", + onPress: func() error { + onSelect("never") + return nil + }, + }, + { + displayString: "when maximised", + onPress: func() error { + onSelect("when-maximised") + return nil + }, + }, + }, createMenuOptions{showCancel: true}) + }, + }, + { + displayString: gui.Tr.SortCommits, + opensMenu: true, + onPress: func() error { + onSelect := func(value string) error { + gui.Config.GetUserConfig().Git.Log.Order = value + return gui.WithWaitingStatus(gui.Tr.LcLoadingCommits, func() error { + return gui.refreshSidePanels(refreshOptions{mode: SYNC, scope: []RefreshableView{COMMITS}}) + }) + } + return gui.createMenu(gui.Tr.LogMenuTitle, []*menuItem{ + { + displayString: "topological (topo-order)", + onPress: func() error { + return onSelect("topo-order") + }, + }, + { + displayString: "date-order", + onPress: func() error { + return onSelect("date-order") + }, + }, + { + displayString: "author-date-order", + onPress: func() error { + return onSelect("author-date-order") + }, + }, + }, createMenuOptions{showCancel: true}) + }, + }, + }, createMenuOptions{showCancel: true}) +} diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 496ded841..4371b9391 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -314,6 +314,8 @@ type guiState struct { RetainOriginalDir bool IsRefreshingFiles bool Searching searchingState + // if this is true, we'll load our commits using `git log --all` + ShowWholeGitGraph bool ScreenMode WindowMaximisation Ptmx *os.File PrevMainWidth int diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go index 8dbcfee7e..232708b9b 100644 --- a/pkg/gui/keybindings.go +++ b/pkg/gui/keybindings.go @@ -724,6 +724,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding { Handler: gui.handleFetchRemote, Description: gui.Tr.LcFetchRemote, }, + { + ViewName: "commits", + Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, + Key: gui.getKey(config.Commits.OpenLogMenu), + Handler: gui.handleOpenLogMenu, + Description: gui.Tr.LcOpenLogMenu, + OpensMenu: true, + }, { ViewName: "commits", Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)}, diff --git a/pkg/gui/menu_panel.go b/pkg/gui/menu_panel.go index f89095f01..23c6d91cb 100644 --- a/pkg/gui/menu_panel.go +++ b/pkg/gui/menu_panel.go @@ -1,6 +1,7 @@ package gui import ( + "errors" "fmt" "strings" @@ -13,6 +14,8 @@ type menuItem struct { displayString string displayStrings []string onPress func() error + // only applies when displayString is used + opensMenu bool } // every item in a list context needs an ID @@ -65,8 +68,16 @@ func (gui *Gui) createMenu(title string, items []*menuItem, createMenuOptions cr stringArrays := make([][]string, len(items)) for i, item := range items { + if item.opensMenu && item.displayStrings != nil { + return errors.New("Message for the developer of this app: you've set opensMenu with displaystrings on the menu panel. Bad developer!. Apologies, user") + } + if item.displayStrings == nil { - stringArrays[i] = []string{item.displayString} + styledStr := item.displayString + if item.opensMenu { + styledStr = opensMenuStyle(styledStr) + } + stringArrays[i] = []string{styledStr} } else { stringArrays[i] = item.displayStrings } diff --git a/pkg/gui/options_menu_panel.go b/pkg/gui/options_menu_panel.go index 172dd83c3..12507597f 100644 --- a/pkg/gui/options_menu_panel.go +++ b/pkg/gui/options_menu_panel.go @@ -36,12 +36,16 @@ func (gui *Gui) getBindings(v *gocui.View) []*Binding { func (gui *Gui) displayDescription(binding *Binding) string { if binding.OpensMenu { - return style.FgMagenta.Sprintf("%s...", binding.Description) + return opensMenuStyle(binding.Description) } return style.FgCyan.Sprint(binding.Description) } +func opensMenuStyle(str string) string { + return style.FgMagenta.Sprintf("%s...", str) +} + func (gui *Gui) handleCreateOptionsMenu() error { view := gui.g.CurrentView() if view == nil { diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index b7c38d7ac..da218ac74 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -436,11 +436,17 @@ type TranslationSet struct { SelectConfigFile string NoConfigFileFoundErr string LcLoadingFileSuggestions string + LcLoadingCommits string MustSpecifyOriginError string GitOutput string GitCommandFailed string AbortTitle string AbortPrompt string + LcOpenLogMenu string + LogMenuTitle string + ToggleShowGitGraphAll string + ShowGitGraph string + SortCommits string Spans Spans } @@ -970,11 +976,17 @@ func englishTranslationSet() TranslationSet { SelectConfigFile: "Select config file", NoConfigFileFoundErr: "No config file found", LcLoadingFileSuggestions: "loading file suggestions", + LcLoadingCommits: "loading commits", MustSpecifyOriginError: "Must specify a remote if specifying a branch", GitOutput: "Git output:", GitCommandFailed: "Git command failed. Check command log for details (open with %s)", AbortTitle: "Abort %s", AbortPrompt: "Are you sure you want to abort the current %s?", + LcOpenLogMenu: "open log menu", + LogMenuTitle: "Commit Log Options", + ToggleShowGitGraphAll: "toggle show whole git graph (pass the `--all` flag to `git log`)", + ShowGitGraph: "show git graph", + SortCommits: "commit sort order", Spans: Spans{ // TODO: combine this with the original keybinding descriptions (those are all in lowercase atm) CheckoutCommit: "Checkout commit",