1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-06-15 00:15:32 +02:00

centralise some list view code

This commit is contained in:
Jesse Duffield
2020-08-16 09:18:57 +10:00
parent b211a14a66
commit cec4cb48cb
8 changed files with 190 additions and 182 deletions

View File

@ -28,10 +28,6 @@ func (gui *Gui) handleBranchSelect() error {
gui.State.SplitMainPanel = false gui.State.SplitMainPanel = false
if _, err := gui.g.SetCurrentView("branches"); err != nil {
return err
}
gui.getMainView().Title = "Log" gui.getMainView().Title = "Log"
// This really shouldn't happen: there should always be a master branch // This really shouldn't happen: there should always be a master branch
@ -39,7 +35,6 @@ func (gui *Gui) handleBranchSelect() error {
return gui.newStringTask("main", gui.Tr.SLocalize("NoBranchesThisRepo")) return gui.newStringTask("main", gui.Tr.SLocalize("NoBranchesThisRepo"))
} }
branch := gui.getSelectedBranch() branch := gui.getSelectedBranch()
gui.getBranchesView().FocusPoint(0, gui.State.Panels.Branches.SelectedLine)
if gui.inDiffMode() { if gui.inDiffMode() {
return gui.renderDiff() return gui.renderDiff()
@ -510,22 +505,6 @@ func (gui *Gui) handleCreateResetToBranchMenu(g *gocui.Gui, v *gocui.View) error
return gui.createResetMenu(branch.Name) return gui.createResetMenu(branch.Name)
} }
func (gui *Gui) onBranchesPanelSearchSelect(selectedLine int) error {
branchesView := gui.getBranchesView()
switch branchesView.Context {
case "local-branches":
gui.State.Panels.Branches.SelectedLine = selectedLine
return gui.handleBranchSelect()
case "remotes":
gui.State.Panels.Remotes.SelectedLine = selectedLine
return gui.handleRemoteSelect()
case "remote-branches":
gui.State.Panels.RemoteBranches.SelectedLine = selectedLine
return gui.handleRemoteBranchSelect()
}
return nil
}
func (gui *Gui) handleRenameBranch(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleRenameBranch(g *gocui.Gui, v *gocui.View) error {
branch := gui.getSelectedBranch() branch := gui.getSelectedBranch()
if branch == nil { if branch == nil {

View File

@ -248,8 +248,3 @@ func (gui *Gui) enterCommitFile(selectedLineIdx int) error {
return enterTheFile(selectedLineIdx) return enterTheFile(selectedLineIdx)
} }
func (gui *Gui) onCommitFilesPanelSearchSelect(selectedLine int) error {
gui.State.Panels.CommitFiles.SelectedLine = selectedLine
return gui.handleCommitFileSelect()
}

View File

@ -715,19 +715,6 @@ func (gui *Gui) handleCreateCommitResetMenu(g *gocui.Gui, v *gocui.View) error {
return gui.createResetMenu(commit.Sha) return gui.createResetMenu(commit.Sha)
} }
func (gui *Gui) onCommitsPanelSearchSelect(selectedLine int) error {
commitsView := gui.getCommitsView()
switch commitsView.Context {
case "branch-commits":
gui.State.Panels.Commits.SelectedLine = selectedLine
return gui.handleCommitSelect()
case "reflog-commits":
gui.State.Panels.ReflogCommits.SelectedLine = selectedLine
return gui.handleReflogCommitSelect()
}
return nil
}
func (gui *Gui) handleOpenSearchForCommitsPanel(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleOpenSearchForCommitsPanel(g *gocui.Gui, v *gocui.View) error {
// we usually lazyload these commits but now that we're searching we need to load them now // we usually lazyload these commits but now that we're searching we need to load them now
if gui.State.Panels.Commits.LimitCommits { if gui.State.Panels.Commits.LimitCommits {

View File

@ -652,8 +652,3 @@ func (gui *Gui) handleStashChanges(g *gocui.Gui, v *gocui.View) error {
func (gui *Gui) handleCreateResetToUpstreamMenu(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCreateResetToUpstreamMenu(g *gocui.Gui, v *gocui.View) error {
return gui.createResetMenu("@{upstream}") return gui.createResetMenu("@{upstream}")
} }
func (gui *Gui) onFilesPanelSearchSelect(selectedLine int) error {
gui.State.Panels.Files.SelectedLine = selectedLine
return gui.focusAndSelectFile()
}

View File

@ -190,7 +190,6 @@ func (gui *Gui) layout(g *gocui.Gui) error {
} }
filesView.Highlight = true filesView.Highlight = true
filesView.Title = gui.Tr.SLocalize("FilesTitle") filesView.Title = gui.Tr.SLocalize("FilesTitle")
filesView.SetOnSelectItem(gui.onSelectItemWrapper(gui.onFilesPanelSearchSelect))
filesView.ContainsList = true filesView.ContainsList = true
} }
@ -202,7 +201,6 @@ func (gui *Gui) layout(g *gocui.Gui) error {
branchesView.Title = gui.Tr.SLocalize("BranchesTitle") branchesView.Title = gui.Tr.SLocalize("BranchesTitle")
branchesView.Tabs = []string{"Local Branches", "Remotes", "Tags"} branchesView.Tabs = []string{"Local Branches", "Remotes", "Tags"}
branchesView.FgColor = textColor branchesView.FgColor = textColor
branchesView.SetOnSelectItem(gui.onSelectItemWrapper(gui.onBranchesPanelSearchSelect))
branchesView.ContainsList = true branchesView.ContainsList = true
} }
@ -213,7 +211,6 @@ func (gui *Gui) layout(g *gocui.Gui) error {
} }
commitFilesView.Title = gui.Tr.SLocalize("CommitFiles") commitFilesView.Title = gui.Tr.SLocalize("CommitFiles")
commitFilesView.FgColor = textColor commitFilesView.FgColor = textColor
commitFilesView.SetOnSelectItem(gui.onSelectItemWrapper(gui.onCommitFilesPanelSearchSelect))
commitFilesView.ContainsList = true commitFilesView.ContainsList = true
} }
@ -225,7 +222,6 @@ func (gui *Gui) layout(g *gocui.Gui) error {
commitsView.Title = gui.Tr.SLocalize("CommitsTitle") commitsView.Title = gui.Tr.SLocalize("CommitsTitle")
commitsView.Tabs = []string{"Commits", "Reflog"} commitsView.Tabs = []string{"Commits", "Reflog"}
commitsView.FgColor = textColor commitsView.FgColor = textColor
commitsView.SetOnSelectItem(gui.onSelectItemWrapper(gui.onCommitsPanelSearchSelect))
commitsView.ContainsList = true commitsView.ContainsList = true
} }
@ -236,7 +232,6 @@ func (gui *Gui) layout(g *gocui.Gui) error {
} }
stashView.Title = gui.Tr.SLocalize("StashTitle") stashView.Title = gui.Tr.SLocalize("StashTitle")
stashView.FgColor = textColor stashView.FgColor = textColor
stashView.SetOnSelectItem(gui.onSelectItemWrapper(gui.onStashPanelSearchSelect))
stashView.ContainsList = true stashView.ContainsList = true
} }
@ -352,32 +347,37 @@ func (gui *Gui) layout(g *gocui.Gui) error {
lineCount int lineCount int
view *gocui.View view *gocui.View
context string context string
listView *listView
} }
listViews := []listViewState{ listViewStates := []listViewState{
{view: filesView, context: "", selectedLine: gui.State.Panels.Files.SelectedLine, lineCount: len(gui.State.Files)}, {view: filesView, context: "", selectedLine: gui.State.Panels.Files.SelectedLine, lineCount: len(gui.State.Files), listView: gui.filesListView()},
{view: branchesView, context: "local-branches", selectedLine: gui.State.Panels.Branches.SelectedLine, lineCount: len(gui.State.Branches)}, {view: branchesView, context: "local-branches", selectedLine: gui.State.Panels.Branches.SelectedLine, lineCount: len(gui.State.Branches), listView: gui.branchesListView()},
{view: branchesView, context: "remotes", selectedLine: gui.State.Panels.Remotes.SelectedLine, lineCount: len(gui.State.Remotes)}, {view: branchesView, context: "remotes", selectedLine: gui.State.Panels.Remotes.SelectedLine, lineCount: len(gui.State.Remotes), listView: gui.remotesListView()},
{view: branchesView, context: "remote-branches", selectedLine: gui.State.Panels.RemoteBranches.SelectedLine, lineCount: len(gui.State.Remotes)}, {view: branchesView, context: "remote-branches", selectedLine: gui.State.Panels.RemoteBranches.SelectedLine, lineCount: len(gui.State.Remotes), listView: gui.remoteBranchesListView()},
{view: commitsView, context: "branch-commits", selectedLine: gui.State.Panels.Commits.SelectedLine, lineCount: len(gui.State.Commits)}, {view: branchesView, context: "tags", selectedLine: gui.State.Panels.Tags.SelectedLine, lineCount: len(gui.State.Tags), listView: gui.tagsListView()},
{view: commitsView, context: "reflog-commits", selectedLine: gui.State.Panels.ReflogCommits.SelectedLine, lineCount: len(gui.State.FilteredReflogCommits)}, {view: commitsView, context: "branch-commits", selectedLine: gui.State.Panels.Commits.SelectedLine, lineCount: len(gui.State.Commits), listView: gui.branchCommitsListView()},
{view: stashView, context: "", selectedLine: gui.State.Panels.Stash.SelectedLine, lineCount: len(gui.State.StashEntries)}, {view: commitsView, context: "reflog-commits", selectedLine: gui.State.Panels.ReflogCommits.SelectedLine, lineCount: len(gui.State.FilteredReflogCommits), listView: gui.reflogCommitsListView()},
{view: commitFilesView, context: "", selectedLine: gui.State.Panels.CommitFiles.SelectedLine, lineCount: len(gui.State.CommitFiles)}, {view: stashView, context: "", selectedLine: gui.State.Panels.Stash.SelectedLine, lineCount: len(gui.State.StashEntries), listView: gui.stashListView()},
{view: commitFilesView, context: "", selectedLine: gui.State.Panels.CommitFiles.SelectedLine, lineCount: len(gui.State.CommitFiles), listView: gui.commitFilesListView()},
} }
// menu view might not exist so we check to be safe // menu view might not exist so we check to be safe
if menuView, err := gui.g.View("menu"); err == nil { if menuView, err := gui.g.View("menu"); err == nil {
listViews = append(listViews, listViewState{view: menuView, context: "", selectedLine: gui.State.Panels.Menu.SelectedLine, lineCount: gui.State.MenuItemCount}) listViewStates = append(listViewStates, listViewState{view: menuView, context: "", selectedLine: gui.State.Panels.Menu.SelectedLine, lineCount: gui.State.MenuItemCount, listView: gui.menuListView()})
} }
for _, listView := range listViews { for _, listViewState := range listViewStates {
// ignore views where the context doesn't match up with the selected line we're trying to focus // ignore views where the context doesn't match up with the selected line we're trying to focus
if listView.context != "" && (listView.view.Context != listView.context) { if listViewState.context != "" && (listViewState.view.Context != listViewState.context) {
continue continue
} }
// check if the selected line is now out of view and if so refocus it // check if the selected line is now out of view and if so refocus it
listView.view.FocusPoint(0, listView.selectedLine) listViewState.view.FocusPoint(0, listViewState.selectedLine)
listView.view.SelBgColor = theme.GocuiSelectedLineBgColor listViewState.view.SelBgColor = theme.GocuiSelectedLineBgColor
// I doubt this is expensive though it's admittedly redundant after the first render
listViewState.view.SetOnSelectItem(gui.onSelectItemWrapper(listViewState.listView.onSearchSelect))
} }
mainViewWidth, mainViewHeight := gui.getMainView().Size() mainViewWidth, mainViewHeight := gui.getMainView().Size()

