1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-31 14:24:25 +03:00

use interface for panel state rather than pointer

This commit is contained in:
Jesse Duffield
2020-08-20 08:52:51 +10:00
parent 99707a527d
commit eb5e54e9fd
5 changed files with 151 additions and 133 deletions

View File

@ -420,7 +420,7 @@ func (gui *Gui) refreshStateFiles() error {
} }
} }
gui.refreshSelectedLine(&gui.State.Panels.Files.SelectedLine, len(gui.State.Files)) gui.refreshSelectedLine(gui.State.Panels.Files, len(gui.State.Files))
return nil return nil
} }

View File

@ -101,10 +101,23 @@ type Gui struct {
ViewTabContextMap map[string][]tabContext ViewTabContextMap map[string][]tabContext
} }
type hasSelectedLine struct { type listPanelState struct {
SelectedLine int SelectedLine int
} }
func (h *listPanelState) SetSelectedLineIdx(value int) {
h.SelectedLine = value
}
func (h *listPanelState) GetSelectedLineIdx() int {
return h.SelectedLine
}
type IListPanelState interface {
SetSelectedLineIdx(int)
GetSelectedLineIdx() int
}
// for now the staging panel state, unlike the other panel states, is going to be // for now the staging panel state, unlike the other panel states, is going to be
// non-mutative, so that we don't accidentally end up // non-mutative, so that we don't accidentally end up
// with mismatches of data. We might change this in the future // with mismatches of data. We might change this in the future
@ -130,47 +143,47 @@ type mergingPanelState struct {
} }
type filePanelState struct { type filePanelState struct {
hasSelectedLine listPanelState
} }
// TODO: consider splitting this out into the window and the branches view // TODO: consider splitting this out into the window and the branches view
type branchPanelState struct { type branchPanelState struct {
hasSelectedLine listPanelState
} }
type remotePanelState struct { type remotePanelState struct {
hasSelectedLine listPanelState
} }
type remoteBranchesState struct { type remoteBranchesState struct {
hasSelectedLine listPanelState
} }
type tagsPanelState struct { type tagsPanelState struct {
hasSelectedLine listPanelState
} }
type commitPanelState struct { type commitPanelState struct {
hasSelectedLine listPanelState
LimitCommits bool LimitCommits bool
} }
type reflogCommitPanelState struct { type reflogCommitPanelState struct {
hasSelectedLine listPanelState
} }
type stashPanelState struct { type stashPanelState struct {
hasSelectedLine listPanelState
} }
type menuPanelState struct { type menuPanelState struct {
hasSelectedLine listPanelState
OnPress func(g *gocui.Gui, v *gocui.View) error OnPress func(g *gocui.Gui, v *gocui.View) error
} }
type commitFilesPanelState struct { type commitFilesPanelState struct {
hasSelectedLine listPanelState
} }
type panelStates struct { type panelStates struct {
@ -271,16 +284,16 @@ func (gui *Gui) resetState() {
CherryPickedCommits: make([]*commands.Commit, 0), CherryPickedCommits: make([]*commands.Commit, 0),
StashEntries: make([]*commands.StashEntry, 0), StashEntries: make([]*commands.StashEntry, 0),
Panels: &panelStates{ Panels: &panelStates{
Files: &filePanelState{hasSelectedLine{SelectedLine: -1}}, Files: &filePanelState{listPanelState{SelectedLine: -1}},
Branches: &branchPanelState{hasSelectedLine{SelectedLine: 0}}, Branches: &branchPanelState{listPanelState{SelectedLine: 0}},
Remotes: &remotePanelState{hasSelectedLine{SelectedLine: 0}}, Remotes: &remotePanelState{listPanelState{SelectedLine: 0}},
RemoteBranches: &remoteBranchesState{hasSelectedLine{SelectedLine: -1}}, RemoteBranches: &remoteBranchesState{listPanelState{SelectedLine: -1}},
Tags: &tagsPanelState{hasSelectedLine{SelectedLine: -1}}, Tags: &tagsPanelState{listPanelState{SelectedLine: -1}},
Commits: &commitPanelState{hasSelectedLine: hasSelectedLine{SelectedLine: -1}, LimitCommits: true}, Commits: &commitPanelState{listPanelState: listPanelState{SelectedLine: -1}, LimitCommits: true},
ReflogCommits: &reflogCommitPanelState{hasSelectedLine{SelectedLine: 0}}, // TODO: might need to make -1 ReflogCommits: &reflogCommitPanelState{listPanelState{SelectedLine: 0}}, // TODO: might need to make -1
CommitFiles: &commitFilesPanelState{hasSelectedLine{SelectedLine: -1}}, CommitFiles: &commitFilesPanelState{listPanelState{SelectedLine: -1}},
Stash: &stashPanelState{hasSelectedLine{SelectedLine: -1}}, Stash: &stashPanelState{listPanelState{SelectedLine: -1}},
Menu: &menuPanelState{hasSelectedLine: hasSelectedLine{SelectedLine: 0}, OnPress: nil}, Menu: &menuPanelState{listPanelState: listPanelState{SelectedLine: 0}, OnPress: nil},
Merging: &mergingPanelState{ Merging: &mergingPanelState{
ConflictIndex: 0, ConflictIndex: 0,
ConflictTop: true, ConflictTop: true,

View File

@ -309,7 +309,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
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
listContextState.view.FocusPoint(0, *listContextState.listContext.GetSelectedLineIdxPtr()) listContextState.view.FocusPoint(0, listContextState.listContext.GetPanelState().GetSelectedLineIdx())
listContextState.view.SelBgColor = theme.GocuiSelectedLineBgColor listContextState.view.SelBgColor = theme.GocuiSelectedLineBgColor

View File

@ -6,15 +6,15 @@ import (
) )
type ListContext struct { type ListContext struct {
ViewName string ViewName string
ContextKey string ContextKey string
GetItemsLength func() int GetItemsLength func() int
GetSelectedLineIdxPtr func() *int GetDisplayStrings func() [][]string
GetDisplayStrings func() [][]string OnFocus func() error
OnFocus func() error OnFocusLost func() error
OnFocusLost func() error OnClickSelectedItem func() error
OnClickSelectedItem func() error GetItems func() []ListItem
GetItems func() []ListItem GetPanelState func() IListPanelState
Gui *Gui Gui *Gui
RendersToMainView bool RendersToMainView bool
@ -32,7 +32,7 @@ func (lc *ListContext) GetSelectedItem() ListItem {
return nil return nil
} }
selectedLineIdx := *lc.GetSelectedLineIdxPtr() selectedLineIdx := lc.GetPanelState().GetSelectedLineIdx()
if selectedLineIdx > len(items)-1 { if selectedLineIdx > len(items)-1 {
return nil return nil
@ -62,7 +62,7 @@ func (lc *ListContext) OnRender() error {
} }
if lc.GetDisplayStrings != nil { if lc.GetDisplayStrings != nil {
lc.Gui.refreshSelectedLine(lc.GetSelectedLineIdxPtr(), lc.GetItemsLength()) lc.Gui.refreshSelectedLine(lc.GetPanelState(), lc.GetItemsLength())
lc.Gui.renderDisplayStrings(view, lc.GetDisplayStrings()) lc.Gui.renderDisplayStrings(view, lc.GetDisplayStrings())
} }
@ -131,8 +131,8 @@ func (lc *ListContext) handleLineChange(change int) error {
return err return err
} }
lc.Gui.changeSelectedLine(lc.GetSelectedLineIdxPtr(), lc.GetItemsLength(), change) lc.Gui.changeSelectedLine(lc.GetPanelState(), lc.GetItemsLength(), change)
view.FocusPoint(0, *lc.GetSelectedLineIdxPtr()) view.FocusPoint(0, lc.GetPanelState().GetSelectedLineIdx())
if lc.RendersToMainView { if lc.RendersToMainView {
if err := lc.Gui.resetOrigin(lc.Gui.getMainView()); err != nil { if err := lc.Gui.resetOrigin(lc.Gui.getMainView()); err != nil {
@ -185,8 +185,7 @@ func (lc *ListContext) handleClick(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
selectedLineIdxPtr := lc.GetSelectedLineIdxPtr() prevSelectedLineIdx := lc.GetPanelState().GetSelectedLineIdx()
prevSelectedLineIdx := *selectedLineIdxPtr
newSelectedLineIdx := v.SelectedLineIdx() newSelectedLineIdx := v.SelectedLineIdx()
// we need to focus the view // we need to focus the view
@ -198,7 +197,7 @@ func (lc *ListContext) handleClick(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
*selectedLineIdxPtr = newSelectedLineIdx lc.GetPanelState().SetSelectedLineIdx(newSelectedLineIdx)
prevViewName := lc.Gui.currentViewName() prevViewName := lc.Gui.currentViewName()
if prevSelectedLineIdx == newSelectedLineIdx && prevViewName == lc.ViewName && lc.OnClickSelectedItem != nil { if prevSelectedLineIdx == newSelectedLineIdx && prevViewName == lc.ViewName && lc.OnClickSelectedItem != nil {
@ -208,23 +207,22 @@ func (lc *ListContext) handleClick(g *gocui.Gui, v *gocui.View) error {
} }
func (lc *ListContext) onSearchSelect(selectedLineIdx int) error { func (lc *ListContext) onSearchSelect(selectedLineIdx int) error {
*lc.GetSelectedLineIdxPtr() = selectedLineIdx lc.GetPanelState().SetSelectedLineIdx(selectedLineIdx)
return lc.HandleFocus() return lc.HandleFocus()
} }
func (gui *Gui) menuListContext() *ListContext { func (gui *Gui) menuListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "menu", ViewName: "menu",
ContextKey: "menu", ContextKey: "menu",
GetItemsLength: func() int { return gui.getMenuView().LinesHeight() }, GetItemsLength: func() int { return gui.getMenuView().LinesHeight() },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Menu.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.Menu },
OnFocus: gui.handleMenuSelect, OnFocus: gui.handleMenuSelect,
// need to add a layer of indirection here because the callback changes during runtime // need to add a layer of indirection here because the callback changes during runtime
OnClickSelectedItem: func() error { return gui.State.Panels.Menu.OnPress(gui.g, nil) }, OnClickSelectedItem: func() error { return gui.State.Panels.Menu.OnPress(gui.g, nil) },
Gui: gui, Gui: gui,
RendersToMainView: false, RendersToMainView: false,
Kind: PERSISTENT_POPUP, Kind: PERSISTENT_POPUP,
// GetItems:
// no GetDisplayStrings field because we do a custom render on menu creation // no GetDisplayStrings field because we do a custom render on menu creation
} }
@ -232,15 +230,15 @@ func (gui *Gui) menuListContext() *ListContext {
func (gui *Gui) filesListContext() *ListContext { func (gui *Gui) filesListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "files", ViewName: "files",
ContextKey: "files", ContextKey: "files",
GetItemsLength: func() int { return len(gui.State.Files) }, GetItemsLength: func() int { return len(gui.State.Files) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Files.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.Files },
OnFocus: gui.focusAndSelectFile, OnFocus: gui.focusAndSelectFile,
OnClickSelectedItem: gui.handleFilePress, OnClickSelectedItem: gui.handleFilePress,
Gui: gui, Gui: gui,
RendersToMainView: false, RendersToMainView: false,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetFileListDisplayStrings(gui.State.Files, gui.State.Diff.Ref) return presentation.GetFileListDisplayStrings(gui.State.Files, gui.State.Diff.Ref)
}, },
@ -249,14 +247,14 @@ func (gui *Gui) filesListContext() *ListContext {
func (gui *Gui) branchesListContext() *ListContext { func (gui *Gui) branchesListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "branches", ViewName: "branches",
ContextKey: "local-branches", ContextKey: "local-branches",
GetItemsLength: func() int { return len(gui.State.Branches) }, GetItemsLength: func() int { return len(gui.State.Branches) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Branches.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.Branches },
OnFocus: gui.handleBranchSelect, OnFocus: gui.handleBranchSelect,
Gui: gui, Gui: gui,
RendersToMainView: true, RendersToMainView: true,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Diff.Ref) return presentation.GetBranchListDisplayStrings(gui.State.Branches, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Diff.Ref)
}, },
@ -265,15 +263,15 @@ func (gui *Gui) branchesListContext() *ListContext {
func (gui *Gui) remotesListContext() *ListContext { func (gui *Gui) remotesListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "branches", ViewName: "branches",
ContextKey: "remotes", ContextKey: "remotes",
GetItemsLength: func() int { return len(gui.State.Remotes) }, GetItemsLength: func() int { return len(gui.State.Remotes) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Remotes.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.Remotes },
OnFocus: gui.handleRemoteSelect, OnFocus: gui.handleRemoteSelect,
OnClickSelectedItem: gui.handleRemoteEnter, OnClickSelectedItem: gui.handleRemoteEnter,
Gui: gui, Gui: gui,
RendersToMainView: true, RendersToMainView: true,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetRemoteListDisplayStrings(gui.State.Remotes, gui.State.Diff.Ref) return presentation.GetRemoteListDisplayStrings(gui.State.Remotes, gui.State.Diff.Ref)
}, },
@ -282,14 +280,14 @@ func (gui *Gui) remotesListContext() *ListContext {
func (gui *Gui) remoteBranchesListContext() *ListContext { func (gui *Gui) remoteBranchesListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "branches", ViewName: "branches",
ContextKey: "remote-branches", ContextKey: "remote-branches",
GetItemsLength: func() int { return len(gui.State.RemoteBranches) }, GetItemsLength: func() int { return len(gui.State.RemoteBranches) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.RemoteBranches.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.RemoteBranches },
OnFocus: gui.handleRemoteBranchSelect, OnFocus: gui.handleRemoteBranchSelect,
Gui: gui, Gui: gui,
RendersToMainView: true, RendersToMainView: true,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetRemoteBranchListDisplayStrings(gui.State.RemoteBranches, gui.State.Diff.Ref) return presentation.GetRemoteBranchListDisplayStrings(gui.State.RemoteBranches, gui.State.Diff.Ref)
}, },
@ -298,14 +296,14 @@ func (gui *Gui) remoteBranchesListContext() *ListContext {
func (gui *Gui) tagsListContext() *ListContext { func (gui *Gui) tagsListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "branches", ViewName: "branches",
ContextKey: "tags", ContextKey: "tags",
GetItemsLength: func() int { return len(gui.State.Tags) }, GetItemsLength: func() int { return len(gui.State.Tags) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Tags.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.Tags },
OnFocus: gui.handleTagSelect, OnFocus: gui.handleTagSelect,
Gui: gui, Gui: gui,
RendersToMainView: true, RendersToMainView: true,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetTagListDisplayStrings(gui.State.Tags, gui.State.Diff.Ref) return presentation.GetTagListDisplayStrings(gui.State.Tags, gui.State.Diff.Ref)
}, },
@ -314,15 +312,15 @@ func (gui *Gui) tagsListContext() *ListContext {
func (gui *Gui) branchCommitsListContext() *ListContext { func (gui *Gui) branchCommitsListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "commits", ViewName: "commits",
ContextKey: "branch-commits", ContextKey: "branch-commits",
GetItemsLength: func() int { return len(gui.State.Commits) }, GetItemsLength: func() int { return len(gui.State.Commits) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Commits.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.Commits },
OnFocus: gui.handleCommitSelect, OnFocus: gui.handleCommitSelect,
OnClickSelectedItem: gui.handleSwitchToCommitFilesPanel, OnClickSelectedItem: gui.handleSwitchToCommitFilesPanel,
Gui: gui, Gui: gui,
RendersToMainView: true, RendersToMainView: true,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetCommitListDisplayStrings(gui.State.Commits, gui.State.ScreenMode != SCREEN_NORMAL, gui.cherryPickedCommitShaMap(), gui.State.Diff.Ref) return presentation.GetCommitListDisplayStrings(gui.State.Commits, gui.State.ScreenMode != SCREEN_NORMAL, gui.cherryPickedCommitShaMap(), gui.State.Diff.Ref)
}, },
@ -331,14 +329,14 @@ func (gui *Gui) branchCommitsListContext() *ListContext {
func (gui *Gui) reflogCommitsListContext() *ListContext { func (gui *Gui) reflogCommitsListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "commits", ViewName: "commits",
ContextKey: "reflog-commits", ContextKey: "reflog-commits",
GetItemsLength: func() int { return len(gui.State.FilteredReflogCommits) }, GetItemsLength: func() int { return len(gui.State.FilteredReflogCommits) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.ReflogCommits.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.ReflogCommits },
OnFocus: gui.handleReflogCommitSelect, OnFocus: gui.handleReflogCommitSelect,
Gui: gui, Gui: gui,
RendersToMainView: true, RendersToMainView: true,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetReflogCommitListDisplayStrings(gui.State.FilteredReflogCommits, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Diff.Ref) return presentation.GetReflogCommitListDisplayStrings(gui.State.FilteredReflogCommits, gui.State.ScreenMode != SCREEN_NORMAL, gui.State.Diff.Ref)
}, },
@ -347,14 +345,14 @@ func (gui *Gui) reflogCommitsListContext() *ListContext {
func (gui *Gui) stashListContext() *ListContext { func (gui *Gui) stashListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "stash", ViewName: "stash",
ContextKey: "stash", ContextKey: "stash",
GetItemsLength: func() int { return len(gui.State.StashEntries) }, GetItemsLength: func() int { return len(gui.State.StashEntries) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Stash.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.Stash },
OnFocus: gui.handleStashEntrySelect, OnFocus: gui.handleStashEntrySelect,
Gui: gui, Gui: gui,
RendersToMainView: true, RendersToMainView: true,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetStashEntryListDisplayStrings(gui.State.StashEntries, gui.State.Diff.Ref) return presentation.GetStashEntryListDisplayStrings(gui.State.StashEntries, gui.State.Diff.Ref)
}, },
@ -363,14 +361,14 @@ func (gui *Gui) stashListContext() *ListContext {
func (gui *Gui) commitFilesListContext() *ListContext { func (gui *Gui) commitFilesListContext() *ListContext {
return &ListContext{ return &ListContext{
ViewName: "commitFiles", ViewName: "commitFiles",
ContextKey: "commitFiles", ContextKey: "commitFiles",
GetItemsLength: func() int { return len(gui.State.CommitFiles) }, GetItemsLength: func() int { return len(gui.State.CommitFiles) },
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.CommitFiles.SelectedLine }, GetPanelState: func() IListPanelState { return gui.State.Panels.CommitFiles },
OnFocus: gui.handleCommitFileSelect, OnFocus: gui.handleCommitFileSelect,
Gui: gui, Gui: gui,
RendersToMainView: true, RendersToMainView: true,
Kind: SIDE_CONTEXT, Kind: SIDE_CONTEXT,
GetDisplayStrings: func() [][]string { GetDisplayStrings: func() [][]string {
return presentation.GetCommitFileListDisplayStrings(gui.State.CommitFiles, gui.State.Diff.Ref) return presentation.GetCommitFileListDisplayStrings(gui.State.CommitFiles, gui.State.Diff.Ref)
}, },

View File

@ -289,25 +289,32 @@ func (gui *Gui) resizePopupPanel(v *gocui.View) error {
return err return err
} }
func (gui *Gui) changeSelectedLine(line *int, total int, change int) { func (gui *Gui) changeSelectedLine(panelState IListPanelState, total int, change int) {
// TODO: find out why we're doing this // TODO: find out why we're doing this
if *line == -1 { line := panelState.GetSelectedLineIdx()
if line == -1 {
return return
} }
if *line+change < 0 { var newLine int
*line = 0 if line+change < 0 {
} else if *line+change >= total { newLine = 0
*line = total - 1 } else if line+change >= total {
newLine = total - 1
} else { } else {
*line += change newLine = line + change
} }
panelState.SetSelectedLineIdx(newLine)
} }
func (gui *Gui) refreshSelectedLine(line *int, total int) { func (gui *Gui) refreshSelectedLine(panelState IListPanelState, total int) {
if *line == -1 && total > 0 { line := panelState.GetSelectedLineIdx()
*line = 0
} else if total-1 < *line { if line == -1 && total > 0 {
*line = total - 1 panelState.SetSelectedLineIdx(0)
} else if total-1 < line {
panelState.SetSelectedLineIdx(total - 1)
} }
} }