history_read.go RawHistoryFolder
1package vt
2
3import renderer "github.com/bnema/vev-vt/core"
4
5// RowWidth returns the retained width of row y, or zero outside the view.
6// Unlike Row, it does not allocate or decode a semantic row.
7func (v HistoryView) RowWidth(y int) int {
8 chunk, _ := v.locateRow(y)
9 if chunk == nil {
10 return 0
11 }
12 return chunk.width
13}
14
15// Cell returns one semantic cell without allocating a row. Coordinates follow
16// Screen.Cell: x is the column and y is the row. Invalid coordinates return the
17// canonical blank cell. Variable-width history does not implement CellSource.
18func (v HistoryView) Cell(x, y int) renderer.Cell {
19 chunk, row := v.locateRow(y)
20 if chunk == nil || x < 0 || x >= chunk.width {
21 return renderer.BlankCell()
22 }
23 return chunk.cell(row, x)
24}
25
26// CopyRow copies up to len(dst) cells into caller-owned storage and returns the
27// number copied. It neither allocates a row nor exposes mutable page storage.
28func (v HistoryView) CopyRow(y int, dst []renderer.Cell) int {
29 chunk, row := v.locateRow(y)
30 if chunk == nil {
31 return 0
32 }
33 n := min(len(dst), chunk.width)
34 frame := chunk.frameView()
35 for x := range n {
36 dst[x] = frame.Cell(x, chunk.start+row)
37 }
38 return n
39}
40
41// RangeText streams each row's text in order without allocating per row. For
42// row i of the given cell width, runes holds one rune per non-continuation
43// cell (zero runes read as a space) and columns holds the cell column of each
44// rune. Both slices are only valid during the callback. Like Range, it
45// restores at most one cold page at a time and does not populate the page
46// cache.
47func (v HistoryView) RangeText(yield func(i int, runes []rune, columns []int, width int) bool) error {
48 var runes []rune
49 var columns []int
50 i := 0
51 for _, chunk := range v.chunks {
52 frame, err := chunk.page.readFrame(false)
53 if err != nil {
54 return err
55 }
56 for row := range chunk.len() {
57 runes, columns = frame.AppendRowText(runes[:0], columns[:0], chunk.start+row)
58 if !yield(i, runes, columns, chunk.width) {
59 return nil
60 }
61 i++
62 }
63 }
64 return nil
65}
66
67func (v HistoryView) locateRow(y int) (*HistoryChunk, int) {
68 if y < 0 {
69 return nil, 0
70 }
71 for _, chunk := range v.chunks {
72 if y < chunk.len() {
73 return chunk, y
74 }
75 y -= chunk.len()
76 }
77 return nil, 0
78}