diff --git a/internal/ui/lazylist/item.go b/internal/ui/lazylist/item.go index dc39451ea5259a06d68b9dc45e78fdc00a2dac24..3ec31fbcf3d091e8d3438b2ecccfd467658b5f0f 100644 --- a/internal/ui/lazylist/item.go +++ b/internal/ui/lazylist/item.go @@ -6,3 +6,25 @@ type Item interface { // width. Render(width int) string } + +// Focusable represents an item that can gain or lose focus. +type Focusable interface { + // Focus sets the focus state of the item. + Focus() + + // Blur removes the focus state of the item. + Blur() + + // Focused returns whether the item is focused. + Focused() bool +} + +// Highlightable represents an item that can have a highlighted region. +type Highlightable interface { + // SetHighlight sets the highlight region (startLine, startCol) to (endLine, endCol). + // Use -1 for all values to clear highlighting. + SetHighlight(startLine, startCol, endLine, endCol int) + + // GetHighlight returns the current highlight region. + GetHighlight() (startLine, startCol, endLine, endCol int) +} diff --git a/internal/ui/lazylist/list.go b/internal/ui/lazylist/list.go index 9d6559b7540a97131c0f9d5c08c037c5279750a7..334af80b263b5e64e3cf8cecad36ca410f47f71c 100644 --- a/internal/ui/lazylist/list.go +++ b/internal/ui/lazylist/list.go @@ -31,9 +31,6 @@ type List struct { // scrolled out of view (above the viewport). // It must always be >= 0. offsetLine int - - // Dirty tracking - dirtyItems map[int]struct{} } // renderedItem holds the rendered content and height of an item. @@ -47,7 +44,6 @@ func NewList(items ...Item) *List { l := new(List) l.items = items l.renderedItems = make(map[int]renderedItem) - l.dirtyItems = make(map[int]struct{}) return l } @@ -88,9 +84,7 @@ func (l *List) getItem(idx int) renderedItem { } if item, ok := l.renderedItems[idx]; ok { - if _, dirty := l.dirtyItems[idx]; !dirty { - return item - } + return item } item := l.items[idx] @@ -104,7 +98,6 @@ func (l *List) getItem(idx int) renderedItem { } l.renderedItems[idx] = ri - delete(l.dirtyItems, idx) return ri } @@ -301,13 +294,6 @@ func (l *List) PrependItems(items ...Item) { } l.renderedItems = newCache - // Shift dirty items - newDirty := make(map[int]struct{}) - for idx := range l.dirtyItems { - newDirty[idx+len(items)] = struct{}{} - } - l.dirtyItems = newDirty - // Keep view position relative to the content that was visible l.offsetIdx += len(items) @@ -325,6 +311,9 @@ func (l *List) AppendItems(items ...Item) { // Focus sets the focus state of the list. func (l *List) Focus() { l.focused = true + if l.selectedIdx < 0 || l.selectedIdx > len(l.items)-1 { + return + } } // Blur removes the focus state from the list.