mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-04-27 12:32:37 +02:00
add menu options for log stuff
This commit is contained in:
parent
37be9dbea1
commit
ccd80a0e4b
@ -62,7 +62,7 @@ git:
|
|||||||
# extra args passed to `git merge`, e.g. --no-ff
|
# extra args passed to `git merge`, e.g. --no-ff
|
||||||
args: ''
|
args: ''
|
||||||
log:
|
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
|
# 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
|
# appear chronologically. See https://git-scm.com/docs/git-log#_commit_ordering
|
||||||
order: 'topo-order'
|
order: 'topo-order'
|
||||||
@ -201,6 +201,7 @@ keybinding:
|
|||||||
checkoutCommit: '<space>'
|
checkoutCommit: '<space>'
|
||||||
resetCherryPick: '<c-R>'
|
resetCherryPick: '<c-R>'
|
||||||
copyCommitMessageToClipboard: '<c-y>'
|
copyCommitMessageToClipboard: '<c-y>'
|
||||||
|
openLogMenu: '<c-l>'
|
||||||
stash:
|
stash:
|
||||||
popStash: 'g'
|
popStash: 'g'
|
||||||
commitFiles:
|
commitFiles:
|
||||||
|
@ -37,7 +37,12 @@ type CommitListBuilder struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewCommitListBuilder builds a new commit list builder
|
// 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{
|
return &CommitListBuilder{
|
||||||
Log: log,
|
Log: log,
|
||||||
GitCommand: gitCommand,
|
GitCommand: gitCommand,
|
||||||
@ -88,6 +93,8 @@ type GetCommitsOptions struct {
|
|||||||
FilterPath string
|
FilterPath string
|
||||||
IncludeRebaseCommits bool
|
IncludeRebaseCommits bool
|
||||||
RefName string // e.g. "HEAD" or "my_branch"
|
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) {
|
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
|
config := c.GitCommand.Config.GetUserConfig().Git.Log
|
||||||
|
|
||||||
orderFlag := "--" + config.Order
|
orderFlag := "--" + config.Order
|
||||||
|
allFlag := ""
|
||||||
|
if opts.All {
|
||||||
|
allFlag = " --all"
|
||||||
|
}
|
||||||
|
|
||||||
return c.OSCommand.ExecutableFromString(
|
return c.OSCommand.ExecutableFromString(
|
||||||
fmt.Sprintf(
|
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),
|
c.OSCommand.Quote(opts.RefName),
|
||||||
orderFlag,
|
orderFlag,
|
||||||
|
allFlag,
|
||||||
prettyFormat,
|
prettyFormat,
|
||||||
limitFlag,
|
limitFlag,
|
||||||
20,
|
20,
|
||||||
|
@ -86,7 +86,7 @@ type MergingConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type LogConfig 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
|
ShowGraph string `yaml:"showGraph"` // one of always, never, when-maximised
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,6 +237,7 @@ type KeybindingCommitsConfig struct {
|
|||||||
CheckoutCommit string `yaml:"checkoutCommit"`
|
CheckoutCommit string `yaml:"checkoutCommit"`
|
||||||
ResetCherryPick string `yaml:"resetCherryPick"`
|
ResetCherryPick string `yaml:"resetCherryPick"`
|
||||||
CopyCommitMessageToClipboard string `yaml:"copyCommitMessageToClipboard"`
|
CopyCommitMessageToClipboard string `yaml:"copyCommitMessageToClipboard"`
|
||||||
|
OpenLogMenu string `yaml:"openLogMenu"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeybindingStashConfig struct {
|
type KeybindingStashConfig struct {
|
||||||
@ -492,6 +493,7 @@ func GetDefaultConfig() *UserConfig {
|
|||||||
CheckoutCommit: "<space>",
|
CheckoutCommit: "<space>",
|
||||||
ResetCherryPick: "<c-R>",
|
ResetCherryPick: "<c-R>",
|
||||||
CopyCommitMessageToClipboard: "<c-y>",
|
CopyCommitMessageToClipboard: "<c-y>",
|
||||||
|
OpenLogMenu: "<c-l>",
|
||||||
},
|
},
|
||||||
Stash: KeybindingStashConfig{
|
Stash: KeybindingStashConfig{
|
||||||
PopStash: "g",
|
PopStash: "g",
|
||||||
|
@ -125,6 +125,7 @@ func (gui *Gui) refreshCommitsWithLimit() error {
|
|||||||
FilterPath: gui.State.Modes.Filtering.GetPath(),
|
FilterPath: gui.State.Modes.Filtering.GetPath(),
|
||||||
IncludeRebaseCommits: true,
|
IncludeRebaseCommits: true,
|
||||||
RefName: "HEAD",
|
RefName: "HEAD",
|
||||||
|
All: gui.State.ShowWholeGitGraph,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -670,3 +671,87 @@ func (gui *Gui) handleCopySelectedCommitMessageToClipboard() error {
|
|||||||
|
|
||||||
return nil
|
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})
|
||||||
|
}
|
||||||
|
@ -314,6 +314,8 @@ type guiState struct {
|
|||||||
RetainOriginalDir bool
|
RetainOriginalDir bool
|
||||||
IsRefreshingFiles bool
|
IsRefreshingFiles bool
|
||||||
Searching searchingState
|
Searching searchingState
|
||||||
|
// if this is true, we'll load our commits using `git log --all`
|
||||||
|
ShowWholeGitGraph bool
|
||||||
ScreenMode WindowMaximisation
|
ScreenMode WindowMaximisation
|
||||||
Ptmx *os.File
|
Ptmx *os.File
|
||||||
PrevMainWidth int
|
PrevMainWidth int
|
||||||
|
@ -724,6 +724,14 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
|
|||||||
Handler: gui.handleFetchRemote,
|
Handler: gui.handleFetchRemote,
|
||||||
Description: gui.Tr.LcFetchRemote,
|
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",
|
ViewName: "commits",
|
||||||
Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)},
|
Contexts: []string{string(BRANCH_COMMITS_CONTEXT_KEY)},
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -13,6 +14,8 @@ type menuItem struct {
|
|||||||
displayString string
|
displayString string
|
||||||
displayStrings []string
|
displayStrings []string
|
||||||
onPress func() error
|
onPress func() error
|
||||||
|
// only applies when displayString is used
|
||||||
|
opensMenu bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// every item in a list context needs an ID
|
// 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))
|
stringArrays := make([][]string, len(items))
|
||||||
for i, item := range 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 {
|
if item.displayStrings == nil {
|
||||||
stringArrays[i] = []string{item.displayString}
|
styledStr := item.displayString
|
||||||
|
if item.opensMenu {
|
||||||
|
styledStr = opensMenuStyle(styledStr)
|
||||||
|
}
|
||||||
|
stringArrays[i] = []string{styledStr}
|
||||||
} else {
|
} else {
|
||||||
stringArrays[i] = item.displayStrings
|
stringArrays[i] = item.displayStrings
|
||||||
}
|
}
|
||||||
|
@ -36,12 +36,16 @@ func (gui *Gui) getBindings(v *gocui.View) []*Binding {
|
|||||||
|
|
||||||
func (gui *Gui) displayDescription(binding *Binding) string {
|
func (gui *Gui) displayDescription(binding *Binding) string {
|
||||||
if binding.OpensMenu {
|
if binding.OpensMenu {
|
||||||
return style.FgMagenta.Sprintf("%s...", binding.Description)
|
return opensMenuStyle(binding.Description)
|
||||||
}
|
}
|
||||||
|
|
||||||
return style.FgCyan.Sprint(binding.Description)
|
return style.FgCyan.Sprint(binding.Description)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func opensMenuStyle(str string) string {
|
||||||
|
return style.FgMagenta.Sprintf("%s...", str)
|
||||||
|
}
|
||||||
|
|
||||||
func (gui *Gui) handleCreateOptionsMenu() error {
|
func (gui *Gui) handleCreateOptionsMenu() error {
|
||||||
view := gui.g.CurrentView()
|
view := gui.g.CurrentView()
|
||||||
if view == nil {
|
if view == nil {
|
||||||
|
@ -436,11 +436,17 @@ type TranslationSet struct {
|
|||||||
SelectConfigFile string
|
SelectConfigFile string
|
||||||
NoConfigFileFoundErr string
|
NoConfigFileFoundErr string
|
||||||
LcLoadingFileSuggestions string
|
LcLoadingFileSuggestions string
|
||||||
|
LcLoadingCommits string
|
||||||
MustSpecifyOriginError string
|
MustSpecifyOriginError string
|
||||||
GitOutput string
|
GitOutput string
|
||||||
GitCommandFailed string
|
GitCommandFailed string
|
||||||
AbortTitle string
|
AbortTitle string
|
||||||
AbortPrompt string
|
AbortPrompt string
|
||||||
|
LcOpenLogMenu string
|
||||||
|
LogMenuTitle string
|
||||||
|
ToggleShowGitGraphAll string
|
||||||
|
ShowGitGraph string
|
||||||
|
SortCommits string
|
||||||
Spans Spans
|
Spans Spans
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -970,11 +976,17 @@ func englishTranslationSet() TranslationSet {
|
|||||||
SelectConfigFile: "Select config file",
|
SelectConfigFile: "Select config file",
|
||||||
NoConfigFileFoundErr: "No config file found",
|
NoConfigFileFoundErr: "No config file found",
|
||||||
LcLoadingFileSuggestions: "loading file suggestions",
|
LcLoadingFileSuggestions: "loading file suggestions",
|
||||||
|
LcLoadingCommits: "loading commits",
|
||||||
MustSpecifyOriginError: "Must specify a remote if specifying a branch",
|
MustSpecifyOriginError: "Must specify a remote if specifying a branch",
|
||||||
GitOutput: "Git output:",
|
GitOutput: "Git output:",
|
||||||
GitCommandFailed: "Git command failed. Check command log for details (open with %s)",
|
GitCommandFailed: "Git command failed. Check command log for details (open with %s)",
|
||||||
AbortTitle: "Abort %s",
|
AbortTitle: "Abort %s",
|
||||||
AbortPrompt: "Are you sure you want to abort the current %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{
|
Spans: Spans{
|
||||||
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
|
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
|
||||||
CheckoutCommit: "Checkout commit",
|
CheckoutCommit: "Checkout commit",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user