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

Set groundwork for better disabled reasons with range select

Something dumb that we're currently doing is expecting list items
to define an ID method which returns a string. We use that when copying
items to clipboard with ctrl+o and when getting a ref name for diffing.

This commit gets us a little deeper into that hole by explicitly requiring
list items to implement that method so that we can easily use the new
helper functions in list_controller_trait.go.

In future we need to just remove the whole ID thing entirely but I'm too
lazy to do that right now.
This commit is contained in:
Jesse Duffield
2024-01-16 17:28:14 +11:00
parent a67ad44781
commit a5f3515ad8
43 changed files with 237 additions and 154 deletions

View File

@ -16,6 +16,7 @@ type ContainsCommits interface {
types.Context
types.IListContext
GetSelected() *models.Commit
GetSelectedItems() ([]*models.Commit, int, int)
GetCommits() []*models.Commit
GetSelectedLineIdx() int
}
@ -36,6 +37,7 @@ func NewBasicCommitsController(c *ControllerCommon, context ContainsCommits) *Ba
c,
context,
context.GetSelected,
context.GetSelectedItems,
),
}
}

View File

@ -30,6 +30,7 @@ func NewBisectController(
c,
c.Contexts().LocalCommits,
c.Contexts().LocalCommits.GetSelected,
c.Contexts().LocalCommits.GetSelectedItems,
),
}
}

View File

@ -33,6 +33,7 @@ func NewBranchesController(
c,
c.Contexts().Branches,
c.Contexts().Branches.GetSelected,
c.Contexts().Branches.GetSelectedItems,
),
}
}

View File

@ -28,6 +28,7 @@ func NewCommitFilesController(
c,
c.Contexts().CommitFiles,
c.Contexts().CommitFiles.GetSelected,
c.Contexts().CommitFiles.GetSelectedItems,
),
}
}

View File

@ -28,6 +28,7 @@ func NewFilesController(
c,
c.Contexts().Files,
c.Contexts().Files.GetSelected,
c.Contexts().Files.GetSelectedItems,
),
}
}

View File

@ -28,6 +28,7 @@ func NewFilesRemoveController(
c,
c.Contexts().Files,
c.Contexts().Files.GetSelected,
c.Contexts().Files.GetSelectedItems,
),
}
}

View File

@ -25,6 +25,7 @@ func NewGitFlowController(
c,
c.Contexts().Branches,
c.Contexts().Branches.GetSelected,
c.Contexts().Branches.GetSelectedItems,
),
c: c,
}

View File

@ -6,20 +6,23 @@ import "github.com/jesseduffield/lazygit/pkg/gui/types"
// ensuring a single item is selected, etc.
type ListControllerTrait[T comparable] struct {
c *ControllerCommon
context types.IListContext
getSelected func() T
c *ControllerCommon
context types.IListContext
getSelectedItem func() T
getSelectedItems func() ([]T, int, int)
}
func NewListControllerTrait[T comparable](
c *ControllerCommon,
context types.IListContext,
getSelected func() T,
getSelectedItems func() ([]T, int, int),
) *ListControllerTrait[T] {
return &ListControllerTrait[T]{
c: c,
context: context,
getSelected: getSelected,
c: c,
context: context,
getSelectedItem: getSelected,
getSelectedItems: getSelectedItems,
}
}
@ -47,7 +50,7 @@ func (self *ListControllerTrait[T]) singleItemSelected(callbacks ...func(T) *typ
}
var zeroValue T
item := self.getSelected()
item := self.getSelectedItem()
if item == zeroValue {
return &types.DisabledReason{Text: self.c.Tr.NoItemSelected}
}
@ -62,11 +65,46 @@ func (self *ListControllerTrait[T]) singleItemSelected(callbacks ...func(T) *typ
}
}
// Ensures that at least one item is selected.
func (self *ListControllerTrait[T]) itemRangeSelected(callbacks ...func([]T, int, int) *types.DisabledReason) func() *types.DisabledReason {
return func() *types.DisabledReason {
items, startIdx, endIdx := self.getSelectedItems()
if len(items) == 0 {
return &types.DisabledReason{Text: self.c.Tr.NoItemSelected}
}
for _, callback := range callbacks {
if reason := callback(items, startIdx, endIdx); reason != nil {
return reason
}
}
return nil
}
}
func (self *ListControllerTrait[T]) itemsSelected(callbacks ...func([]T) *types.DisabledReason) func() *types.DisabledReason { //nolint:unused
return func() *types.DisabledReason {
items, _, _ := self.getSelectedItems()
if len(items) == 0 {
return &types.DisabledReason{Text: self.c.Tr.NoItemSelected}
}
for _, callback := range callbacks {
if reason := callback(items); reason != nil {
return reason
}
}
return nil
}
}
// Passes the selected item to the callback. Used for handler functions.
func (self *ListControllerTrait[T]) withItem(callback func(T) error) func() error {
return func() error {
var zeroValue T
commit := self.getSelected()
commit := self.getSelectedItem()
if commit == zeroValue {
return self.c.ErrorMsg(self.c.Tr.NoItemSelected)
}
@ -75,12 +113,35 @@ func (self *ListControllerTrait[T]) withItem(callback func(T) error) func() erro
}
}
func (self *ListControllerTrait[T]) withItems(callback func([]T) error) func() error {
return func() error {
items, _, _ := self.getSelectedItems()
if len(items) == 0 {
return self.c.ErrorMsg(self.c.Tr.NoItemSelected)
}
return callback(items)
}
}
// like withItems but also passes the start and end index of the selection
func (self *ListControllerTrait[T]) withItemsRange(callback func([]T, int, int) error) func() error {
return func() error {
items, startIdx, endIdx := self.getSelectedItems()
if len(items) == 0 {
return self.c.ErrorMsg(self.c.Tr.NoItemSelected)
}
return callback(items, startIdx, endIdx)
}
}
// Like withItem, but doesn't show an error message if no item is selected.
// Use this for click actions (it's a no-op to click empty space)
func (self *ListControllerTrait[T]) withItemGraceful(callback func(T) error) func() error {
return func() error {
var zeroValue T
commit := self.getSelected()
commit := self.getSelectedItem()
if commit == zeroValue {
return nil
}

View File

@ -22,6 +22,7 @@ func NewMenuController(
c,
c.Contexts().Menu,
c.Contexts().Menu.GetSelected,
c.Contexts().Menu.GetSelectedItems,
),
c: c,
}

View File

@ -23,6 +23,7 @@ func NewReflogCommitsController(
c,
c.Contexts().ReflogCommits,
c.Contexts().ReflogCommits.GetSelected,
c.Contexts().ReflogCommits.GetSelectedItems,
),
c: c,
}

