bindings.go RawHistoryFolder

1package keys
2
3// Bindings maps intercepted Alt keys to actions. A Bindings value is mutable
4// while being built, then treated as frozen once published through an atomic
5// pointer; callers must clone before using mutators.
6type Bindings struct {
7	altRunes  map[rune]Action
8	altArrows map[byte]Action
9}
10
11var defaultBindings = DefaultBindings()
12
13// DefaultBindings returns vev's built-in Alt-key bindings.
14func DefaultBindings() *Bindings {
15	altRunes := map[rune]Action{
16		' ': ActionOpenPalette,
17		'a': ActionJumpAttention,
18		'f': ActionToggleFloatingPane,
19		'h': ActionFocusPaneLeft,
20		'j': ActionFocusPaneDown,
21		'k': ActionFocusPaneUp,
22		'l': ActionFocusPaneRight,
23	}
24	for idx, aliases := range topRowDigitAliases {
25		for _, alias := range aliases {
26			altRunes[alias] = ActionSwitchTab1 + Action(idx)
27		}
28	}
29	return &Bindings{
30		altRunes: altRunes,
31		altArrows: map[byte]Action{
32			'A': ActionFocusPaneUp,
33			'B': ActionFocusPaneDown,
34			'C': ActionFocusPaneRight,
35			'D': ActionFocusPaneLeft,
36		},
37	}
38}
39
40func (b *Bindings) clone() *Bindings {
41	if b == nil {
42		return DefaultBindings()
43	}
44	clone := &Bindings{
45		altRunes:  make(map[rune]Action, len(b.altRunes)),
46		altArrows: make(map[byte]Action, len(b.altArrows)),
47	}
48	for key, action := range b.altRunes {
49		clone.altRunes[key] = action
50	}
51	for key, action := range b.altArrows {
52		clone.altArrows[key] = action
53	}
54	return clone
55}
56
57func (b *Bindings) removeAction(action Action) {
58	for key, bound := range b.altRunes {
59		if bound == action {
60			delete(b.altRunes, key)
61		}
62	}
63	for key, bound := range b.altArrows {
64		if bound == action {
65			delete(b.altArrows, key)
66		}
67	}
68}
69
70func (b *Bindings) bind(action Action, spec KeySpec) {
71	for _, key := range spec.altRunes {
72		b.altRunes[key] = action
73	}
74	if spec.altArrow != 0 {
75		b.altArrows[spec.altArrow] = action
76	}
77}
78
79func (b *Bindings) restoreDefaultAction(action Action) {
80	defaults := DefaultBindings()
81	for key, bound := range defaults.altRunes {
82		if bound == action {
83			if _, occupied := b.altRunes[key]; !occupied {
84				b.altRunes[key] = action
85			}
86		}
87	}
88	for key, bound := range defaults.altArrows {
89		if bound == action {
90			if _, occupied := b.altArrows[key]; !occupied {
91				b.altArrows[key] = action
92			}
93		}
94	}
95}
96
97func (b *Bindings) conflictingAction(spec KeySpec, action Action) (Action, bool) {
98	for _, key := range spec.altRunes {
99		if bound, ok := b.altRunes[key]; ok && bound != action {
100			return bound, true
101		}
102	}
103	if spec.altArrow != 0 {
104		if bound, ok := b.altArrows[spec.altArrow]; ok && bound != action {
105			return bound, true
106		}
107	}
108	return 0, false
109}
110
111func (b *Bindings) actionForAltRune(key rune) (Action, bool) {
112	if b == nil {
113		b = defaultBindings
114	}
115	action, ok := b.altRunes[key]
116	return action, ok
117}
118
119func (b *Bindings) actionForAltArrow(final byte) (Action, bool) {
120	if b == nil {
121		b = defaultBindings
122	}
123	action, ok := b.altArrows[final]
124	return action, ok
125}

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