Fix scrolling performance when --wrap is enabled

Fix #4221
This commit is contained in:
Junegunn Choi 2025-02-06 22:30:39 +09:00
parent 62e0a2824a
commit fcd2baa945
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627

View File

@ -390,6 +390,12 @@ type Terminal struct {
clickHeaderLine int
clickHeaderColumn int
proxyScript string
numLinesCache map[int32]numLinesCacheValue
}
type numLinesCacheValue struct {
atMost int
numLines int
}
type selectedItem struct {
@ -947,7 +953,8 @@ func NewTerminal(opts *Options, eventBox *util.EventBox, executor *util.Executor
initFunc: func() error { return renderer.Init() },
executing: util.NewAtomicBool(false),
lastAction: actStart,
lastFocus: minItem.Index()}
lastFocus: minItem.Index(),
numLinesCache: make(map[int32]numLinesCacheValue)}
// This should be called before accessing tui.Color*
tui.InitTheme(opts.Theme, renderer.DefaultTheme(), opts.Black, opts.InputBorderShape.Visible(), opts.HeaderBorderShape.Visible())
@ -1318,6 +1325,10 @@ func (t *Terminal) wrapCols() int {
return util.Max(t.window.Width()-(t.pointerLen+t.markerLen+1), 1)
}
func (t *Terminal) clearNumLinesCache() {
t.numLinesCache = make(map[int32]numLinesCacheValue)
}
// Number of lines the item takes including the gap
func (t *Terminal) numItemLines(item *Item, atMost int) (int, bool) {
var numLines int
@ -1325,6 +1336,12 @@ func (t *Terminal) numItemLines(item *Item, atMost int) (int, bool) {
numLines = 1 + t.gap
return numLines, numLines > atMost
}
if cached, prs := t.numLinesCache[item.Index()]; prs {
// Can we use this cache? Let's be conservative.
if cached.atMost >= atMost {
return cached.numLines, false
}
}
var overflow bool
if !t.wrap && t.multiLine {
numLines, overflow = item.text.NumLines(atMost)
@ -1334,6 +1351,9 @@ func (t *Terminal) numItemLines(item *Item, atMost int) (int, bool) {
numLines = len(lines)
}
numLines += t.gap
if !overflow {
t.numLinesCache[item.Index()] = numLinesCacheValue{atMost, numLines}
}
return numLines, overflow || numLines > atMost
}
@ -1461,6 +1481,7 @@ func (t *Terminal) UpdateList(merger *Merger) {
if !t.revision.compatible(newRevision) {
// Reloaded: clear selection
t.selected = make(map[int32]selectedItem)
t.clearNumLinesCache()
} else {
// Trimmed by --tail: filter selection by index
filtered := make(map[int32]selectedItem)
@ -1712,6 +1733,7 @@ func (t *Terminal) hasHeaderLinesWindow() bool {
}
func (t *Terminal) resizeWindows(forcePreview bool, redrawBorder bool) {
t.clearNumLinesCache()
t.forcePreview = forcePreview
screenWidth, screenHeight, marginInt, paddingInt := t.adjustMarginAndPadding()
width := screenWidth - marginInt[1] - marginInt[3]
@ -5464,9 +5486,11 @@ func (t *Terminal) Loop() error {
req(reqList, reqInfo, reqPrompt, reqHeader)
case actToggleWrap:
t.wrap = !t.wrap
t.clearNumLinesCache()
req(reqList, reqHeader)
case actToggleMultiLine:
t.multiLine = !t.multiLine
t.clearNumLinesCache()
req(reqList)
case actToggleHscroll:
// Force re-rendering of the list