1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-12 11:15:00 +02:00
lazygit/pkg/gui/list_context_config.go

448 lines
16 KiB
Go
Raw Normal View History

package gui
import (
2021-11-02 11:05:23 +02:00
"log"
"github.com/jesseduffield/gocui"
2022-01-19 09:32:27 +02:00
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/style"
)
func (gui *Gui) menuListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "menu",
Key: "menu",
Kind: PERSISTENT_POPUP,
OnGetOptionsMap: gui.getMenuOptions,
},
2021-10-17 10:01:02 +02:00
GetItemsLength: func() int { return gui.Views.Menu.LinesHeight() },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Menu },
2021-10-17 10:01:02 +02:00
OnClickSelectedItem: gui.onMenuPress,
Gui: gui,
// no GetDisplayStrings field because we do a custom render on menu creation
}
}
func (gui *Gui) filesListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "files",
WindowName: "files",
Key: FILES_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
2022-01-21 15:13:51 +02:00
GetItemsLength: func() int { return gui.State.FileTreeViewModel.GetItemsLength() },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Files },
OnFocus: OnFocusWrapper(gui.onFocusFile),
OnRenderToMain: OnFocusWrapper(gui.filesRenderToMain),
2021-10-17 10:01:02 +02:00
OnClickSelectedItem: gui.handleFilePress,
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
2022-01-21 15:13:51 +02:00
lines := presentation.RenderFileTree(gui.State.FileTreeViewModel, gui.State.Modes.Diffing.Ref, gui.State.Submodules)
mappedLines := make([][]string, len(lines))
for i, line := range lines {
mappedLines[i] = []string{line}
}
return mappedLines
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedFileNode()
return item, item != nil
},
}
}
func (gui *Gui) branchesListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "branches",
WindowName: "branches",
Key: LOCAL_BRANCHES_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
GetItemsLength: func() int { return len(gui.State.Branches) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Branches },
OnRenderToMain: OnFocusWrapper(gui.branchesRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Modes.Diffing.Ref)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedBranch()
return item, item != nil
},
}
}
func (gui *Gui) remotesListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "branches",
WindowName: "branches",
Key: REMOTES_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
2021-10-17 10:01:02 +02:00
GetItemsLength: func() int { return len(gui.State.Remotes) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Remotes },
OnRenderToMain: OnFocusWrapper(gui.remotesRenderToMain),
2021-10-17 10:01:02 +02:00
OnClickSelectedItem: gui.handleRemoteEnter,
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetRemoteListDisplayStrings(gui.State.Remotes, gui.State.Modes.Diffing.Ref)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedRemote()
return item, item != nil
},
}
}
func (gui *Gui) remoteBranchesListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "branches",
WindowName: "branches",
Key: REMOTE_BRANCHES_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
GetItemsLength: func() int { return len(gui.State.RemoteBranches) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.RemoteBranches },
OnRenderToMain: OnFocusWrapper(gui.remoteBranchesRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetRemoteBranchListDisplayStrings(gui.State.RemoteBranches, gui.State.Modes.Diffing.Ref)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedRemoteBranch()
return item, item != nil
},
}
}
func (gui *Gui) tagsListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "branches",
WindowName: "branches",
Key: TAGS_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
GetItemsLength: func() int { return len(gui.State.Tags) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Tags },
OnRenderToMain: OnFocusWrapper(gui.tagsRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetTagListDisplayStrings(gui.State.Tags, gui.State.Modes.Diffing.Ref)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedTag()
return item, item != nil
},
}
}
func (gui *Gui) branchCommitsListContext() IListContext {
2021-12-29 02:50:20 +02:00
parseEmoji := gui.UserConfig.Git.ParseEmoji
return &ListContext{
BasicContext: &BasicContext{
ViewName: "commits",
WindowName: "commits",
Key: BRANCH_COMMITS_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
2021-10-17 10:01:02 +02:00
GetItemsLength: func() int { return len(gui.State.Commits) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Commits },
OnFocus: OnFocusWrapper(gui.onCommitFocus),
OnRenderToMain: OnFocusWrapper(gui.branchCommitsRenderToMain),
2021-10-17 10:01:02 +02:00
OnClickSelectedItem: gui.handleViewCommitFiles,
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
2021-11-02 07:39:15 +02:00
selectedCommitSha := ""
if gui.currentContext().GetKey() == BRANCH_COMMITS_CONTEXT_KEY {
selectedCommit := gui.getSelectedLocalCommit()
if selectedCommit != nil {
selectedCommitSha = selectedCommit.Sha
}
}
2021-07-16 14:06:01 +02:00
return presentation.GetCommitListDisplayStrings(
gui.State.Commits,
gui.State.ScreenMode != SCREEN_NORMAL,
gui.cherryPickedCommitShaMap(),
gui.State.Modes.Diffing.Ref,
parseEmoji,
2021-11-02 07:39:15 +02:00
selectedCommitSha,
startIdx,
length,
2021-11-02 11:05:23 +02:00
gui.shouldShowGraph(),
2022-01-19 09:32:27 +02:00
gui.State.BisectInfo,
2021-07-16 14:06:01 +02:00
)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedLocalCommit()
return item, item != nil
},
2021-11-02 07:39:15 +02:00
RenderSelection: true,
}
}
2021-11-09 23:48:58 +02:00
func (gui *Gui) subCommitsListContext() IListContext {
2021-12-29 02:50:20 +02:00
parseEmoji := gui.UserConfig.Git.ParseEmoji
2021-11-09 23:48:58 +02:00
return &ListContext{
BasicContext: &BasicContext{
ViewName: "branches",
WindowName: "branches",
Key: SUB_COMMITS_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
GetItemsLength: func() int { return len(gui.State.SubCommits) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.SubCommits },
OnRenderToMain: OnFocusWrapper(gui.subCommitsRenderToMain),
2021-11-09 23:48:58 +02:00
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
selectedCommitSha := ""
if gui.currentContext().GetKey() == SUB_COMMITS_CONTEXT_KEY {
selectedCommit := gui.getSelectedSubCommit()
if selectedCommit != nil {
selectedCommitSha = selectedCommit.Sha
}
}
return presentation.GetCommitListDisplayStrings(
gui.State.SubCommits,
gui.State.ScreenMode != SCREEN_NORMAL,
gui.cherryPickedCommitShaMap(),
gui.State.Modes.Diffing.Ref,
parseEmoji,
selectedCommitSha,
startIdx,
length,
gui.shouldShowGraph(),
2022-01-19 09:32:27 +02:00
git_commands.NewNullBisectInfo(),
2021-11-09 23:48:58 +02:00
)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedSubCommit()
return item, item != nil
},
RenderSelection: true,
}
}
2021-11-02 11:05:23 +02:00
func (gui *Gui) shouldShowGraph() bool {
if gui.State.Modes.Filtering.Active() {
return false
}
2021-12-29 02:50:20 +02:00
value := gui.UserConfig.Git.Log.ShowGraph
2021-11-02 11:05:23 +02:00
switch value {
case "always":
return true
case "never":
return false
case "when-maximised":
return gui.State.ScreenMode != SCREEN_NORMAL
}
log.Fatalf("Unknown value for git.log.showGraph: %s. Expected one of: 'always', 'never', 'when-maximised'", value)
return false
}
func (gui *Gui) reflogCommitsListContext() IListContext {
2021-12-29 02:50:20 +02:00
parseEmoji := gui.UserConfig.Git.ParseEmoji
return &ListContext{
BasicContext: &BasicContext{
ViewName: "commits",
WindowName: "commits",
Key: REFLOG_COMMITS_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
GetItemsLength: func() int { return len(gui.State.FilteredReflogCommits) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.ReflogCommits },
OnRenderToMain: OnFocusWrapper(gui.reflogCommitsRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
2021-07-16 14:06:01 +02:00
return presentation.GetReflogCommitListDisplayStrings(
gui.State.FilteredReflogCommits,
gui.State.ScreenMode != SCREEN_NORMAL,
gui.cherryPickedCommitShaMap(),
gui.State.Modes.Diffing.Ref,
parseEmoji,
)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedReflogCommit()
return item, item != nil
},
}
}
func (gui *Gui) stashListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "stash",
WindowName: "stash",
Key: STASH_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
GetItemsLength: func() int { return len(gui.State.StashEntries) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Stash },
OnRenderToMain: OnFocusWrapper(gui.stashRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetStashEntryListDisplayStrings(gui.State.StashEntries, gui.State.Modes.Diffing.Ref)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedStashEntry()
return item, item != nil
},
}
}
func (gui *Gui) commitFilesListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "commitFiles",
WindowName: "commits",
Key: COMMIT_FILES_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
2022-01-21 15:13:51 +02:00
GetItemsLength: func() int { return gui.State.CommitFileTreeViewModel.GetItemsLength() },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.CommitFiles },
OnFocus: OnFocusWrapper(gui.onCommitFileFocus),
OnRenderToMain: OnFocusWrapper(gui.commitFilesRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
2022-01-21 15:13:51 +02:00
if gui.State.CommitFileTreeViewModel.GetItemsLength() == 0 {
return [][]string{{style.FgRed.Sprint("(none)")}}
}
2022-01-21 15:13:51 +02:00
lines := presentation.RenderCommitFileTree(gui.State.CommitFileTreeViewModel, gui.State.Modes.Diffing.Ref, gui.Git.Patch.PatchManager)
mappedLines := make([][]string, len(lines))
for i, line := range lines {
mappedLines[i] = []string{line}
}
return mappedLines
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedCommitFileNode()
return item, item != nil
},
}
}
func (gui *Gui) submodulesListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "files",
WindowName: "files",
Key: SUBMODULES_CONTEXT_KEY,
Kind: SIDE_CONTEXT,
},
GetItemsLength: func() int { return len(gui.State.Submodules) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Submodules },
OnRenderToMain: OnFocusWrapper(gui.submodulesRenderToMain),
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetSubmoduleListDisplayStrings(gui.State.Submodules)
},
SelectedItem: func() (ListItem, bool) {
item := gui.getSelectedSubmodule()
return item, item != nil
},
}
}
func (gui *Gui) suggestionsListContext() IListContext {
return &ListContext{
BasicContext: &BasicContext{
ViewName: "suggestions",
WindowName: "suggestions",
Key: SUGGESTIONS_CONTEXT_KEY,
Kind: PERSISTENT_POPUP,
},
GetItemsLength: func() int { return len(gui.State.Suggestions) },
OnGetPanelState: func() IListPanelState { return gui.State.Panels.Suggestions },
Gui: gui,
GetDisplayStrings: func(startIdx int, length int) [][]string {
return presentation.GetSuggestionListDisplayStrings(gui.State.Suggestions)
},
}
}
func (gui *Gui) getListContexts() []IListContext {
return []IListContext{
gui.State.Contexts.Menu,
gui.State.Contexts.Files,
gui.State.Contexts.Branches,
gui.State.Contexts.Remotes,
gui.State.Contexts.RemoteBranches,
gui.State.Contexts.Tags,
gui.State.Contexts.BranchCommits,
gui.State.Contexts.ReflogCommits,
gui.State.Contexts.SubCommits,
gui.State.Contexts.Stash,
gui.State.Contexts.CommitFiles,
gui.State.Contexts.Submodules,
gui.State.Contexts.Suggestions,
}
}
func (gui *Gui) getListContextKeyBindings() []*Binding {
bindings := make([]*Binding, 0)
2021-12-29 02:50:20 +02:00
keybindingConfig := gui.UserConfig.Keybinding
for _, listContext := range gui.getListContexts() {
listContext := listContext
bindings = append(bindings, []*Binding{
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.PrevItemAlt), Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.PrevItem), Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gocui.MouseWheelUp, Modifier: gocui.ModNone, Handler: listContext.handlePrevLine},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.NextItemAlt), Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.NextItem), Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.PrevPage), Modifier: gocui.ModNone, Handler: listContext.handlePrevPage, Description: gui.Tr.LcPrevPage},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.NextPage), Modifier: gocui.ModNone, Handler: listContext.handleNextPage, Description: gui.Tr.LcNextPage},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.GotoTop), Modifier: gocui.ModNone, Handler: listContext.handleGotoTop, Description: gui.Tr.LcGotoTop},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gocui.MouseWheelDown, Modifier: gocui.ModNone, Handler: listContext.handleNextLine},
{ViewName: listContext.GetViewName(), Contexts: []string{string(listContext.GetKey())}, Key: gocui.MouseLeft, Modifier: gocui.ModNone, Handler: listContext.handleClick},
2021-11-02 11:35:53 +02:00
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.ScrollLeft), Modifier: gocui.ModNone, Handler: listContext.handleScrollLeft},
{ViewName: listContext.GetViewName(), Tag: "navigation", Contexts: []string{string(listContext.GetKey())}, Key: gui.getKey(keybindingConfig.Universal.ScrollRight), Modifier: gocui.ModNone, Handler: listContext.handleScrollRight},
}...)
openSearchHandler := gui.handleOpenSearch
gotoBottomHandler := listContext.handleGotoBottom
// the branch commits context needs to lazyload things so it has a couple of its own handlers
if listContext.GetKey() == BRANCH_COMMITS_CONTEXT_KEY {
openSearchHandler = gui.handleOpenSearchForCommitsPanel
gotoBottomHandler = gui.handleGotoBottomForCommitsPanel
}
bindings = append(bindings, []*Binding{
{
ViewName: listContext.GetViewName(),
Contexts: []string{string(listContext.GetKey())},
Key: gui.getKey(keybindingConfig.Universal.StartSearch),
Handler: func() error { return openSearchHandler(listContext.GetViewName()) },
Description: gui.Tr.LcStartSearch,
Tag: "navigation",
},
{
ViewName: listContext.GetViewName(),
Contexts: []string{string(listContext.GetKey())},
Key: gui.getKey(keybindingConfig.Universal.GotoBottom),
Handler: gotoBottomHandler,
Description: gui.Tr.LcGotoBottom,
Tag: "navigation",
},
}...)
}
return bindings
}