use generics to DRY up context code

This commit is contained in:
Jesse Duffield 2022-03-19 09:31:52 +11:00
parent 4b56d428ff
commit d93fef4c61
31 changed files with 117 additions and 364 deletions

View file

@ -12,7 +12,7 @@ func (gui *Gui) onCommitFileFocus() error {
} }
func (gui *Gui) commitFilesRenderToMain() error { func (gui *Gui) commitFilesRenderToMain() error {
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode() node := gui.State.Contexts.CommitFiles.GetSelected()
if node == nil { if node == nil {
return nil return nil
} }
@ -78,7 +78,7 @@ func (gui *Gui) refreshCommitFilesView() error {
} }
func (gui *Gui) getSelectedCommitFileName() string { func (gui *Gui) getSelectedCommitFileName() string {
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode() node := gui.State.Contexts.CommitFiles.GetSelected()
if node == nil { if node == nil {
return "" return ""
} }

View file

@ -0,0 +1,34 @@
package context
import "github.com/jesseduffield/lazygit/pkg/gui/context/traits"
type BasicViewModel[T any] struct {
*traits.ListCursor
getModel func() []T
}
func NewBasicViewModel[T any](getModel func() []T) *BasicViewModel[T] {
self := &BasicViewModel[T]{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *BasicViewModel[T]) Len() int {
return len(self.getModel())
}
func (self *BasicViewModel[T]) GetSelected() T {
if self.Len() == 0 {
return Zero[T]()
}
return self.getModel()[self.GetSelectedLineIdx()]
}
func Zero[T any]() T {
return *new(T)
}

View file

@ -3,12 +3,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type BranchesContext struct { type BranchesContext struct {
*BranchesViewModel *BasicViewModel[*models.Branch]
*ListContextTrait *ListContextTrait
} }
@ -25,10 +24,10 @@ func NewBranchesContext(
c *types.HelperCommon, c *types.HelperCommon,
) *BranchesContext { ) *BranchesContext {
viewModel := NewBranchesViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &BranchesContext{ return &BranchesContext{
BranchesViewModel: viewModel, BasicViewModel: viewModel,
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "branches", ViewName: "branches",
@ -58,34 +57,7 @@ func (self *BranchesContext) GetSelectedItemId() string {
return item.ID() return item.ID()
} }
type BranchesViewModel struct { func (self *BranchesContext) GetSelectedRefName() string {
*traits.ListCursor
getModel func() []*models.Branch
}
func NewBranchesViewModel(getModel func() []*models.Branch) *BranchesViewModel {
self := &BranchesViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *BranchesViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *BranchesViewModel) GetSelected() *models.Branch {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}
func (self *BranchesViewModel) GetSelectedRefName() string {
item := self.GetSelected() item := self.GetSelected()
if item == nil { if item == nil {
return "" return ""

View file

@ -52,7 +52,7 @@ func NewCommitFilesContext(
} }
func (self *CommitFilesContext) GetSelectedItemId() string { func (self *CommitFilesContext) GetSelectedItemId() string {
item := self.GetSelectedFileNode() item := self.GetSelected()
if item == nil { if item == nil {
return "" return ""
} }

View file

@ -27,7 +27,7 @@ func (self *ListContextTrait) GetViewTrait() types.IViewTrait {
func (self *ListContextTrait) FocusLine() { func (self *ListContextTrait) FocusLine() {
// we need a way of knowing whether we've rendered to the view yet. // we need a way of knowing whether we've rendered to the view yet.
self.viewTrait.FocusPoint(self.list.GetSelectedLineIdx()) self.viewTrait.FocusPoint(self.list.GetSelectedLineIdx())
self.viewTrait.SetFooter(formatListFooter(self.list.GetSelectedLineIdx(), self.list.GetItemsLength())) self.viewTrait.SetFooter(formatListFooter(self.list.GetSelectedLineIdx(), self.list.Len()))
} }
func formatListFooter(selectedLineIdx int, length int) string { func formatListFooter(selectedLineIdx int, length int) string {
@ -49,7 +49,7 @@ func (self *ListContextTrait) HandleFocusLost() error {
// OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view // OnFocus assumes that the content of the context has already been rendered to the view. OnRender is the function which actually renders the content to the view
func (self *ListContextTrait) HandleRender() error { func (self *ListContextTrait) HandleRender() error {
self.list.RefreshSelectedIdx() self.list.RefreshSelectedIdx()
content := utils.RenderDisplayStrings(self.getDisplayStrings(0, self.list.GetItemsLength())) content := utils.RenderDisplayStrings(self.getDisplayStrings(0, self.list.Len()))
self.viewTrait.SetContent(content) self.viewTrait.SetContent(content)
self.c.Render() self.c.Render()

View file

@ -3,7 +3,6 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
@ -60,8 +59,7 @@ func (self *LocalCommitsContext) GetSelectedItemId() string {
} }
type LocalCommitsViewModel struct { type LocalCommitsViewModel struct {
*traits.ListCursor *BasicViewModel[*models.Commit]
getModel func() []*models.Commit
// If this is true we limit the amount of commits we load, for the sake of keeping things fast. // If this is true we limit the amount of commits we load, for the sake of keeping things fast.
// If the user attempts to scroll past the end of the list, we will load more commits. // If the user attempts to scroll past the end of the list, we will load more commits.
@ -73,12 +71,10 @@ type LocalCommitsViewModel struct {
func NewLocalCommitsViewModel(getModel func() []*models.Commit) *LocalCommitsViewModel { func NewLocalCommitsViewModel(getModel func() []*models.Commit) *LocalCommitsViewModel {
self := &LocalCommitsViewModel{ self := &LocalCommitsViewModel{
getModel: getModel, BasicViewModel: NewBasicViewModel(getModel),
limitCommits: true, limitCommits: true,
} }
self.ListCursor = traits.NewListCursor(self)
return self return self
} }
@ -96,18 +92,6 @@ func (self *LocalCommitsContext) GetSelectedRefName() string {
return item.RefName() return item.RefName()
} }
func (self *LocalCommitsViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *LocalCommitsViewModel) GetSelected() *models.Commit {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}
func (self *LocalCommitsViewModel) SetLimitCommits(value bool) { func (self *LocalCommitsViewModel) SetLimitCommits(value bool) {
self.limitCommits = value self.limitCommits = value
} }

View file

@ -2,7 +2,6 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
@ -59,8 +58,8 @@ func (self *MenuContext) GetSelectedItemId() string {
} }
type MenuViewModel struct { type MenuViewModel struct {
*traits.ListCursor
menuItems []*types.MenuItem menuItems []*types.MenuItem
*BasicViewModel[*types.MenuItem]
} }
func NewMenuViewModel() *MenuViewModel { func NewMenuViewModel() *MenuViewModel {
@ -68,23 +67,11 @@ func NewMenuViewModel() *MenuViewModel {
menuItems: nil, menuItems: nil,
} }
self.ListCursor = traits.NewListCursor(self) self.BasicViewModel = NewBasicViewModel(func() []*types.MenuItem { return self.menuItems })
return self return self
} }
func (self *MenuViewModel) GetItemsLength() int {
return len(self.menuItems)
}
func (self *MenuViewModel) GetSelected() *types.MenuItem {
if self.GetItemsLength() == 0 {
return nil
}
return self.menuItems[self.GetSelectedLineIdx()]
}
func (self *MenuViewModel) SetMenuItems(items []*types.MenuItem) { func (self *MenuViewModel) SetMenuItems(items []*types.MenuItem) {
self.menuItems = items self.menuItems = items
} }

View file

@ -3,12 +3,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type ReflogCommitsContext struct { type ReflogCommitsContext struct {
*ReflogCommitsViewModel *BasicViewModel[*models.Commit]
*ListContextTrait *ListContextTrait
} }
@ -25,10 +24,10 @@ func NewReflogCommitsContext(
c *types.HelperCommon, c *types.HelperCommon,
) *ReflogCommitsContext { ) *ReflogCommitsContext {
viewModel := NewReflogCommitsViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &ReflogCommitsContext{ return &ReflogCommitsContext{
ReflogCommitsViewModel: viewModel, BasicViewModel: viewModel,
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "commits", ViewName: "commits",
@ -71,30 +70,3 @@ func (self *ReflogCommitsContext) GetSelectedRefName() string {
return item.RefName() return item.RefName()
} }
type ReflogCommitsViewModel struct {
*traits.ListCursor
getModel func() []*models.Commit
}
func NewReflogCommitsViewModel(getModel func() []*models.Commit) *ReflogCommitsViewModel {
self := &ReflogCommitsViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *ReflogCommitsViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *ReflogCommitsViewModel) GetSelected() *models.Commit {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}

View file

@ -3,12 +3,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type RemoteBranchesContext struct { type RemoteBranchesContext struct {
*RemoteBranchesViewModel *BasicViewModel[*models.RemoteBranch]
*ListContextTrait *ListContextTrait
} }
@ -25,10 +24,10 @@ func NewRemoteBranchesContext(
c *types.HelperCommon, c *types.HelperCommon,
) *RemoteBranchesContext { ) *RemoteBranchesContext {
viewModel := NewRemoteBranchesViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &RemoteBranchesContext{ return &RemoteBranchesContext{
RemoteBranchesViewModel: viewModel, BasicViewModel: viewModel,
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "branches", ViewName: "branches",
@ -58,34 +57,7 @@ func (self *RemoteBranchesContext) GetSelectedItemId() string {
return item.ID() return item.ID()
} }
type RemoteBranchesViewModel struct { func (self *RemoteBranchesContext) GetSelectedRefName() string {
*traits.ListCursor
getModel func() []*models.RemoteBranch
}
func NewRemoteBranchesViewModel(getModel func() []*models.RemoteBranch) *RemoteBranchesViewModel {
self := &RemoteBranchesViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *RemoteBranchesViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *RemoteBranchesViewModel) GetSelected() *models.RemoteBranch {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}
func (self *RemoteBranchesViewModel) GetSelectedRefName() string {
item := self.GetSelected() item := self.GetSelected()
if item == nil { if item == nil {
return "" return ""

View file

@ -3,12 +3,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type RemotesContext struct { type RemotesContext struct {
*RemotesViewModel *BasicViewModel[*models.Remote]
*ListContextTrait *ListContextTrait
} }
@ -25,10 +24,10 @@ func NewRemotesContext(
c *types.HelperCommon, c *types.HelperCommon,
) *RemotesContext { ) *RemotesContext {
viewModel := NewRemotesViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &RemotesContext{ return &RemotesContext{
RemotesViewModel: viewModel, BasicViewModel: viewModel,
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "branches", ViewName: "branches",
@ -57,30 +56,3 @@ func (self *RemotesContext) GetSelectedItemId() string {
return item.ID() return item.ID()
} }
type RemotesViewModel struct {
*traits.ListCursor
getModel func() []*models.Remote
}
func NewRemotesViewModel(getModel func() []*models.Remote) *RemotesViewModel {
self := &RemotesViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *RemotesViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *RemotesViewModel) GetSelected() *models.Remote {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}

View file

@ -3,12 +3,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type StashContext struct { type StashContext struct {
*StashViewModel *BasicViewModel[*models.StashEntry]
*ListContextTrait *ListContextTrait
} }
@ -25,10 +24,10 @@ func NewStashContext(
c *types.HelperCommon, c *types.HelperCommon,
) *StashContext { ) *StashContext {
viewModel := NewStashViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &StashContext{ return &StashContext{
StashViewModel: viewModel, BasicViewModel: viewModel,
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "stash", ViewName: "stash",
@ -71,30 +70,3 @@ func (self *StashContext) GetSelectedRefName() string {
return item.RefName() return item.RefName()
} }
type StashViewModel struct {
*traits.ListCursor
getModel func() []*models.StashEntry
}
func NewStashViewModel(getModel func() []*models.StashEntry) *StashViewModel {
self := &StashViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *StashViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *StashViewModel) GetSelected() *models.StashEntry {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}

View file

@ -3,12 +3,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type SubCommitsContext struct { type SubCommitsContext struct {
*SubCommitsViewModel *BasicViewModel[*models.Commit]
*ViewportListContextTrait *ViewportListContextTrait
} }
@ -25,10 +24,10 @@ func NewSubCommitsContext(
c *types.HelperCommon, c *types.HelperCommon,
) *SubCommitsContext { ) *SubCommitsContext {
viewModel := NewSubCommitsViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &SubCommitsContext{ return &SubCommitsContext{
SubCommitsViewModel: viewModel, BasicViewModel: viewModel,
ViewportListContextTrait: &ViewportListContextTrait{ ViewportListContextTrait: &ViewportListContextTrait{
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
@ -72,30 +71,3 @@ func (self *SubCommitsContext) GetSelectedRefName() string {
return item.RefName() return item.RefName()
} }
type SubCommitsViewModel struct {
*traits.ListCursor
getModel func() []*models.Commit
}
func NewSubCommitsViewModel(getModel func() []*models.Commit) *SubCommitsViewModel {
self := &SubCommitsViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *SubCommitsViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *SubCommitsViewModel) GetSelected() *models.Commit {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}

View file

@ -3,12 +3,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type SubmodulesContext struct { type SubmodulesContext struct {
*SubmodulesViewModel *BasicViewModel[*models.SubmoduleConfig]
*ListContextTrait *ListContextTrait
} }
@ -25,10 +24,10 @@ func NewSubmodulesContext(
c *types.HelperCommon, c *types.HelperCommon,
) *SubmodulesContext { ) *SubmodulesContext {
viewModel := NewSubmodulesViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &SubmodulesContext{ return &SubmodulesContext{
SubmodulesViewModel: viewModel, BasicViewModel: viewModel,
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "files", ViewName: "files",
@ -57,30 +56,3 @@ func (self *SubmodulesContext) GetSelectedItemId() string {
return item.ID() return item.ID()
} }
type SubmodulesViewModel struct {
*traits.ListCursor
getModel func() []*models.SubmoduleConfig
}
func NewSubmodulesViewModel(getModel func() []*models.SubmoduleConfig) *SubmodulesViewModel {
self := &SubmodulesViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *SubmodulesViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *SubmodulesViewModel) GetSelected() *models.SubmoduleConfig {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}

View file

@ -2,12 +2,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type SuggestionsContext struct { type SuggestionsContext struct {
*SuggestionsViewModel *BasicViewModel[*types.Suggestion]
*ListContextTrait *ListContextTrait
} }
@ -24,10 +23,10 @@ func NewSuggestionsContext(
c *types.HelperCommon, c *types.HelperCommon,
) *SuggestionsContext { ) *SuggestionsContext {
viewModel := NewSuggestionsViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &SuggestionsContext{ return &SuggestionsContext{
SuggestionsViewModel: viewModel, BasicViewModel: viewModel,
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "suggestions", ViewName: "suggestions",
@ -56,30 +55,3 @@ func (self *SuggestionsContext) GetSelectedItemId() string {
return item.Value return item.Value
} }
type SuggestionsViewModel struct {
*traits.ListCursor
getModel func() []*types.Suggestion
}
func NewSuggestionsViewModel(getModel func() []*types.Suggestion) *SuggestionsViewModel {
self := &SuggestionsViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *SuggestionsViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *SuggestionsViewModel) GetSelected() *types.Suggestion {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}

View file

@ -3,12 +3,11 @@ package context
import ( import (
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gui/context/traits"
"github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/gui/types"
) )
type TagsContext struct { type TagsContext struct {
*TagsViewModel *BasicViewModel[*models.Tag]
*ListContextTrait *ListContextTrait
} }
@ -25,10 +24,10 @@ func NewTagsContext(
c *types.HelperCommon, c *types.HelperCommon,
) *TagsContext { ) *TagsContext {
viewModel := NewTagsViewModel(getModel) viewModel := NewBasicViewModel(getModel)
return &TagsContext{ return &TagsContext{
TagsViewModel: viewModel, BasicViewModel: viewModel,
ListContextTrait: &ListContextTrait{ ListContextTrait: &ListContextTrait{
Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{ Context: NewSimpleContext(NewBaseContext(NewBaseContextOpts{
ViewName: "branches", ViewName: "branches",
@ -58,34 +57,7 @@ func (self *TagsContext) GetSelectedItemId() string {
return item.ID() return item.ID()
} }
type TagsViewModel struct { func (self *TagsContext) GetSelectedRefName() string {
*traits.ListCursor
getModel func() []*models.Tag
}
func NewTagsViewModel(getModel func() []*models.Tag) *TagsViewModel {
self := &TagsViewModel{
getModel: getModel,
}
self.ListCursor = traits.NewListCursor(self)
return self
}
func (self *TagsViewModel) GetItemsLength() int {
return len(self.getModel())
}
func (self *TagsViewModel) GetSelected() *models.Tag {
if self.GetItemsLength() == 0 {
return nil
}
return self.getModel()[self.GetSelectedLineIdx()]
}
func (self *TagsViewModel) GetSelectedRefName() string {
item := self.GetSelected() item := self.GetSelected()
if item == nil { if item == nil {
return "" return ""

View file

@ -6,7 +6,7 @@ import (
) )
type HasLength interface { type HasLength interface {
GetItemsLength() int Len() int
} }
type ListCursor struct { type ListCursor struct {
@ -25,7 +25,7 @@ func (self *ListCursor) GetSelectedLineIdx() int {
} }
func (self *ListCursor) SetSelectedLineIdx(value int) { func (self *ListCursor) SetSelectedLineIdx(value int) {
self.selectedIdx = utils.Clamp(value, 0, self.list.GetItemsLength()-1) self.selectedIdx = utils.Clamp(value, 0, self.list.Len()-1)
} }
// moves the cursor up or down by the given amount // moves the cursor up or down by the given amount
@ -38,6 +38,6 @@ func (self *ListCursor) RefreshSelectedIdx() {
self.SetSelectedLineIdx(self.selectedIdx) self.SetSelectedLineIdx(self.selectedIdx)
} }
func (self *ListCursor) GetItemsLength() int { func (self *ListCursor) Len() int {
return self.list.GetItemsLength() return self.list.Len()
} }

View file

@ -50,7 +50,7 @@ func NewWorkingTreeContext(
} }
func (self *WorkingTreeContext) GetSelectedItemId() string { func (self *WorkingTreeContext) GetSelectedItemId() string {
item := self.GetSelectedFileNode() item := self.GetSelected()
if item == nil { if item == nil {
return "" return ""
} }

View file

@ -80,7 +80,7 @@ func (self *CommitFilesController) GetMouseKeybindings(opts types.KeybindingsOpt
func (self *CommitFilesController) checkSelected(callback func(*filetree.CommitFileNode) error) func() error { func (self *CommitFilesController) checkSelected(callback func(*filetree.CommitFileNode) error) func() error {
return func() error { return func() error {
selected := self.context().GetSelectedFileNode() selected := self.context().GetSelected()
if selected == nil { if selected == nil {
return nil return nil
} }
@ -98,7 +98,7 @@ func (self *CommitFilesController) context() *context.CommitFilesContext {
} }
func (self *CommitFilesController) onClickMain(opts gocui.ViewMouseBindingOpts) error { func (self *CommitFilesController) onClickMain(opts gocui.ViewMouseBindingOpts) error {
node := self.context().GetSelectedFileNode() node := self.context().GetSelected()
if node == nil { if node == nil {
return nil return nil
} }

View file

@ -216,7 +216,7 @@ func (self *FilesController) press(node *filetree.FileNode) error {
func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error { func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error {
return func() error { return func() error {
node := self.context().GetSelectedFileNode() node := self.context().GetSelected()
if node == nil { if node == nil {
return nil return nil
} }
@ -234,7 +234,7 @@ func (self *FilesController) context() *context.WorkingTreeContext {
} }
func (self *FilesController) getSelectedFile() *models.File { func (self *FilesController) getSelectedFile() *models.File {
node := self.context().GetSelectedFileNode() node := self.context().GetSelected()
if node == nil { if node == nil {
return nil return nil
} }
@ -246,7 +246,7 @@ func (self *FilesController) enter() error {
} }
func (self *FilesController) EnterFile(opts types.OnFocusOpts) error { func (self *FilesController) EnterFile(opts types.OnFocusOpts) error {
node := self.context().GetSelectedFileNode() node := self.context().GetSelected()
if node == nil { if node == nil {
return nil return nil
} }
@ -535,7 +535,7 @@ func (self *FilesController) edit(node *filetree.FileNode) error {
} }
func (self *FilesController) Open() error { func (self *FilesController) Open() error {
node := self.context().GetSelectedFileNode() node := self.context().GetSelected()
if node == nil { if node == nil {
return nil return nil
} }
@ -583,7 +583,7 @@ func (self *FilesController) createResetToUpstreamMenu() error {
} }
func (self *FilesController) handleToggleDirCollapsed() error { func (self *FilesController) handleToggleDirCollapsed() error {
node := self.context().GetSelectedFileNode() node := self.context().GetSelected()
if node == nil { if node == nil {
return nil return nil
} }

View file

@ -139,7 +139,7 @@ func (self *FilesRemoveController) ResetSubmodule(submodule *models.SubmoduleCon
func (self *FilesRemoveController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error { func (self *FilesRemoveController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error {
return func() error { return func() error {
node := self.context().GetSelectedFileNode() node := self.context().GetSelected()
if node == nil { if node == nil {
return nil return nil
} }

View file

@ -83,11 +83,11 @@ func (self *ListController) HandleNextPage() error {
} }
func (self *ListController) HandleGotoTop() error { func (self *ListController) HandleGotoTop() error {
return self.handleLineChange(-self.context.GetList().GetItemsLength()) return self.handleLineChange(-self.context.GetList().Len())
} }
func (self *ListController) HandleGotoBottom() error { func (self *ListController) HandleGotoBottom() error {
return self.handleLineChange(self.context.GetList().GetItemsLength()) return self.handleLineChange(self.context.GetList().Len())
} }
func (self *ListController) HandleClick(opts gocui.ViewMouseBindingOpts) error { func (self *ListController) HandleClick(opts gocui.ViewMouseBindingOpts) error {
@ -99,7 +99,7 @@ func (self *ListController) HandleClick(opts gocui.ViewMouseBindingOpts) error {
return err return err
} }
if newSelectedLineIdx > self.context.GetList().GetItemsLength()-1 { if newSelectedLineIdx > self.context.GetList().Len()-1 {
return nil return nil
} }

View file

@ -588,7 +588,7 @@ func (self *LocalCommitsController) gotoBottom() error {
} }
} }
self.context().SetSelectedLineIdx(self.context().GetItemsLength() - 1) self.context().SetSelectedLineIdx(self.context().Len() - 1)
return nil return nil
} }

View file

@ -9,7 +9,7 @@ import (
// list panel functions // list panel functions
func (gui *Gui) getSelectedFileNode() *filetree.FileNode { func (gui *Gui) getSelectedFileNode() *filetree.FileNode {
return gui.State.Contexts.Files.GetSelectedFileNode() return gui.State.Contexts.Files.GetSelected()
} }
func (gui *Gui) getSelectedFile() *models.File { func (gui *Gui) getSelectedFile() *models.File {

View file

@ -8,7 +8,7 @@ import (
type ICommitFileTree interface { type ICommitFileTree interface {
ITree ITree
GetItemAtIndex(index int) *CommitFileNode Get(index int) *CommitFileNode
GetFile(path string) *models.CommitFile GetFile(path string) *models.CommitFile
GetAllItems() []*CommitFileNode GetAllItems() []*CommitFileNode
GetAllFiles() []*models.CommitFile GetAllFiles() []*models.CommitFile
@ -42,7 +42,7 @@ func (self *CommitFileTree) ToggleShowTree() {
self.SetTree() self.SetTree()
} }
func (self *CommitFileTree) GetItemAtIndex(index int) *CommitFileNode { func (self *CommitFileTree) Get(index int) *CommitFileNode {
// need to traverse the three depth first until we get to the index. // need to traverse the three depth first until we get to the index.
return self.tree.GetNodeAtIndex(index+1, self.collapsedPaths) // ignoring root return self.tree.GetNodeAtIndex(index+1, self.collapsedPaths) // ignoring root
} }
@ -60,7 +60,7 @@ func (self *CommitFileTree) GetAllItems() []*CommitFileNode {
return self.tree.Flatten(self.collapsedPaths)[1:] // ignoring root return self.tree.Flatten(self.collapsedPaths)[1:] // ignoring root
} }
func (self *CommitFileTree) GetItemsLength() int { func (self *CommitFileTree) Len() int {
return self.tree.Size(self.collapsedPaths) - 1 // ignoring root return self.tree.Size(self.collapsedPaths) - 1 // ignoring root
} }

View file

@ -61,16 +61,16 @@ func (self *CommitFileTreeViewModel) SetCanRebase(canRebase bool) {
self.canRebase = canRebase self.canRebase = canRebase
} }
func (self *CommitFileTreeViewModel) GetSelectedFileNode() *CommitFileNode { func (self *CommitFileTreeViewModel) GetSelected() *CommitFileNode {
if self.GetItemsLength() == 0 { if self.Len() == 0 {
return nil return nil
} }
return self.GetItemAtIndex(self.GetSelectedLineIdx()) return self.Get(self.GetSelectedLineIdx())
} }
func (self *CommitFileTreeViewModel) GetSelectedFile() *models.CommitFile { func (self *CommitFileTreeViewModel) GetSelectedFile() *models.CommitFile {
node := self.GetSelectedFileNode() node := self.GetSelected()
if node == nil { if node == nil {
return nil return nil
} }
@ -79,7 +79,7 @@ func (self *CommitFileTreeViewModel) GetSelectedFile() *models.CommitFile {
} }
func (self *CommitFileTreeViewModel) GetSelectedPath() string { func (self *CommitFileTreeViewModel) GetSelectedPath() string {
node := self.GetSelectedFileNode() node := self.GetSelected()
if node == nil { if node == nil {
return "" return ""
} }
@ -89,7 +89,7 @@ func (self *CommitFileTreeViewModel) GetSelectedPath() string {
// duplicated from file_tree_view_model.go. Generics will help here // duplicated from file_tree_view_model.go. Generics will help here
func (self *CommitFileTreeViewModel) ToggleShowTree() { func (self *CommitFileTreeViewModel) ToggleShowTree() {
selectedNode := self.GetSelectedFileNode() selectedNode := self.GetSelected()
self.ICommitFileTree.ToggleShowTree() self.ICommitFileTree.ToggleShowTree()

View file

@ -22,7 +22,7 @@ type ITree interface {
ExpandToPath(path string) ExpandToPath(path string)
ToggleShowTree() ToggleShowTree()
GetIndexForPath(path string) (int, bool) GetIndexForPath(path string) (int, bool)
GetItemsLength() int Len() int
SetTree() SetTree()
IsCollapsed(path string) bool IsCollapsed(path string) bool
ToggleCollapsed(path string) ToggleCollapsed(path string)
@ -35,7 +35,7 @@ type IFileTree interface {
FilterFiles(test func(*models.File) bool) []*models.File FilterFiles(test func(*models.File) bool) []*models.File
SetFilter(filter FileTreeDisplayFilter) SetFilter(filter FileTreeDisplayFilter)
GetItemAtIndex(index int) *FileNode Get(index int) *FileNode
GetFile(path string) *models.File GetFile(path string) *models.File
GetAllItems() []*FileNode GetAllItems() []*FileNode
GetAllFiles() []*models.File GetAllFiles() []*models.File
@ -104,7 +104,7 @@ func (self *FileTree) ToggleShowTree() {
self.SetTree() self.SetTree()
} }
func (self *FileTree) GetItemAtIndex(index int) *FileNode { func (self *FileTree) Get(index int) *FileNode {
// need to traverse the three depth first until we get to the index. // need to traverse the three depth first until we get to the index.
return self.tree.GetNodeAtIndex(index+1, self.collapsedPaths) // ignoring root return self.tree.GetNodeAtIndex(index+1, self.collapsedPaths) // ignoring root
} }
@ -135,7 +135,7 @@ func (self *FileTree) GetAllItems() []*FileNode {
return self.tree.Flatten(self.collapsedPaths)[1:] // ignoring root return self.tree.Flatten(self.collapsedPaths)[1:] // ignoring root
} }
func (self *FileTree) GetItemsLength() int { func (self *FileTree) Len() int {
return self.tree.Size(self.collapsedPaths) - 1 // ignoring root return self.tree.Size(self.collapsedPaths) - 1 // ignoring root
} }

View file

@ -35,16 +35,16 @@ func NewFileTreeViewModel(getFiles func() []*models.File, log *logrus.Entry, sho
} }
} }
func (self *FileTreeViewModel) GetSelectedFileNode() *FileNode { func (self *FileTreeViewModel) GetSelected() *FileNode {
if self.GetItemsLength() == 0 { if self.Len() == 0 {
return nil return nil
} }
return self.GetItemAtIndex(self.GetSelectedLineIdx()) return self.Get(self.GetSelectedLineIdx())
} }
func (self *FileTreeViewModel) GetSelectedFile() *models.File { func (self *FileTreeViewModel) GetSelectedFile() *models.File {
node := self.GetSelectedFileNode() node := self.GetSelected()
if node == nil { if node == nil {
return nil return nil
} }
@ -53,7 +53,7 @@ func (self *FileTreeViewModel) GetSelectedFile() *models.File {
} }
func (self *FileTreeViewModel) GetSelectedPath() string { func (self *FileTreeViewModel) GetSelectedPath() string {
node := self.GetSelectedFileNode() node := self.GetSelected()
if node == nil { if node == nil {
return "" return ""
} }
@ -63,7 +63,7 @@ func (self *FileTreeViewModel) GetSelectedPath() string {
func (self *FileTreeViewModel) SetTree() { func (self *FileTreeViewModel) SetTree() {
newFiles := self.GetAllFiles() newFiles := self.GetAllFiles()
selectedNode := self.GetSelectedFileNode() selectedNode := self.GetSelected()
// for when you stage the old file of a rename and the new file is in a collapsed dir // for when you stage the old file of a rename and the new file is in a collapsed dir
for _, file := range newFiles { for _, file := range newFiles {
@ -135,7 +135,7 @@ func (self *FileTreeViewModel) SetFilter(filter FileTreeDisplayFilter) {
// If we're going from tree to flat and we have a file selected we want to select that. // If we're going from tree to flat and we have a file selected we want to select that.
// If instead we've selected a directory we need to select the first file in that directory. // If instead we've selected a directory we need to select the first file in that directory.
func (self *FileTreeViewModel) ToggleShowTree() { func (self *FileTreeViewModel) ToggleShowTree() {
selectedNode := self.GetSelectedFileNode() selectedNode := self.GetSelected()
self.IFileTree.ToggleShowTree() self.IFileTree.ToggleShowTree()

View file

@ -16,7 +16,7 @@ func (gui *Gui) handleCreateFilteringMenuPanel() error {
fileName = node.GetPath() fileName = node.GetPath()
} }
case gui.State.Contexts.CommitFiles: case gui.State.Contexts.CommitFiles:
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode() node := gui.State.Contexts.CommitFiles.GetSelected()
if node != nil { if node != nil {
fileName = node.GetPath() fileName = node.GetPath()
} }

View file

@ -230,7 +230,7 @@ func (gui *Gui) commitFilesListContext() *context.CommitFilesContext {
func() []*models.CommitFile { return gui.State.Model.CommitFiles }, func() []*models.CommitFile { return gui.State.Model.CommitFiles },
gui.Views.CommitFiles, gui.Views.CommitFiles,
func(startIdx int, length int) [][]string { func(startIdx int, length int) [][]string {
if gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.GetItemsLength() == 0 { if gui.State.Contexts.CommitFiles.CommitFileTreeViewModel.Len() == 0 {
return [][]string{{style.FgRed.Sprint("(none)")}} return [][]string{{style.FgRed.Sprint("(none)")}}
} }

View file

@ -13,7 +13,7 @@ func (gui *Gui) refreshPatchBuildingPanel(selectedLineIdx int) error {
gui.Views.Secondary.Title = "Custom Patch" gui.Views.Secondary.Title = "Custom Patch"
// get diff from commit file that's currently selected // get diff from commit file that's currently selected
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode() node := gui.State.Contexts.CommitFiles.GetSelected()
if node == nil { if node == nil {
return nil return nil
} }
@ -74,7 +74,7 @@ func (gui *Gui) handleToggleSelectionForPatch() error {
} }
// add range of lines to those set for the file // add range of lines to those set for the file
node := gui.State.Contexts.CommitFiles.GetSelectedFileNode() node := gui.State.Contexts.CommitFiles.GetSelected()
if node == nil { if node == nil {
return nil return nil
} }

View file

@ -109,7 +109,7 @@ type IController interface {
type IList interface { type IList interface {
IListCursor IListCursor
GetItemsLength() int Len() int
} }
type IListCursor interface { type IListCursor interface {