mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-10 05:01:28 -10:00
Add a bounded per-model transcript body height cache keyed by the existing row render fingerprint, then use measured spans to render only the visible alt-screen item window instead of building the full body string every frame. Mouse hit testing now uses the same visible item layout, while inline rendering and selection copy keep the full layout path for behavior parity. Tests cover height cache reuse, visible-only item rendering, absolute selectable body coordinates, and output parity with the previous full-layout renderer. Tested: env GOCACHE=/tmp/zero-go-cache go test ./internal/tui Tested: git diff --check Tested: /bin/bash -lc "GOCACHE=/tmp/zero-go-cache go test ./..."
66 lines
1.4 KiB
Go
66 lines
1.4 KiB
Go
package tui
|
|
|
|
import (
|
|
"container/list"
|
|
"sync"
|
|
)
|
|
|
|
const defaultTranscriptBodyHeightCacheMaxEntries = 512
|
|
|
|
type transcriptBodyHeightCache struct {
|
|
mu sync.Mutex
|
|
maxEntries int
|
|
items map[string]*list.Element
|
|
lru *list.List
|
|
}
|
|
|
|
type transcriptBodyHeightCacheEntry struct {
|
|
key string
|
|
height int
|
|
}
|
|
|
|
func newTranscriptBodyHeightCache(maxEntries int) *transcriptBodyHeightCache {
|
|
return &transcriptBodyHeightCache{
|
|
maxEntries: maxEntries,
|
|
items: map[string]*list.Element{},
|
|
lru: list.New(),
|
|
}
|
|
}
|
|
|
|
func (c *transcriptBodyHeightCache) get(key string) (int, bool) {
|
|
if c == nil || key == "" {
|
|
return 0, false
|
|
}
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
element, ok := c.items[key]
|
|
if !ok {
|
|
return 0, false
|
|
}
|
|
c.lru.MoveToFront(element)
|
|
return element.Value.(*transcriptBodyHeightCacheEntry).height, true
|
|
}
|
|
|
|
func (c *transcriptBodyHeightCache) set(key string, height int) {
|
|
if c == nil || key == "" || c.maxEntries <= 0 {
|
|
return
|
|
}
|
|
c.mu.Lock()
|
|
defer c.mu.Unlock()
|
|
if element, ok := c.items[key]; ok {
|
|
element.Value.(*transcriptBodyHeightCacheEntry).height = height
|
|
c.lru.MoveToFront(element)
|
|
return
|
|
}
|
|
c.items[key] = c.lru.PushFront(&transcriptBodyHeightCacheEntry{key: key, height: height})
|
|
for len(c.items) > c.maxEntries {
|
|
element := c.lru.Back()
|
|
if element == nil {
|
|
return
|
|
}
|
|
entry := element.Value.(*transcriptBodyHeightCacheEntry)
|
|
delete(c.items, entry.key)
|
|
c.lru.Remove(element)
|
|
}
|
|
}
|