screen_snapshot.go RawHistoryFolder
1package vt
2
3import renderer "github.com/bnema/vev-vt/core"
4
5// CursorSnapshot is the cursor state captured with a visible screen snapshot.
6type CursorSnapshot struct {
7 Row int
8 Col int
9 Visible bool
10 Style int
11 StyleSet bool
12}
13
14// ModeSnapshot is the renderer-relevant VT mode state captured with a screen.
15type ModeSnapshot struct {
16 AlternateScreen bool
17 BracketedPaste bool
18 SynchronizedUpdate bool
19 ColorSchemeMode bool
20 MouseTracking int
21 MouseSGR bool
22}
23
24// ScreenSnapshot is an owned immutable-by-convention capture of the active
25// terminal viewport. Row returns caller-owned storage; BorrowedRow must not be
26// mutated and remains valid while the snapshot is retained.
27type ScreenSnapshot struct {
28 frame renderer.Frame
29 bounds []LineBound
30 rowIDs []RowID
31 cursor CursorSnapshot
32 modes ModeSnapshot
33 title string
34 nextRowID RowID
35}
36
37// Snapshot captures the active visible viewport without mutating Screen,
38// history, or pending damage. Screen remains single-owner; callers must
39// serialize Snapshot with Write, Resize, and host mutations.
40func (s *Screen) Snapshot() ScreenSnapshot {
41 if s == nil {
42 return ScreenSnapshot{}
43 }
44 cursorStyle, cursorStyleSet := s.CursorStyle()
45 mouseTracking, mouseSGR := s.MouseMode()
46 nextRowID := s.nextRowID
47 if nextRowID < ^RowID(0) {
48 nextRowID++
49 }
50 return ScreenSnapshot{
51 frame: s.Frame.Clone(),
52 bounds: s.LineBounds(),
53 rowIDs: s.RowIDs(),
54 nextRowID: nextRowID,
55 cursor: CursorSnapshot{
56 Row: s.CursorRow(),
57 Col: s.CursorCol(),
58 Visible: s.CursorVisible(),
59 Style: cursorStyle,
60 StyleSet: cursorStyleSet,
61 },
62 modes: ModeSnapshot{
63 AlternateScreen: s.AltScreenActive(),
64 BracketedPaste: s.BracketedPasteMode(),
65 SynchronizedUpdate: s.SyncUpdateActive(),
66 ColorSchemeMode: s.ColorSchemeMode(),
67 MouseTracking: mouseTracking,
68 MouseSGR: mouseSGR,
69 },
70 title: s.TerminalTitle(),
71 }
72}
73
74func (s ScreenSnapshot) Columns() int { return s.frame.Width }
75func (s ScreenSnapshot) Rows() int { return s.frame.Height }
76
77func (s ScreenSnapshot) Row(y int) []renderer.Cell {
78 return append([]renderer.Cell(nil), s.BorrowedRow(y)...)
79}
80
81func (s ScreenSnapshot) BorrowedRow(y int) []renderer.Cell {
82 if y < 0 || y >= s.frame.Height {
83 return nil
84 }
85 return s.frame.Row(y)
86}
87
88func (s ScreenSnapshot) Bound(y int) LineBound {
89 if y < 0 || y >= len(s.bounds) {
90 return LineBound{}
91 }
92 return s.bounds[y]
93}
94
95// RowIDs returns an owned copy of the visible physical-row identities.
96func (s ScreenSnapshot) RowIDs() []RowID { return append([]RowID(nil), s.rowIDs...) }
97
98// RowID returns the identity of visible row y, or zero when out of range.
99func (s ScreenSnapshot) RowID(y int) RowID {
100 if y < 0 || y >= len(s.rowIDs) {
101 return 0
102 }
103 return s.rowIDs[y]
104}
105
106// NextRowID returns the next identity allocated by the captured screen.
107func (s ScreenSnapshot) NextRowID() RowID {
108 if s.nextRowID == 0 {
109 return 1
110 }
111 return s.nextRowID
112}
113
114func (s ScreenSnapshot) Cursor() CursorSnapshot { return s.cursor }
115func (s ScreenSnapshot) Modes() ModeSnapshot { return s.modes }
116func (s ScreenSnapshot) Title() string { return s.title }