Skip to content

Commit 9c94f9c

Browse files
committed
Another attempt to fix (half-)page-up/down for multi-line items
Fix #4069
1 parent 4a85843 commit 9c94f9c

File tree

1 file changed

+50
-13
lines changed

1 file changed

+50
-13
lines changed

src/terminal.go

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4411,35 +4411,72 @@ func (t *Terminal) Loop() error {
44114411
t.input = append(append(t.input[:t.cx], t.yanked...), suffix...)
44124412
t.cx += len(t.yanked)
44134413
case actPageUp, actPageDown, actHalfPageUp, actHalfPageDown:
4414+
// Calculate the number of lines to move
44144415
maxItems := t.maxItems()
44154416
linesToMove := maxItems - 1
44164417
if a.t == actHalfPageUp || a.t == actHalfPageDown {
44174418
linesToMove = maxItems / 2
44184419
}
4420+
// Move at least one line even in a very short window
4421+
linesToMove = util.Max(1, linesToMove)
44194422

4423+
// Determine the direction of the movement
44204424
direction := -1
44214425
if a.t == actPageUp || a.t == actHalfPageUp {
44224426
direction = 1
44234427
}
44244428

4425-
moved := false
4426-
for linesToMove > 0 {
4427-
currentItem := t.currentItem()
4428-
if currentItem == nil {
4429-
break
4430-
}
4429+
// In non-default layout, items are listed from top to bottom
4430+
if t.layout != layoutDefault {
4431+
direction *= -1
4432+
}
44314433

4432-
itemLines, _ := t.numItemLines(currentItem, maxItems)
4433-
linesToMove -= itemLines
4434-
if moved && linesToMove < 0 {
4435-
break
4434+
// We can simply add the number of lines to the current position in
4435+
// single-line mode
4436+
if !t.canSpanMultiLines() {
4437+
t.vset(t.cy + direction*linesToMove)
4438+
req(reqList)
4439+
break
4440+
}
4441+
4442+
// But in multi-line mode, we need to carefully limit the amount of
4443+
// vertical movement so that items are not skipped. In order to do
4444+
// this, we calculate the minimum or maximum offset based on the
4445+
// direction of the movement and the number of lines of the items
4446+
// around the current scroll offset.
4447+
var minOffset, maxOffset, lineSum int
4448+
if direction > 0 {
4449+
maxOffset = t.offset
4450+
for ; maxOffset < t.merger.Length(); maxOffset++ {
4451+
itemLines, _ := t.numItemLines(t.merger.Get(maxOffset).item, maxItems)
4452+
lineSum += itemLines
4453+
if lineSum >= maxItems {
4454+
break
4455+
}
44364456
}
4457+
} else {
4458+
minOffset = t.offset
4459+
for ; minOffset >= 0 && minOffset < t.merger.Length(); minOffset-- {
4460+
itemLines, _ := t.numItemLines(t.merger.Get(minOffset).item, maxItems)
4461+
lineSum += itemLines
4462+
if lineSum >= maxItems {
4463+
if lineSum > maxItems {
4464+
minOffset++
4465+
}
4466+
break
4467+
}
4468+
}
4469+
}
4470+
4471+
for ; linesToMove > 0; linesToMove-- {
44374472
cy := t.cy
4438-
t.vmove(direction, false)
4439-
if cy == t.cy {
4473+
t.vset(cy + direction)
4474+
t.constrain()
4475+
if cy == t.cy ||
4476+
direction > 0 && t.offset >= maxOffset ||
4477+
direction < 0 && t.offset <= minOffset {
44404478
break
44414479
}
4442-
moved = true
44434480
}
44444481
req(reqList)
44454482
case actOffsetUp, actOffsetDown:

0 commit comments

Comments
 (0)