mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-15 18:16:25 -04:00
Pressing space in the commit-files focused main view now toggles the selected line(s)/hunk into or out of the custom patch, instead of being a no-op. It's the patch-building counterpart of working-tree staging from the main view: the selection is resolved to change-line identities the same way (ChangeLinesInViewRange), then mapped to the patch builder's per-file line indices and added or removed. The crux is that the commit's diff is unchanged by a toggle — only the inclusion set changes — so unlike staging there's no async re-render to ride. Membership is shown by an on-demand inclusion gutter: a reserved left column painted with a marker on every change line currently in the patch, recomputed synchronously after each toggle and on focusing the main view, over the existing pager output. This is what lets patch building work over a restructuring pager at all, where the old green first-char overlay (which rewrites the rendered bytes) can't. space routes to staging or patch building based on which handler the panel beneath registers, via a new onTogglePatchFocusedMainView channel (kept separate from staging because the post-action differs: sync gutter repaint vs async reveal). Scoped to the commit-files panel for now; commits/sub-commits/stash and the whole-commit multi-file diff follow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
104 lines
3.2 KiB
Go
104 lines
3.2 KiB
Go
package controllers
|
|
|
|
import (
|
|
"github.com/jesseduffield/lazygit/pkg/gocui"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
)
|
|
|
|
// This controller is for all contexts that can focus their main view.
|
|
|
|
var _ types.IController = &SwitchToFocusedMainViewController{}
|
|
|
|
type SwitchToFocusedMainViewController struct {
|
|
baseController
|
|
c *ControllerCommon
|
|
context types.Context
|
|
}
|
|
|
|
func NewSwitchToFocusedMainViewController(
|
|
c *ControllerCommon,
|
|
context types.Context,
|
|
) *SwitchToFocusedMainViewController {
|
|
return &SwitchToFocusedMainViewController{
|
|
baseController: baseController{},
|
|
c: c,
|
|
context: context,
|
|
}
|
|
}
|
|
|
|
func (self *SwitchToFocusedMainViewController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
|
bindings := []*types.Binding{
|
|
{
|
|
Keys: opts.GetKeys(opts.Config.Universal.FocusMainView),
|
|
Handler: self.handleFocusMainView,
|
|
Description: self.c.Tr.FocusMainView,
|
|
Tag: "global",
|
|
},
|
|
}
|
|
|
|
return bindings
|
|
}
|
|
|
|
func (self *SwitchToFocusedMainViewController) GetMouseKeybindings(opts types.KeybindingsOpts) []*gocui.ViewMouseBinding {
|
|
return []*gocui.ViewMouseBinding{
|
|
{
|
|
ViewName: "main",
|
|
Key: gocui.MouseLeft,
|
|
Handler: self.onClickMain,
|
|
FocusedView: self.context.GetViewName(),
|
|
},
|
|
{
|
|
ViewName: "secondary",
|
|
Key: gocui.MouseLeft,
|
|
Handler: self.onClickSecondary,
|
|
FocusedView: self.context.GetViewName(),
|
|
},
|
|
}
|
|
}
|
|
|
|
func (self *SwitchToFocusedMainViewController) Context() types.Context {
|
|
return self.context
|
|
}
|
|
|
|
func (self *SwitchToFocusedMainViewController) onClickMain(opts gocui.ViewMouseBindingOpts) error {
|
|
return self.focusMainView(self.c.Contexts().Normal, opts.Y)
|
|
}
|
|
|
|
func (self *SwitchToFocusedMainViewController) onClickSecondary(opts gocui.ViewMouseBindingOpts) error {
|
|
return self.focusMainView(self.c.Contexts().NormalSecondary, opts.Y)
|
|
}
|
|
|
|
func (self *SwitchToFocusedMainViewController) handleFocusMainView() error {
|
|
// Focusing by keyboard doesn't point at any particular line: in a diff view
|
|
// we start at the first change block (like entering the staging view), in a
|
|
// non-diff view we show no selection and the user just scrolls. Clicking does
|
|
// point at a line, so it selects that line instead (focusMainView's
|
|
// clickedLineIdx).
|
|
return self.focusMainView(self.c.Contexts().Normal, -1)
|
|
}
|
|
|
|
func (self *SwitchToFocusedMainViewController) focusMainView(mainViewContext *context.MainContext, clickedLineIdx int) error {
|
|
mainViewContext.ClearSearchString()
|
|
self.c.Context().Push(mainViewContext, types.OnFocusOpts{})
|
|
|
|
if !sidePanelShowsDiff(self.context) {
|
|
// Non-diff main content (e.g. a branch's commit log): focus only, no
|
|
// selection, since there's nothing to act on.
|
|
return nil
|
|
}
|
|
|
|
if clickedLineIdx >= 0 {
|
|
// A click points at a specific line, so select it directly (in the default
|
|
// single-line mode).
|
|
resetDiffSelectMode(mainViewContext)
|
|
showSelectionAtLine(mainViewContext.GetView(), clickedLineIdx, false)
|
|
} else {
|
|
showInitialDiffSelection(self.c, mainViewContext)
|
|
}
|
|
|
|
// The inclusion gutter is refreshed by the main view's focus handler (it's shown
|
|
// only while focused, so it tracks focus changes there).
|
|
return nil
|
|
}
|