codec_encoder_test.go RawHistoryFolder

1package snapshot
2
3import (
4	"encoding/binary"
5	"fmt"
6	"hash/crc32"
7	"math"
8
9	"github.com/bnema/vev/internal/usecase/layout"
10)
11
12// marshalTest is a test-only v4 encoder. Production retains only the decoder
13// required by the one-time import.
14func marshalTest(s Session) ([]byte, error) {
15	var w payloadWriter
16	if err := writeSession(&w, s); err != nil {
17		return nil, err
18	}
19	if len(w.b) > maxDecodedBodySize || len(w.b) > math.MaxUint32 {
20		return nil, fmt.Errorf("%w: body too large", ErrInvalidData)
21	}
22	out := make([]byte, 16+len(w.b))
23	copy(out[:4], magic)
24	binary.BigEndian.PutUint16(out[4:6], version)
25	binary.BigEndian.PutUint32(out[8:12], uint32(len(w.b)))
26	binary.BigEndian.PutUint32(out[12:16], crc32.ChecksumIEEE(w.b))
27	copy(out[16:], w.b)
28	return out, nil
29}
30
31func writeSession(w *payloadWriter, s Session) error {
32	if len(s.Tabs) > math.MaxUint16 {
33		return fmt.Errorf("%w: too many tabs", ErrInvalidData)
34	}
35	if err := validateActive(s.Active, len(s.Tabs)); err != nil {
36		return err
37	}
38	if err := w.putString(s.Name); err != nil {
39		return err
40	}
41	w.putUint64(s.CreatedAt)
42	w.putUint16(s.Active)
43	w.putUint16(uint16(len(s.Tabs)))
44	for _, t := range s.Tabs {
45		if err := writeTab(w, t); err != nil {
46			return err
47		}
48	}
49	return nil
50}
51
52func writeTab(w *payloadWriter, t Tab) error {
53	if err := w.putString(t.StableID); err != nil {
54		return err
55	}
56	w.putUint16(t.Cols)
57	w.putUint16(t.Rows)
58	w.putUint64(t.NextPaneID)
59	if err := w.putString(string(t.Focus)); err != nil {
60		return err
61	}
62	var root *layout.Node
63	if t.Tree != nil {
64		root = t.Tree.Root
65	}
66	if err := writeNode(w, root); err != nil {
67		return err
68	}
69	if len(t.Panes) > math.MaxUint16 {
70		return fmt.Errorf("%w: too many panes", ErrInvalidData)
71	}
72	w.putUint16(uint16(len(t.Panes)))
73	for _, p := range t.Panes {
74		if err := writePane(w, p); err != nil {
75			return err
76		}
77	}
78	return nil
79}
80
81func writePane(w *payloadWriter, p Pane) error {
82	if err := w.putString(string(p.ID)); err != nil {
83		return err
84	}
85	if err := w.putString(p.StableID); err != nil {
86		return err
87	}
88	if err := w.putString(p.Cwd); err != nil {
89		return err
90	}
91	if len(p.SealedChunks) > maxSnapshotObjects {
92		return fmt.Errorf("%w: too many sealed chunks", ErrInvalidData)
93	}
94	w.putUint32(uint32(len(p.SealedChunks)))
95	for _, blob := range p.SealedChunks {
96		if len(blob) == 0 || len(blob) > math.MaxUint32 {
97			return fmt.Errorf("%w: sealed chunk length", ErrInvalidData)
98		}
99		w.putUint32(uint32(len(blob)))
100		w.b = append(w.b, blob...)
101	}
102	if len(p.Tail) == 0 || len(p.Tail) > math.MaxUint32 {
103		return fmt.Errorf("%w: tail length", ErrInvalidData)
104	}
105	w.putUint32(uint32(len(p.Tail)))
106	w.b = append(w.b, p.Tail...)
107	if len(p.Transcript) == 0 || len(p.Transcript) > math.MaxUint32 {
108		return fmt.Errorf("%w: transcript length", ErrInvalidData)
109	}
110	w.putUint32(uint32(len(p.Transcript)))
111	w.b = append(w.b, p.Transcript...)
112	return writeProcess(w, p.Process)
113}

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