View File

@ -26,6 +26,7 @@ func NewRemoteBranchesController(
c,
c.Contexts().RemoteBranches,
c.Contexts().RemoteBranches.GetSelected,
c.Contexts().RemoteBranches.GetSelectedItems,
),
c: c,
}

View File

@ -32,6 +32,7 @@ func NewRemotesController(
c,
c.Contexts().Remotes,
c.Contexts().Remotes.GetSelected,
c.Contexts().Remotes.GetSelectedItems,
),
c: c,
setRemoteBranches: setRemoteBranches,

View File

@ -24,6 +24,7 @@ func NewStashController(
c,
c.Contexts().Stash,
c.Contexts().Stash.GetSelected,
c.Contexts().Stash.GetSelectedItems,
),
c: c,
}

View File

@ -24,6 +24,7 @@ func NewSubCommitsController(
c,
c.Contexts().SubCommits,
c.Contexts().SubCommits.GetSelected,
c.Contexts().SubCommits.GetSelectedItems,
),
c: c,
}

View File

@ -29,6 +29,7 @@ func NewSubmodulesController(
c,
c.Contexts().Submodules,
c.Contexts().Submodules.GetSelected,
c.Contexts().Submodules.GetSelectedItems,
),
c: c,
}

View File

@ -22,6 +22,7 @@ func NewSuggestionsController(
c,
c.Contexts().Suggestions,
c.Contexts().Suggestions.GetSelected,
c.Contexts().Suggestions.GetSelectedItems,
),
c: c,
}

View File

@ -36,6 +36,9 @@ func NewSwitchToDiffFilesController(
c,
context,
context.GetSelectedRef,
func() ([]types.Ref, int, int) {
panic("Not implemented")
},
),
c: c,
context: context,

View File

@ -32,6 +32,9 @@ func NewSwitchToSubCommitsController(
c,
context,
context.GetSelectedRef,
func() ([]types.Ref, int, int) {
panic("Not implemented")
},
),
c: c,
context: context,

View File

@ -25,6 +25,7 @@ func NewTagsController(
c,
c.Contexts().Tags,
c.Contexts().Tags.GetSelected,
c.Contexts().Tags.GetSelectedItems,
),
c: c,
}

View File

@ -26,6 +26,7 @@ func NewWorktreeOptionsController(c *ControllerCommon, context CanViewWorktreeOp
c,
context,
context.GetSelectedItemId,
context.GetSelectedItemIds,
),
c: c,
context: context,

View File

@ -28,6 +28,7 @@ func NewWorktreesController(
c,
c.Contexts().Worktrees,
c.Contexts().Worktrees.GetSelected,
c.Contexts().Worktrees.GetSelectedItems,
),
c: c,
}