Skip to content

Commit f91adf0

Browse files
committed
fix lbl scrolling
1 parent 6d91661 commit f91adf0

File tree

4 files changed

+161
-12
lines changed

4 files changed

+161
-12
lines changed

pkg/gui/lbl/focus.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package lbl
2+
3+
import "github.com/jesseduffield/lazygit/pkg/utils"
4+
5+
func calculateOrigin(currentOrigin int, bufferHeight int, firstLineIdx int, lastLineIdx int, selectedLineIdx int, mode selectMode) int {
6+
needToSeeIdx, wantToSeeIdx := getNeedAndWantLineIdx(firstLineIdx, lastLineIdx, selectedLineIdx, mode)
7+
8+
return calculateNewOriginWithNeededAndWantedIdx(currentOrigin, bufferHeight, needToSeeIdx, wantToSeeIdx)
9+
}
10+
11+
// we want to scroll our origin so that the index we need to see is in view
12+
// and the other index we want to see (e.g. the other side of a line range)
13+
// is in as close to being in view as possible.
14+
func calculateNewOriginWithNeededAndWantedIdx(currentOrigin int, bufferHeight int, needToSeeIdx int, wantToSeeIdx int) int {
15+
origin := currentOrigin
16+
if needToSeeIdx < currentOrigin {
17+
origin = needToSeeIdx
18+
} else if needToSeeIdx > currentOrigin+bufferHeight {
19+
origin = needToSeeIdx - bufferHeight
20+
}
21+
22+
bottom := origin + bufferHeight
23+
24+
if wantToSeeIdx < origin {
25+
requiredChange := origin - wantToSeeIdx
26+
allowedChange := bottom - needToSeeIdx
27+
return origin - utils.Min(requiredChange, allowedChange)
28+
} else if wantToSeeIdx > origin+bufferHeight {
29+
requiredChange := wantToSeeIdx - bottom
30+
allowedChange := needToSeeIdx - origin
31+
return origin + utils.Min(requiredChange, allowedChange)
32+
} else {
33+
return origin
34+
}
35+
}
36+
37+
func getNeedAndWantLineIdx(firstLineIdx int, lastLineIdx int, selectedLineIdx int, mode selectMode) (int, int) {
38+
switch mode {
39+
case LINE:
40+
return selectedLineIdx, selectedLineIdx
41+
case RANGE:
42+
if selectedLineIdx == firstLineIdx {
43+
return firstLineIdx, lastLineIdx
44+
} else {
45+
return lastLineIdx, firstLineIdx
46+
}
47+
case HUNK:
48+
return firstLineIdx, lastLineIdx
49+
default:
50+
panic("unknown mode")
51+
}
52+
}

pkg/gui/lbl/focus_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package lbl
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestNewOrigin(t *testing.T) {
10+
type scenario struct {
11+
name string
12+
origin int
13+
bufferHeight int
14+
firstLineIdx int
15+
lastLineIdx int
16+
selectedLineIdx int
17+
selectMode selectMode
18+
expected int
19+
}
20+
21+
scenarios := []scenario{
22+
{
23+
name: "selection above scroll window",
24+
origin: 50,
25+
bufferHeight: 100,
26+
firstLineIdx: 10,
27+
lastLineIdx: 10,
28+
selectedLineIdx: 10,
29+
selectMode: LINE,
30+
expected: 10,
31+
},
32+
{
33+
name: "selection below scroll window",
34+
origin: 0,
35+
bufferHeight: 100,
36+
firstLineIdx: 150,
37+
lastLineIdx: 150,
38+
selectedLineIdx: 150,
39+
selectMode: LINE,
40+
expected: 50,
41+
},
42+
{
43+
name: "selection within scroll window",
44+
origin: 0,
45+
bufferHeight: 100,
46+
firstLineIdx: 50,
47+
lastLineIdx: 50,
48+
selectedLineIdx: 50,
49+
selectMode: LINE,
50+
expected: 0,
51+
},
52+
{
53+
name: "range ending below scroll window with selection at end of range",
54+
origin: 0,
55+
bufferHeight: 100,
56+
firstLineIdx: 40,
57+
lastLineIdx: 150,
58+
selectedLineIdx: 150,
59+
selectMode: RANGE,
60+
expected: 50,
61+
},
62+
{
63+
name: "range ending below scroll window with selection at beginning of range",
64+
origin: 0,
65+
bufferHeight: 100,
66+
firstLineIdx: 40,
67+
lastLineIdx: 150,
68+
selectedLineIdx: 40,
69+
selectMode: RANGE,
70+
expected: 40,
71+
},
72+
{
73+
name: "range starting above scroll window with selection at beginning of range",
74+
origin: 50,
75+
bufferHeight: 100,
76+
firstLineIdx: 40,
77+
lastLineIdx: 150,
78+
selectedLineIdx: 40,
79+
selectMode: RANGE,
80+
expected: 40,
81+
},
82+
{
83+
name: "hunk extending beyond both bounds of scroll window",
84+
origin: 50,
85+
bufferHeight: 100,
86+
firstLineIdx: 40,
87+
lastLineIdx: 200,
88+
selectedLineIdx: 70,
89+
selectMode: HUNK,
90+
expected: 40,
91+
},
92+
}
93+
94+
for _, s := range scenarios {
95+
s := s
96+
t.Run(s.name, func(t *testing.T) {
97+
assert.EqualValues(t, s.expected, calculateOrigin(s.origin, s.bufferHeight, s.firstLineIdx, s.lastLineIdx, s.selectedLineIdx, s.selectMode))
98+
})
99+
}
100+
}

pkg/gui/lbl/state.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,3 +189,9 @@ func (s *State) SelectTop() {
189189
s.SetLineSelectMode()
190190
s.SelectLine(0)
191191
}
192+
193+
func (s *State) CalculateOrigin(currentOrigin int, bufferHeight int) int {
194+
firstLineIdx, lastLineIdx := s.SelectedRange()
195+
196+
return calculateOrigin(currentOrigin, bufferHeight, firstLineIdx, lastLineIdx, s.GetSelectedLineIdx(), s.selectMode)
197+
}

pkg/gui/line_by_line_panel.go

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -155,25 +155,16 @@ func (gui *Gui) focusSelection(state *LblPanelState) error {
155155
bufferHeight := viewHeight - 1
156156
_, origin := stagingView.Origin()
157157

158-
firstLineIdx, lastLineIdx := state.SelectedRange()
158+
selectedLineIdx := state.GetSelectedLineIdx()
159159

160-
margin := 0 // we may want to have a margin in place to show context but right now I'm thinking we keep this at zero
161-
162-
var newOrigin int
163-
if firstLineIdx-origin < margin {
164-
newOrigin = firstLineIdx - margin
165-
} else if lastLineIdx-origin > bufferHeight-margin {
166-
newOrigin = lastLineIdx - bufferHeight + margin
167-
} else {
168-
newOrigin = origin
169-
}
160+
newOrigin := state.CalculateOrigin(origin, bufferHeight)
170161

171162
gui.g.Update(func(*gocui.Gui) error {
172163
if err := stagingView.SetOrigin(0, newOrigin); err != nil {
173164
return err
174165
}
175166

176-
return stagingView.SetCursor(0, state.GetSelectedLineIdx()-newOrigin)
167+
return stagingView.SetCursor(0, selectedLineIdx-newOrigin)
177168
})
178169

179170
return nil

0 commit comments

Comments
 (0)