v0.33.1 9577fee

key_test.go RawHistoryFolder

1package vimkeys
2
3import (
4	"testing"
5)
6
7func TestKeyString(t *testing.T) {
8	tests := []struct {
9		name string
10		key  Key
11		want string
12	}{
13		{name: "letter", key: Key{Sym: "j"}, want: "j"},
14		{name: "shift letter", key: Key{Sym: "j", Mods: ModShift}, want: "J"},
15		{name: "ctrl letter", key: Key{Sym: "d", Mods: ModCtrl}, want: "<C-d>"},
16		{name: "ctrl plus", key: Key{Sym: "+", Mods: ModCtrl}, want: "<C-+>"},
17		{name: "bare plus", key: Key{Sym: "+"}, want: "<Plus>"},
18		{name: "shift glyph", key: Key{Sym: "!"}, want: "!"},
19		{name: "special CR", key: Key{Sym: "CR"}, want: "<Return>"},
20		{name: "special Esc", key: Key{Sym: "Esc"}, want: "<Escape>"},
21		{name: "special Space", key: Key{Sym: "Space"}, want: "<Space>"},
22		{name: "special Tab", key: Key{Sym: "Tab"}, want: "<Tab>"},
23		{name: "special BackSpace", key: Key{Sym: "BackSpace"}, want: "<BackSpace>"},
24		{name: "special Delete", key: Key{Sym: "Delete"}, want: "<Delete>"},
25		{name: "special Left", key: Key{Sym: "Left"}, want: "<Left>"},
26		{name: "special Right", key: Key{Sym: "Right"}, want: "<Right>"},
27		{name: "special Up", key: Key{Sym: "Up"}, want: "<Up>"},
28		{name: "special Down", key: Key{Sym: "Down"}, want: "<Down>"},
29		{name: "special Home", key: Key{Sym: "Home"}, want: "<Home>"},
30		{name: "special End", key: Key{Sym: "End"}, want: "<End>"},
31		{name: "special PageUp", key: Key{Sym: "PageUp"}, want: "<PageUp>"},
32		{name: "special PageDown", key: Key{Sym: "PageDown"}, want: "<PageDown>"},
33		{name: "ctrl Tab", key: Key{Sym: "Tab", Mods: ModCtrl}, want: "<C-Tab>"},
34		{name: "shift BackSpace", key: Key{Sym: "BackSpace", Mods: ModShift}, want: "<S-BackSpace>"},
35		{name: "alt Delete", key: Key{Sym: "Delete", Mods: ModAlt}, want: "<A-Delete>"},
36		{name: "ctrl Left", key: Key{Sym: "Left", Mods: ModCtrl}, want: "<C-Left>"},
37		{name: "literal lt", key: Key{Sym: "<"}, want: "<lt>"},
38		{name: "literal gt", key: Key{Sym: ">"}, want: "<gt>"},
39		{name: "ctrl gt", key: Key{Sym: ">", Mods: ModCtrl}, want: "<C-gt>"},
40		{name: "alt only", key: Key{Sym: "b", Mods: ModAlt}, want: "<A-b>"},
41		{name: "ctrl alt", key: Key{Sym: "c", Mods: ModCtrl | ModAlt}, want: "<C-A-c>"},
42		{name: "ctrl shift", key: Key{Sym: "a", Mods: ModCtrl | ModShift}, want: "<C-S-a>"},
43	}
44	for _, tt := range tests {
45		t.Run(tt.name, func(t *testing.T) {
46			if got := tt.key.String(); got != tt.want {
47				t.Errorf("Key.String() = %q, want %q", got, tt.want)
48			}
49		})
50	}
51}
52
53func TestSequenceString(t *testing.T) {
54	tests := []struct {
55		name string
56		seq  Sequence
57		want string
58	}{
59		{name: "yah", seq: Sequence{{Sym: "y"}, {Sym: "a"}, {Sym: "h"}}, want: "yah"},
60		{name: "double bracket", seq: Sequence{{Sym: "]"}, {Sym: "]"}}, want: "]]"},
61		{name: "gO", seq: Sequence{{Sym: "g"}, {Sym: "o", Mods: ModShift}}, want: "gO"},
62		{name: "esc collision", seq: Sequence{{Sym: "e"}, {Sym: "s"}, {Sym: "c"}}, want: "<e>sc"},
63		{name: "enter collision", seq: Sequence{{Sym: "e"}, {Sym: "n"}, {Sym: "t"}, {Sym: "e"}, {Sym: "r"}}, want: "<e>nter"},
64	}
65	for _, tt := range tests {
66		t.Run(tt.name, func(t *testing.T) {
67			if got := tt.seq.String(); got != tt.want {
68				t.Errorf("Sequence.String() = %q, want %q", got, tt.want)
69			}
70		})
71	}
72}
73
74func TestSequenceEqual(t *testing.T) {
75	a := Sequence{{Sym: "j"}, {Sym: "k"}}
76	b := Sequence{{Sym: "j"}, {Sym: "k"}}
77	c := Sequence{{Sym: "j"}}
78	if !a.Equal(b) {
79		t.Fatal("equal sequences reported unequal")
80	}
81	if a.Equal(c) {
82		t.Fatal("unequal length sequences reported equal")
83	}
84	if a.Equal(Sequence{{Sym: "j"}, {Sym: "x"}}) {
85		t.Fatal("different keys reported equal")
86	}
87}
88
89func TestKeyStringEmpty(t *testing.T) {
90	if got := (Key{}).String(); got != "" {
91		t.Fatalf("empty Key.String() = %q, want empty", got)
92	}
93}
94
95func TestErrorSentinels(t *testing.T) {
96	if ErrEmptyBinding.Error() != "vimkeys: empty binding" {
97		t.Errorf("ErrEmptyBinding = %q, want %q", ErrEmptyBinding.Error(), "vimkeys: empty binding")
98	}
99	if ErrBadBinding.Error() != "vimkeys: malformed binding" {
100		t.Errorf("ErrBadBinding = %q, want %q", ErrBadBinding.Error(), "vimkeys: malformed binding")
101	}
102}

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 8

Tags 42

↑↓ moveenter openesc close