package gui import "github.com/jesseduffield/gocui" type listView struct { viewName string context string getItemsLength func() int getSelectedLineIdxPtr func() *int handleFocus func(g *gocui.Gui, v *gocui.View) error handleItemSelect func(g *gocui.Gui, v *gocui.View) error handleClickSelectedItem func(g *gocui.Gui, v *gocui.View) error gui *Gui rendersToMainView bool } func (lv *listView) handlePrevLine(g *gocui.Gui, v *gocui.View) error { return lv.handleLineChange(-1) } func (lv *listView) handleNextLine(g *gocui.Gui, v *gocui.View) error { return lv.handleLineChange(1) } func (lv *listView) handleLineChange(change int) error { if !lv.gui.isPopupPanel(lv.viewName) && lv.gui.popupPanelFocused() { return nil } lv.gui.changeSelectedLine(lv.getSelectedLineIdxPtr(), lv.getItemsLength(), change) if lv.rendersToMainView { if err := lv.gui.resetOrigin(lv.gui.getMainView()); err != nil { return err } } view, err := lv.gui.g.View(lv.viewName) if err != nil { return err } return lv.handleItemSelect(lv.gui.g, view) } func (lv *listView) handleClick(g *gocui.Gui, v *gocui.View) error { if !lv.gui.isPopupPanel(lv.viewName) && lv.gui.popupPanelFocused() { return nil } selectedLineIdxPtr := lv.getSelectedLineIdxPtr() prevSelectedLineIdx := *selectedLineIdxPtr newSelectedLineIdx := v.SelectedLineIdx() if newSelectedLineIdx > lv.getItemsLength()-1 { return lv.handleFocus(lv.gui.g, v) } *selectedLineIdxPtr = newSelectedLineIdx if prevSelectedLineIdx == newSelectedLineIdx && lv.gui.currentViewName() == lv.viewName && lv.handleClickSelectedItem != nil { return lv.handleClickSelectedItem(lv.gui.g, v) } return lv.handleItemSelect(lv.gui.g, v) } func (gui *Gui) getListViews() []*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: gui.wrappedHandler(func() error { return gui.State.Panels.Menu.OnPress(gui.g, nil) }), gui: gui, rendersToMainView: false, }, { 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.wrappedHandler(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", 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: "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, }, } }