v0.1.0 7deb448

screen_snapshot.go RawHistoryFolder

1package vt
2
3import "github.com/bnema/vev/pkg/renderer"
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	cursor CursorSnapshot
31	modes  ModeSnapshot
32	title  string
33}
34
35// Snapshot captures the active visible viewport without mutating Screen,
36// history, or pending damage. Screen remains single-owner; callers must
37// serialize Snapshot with Write, Resize, and host mutations.
38func (s *Screen) Snapshot() ScreenSnapshot {
39	if s == nil {
40		return ScreenSnapshot{}
41	}
42	cursorStyle, cursorStyleSet := s.CursorStyle()
43	mouseTracking, mouseSGR := s.MouseMode()
44	return ScreenSnapshot{
45		frame:  s.Frame.Clone(),
46		bounds: s.LineBounds(),
47		cursor: CursorSnapshot{
48			Row:      s.CursorRow(),
49			Col:      s.CursorCol(),
50			Visible:  s.CursorVisible(),
51			Style:    cursorStyle,
52			StyleSet: cursorStyleSet,
53		},
54		modes: ModeSnapshot{
55			AlternateScreen:    s.AltScreenActive(),
56			BracketedPaste:     s.BracketedPasteMode(),
57			SynchronizedUpdate: s.SyncUpdateActive(),
58			ColorSchemeMode:    s.ColorSchemeMode(),
59			MouseTracking:      mouseTracking,
60			MouseSGR:           mouseSGR,
61		},
62		title: s.TerminalTitle(),
63	}
64}
65
66func (s ScreenSnapshot) Columns() int { return s.frame.Width }
67func (s ScreenSnapshot) Rows() int    { return s.frame.Height }
68
69func (s ScreenSnapshot) Row(y int) []renderer.Cell {
70	return append([]renderer.Cell(nil), s.BorrowedRow(y)...)
71}
72
73func (s ScreenSnapshot) BorrowedRow(y int) []renderer.Cell {
74	if y < 0 || y >= s.frame.Height {
75		return nil
76	}
77	return s.frame.Row(y)
78}
79
80func (s ScreenSnapshot) Bound(y int) LineBound {
81	if y < 0 || y >= len(s.bounds) {
82		return LineBound{}
83	}
84	return s.bounds[y]
85}
86
87func (s ScreenSnapshot) Cursor() CursorSnapshot { return s.cursor }
88func (s ScreenSnapshot) Modes() ModeSnapshot    { return s.modes }
89func (s ScreenSnapshot) Title() string          { return s.title }

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close