mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-12 08:36:25 -04:00
Click-and-drag in the focused main view turns a hunk selection into a range, but it was anchored at the change block's far end — where selecting a hunk leaves the range anchor — rather than the clicked line. And on a context line, where the click leaves no range anchor at all, dragging just moved the single selected line instead of opening a range. Remember the line each mouse-down lands on (the click can show a whole hunk, so it can't be read back from the view) and, as the drag proceeds, anchor the range there while the cursor end follows the mouse as gocui already moves it. Works for a click that focuses the view and for one while it's already focused, on change and context lines alike. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
94 lines
3 KiB
Go
94 lines
3 KiB
Go
package context
|
|
|
|
import (
|
|
"github.com/jesseduffield/lazygit/pkg/gocui"
|
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
|
)
|
|
|
|
type MainContext struct {
|
|
*SimpleContext
|
|
*SearchTrait
|
|
|
|
diffSelect DiffSelectState
|
|
// dragAnchorViewLine is the view line a mouse-down landed on, remembered so a drag
|
|
// that follows can anchor its range there. The click can show a whole hunk (a range
|
|
// with a different anchor), so the clicked line can't be read back from the view.
|
|
dragAnchorViewLine int
|
|
}
|
|
|
|
var _ types.ISearchableContext = (*MainContext)(nil)
|
|
|
|
// DiffSelectMode is how the focused main view's diff selection extends from the
|
|
// cursor: a single line, a range from a fixed anchor, or the change block (hunk)
|
|
// around the cursor.
|
|
type DiffSelectMode int
|
|
|
|
const (
|
|
DiffSelectModeLine DiffSelectMode = iota
|
|
DiffSelectModeRange
|
|
DiffSelectModeHunk
|
|
)
|
|
|
|
// DiffSelectState holds the *mode* of the focused main view's diff selection. The
|
|
// selected line and the range anchor themselves live in the gocui view (its
|
|
// cursor and rangeSelectStartY, i.e. native range select); only the mode lives
|
|
// here. It's on the context, not the controller, so that the main view controller
|
|
// (which drives the selection), the focus controller (which resets it on focus),
|
|
// and togglePanel (which sets it on the other pane) can all reach it via the
|
|
// context they already hold.
|
|
type DiffSelectState struct {
|
|
Mode DiffSelectMode
|
|
// When a range is sticky, moving the cursor without holding shift extends the
|
|
// range; otherwise it collapses the range back to a single line.
|
|
RangeIsSticky bool
|
|
// Whether the user turned on hunk mode explicitly, as opposed to it being the
|
|
// configured default; this decides whether escape leaves hunk mode.
|
|
UserEnabledHunkMode bool
|
|
}
|
|
|
|
// DiffSelectState returns the focused main view's selection mode state, for the
|
|
// controllers to read and mutate directly.
|
|
func (self *MainContext) DiffSelectState() *DiffSelectState {
|
|
return &self.diffSelect
|
|
}
|
|
|
|
// SetDragAnchorViewLine records the view line a mouse-down landed on, so a drag that
|
|
// follows can anchor its range there (see dragAnchorViewLine).
|
|
func (self *MainContext) SetDragAnchorViewLine(viewLine int) {
|
|
self.dragAnchorViewLine = viewLine
|
|
}
|
|
|
|
// DragAnchorViewLine returns the view line the last mouse-down landed on.
|
|
func (self *MainContext) DragAnchorViewLine() int {
|
|
return self.dragAnchorViewLine
|
|
}
|
|
|
|
func NewMainContext(
|
|
view *gocui.View,
|
|
windowName string,
|
|
key types.ContextKey,
|
|
c *ContextCommon,
|
|
) *MainContext {
|
|
ctx := &MainContext{
|
|
SimpleContext: NewSimpleContext(
|
|
NewBaseContext(NewBaseContextOpts{
|
|
Kind: types.MAIN_CONTEXT,
|
|
View: view,
|
|
WindowName: windowName,
|
|
Key: key,
|
|
Focusable: true,
|
|
HighlightOnFocus: false,
|
|
})),
|
|
SearchTrait: NewSearchTrait(c),
|
|
}
|
|
|
|
return ctx
|
|
}
|
|
|
|
func (self *MainContext) ModelSearchResults(searchStr string, caseSensitive bool) []gocui.SearchPosition {
|
|
return nil
|
|
}
|
|
|
|
func (self *MainContext) OnSearchSelect(int) {
|
|
}
|