v0.8.1 1f54f61

content_selection_test.go RawHistoryFolder

1package copy
2
3import (
4	"testing"
5
6	vt "github.com/bnema/vev-vt"
7	"github.com/stretchr/testify/require"
8)
9
10func TestSelectionContentBoundedRanges(t *testing.T) {
11	tests := []struct {
12		name      string
13		rows      [][]vt.Cell
14		bounds    []vt.LineBound
15		selection Selection
16		target    int
17		want      CellRange
18		text      string
19	}{
20		{"line", [][]vt.Cell{padRow("ab", 8)}, nil, Selection{Anchor: Pos{0, 0}, Active: Pos{0, 0}, Granularity: Line, Enabled: true}, 0, CellRange{Row: 0, End: 1}, "ab"},
21		{"character middle", [][]vt.Cell{padRow("x", 8), padRow("ab", 8), padRow("z", 8)}, nil, Selection{Anchor: Pos{0, 0}, Active: Pos{2, 0}, Granularity: Character, Enabled: true}, 1, CellRange{Row: 1, End: 1}, "x\nab\nz"},
22		{"character end in padding", [][]vt.Cell{padRow("ab", 8)}, nil, Selection{Anchor: Pos{0, 0}, Active: Pos{0, 6}, Granularity: Character, Enabled: true}, 0, CellRange{End: 1}, "ab"},
23		{"soft trailing spaces", [][]vt.Cell{padRow("abc     ", 8), padRow("de", 8)}, []vt.LineBound{{End: 8, Soft: true}, {End: 2}}, Selection{Anchor: Pos{0, 0}, Active: Pos{1, 1}, Granularity: Character, Enabled: true}, 0, CellRange{End: 7}, "abc     de"},
24		{"soft partial bound", [][]vt.Cell{padRow("abc", 8), padRow("de", 8)}, []vt.LineBound{{End: 5, Soft: true}, {End: 2}}, Selection{Anchor: Pos{0, 0}, Active: Pos{1, 1}, Granularity: Character, Enabled: true}, 0, CellRange{End: 4}, "abc  de"},
25		{"blank middle", [][]vt.Cell{padRow("ab", 8), padRow("", 8), padRow("cd", 8)}, nil, Selection{Anchor: Pos{0, 0}, Active: Pos{2, 1}, Granularity: Character, Enabled: true}, 1, CellRange{Row: 1, End: -1}, "ab\n\ncd"},
26		{"anchor in padding", [][]vt.Cell{padRow("ab", 8)}, nil, Selection{Anchor: Pos{0, 5}, Active: Pos{0, 6}, Granularity: Character, Enabled: true}, 0, CellRange{Start: 5, End: 4}, ""},
27	}
28	for _, tt := range tests {
29		t.Run(tt.name, func(t *testing.T) {
30			doc := NewDocument(NewSnapshotFromLines(tt.rows, tt.bounds, 8, len(tt.rows)), "")
31			got, ok := tt.selection.RangeForRow(doc, tt.target)
32			require.True(t, ok)
33			require.Equal(t, tt.want, got)
34			require.Contains(t, tt.selection.Ranges(doc), got)
35			require.Equal(t, tt.text, tt.selection.Text(doc))
36		})
37	}
38}
39
40func TestDocumentExtractSelectedEmptyRanges(t *testing.T) {
41	doc := NewDocument(NewSnapshotFromRows([][]vt.Cell{padRow("ab", 8), padRow("", 8), padRow("cd", 8)}, 8, 3), "")
42	tests := []struct {
43		name   string
44		ranges []CellRange
45		want   string
46	}{
47		{"empty", []CellRange{{Row: 0, End: -1}}, ""},
48		{"reversed", []CellRange{{Row: 2, Start: 7, End: 0}}, "cd"},
49		{"past end", []CellRange{{Row: 0, Start: 99, End: 50}, {Row: 2, End: 1}}, "cd"},
50		{"negative", []CellRange{{Row: 0, Start: -3, End: -9}, {Row: 2, End: 1}}, "cd"},
51		{"blank middle", []CellRange{{Row: 0, End: 1}, {Row: 1, End: -1}, {Row: 2, End: 1}}, "ab\n\ncd"},
52	}
53	for _, tt := range tests {
54		t.Run(tt.name, func(t *testing.T) { require.Equal(t, tt.want, doc.Extract(tt.ranges)) })
55	}
56}

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