mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-13 00:56:25 -04:00
Offer commit and find-fixup-base in the focused main view
The focused main view now plays the role the staging panel used to, so the working-tree commands the staging panel offered — commit (and its variants) and find-base-commit-for-fixup — need to be reachable there as well. Gate them to when the focused main view actually shows the working-tree diff (DiffMainViewTypeStaging), which is exactly the role the staging panel filled. Over a commit's or stash's diff these commands would operate on the working tree, unrelated to what's on screen, so the keys are a no-op there and the bindings don't clutter its keybinding menu. The gate is re-checked on each press rather than captured at registration time, since one keybinding set serves the main view over every panel. That requires reading the panel beneath the main view from GetKeybindings (to decide whether to show the descriptions), which runs for off-stack contexts too — at startup and during cheatsheet generation — so a panic-safe IsInStack guards the NextInStack lookup. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
140cc03fd1
commit
97b1b4cf7f
|
|
@ -373,3 +373,15 @@ func (self *ContextMgr) NextInStack(c types.Context) types.Context {
|
|||
|
||||
panic("context not in stack")
|
||||
}
|
||||
|
||||
// IsInStack reports whether the given context is somewhere in the context stack.
|
||||
// Unlike NextInStack it never panics, so it's safe to call before dereferencing
|
||||
// the stack from a caller that might run with the context off-stack.
|
||||
func (self *ContextMgr) IsInStack(c types.Context) bool {
|
||||
self.RLock()
|
||||
defer self.RUnlock()
|
||||
|
||||
return lo.ContainsBy(self.ContextStack, func(other types.Context) bool {
|
||||
return other.GetKey() == c.GetKey()
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||
// line in the branch's pull request).
|
||||
selectionShown := self.context.GetView().Highlight
|
||||
|
||||
// The commit and find-fixup-base commands act on the working tree, so — like the
|
||||
// old staging panel, which was always the working-tree diff — we only surface them
|
||||
// while the focused main view plays that role (see workingTreeAction).
|
||||
stagingMode := self.diffMainViewType() == types.DiffMainViewTypeStaging
|
||||
|
||||
var enterDescription string
|
||||
var editDescription string
|
||||
var editTooltip string
|
||||
|
|
@ -59,6 +64,21 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||
openPullRequestTooltip = "Open a browser at the selected line in the diff of the current branch's pull request, so that you can comment on it. Only works for local branches that have a pull request on GitHub."
|
||||
}
|
||||
|
||||
var commitDescription string
|
||||
var commitTooltip string
|
||||
var commitWithoutHookDescription string
|
||||
var commitWithEditorDescription string
|
||||
var findBaseCommitDescription string
|
||||
var findBaseCommitTooltip string
|
||||
if stagingMode {
|
||||
commitDescription = self.c.Tr.Commit
|
||||
commitTooltip = self.c.Tr.CommitTooltip
|
||||
commitWithoutHookDescription = self.c.Tr.CommitChangesWithoutHook
|
||||
commitWithEditorDescription = self.c.Tr.CommitChangesWithEditor
|
||||
findBaseCommitDescription = self.c.Tr.FindBaseCommitForFixup
|
||||
findBaseCommitTooltip = self.c.Tr.FindBaseCommitForFixupTooltip
|
||||
}
|
||||
|
||||
return []*types.Binding{
|
||||
{
|
||||
Keys: opts.GetKeys(opts.Config.Universal.TogglePanel),
|
||||
|
|
@ -112,6 +132,28 @@ func (self *MainViewController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||
Description: openPullRequestDescription,
|
||||
Tooltip: openPullRequestTooltip,
|
||||
},
|
||||
{
|
||||
Keys: opts.GetKeys(opts.Config.Files.CommitChanges),
|
||||
Handler: self.workingTreeAction(self.c.Helpers().WorkingTree.HandleCommitPress),
|
||||
Description: commitDescription,
|
||||
Tooltip: commitTooltip,
|
||||
},
|
||||
{
|
||||
Keys: opts.GetKeys(opts.Config.Files.CommitChangesWithoutHook),
|
||||
Handler: self.workingTreeAction(self.c.Helpers().WorkingTree.HandleWIPCommitPress),
|
||||
Description: commitWithoutHookDescription,
|
||||
},
|
||||
{
|
||||
Keys: opts.GetKeys(opts.Config.Files.CommitChangesWithEditor),
|
||||
Handler: self.workingTreeAction(self.c.Helpers().WorkingTree.HandleCommitEditorPress),
|
||||
Description: commitWithEditorDescription,
|
||||
},
|
||||
{
|
||||
Keys: opts.GetKeys(opts.Config.Files.FindBaseCommitForFixup),
|
||||
Handler: self.workingTreeAction(self.c.Helpers().FixupHelper.HandleFindBaseCommitForFixupPress),
|
||||
Description: findBaseCommitDescription,
|
||||
Tooltip: findBaseCommitTooltip,
|
||||
},
|
||||
{
|
||||
Keys: opts.GetKeys(opts.Config.Main.ToggleSelectHunk),
|
||||
Handler: self.toggleSelectHunk,
|
||||
|
|
@ -383,6 +425,37 @@ func (self *MainViewController) focusedMainViewActions() types.FocusedMainViewAc
|
|||
return sidePanelContext.GetFocusedMainViewActions()
|
||||
}
|
||||
|
||||
// diffMainViewType reports what the side panel beneath the focused main view makes its
|
||||
// primary action mean — staging (the working tree), patch-building, or nothing — or
|
||||
// DiffMainViewTypeNone when this pane isn't focused or has no diff panel beneath it. The
|
||||
// IsInStack guard is essential: NextInStack panics for a context that isn't in the stack,
|
||||
// and GetKeybindings (which calls this) runs for off-stack panes too — at startup and
|
||||
// during cheatsheet generation, where the stack is empty.
|
||||
func (self *MainViewController) diffMainViewType() types.DiffMainViewType {
|
||||
if !self.c.Context().IsInStack(self.context) {
|
||||
return types.DiffMainViewTypeNone
|
||||
}
|
||||
if diffContext, ok := self.c.Context().NextInStack(self.context).(types.DiffMainViewContext); ok {
|
||||
return diffContext.GetDiffMainViewType()
|
||||
}
|
||||
return types.DiffMainViewTypeNone
|
||||
}
|
||||
|
||||
// workingTreeAction wraps a working-tree command (commit, find-fixup-base) so it runs
|
||||
// only while the focused main view shows the working-tree diff — the role the staging
|
||||
// panel used to play, and the only place these commands mean anything. Over any other
|
||||
// diff (a commit, a stash) the key is a no-op, so committing can't be triggered by
|
||||
// accident while browsing history. Re-checks on each press rather than capturing the
|
||||
// state at keybinding-registration time.
|
||||
func (self *MainViewController) workingTreeAction(action func() error) func() error {
|
||||
return func() error {
|
||||
if self.diffMainViewType() != types.DiffMainViewTypeStaging {
|
||||
return nil
|
||||
}
|
||||
return action()
|
||||
}
|
||||
}
|
||||
|
||||
// primaryAction acts on the selected diff line(s) — a single line, a range, or a hunk —
|
||||
// delegating to the side panel beneath the focused main view, since what the action means
|
||||
// is the panel's business: the working tree stages, while commits toggle the selection
|
||||
|
|
|
|||
|
|
@ -441,6 +441,7 @@ type IContextMgr interface {
|
|||
CurrentSide() Context
|
||||
CurrentPopup() []Context
|
||||
NextInStack(context Context) Context
|
||||
IsInStack(c Context) bool
|
||||
IsCurrent(c Context) bool
|
||||
IsCurrentOrParent(c Context) bool
|
||||
ForEach(func(Context))
|
||||
|
|
|
|||
Loading…
Reference in a new issue