v0.0.21 4dde650

quote_paste_test.go RawHistoryFolder

1package tui
2
3import "testing"
4
5func TestQuotePastedFilePaths(t *testing.T) {
6	cases := []struct {
7		name string
8		in   string
9		want string
10	}{
11		// macOS Terminal default: backslash-escaped spaces in path.
12		{"backslash-escaped space", `/Users/pat/foo\ bar.png`, `'/Users/pat/foo bar.png'`},
13
14		// Plain absolute path with no special chars.
15		{"plain absolute", `/Users/pat/file.png`, `'/Users/pat/file.png'`},
16
17		// file:// URL form; URL-decoded and scheme stripped.
18		{"file url", `file:///Users/pat/foo%20bar.png`, `'/Users/pat/foo bar.png'`},
19
20		// Tilde paths.
21		{"tilde", `~/Pictures/x.png`, `'~/Pictures/x.png'`},
22
23		// Multi-file drop, each path quoted independently.
24		{"two paths", `/a.png /b.png`, `'/a.png' '/b.png'`},
25
26		// Already single-quoted: re-normalise to consistent quoting.
27		{"already single quoted", `'/Users/pat/x.png'`, `'/Users/pat/x.png'`},
28
29		// Already double-quoted: re-normalise.
30		{"already double quoted", `"/Users/pat/x.png"`, `'/Users/pat/x.png'`},
31
32		// Embedded apostrophe gets the standard '\'' splice escape.
33		{"embedded apostrophe", `/Users/pat/it's.png`, `'/Users/pat/it'\''s.png'`},
34
35		// Plain prose left alone.
36		{"prose", `hello world`, `hello world`},
37
38		// Multi-line paste left alone (typical code paste).
39		{"multiline", "foo\nbar", "foo\nbar"},
40
41		// Anything containing shell metacharacters is left alone so a
42		// crafted "drop" can't smuggle a command.
43		{"metachar", `/foo;rm -rf /`, `/foo;rm -rf /`},
44
45		// Mixed: valid path token quoted, surrounding words preserved.
46		{"path mixed with prose", `/x.png is good`, `'/x.png' is good`},
47	}
48	for _, c := range cases {
49		t.Run(c.name, func(t *testing.T) {
50			got := quotePastedFilePaths(c.in)
51			if got != c.want {
52				t.Errorf("input %q\n  want %q\n  got  %q", c.in, c.want, got)
53			}
54		})
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 1

Tags 476

↑↓ moveenter openesc close