2019-11-16 05:00:27 +02:00
|
|
|
package gui
|
|
|
|
|
|
|
|
import "github.com/jesseduffield/gocui"
|
|
|
|
|
|
|
|
type listView struct {
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName string
|
|
|
|
Context string
|
|
|
|
GetItemsLength func() int
|
|
|
|
GetSelectedLineIdxPtr func() *int
|
|
|
|
OnFocus func() error
|
|
|
|
OnItemSelect func() error
|
|
|
|
OnClickSelectedItem func() error
|
|
|
|
Gui *Gui
|
|
|
|
RendersToMainView bool
|
2019-11-16 05:00:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2020-08-16 02:05:45 +02:00
|
|
|
if !lv.Gui.isPopupPanel(lv.ViewName) && lv.Gui.popupPanelFocused() {
|
2019-11-16 05:00:27 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-08-16 02:05:45 +02:00
|
|
|
view, err := lv.Gui.g.View(lv.ViewName)
|
2020-08-16 01:18:57 +02:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-08-16 02:05:45 +02:00
|
|
|
lv.Gui.changeSelectedLine(lv.GetSelectedLineIdxPtr(), lv.GetItemsLength(), change)
|
|
|
|
view.FocusPoint(0, *lv.GetSelectedLineIdxPtr())
|
2019-11-16 05:00:27 +02:00
|
|
|
|
2020-08-16 02:05:45 +02:00
|
|
|
if lv.RendersToMainView {
|
|
|
|
if err := lv.Gui.resetOrigin(lv.Gui.getMainView()); err != nil {
|
2019-11-16 05:00:27 +02:00
|
|
|
return err
|
|
|
|
}
|
2020-08-16 02:05:45 +02:00
|
|
|
if err := lv.Gui.resetOrigin(lv.Gui.getSecondaryView()); err != nil {
|
2020-08-16 01:18:57 +02:00
|
|
|
return err
|
|
|
|
}
|
2019-11-16 05:00:27 +02:00
|
|
|
}
|
2020-01-12 04:39:48 +02:00
|
|
|
|
2020-08-16 02:05:45 +02:00
|
|
|
if lv.OnItemSelect != nil {
|
|
|
|
return lv.OnItemSelect()
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
return nil
|
2019-11-16 05:00:27 +02:00
|
|
|
}
|
|
|
|
|
2020-03-28 04:44:20 +02:00
|
|
|
func (lv *listView) handleNextPage(g *gocui.Gui, v *gocui.View) error {
|
2020-08-16 02:05:45 +02:00
|
|
|
view, err := lv.Gui.g.View(lv.ViewName)
|
2020-03-28 04:44:20 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
_, height := view.Size()
|
|
|
|
delta := height - 1
|
|
|
|
if delta == 0 {
|
|
|
|
delta = 1
|
|
|
|
}
|
|
|
|
return lv.handleLineChange(delta)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (lv *listView) handleGotoTop(g *gocui.Gui, v *gocui.View) error {
|
2020-08-16 02:05:45 +02:00
|
|
|
return lv.handleLineChange(-lv.GetItemsLength())
|
2020-03-28 04:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (lv *listView) handleGotoBottom(g *gocui.Gui, v *gocui.View) error {
|
2020-08-16 02:05:45 +02:00
|
|
|
return lv.handleLineChange(lv.GetItemsLength())
|
2020-03-28 04:44:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (lv *listView) handlePrevPage(g *gocui.Gui, v *gocui.View) error {
|
2020-08-16 02:05:45 +02:00
|
|
|
view, err := lv.Gui.g.View(lv.ViewName)
|
2020-03-28 04:44:20 +02:00
|
|
|
if err != nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
_, height := view.Size()
|
|
|
|
delta := height - 1
|
|
|
|
if delta == 0 {
|
|
|
|
delta = 1
|
|
|
|
}
|
|
|
|
return lv.handleLineChange(-delta)
|
|
|
|
}
|
|
|
|
|
2019-11-17 08:23:06 +02:00
|
|
|
func (lv *listView) handleClick(g *gocui.Gui, v *gocui.View) error {
|
2020-08-16 02:05:45 +02:00
|
|
|
if !lv.Gui.isPopupPanel(lv.ViewName) && lv.Gui.popupPanelFocused() {
|
2019-11-17 08:23:06 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-08-16 02:05:45 +02:00
|
|
|
selectedLineIdxPtr := lv.GetSelectedLineIdxPtr()
|
2019-11-17 08:23:06 +02:00
|
|
|
prevSelectedLineIdx := *selectedLineIdxPtr
|
|
|
|
newSelectedLineIdx := v.SelectedLineIdx()
|
|
|
|
|
2020-08-16 01:18:57 +02:00
|
|
|
// we need to focus the view
|
2020-08-16 02:05:45 +02:00
|
|
|
if err := lv.Gui.switchFocus(nil, v); err != nil {
|
2020-08-16 01:18:57 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2020-08-16 02:05:45 +02:00
|
|
|
if newSelectedLineIdx > lv.GetItemsLength()-1 {
|
|
|
|
return lv.OnFocus()
|
2019-11-17 08:23:06 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
*selectedLineIdxPtr = newSelectedLineIdx
|
|
|
|
|
2020-08-16 02:05:45 +02:00
|
|
|
prevViewName := lv.Gui.currentViewName()
|
|
|
|
if prevSelectedLineIdx == newSelectedLineIdx && prevViewName == lv.ViewName && lv.OnClickSelectedItem != nil {
|
|
|
|
return lv.OnClickSelectedItem()
|
2019-11-17 08:23:06 +02:00
|
|
|
}
|
2020-08-16 02:05:45 +02:00
|
|
|
if lv.OnItemSelect != nil {
|
|
|
|
return lv.OnItemSelect()
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (lv *listView) onSearchSelect(selectedLineIdx int) error {
|
2020-08-16 02:05:45 +02:00
|
|
|
*lv.GetSelectedLineIdxPtr() = selectedLineIdx
|
|
|
|
if lv.OnItemSelect != nil {
|
|
|
|
return lv.OnItemSelect()
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) menuListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "menu",
|
|
|
|
GetItemsLength: func() int { return gui.getMenuView().LinesHeight() },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Menu.SelectedLine },
|
|
|
|
OnFocus: gui.handleMenuSelect,
|
|
|
|
OnItemSelect: gui.handleMenuSelect,
|
2020-08-16 01:18:57 +02:00
|
|
|
// need to add a layer of indirection here because the callback changes during runtime
|
2020-08-16 02:05:45 +02:00
|
|
|
OnClickSelectedItem: func() error { return gui.State.Panels.Menu.OnPress(gui.g, nil) },
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: false,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) filesListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "files",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.Files) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Files.SelectedLine },
|
|
|
|
OnFocus: gui.focusAndSelectFile,
|
|
|
|
OnItemSelect: gui.focusAndSelectFile,
|
|
|
|
OnClickSelectedItem: gui.handleFilePress,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: false,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) branchesListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "branches",
|
|
|
|
Context: "local-branches",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.Branches) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Branches.SelectedLine },
|
|
|
|
OnFocus: gui.handleBranchSelect,
|
|
|
|
OnItemSelect: gui.handleBranchSelect,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: true,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) remotesListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "branches",
|
|
|
|
Context: "remotes",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.Remotes) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Remotes.SelectedLine },
|
|
|
|
OnFocus: gui.renderRemotesWithSelection,
|
|
|
|
OnItemSelect: gui.handleRemoteSelect,
|
|
|
|
OnClickSelectedItem: gui.handleRemoteEnter,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: true,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) remoteBranchesListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "branches",
|
|
|
|
Context: "remote-branches",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.RemoteBranches) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.RemoteBranches.SelectedLine },
|
|
|
|
OnFocus: gui.handleRemoteBranchSelect,
|
|
|
|
OnItemSelect: gui.handleRemoteBranchSelect,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: true,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) tagsListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "branches",
|
|
|
|
Context: "tags",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.Tags) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Tags.SelectedLine },
|
|
|
|
OnFocus: gui.handleTagSelect,
|
|
|
|
OnItemSelect: gui.handleTagSelect,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: true,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) branchCommitsListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "commits",
|
|
|
|
Context: "branch-commits",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.Commits) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Commits.SelectedLine },
|
|
|
|
OnFocus: gui.handleCommitSelect,
|
|
|
|
OnItemSelect: gui.handleCommitSelect,
|
|
|
|
OnClickSelectedItem: gui.handleSwitchToCommitFilesPanel,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: true,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) reflogCommitsListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "commits",
|
|
|
|
Context: "reflog-commits",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.FilteredReflogCommits) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.ReflogCommits.SelectedLine },
|
|
|
|
OnFocus: gui.handleReflogCommitSelect,
|
|
|
|
OnItemSelect: gui.handleReflogCommitSelect,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: true,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) stashListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "stash",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.StashEntries) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.Stash.SelectedLine },
|
|
|
|
OnFocus: gui.handleStashEntrySelect,
|
|
|
|
OnItemSelect: gui.handleStashEntrySelect,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: true,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (gui *Gui) commitFilesListView() *listView {
|
|
|
|
return &listView{
|
2020-08-16 02:05:45 +02:00
|
|
|
ViewName: "commitFiles",
|
|
|
|
GetItemsLength: func() int { return len(gui.State.CommitFiles) },
|
|
|
|
GetSelectedLineIdxPtr: func() *int { return &gui.State.Panels.CommitFiles.SelectedLine },
|
|
|
|
OnFocus: gui.handleCommitFileSelect,
|
|
|
|
OnItemSelect: gui.handleCommitFileSelect,
|
|
|
|
Gui: gui,
|
|
|
|
RendersToMainView: true,
|
2020-08-16 01:18:57 +02:00
|
|
|
}
|
2019-11-17 08:23:06 +02:00
|
|
|
}
|
|
|
|
|
2019-11-16 05:00:27 +02:00
|
|
|
func (gui *Gui) getListViews() []*listView {
|
|
|
|
return []*listView{
|
2020-08-16 01:18:57 +02:00
|
|
|
gui.menuListView(),
|
|
|
|
gui.filesListView(),
|
|
|
|
gui.branchesListView(),
|
|
|
|
gui.remotesListView(),
|
|
|
|
gui.remoteBranchesListView(),
|
|
|
|
gui.tagsListView(),
|
|
|
|
gui.branchCommitsListView(),
|
|
|
|
gui.reflogCommitsListView(),
|
|
|
|
gui.stashListView(),
|
|
|
|
gui.commitFilesListView(),
|
2019-11-16 05:00:27 +02:00
|
|
|
}
|
|
|
|
}
|