1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-17 01:42:45 +02:00

Use DisabledReason for commits panel commands

This commit is contained in:
Stefan Haller
2023-09-15 10:30:48 +02:00
parent c9371f812f
commit 8b6766de79
2 changed files with 153 additions and 81 deletions

View File

@ -44,59 +44,70 @@ func NewLocalCommitsController(
func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding { func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
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.checkSelected(self.squashDown),
Description: self.c.Tr.SquashDown, GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(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.checkSelected(self.fixup),
Description: self.c.Tr.FixupCommit, GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(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.checkSelected(self.reword),
Description: self.c.Tr.RewordCommit, GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(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.checkSelected(self.rewordEditor),
Description: self.c.Tr.RenameCommitEditor, GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(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.checkSelected(self.drop),
Description: self.c.Tr.DeleteCommit, GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(todo.Drop),
Description: self.c.Tr.DeleteCommit,
}, },
{ {
Key: opts.GetKey(opts.Config.Universal.Edit), Key: opts.GetKey(opts.Config.Universal.Edit),
Handler: self.checkSelected(self.edit), Handler: self.checkSelected(self.edit),
Description: self.c.Tr.EditCommit, GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(todo.Edit),
Description: self.c.Tr.EditCommit,
}, },
{ {
Key: opts.GetKey(opts.Config.Commits.PickCommit), Key: opts.GetKey(opts.Config.Commits.PickCommit),
Handler: self.checkSelected(self.pick), Handler: self.checkSelected(self.pick),
Description: self.c.Tr.PickCommit, GetDisabledReason: self.getDisabledReasonForRebaseCommandWithSelectedCommit(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.checkSelected(self.createFixupCommit),
Description: self.c.Tr.CreateFixupCommitDescription, GetDisabledReason: self.disabledIfNoSelectedCommit(),
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.checkSelected(self.squashAllAboveFixupCommits),
Description: self.c.Tr.SquashAboveCommits, GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(self.getDisabledReasonForSquashAllAboveFixupCommits),
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.checkSelected(self.moveDown),
Description: self.c.Tr.MoveDownCommit, GetDisabledReason: self.disabledIfNoSelectedCommit(),
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.checkSelected(self.moveUp),
Description: self.c.Tr.MoveUpCommit, GetDisabledReason: self.disabledIfNoSelectedCommit(),
Description: self.c.Tr.MoveUpCommit,
}, },
{ {
Key: opts.GetKey(opts.Config.Commits.PasteCommits), Key: opts.GetKey(opts.Config.Commits.PasteCommits),
@ -104,10 +115,11 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
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.checkSelected(self.markAsBaseCommit),
Description: self.c.Tr.MarkAsBaseCommit, GetDisabledReason: self.disabledIfNoSelectedCommit(),
Tooltip: self.c.Tr.MarkAsBaseCommitTooltip, Description: self.c.Tr.MarkAsBaseCommit,
Tooltip: self.c.Tr.MarkAsBaseCommitTooltip,
}, },
// overriding these navigation keybindings because we might need to load // overriding these navigation keybindings because we might need to load
// more commits on demand // more commits on demand
@ -131,25 +143,29 @@ 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.checkSelected(self.amendTo),
Description: self.c.Tr.AmendToCommit, GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(self.getDisabledReasonForAmendTo),
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.checkSelected(self.amendAttribute),
Description: self.c.Tr.SetResetCommitAuthor, GetDisabledReason: self.callGetDisabledReasonFuncWithSelectedCommit(self.getDisabledReasonForAmendTo),
OpensMenu: true, Description: self.c.Tr.SetResetCommitAuthor,
OpensMenu: true,
}, },
{ {
Key: opts.GetKey(opts.Config.Commits.RevertCommit), Key: opts.GetKey(opts.Config.Commits.RevertCommit),
Handler: self.checkSelected(self.revert), Handler: self.checkSelected(self.revert),
Description: self.c.Tr.RevertCommit, GetDisabledReason: self.disabledIfNoSelectedCommit(),
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.checkSelected(self.createTag),
Description: self.c.Tr.TagCommit, GetDisabledReason: self.disabledIfNoSelectedCommit(),
Description: self.c.Tr.TagCommit,
}, },
{ {
Key: opts.GetKey(opts.Config.Commits.OpenLogMenu), Key: opts.GetKey(opts.Config.Commits.OpenLogMenu),
@ -208,10 +224,6 @@ func secondaryPatchPanelUpdateOpts(c *ControllerCommon) *types.ViewUpdateOpts {
} }
func (self *LocalCommitsController) squashDown(commit *models.Commit) error { func (self *LocalCommitsController) squashDown(commit *models.Commit) error {
if self.context().GetSelectedLineIdx() >= len(self.c.Model().Commits)-1 {
return self.c.ErrorMsg(self.c.Tr.CannotSquashOrFixupFirstCommit)
}
applied, err := self.handleMidRebaseCommand(todo.Squash, commit) applied, err := self.handleMidRebaseCommand(todo.Squash, commit)
if err != nil { if err != nil {
return err return err
@ -232,11 +244,15 @@ func (self *LocalCommitsController) squashDown(commit *models.Commit) error {
}) })
} }
func (self *LocalCommitsController) fixup(commit *models.Commit) error { func (self *LocalCommitsController) getDisabledReasonForSquashDown(commit *models.Commit) string {
if self.context().GetSelectedLineIdx() >= len(self.c.Model().Commits)-1 { if self.context().GetSelectedLineIdx() >= len(self.c.Model().Commits)-1 {
return self.c.ErrorMsg(self.c.Tr.CannotSquashOrFixupFirstCommit) return self.c.Tr.CannotSquashOrFixupFirstCommit
} }
return self.rebaseCommandEnabled(todo.Squash, commit)
}
func (self *LocalCommitsController) fixup(commit *models.Commit) error {
applied, err := self.handleMidRebaseCommand(todo.Fixup, commit) applied, err := self.handleMidRebaseCommand(todo.Fixup, commit)
if err != nil { if err != nil {
return err return err
@ -257,6 +273,14 @@ func (self *LocalCommitsController) fixup(commit *models.Commit) error {
}) })
} }
func (self *LocalCommitsController) getDisabledReasonForFixup(commit *models.Commit) string {
if self.context().GetSelectedLineIdx() >= len(self.c.Model().Commits)-1 {
return self.c.Tr.CannotSquashOrFixupFirstCommit
}
return self.rebaseCommandEnabled(todo.Squash, commit)
}
func (self *LocalCommitsController) reword(commit *models.Commit) error { func (self *LocalCommitsController) reword(commit *models.Commit) error {
applied, err := self.handleMidRebaseCommand(todo.Reword, commit) applied, err := self.handleMidRebaseCommand(todo.Reword, commit)
if err != nil { if err != nil {
@ -428,34 +452,10 @@ func (self *LocalCommitsController) interactiveRebase(action todo.TodoCommand) e
// commit meaning you are trying to edit the todo file rather than actually // commit meaning you are trying to edit the todo file rather than actually
// begin a rebase. It then updates the todo file with that action // begin a rebase. It then updates the todo file with that action
func (self *LocalCommitsController) handleMidRebaseCommand(action todo.TodoCommand, commit *models.Commit) (bool, error) { func (self *LocalCommitsController) handleMidRebaseCommand(action todo.TodoCommand, commit *models.Commit) (bool, error) {
if commit.Action == models.ActionConflict {
return true, self.c.ErrorMsg(self.c.Tr.ChangingThisActionIsNotAllowed)
}
if !commit.IsTODO() { if !commit.IsTODO() {
if self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE {
// If we are in a rebase, the only action that is allowed for
// non-todo commits is rewording the current head commit
if !(action == todo.Reword && self.isHeadCommit()) {
return true, self.c.ErrorMsg(self.c.Tr.AlreadyRebasing)
}
}
return false, nil return false, 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 true, self.c.ErrorMsg(self.c.Tr.RewordNotSupported)
}
if allowed := isChangeOfRebaseTodoAllowed(action); !allowed {
return true, self.c.ErrorMsg(self.c.Tr.ChangingThisActionIsNotAllowed)
}
self.c.LogAction("Update rebase TODO") self.c.LogAction("Update rebase TODO")
msg := utils.ResolvePlaceholderString( msg := utils.ResolvePlaceholderString(
@ -476,6 +476,38 @@ func (self *LocalCommitsController) handleMidRebaseCommand(action todo.TodoComma
}) })
} }
func (self *LocalCommitsController) rebaseCommandEnabled(action todo.TodoCommand, commit *models.Commit) string {
if commit.Action == models.ActionConflict {
return self.c.Tr.ChangingThisActionIsNotAllowed
}
if !commit.IsTODO() {
if self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE {
// If we are in a rebase, the only action that is allowed for
// non-todo commits is rewording the current head commit
if !(action == todo.Reword && self.isHeadCommit()) {
return self.c.Tr.AlreadyRebasing
}
}
return ""
}
// 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 self.c.Tr.RewordNotSupported
}
if allowed := isChangeOfRebaseTodoAllowed(action); !allowed {
return self.c.Tr.ChangingThisActionIsNotAllowed
}
return ""
}
func (self *LocalCommitsController) moveDown(commit *models.Commit) error { func (self *LocalCommitsController) moveDown(commit *models.Commit) error {
index := self.context().GetSelectedLineIdx() index := self.context().GetSelectedLineIdx()
commits := self.c.Model().Commits commits := self.c.Model().Commits
@ -601,6 +633,14 @@ func (self *LocalCommitsController) amendTo(commit *models.Commit) error {
}) })
} }
func (self *LocalCommitsController) getDisabledReasonForAmendTo(commit *models.Commit) string {
if !self.isHeadCommit() && self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE {
return self.c.Tr.AlreadyRebasing
}
return ""
}
func (self *LocalCommitsController) amendAttribute(commit *models.Commit) error { func (self *LocalCommitsController) amendAttribute(commit *models.Commit) error {
if self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE && !self.isHeadCommit() { if self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE && !self.isHeadCommit() {
return self.c.ErrorMsg(self.c.Tr.AlreadyRebasing) return self.c.ErrorMsg(self.c.Tr.AlreadyRebasing)
@ -772,6 +812,14 @@ func (self *LocalCommitsController) squashAllAboveFixupCommits(commit *models.Co
}) })
} }
func (self *LocalCommitsController) getDisabledReasonForSquashAllAboveFixupCommits(commit *models.Commit) string {
if self.c.Git().Status.WorkingTreeState() != enums.REBASE_MODE_NONE {
return self.c.Tr.AlreadyRebasing
}
return ""
}
func (self *LocalCommitsController) createTag(commit *models.Commit) error { func (self *LocalCommitsController) createTag(commit *models.Commit) error {
return self.c.Helpers().Tags.OpenCreateTagPrompt(commit.Sha, func() {}) return self.c.Helpers().Tags.OpenCreateTagPrompt(commit.Sha, func() {})
} }
@ -896,13 +944,35 @@ func (self *LocalCommitsController) checkSelected(callback func(*models.Commit)
return func() error { return func() error {
commit := self.context().GetSelected() commit := self.context().GetSelected()
if commit == nil { if commit == nil {
return nil // The enabled callback should have checked for this
panic("no commit selected")
} }
return callback(commit) return callback(commit)
} }
} }
func (self *LocalCommitsController) callGetDisabledReasonFuncWithSelectedCommit(callback func(*models.Commit) string) func() string {
return func() string {
commit := self.context().GetSelected()
if commit == nil {
return self.c.Tr.NoCommitSelected
}
return callback(commit)
}
}
func (self *LocalCommitsController) disabledIfNoSelectedCommit() func() string {
return self.callGetDisabledReasonFuncWithSelectedCommit(func(*models.Commit) string { return "" })
}
func (self *LocalCommitsController) getDisabledReasonForRebaseCommandWithSelectedCommit(action todo.TodoCommand) func() string {
return self.callGetDisabledReasonFuncWithSelectedCommit(func(commit *models.Commit) string {
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()

View File

@ -611,6 +611,7 @@ type TranslationSet struct {
MarkedCommitMarker string MarkedCommitMarker string
PleaseGoToURL string PleaseGoToURL string
DisabledMenuItemPrefix string DisabledMenuItemPrefix string
NoCommitSelected string
Actions Actions Actions Actions
Bisect Bisect Bisect Bisect
Log Log Log Log
@ -1401,6 +1402,7 @@ 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",
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",