on main help sign in
refactor(ui): remove dirty tracking from LazyList
94de6bcAyman Bagabas
internal/ui/lazylist/item.go+22
@@ -6,3 +6,25 @@ type Item interface {
6 // width.
6 // width.
7 Render(width int) string
7 Render(width int) string
8}
8}
9+
10+// Focusable represents an item that can gain or lose focus.
11+type Focusable interface {
12+ // Focus sets the focus state of the item.
13+ Focus()
14+
15+ // Blur removes the focus state of the item.
16+ Blur()
17+
18+ // Focused returns whether the item is focused.
19+ Focused() bool
20+}
21+
22+// Highlightable represents an item that can have a highlighted region.
23+type Highlightable interface {
24+ // SetHighlight sets the highlight region (startLine, startCol) to (endLine, endCol).
25+ // Use -1 for all values to clear highlighting.
26+ SetHighlight(startLine, startCol, endLine, endCol int)
27+
28+ // GetHighlight returns the current highlight region.
29+ GetHighlight() (startLine, startCol, endLine, endCol int)
30+}
internal/ui/lazylist/list.go+4−15
@@ -31,9 +31,6 @@ type List struct {
31 // scrolled out of view (above the viewport).
31 // scrolled out of view (above the viewport).
32 // It must always be >= 0.
32 // It must always be >= 0.
33 offsetLine int
33 offsetLine int
34−
35− // Dirty tracking
36− dirtyItems map[int]struct{}
37}
34}
38
35
39// renderedItem holds the rendered content and height of an item.
36// renderedItem holds the rendered content and height of an item.
@@ -47,7 +44,6 @@ func NewList(items ...Item) *List {
47 l := new(List)
44 l := new(List)
48 l.items = items
45 l.items = items
49 l.renderedItems = make(map[int]renderedItem)
46 l.renderedItems = make(map[int]renderedItem)
50− l.dirtyItems = make(map[int]struct{})
51 return l
47 return l
52}
48}
53
49
@@ -88,9 +84,7 @@ func (l *List) getItem(idx int) renderedItem {
88 }
84 }
89
85
90 if item, ok := l.renderedItems[idx]; ok {
86 if item, ok := l.renderedItems[idx]; ok {
91− if _, dirty := l.dirtyItems[idx]; !dirty {
92− return item
87+ return item
93− }
94 }
88 }
95
89
96 item := l.items[idx]
90 item := l.items[idx]
@@ -104,7 +98,6 @@ func (l *List) getItem(idx int) renderedItem {
104 }
98 }
105
99
106 l.renderedItems[idx] = ri
100 l.renderedItems[idx] = ri
107− delete(l.dirtyItems, idx)
108
101
109 return ri
102 return ri
110}
103}
@@ -301,13 +294,6 @@ func (l *List) PrependItems(items ...Item) {
301 }
294 }
302 l.renderedItems = newCache
295 l.renderedItems = newCache
303
296
304− // Shift dirty items
305− newDirty := make(map[int]struct{})
306− for idx := range l.dirtyItems {
307− newDirty[idx+len(items)] = struct{}{}
308− }
309− l.dirtyItems = newDirty
310−
311 // Keep view position relative to the content that was visible
297 // Keep view position relative to the content that was visible
312 l.offsetIdx += len(items)
298 l.offsetIdx += len(items)
313
299
@@ -325,6 +311,9 @@ func (l *List) AppendItems(items ...Item) {
325// Focus sets the focus state of the list.
311// Focus sets the focus state of the list.
326func (l *List) Focus() {
312func (l *List) Focus() {
327 l.focused = true
313 l.focused = true
314+ if l.selectedIdx < 0 || l.selectedIdx > len(l.items)-1 {
315+ return
316+ }
328}
317}
329
318
330// Blur removes the focus state from the list.
319// Blur removes the focus state from the list.