mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-07-30 03:23:08 +03:00
Enforce single-item selection in various actions
We want to show an error when the user tries to invoke an action that expects only a single item to be selected. We're using the GetDisabledReason field to enforce this (as well as DisabledReason on menu items). I've created a ListControllerTrait to store some shared convenience functions for this.
This commit is contained in:
@ -17,48 +17,61 @@ import (
|
||||
|
||||
type BranchesController struct {
|
||||
baseController
|
||||
*ListControllerTrait[*models.Branch]
|
||||
c *ControllerCommon
|
||||
}
|
||||
|
||||
var _ types.IController = &BranchesController{}
|
||||
|
||||
func NewBranchesController(
|
||||
common *ControllerCommon,
|
||||
c *ControllerCommon,
|
||||
) *BranchesController {
|
||||
return &BranchesController{
|
||||
baseController: baseController{},
|
||||
c: common,
|
||||
c: c,
|
||||
ListControllerTrait: NewListControllerTrait[*models.Branch](
|
||||
c,
|
||||
c.Contexts().Branches,
|
||||
c.Contexts().Branches.GetSelected,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||
return []*types.Binding{
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||
Handler: self.checkSelected(self.press),
|
||||
GetDisabledReason: self.getDisabledReasonForPress,
|
||||
Description: self.c.Tr.Checkout,
|
||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||
Handler: self.withItem(self.press),
|
||||
GetDisabledReason: self.require(
|
||||
self.singleItemSelected(),
|
||||
self.notPulling,
|
||||
),
|
||||
Description: self.c.Tr.Checkout,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.New),
|
||||
Handler: self.checkSelected(self.newBranch),
|
||||
Description: self.c.Tr.NewBranch,
|
||||
Key: opts.GetKey(opts.Config.Universal.New),
|
||||
Handler: self.withItem(self.newBranch),
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.NewBranch,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.CreatePullRequest),
|
||||
Handler: self.checkSelected(self.handleCreatePullRequest),
|
||||
Description: self.c.Tr.CreatePullRequest,
|
||||
Key: opts.GetKey(opts.Config.Branches.CreatePullRequest),
|
||||
Handler: self.withItem(self.handleCreatePullRequest),
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.CreatePullRequest,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.ViewPullRequestOptions),
|
||||
Handler: self.checkSelected(self.handleCreatePullRequestMenu),
|
||||
Description: self.c.Tr.CreatePullRequestOptions,
|
||||
OpensMenu: true,
|
||||
Key: opts.GetKey(opts.Config.Branches.ViewPullRequestOptions),
|
||||
Handler: self.withItem(self.handleCreatePullRequestMenu),
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.CreatePullRequestOptions,
|
||||
OpensMenu: true,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.CopyPullRequestURL),
|
||||
Handler: self.copyPullRequestURL,
|
||||
Description: self.c.Tr.CopyPullRequestURL,
|
||||
Key: opts.GetKey(opts.Config.Branches.CopyPullRequestURL),
|
||||
Handler: self.copyPullRequestURL,
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.CopyPullRequestURL,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.CheckoutBranchByName),
|
||||
@ -66,60 +79,69 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
||||
Description: self.c.Tr.CheckoutByName,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.ForceCheckoutBranch),
|
||||
Handler: self.forceCheckout,
|
||||
Description: self.c.Tr.ForceCheckout,
|
||||
Key: opts.GetKey(opts.Config.Branches.ForceCheckoutBranch),
|
||||
Handler: self.forceCheckout,
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.ForceCheckout,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||
Handler: self.checkSelectedAndReal(self.delete),
|
||||
Description: self.c.Tr.ViewDeleteOptions,
|
||||
OpensMenu: true,
|
||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||
Handler: self.withItem(self.delete),
|
||||
GetDisabledReason: self.require(self.singleItemSelected(self.branchIsReal)),
|
||||
Description: self.c.Tr.ViewDeleteOptions,
|
||||
OpensMenu: true,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
||||
Handler: opts.Guards.OutsideFilterMode(self.rebase),
|
||||
Description: self.c.Tr.RebaseBranch,
|
||||
GetDisabledReason: self.getDisabledReasonForRebase,
|
||||
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
||||
Handler: opts.Guards.OutsideFilterMode(self.rebase),
|
||||
GetDisabledReason: self.require(
|
||||
self.singleItemSelected(self.notRebasingOntoSelf),
|
||||
),
|
||||
Description: self.c.Tr.RebaseBranch,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
||||
Handler: opts.Guards.OutsideFilterMode(self.merge),
|
||||
Description: self.c.Tr.MergeIntoCurrentBranch,
|
||||
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
||||
Handler: opts.Guards.OutsideFilterMode(self.merge),
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.MergeIntoCurrentBranch,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.FastForward),
|
||||
Handler: self.checkSelectedAndReal(self.fastForward),
|
||||
Description: self.c.Tr.FastForward,
|
||||
Key: opts.GetKey(opts.Config.Branches.FastForward),
|
||||
Handler: self.withItem(self.fastForward),
|
||||
GetDisabledReason: self.require(self.singleItemSelected(self.branchIsReal)),
|
||||
Description: self.c.Tr.FastForward,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.CreateTag),
|
||||
Handler: self.checkSelected(self.createTag),
|
||||
Description: self.c.Tr.CreateTag,
|
||||
Key: opts.GetKey(opts.Config.Branches.CreateTag),
|
||||
Handler: self.withItem(self.createTag),
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.CreateTag,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.SortOrder),
|
||||
Handler: self.createSortMenu,
|
||||
Description: self.c.Tr.SortOrder,
|
||||
OpensMenu: true,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||
Handler: self.checkSelected(self.createResetMenu),
|
||||
Description: self.c.Tr.ViewResetOptions,
|
||||
OpensMenu: true,
|
||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||
Handler: self.withItem(self.createResetMenu),
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.ViewResetOptions,
|
||||
OpensMenu: true,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.RenameBranch),
|
||||
Handler: self.checkSelectedAndReal(self.rename),
|
||||
Description: self.c.Tr.RenameBranch,
|
||||
Key: opts.GetKey(opts.Config.Branches.RenameBranch),
|
||||
Handler: self.withItem(self.rename),
|
||||
GetDisabledReason: self.require(self.singleItemSelected(self.branchIsReal)),
|
||||
Description: self.c.Tr.RenameBranch,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
||||
Handler: self.checkSelected(self.viewUpstreamOptions),
|
||||
Description: self.c.Tr.ViewBranchUpstreamOptions,
|
||||
Tooltip: self.c.Tr.ViewBranchUpstreamOptionsTooltip,
|
||||
OpensMenu: true,
|
||||
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
||||
Handler: self.withItem(self.viewUpstreamOptions),
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
Description: self.c.Tr.ViewBranchUpstreamOptions,
|
||||
Tooltip: self.c.Tr.ViewBranchUpstreamOptionsTooltip,
|
||||
OpensMenu: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -308,7 +330,7 @@ func (self *BranchesController) press(selectedBranch *models.Branch) error {
|
||||
return self.c.Helpers().Refs.CheckoutRef(selectedBranch.Name, types.CheckoutRefOptions{})
|
||||
}
|
||||
|
||||
func (self *BranchesController) getDisabledReasonForPress() *types.DisabledReason {
|
||||
func (self *BranchesController) notPulling() *types.DisabledReason {
|
||||
currentBranch := self.c.Helpers().Refs.GetCheckedOutRef()
|
||||
if currentBranch != nil {
|
||||
op := self.c.State().GetItemOperation(currentBranch)
|
||||
@ -561,8 +583,8 @@ func (self *BranchesController) rebase() error {
|
||||
return self.c.Helpers().MergeAndRebase.RebaseOntoRef(selectedBranchName)
|
||||
}
|
||||
|
||||
func (self *BranchesController) getDisabledReasonForRebase() *types.DisabledReason {
|
||||
selectedBranchName := self.context().GetSelected().Name
|
||||
func (self *BranchesController) notRebasingOntoSelf(branch *models.Branch) *types.DisabledReason {
|
||||
selectedBranchName := branch.Name
|
||||
checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef().Name
|
||||
if selectedBranchName == checkedOutBranch {
|
||||
return &types.DisabledReason{Text: self.c.Tr.CantRebaseOntoSelf}
|
||||
@ -753,24 +775,10 @@ func (self *BranchesController) createPullRequest(from string, to string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *BranchesController) checkSelected(callback func(*models.Branch) error) func() error {
|
||||
return func() error {
|
||||
selectedItem := self.context().GetSelected()
|
||||
if selectedItem == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return callback(selectedItem)
|
||||
func (self *BranchesController) branchIsReal(branch *models.Branch) *types.DisabledReason {
|
||||
if !branch.IsRealBranch() {
|
||||
return &types.DisabledReason{Text: self.c.Tr.SelectedItemIsNotABranch}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *BranchesController) checkSelectedAndReal(callback func(*models.Branch) error) func() error {
|
||||
return func() error {
|
||||
selectedItem := self.context().GetSelected()
|
||||
if selectedItem == nil || !selectedItem.IsRealBranch() {
|
||||
return nil
|
||||
}
|
||||
|
||||
return callback(selectedItem)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user