View File

@ -27,15 +27,27 @@ func (lv *listView) handleLineChange(change int) error {
return nil return nil
} }
view, err := lv.gui.g.View(lv.viewName)
if err != nil {
return err
}
lv.gui.changeSelectedLine(lv.getSelectedLineIdxPtr(), lv.getItemsLength(), change) lv.gui.changeSelectedLine(lv.getSelectedLineIdxPtr(), lv.getItemsLength(), change)
view.FocusPoint(0, *lv.getSelectedLineIdxPtr())
if lv.rendersToMainView { if lv.rendersToMainView {
if err := lv.gui.resetOrigin(lv.gui.getMainView()); err != nil { if err := lv.gui.resetOrigin(lv.gui.getMainView()); err != nil {
return err return err
} }
if err := lv.gui.resetOrigin(lv.gui.getSecondaryView()); err != nil {
return err
}
} }
return lv.handleItemSelect() if lv.handleItemSelect != nil {
return lv.handleItemSelect()
}
return nil
} }
func (lv *listView) handleNextPage(g *gocui.Gui, v *gocui.View) error { func (lv *listView) handleNextPage(g *gocui.Gui, v *gocui.View) error {
@ -81,128 +93,177 @@ func (lv *listView) handleClick(g *gocui.Gui, v *gocui.View) error {
prevSelectedLineIdx := *selectedLineIdxPtr prevSelectedLineIdx := *selectedLineIdxPtr
newSelectedLineIdx := v.SelectedLineIdx() newSelectedLineIdx := v.SelectedLineIdx()
// we need to focus the view
if err := lv.gui.switchFocus(nil, v); err != nil {
return err
}
if newSelectedLineIdx > lv.getItemsLength()-1 { if newSelectedLineIdx > lv.getItemsLength()-1 {
return lv.handleFocus() return lv.handleFocus()
} }
*selectedLineIdxPtr = newSelectedLineIdx *selectedLineIdxPtr = newSelectedLineIdx
if lv.rendersToMainView {
if err := lv.gui.resetOrigin(lv.gui.getMainView()); err != nil {
return err
}
}
prevViewName := lv.gui.currentViewName() prevViewName := lv.gui.currentViewName()
if prevSelectedLineIdx == newSelectedLineIdx && prevViewName == lv.viewName && lv.handleClickSelectedItem != nil { if prevSelectedLineIdx == newSelectedLineIdx && prevViewName == lv.viewName && lv.handleClickSelectedItem != nil {
return lv.handleClickSelectedItem() return lv.handleClickSelectedItem()
} }
return lv.handleItemSelect() if lv.handleItemSelect != nil {
return lv.handleItemSelect()
}
return nil
}
func (lv *listView) onSearchSelect(selectedLineIdx int) error {
*lv.getSelectedLineIdxPtr() = selectedLineIdx
if lv.handleItemSelect != nil {
return lv.handleItemSelect()
}
return nil
}
func (gui *Gui) menuListView() *listView {
return &listView{
viewName: "menu",
getItemsLength: func() int { return gui.getMenuView().LinesHeight() },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Menu.SelectedLine },
handleFocus: gui.handleMenuSelect,
handleItemSelect: gui.handleMenuSelect,
// need to add a layer of indirection here because the callback changes during runtime
handleClickSelectedItem: func() error { return gui.State.Panels.Menu.OnPress(gui.g, nil) },
gui: gui,
rendersToMainView: false,
}
}
func (gui *Gui) filesListView() *listView {
return &listView{
viewName: "files",
getItemsLength: func() int { return len(gui.State.Files) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Files.SelectedLine },
handleFocus: gui.focusAndSelectFile,
handleItemSelect: gui.focusAndSelectFile,
handleClickSelectedItem: gui.handleFilePress,
gui: gui,
rendersToMainView: false,
}
}
func (gui *Gui) branchesListView() *listView {
return &listView{
viewName: "branches",
context: "local-branches",
getItemsLength: func() int { return len(gui.State.Branches) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Branches.SelectedLine },
handleFocus: gui.handleBranchSelect,
handleItemSelect: gui.handleBranchSelect,
gui: gui,
rendersToMainView: true,
}
}
func (gui *Gui) remotesListView() *listView {
return &listView{
viewName: "branches",
context: "remotes",
getItemsLength: func() int { return len(gui.State.Remotes) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Remotes.SelectedLine },
handleFocus: gui.renderRemotesWithSelection,
handleItemSelect: gui.handleRemoteSelect,
handleClickSelectedItem: gui.handleRemoteEnter,
gui: gui,
rendersToMainView: true,
}
}
func (gui *Gui) remoteBranchesListView() *listView {
return &listView{
viewName: "branches",
context: "remote-branches",
getItemsLength: func() int { return len(gui.State.RemoteBranches) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.RemoteBranches.SelectedLine },
handleFocus: gui.handleRemoteBranchSelect,
handleItemSelect: gui.handleRemoteBranchSelect,
gui: gui,
rendersToMainView: true,
}
}
func (gui *Gui) tagsListView() *listView {
return &listView{
viewName: "branches",
context: "tags",
getItemsLength: func() int { return len(gui.State.Tags) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Tags.SelectedLine },
handleFocus: gui.handleTagSelect,
handleItemSelect: gui.handleTagSelect,
gui: gui,
rendersToMainView: true,
}
}
func (gui *Gui) branchCommitsListView() *listView {
return &listView{
viewName: "commits",
context: "branch-commits",
getItemsLength: func() int { return len(gui.State.Commits) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Commits.SelectedLine },
handleFocus: gui.handleCommitSelect,
handleItemSelect: gui.handleCommitSelect,
handleClickSelectedItem: gui.handleSwitchToCommitFilesPanel,
gui: gui,
rendersToMainView: true,
}
}
func (gui *Gui) reflogCommitsListView() *listView {
return &listView{
viewName: "commits",
context: "reflog-commits",
getItemsLength: func() int { return len(gui.State.FilteredReflogCommits) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.ReflogCommits.SelectedLine },
handleFocus: gui.handleReflogCommitSelect,
handleItemSelect: gui.handleReflogCommitSelect,
gui: gui,
rendersToMainView: true,
}
}
func (gui *Gui) stashListView() *listView {
return &listView{
viewName: "stash",
getItemsLength: func() int { return len(gui.State.StashEntries) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Stash.SelectedLine },
handleFocus: gui.handleStashEntrySelect,
handleItemSelect: gui.handleStashEntrySelect,
gui: gui,
rendersToMainView: true,
}
}
func (gui *Gui) commitFilesListView() *listView {
return &listView{
viewName: "commitFiles",
getItemsLength: func() int { return len(gui.State.CommitFiles) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.CommitFiles.SelectedLine },
handleFocus: gui.handleCommitFileSelect,
handleItemSelect: gui.handleCommitFileSelect,
gui: gui,
rendersToMainView: true,
}
} }
func (gui *Gui) getListViews() []*listView { func (gui *Gui) getListViews() []*listView {
return []*listView{ return []*listView{
{ gui.menuListView(),
viewName: "menu", gui.filesListView(),
getItemsLength: func() int { return gui.getMenuView().LinesHeight() }, gui.branchesListView(),
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Menu.SelectedLine }, gui.remotesListView(),
handleFocus: gui.handleMenuSelect, gui.remoteBranchesListView(),
handleItemSelect: gui.handleMenuSelect, gui.tagsListView(),
// need to add a layer of indirection here because the callback changes during runtime gui.branchCommitsListView(),
handleClickSelectedItem: func() error { return gui.State.Panels.Menu.OnPress(gui.g, nil) }, gui.reflogCommitsListView(),
gui: gui, gui.stashListView(),
rendersToMainView: false, gui.commitFilesListView(),
},
{
viewName: "files",
getItemsLength: func() int { return len(gui.State.Files) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Files.SelectedLine },
handleFocus: gui.focusAndSelectFile,
handleItemSelect: gui.focusAndSelectFile,
handleClickSelectedItem: gui.handleFilePress,
gui: gui,
rendersToMainView: true,
},
{
viewName: "branches",
context: "local-branches",
getItemsLength: func() int { return len(gui.State.Branches) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Branches.SelectedLine },
handleFocus: gui.handleBranchSelect,
handleItemSelect: gui.handleBranchSelect,
gui: gui,
rendersToMainView: true,
},
{
viewName: "branches",
context: "remotes",
getItemsLength: func() int { return len(gui.State.Remotes) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Remotes.SelectedLine },
handleFocus: gui.renderRemotesWithSelection,
handleItemSelect: gui.handleRemoteSelect,
handleClickSelectedItem: gui.handleRemoteEnter,
gui: gui,
rendersToMainView: true,
},
{
viewName: "branches",
context: "remote-branches",
getItemsLength: func() int { return len(gui.State.RemoteBranches) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.RemoteBranches.SelectedLine },
handleFocus: gui.handleRemoteBranchSelect,
handleItemSelect: gui.handleRemoteBranchSelect,
gui: gui,
rendersToMainView: true,
},
{
viewName: "branches",
context: "tags",
getItemsLength: func() int { return len(gui.State.Tags) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Tags.SelectedLine },
handleFocus: gui.handleTagSelect,
handleItemSelect: gui.handleTagSelect,
gui: gui,
rendersToMainView: true,
},
{
viewName: "commits",
context: "branch-commits",
getItemsLength: func() int { return len(gui.State.Commits) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Commits.SelectedLine },
handleFocus: gui.handleCommitSelect,
handleItemSelect: gui.handleCommitSelect,
handleClickSelectedItem: gui.handleSwitchToCommitFilesPanel,
gui: gui,
rendersToMainView: true,
},
{
viewName: "commits",
context: "reflog-commits",
getItemsLength: func() int { return len(gui.State.FilteredReflogCommits) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.ReflogCommits.SelectedLine },
handleFocus: gui.handleReflogCommitSelect,
handleItemSelect: gui.handleReflogCommitSelect,
gui: gui,
rendersToMainView: true,
},
{
viewName: "stash",
getItemsLength: func() int { return len(gui.State.StashEntries) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Stash.SelectedLine },
handleFocus: gui.handleStashEntrySelect,
handleItemSelect: gui.handleStashEntrySelect,
gui: gui,
rendersToMainView: true,
},
{
viewName: "commitFiles",
getItemsLength: func() int { return len(gui.State.CommitFiles) },
getSelectedLineIdxPtr: func() *int { return &gui.State.Panels.CommitFiles.SelectedLine },
handleFocus: gui.handleCommitFileSelect,
handleItemSelect: gui.handleCommitFileSelect,
gui: gui,
rendersToMainView: true,
},
} }
} }

View File

@ -149,8 +149,3 @@ func (gui *Gui) handleStashSave(stashFunc func(message string) error) error {
return gui.refreshSidePanels(refreshOptions{scope: []int{STASH, FILES}}) return gui.refreshSidePanels(refreshOptions{scope: []int{STASH, FILES}})
}) })
} }
func (gui *Gui) onStashPanelSearchSelect(selectedLine int) error {
gui.State.Panels.Stash.SelectedLine = selectedLine
return gui.handleStashEntrySelect()
}

View File

@ -24,10 +24,6 @@ func (gui *Gui) handleTagSelect() error {
gui.State.SplitMainPanel = false gui.State.SplitMainPanel = false
if _, err := gui.g.SetCurrentView("branches"); err != nil {
return err
}
gui.getMainView().Title = "Tag" gui.getMainView().Title = "Tag"
tag := gui.getSelectedTag() tag := gui.getSelectedTag()