v0.6.0 b250c5e

update.go RawHistoryFolder

1package html
2
3import (
4	"encoding/json"
5	"fmt"
6
7	"github.com/bnema/vev-vt/core"
8)
9
10// UpdateSchemaVersion identifies the browser update contract.
11const UpdateSchemaVersion uint16 = 2
12
13// CursorStyle is a DECSCUSR cursor shape value from 0 through 6.
14type CursorStyle uint8
15
16// Cursor is the absolute cursor state associated with an update. StyleSet
17// distinguishes an unset style from an explicit DECSCUSR style zero.
18type Cursor struct {
19	Row      int         `json:"row"`
20	Column   int         `json:"column"`
21	Visible  bool        `json:"visible"`
22	Style    CursorStyle `json:"style"`
23	StyleSet bool        `json:"styleSet"`
24}
25
26// ColorKind identifies how a terminal color is resolved.
27type ColorKind uint8
28
29const (
30	ColorDefault ColorKind = iota
31	ColorIndexed
32	ColorRGB
33)
34
35// RGB is a browser-facing RGB color.
36type RGB struct {
37	R uint8 `json:"r"`
38	G uint8 `json:"g"`
39	B uint8 `json:"b"`
40}
41
42// Color is a validated terminal color token.
43type Color struct {
44	Kind  ColorKind
45	Index uint8
46	RGB   RGB
47}
48
49func (color Color) MarshalJSON() ([]byte, error) {
50	switch color.Kind {
51	case ColorDefault:
52		return []byte(`{"kind":0}`), nil
53	case ColorIndexed:
54		return json.Marshal(struct {
55			Kind  ColorKind `json:"kind"`
56			Index uint8     `json:"index"`
57		}{Kind: color.Kind, Index: color.Index})
58	case ColorRGB:
59		return json.Marshal(struct {
60			Kind ColorKind `json:"kind"`
61			RGB  RGB       `json:"rgb"`
62		}{Kind: color.Kind, RGB: color.RGB})
63	default:
64		return nil, fmt.Errorf("html: invalid color kind %d", color.Kind)
65	}
66}
67
68// Style is the canonical, browser-facing subset of core.Style.
69type Style struct {
70	Bold           bool                `json:"bold,omitempty"`
71	Italic         bool                `json:"italic,omitempty"`
72	Inverse        bool                `json:"inverse,omitempty"`
73	Dim            bool                `json:"dim,omitempty"`
74	Blink          bool                `json:"blink,omitempty"`
75	Strikethrough  bool                `json:"strikethrough,omitempty"`
76	Underline      bool                `json:"underline,omitempty"`
77	UnderlineStyle core.UnderlineStyle `json:"underlineStyle,omitempty"`
78	Foreground     Color               `json:"foreground"`
79	Background     Color               `json:"background"`
80	UnderlineColor Color               `json:"underlineColor"`
81}
82
83// CellUpdate occupies Width terminal columns beginning at Column. It is
84// either a text run of Width printable ASCII characters (blank cells are
85// spaces) sharing one style, or one non-ASCII character of width 1 or 2.
86// Wide-cell continuation markers are represented by the preceding cell's
87// width. Text values of one update may share backing storage, so retaining
88// one keeps that update's text alive.
89type CellUpdate struct {
90	Column int    `json:"column"`
91	Width  int    `json:"width"`
92	Text   string `json:"text"`
93	Style  int    `json:"style"`
94}
95
96// RowUpdate replaces one complete logical terminal row.
97type RowUpdate struct {
98	Row   int          `json:"row"`
99	Cells []CellUpdate `json:"cells"`
100}
101
102// Update is an immutable-by-contract browser update. Snapshot updates contain
103// every logical row; incremental updates contain complete changed rows.
104type Update struct {
105	SchemaVersion uint16      `json:"schemaVersion"`
106	Width         int         `json:"width"`
107	Height        int         `json:"height"`
108	Snapshot      bool        `json:"snapshot"`
109	Rows          []RowUpdate `json:"rows"`
110	Styles        []Style     `json:"styles"`
111	Cursor        Cursor      `json:"cursor"`
112}
113
114func cloneUpdate(src Update) Update {
115	dst := src
116	dst.Styles = make([]Style, len(src.Styles))
117	copy(dst.Styles, src.Styles)
118	dst.Rows = make([]RowUpdate, len(src.Rows))
119	for i := range src.Rows {
120		dst.Rows[i] = src.Rows[i]
121		dst.Rows[i].Cells = append([]CellUpdate(nil), src.Rows[i].Cells...)
122	}
123	return dst
124}

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 2

Tags 13

↑↓ moveenter openesc close