v0.50.1 a637010

highlight_test.go RawHistoryFolder

1package tui
2
3import (
4	"regexp"
5	"strings"
6	"testing"
7)
8
9func TestStripANSIBackgroundsKeepsExtendedColors(t *testing.T) {
10	cases := []struct{ name, in, want string }{
11		{"256 foreground in background range", "\x1b[38;5;45mstring\x1b[0m", "\x1b[38;5;45mstring\x1b[0m"},
12		{"256 foreground index 48", "\x1b[38;5;48mx\x1b[0m", "\x1b[38;5;48mx\x1b[0m"},
13		{"256 foreground index 49", "\x1b[38;5;49mx\x1b[0m", "\x1b[38;5;49mx\x1b[0m"},
14		{"256 foreground bright range", "\x1b[38;5;101mcomment\x1b[0m", "\x1b[38;5;101mcomment\x1b[0m"},
15		{"256 foreground index 107", "\x1b[38;5;107mx\x1b[0m", "\x1b[38;5;107mx\x1b[0m"},
16		{"bold plus foreground", "\x1b[1;38;5;45mstring\x1b[0m", "\x1b[1;38;5;45mstring\x1b[0m"},
17		{"truecolor foreground", "\x1b[38;2;40;101;49mstring\x1b[0m", "\x1b[38;2;40;101;49mstring\x1b[0m"},
18		{"plain text", "hello", "hello"},
19		{"reset", "\x1b[0m", "\x1b[0m"},
20		{"256 background dropped", "\x1b[48;5;45mbg\x1b[0m", "bg\x1b[0m"},
21		{"separate background dropped", "\x1b[38;5;45m\x1b[48;5;0mtext", "\x1b[38;5;45mtext"},
22		{"combined background dropped", "\x1b[38;5;45;48;5;0mtext", "\x1b[38;5;45mtext"},
23		{"truecolor background dropped", "\x1b[48;2;9;0;21mbg\x1b[0m", "bg\x1b[0m"},
24		{"default background dropped", "\x1b[49mbg", "bg"},
25		{"ANSI background dropped", "\x1b[41mbg", "bg"},
26		{"bright background dropped", "\x1b[101mbg", "bg"},
27		{"bare foreground introducer dropped", "\x1b[38mtext", "text"},
28		{"truncated indexed foreground", "\x1b[38;5mstring", "string"},
29		{"truncated indexed background", "\x1b[48;5mstring", "string"},
30		{"truncated truecolor foreground", "\x1b[38;2;1;2mtext", "text"},
31		{"truncated truecolor background", "\x1b[48;2;1;2mtext", "text"},
32		// An unsupported extended selector is not consumed as a color unit;
33		// unrelated standalone attributes keep their ordinary SGR semantics.
34		{"unknown selector preserves reverse", "\x1b[38;7mtext", "\x1b[7mtext"},
35	}
36	for _, tc := range cases {
37		t.Run(tc.name, func(t *testing.T) {
38			if got := stripANSIBackgrounds(tc.in); got != tc.want {
39				t.Fatalf("got %q, want %q", got, tc.want)
40			}
41		})
42	}
43}
44
45// Chroma maps this custom type color to xterm index 45, which the old
46// background filter removed from the foreground unit.
47func TestHighlightCodeExtendedColorIsWellFormed(t *testing.T) {
48	th := Dark
49	th.Syntax = SyntaxTheme{KeywordType: "#00e5ff", NameBuiltin: "#00e5ff"}
50	joined := strings.Join(th.HighlightCode("func splitFrontmatter(raw string) (string, string) {\n", "go"), "\n")
51	if strings.Contains(joined, "\x1b[38;5m") || strings.Contains(joined, "\x1b[48;5m") {
52		t.Fatalf("highlighting emitted a malformed extended color: %q", joined)
53	}
54	idx := strings.Index(joined, "string")
55	if idx < 0 {
56		t.Fatalf("type keyword missing: %q", joined)
57	}
58	prefix := joined[:idx]
59	escape := strings.LastIndex(prefix, "\x1b[")
60	if escape < 0 || !regexp.MustCompile(`^\x1b\[(?:[0-9]+;)*38;5;[0-9]+m$`).MatchString(prefix[escape:]) {
61		t.Fatalf("type keyword lost its foreground color: %q", joined)
62	}
63}

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 1

Tags 476

↑↓ moveenter openesc close