mirror of
https://github.com/Llewellynvdm/fzf.git
synced 2024-11-21 12:25:09 +00:00
Another attempt to fix (half-)page-up/down for multi-line items
Fix #4069
This commit is contained in:
parent
4a85843bcf
commit
9c94f9c3d0
@ -4411,35 +4411,72 @@ func (t *Terminal) Loop() error {
|
||||
t.input = append(append(t.input[:t.cx], t.yanked...), suffix...)
|
||||
t.cx += len(t.yanked)
|
||||
case actPageUp, actPageDown, actHalfPageUp, actHalfPageDown:
|
||||
// Calculate the number of lines to move
|
||||
maxItems := t.maxItems()
|
||||
linesToMove := maxItems - 1
|
||||
if a.t == actHalfPageUp || a.t == actHalfPageDown {
|
||||
linesToMove = maxItems / 2
|
||||
}
|
||||
// Move at least one line even in a very short window
|
||||
linesToMove = util.Max(1, linesToMove)
|
||||
|
||||
// Determine the direction of the movement
|
||||
direction := -1
|
||||
if a.t == actPageUp || a.t == actHalfPageUp {
|
||||
direction = 1
|
||||
}
|
||||
|
||||
moved := false
|
||||
for linesToMove > 0 {
|
||||
currentItem := t.currentItem()
|
||||
if currentItem == nil {
|
||||
break
|
||||
}
|
||||
// In non-default layout, items are listed from top to bottom
|
||||
if t.layout != layoutDefault {
|
||||
direction *= -1
|
||||
}
|
||||
|
||||
itemLines, _ := t.numItemLines(currentItem, maxItems)
|
||||
linesToMove -= itemLines
|
||||
if moved && linesToMove < 0 {
|
||||
break
|
||||
// We can simply add the number of lines to the current position in
|
||||
// single-line mode
|
||||
if !t.canSpanMultiLines() {
|
||||
t.vset(t.cy + direction*linesToMove)
|
||||
req(reqList)
|
||||
break
|
||||
}
|
||||
|
||||
// But in multi-line mode, we need to carefully limit the amount of
|
||||
// vertical movement so that items are not skipped. In order to do
|
||||
// this, we calculate the minimum or maximum offset based on the
|
||||
// direction of the movement and the number of lines of the items
|
||||
// around the current scroll offset.
|
||||
var minOffset, maxOffset, lineSum int
|
||||
if direction > 0 {
|
||||
maxOffset = t.offset
|
||||
for ; maxOffset < t.merger.Length(); maxOffset++ {
|
||||
itemLines, _ := t.numItemLines(t.merger.Get(maxOffset).item, maxItems)
|
||||
lineSum += itemLines
|
||||
if lineSum >= maxItems {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
minOffset = t.offset
|
||||
for ; minOffset >= 0 && minOffset < t.merger.Length(); minOffset-- {
|
||||
itemLines, _ := t.numItemLines(t.merger.Get(minOffset).item, maxItems)
|
||||
lineSum += itemLines
|
||||
if lineSum >= maxItems {
|
||||
if lineSum > maxItems {
|
||||
minOffset++
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ; linesToMove > 0; linesToMove-- {
|
||||
cy := t.cy
|
||||
t.vmove(direction, false)
|
||||
if cy == t.cy {
|
||||
t.vset(cy + direction)
|
||||
t.constrain()
|
||||
if cy == t.cy ||
|
||||
direction > 0 && t.offset >= maxOffset ||
|
||||
direction < 0 && t.offset <= minOffset {
|
||||
break
|
||||
}
|
||||
moved = true
|
||||
}
|
||||
req(reqList)
|
||||
case actOffsetUp, actOffsetDown:
|
||||
|
Loading…
Reference in New Issue
Block a user