mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-01-26 01:41:35 +03:00
Avoid scrolling the selection into view on refresh
It is possible to scroll the selection out of view using the mouse wheel; after doing this, it would sometimes scroll into view by itself again, for example when a background fetch occurred. In the files panel this would even happen every 10s with every regular files refresh. Fix this by adding a scrollIntoView parameter to HandleFocus, which is false by default, and is only set to true from controllers that change the selection.
This commit is contained in:
2
go.mod
2
go.mod
@@ -18,7 +18,7 @@ require (
|
||||
github.com/integrii/flaggy v1.4.0
|
||||
github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251214132308-02ab34c1c624
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223143206-950739ccd44a
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
|
||||
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0
|
||||
github.com/karimkhaleel/jsonschema v0.0.0-20231001195015-d933f0d94ea3
|
||||
|
||||
4
go.sum
4
go.sum
@@ -194,8 +194,8 @@ github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c h1:tC2Paiis
|
||||
github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c/go.mod h1:F2fEBk0ddf6ixrBrJjY7phfQ3hL9rXG0uSjvwYe50bE=
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd h1:ViKj6qth8FgcIWizn9KiACWwPemWSymx62OPN0tHT+Q=
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd/go.mod h1:lRhCiBr6XjQrvcQVa+UYsy/99d3wMXn/a0nSQlhnhlA=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251214132308-02ab34c1c624 h1:30mIX4f52zrO4fWfZQKHJG29t2apcSOtR/sbd3BNsVE=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251214132308-02ab34c1c624/go.mod h1:sLIyZ2J42R6idGdtemZzsiR3xY5EF0KsvYEGh3dQv3s=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223143206-950739ccd44a h1:XRsyqrSljes4TlaPczQViIAA4xqdnB0fKEEpZdqWWTA=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20251223143206-950739ccd44a/go.mod h1:sLIyZ2J42R6idGdtemZzsiR3xY5EF0KsvYEGh3dQv3s=
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5/go.mod h1:qxN4mHOAyeIDLP7IK7defgPClM/z1Kze8VVQiaEjzsQ=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
|
||||
@@ -25,8 +25,8 @@ type ListContextTrait struct {
|
||||
|
||||
func (self *ListContextTrait) IsListContext() {}
|
||||
|
||||
func (self *ListContextTrait) FocusLine() {
|
||||
self.Context.FocusLine()
|
||||
func (self *ListContextTrait) FocusLine(scrollIntoView bool) {
|
||||
self.Context.FocusLine(scrollIntoView)
|
||||
|
||||
// Doing this at the end of the layout function because we need the view to be
|
||||
// resized before we focus the line, otherwise if we're in accordion mode
|
||||
@@ -36,7 +36,7 @@ func (self *ListContextTrait) FocusLine() {
|
||||
oldOrigin, _ := self.GetViewTrait().ViewPortYBounds()
|
||||
|
||||
self.GetViewTrait().FocusPoint(
|
||||
self.ModelIndexToViewIndex(self.list.GetSelectedLineIdx()))
|
||||
self.ModelIndexToViewIndex(self.list.GetSelectedLineIdx()), scrollIntoView)
|
||||
|
||||
selectRangeIndex, isSelectingRange := self.list.GetRangeStartIdx()
|
||||
if isSelectingRange {
|
||||
@@ -75,7 +75,7 @@ func formatListFooter(selectedLineIdx int, length int) string {
|
||||
}
|
||||
|
||||
func (self *ListContextTrait) HandleFocus(opts types.OnFocusOpts) {
|
||||
self.FocusLine()
|
||||
self.FocusLine(opts.ScrollSelectionIntoView)
|
||||
|
||||
self.GetViewTrait().SetHighlight(self.list.Len() > 0)
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ func (self *SimpleContext) HandleFocusLost(opts types.OnFocusLostOpts) {
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SimpleContext) FocusLine() {
|
||||
func (self *SimpleContext) FocusLine(scrollIntoView bool) {
|
||||
}
|
||||
|
||||
func (self *SimpleContext) HandleRender() {
|
||||
|
||||
@@ -17,8 +17,8 @@ func NewViewTrait(view *gocui.View) *ViewTrait {
|
||||
return &ViewTrait{view: view}
|
||||
}
|
||||
|
||||
func (self *ViewTrait) FocusPoint(yIdx int) {
|
||||
self.view.FocusPoint(self.view.OriginX(), yIdx)
|
||||
func (self *ViewTrait) FocusPoint(yIdx int, scrollIntoView bool) {
|
||||
self.view.FocusPoint(self.view.OriginX(), yIdx, scrollIntoView)
|
||||
}
|
||||
|
||||
func (self *ViewTrait) SetRangeSelectStart(yIdx int) {
|
||||
|
||||
@@ -101,7 +101,7 @@ func (self *CherryPickHelper) Paste() error {
|
||||
// below the selection.
|
||||
if commit := self.c.Contexts().LocalCommits.GetSelected(); commit != nil && !commit.IsTODO() {
|
||||
self.c.Contexts().LocalCommits.MoveSelection(len(cherryPickedCommits))
|
||||
self.c.Contexts().LocalCommits.FocusLine()
|
||||
self.c.Contexts().LocalCommits.FocusLine(true)
|
||||
}
|
||||
|
||||
// If we're in the cherry-picking state at this point, it must
|
||||
|
||||
@@ -35,6 +35,9 @@ func (self *RefsHelper) SelectFirstBranchAndFirstCommit() {
|
||||
self.c.Contexts().Branches.SetSelection(0)
|
||||
self.c.Contexts().ReflogCommits.SetSelection(0)
|
||||
self.c.Contexts().LocalCommits.SetSelection(0)
|
||||
self.c.Contexts().Branches.GetView().SetOriginY(0)
|
||||
self.c.Contexts().ReflogCommits.GetView().SetOriginY(0)
|
||||
self.c.Contexts().LocalCommits.GetView().SetOriginY(0)
|
||||
}
|
||||
|
||||
func (self *RefsHelper) CheckoutRef(ref string, options types.CheckoutRefOptions) error {
|
||||
|
||||
@@ -116,7 +116,7 @@ func (self *ListController) handleLineChangeAux(f func(int), change int) error {
|
||||
}
|
||||
|
||||
if cursorMoved || rangeBefore != rangeAfter {
|
||||
self.context.HandleFocus(types.OnFocusOpts{})
|
||||
self.context.HandleFocus(types.OnFocusOpts{ScrollSelectionIntoView: true})
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -173,6 +173,8 @@ func (self *ListController) handlePageChange(delta int) error {
|
||||
}
|
||||
}
|
||||
|
||||
// Since we are maintaining the scroll position ourselves above, there's no point in passing
|
||||
// ScrollSelectionIntoView=true here.
|
||||
self.context.HandleFocus(types.OnFocusOpts{})
|
||||
|
||||
return nil
|
||||
|
||||
@@ -869,7 +869,7 @@ func (self *LocalCommitsController) revert(commits []*models.Commit, start, end
|
||||
return err
|
||||
}
|
||||
self.context().MoveSelection(len(commits))
|
||||
self.context().HandleFocus(types.OnFocusOpts{})
|
||||
self.context().HandleFocus(types.OnFocusOpts{ScrollSelectionIntoView: true})
|
||||
|
||||
if mustStash {
|
||||
if err := self.c.Git().Stash.Pop(0); err != nil {
|
||||
|
||||
@@ -205,7 +205,7 @@ func (self *StashController) handleRenameStashEntry(stashEntry *models.StashEntr
|
||||
return err
|
||||
}
|
||||
self.context().SetSelection(0) // Select the renamed stash
|
||||
self.context().FocusLine()
|
||||
self.context().FocusLine(true)
|
||||
self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.STASH}})
|
||||
return nil
|
||||
},
|
||||
|
||||
@@ -109,7 +109,7 @@ type Context interface {
|
||||
|
||||
HandleFocus(opts OnFocusOpts)
|
||||
HandleFocusLost(opts OnFocusLostOpts)
|
||||
FocusLine()
|
||||
FocusLine(scrollIntoView bool)
|
||||
HandleRender()
|
||||
HandleRenderToMain()
|
||||
}
|
||||
@@ -201,7 +201,7 @@ type IPatchExplorerContext interface {
|
||||
}
|
||||
|
||||
type IViewTrait interface {
|
||||
FocusPoint(yIdx int)
|
||||
FocusPoint(yIdx int, scrollIntoView bool)
|
||||
SetRangeSelectStart(yIdx int)
|
||||
CancelRangeSelect()
|
||||
SetViewPortContent(content string)
|
||||
@@ -221,8 +221,9 @@ type IViewTrait interface {
|
||||
}
|
||||
|
||||
type OnFocusOpts struct {
|
||||
ClickedWindowName string
|
||||
ClickedViewLineIdx int
|
||||
ClickedWindowName string
|
||||
ClickedViewLineIdx int
|
||||
ScrollSelectionIntoView bool
|
||||
}
|
||||
|
||||
type OnFocusLostOpts struct {
|
||||
|
||||
@@ -140,7 +140,7 @@ func (gui *Gui) postRefreshUpdate(c types.Context) {
|
||||
// non-focused views to ensure that an inactive selection is painted
|
||||
// correctly, and that integration tests see the up to date selection
|
||||
// state.
|
||||
c.FocusLine()
|
||||
c.FocusLine(false)
|
||||
|
||||
currentCtx := gui.State.ContextMgr.Current()
|
||||
if currentCtx.GetKey() == context.NORMAL_MAIN_CONTEXT_KEY || currentCtx.GetKey() == context.NORMAL_SECONDARY_CONTEXT_KEY {
|
||||
|
||||
@@ -51,7 +51,7 @@ func RunTUI(raceDetector bool) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listView.FocusPoint(0, app.itemIdx)
|
||||
listView.FocusPoint(0, app.itemIdx, true)
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Panicln(err)
|
||||
@@ -66,7 +66,7 @@ func RunTUI(raceDetector bool) {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listView.FocusPoint(0, app.itemIdx)
|
||||
listView.FocusPoint(0, app.itemIdx, true)
|
||||
return nil
|
||||
}); err != nil {
|
||||
log.Panicln(err)
|
||||
|
||||
11
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
11
vendor/github.com/jesseduffield/gocui/view.go
generated
vendored
@@ -262,7 +262,7 @@ func (v *View) SelectSearchResult(index int) error {
|
||||
|
||||
y := v.searcher.searchPositions[index].Y
|
||||
|
||||
v.FocusPoint(v.ox, y)
|
||||
v.FocusPoint(v.ox, y, true)
|
||||
if v.searcher.onSelectItem != nil {
|
||||
return v.searcher.onSelectItem(y, index, itemCount)
|
||||
}
|
||||
@@ -325,14 +325,17 @@ func (v *View) IsSearching() bool {
|
||||
return v.searcher.searchString != ""
|
||||
}
|
||||
|
||||
func (v *View) FocusPoint(cx int, cy int) {
|
||||
func (v *View) FocusPoint(cx int, cy int, scrollIntoView bool) {
|
||||
lineCount := len(v.lines)
|
||||
if cy < 0 || cy > lineCount {
|
||||
return
|
||||
}
|
||||
height := v.InnerHeight()
|
||||
|
||||
v.oy = calculateNewOrigin(cy, v.oy, lineCount, height)
|
||||
if scrollIntoView {
|
||||
height := v.InnerHeight()
|
||||
v.oy = calculateNewOrigin(cy, v.oy, lineCount, height)
|
||||
}
|
||||
|
||||
v.cx = cx
|
||||
v.cy = cy - v.oy
|
||||
}
|
||||
|
||||
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@@ -221,7 +221,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
|
||||
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
|
||||
github.com/jesseduffield/go-git/v5/utils/sync
|
||||
github.com/jesseduffield/go-git/v5/utils/trace
|
||||
# github.com/jesseduffield/gocui v0.3.1-0.20251214132308-02ab34c1c624
|
||||
# github.com/jesseduffield/gocui v0.3.1-0.20251223143206-950739ccd44a
|
||||
## explicit; go 1.12
|
||||
github.com/jesseduffield/gocui
|
||||
# github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
|
||||
|
||||
Reference in New Issue
Block a user