Files
zero/internal/tui/transcript_body_cache.go
Anandan 0b496ce87d Render transcript viewport from measured items (#227)
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 ./..."
2026-06-17 09:01:50 +05:30

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)
}
}