mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-31 23:19:40 +02: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:
parent
280b4d60f8
commit
51fb82d6bf
@ -114,10 +114,18 @@ func (self *ListCursor) CancelRangeSelect() {
|
|||||||
self.rangeSelectMode = RangeSelectModeNone
|
self.rangeSelectMode = RangeSelectModeNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if we are in range select mode. Note that we may be in range select
|
||||||
|
// mode and still only selecting a single item. See AreMultipleItemsSelected below.
|
||||||
func (self *ListCursor) IsSelectingRange() bool {
|
func (self *ListCursor) IsSelectingRange() bool {
|
||||||
return self.rangeSelectMode != RangeSelectModeNone
|
return self.rangeSelectMode != RangeSelectModeNone
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if we are in range select mode and selecting multiple items
|
||||||
|
func (self *ListCursor) AreMultipleItemsSelected() bool {
|
||||||
|
startIdx, endIdx := self.GetSelectionRange()
|
||||||
|
return startIdx != endIdx
|
||||||
|
}
|
||||||
|
|
||||||
func (self *ListCursor) GetSelectionRange() (int, int) {
|
func (self *ListCursor) GetSelectionRange() (int, int) {
|
||||||
if self.IsSelectingRange() {
|
if self.IsSelectingRange() {
|
||||||
return utils.MinMax(self.selectedIdx, self.rangeStartIdx)
|
return utils.MinMax(self.selectedIdx, self.rangeStartIdx)
|
||||||
|
@ -22,50 +22,61 @@ type ContainsCommits interface {
|
|||||||
|
|
||||||
type BasicCommitsController struct {
|
type BasicCommitsController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Commit]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
context ContainsCommits
|
context ContainsCommits
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBasicCommitsController(controllerCommon *ControllerCommon, context ContainsCommits) *BasicCommitsController {
|
func NewBasicCommitsController(c *ControllerCommon, context ContainsCommits) *BasicCommitsController {
|
||||||
return &BasicCommitsController{
|
return &BasicCommitsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: controllerCommon,
|
c: c,
|
||||||
context: context,
|
context: context,
|
||||||
|
ListControllerTrait: NewListControllerTrait[*models.Commit](
|
||||||
|
c,
|
||||||
|
context,
|
||||||
|
context.GetSelected,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CheckoutCommit),
|
Key: opts.GetKey(opts.Config.Commits.CheckoutCommit),
|
||||||
Handler: self.checkSelected(self.checkout),
|
Handler: self.withItem(self.checkout),
|
||||||
Description: self.c.Tr.CheckoutCommit,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.CheckoutCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CopyCommitAttributeToClipboard),
|
Key: opts.GetKey(opts.Config.Commits.CopyCommitAttributeToClipboard),
|
||||||
Handler: self.checkSelected(self.copyCommitAttribute),
|
Handler: self.withItem(self.copyCommitAttribute),
|
||||||
Description: self.c.Tr.CopyCommitAttributeToClipboard,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.CopyCommitAttributeToClipboard,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.OpenInBrowser),
|
Key: opts.GetKey(opts.Config.Commits.OpenInBrowser),
|
||||||
Handler: self.checkSelected(self.openInBrowser),
|
Handler: self.withItem(self.openInBrowser),
|
||||||
Description: self.c.Tr.OpenCommitInBrowser,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.OpenCommitInBrowser,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.checkSelected(self.newBranch),
|
Handler: self.withItem(self.newBranch),
|
||||||
Description: self.c.Tr.CreateNewBranchFromCommit,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.CreateNewBranchFromCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||||
Handler: self.checkSelected(self.createResetMenu),
|
Handler: self.withItem(self.createResetMenu),
|
||||||
Description: self.c.Tr.ViewResetOptions,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.ViewResetOptions,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CherryPickCopy),
|
Key: opts.GetKey(opts.Config.Commits.CherryPickCopy),
|
||||||
Handler: self.checkSelected(self.copyRange),
|
Handler: self.withItem(self.copyRange),
|
||||||
Description: self.c.Tr.CherryPickCopy,
|
Description: self.c.Tr.CherryPickCopy,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -74,30 +85,16 @@ func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
Description: self.c.Tr.ResetCherryPick,
|
Description: self.c.Tr.ResetCherryPick,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
||||||
Handler: self.checkSelected(self.openDiffTool),
|
Handler: self.withItem(self.openDiffTool),
|
||||||
Description: self.c.Tr.OpenDiffTool,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.OpenDiffTool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return bindings
|
return bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *BasicCommitsController) checkSelected(callback func(*models.Commit) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
commit := self.context.GetSelected()
|
|
||||||
if commit == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(commit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *BasicCommitsController) Context() types.Context {
|
|
||||||
return self.context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *BasicCommitsController) copyCommitAttribute(commit *models.Commit) error {
|
func (self *BasicCommitsController) copyCommitAttribute(commit *models.Commit) error {
|
||||||
return self.c.Menu(types.CreateMenuOptions{
|
return self.c.Menu(types.CreateMenuOptions{
|
||||||
Title: self.c.Tr.Actions.CopyCommitAttributeToClipboard,
|
Title: self.c.Tr.Actions.CopyCommitAttributeToClipboard,
|
||||||
|
@ -14,17 +14,23 @@ import (
|
|||||||
|
|
||||||
type BisectController struct {
|
type BisectController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Commit]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &BisectController{}
|
var _ types.IController = &BisectController{}
|
||||||
|
|
||||||
func NewBisectController(
|
func NewBisectController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *BisectController {
|
) *BisectController {
|
||||||
return &BisectController{
|
return &BisectController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
|
ListControllerTrait: NewListControllerTrait[*models.Commit](
|
||||||
|
c,
|
||||||
|
c.Contexts().LocalCommits,
|
||||||
|
c.Contexts().LocalCommits.GetSelected,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,7 +38,7 @@ func (self *BisectController) GetKeybindings(opts types.KeybindingsOpts) []*type
|
|||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewBisectOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewBisectOptions),
|
||||||
Handler: opts.Guards.OutsideFilterMode(self.checkSelected(self.openMenu)),
|
Handler: opts.Guards.OutsideFilterMode(self.withItem(self.openMenu)),
|
||||||
Description: self.c.Tr.ViewBisectOptions,
|
Description: self.c.Tr.ViewBisectOptions,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
@ -70,9 +76,19 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
|
|||||||
// If we have a current sha already, then we always want to use that one. If
|
// If we have a current sha already, then we always want to use that one. If
|
||||||
// not, we're still picking the initial commits before we really start, so
|
// not, we're still picking the initial commits before we really start, so
|
||||||
// use the selected commit in that case.
|
// use the selected commit in that case.
|
||||||
shaToMark := lo.Ternary(info.GetCurrentSha() != "", info.GetCurrentSha(), commit.Sha)
|
|
||||||
|
bisecting := info.GetCurrentSha() != ""
|
||||||
|
shaToMark := lo.Ternary(bisecting, info.GetCurrentSha(), commit.Sha)
|
||||||
shortShaToMark := utils.ShortSha(shaToMark)
|
shortShaToMark := utils.ShortSha(shaToMark)
|
||||||
|
|
||||||
|
// For marking a commit as bad, when we're not already bisecting, we require
|
||||||
|
// a single item selected, but once we are bisecting, it doesn't matter because
|
||||||
|
// the action applies to the HEAD commit rather than the selected commit.
|
||||||
|
var singleItemIfNotBisecting *types.DisabledReason
|
||||||
|
if !bisecting {
|
||||||
|
singleItemIfNotBisecting = self.require(self.singleItemSelected())()
|
||||||
|
}
|
||||||
|
|
||||||
menuItems := []*types.MenuItem{
|
menuItems := []*types.MenuItem{
|
||||||
{
|
{
|
||||||
Label: fmt.Sprintf(self.c.Tr.Bisect.Mark, shortShaToMark, info.NewTerm()),
|
Label: fmt.Sprintf(self.c.Tr.Bisect.Mark, shortShaToMark, info.NewTerm()),
|
||||||
@ -84,7 +100,8 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
|
|||||||
|
|
||||||
return self.afterMark(selectCurrentAfter, waitToReselect)
|
return self.afterMark(selectCurrentAfter, waitToReselect)
|
||||||
},
|
},
|
||||||
Key: 'b',
|
DisabledReason: singleItemIfNotBisecting,
|
||||||
|
Key: 'b',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: fmt.Sprintf(self.c.Tr.Bisect.Mark, shortShaToMark, info.OldTerm()),
|
Label: fmt.Sprintf(self.c.Tr.Bisect.Mark, shortShaToMark, info.OldTerm()),
|
||||||
@ -96,7 +113,8 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
|
|||||||
|
|
||||||
return self.afterMark(selectCurrentAfter, waitToReselect)
|
return self.afterMark(selectCurrentAfter, waitToReselect)
|
||||||
},
|
},
|
||||||
Key: 'g',
|
DisabledReason: singleItemIfNotBisecting,
|
||||||
|
Key: 'g',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: fmt.Sprintf(self.c.Tr.Bisect.SkipCurrent, shortShaToMark),
|
Label: fmt.Sprintf(self.c.Tr.Bisect.SkipCurrent, shortShaToMark),
|
||||||
@ -108,7 +126,8 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
|
|||||||
|
|
||||||
return self.afterMark(selectCurrentAfter, waitToReselect)
|
return self.afterMark(selectCurrentAfter, waitToReselect)
|
||||||
},
|
},
|
||||||
Key: 's',
|
DisabledReason: singleItemIfNotBisecting,
|
||||||
|
Key: 's',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if info.GetCurrentSha() != "" && info.GetCurrentSha() != commit.Sha {
|
if info.GetCurrentSha() != "" && info.GetCurrentSha() != commit.Sha {
|
||||||
@ -122,7 +141,8 @@ func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, c
|
|||||||
|
|
||||||
return self.afterMark(selectCurrentAfter, waitToReselect)
|
return self.afterMark(selectCurrentAfter, waitToReselect)
|
||||||
},
|
},
|
||||||
Key: 'S',
|
DisabledReason: self.require(self.singleItemSelected())(),
|
||||||
|
Key: 'S',
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
menuItems = append(menuItems, lo.ToPtr(types.MenuItem{
|
menuItems = append(menuItems, lo.ToPtr(types.MenuItem{
|
||||||
@ -157,7 +177,8 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo,
|
|||||||
|
|
||||||
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
|
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
|
||||||
},
|
},
|
||||||
Key: 'b',
|
DisabledReason: self.require(self.singleItemSelected())(),
|
||||||
|
Key: 'b',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: fmt.Sprintf(self.c.Tr.Bisect.MarkStart, commit.ShortSha(), info.OldTerm()),
|
Label: fmt.Sprintf(self.c.Tr.Bisect.MarkStart, commit.ShortSha(), info.OldTerm()),
|
||||||
@ -173,7 +194,8 @@ func (self *BisectController) openStartBisectMenu(info *git_commands.BisectInfo,
|
|||||||
|
|
||||||
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
|
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
|
||||||
},
|
},
|
||||||
Key: 'g',
|
DisabledReason: self.require(self.singleItemSelected())(),
|
||||||
|
Key: 'g',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: self.c.Tr.Bisect.ChooseTerms,
|
Label: self.c.Tr.Bisect.ChooseTerms,
|
||||||
@ -273,21 +295,6 @@ func (self *BisectController) selectCurrentBisectCommit() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *BisectController) checkSelected(callback func(*models.Commit) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
commit := self.context().GetSelected()
|
|
||||||
if commit == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(commit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *BisectController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *BisectController) context() *context.LocalCommitsContext {
|
func (self *BisectController) context() *context.LocalCommitsContext {
|
||||||
return self.c.Contexts().LocalCommits
|
return self.c.Contexts().LocalCommits
|
||||||
}
|
}
|
||||||
|
@ -17,48 +17,61 @@ import (
|
|||||||
|
|
||||||
type BranchesController struct {
|
type BranchesController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Branch]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &BranchesController{}
|
var _ types.IController = &BranchesController{}
|
||||||
|
|
||||||
func NewBranchesController(
|
func NewBranchesController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *BranchesController {
|
) *BranchesController {
|
||||||
return &BranchesController{
|
return &BranchesController{
|
||||||
baseController: baseController{},
|
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 {
|
func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
return []*types.Binding{
|
return []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.checkSelected(self.press),
|
Handler: self.withItem(self.press),
|
||||||
GetDisabledReason: self.getDisabledReasonForPress,
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.Checkout,
|
self.singleItemSelected(),
|
||||||
|
self.notPulling,
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.Checkout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.checkSelected(self.newBranch),
|
Handler: self.withItem(self.newBranch),
|
||||||
Description: self.c.Tr.NewBranch,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.NewBranch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.CreatePullRequest),
|
Key: opts.GetKey(opts.Config.Branches.CreatePullRequest),
|
||||||
Handler: self.checkSelected(self.handleCreatePullRequest),
|
Handler: self.withItem(self.handleCreatePullRequest),
|
||||||
Description: self.c.Tr.CreatePullRequest,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.CreatePullRequest,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.ViewPullRequestOptions),
|
Key: opts.GetKey(opts.Config.Branches.ViewPullRequestOptions),
|
||||||
Handler: self.checkSelected(self.handleCreatePullRequestMenu),
|
Handler: self.withItem(self.handleCreatePullRequestMenu),
|
||||||
Description: self.c.Tr.CreatePullRequestOptions,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.CreatePullRequestOptions,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.CopyPullRequestURL),
|
Key: opts.GetKey(opts.Config.Branches.CopyPullRequestURL),
|
||||||
Handler: self.copyPullRequestURL,
|
Handler: self.copyPullRequestURL,
|
||||||
Description: self.c.Tr.CopyPullRequestURL,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.CopyPullRequestURL,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.CheckoutBranchByName),
|
Key: opts.GetKey(opts.Config.Branches.CheckoutBranchByName),
|
||||||
@ -66,60 +79,69 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||||||
Description: self.c.Tr.CheckoutByName,
|
Description: self.c.Tr.CheckoutByName,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.ForceCheckoutBranch),
|
Key: opts.GetKey(opts.Config.Branches.ForceCheckoutBranch),
|
||||||
Handler: self.forceCheckout,
|
Handler: self.forceCheckout,
|
||||||
Description: self.c.Tr.ForceCheckout,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.ForceCheckout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelectedAndReal(self.delete),
|
Handler: self.withItem(self.delete),
|
||||||
Description: self.c.Tr.ViewDeleteOptions,
|
GetDisabledReason: self.require(self.singleItemSelected(self.branchIsReal)),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.ViewDeleteOptions,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
||||||
Handler: opts.Guards.OutsideFilterMode(self.rebase),
|
Handler: opts.Guards.OutsideFilterMode(self.rebase),
|
||||||
Description: self.c.Tr.RebaseBranch,
|
GetDisabledReason: self.require(
|
||||||
GetDisabledReason: self.getDisabledReasonForRebase,
|
self.singleItemSelected(self.notRebasingOntoSelf),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.RebaseBranch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
||||||
Handler: opts.Guards.OutsideFilterMode(self.merge),
|
Handler: opts.Guards.OutsideFilterMode(self.merge),
|
||||||
Description: self.c.Tr.MergeIntoCurrentBranch,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.MergeIntoCurrentBranch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.FastForward),
|
Key: opts.GetKey(opts.Config.Branches.FastForward),
|
||||||
Handler: self.checkSelectedAndReal(self.fastForward),
|
Handler: self.withItem(self.fastForward),
|
||||||
Description: self.c.Tr.FastForward,
|
GetDisabledReason: self.require(self.singleItemSelected(self.branchIsReal)),
|
||||||
|
Description: self.c.Tr.FastForward,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.CreateTag),
|
Key: opts.GetKey(opts.Config.Branches.CreateTag),
|
||||||
Handler: self.checkSelected(self.createTag),
|
Handler: self.withItem(self.createTag),
|
||||||
Description: self.c.Tr.CreateTag,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.CreateTag,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.SortOrder),
|
Key: opts.GetKey(opts.Config.Branches.SortOrder),
|
||||||
Handler: self.createSortMenu,
|
Handler: self.createSortMenu,
|
||||||
Description: self.c.Tr.SortOrder,
|
Description: self.c.Tr.SortOrder,
|
||||||
OpensMenu: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||||
Handler: self.checkSelected(self.createResetMenu),
|
Handler: self.withItem(self.createResetMenu),
|
||||||
Description: self.c.Tr.ViewResetOptions,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.ViewResetOptions,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.RenameBranch),
|
Key: opts.GetKey(opts.Config.Branches.RenameBranch),
|
||||||
Handler: self.checkSelectedAndReal(self.rename),
|
Handler: self.withItem(self.rename),
|
||||||
Description: self.c.Tr.RenameBranch,
|
GetDisabledReason: self.require(self.singleItemSelected(self.branchIsReal)),
|
||||||
|
Description: self.c.Tr.RenameBranch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
||||||
Handler: self.checkSelected(self.viewUpstreamOptions),
|
Handler: self.withItem(self.viewUpstreamOptions),
|
||||||
Description: self.c.Tr.ViewBranchUpstreamOptions,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Tooltip: self.c.Tr.ViewBranchUpstreamOptionsTooltip,
|
Description: self.c.Tr.ViewBranchUpstreamOptions,
|
||||||
OpensMenu: true,
|
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{})
|
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()
|
currentBranch := self.c.Helpers().Refs.GetCheckedOutRef()
|
||||||
if currentBranch != nil {
|
if currentBranch != nil {
|
||||||
op := self.c.State().GetItemOperation(currentBranch)
|
op := self.c.State().GetItemOperation(currentBranch)
|
||||||
@ -561,8 +583,8 @@ func (self *BranchesController) rebase() error {
|
|||||||
return self.c.Helpers().MergeAndRebase.RebaseOntoRef(selectedBranchName)
|
return self.c.Helpers().MergeAndRebase.RebaseOntoRef(selectedBranchName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *BranchesController) getDisabledReasonForRebase() *types.DisabledReason {
|
func (self *BranchesController) notRebasingOntoSelf(branch *models.Branch) *types.DisabledReason {
|
||||||
selectedBranchName := self.context().GetSelected().Name
|
selectedBranchName := branch.Name
|
||||||
checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef().Name
|
checkedOutBranch := self.c.Helpers().Refs.GetCheckedOutRef().Name
|
||||||
if selectedBranchName == checkedOutBranch {
|
if selectedBranchName == checkedOutBranch {
|
||||||
return &types.DisabledReason{Text: self.c.Tr.CantRebaseOntoSelf}
|
return &types.DisabledReason{Text: self.c.Tr.CantRebaseOntoSelf}
|
||||||
@ -753,24 +775,10 @@ func (self *BranchesController) createPullRequest(from string, to string) error
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *BranchesController) checkSelected(callback func(*models.Branch) error) func() error {
|
func (self *BranchesController) branchIsReal(branch *models.Branch) *types.DisabledReason {
|
||||||
return func() error {
|
if !branch.IsRealBranch() {
|
||||||
selectedItem := self.context().GetSelected()
|
return &types.DisabledReason{Text: self.c.Tr.SelectedItemIsNotABranch}
|
||||||
if selectedItem == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(selectedItem)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
func (self *BranchesController) checkSelectedAndReal(callback func(*models.Branch) error) func() error {
|
return nil
|
||||||
return func() error {
|
|
||||||
selectedItem := self.context().GetSelected()
|
|
||||||
if selectedItem == nil || !selectedItem.IsRealBranch() {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(selectedItem)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -12,11 +12,11 @@ type CommandLogController struct {
|
|||||||
var _ types.IController = &CommandLogController{}
|
var _ types.IController = &CommandLogController{}
|
||||||
|
|
||||||
func NewCommandLogController(
|
func NewCommandLogController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *CommandLogController {
|
) *CommandLogController {
|
||||||
return &CommandLogController{
|
return &CommandLogController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,11 +13,11 @@ type CommitDescriptionController struct {
|
|||||||
var _ types.IController = &CommitMessageController{}
|
var _ types.IController = &CommitMessageController{}
|
||||||
|
|
||||||
func NewCommitDescriptionController(
|
func NewCommitDescriptionController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *CommitDescriptionController {
|
) *CommitDescriptionController {
|
||||||
return &CommitDescriptionController{
|
return &CommitDescriptionController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ type CommitMessageController struct {
|
|||||||
var _ types.IController = &CommitMessageController{}
|
var _ types.IController = &CommitMessageController{}
|
||||||
|
|
||||||
func NewCommitMessageController(
|
func NewCommitMessageController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *CommitMessageController {
|
) *CommitMessageController {
|
||||||
return &CommitMessageController{
|
return &CommitMessageController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,61 +12,74 @@ import (
|
|||||||
|
|
||||||
type CommitFilesController struct {
|
type CommitFilesController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*filetree.CommitFileNode]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &CommitFilesController{}
|
var _ types.IController = &CommitFilesController{}
|
||||||
|
|
||||||
func NewCommitFilesController(
|
func NewCommitFilesController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *CommitFilesController {
|
) *CommitFilesController {
|
||||||
return &CommitFilesController{
|
return &CommitFilesController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
|
ListControllerTrait: NewListControllerTrait[*filetree.CommitFileNode](
|
||||||
|
c,
|
||||||
|
c.Contexts().CommitFiles,
|
||||||
|
c.Contexts().CommitFiles.GetSelected,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitFilesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *CommitFilesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.CommitFiles.CheckoutCommitFile),
|
Key: opts.GetKey(opts.Config.CommitFiles.CheckoutCommitFile),
|
||||||
Handler: self.checkSelected(self.checkout),
|
Handler: self.withItem(self.checkout),
|
||||||
Description: self.c.Tr.CheckoutCommitFile,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.CheckoutCommitFile,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelected(self.discard),
|
Handler: self.withItem(self.discard),
|
||||||
Description: self.c.Tr.DiscardOldFileChange,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.DiscardOldFileChange,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
||||||
Handler: self.checkSelected(self.open),
|
Handler: self.withItem(self.open),
|
||||||
Description: self.c.Tr.OpenFile,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.OpenFile,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Edit),
|
Key: opts.GetKey(opts.Config.Universal.Edit),
|
||||||
Handler: self.checkSelected(self.edit),
|
Handler: self.withItem(self.edit),
|
||||||
Description: self.c.Tr.EditFile,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.EditFile,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
||||||
Handler: self.checkSelected(self.openDiffTool),
|
Handler: self.withItem(self.openDiffTool),
|
||||||
Description: self.c.Tr.OpenDiffTool,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.OpenDiffTool,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.checkSelected(self.toggleForPatch),
|
Handler: self.withItem(self.toggleForPatch),
|
||||||
Description: self.c.Tr.ToggleAddToPatch,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.ToggleAddToPatch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.ToggleStagedAll),
|
Key: opts.GetKey(opts.Config.Files.ToggleStagedAll),
|
||||||
Handler: self.checkSelected(self.toggleAllForPatch),
|
Handler: self.withItem(self.toggleAllForPatch),
|
||||||
Description: self.c.Tr.ToggleAllInPatch,
|
Description: self.c.Tr.ToggleAllInPatch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
||||||
Handler: self.checkSelected(self.enter),
|
Handler: self.withItem(self.enter),
|
||||||
Description: self.c.Tr.EnterFile,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.EnterFile,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.ToggleTreeView),
|
Key: opts.GetKey(opts.Config.Files.ToggleTreeView),
|
||||||
@ -89,21 +102,6 @@ func (self *CommitFilesController) GetMouseKeybindings(opts types.KeybindingsOpt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *CommitFilesController) checkSelected(callback func(*filetree.CommitFileNode) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
selected := self.context().GetSelected()
|
|
||||||
if selected == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(selected)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *CommitFilesController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *CommitFilesController) context() *context.CommitFilesContext {
|
func (self *CommitFilesController) context() *context.CommitFilesContext {
|
||||||
return self.c.Contexts().CommitFiles
|
return self.c.Contexts().CommitFiles
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,11 @@ type ConfirmationController struct {
|
|||||||
var _ types.IController = &ConfirmationController{}
|
var _ types.IController = &ConfirmationController{}
|
||||||
|
|
||||||
func NewConfirmationController(
|
func NewConfirmationController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *ConfirmationController {
|
) *ConfirmationController {
|
||||||
return &ConfirmationController{
|
return &ConfirmationController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,11 +31,11 @@ type ContextLinesController struct {
|
|||||||
var _ types.IController = &ContextLinesController{}
|
var _ types.IController = &ContextLinesController{}
|
||||||
|
|
||||||
func NewContextLinesController(
|
func NewContextLinesController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *ContextLinesController {
|
) *ContextLinesController {
|
||||||
return &ContextLinesController{
|
return &ContextLinesController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,15 +62,22 @@ func (self *CustomPatchOptionsMenuAction) Call() error {
|
|||||||
if self.c.CurrentContext().GetKey() == self.c.Contexts().LocalCommits.GetKey() {
|
if self.c.CurrentContext().GetKey() == self.c.Contexts().LocalCommits.GetKey() {
|
||||||
selectedCommit := self.c.Contexts().LocalCommits.GetSelected()
|
selectedCommit := self.c.Contexts().LocalCommits.GetSelected()
|
||||||
if selectedCommit != nil && self.c.Git().Patch.PatchBuilder.To != selectedCommit.Sha {
|
if selectedCommit != nil && self.c.Git().Patch.PatchBuilder.To != selectedCommit.Sha {
|
||||||
|
|
||||||
|
var disabledReason *types.DisabledReason
|
||||||
|
if self.c.Contexts().LocalCommits.AreMultipleItemsSelected() {
|
||||||
|
disabledReason = &types.DisabledReason{Text: self.c.Tr.RangeSelectNotSupported}
|
||||||
|
}
|
||||||
|
|
||||||
// adding this option to index 1
|
// adding this option to index 1
|
||||||
menuItems = append(
|
menuItems = append(
|
||||||
menuItems[:1],
|
menuItems[:1],
|
||||||
append(
|
append(
|
||||||
[]*types.MenuItem{
|
[]*types.MenuItem{
|
||||||
{
|
{
|
||||||
Label: fmt.Sprintf(self.c.Tr.MovePatchToSelectedCommit, selectedCommit.Sha),
|
Label: fmt.Sprintf(self.c.Tr.MovePatchToSelectedCommit, selectedCommit.Sha),
|
||||||
OnPress: self.handleMovePatchToSelectedCommit,
|
OnPress: self.handleMovePatchToSelectedCommit,
|
||||||
Key: 'm',
|
Key: 'm',
|
||||||
|
DisabledReason: disabledReason,
|
||||||
},
|
},
|
||||||
}, menuItems[1:]...,
|
}, menuItems[1:]...,
|
||||||
)...,
|
)...,
|
||||||
|
@ -13,25 +13,32 @@ import (
|
|||||||
|
|
||||||
type FilesController struct {
|
type FilesController struct {
|
||||||
baseController // nolint: unused
|
baseController // nolint: unused
|
||||||
c *ControllerCommon
|
*ListControllerTrait[*filetree.FileNode]
|
||||||
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &FilesController{}
|
var _ types.IController = &FilesController{}
|
||||||
|
|
||||||
func NewFilesController(
|
func NewFilesController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *FilesController {
|
) *FilesController {
|
||||||
return &FilesController{
|
return &FilesController{
|
||||||
c: common,
|
c: c,
|
||||||
|
ListControllerTrait: NewListControllerTrait[*filetree.FileNode](
|
||||||
|
c,
|
||||||
|
c.Contexts().Files,
|
||||||
|
c.Contexts().Files.GetSelected,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
return []*types.Binding{
|
return []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.checkSelectedFileNode(self.press),
|
Handler: self.withItem(self.press),
|
||||||
Description: self.c.Tr.ToggleStaged,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.ToggleStaged,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.OpenStatusFilter),
|
Key: opts.GetKey(opts.Config.Files.OpenStatusFilter),
|
||||||
@ -71,20 +78,23 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
Tooltip: self.c.Tr.FindBaseCommitForFixupTooltip,
|
Tooltip: self.c.Tr.FindBaseCommitForFixupTooltip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Edit),
|
Key: opts.GetKey(opts.Config.Universal.Edit),
|
||||||
Handler: self.checkSelectedFileNode(self.edit),
|
Handler: self.withItem(self.edit),
|
||||||
Description: self.c.Tr.EditFile,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.EditFile,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
||||||
Handler: self.Open,
|
Handler: self.Open,
|
||||||
Description: self.c.Tr.OpenFile,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.OpenFile,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.IgnoreFile),
|
Key: opts.GetKey(opts.Config.Files.IgnoreFile),
|
||||||
Handler: self.checkSelectedFileNode(self.ignoreOrExcludeMenu),
|
Handler: self.withItem(self.ignoreOrExcludeMenu),
|
||||||
Description: self.c.Tr.Actions.IgnoreExcludeFile,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.Actions.IgnoreExcludeFile,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.RefreshFiles),
|
Key: opts.GetKey(opts.Config.Files.RefreshFiles),
|
||||||
@ -108,9 +118,10 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
Description: self.c.Tr.ToggleStagedAll,
|
Description: self.c.Tr.ToggleStagedAll,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
||||||
Handler: self.enter,
|
Handler: self.enter,
|
||||||
Description: self.c.Tr.FileEnter,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.FileEnter,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||||
@ -130,9 +141,10 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
Description: self.c.Tr.ToggleTreeView,
|
Description: self.c.Tr.ToggleTreeView,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
||||||
Handler: self.checkSelectedFileNode(self.openDiffTool),
|
Handler: self.withItem(self.openDiffTool),
|
||||||
Description: self.c.Tr.OpenDiffTool,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.OpenDiffTool,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.OpenMergeTool),
|
Key: opts.GetKey(opts.Config.Files.OpenMergeTool),
|
||||||
@ -254,7 +266,7 @@ func (self *FilesController) GetOnRenderToMain() func() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *FilesController) GetOnClick() func() error {
|
func (self *FilesController) GetOnClick() func() error {
|
||||||
return self.checkSelectedFileNode(self.press)
|
return self.withItemGraceful(self.press)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we are dealing with a status for which there is no key in this map,
|
// if we are dealing with a status for which there is no key in this map,
|
||||||
@ -411,17 +423,6 @@ func (self *FilesController) press(node *filetree.FileNode) error {
|
|||||||
return self.context().HandleFocus(types.OnFocusOpts{})
|
return self.context().HandleFocus(types.OnFocusOpts{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FilesController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
node := self.context().GetSelected()
|
|
||||||
if node == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FilesController) Context() types.Context {
|
func (self *FilesController) Context() types.Context {
|
||||||
return self.context()
|
return self.context()
|
||||||
}
|
}
|
||||||
@ -798,7 +799,8 @@ func (self *FilesController) openCopyMenu() error {
|
|||||||
self.c.Toast(self.c.Tr.FileNameCopiedToast)
|
self.c.Toast(self.c.Tr.FileNameCopiedToast)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Key: 'n',
|
DisabledReason: self.require(self.singleItemSelected())(),
|
||||||
|
Key: 'n',
|
||||||
}
|
}
|
||||||
copyPathItem := &types.MenuItem{
|
copyPathItem := &types.MenuItem{
|
||||||
Label: self.c.Tr.CopyFilePath,
|
Label: self.c.Tr.CopyFilePath,
|
||||||
@ -809,7 +811,8 @@ func (self *FilesController) openCopyMenu() error {
|
|||||||
self.c.Toast(self.c.Tr.FilePathCopiedToast)
|
self.c.Toast(self.c.Tr.FilePathCopiedToast)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
Key: 'p',
|
DisabledReason: self.require(self.singleItemSelected())(),
|
||||||
|
Key: 'p',
|
||||||
}
|
}
|
||||||
copyFileDiffItem := &types.MenuItem{
|
copyFileDiffItem := &types.MenuItem{
|
||||||
Label: self.c.Tr.CopySelectedDiff,
|
Label: self.c.Tr.CopySelectedDiff,
|
||||||
@ -827,6 +830,14 @@ func (self *FilesController) openCopyMenu() error {
|
|||||||
self.c.Toast(self.c.Tr.FileDiffCopiedToast)
|
self.c.Toast(self.c.Tr.FileDiffCopiedToast)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
DisabledReason: self.require(self.singleItemSelected(
|
||||||
|
func(file *filetree.FileNode) *types.DisabledReason {
|
||||||
|
if !node.GetHasStagedOrTrackedChanges() {
|
||||||
|
return &types.DisabledReason{Text: self.c.Tr.NoContentToCopyError}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
))(),
|
||||||
Key: 's',
|
Key: 's',
|
||||||
}
|
}
|
||||||
copyAllDiff := &types.MenuItem{
|
copyAllDiff := &types.MenuItem{
|
||||||
@ -844,21 +855,17 @@ func (self *FilesController) openCopyMenu() error {
|
|||||||
self.c.Toast(self.c.Tr.AllFilesDiffCopiedToast)
|
self.c.Toast(self.c.Tr.AllFilesDiffCopiedToast)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
DisabledReason: self.require(
|
||||||
|
func() *types.DisabledReason {
|
||||||
|
if !self.anyStagedOrTrackedFile() {
|
||||||
|
return &types.DisabledReason{Text: self.c.Tr.NoContentToCopyError}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)(),
|
||||||
Key: 'a',
|
Key: 'a',
|
||||||
}
|
}
|
||||||
|
|
||||||
if node == nil {
|
|
||||||
copyNameItem.DisabledReason = &types.DisabledReason{Text: self.c.Tr.NoContentToCopyError}
|
|
||||||
copyPathItem.DisabledReason = &types.DisabledReason{Text: self.c.Tr.NoContentToCopyError}
|
|
||||||
copyFileDiffItem.DisabledReason = &types.DisabledReason{Text: self.c.Tr.NoContentToCopyError}
|
|
||||||
}
|
|
||||||
if node != nil && !node.GetHasStagedOrTrackedChanges() {
|
|
||||||
copyFileDiffItem.DisabledReason = &types.DisabledReason{Text: self.c.Tr.NoContentToCopyError}
|
|
||||||
}
|
|
||||||
if !self.anyStagedOrTrackedFile() {
|
|
||||||
copyAllDiff.DisabledReason = &types.DisabledReason{Text: self.c.Tr.NoContentToCopyError}
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.c.Menu(types.CreateMenuOptions{
|
return self.c.Menu(types.CreateMenuOptions{
|
||||||
Title: self.c.Tr.CopyToClipboardMenu,
|
Title: self.c.Tr.CopyToClipboardMenu,
|
||||||
Items: []*types.MenuItem{
|
Items: []*types.MenuItem{
|
||||||
|
@ -3,7 +3,6 @@ package controllers
|
|||||||
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"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
@ -13,27 +12,34 @@ import (
|
|||||||
|
|
||||||
type FilesRemoveController struct {
|
type FilesRemoveController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*filetree.FileNode]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &FilesRemoveController{}
|
var _ types.IController = &FilesRemoveController{}
|
||||||
|
|
||||||
func NewFilesRemoveController(
|
func NewFilesRemoveController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *FilesRemoveController {
|
) *FilesRemoveController {
|
||||||
return &FilesRemoveController{
|
return &FilesRemoveController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
|
ListControllerTrait: NewListControllerTrait[*filetree.FileNode](
|
||||||
|
c,
|
||||||
|
c.Contexts().Files,
|
||||||
|
c.Contexts().Files.GetSelected,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FilesRemoveController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *FilesRemoveController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelectedFileNode(self.remove),
|
Handler: self.withItem(self.remove),
|
||||||
Description: self.c.Tr.ViewDiscardOptions,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.ViewDiscardOptions,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,22 +172,3 @@ func (self *FilesRemoveController) ResetSubmodule(submodule *models.SubmoduleCon
|
|||||||
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.SUBMODULES}})
|
return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.FILES, types.SUBMODULES}})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FilesRemoveController) checkSelectedFileNode(callback func(*filetree.FileNode) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
node := self.context().GetSelected()
|
|
||||||
if node == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FilesRemoveController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *FilesRemoveController) context() *context.WorkingTreeContext {
|
|
||||||
return self.c.Contexts().Files
|
|
||||||
}
|
|
||||||
|
@ -4,24 +4,29 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GitFlowController struct {
|
type GitFlowController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Branch]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &GitFlowController{}
|
var _ types.IController = &GitFlowController{}
|
||||||
|
|
||||||
func NewGitFlowController(
|
func NewGitFlowController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *GitFlowController {
|
) *GitFlowController {
|
||||||
return &GitFlowController{
|
return &GitFlowController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*models.Branch](
|
||||||
|
c,
|
||||||
|
c.Contexts().Branches,
|
||||||
|
c.Contexts().Branches.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,7 +34,7 @@ func (self *GitFlowController) GetKeybindings(opts types.KeybindingsOpts) []*typ
|
|||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.ViewGitFlowOptions),
|
Key: opts.GetKey(opts.Config.Branches.ViewGitFlowOptions),
|
||||||
Handler: self.checkSelected(self.handleCreateGitFlowMenu),
|
Handler: self.withItem(self.handleCreateGitFlowMenu),
|
||||||
Description: self.c.Tr.GitFlowOptions,
|
Description: self.c.Tr.GitFlowOptions,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
@ -68,6 +73,7 @@ func (self *GitFlowController) handleCreateGitFlowMenu(branch *models.Branch) er
|
|||||||
OnPress: func() error {
|
OnPress: func() error {
|
||||||
return self.gitFlowFinishBranch(branch.Name)
|
return self.gitFlowFinishBranch(branch.Name)
|
||||||
},
|
},
|
||||||
|
DisabledReason: self.require(self.singleItemSelected())(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Label: "start feature",
|
Label: "start feature",
|
||||||
@ -102,22 +108,3 @@ func (self *GitFlowController) gitFlowFinishBranch(branchName string) error {
|
|||||||
self.c.LogAction(self.c.Tr.Actions.GitFlowFinish)
|
self.c.LogAction(self.c.Tr.Actions.GitFlowFinish)
|
||||||
return self.c.RunSubprocessAndRefresh(cmdObj)
|
return self.c.RunSubprocessAndRefresh(cmdObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *GitFlowController) checkSelected(callback func(*models.Branch) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
node := self.context().GetSelected()
|
|
||||||
if node == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *GitFlowController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *GitFlowController) context() *context.BranchesContext {
|
|
||||||
return self.c.Contexts().Branches
|
|
||||||
}
|
|
||||||
|
@ -11,11 +11,11 @@ type GlobalController struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewGlobalController(
|
func NewGlobalController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *GlobalController {
|
) *GlobalController {
|
||||||
return &GlobalController{
|
return &GlobalController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ type JumpToSideWindowController struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewJumpToSideWindowController(
|
func NewJumpToSideWindowController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *JumpToSideWindowController {
|
) *JumpToSideWindowController {
|
||||||
return &JumpToSideWindowController{
|
return &JumpToSideWindowController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
95
pkg/gui/controllers/list_controller_trait.go
Normal file
95
pkg/gui/controllers/list_controller_trait.go
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import "github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
|
|
||||||
|
// Embed this into your list controller to get some convenience methods for
|
||||||
|
// ensuring a single item is selected, etc.
|
||||||
|
|
||||||
|
type ListControllerTrait[T comparable] struct {
|
||||||
|
c *ControllerCommon
|
||||||
|
context types.IListContext
|
||||||
|
getSelected func() T
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewListControllerTrait[T comparable](
|
||||||
|
c *ControllerCommon,
|
||||||
|
context types.IListContext,
|
||||||
|
getSelected func() T,
|
||||||
|
) *ListControllerTrait[T] {
|
||||||
|
return &ListControllerTrait[T]{
|
||||||
|
c: c,
|
||||||
|
context: context,
|
||||||
|
getSelected: getSelected,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience function for combining multiple disabledReason callbacks.
|
||||||
|
// The first callback to return a disabled reason will be the one returned.
|
||||||
|
func (self *ListControllerTrait[T]) require(callbacks ...func() *types.DisabledReason) func() *types.DisabledReason {
|
||||||
|
return func() *types.DisabledReason {
|
||||||
|
for _, callback := range callbacks {
|
||||||
|
if disabledReason := callback(); disabledReason != nil {
|
||||||
|
return disabledReason
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenience function for enforcing that a single item is selected.
|
||||||
|
// Also takes callbacks for additional disabled reasons, and passes the selected
|
||||||
|
// item into each one.
|
||||||
|
func (self *ListControllerTrait[T]) singleItemSelected(callbacks ...func(T) *types.DisabledReason) func() *types.DisabledReason {
|
||||||
|
return func() *types.DisabledReason {
|
||||||
|
if self.context.GetList().AreMultipleItemsSelected() {
|
||||||
|
return &types.DisabledReason{Text: self.c.Tr.RangeSelectNotSupported}
|
||||||
|
}
|
||||||
|
|
||||||
|
var zeroValue T
|
||||||
|
item := self.getSelected()
|
||||||
|
if item == zeroValue {
|
||||||
|
return &types.DisabledReason{Text: self.c.Tr.NoItemSelected}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, callback := range callbacks {
|
||||||
|
if reason := callback(item); 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()
|
||||||
|
if commit == zeroValue {
|
||||||
|
return self.c.ErrorMsg(self.c.Tr.NoItemSelected)
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(commit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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()
|
||||||
|
if commit == zeroValue {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return callback(commit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All controllers must implement this method so we're defining it here for convenience
|
||||||
|
func (self *ListControllerTrait[T]) Context() types.Context {
|
||||||
|
return self.context
|
||||||
|
}
|
@ -25,6 +25,7 @@ type (
|
|||||||
|
|
||||||
type LocalCommitsController struct {
|
type LocalCommitsController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Commit]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
|
|
||||||
pullFiles PullFilesFn
|
pullFiles PullFilesFn
|
||||||
@ -33,13 +34,18 @@ type LocalCommitsController struct {
|
|||||||
var _ types.IController = &LocalCommitsController{}
|
var _ types.IController = &LocalCommitsController{}
|
||||||
|
|
||||||
func NewLocalCommitsController(
|
func NewLocalCommitsController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
pullFiles PullFilesFn,
|
pullFiles PullFilesFn,
|
||||||
) *LocalCommitsController {
|
) *LocalCommitsController {
|
||||||
return &LocalCommitsController{
|
return &LocalCommitsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
pullFiles: pullFiles,
|
pullFiles: pullFiles,
|
||||||
|
ListControllerTrait: NewListControllerTrait[*models.Commit](
|
||||||
|
c,
|
||||||
|
c.Contexts().LocalCommits,
|
||||||
|
c.Contexts().LocalCommits.GetSelected,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,47 +54,59 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
|
|
||||||
outsideFilterModeBindings := []*types.Binding{
|
outsideFilterModeBindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.SquashDown),
|
Key: opts.GetKey(opts.Config.Commits.SquashDown),
|
||||||
Handler: self.checkSelected(self.squashDown),
|
Handler: self.withItem(self.squashDown),
|
||||||
GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(self.getDisabledReasonForSquashDown),
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.SquashDown,
|
self.singleItemSelected(self.getDisabledReasonForSquashDown),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.SquashDown,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsFixup),
|
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsFixup),
|
||||||
Handler: self.checkSelected(self.fixup),
|
Handler: self.withItem(self.fixup),
|
||||||
GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(self.getDisabledReasonForFixup),
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.FixupCommit,
|
self.singleItemSelected(self.getDisabledReasonForFixup),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.FixupCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.RenameCommit),
|
Key: opts.GetKey(opts.Config.Commits.RenameCommit),
|
||||||
Handler: self.checkSelected(self.reword),
|
Handler: self.withItem(self.reword),
|
||||||
GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(todo.Reword),
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.RewordCommit,
|
self.singleItemSelected(self.rebaseCommandEnabled(todo.Reword)),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.RewordCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.RenameCommitWithEditor),
|
Key: opts.GetKey(opts.Config.Commits.RenameCommitWithEditor),
|
||||||
Handler: self.checkSelected(self.rewordEditor),
|
Handler: self.withItem(self.rewordEditor),
|
||||||
GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(todo.Reword),
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.RenameCommitEditor,
|
self.singleItemSelected(self.rebaseCommandEnabled(todo.Reword)),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.RenameCommitEditor,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelected(self.drop),
|
Handler: self.withItem(self.drop),
|
||||||
GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(todo.Drop),
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.DeleteCommit,
|
self.singleItemSelected(self.rebaseCommandEnabled(todo.Drop)),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.DeleteCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(editCommitKey),
|
Key: opts.GetKey(editCommitKey),
|
||||||
Handler: self.checkSelected(self.edit),
|
Handler: self.withItem(self.edit),
|
||||||
GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(todo.Edit),
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.EditCommit,
|
self.singleItemSelected(self.rebaseCommandEnabled(todo.Edit)),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.EditCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// The user-facing description here is 'Start interactive rebase' but internally
|
// The user-facing description here is 'Start interactive rebase' but internally
|
||||||
// we're calling it 'quick-start interactive rebase' to differentiate it from
|
// we're calling it 'quick-start interactive rebase' to differentiate it from
|
||||||
// when you manually select the base commit.
|
// when you manually select the base commit.
|
||||||
Key: opts.GetKey(opts.Config.Commits.StartInteractiveRebase),
|
Key: opts.GetKey(opts.Config.Commits.StartInteractiveRebase),
|
||||||
Handler: self.checkSelected(self.quickStartInteractiveRebase),
|
Handler: self.withItem(self.quickStartInteractiveRebase),
|
||||||
GetDisabledReason: self.require(self.notMidRebase, self.canFindCommitForQuickStart),
|
GetDisabledReason: self.require(self.notMidRebase, self.canFindCommitForQuickStart),
|
||||||
Description: self.c.Tr.QuickStartInteractiveRebase,
|
Description: self.c.Tr.QuickStartInteractiveRebase,
|
||||||
Tooltip: utils.ResolvePlaceholderString(self.c.Tr.QuickStartInteractiveRebaseTooltip, map[string]string{
|
Tooltip: utils.ResolvePlaceholderString(self.c.Tr.QuickStartInteractiveRebaseTooltip, map[string]string{
|
||||||
@ -96,45 +114,50 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.PickCommit),
|
Key: opts.GetKey(opts.Config.Commits.PickCommit),
|
||||||
Handler: self.checkSelected(self.pick),
|
Handler: self.withItem(self.pick),
|
||||||
GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(todo.Pick),
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.PickCommit,
|
self.singleItemSelected(self.rebaseCommandEnabled(todo.Pick)),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.PickCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CreateFixupCommit),
|
Key: opts.GetKey(opts.Config.Commits.CreateFixupCommit),
|
||||||
Handler: self.checkSelected(self.createFixupCommit),
|
Handler: self.withItem(self.createFixupCommit),
|
||||||
GetDisabledReason: self.disabledIfNoSelectedCommit(),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.CreateFixupCommitDescription,
|
Description: self.c.Tr.CreateFixupCommitDescription,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.SquashAboveCommits),
|
Key: opts.GetKey(opts.Config.Commits.SquashAboveCommits),
|
||||||
Handler: self.checkSelected(self.squashAllAboveFixupCommits),
|
Handler: self.withItem(self.squashAllAboveFixupCommits),
|
||||||
GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(self.getDisabledReasonForSquashAllAboveFixupCommits),
|
GetDisabledReason: self.require(
|
||||||
Description: self.c.Tr.SquashAboveCommits,
|
self.notMidRebase,
|
||||||
|
self.singleItemSelected(),
|
||||||
|
),
|
||||||
|
Description: self.c.Tr.SquashAboveCommits,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MoveDownCommit),
|
Key: opts.GetKey(opts.Config.Commits.MoveDownCommit),
|
||||||
Handler: self.checkSelected(self.moveDown),
|
Handler: self.withItem(self.moveDown),
|
||||||
GetDisabledReason: self.disabledIfNoSelectedCommit(),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.MoveDownCommit,
|
Description: self.c.Tr.MoveDownCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MoveUpCommit),
|
Key: opts.GetKey(opts.Config.Commits.MoveUpCommit),
|
||||||
Handler: self.checkSelected(self.moveUp),
|
Handler: self.withItem(self.moveUp),
|
||||||
GetDisabledReason: self.disabledIfNoSelectedCommit(),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.MoveUpCommit,
|
Description: self.c.Tr.MoveUpCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.PasteCommits),
|
Key: opts.GetKey(opts.Config.Commits.PasteCommits),
|
||||||
Handler: self.paste,
|
Handler: self.paste,
|
||||||
GetDisabledReason: self.getDisabledReasonForPaste,
|
GetDisabledReason: self.require(self.canPaste),
|
||||||
Description: self.c.Tr.PasteCommits,
|
Description: self.c.Tr.PasteCommits,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsBaseForRebase),
|
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsBaseForRebase),
|
||||||
Handler: self.checkSelected(self.markAsBaseCommit),
|
Handler: self.withItem(self.markAsBaseCommit),
|
||||||
GetDisabledReason: self.disabledIfNoSelectedCommit(),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.MarkAsBaseCommit,
|
Description: self.c.Tr.MarkAsBaseCommit,
|
||||||
Tooltip: self.c.Tr.MarkAsBaseCommitTooltip,
|
Tooltip: self.c.Tr.MarkAsBaseCommitTooltip,
|
||||||
},
|
},
|
||||||
@ -161,27 +184,27 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
bindings := append(outsideFilterModeBindings, []*types.Binding{
|
bindings := append(outsideFilterModeBindings, []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.AmendToCommit),
|
Key: opts.GetKey(opts.Config.Commits.AmendToCommit),
|
||||||
Handler: self.checkSelected(self.amendTo),
|
Handler: self.withItem(self.amendTo),
|
||||||
GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(self.getDisabledReasonForAmendTo),
|
GetDisabledReason: self.require(self.singleItemSelected(self.canAmend)),
|
||||||
Description: self.c.Tr.AmendToCommit,
|
Description: self.c.Tr.AmendToCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ResetCommitAuthor),
|
Key: opts.GetKey(opts.Config.Commits.ResetCommitAuthor),
|
||||||
Handler: self.checkSelected(self.amendAttribute),
|
Handler: self.withItem(self.amendAttribute),
|
||||||
GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(self.getDisabledReasonForAmendTo),
|
GetDisabledReason: self.require(self.singleItemSelected(self.canAmend)),
|
||||||
Description: self.c.Tr.SetResetCommitAuthor,
|
Description: self.c.Tr.SetResetCommitAuthor,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.RevertCommit),
|
Key: opts.GetKey(opts.Config.Commits.RevertCommit),
|
||||||
Handler: self.checkSelected(self.revert),
|
Handler: self.withItem(self.revert),
|
||||||
GetDisabledReason: self.disabledIfNoSelectedCommit(),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.RevertCommit,
|
Description: self.c.Tr.RevertCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CreateTag),
|
Key: opts.GetKey(opts.Config.Commits.CreateTag),
|
||||||
Handler: self.checkSelected(self.createTag),
|
Handler: self.withItem(self.createTag),
|
||||||
GetDisabledReason: self.disabledIfNoSelectedCommit(),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.TagCommit,
|
Description: self.c.Tr.TagCommit,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -266,7 +289,7 @@ func (self *LocalCommitsController) getDisabledReasonForSquashDown(commit *model
|
|||||||
return &types.DisabledReason{Text: self.c.Tr.CannotSquashOrFixupFirstCommit}
|
return &types.DisabledReason{Text: self.c.Tr.CannotSquashOrFixupFirstCommit}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.rebaseCommandEnabled(todo.Squash, commit)
|
return self.rebaseCommandEnabled(todo.Squash)(commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) fixup(commit *models.Commit) error {
|
func (self *LocalCommitsController) fixup(commit *models.Commit) error {
|
||||||
@ -295,7 +318,7 @@ func (self *LocalCommitsController) getDisabledReasonForFixup(commit *models.Com
|
|||||||
return &types.DisabledReason{Text: self.c.Tr.CannotSquashOrFixupFirstCommit}
|
return &types.DisabledReason{Text: self.c.Tr.CannotSquashOrFixupFirstCommit}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.rebaseCommandEnabled(todo.Squash, commit)
|
return self.rebaseCommandEnabled(todo.Squash)(commit)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) reword(commit *models.Commit) error {
|
func (self *LocalCommitsController) reword(commit *models.Commit) error {
|
||||||
@ -528,36 +551,38 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action todo.TodoComma
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) rebaseCommandEnabled(action todo.TodoCommand, commit *models.Commit) *types.DisabledReason {
|
func (self *LocalCommitsController) rebaseCommandEnabled(action todo.TodoCommand) func(*models.Commit) *types.DisabledReason {
|
||||||
if commit.Action == models.ActionConflict {
|
return func(commit *models.Commit) *types.DisabledReason {
|
||||||
return &types.DisabledReason{Text: self.c.Tr.ChangingThisActionIsNotAllowed}
|
if commit.Action == models.ActionConflict {
|
||||||
}
|
return &types.DisabledReason{Text: self.c.Tr.ChangingThisActionIsNotAllowed}
|
||||||
|
}
|
||||||
|
|
||||||
if !commit.IsTODO() {
|
if !commit.IsTODO() {
|
||||||
if self.c.Model().WorkingTreeStateAtLastCommitRefresh != enums.REBASE_MODE_NONE {
|
if self.c.Model().WorkingTreeStateAtLastCommitRefresh != enums.REBASE_MODE_NONE {
|
||||||
// If we are in a rebase, the only action that is allowed for
|
// If we are in a rebase, the only action that is allowed for
|
||||||
// non-todo commits is rewording the current head commit
|
// non-todo commits is rewording the current head commit
|
||||||
if !(action == todo.Reword && self.isHeadCommit()) {
|
if !(action == todo.Reword && self.isHeadCommit()) {
|
||||||
return &types.DisabledReason{Text: self.c.Tr.AlreadyRebasing}
|
return &types.DisabledReason{Text: self.c.Tr.AlreadyRebasing}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// for now we do not support setting 'reword' because it requires an editor
|
||||||
|
// and that means we either unconditionally wait around for the subprocess to ask for
|
||||||
|
// our input or we set a lazygit client as the EDITOR env variable and have it
|
||||||
|
// request us to edit the commit message when prompted.
|
||||||
|
if action == todo.Reword {
|
||||||
|
return &types.DisabledReason{Text: self.c.Tr.RewordNotSupported}
|
||||||
|
}
|
||||||
|
|
||||||
|
if allowed := isChangeOfRebaseTodoAllowed(action); !allowed {
|
||||||
|
return &types.DisabledReason{Text: self.c.Tr.ChangingThisActionIsNotAllowed}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// for now we do not support setting 'reword' because it requires an editor
|
|
||||||
// and that means we either unconditionally wait around for the subprocess to ask for
|
|
||||||
// our input or we set a lazygit client as the EDITOR env variable and have it
|
|
||||||
// request us to edit the commit message when prompted.
|
|
||||||
if action == todo.Reword {
|
|
||||||
return &types.DisabledReason{Text: self.c.Tr.RewordNotSupported}
|
|
||||||
}
|
|
||||||
|
|
||||||
if allowed := isChangeOfRebaseTodoAllowed(action); !allowed {
|
|
||||||
return &types.DisabledReason{Text: self.c.Tr.ChangingThisActionIsNotAllowed}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) moveDown(commit *models.Commit) error {
|
func (self *LocalCommitsController) moveDown(commit *models.Commit) error {
|
||||||
@ -687,7 +712,7 @@ func (self *LocalCommitsController) amendTo(commit *models.Commit) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) getDisabledReasonForAmendTo(commit *models.Commit) *types.DisabledReason {
|
func (self *LocalCommitsController) canAmend(commit *models.Commit) *types.DisabledReason {
|
||||||
if !self.isHeadCommit() && self.c.Model().WorkingTreeStateAtLastCommitRefresh != enums.REBASE_MODE_NONE {
|
if !self.isHeadCommit() && self.c.Model().WorkingTreeStateAtLastCommitRefresh != enums.REBASE_MODE_NONE {
|
||||||
return &types.DisabledReason{Text: self.c.Tr.AlreadyRebasing}
|
return &types.DisabledReason{Text: self.c.Tr.AlreadyRebasing}
|
||||||
}
|
}
|
||||||
@ -870,14 +895,6 @@ func (self *LocalCommitsController) squashAllAboveFixupCommits(commit *models.Co
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) getDisabledReasonForSquashAllAboveFixupCommits(commit *models.Commit) *types.DisabledReason {
|
|
||||||
if self.c.Model().WorkingTreeStateAtLastCommitRefresh != enums.REBASE_MODE_NONE {
|
|
||||||
return &types.DisabledReason{Text: self.c.Tr.AlreadyRebasing}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// For getting disabled reason
|
// For getting disabled reason
|
||||||
func (self *LocalCommitsController) notMidRebase() *types.DisabledReason {
|
func (self *LocalCommitsController) notMidRebase() *types.DisabledReason {
|
||||||
if self.c.Model().WorkingTreeStateAtLastCommitRefresh != enums.REBASE_MODE_NONE {
|
if self.c.Model().WorkingTreeStateAtLastCommitRefresh != enums.REBASE_MODE_NONE {
|
||||||
@ -1016,39 +1033,6 @@ func (self *LocalCommitsController) handleOpenLogMenu() error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) checkSelected(callback func(*models.Commit) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
commit := self.context().GetSelected()
|
|
||||||
if commit == nil {
|
|
||||||
// The enabled callback should have checked for this
|
|
||||||
panic("no commit selected")
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(commit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *LocalCommitsController) callGetDisabledReasonFuncWithSelectedCommit(callback func(*models.Commit) *types.DisabledReason) func() *types.DisabledReason {
|
|
||||||
return func() *types.DisabledReason {
|
|
||||||
commit := self.context().GetSelected()
|
|
||||||
if commit == nil {
|
|
||||||
return &types.DisabledReason{Text: self.c.Tr.NoCommitSelected}
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(commit)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *LocalCommitsController) disabledIfNoSelectedCommit() func() *types.DisabledReason {
|
|
||||||
return self.callGetDisabledReasonFuncWithSelectedCommit(func(*models.Commit) *types.DisabledReason { return nil })
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *LocalCommitsController) getDisabledReasonForRebaseCommandWithSelectedCommit(action todo.TodoCommand) func() *types.DisabledReason {
|
|
||||||
return self.callGetDisabledReasonFuncWithSelectedCommit(func(commit *models.Commit) *types.DisabledReason {
|
|
||||||
return self.rebaseCommandEnabled(action, commit)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *LocalCommitsController) GetOnFocus() func(types.OnFocusOpts) error {
|
func (self *LocalCommitsController) GetOnFocus() func(types.OnFocusOpts) error {
|
||||||
return func(types.OnFocusOpts) error {
|
return func(types.OnFocusOpts) error {
|
||||||
context := self.context()
|
context := self.context()
|
||||||
@ -1065,10 +1049,6 @@ func (self *LocalCommitsController) GetOnFocus() func(types.OnFocusOpts) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *LocalCommitsController) context() *context.LocalCommitsContext {
|
func (self *LocalCommitsController) context() *context.LocalCommitsContext {
|
||||||
return self.c.Contexts().LocalCommits
|
return self.c.Contexts().LocalCommits
|
||||||
}
|
}
|
||||||
@ -1077,7 +1057,7 @@ func (self *LocalCommitsController) paste() error {
|
|||||||
return self.c.Helpers().CherryPick.Paste()
|
return self.c.Helpers().CherryPick.Paste()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *LocalCommitsController) getDisabledReasonForPaste() *types.DisabledReason {
|
func (self *LocalCommitsController) canPaste() *types.DisabledReason {
|
||||||
if !self.c.Helpers().CherryPick.CanPaste() {
|
if !self.c.Helpers().CherryPick.CanPaste() {
|
||||||
return &types.DisabledReason{Text: self.c.Tr.NoCopiedCommits}
|
return &types.DisabledReason{Text: self.c.Tr.NoCopiedCommits}
|
||||||
}
|
}
|
||||||
@ -1099,19 +1079,6 @@ func (self *LocalCommitsController) isHeadCommit() bool {
|
|||||||
return models.IsHeadCommit(self.c.Model().Commits, self.context().GetSelectedLineIdx())
|
return models.IsHeadCommit(self.c.Model().Commits, self.context().GetSelectedLineIdx())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience function for composing multiple disabled reason functions
|
|
||||||
func (self *LocalCommitsController) require(callbacks ...func() *types.DisabledReason) func() *types.DisabledReason {
|
|
||||||
return func() *types.DisabledReason {
|
|
||||||
for _, callback := range callbacks {
|
|
||||||
if disabledReason := callback(); disabledReason != nil {
|
|
||||||
return disabledReason
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func isChangeOfRebaseTodoAllowed(action todo.TodoCommand) bool {
|
func isChangeOfRebaseTodoAllowed(action todo.TodoCommand) bool {
|
||||||
allowedActions := []todo.TodoCommand{
|
allowedActions := []todo.TodoCommand{
|
||||||
todo.Pick,
|
todo.Pick,
|
||||||
|
@ -7,17 +7,23 @@ import (
|
|||||||
|
|
||||||
type MenuController struct {
|
type MenuController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*types.MenuItem]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &MenuController{}
|
var _ types.IController = &MenuController{}
|
||||||
|
|
||||||
func NewMenuController(
|
func NewMenuController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *MenuController {
|
) *MenuController {
|
||||||
return &MenuController{
|
return &MenuController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*types.MenuItem](
|
||||||
|
c,
|
||||||
|
c.Contexts().Menu,
|
||||||
|
c.Contexts().Menu.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,14 +32,16 @@ func NewMenuController(
|
|||||||
func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.press,
|
Handler: self.withItem(self.press),
|
||||||
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
||||||
Handler: self.press,
|
Handler: self.withItem(self.press),
|
||||||
Description: self.c.Tr.Execute,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Display: true,
|
Description: self.c.Tr.Execute,
|
||||||
|
Display: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
Key: opts.GetKey(opts.Config.Universal.Return),
|
||||||
@ -47,7 +55,7 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *MenuController) GetOnClick() func() error {
|
func (self *MenuController) GetOnClick() func() error {
|
||||||
return self.press
|
return self.withItemGraceful(self.press)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MenuController) GetOnFocus() func(types.OnFocusOpts) error {
|
func (self *MenuController) GetOnFocus() func(types.OnFocusOpts) error {
|
||||||
@ -60,8 +68,8 @@ func (self *MenuController) GetOnFocus() func(types.OnFocusOpts) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MenuController) press() error {
|
func (self *MenuController) press(selectedItem *types.MenuItem) error {
|
||||||
return self.context().OnMenuPress(self.context().GetSelected())
|
return self.context().OnMenuPress(selectedItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MenuController) close() error {
|
func (self *MenuController) close() error {
|
||||||
@ -73,10 +81,6 @@ func (self *MenuController) close() error {
|
|||||||
return self.c.PopContext()
|
return self.c.PopContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *MenuController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *MenuController) context() *context.MenuContext {
|
func (self *MenuController) context() *context.MenuContext {
|
||||||
return self.c.Contexts().Menu
|
return self.c.Contexts().Menu
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,11 @@ type MergeConflictsController struct {
|
|||||||
var _ types.IController = &MergeConflictsController{}
|
var _ types.IController = &MergeConflictsController{}
|
||||||
|
|
||||||
func NewMergeConflictsController(
|
func NewMergeConflictsController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *MergeConflictsController {
|
) *MergeConflictsController {
|
||||||
return &MergeConflictsController{
|
return &MergeConflictsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,11 @@ type PatchBuildingController struct {
|
|||||||
var _ types.IController = &PatchBuildingController{}
|
var _ types.IController = &PatchBuildingController{}
|
||||||
|
|
||||||
func NewPatchBuildingController(
|
func NewPatchBuildingController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *PatchBuildingController {
|
) *PatchBuildingController {
|
||||||
return &PatchBuildingController{
|
return &PatchBuildingController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,23 +1,30 @@
|
|||||||
package controllers
|
package controllers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ReflogCommitsController struct {
|
type ReflogCommitsController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Commit]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &ReflogCommitsController{}
|
var _ types.IController = &ReflogCommitsController{}
|
||||||
|
|
||||||
func NewReflogCommitsController(
|
func NewReflogCommitsController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *ReflogCommitsController {
|
) *ReflogCommitsController {
|
||||||
return &ReflogCommitsController{
|
return &ReflogCommitsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*models.Commit](
|
||||||
|
c,
|
||||||
|
c.Contexts().ReflogCommits,
|
||||||
|
c.Contexts().ReflogCommits.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,17 +11,23 @@ import (
|
|||||||
|
|
||||||
type RemoteBranchesController struct {
|
type RemoteBranchesController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.RemoteBranch]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &RemoteBranchesController{}
|
var _ types.IController = &RemoteBranchesController{}
|
||||||
|
|
||||||
func NewRemoteBranchesController(
|
func NewRemoteBranchesController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *RemoteBranchesController {
|
) *RemoteBranchesController {
|
||||||
return &RemoteBranchesController{
|
return &RemoteBranchesController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*models.RemoteBranch](
|
||||||
|
c,
|
||||||
|
c.Contexts().RemoteBranches,
|
||||||
|
c.Contexts().RemoteBranches.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,33 +36,39 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
// gonna use the exact same handler as the 'n' keybinding because everybody wants this to happen when they checkout a remote branch
|
// gonna use the exact same handler as the 'n' keybinding because everybody wants this to happen when they checkout a remote branch
|
||||||
Handler: self.checkSelected(self.newLocalBranch),
|
Handler: self.withItem(self.newLocalBranch),
|
||||||
Description: self.c.Tr.Checkout,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.Checkout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.checkSelected(self.newLocalBranch),
|
Handler: self.withItem(self.newLocalBranch),
|
||||||
Description: self.c.Tr.NewBranch,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.NewBranch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
||||||
Handler: opts.Guards.OutsideFilterMode(self.checkSelected(self.merge)),
|
Handler: opts.Guards.OutsideFilterMode(self.withItem(self.merge)),
|
||||||
Description: self.c.Tr.MergeIntoCurrentBranch,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.MergeIntoCurrentBranch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
||||||
Handler: opts.Guards.OutsideFilterMode(self.checkSelected(self.rebase)),
|
Handler: opts.Guards.OutsideFilterMode(self.withItem(self.rebase)),
|
||||||
Description: self.c.Tr.RebaseBranch,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.RebaseBranch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelected(self.delete),
|
Handler: self.withItem(self.delete),
|
||||||
Description: self.c.Tr.DeleteRemoteTag,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.DeleteRemoteTag,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
||||||
Handler: self.checkSelected(self.setAsUpstream),
|
Handler: self.withItem(self.setAsUpstream),
|
||||||
Description: self.c.Tr.SetAsUpstream,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.SetAsUpstream,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.SortOrder),
|
Key: opts.GetKey(opts.Config.Branches.SortOrder),
|
||||||
@ -65,10 +77,11 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||||
Handler: self.checkSelected(self.createResetMenu),
|
Handler: self.withItem(self.createResetMenu),
|
||||||
Description: self.c.Tr.ViewResetOptions,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.ViewResetOptions,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,25 +109,10 @@ func (self *RemoteBranchesController) GetOnRenderToMain() func() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *RemoteBranchesController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *RemoteBranchesController) context() *context.RemoteBranchesContext {
|
func (self *RemoteBranchesController) context() *context.RemoteBranchesContext {
|
||||||
return self.c.Contexts().RemoteBranches
|
return self.c.Contexts().RemoteBranches
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *RemoteBranchesController) checkSelected(callback func(*models.RemoteBranch) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
selectedItem := self.context().GetSelected()
|
|
||||||
if selectedItem == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(selectedItem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *RemoteBranchesController) delete(selectedBranch *models.RemoteBranch) error {
|
func (self *RemoteBranchesController) delete(selectedBranch *models.RemoteBranch) error {
|
||||||
return self.c.Helpers().BranchesHelper.ConfirmDeleteRemote(selectedBranch.RemoteName, selectedBranch.Name)
|
return self.c.Helpers().BranchesHelper.ConfirmDeleteRemote(selectedBranch.RemoteName, selectedBranch.Name)
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
type RemotesController struct {
|
type RemotesController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Remote]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
|
|
||||||
setRemoteBranches func([]*models.RemoteBranch)
|
setRemoteBranches func([]*models.RemoteBranch)
|
||||||
@ -22,12 +23,17 @@ type RemotesController struct {
|
|||||||
var _ types.IController = &RemotesController{}
|
var _ types.IController = &RemotesController{}
|
||||||
|
|
||||||
func NewRemotesController(
|
func NewRemotesController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
setRemoteBranches func([]*models.RemoteBranch),
|
setRemoteBranches func([]*models.RemoteBranch),
|
||||||
) *RemotesController {
|
) *RemotesController {
|
||||||
return &RemotesController{
|
return &RemotesController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*models.Remote](
|
||||||
|
c,
|
||||||
|
c.Contexts().Remotes,
|
||||||
|
c.Contexts().Remotes.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
setRemoteBranches: setRemoteBranches,
|
setRemoteBranches: setRemoteBranches,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,13 +41,15 @@ func NewRemotesController(
|
|||||||
func (self *RemotesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *RemotesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
||||||
Handler: self.checkSelected(self.enter),
|
Handler: self.withItem(self.enter),
|
||||||
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.FetchRemote),
|
Key: opts.GetKey(opts.Config.Branches.FetchRemote),
|
||||||
Handler: self.checkSelected(self.fetch),
|
Handler: self.withItem(self.fetch),
|
||||||
Description: self.c.Tr.FetchRemote,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.FetchRemote,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
@ -49,24 +57,22 @@ func (self *RemotesController) GetKeybindings(opts types.KeybindingsOpts) []*typ
|
|||||||
Description: self.c.Tr.AddNewRemote,
|
Description: self.c.Tr.AddNewRemote,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelected(self.remove),
|
Handler: self.withItem(self.remove),
|
||||||
Description: self.c.Tr.RemoveRemote,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.RemoveRemote,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Edit),
|
Key: opts.GetKey(opts.Config.Universal.Edit),
|
||||||
Handler: self.checkSelected(self.edit),
|
Handler: self.withItem(self.edit),
|
||||||
Description: self.c.Tr.EditRemote,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.EditRemote,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return bindings
|
return bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *RemotesController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *RemotesController) context() *context.RemotesContext {
|
func (self *RemotesController) context() *context.RemotesContext {
|
||||||
return self.c.Contexts().Remotes
|
return self.c.Contexts().Remotes
|
||||||
}
|
}
|
||||||
@ -94,7 +100,7 @@ func (self *RemotesController) GetOnRenderToMain() func() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *RemotesController) GetOnClick() func() error {
|
func (self *RemotesController) GetOnClick() func() error {
|
||||||
return self.checkSelected(self.enter)
|
return self.withItemGraceful(self.enter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *RemotesController) enter(remote *models.Remote) error {
|
func (self *RemotesController) enter(remote *models.Remote) error {
|
||||||
@ -208,14 +214,3 @@ func (self *RemotesController) fetch(remote *models.Remote) error {
|
|||||||
return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.REMOTES}})
|
return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.BRANCHES, types.REMOTES}})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *RemotesController) checkSelected(callback func(*models.Remote) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
file := self.context().GetSelected()
|
|
||||||
if file == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(file)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -13,11 +13,11 @@ type SearchPromptController struct {
|
|||||||
var _ types.IController = &SearchPromptController{}
|
var _ types.IController = &SearchPromptController{}
|
||||||
|
|
||||||
func NewSearchPromptController(
|
func NewSearchPromptController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *SearchPromptController {
|
) *SearchPromptController {
|
||||||
return &SearchPromptController{
|
return &SearchPromptController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ type SideWindowControllerFactory struct {
|
|||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSideWindowControllerFactory(common *ControllerCommon) *SideWindowControllerFactory {
|
func NewSideWindowControllerFactory(c *ControllerCommon) *SideWindowControllerFactory {
|
||||||
return &SideWindowControllerFactory{c: common}
|
return &SideWindowControllerFactory{c: c}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SideWindowControllerFactory) Create(context types.Context) types.IController {
|
func (self *SideWindowControllerFactory) Create(context types.Context) types.IController {
|
||||||
@ -24,12 +24,12 @@ type SideWindowController struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewSideWindowController(
|
func NewSideWindowController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
context types.Context,
|
context types.Context,
|
||||||
) *SideWindowController {
|
) *SideWindowController {
|
||||||
return &SideWindowController{
|
return &SideWindowController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
context: context,
|
context: context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,11 +13,11 @@ type SnakeController struct {
|
|||||||
var _ types.IController = &SnakeController{}
|
var _ types.IController = &SnakeController{}
|
||||||
|
|
||||||
func NewSnakeController(
|
func NewSnakeController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *SnakeController {
|
) *SnakeController {
|
||||||
return &SnakeController{
|
return &SnakeController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,14 +23,14 @@ type StagingController struct {
|
|||||||
var _ types.IController = &StagingController{}
|
var _ types.IController = &StagingController{}
|
||||||
|
|
||||||
func NewStagingController(
|
func NewStagingController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
context types.IPatchExplorerContext,
|
context types.IPatchExplorerContext,
|
||||||
otherContext types.IPatchExplorerContext,
|
otherContext types.IPatchExplorerContext,
|
||||||
staged bool,
|
staged bool,
|
||||||
) *StagingController {
|
) *StagingController {
|
||||||
return &StagingController{
|
return &StagingController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
context: context,
|
context: context,
|
||||||
otherContext: otherContext,
|
otherContext: otherContext,
|
||||||
staged: staged,
|
staged: staged,
|
||||||
|
@ -9,46 +9,57 @@ import (
|
|||||||
|
|
||||||
type StashController struct {
|
type StashController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.StashEntry]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &StashController{}
|
var _ types.IController = &StashController{}
|
||||||
|
|
||||||
func NewStashController(
|
func NewStashController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *StashController {
|
) *StashController {
|
||||||
return &StashController{
|
return &StashController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*models.StashEntry](
|
||||||
|
c,
|
||||||
|
c.Contexts().Stash,
|
||||||
|
c.Contexts().Stash.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StashController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *StashController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.checkSelected(self.handleStashApply),
|
Handler: self.withItem(self.handleStashApply),
|
||||||
Description: self.c.Tr.Apply,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.Apply,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Stash.PopStash),
|
Key: opts.GetKey(opts.Config.Stash.PopStash),
|
||||||
Handler: self.checkSelected(self.handleStashPop),
|
Handler: self.withItem(self.handleStashPop),
|
||||||
Description: self.c.Tr.Pop,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.Pop,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelected(self.handleStashDrop),
|
Handler: self.withItem(self.handleStashDrop),
|
||||||
Description: self.c.Tr.Drop,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.Drop,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.checkSelected(self.handleNewBranchOffStashEntry),
|
Handler: self.withItem(self.handleNewBranchOffStashEntry),
|
||||||
Description: self.c.Tr.NewBranch,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.NewBranch,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Stash.RenameStash),
|
Key: opts.GetKey(opts.Config.Stash.RenameStash),
|
||||||
Handler: self.checkSelected(self.handleRenameStashEntry),
|
Handler: self.withItem(self.handleRenameStashEntry),
|
||||||
Description: self.c.Tr.RenameStash,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.RenameStash,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,21 +91,6 @@ func (self *StashController) GetOnRenderToMain() func() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *StashController) checkSelected(callback func(*models.StashEntry) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
item := self.context().GetSelected()
|
|
||||||
if item == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *StashController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *StashController) context() *context.StashContext {
|
func (self *StashController) context() *context.StashContext {
|
||||||
return self.c.Contexts().Stash
|
return self.c.Contexts().Stash
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,11 @@ type StatusController struct {
|
|||||||
var _ types.IController = &StatusController{}
|
var _ types.IController = &StatusController{}
|
||||||
|
|
||||||
func NewStatusController(
|
func NewStatusController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *StatusController {
|
) *StatusController {
|
||||||
return &StatusController{
|
return &StatusController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,23 +2,30 @@ package controllers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/jesseduffield/gocui"
|
"github.com/jesseduffield/gocui"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SubCommitsController struct {
|
type SubCommitsController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Commit]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &SubCommitsController{}
|
var _ types.IController = &SubCommitsController{}
|
||||||
|
|
||||||
func NewSubCommitsController(
|
func NewSubCommitsController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *SubCommitsController {
|
) *SubCommitsController {
|
||||||
return &SubCommitsController{
|
return &SubCommitsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*models.Commit](
|
||||||
|
c,
|
||||||
|
c.Contexts().SubCommits,
|
||||||
|
c.Contexts().SubCommits.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,41 +14,51 @@ import (
|
|||||||
|
|
||||||
type SubmodulesController struct {
|
type SubmodulesController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.SubmoduleConfig]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &SubmodulesController{}
|
var _ types.IController = &SubmodulesController{}
|
||||||
|
|
||||||
func NewSubmodulesController(
|
func NewSubmodulesController(
|
||||||
controllerCommon *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *SubmodulesController {
|
) *SubmodulesController {
|
||||||
return &SubmodulesController{
|
return &SubmodulesController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: controllerCommon,
|
ListControllerTrait: NewListControllerTrait[*models.SubmoduleConfig](
|
||||||
|
c,
|
||||||
|
c.Contexts().Submodules,
|
||||||
|
c.Contexts().Submodules.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
return []*types.Binding{
|
return []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
||||||
Handler: self.checkSelected(self.enter),
|
Handler: self.withItem(self.enter),
|
||||||
Description: self.c.Tr.EnterSubmodule,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.EnterSubmodule,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.checkSelected(self.enter),
|
Handler: self.withItem(self.enter),
|
||||||
Description: self.c.Tr.EnterSubmodule,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.EnterSubmodule,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelected(self.remove),
|
Handler: self.withItem(self.remove),
|
||||||
Description: self.c.Tr.RemoveSubmodule,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.RemoveSubmodule,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Submodules.Update),
|
Key: opts.GetKey(opts.Config.Submodules.Update),
|
||||||
Handler: self.checkSelected(self.update),
|
Handler: self.withItem(self.update),
|
||||||
Description: self.c.Tr.SubmoduleUpdate,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.SubmoduleUpdate,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
@ -56,14 +66,16 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*
|
|||||||
Description: self.c.Tr.AddSubmodule,
|
Description: self.c.Tr.AddSubmodule,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Edit),
|
Key: opts.GetKey(opts.Config.Universal.Edit),
|
||||||
Handler: self.checkSelected(self.editURL),
|
Handler: self.withItem(self.editURL),
|
||||||
Description: self.c.Tr.EditSubmoduleUrl,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.EditSubmoduleUrl,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Submodules.Init),
|
Key: opts.GetKey(opts.Config.Submodules.Init),
|
||||||
Handler: self.checkSelected(self.init),
|
Handler: self.withItem(self.init),
|
||||||
Description: self.c.Tr.InitSubmodule,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.InitSubmodule,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Submodules.BulkMenu),
|
Key: opts.GetKey(opts.Config.Submodules.BulkMenu),
|
||||||
@ -80,7 +92,7 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *SubmodulesController) GetOnClick() func() error {
|
func (self *SubmodulesController) GetOnClick() func() error {
|
||||||
return self.checkSelected(self.enter)
|
return self.withItemGraceful(self.enter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SubmodulesController) GetOnRenderToMain() func() error {
|
func (self *SubmodulesController) GetOnRenderToMain() func() error {
|
||||||
@ -265,21 +277,6 @@ func (self *SubmodulesController) easterEgg() error {
|
|||||||
return self.c.PushContext(self.c.Contexts().Snake)
|
return self.c.PushContext(self.c.Contexts().Snake)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SubmodulesController) checkSelected(callback func(*models.SubmoduleConfig) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
submodule := self.context().GetSelected()
|
|
||||||
if submodule == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(submodule)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *SubmodulesController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *SubmodulesController) context() *context.SubmodulesContext {
|
func (self *SubmodulesController) context() *context.SubmodulesContext {
|
||||||
return self.c.Contexts().Submodules
|
return self.c.Contexts().Submodules
|
||||||
}
|
}
|
||||||
|
@ -7,25 +7,32 @@ import (
|
|||||||
|
|
||||||
type SuggestionsController struct {
|
type SuggestionsController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*types.Suggestion]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &SuggestionsController{}
|
var _ types.IController = &SuggestionsController{}
|
||||||
|
|
||||||
func NewSuggestionsController(
|
func NewSuggestionsController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *SuggestionsController {
|
) *SuggestionsController {
|
||||||
return &SuggestionsController{
|
return &SuggestionsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*types.Suggestion](
|
||||||
|
c,
|
||||||
|
c.Contexts().Suggestions,
|
||||||
|
c.Contexts().Suggestions.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SuggestionsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *SuggestionsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
||||||
Handler: func() error { return self.context().State.OnConfirm() },
|
Handler: func() error { return self.context().State.OnConfirm() },
|
||||||
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
Key: opts.GetKey(opts.Config.Universal.Return),
|
||||||
@ -47,10 +54,6 @@ func (self *SuggestionsController) GetOnFocusLost() func(types.OnFocusLostOpts)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SuggestionsController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *SuggestionsController) context() *context.SuggestionsContext {
|
func (self *SuggestionsController) context() *context.SuggestionsContext {
|
||||||
return self.c.Contexts().Suggestions
|
return self.c.Contexts().Suggestions
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,16 @@ import (
|
|||||||
var _ types.IController = &SwitchToDiffFilesController{}
|
var _ types.IController = &SwitchToDiffFilesController{}
|
||||||
|
|
||||||
type CanSwitchToDiffFiles interface {
|
type CanSwitchToDiffFiles interface {
|
||||||
types.Context
|
types.IListContext
|
||||||
CanRebase() bool
|
CanRebase() bool
|
||||||
GetSelectedRef() types.Ref
|
GetSelectedRef() types.Ref
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not using our ListControllerTrait because our 'selected' item is not a list item
|
||||||
|
// but an attribute on it i.e. the ref of an item.
|
||||||
type SwitchToDiffFilesController struct {
|
type SwitchToDiffFilesController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[types.Ref]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
context CanSwitchToDiffFiles
|
context CanSwitchToDiffFiles
|
||||||
diffFilesContext *context.CommitFilesContext
|
diffFilesContext *context.CommitFilesContext
|
||||||
@ -28,7 +31,12 @@ func NewSwitchToDiffFilesController(
|
|||||||
diffFilesContext *context.CommitFilesContext,
|
diffFilesContext *context.CommitFilesContext,
|
||||||
) *SwitchToDiffFilesController {
|
) *SwitchToDiffFilesController {
|
||||||
return &SwitchToDiffFilesController{
|
return &SwitchToDiffFilesController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
|
ListControllerTrait: NewListControllerTrait[types.Ref](
|
||||||
|
c,
|
||||||
|
context,
|
||||||
|
context.GetSelectedRef,
|
||||||
|
),
|
||||||
c: c,
|
c: c,
|
||||||
context: context,
|
context: context,
|
||||||
diffFilesContext: diffFilesContext,
|
diffFilesContext: diffFilesContext,
|
||||||
@ -38,9 +46,10 @@ func NewSwitchToDiffFilesController(
|
|||||||
func (self *SwitchToDiffFilesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *SwitchToDiffFilesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
||||||
Handler: self.checkSelected(self.enter),
|
Handler: self.withItem(self.enter),
|
||||||
Description: self.c.Tr.ViewItemFiles,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.ViewItemFiles,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,18 +57,7 @@ func (self *SwitchToDiffFilesController) GetKeybindings(opts types.KeybindingsOp
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *SwitchToDiffFilesController) GetOnClick() func() error {
|
func (self *SwitchToDiffFilesController) GetOnClick() func() error {
|
||||||
return self.checkSelected(self.enter)
|
return self.withItemGraceful(self.enter)
|
||||||
}
|
|
||||||
|
|
||||||
func (self *SwitchToDiffFilesController) checkSelected(callback func(types.Ref) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
ref := self.context.GetSelectedRef()
|
|
||||||
if ref == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(ref)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SwitchToDiffFilesController) enter(ref types.Ref) error {
|
func (self *SwitchToDiffFilesController) enter(ref types.Ref) error {
|
||||||
@ -70,10 +68,6 @@ func (self *SwitchToDiffFilesController) enter(ref types.Ref) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SwitchToDiffFilesController) Context() types.Context {
|
|
||||||
return self.context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *SwitchToDiffFilesController) viewFiles(opts SwitchToCommitFilesContextOpts) error {
|
func (self *SwitchToDiffFilesController) viewFiles(opts SwitchToCommitFilesContextOpts) error {
|
||||||
diffFilesContext := self.diffFilesContext
|
diffFilesContext := self.diffFilesContext
|
||||||
|
|
||||||
|
@ -8,34 +8,43 @@ import (
|
|||||||
var _ types.IController = &SwitchToSubCommitsController{}
|
var _ types.IController = &SwitchToSubCommitsController{}
|
||||||
|
|
||||||
type CanSwitchToSubCommits interface {
|
type CanSwitchToSubCommits interface {
|
||||||
types.Context
|
types.IListContext
|
||||||
GetSelectedRef() types.Ref
|
GetSelectedRef() types.Ref
|
||||||
ShowBranchHeadsInSubCommits() bool
|
ShowBranchHeadsInSubCommits() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not using our ListControllerTrait because our 'selected' item is not a list item
|
||||||
|
// but an attribute on it i.e. the ref of an item.
|
||||||
type SwitchToSubCommitsController struct {
|
type SwitchToSubCommitsController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[types.Ref]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
context CanSwitchToSubCommits
|
context CanSwitchToSubCommits
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSwitchToSubCommitsController(
|
func NewSwitchToSubCommitsController(
|
||||||
controllerCommon *ControllerCommon,
|
c *ControllerCommon,
|
||||||
context CanSwitchToSubCommits,
|
context CanSwitchToSubCommits,
|
||||||
) *SwitchToSubCommitsController {
|
) *SwitchToSubCommitsController {
|
||||||
return &SwitchToSubCommitsController{
|
return &SwitchToSubCommitsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: controllerCommon,
|
ListControllerTrait: NewListControllerTrait[types.Ref](
|
||||||
context: context,
|
c,
|
||||||
|
context,
|
||||||
|
context.GetSelectedRef,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
|
context: context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SwitchToSubCommitsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *SwitchToSubCommitsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Handler: self.viewCommits,
|
Handler: self.viewCommits,
|
||||||
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.ViewCommits,
|
Key: opts.GetKey(opts.Config.Universal.GoInto),
|
||||||
|
Description: self.c.Tr.ViewCommits,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +68,3 @@ func (self *SwitchToSubCommitsController) viewCommits() error {
|
|||||||
ShowBranchHeads: self.context.ShowBranchHeadsInSubCommits(),
|
ShowBranchHeads: self.context.ShowBranchHeadsInSubCommits(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *SwitchToSubCommitsController) Context() types.Context {
|
|
||||||
return self.context
|
|
||||||
}
|
|
||||||
|
@ -10,37 +10,46 @@ import (
|
|||||||
|
|
||||||
type TagsController struct {
|
type TagsController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Tag]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &TagsController{}
|
var _ types.IController = &TagsController{}
|
||||||
|
|
||||||
func NewTagsController(
|
func NewTagsController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *TagsController {
|
) *TagsController {
|
||||||
return &TagsController{
|
return &TagsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*models.Tag](
|
||||||
|
c,
|
||||||
|
c.Contexts().Tags,
|
||||||
|
c.Contexts().Tags.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.withSelectedTag(self.checkout),
|
Handler: self.withItem(self.checkout),
|
||||||
Description: self.c.Tr.Checkout,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.Checkout,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.withSelectedTag(self.delete),
|
Handler: self.withItem(self.delete),
|
||||||
Description: self.c.Tr.ViewDeleteOptions,
|
Description: self.c.Tr.ViewDeleteOptions,
|
||||||
OpensMenu: true,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.PushTag),
|
Key: opts.GetKey(opts.Config.Branches.PushTag),
|
||||||
Handler: self.withSelectedTag(self.push),
|
Handler: self.withItem(self.push),
|
||||||
Description: self.c.Tr.PushTag,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.PushTag,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
@ -48,10 +57,11 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||||||
Description: self.c.Tr.CreateTag,
|
Description: self.c.Tr.CreateTag,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||||
Handler: self.withSelectedTag(self.createResetMenu),
|
Handler: self.withItem(self.createResetMenu),
|
||||||
Description: self.c.Tr.ViewResetOptions,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
OpensMenu: true,
|
Description: self.c.Tr.ViewResetOptions,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,21 +225,6 @@ func (self *TagsController) create() error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *TagsController) withSelectedTag(f func(tag *models.Tag) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
tag := self.context().GetSelected()
|
|
||||||
if tag == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return f(tag)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TagsController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *TagsController) context() *context.TagsContext {
|
func (self *TagsController) context() *context.TagsContext {
|
||||||
return self.c.Contexts().Tags
|
return self.c.Contexts().Tags
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,11 @@ type UndoController struct {
|
|||||||
var _ types.IController = &UndoController{}
|
var _ types.IController = &UndoController{}
|
||||||
|
|
||||||
func NewUndoController(
|
func NewUndoController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *UndoController {
|
) *UndoController {
|
||||||
return &UndoController{
|
return &UndoController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,15 +14,21 @@ type CanViewWorktreeOptions interface {
|
|||||||
|
|
||||||
type WorktreeOptionsController struct {
|
type WorktreeOptionsController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[string]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
context CanViewWorktreeOptions
|
context CanViewWorktreeOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWorktreeOptionsController(controllerCommon *ControllerCommon, context CanViewWorktreeOptions) *WorktreeOptionsController {
|
func NewWorktreeOptionsController(c *ControllerCommon, context CanViewWorktreeOptions) *WorktreeOptionsController {
|
||||||
return &WorktreeOptionsController{
|
return &WorktreeOptionsController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: controllerCommon,
|
ListControllerTrait: NewListControllerTrait[string](
|
||||||
context: context,
|
c,
|
||||||
|
context,
|
||||||
|
context.GetSelectedItemId,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
|
context: context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +36,7 @@ func (self *WorktreeOptionsController) GetKeybindings(opts types.KeybindingsOpts
|
|||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Worktrees.ViewWorktreeOptions),
|
Key: opts.GetKey(opts.Config.Worktrees.ViewWorktreeOptions),
|
||||||
Handler: self.checkSelected(self.viewWorktreeOptions),
|
Handler: self.withItem(self.viewWorktreeOptions),
|
||||||
Description: self.c.Tr.ViewWorktreeOptions,
|
Description: self.c.Tr.ViewWorktreeOptions,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
@ -39,21 +45,6 @@ func (self *WorktreeOptionsController) GetKeybindings(opts types.KeybindingsOpts
|
|||||||
return bindings
|
return bindings
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreeOptionsController) checkSelected(callback func(string) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
ref := self.context.GetSelectedItemId()
|
|
||||||
if ref == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(ref)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *WorktreeOptionsController) Context() types.Context {
|
|
||||||
return self.context
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *WorktreeOptionsController) viewWorktreeOptions(ref string) error {
|
func (self *WorktreeOptionsController) viewWorktreeOptions(ref string) error {
|
||||||
return self.c.Helpers().Worktree.ViewWorktreeOptions(self.context, ref)
|
return self.c.Helpers().Worktree.ViewWorktreeOptions(self.context, ref)
|
||||||
}
|
}
|
||||||
|
@ -13,17 +13,23 @@ import (
|
|||||||
|
|
||||||
type WorktreesController struct {
|
type WorktreesController struct {
|
||||||
baseController
|
baseController
|
||||||
|
*ListControllerTrait[*models.Worktree]
|
||||||
c *ControllerCommon
|
c *ControllerCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ types.IController = &WorktreesController{}
|
var _ types.IController = &WorktreesController{}
|
||||||
|
|
||||||
func NewWorktreesController(
|
func NewWorktreesController(
|
||||||
common *ControllerCommon,
|
c *ControllerCommon,
|
||||||
) *WorktreesController {
|
) *WorktreesController {
|
||||||
return &WorktreesController{
|
return &WorktreesController{
|
||||||
baseController: baseController{},
|
baseController: baseController{},
|
||||||
c: common,
|
ListControllerTrait: NewListControllerTrait[*models.Worktree](
|
||||||
|
c,
|
||||||
|
c.Contexts().Worktrees,
|
||||||
|
c.Contexts().Worktrees.GetSelected,
|
||||||
|
),
|
||||||
|
c: c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,24 +41,28 @@ func (self *WorktreesController) GetKeybindings(opts types.KeybindingsOpts) []*t
|
|||||||
Description: self.c.Tr.CreateWorktree,
|
Description: self.c.Tr.CreateWorktree,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.checkSelected(self.enter),
|
Handler: self.withItem(self.enter),
|
||||||
Description: self.c.Tr.SwitchToWorktree,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.SwitchToWorktree,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
||||||
Handler: self.checkSelected(self.enter),
|
Handler: self.withItem(self.enter),
|
||||||
Description: self.c.Tr.SwitchToWorktree,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.SwitchToWorktree,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
||||||
Handler: self.checkSelected(self.open),
|
Handler: self.withItem(self.open),
|
||||||
Description: self.c.Tr.OpenInEditor,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.OpenInEditor,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.checkSelected(self.remove),
|
Handler: self.withItem(self.remove),
|
||||||
Description: self.c.Tr.RemoveWorktree,
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
|
Description: self.c.Tr.RemoveWorktree,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +123,7 @@ func (self *WorktreesController) remove(worktree *models.Worktree) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreesController) GetOnClick() func() error {
|
func (self *WorktreesController) GetOnClick() func() error {
|
||||||
return self.checkSelected(self.enter)
|
return self.withItemGraceful(self.enter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreesController) enter(worktree *models.Worktree) error {
|
func (self *WorktreesController) enter(worktree *models.Worktree) error {
|
||||||
@ -124,21 +134,6 @@ func (self *WorktreesController) open(worktree *models.Worktree) error {
|
|||||||
return self.c.Helpers().Files.OpenDirInEditor(worktree.Path)
|
return self.c.Helpers().Files.OpenDirInEditor(worktree.Path)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *WorktreesController) checkSelected(callback func(worktree *models.Worktree) error) func() error {
|
|
||||||
return func() error {
|
|
||||||
worktree := self.context().GetSelected()
|
|
||||||
if worktree == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return callback(worktree)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *WorktreesController) Context() types.Context {
|
|
||||||
return self.context()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *WorktreesController) context() *context.WorktreesContext {
|
func (self *WorktreesController) context() *context.WorktreesContext {
|
||||||
return self.c.Contexts().Worktrees
|
return self.c.Contexts().Worktrees
|
||||||
}
|
}
|
||||||
|
@ -139,6 +139,28 @@ func (gui *Gui) handleCopySelectedSideContextItemToClipboard() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) getCopySelectedSideContextItemToClipboardDisabledReason() *types.DisabledReason {
|
||||||
|
// important to note that this assumes we've selected an item in a side context
|
||||||
|
currentSideContext := gui.c.CurrentSideContext()
|
||||||
|
if currentSideContext == nil {
|
||||||
|
// This should never happen but if it does we'll just ignore the keypress
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
listContext, ok := currentSideContext.(types.IListContext)
|
||||||
|
if !ok {
|
||||||
|
// This should never happen but if it does we'll just ignore the keypress
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
startIdx, endIdx := listContext.GetList().GetSelectionRange()
|
||||||
|
if startIdx != endIdx {
|
||||||
|
return &types.DisabledReason{Text: gui.Tr.RangeSelectNotSupported}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (gui *Gui) setCaption(caption string) {
|
func (gui *Gui) setCaption(caption string) {
|
||||||
gui.Views.Options.FgColor = gocui.ColorWhite
|
gui.Views.Options.FgColor = gocui.ColorWhite
|
||||||
gui.Views.Options.FgColor |= gocui.AttrBold
|
gui.Views.Options.FgColor |= gocui.AttrBold
|
||||||
|
@ -123,28 +123,32 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
|
|||||||
Handler: self.scrollDownMain,
|
Handler: self.scrollDownMain,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "files",
|
ViewName: "files",
|
||||||
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.CopyFileNameToClipboard,
|
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
|
||||||
|
Description: self.c.Tr.CopyFileNameToClipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "localBranches",
|
ViewName: "localBranches",
|
||||||
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.CopyBranchNameToClipboard,
|
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
|
||||||
|
Description: self.c.Tr.CopyBranchNameToClipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "remoteBranches",
|
ViewName: "remoteBranches",
|
||||||
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.CopyBranchNameToClipboard,
|
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
|
||||||
|
Description: self.c.Tr.CopyBranchNameToClipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "commits",
|
ViewName: "commits",
|
||||||
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.CopyCommitShaToClipboard,
|
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
|
||||||
|
Description: self.c.Tr.CopyCommitShaToClipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "commits",
|
ViewName: "commits",
|
||||||
@ -153,16 +157,18 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
|
|||||||
Description: self.c.Tr.ResetCherryPick,
|
Description: self.c.Tr.ResetCherryPick,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "reflogCommits",
|
ViewName: "reflogCommits",
|
||||||
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.CopyCommitShaToClipboard,
|
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
|
||||||
|
Description: self.c.Tr.CopyCommitShaToClipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "subCommits",
|
ViewName: "subCommits",
|
||||||
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.CopyCommitShaToClipboard,
|
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
|
||||||
|
Description: self.c.Tr.CopyCommitShaToClipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "information",
|
ViewName: "information",
|
||||||
@ -171,10 +177,11 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
|
|||||||
Handler: self.handleInfoClick,
|
Handler: self.handleInfoClick,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "commitFiles",
|
ViewName: "commitFiles",
|
||||||
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.CopyCommitFileNameToClipboard,
|
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
|
||||||
|
Description: self.c.Tr.CopyCommitFileNameToClipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "",
|
ViewName: "",
|
||||||
@ -240,10 +247,11 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
|
|||||||
Handler: self.scrollDownConfirmationPanel,
|
Handler: self.scrollDownConfirmationPanel,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "submodules",
|
ViewName: "submodules",
|
||||||
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
|
||||||
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
Handler: self.handleCopySelectedSideContextItemToClipboard,
|
||||||
Description: self.c.Tr.CopySubmoduleNameToClipboard,
|
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
|
||||||
|
Description: self.c.Tr.CopySubmoduleNameToClipboard,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "extras",
|
ViewName: "extras",
|
||||||
|
@ -231,6 +231,7 @@ type IListCursor interface {
|
|||||||
GetRangeStartIdx() (int, bool)
|
GetRangeStartIdx() (int, bool)
|
||||||
GetSelectionRange() (int, int)
|
GetSelectionRange() (int, int)
|
||||||
IsSelectingRange() bool
|
IsSelectingRange() bool
|
||||||
|
AreMultipleItemsSelected() bool
|
||||||
ToggleStickyRange()
|
ToggleStickyRange()
|
||||||
ExpandNonStickyRange(int)
|
ExpandNonStickyRange(int)
|
||||||
}
|
}
|
||||||
|
@ -644,7 +644,6 @@ type TranslationSet struct {
|
|||||||
MarkedCommitMarker string
|
MarkedCommitMarker string
|
||||||
PleaseGoToURL string
|
PleaseGoToURL string
|
||||||
DisabledMenuItemPrefix string
|
DisabledMenuItemPrefix string
|
||||||
NoCommitSelected string
|
|
||||||
NoCopiedCommits string
|
NoCopiedCommits string
|
||||||
QuickStartInteractiveRebase string
|
QuickStartInteractiveRebase string
|
||||||
QuickStartInteractiveRebaseTooltip string
|
QuickStartInteractiveRebaseTooltip string
|
||||||
@ -652,6 +651,9 @@ type TranslationSet struct {
|
|||||||
ToggleRangeSelect string
|
ToggleRangeSelect string
|
||||||
RangeSelectUp string
|
RangeSelectUp string
|
||||||
RangeSelectDown string
|
RangeSelectDown string
|
||||||
|
RangeSelectNotSupported string
|
||||||
|
NoItemSelected string
|
||||||
|
SelectedItemIsNotABranch string
|
||||||
Actions Actions
|
Actions Actions
|
||||||
Bisect Bisect
|
Bisect Bisect
|
||||||
Log Log
|
Log Log
|
||||||
@ -1478,13 +1480,15 @@ func EnglishTranslationSet() TranslationSet {
|
|||||||
MarkedCommitMarker: "↑↑↑ Will rebase from here ↑↑↑",
|
MarkedCommitMarker: "↑↑↑ Will rebase from here ↑↑↑",
|
||||||
PleaseGoToURL: "Please go to {{.url}}",
|
PleaseGoToURL: "Please go to {{.url}}",
|
||||||
DisabledMenuItemPrefix: "Disabled: ",
|
DisabledMenuItemPrefix: "Disabled: ",
|
||||||
NoCommitSelected: "No commit selected",
|
|
||||||
NoCopiedCommits: "No copied commits",
|
NoCopiedCommits: "No copied commits",
|
||||||
QuickStartInteractiveRebase: "Start interactive rebase",
|
QuickStartInteractiveRebase: "Start interactive rebase",
|
||||||
QuickStartInteractiveRebaseTooltip: "Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.\nIf you would instead like to start an interactive rebase from the selected commit, press `{{.editKey}}`.",
|
QuickStartInteractiveRebaseTooltip: "Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.\nIf you would instead like to start an interactive rebase from the selected commit, press `{{.editKey}}`.",
|
||||||
CannotQuickStartInteractiveRebase: "Cannot start interactive rebase: the HEAD commit is a merge commit or is present on the main branch, so there is no appropriate base commit to start the rebase from. You can start an interactive rebase from a specific commit by selecting the commit and pressing `{{.editKey}}`.",
|
CannotQuickStartInteractiveRebase: "Cannot start interactive rebase: the HEAD commit is a merge commit or is present on the main branch, so there is no appropriate base commit to start the rebase from. You can start an interactive rebase from a specific commit by selecting the commit and pressing `{{.editKey}}`.",
|
||||||
RangeSelectUp: "Range select up",
|
RangeSelectUp: "Range select up",
|
||||||
RangeSelectDown: "Range select down",
|
RangeSelectDown: "Range select down",
|
||||||
|
RangeSelectNotSupported: "Action does not support range selection, please select a single item",
|
||||||
|
NoItemSelected: "No item selected",
|
||||||
|
SelectedItemIsNotABranch: "Selected item is not a branch",
|
||||||
Actions: Actions{
|
Actions: Actions{
|
||||||
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
|
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
|
||||||
CheckoutCommit: "Checkout commit",
|
CheckoutCommit: "Checkout commit",
|
||||||
|
@ -29,10 +29,10 @@ var CopyMenu = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
t.ExpectPopup().Menu().
|
t.ExpectPopup().Menu().
|
||||||
Title(Equals("Copy to clipboard")).
|
Title(Equals("Copy to clipboard")).
|
||||||
Select(Contains("File name")).
|
Select(Contains("File name")).
|
||||||
Tooltip(Equals("Disabled: Nothing to copy")).
|
Tooltip(Equals("Disabled: No item selected")).
|
||||||
Confirm().
|
Confirm().
|
||||||
Tap(func() {
|
Tap(func() {
|
||||||
t.ExpectToast(Equals("Disabled: Nothing to copy"))
|
t.ExpectToast(Equals("Disabled: No item selected"))
|
||||||
}).
|
}).
|
||||||
Cancel()
|
Cancel()
|
||||||
})
|
})
|
||||||
|
@ -22,7 +22,14 @@ var EmptyMenu = NewIntegrationTest(NewIntegrationTestArgs{
|
|||||||
// a string that filters everything out
|
// a string that filters everything out
|
||||||
FilterOrSearch("ljasldkjaslkdjalskdjalsdjaslkd").
|
FilterOrSearch("ljasldkjaslkdjalskdjalsdjaslkd").
|
||||||
IsEmpty().
|
IsEmpty().
|
||||||
Press(keys.Universal.Select)
|
Press(keys.Universal.Select).
|
||||||
|
Tap(func() {
|
||||||
|
t.ExpectToast(Equals("Disabled: No item selected"))
|
||||||
|
}).
|
||||||
|
// escape the search
|
||||||
|
PressEscape().
|
||||||
|
// escape the view
|
||||||
|
PressEscape()
|
||||||
|
|
||||||
// back in the files view, selecting the non-existing menu item was a no-op
|
// back in the files view, selecting the non-existing menu item was a no-op
|
||||||
t.Views().Files().
|
t.Views().Files().
|
||||||
|
Loading…
x
Reference in New Issue
Block a user