1 /* Configure your desired default key bindings. */
3 #define ALIAS(name) .alias = name,
4 #define ACTION(id) .action = &vis_action[VIS_ACTION_##id],
6 static const char *keymaps
[] = {
10 static const KeyBinding bindings_basic
[] = {
11 { "<C-z>", ACTION(EDITOR_SUSPEND
) },
12 { "<Down>", ACTION(CURSOR_LINE_DOWN
) },
13 { "<End>", ACTION(CURSOR_LINE_END
) },
14 { "<Home>", ACTION(CURSOR_LINE_BEGIN
) },
15 { "<Left>", ACTION(CURSOR_CHAR_PREV
) },
16 { "<PageDown>", ACTION(WINDOW_PAGE_DOWN
) },
17 { "<PageUp>", ACTION(WINDOW_PAGE_UP
) },
18 { "<Right>", ACTION(CURSOR_CHAR_NEXT
) },
19 { "<S-Left>", ACTION(CURSOR_LONGWORD_START_PREV
) },
20 { "<S-PageDown>", ACTION(WINDOW_HALFPAGE_DOWN
) },
21 { "<S-PageUp>", ACTION(WINDOW_HALFPAGE_UP
) },
22 { "<S-Right>", ACTION(CURSOR_LONGWORD_START_NEXT
) },
23 { "<Up>", ACTION(CURSOR_LINE_UP
) },
24 { 0 /* empty last element, array terminator */ },
27 static const KeyBinding bindings_motions
[] = {
28 { "g|", ACTION(CURSOR_COLUMN
) },
29 { "[{", ACTION(CURSOR_BLOCK_START
) },
30 { "]}", ACTION(CURSOR_BLOCK_END
) },
31 { "[(", ACTION(CURSOR_PARENTHESIS_START
) },
32 { "])", ACTION(CURSOR_PARENTHESIS_END
) },
33 { "$", ACTION(CURSOR_LINE_END
) },
34 { "^", ACTION(CURSOR_LINE_START
) },
35 { "}", ACTION(CURSOR_PARAGRAPH_NEXT
) },
36 { "{", ACTION(CURSOR_PARAGRAPH_PREV
) },
37 { "%", ACTION(CURSOR_PERCENT
) },
38 { "#", ACTION(CURSOR_SEARCH_WORD_BACKWARD
) },
39 { "*", ACTION(CURSOR_SEARCH_WORD_FORWARD
) },
40 { ")", ACTION(CURSOR_SENTENCE_NEXT
) },
41 { "(", ACTION(CURSOR_SENTENCE_PREV
) },
42 { "?", ACTION(PROMPT_SEARCH_BACKWARD
) },
43 { "/", ACTION(PROMPT_SEARCH_FORWARD
) },
44 { ";", ACTION(TOTILL_REPEAT
) },
45 { ",", ACTION(TOTILL_REVERSE
) },
48 { "B", ACTION(CURSOR_LONGWORD_START_PREV
) },
49 { "b", ACTION(CURSOR_WORD_START_PREV
) },
50 { "E", ACTION(CURSOR_LONGWORD_END_NEXT
) },
51 { "e", ACTION(CURSOR_WORD_END_NEXT
) },
52 { "F", ACTION(TO_LINE_LEFT
) },
53 { "f", ACTION(TO_LINE_RIGHT
) },
54 { "go", ACTION(CURSOR_BYTE
) },
55 { "gH", ACTION(CURSOR_BYTE_LEFT
) },
56 { "gL", ACTION(CURSOR_BYTE_RIGHT
) },
57 { "gh", ACTION(CURSOR_CODEPOINT_PREV
) },
58 { "gl", ACTION(CURSOR_CODEPOINT_NEXT
) },
59 { "g0", ACTION(CURSOR_SCREEN_LINE_BEGIN
) },
60 { "g_", ACTION(CURSOR_LINE_FINISH
) },
61 { "G", ACTION(CURSOR_LINE_LAST
) },
62 { "g$", ACTION(CURSOR_SCREEN_LINE_END
) },
63 { "gE", ACTION(CURSOR_LONGWORD_END_PREV
) },
64 { "ge", ACTION(CURSOR_WORD_END_PREV
) },
65 { "gg", ACTION(CURSOR_LINE_FIRST
) },
66 { "gj", ACTION(CURSOR_SCREEN_LINE_DOWN
) },
67 { "gk", ACTION(CURSOR_SCREEN_LINE_UP
) },
68 { "gm", ACTION(CURSOR_SCREEN_LINE_MIDDLE
) },
69 { "h", ACTION(CURSOR_CHAR_PREV
) },
70 { "H", ACTION(CURSOR_WINDOW_LINE_TOP
) },
71 { "j", ACTION(CURSOR_LINE_DOWN
) },
72 { "k", ACTION(CURSOR_LINE_UP
) },
73 { "l", ACTION(CURSOR_CHAR_NEXT
) },
74 { "L", ACTION(CURSOR_WINDOW_LINE_BOTTOM
) },
75 { "M", ACTION(CURSOR_WINDOW_LINE_MIDDLE
) },
76 { "n", ACTION(CURSOR_SEARCH_REPEAT_FORWARD
) },
77 { "N", ACTION(CURSOR_SEARCH_REPEAT_BACKWARD
) },
78 { "T", ACTION(TILL_LINE_LEFT
) },
79 { "t", ACTION(TILL_LINE_RIGHT
) },
80 { "W", ACTION(CURSOR_LONGWORD_START_NEXT
) },
81 { "w", ACTION(CURSOR_WORD_START_NEXT
) },
82 { 0 /* empty last element, array terminator */ },
85 static const KeyBinding bindings_textobjects
[] = {
86 { "a<", ACTION(TEXT_OBJECT_ANGLE_BRACKET_OUTER
) },
87 { "a`", ACTION(TEXT_OBJECT_BACKTICK_OUTER
) },
88 { "a{", ACTION(TEXT_OBJECT_CURLY_BRACKET_OUTER
) },
89 { "a(", ACTION(TEXT_OBJECT_PARENTHESIS_OUTER
) },
90 { "a\"", ACTION(TEXT_OBJECT_QUOTE_OUTER
) },
91 { "a\'", ACTION(TEXT_OBJECT_SINGLE_QUOTE_OUTER
) },
92 { "a[", ACTION(TEXT_OBJECT_SQUARE_BRACKET_OUTER
) },
93 { "a>", ALIAS("a<") },
94 { "a)", ALIAS("a(") },
95 { "a]", ALIAS("a[") },
96 { "a}", ALIAS("a{") },
97 { "ab", ALIAS("a(") },
98 { "aB", ALIAS("a{") },
99 { "al", ACTION(TEXT_OBJECT_LINE_OUTER
) },
100 { "ap", ACTION(TEXT_OBJECT_PARAGRAPH_OUTER
) },
101 { "as", ACTION(TEXT_OBJECT_SENTENCE
) },
102 { "a<Tab>", ACTION(TEXT_OBJECT_INDENTATION
) },
103 { "aW", ACTION(TEXT_OBJECT_LONGWORD_OUTER
) },
104 { "aw", ACTION(TEXT_OBJECT_WORD_OUTER
) },
105 { "gN", ACTION(TEXT_OBJECT_SEARCH_BACKWARD
) },
106 { "gn", ACTION(TEXT_OBJECT_SEARCH_FORWARD
) },
107 { "i<", ACTION(TEXT_OBJECT_ANGLE_BRACKET_INNER
) },
108 { "i`", ACTION(TEXT_OBJECT_BACKTICK_INNER
) },
109 { "i{", ACTION(TEXT_OBJECT_CURLY_BRACKET_INNER
) },
110 { "i(", ACTION(TEXT_OBJECT_PARENTHESIS_INNER
) },
111 { "i\"", ACTION(TEXT_OBJECT_QUOTE_INNER
) },
112 { "i\'", ACTION(TEXT_OBJECT_SINGLE_QUOTE_INNER
) },
113 { "i[", ACTION(TEXT_OBJECT_SQUARE_BRACKET_INNER
) },
114 { "i>", ALIAS("i<") },
115 { "i)", ALIAS("i(") },
116 { "i]", ALIAS("i[") },
117 { "i}", ALIAS("i{") },
118 { "ib", ALIAS("i(") },
119 { "iB", ALIAS("i{") },
120 { "il", ACTION(TEXT_OBJECT_LINE_INNER
) },
121 { "ip", ACTION(TEXT_OBJECT_PARAGRAPH
) },
122 { "is", ACTION(TEXT_OBJECT_SENTENCE
) },
123 { "i<Tab>", ACTION(TEXT_OBJECT_INDENTATION
) },
124 { "iW", ACTION(TEXT_OBJECT_LONGWORD_INNER
) },
125 { "iw", ACTION(TEXT_OBJECT_WORD_INNER
) },
126 { 0 /* empty last element, array terminator */ },
129 static const KeyBinding bindings_selections
[] = {
130 { "m", ACTION(SELECTIONS_SAVE
) },
131 { "M", ACTION(SELECTIONS_RESTORE
) },
132 { "|", ACTION(SELECTIONS_UNION
) },
133 { "&", ACTION(SELECTIONS_INTERSECT
) },
134 { "~", ACTION(SELECTIONS_COMPLEMENT
) },
135 { "\\", ACTION(SELECTIONS_MINUS
) },
136 { "_", ACTION(SELECTIONS_TRIM
) },
137 { "<S-Tab>", ACTION(SELECTIONS_ALIGN_INDENT_RIGHT
) },
138 { "<Tab>", ACTION(SELECTIONS_ALIGN_INDENT_LEFT
) },
139 { "g<", ACTION(JUMPLIST_PREV
) },
140 { "gs", ACTION(JUMPLIST_SAVE
) },
141 { "g>", ACTION(JUMPLIST_NEXT
) },
142 { 0 /* empty last element, array terminator */ },
145 static const KeyBinding bindings_operators
[] = {
146 { "0", ACTION(COUNT
) },
147 { "1", ACTION(COUNT
) },
148 { "2", ACTION(COUNT
) },
149 { "3", ACTION(COUNT
) },
150 { "4", ACTION(COUNT
) },
151 { "5", ACTION(COUNT
) },
152 { "6", ACTION(COUNT
) },
153 { "7", ACTION(COUNT
) },
154 { "8", ACTION(COUNT
) },
155 { "9", ACTION(COUNT
) },
156 { "=", ALIAS(":|fmt<Enter>") },
157 { "<", ACTION(OPERATOR_SHIFT_LEFT
) },
158 { ">", ACTION(OPERATOR_SHIFT_RIGHT
) },
159 { "\"", ACTION(REGISTER
) },
160 { "'", ACTION(MARK
) },
161 { "c", ACTION(OPERATOR_CHANGE
) },
162 { "d", ACTION(OPERATOR_DELETE
) },
163 { "g~", ALIAS(":|tr '[:lower:][:upper:]' '[:upper:][:lower:]'<Enter>") },
164 { "gu", ALIAS(":|awk '{printf \"%s\", tolower($0)}'<Enter>")},
165 { "gU", ALIAS(":|awk '{printf \"%s\", toupper($0)}'<Enter>")},
166 { "p", ACTION(PUT_AFTER
) },
167 { "P", ACTION(PUT_BEFORE
) },
168 { "y", ACTION(OPERATOR_YANK
) },
169 { 0 /* empty last element, array terminator */ },
172 static const KeyBinding bindings_normal
[] = {
173 { "a", ACTION(APPEND_CHAR_NEXT
) },
174 { "A", ACTION(APPEND_LINE_END
) },
175 { "@", ACTION(MACRO_REPLAY
) },
176 { ":", ACTION(PROMPT_SHOW
) },
177 { ".", ACTION(REPEAT
) },
178 { "C", ALIAS("c$") },
179 { "<C-b>", ALIAS("<PageUp>") },
180 { "<C-c>", ACTION(SELECTIONS_REMOVE_COLUMN
) },
181 { "<C-d>", ACTION(SELECTIONS_NEXT
) },
182 { "<C-e>", ACTION(WINDOW_SLIDE_UP
) },
183 { "<C-f>", ALIAS("<PageDown>") },
184 { "<C-j>", ACTION(SELECTIONS_NEW_LINE_BELOW
) },
185 { "<C-k>", ACTION(SELECTIONS_NEW_LINE_ABOVE
) },
186 { "<C-l>", ACTION(SELECTIONS_REMOVE_COLUMN_EXCEPT
) },
187 { "<C-n>", ALIAS("viw") },
188 { "<C-p>", ACTION(SELECTIONS_REMOVE_LAST
) },
189 { "<C-r>", ACTION(REDO
) },
190 { "<C-u>", ACTION(SELECTIONS_PREV
) },
191 { "<C-w>c", ALIAS(":q<Enter>") },
192 { "<C-w>h", ALIAS("<C-w>k") },
193 { "<C-w>j", ACTION(WINDOW_NEXT
) },
194 { "<C-w>k", ACTION(WINDOW_PREV
) },
195 { "<C-w>l", ALIAS("<C-w>j") },
196 { "<C-w>n", ALIAS(":open<Enter>") },
197 { "<C-w>s", ALIAS(":split<Enter>") },
198 { "<C-w>v", ALIAS(":vsplit<Enter>") },
199 { "<C-y>", ACTION(WINDOW_SLIDE_DOWN
) },
200 { "D", ALIAS("d$") },
201 { "<Escape>", ACTION(MODE_NORMAL_ESCAPE
) },
202 { "<F1>", ALIAS(":help<Enter>") },
203 { "ga", ACTION(UNICODE_INFO
) },
204 { "g8", ACTION(UTF8_INFO
) },
205 { "g-", ACTION(EARLIER
) },
206 { "g+", ACTION(LATER
) },
207 { "gn", ALIAS("vgn") },
208 { "gN", ALIAS("vgN") },
209 { "gv", ALIAS("v'^M") },
210 { "I", ACTION(INSERT_LINE_START
) },
211 { "i", ACTION(MODE_INSERT
) },
212 { "J", ACTION(JOIN_LINES
) },
213 { "gJ", ACTION(JOIN_LINES_TRIM
) },
214 { "<M-C-j>", ACTION(SELECTIONS_NEW_LINE_BELOW_LAST
) },
215 { "<M-C-k>", ACTION(SELECTIONS_NEW_LINE_ABOVE_FIRST
) },
216 { "O", ACTION(OPEN_LINE_ABOVE
) },
217 { "o", ACTION(OPEN_LINE_BELOW
) },
218 { "q", ACTION(MACRO_RECORD
) },
219 { "R", ACTION(MODE_REPLACE
) },
220 { "r", ACTION(REPLACE_CHAR
) },
221 { "S", ALIAS("^c$") },
222 { "s", ALIAS("cl") },
223 { "<Tab>", ACTION(SELECTIONS_ALIGN
) },
224 { "u", ACTION(UNDO
) },
225 { "v", ACTION(MODE_VISUAL
) },
226 { "V", ACTION(MODE_VISUAL_LINE
) },
227 { "x", ACTION(DELETE_CHAR_NEXT
) },
228 { "X", ALIAS("dh") },
229 { "Y", ALIAS("y$") },
230 { "zb", ACTION(WINDOW_REDRAW_BOTTOM
) },
231 { "ZQ", ALIAS(":q!<Enter>") },
232 { "zt", ACTION(WINDOW_REDRAW_TOP
) },
233 { "zz", ACTION(WINDOW_REDRAW_CENTER
) },
234 { "ZZ", ALIAS(":wq<Enter>") },
235 { 0 /* empty last element, array terminator */ },
238 static const KeyBinding bindings_visual
[] = {
239 { "A", ACTION(SELECTIONS_NEW_LINES_END
) },
240 { "@", ACTION(MACRO_REPLAY
) },
241 { ":", ACTION(PROMPT_SHOW
) },
242 { "-", ACTION(SELECTIONS_ROTATE_LEFT
) },
243 { "+", ACTION(SELECTIONS_ROTATE_RIGHT
) },
244 { "<", ALIAS("<vis-operator-shift-left>gv") },
245 { ">", ALIAS("<vis-operator-shift-right>gv") },
246 { "<C-a>", ACTION(SELECTIONS_NEW_MATCH_ALL
) },
247 { "<C-b>", ALIAS("<PageUp>") },
248 { "<C-c>", ACTION(SELECTIONS_REMOVE_COLUMN
) },
249 { "<C-d>", ACTION(SELECTIONS_NEXT
) },
250 { "<C-f>", ALIAS("<PageDown>") },
251 { "<C-j>", ALIAS("<C-d>") },
252 { "<C-k>", ALIAS("<C-u>") },
253 { "<C-l>", ACTION(SELECTIONS_REMOVE_COLUMN_EXCEPT
) },
254 { "<C-n>", ACTION(SELECTIONS_NEW_MATCH_NEXT
) },
255 { "<C-p>", ACTION(SELECTIONS_REMOVE_LAST
) },
256 { "<C-u>", ACTION(SELECTIONS_PREV
) },
257 { "<C-x>", ACTION(SELECTIONS_NEW_MATCH_SKIP
) },
258 { "<Escape>", ACTION(MODE_VISUAL_ESCAPE
) },
259 { "I", ACTION(SELECTIONS_NEW_LINES_BEGIN
) },
260 { "J", ACTION(JOIN_LINES
) },
261 { "gJ", ACTION(JOIN_LINES_TRIM
) },
262 { "o", ACTION(SELECTION_FLIP
) },
263 { "q", ACTION(MACRO_RECORD
) },
264 { "r", ACTION(REPLACE_CHAR
) },
266 { "u", ALIAS("gu<Escape>") },
267 { "U", ALIAS("gU<Escape>") },
268 { "V", ACTION(MODE_VISUAL_LINE
) },
269 { "v", ALIAS("<Escape>") },
271 { 0 /* empty last element, array terminator */ },
274 static const KeyBinding bindings_visual_line
[] = {
275 { "v", ACTION(MODE_VISUAL
) },
276 { "V", ACTION(MODE_NORMAL
) },
277 { 0 /* empty last element, array terminator */ },
280 static const KeyBinding bindings_readline
[] = {
281 { "<Backspace>", ACTION(DELETE_CHAR_PREV
) },
282 { "<C-c>", ALIAS("<Escape>") },
283 { "<C-d>", ACTION(DELETE_CHAR_NEXT
) },
284 { "<C-h>", ALIAS("<Backspace>") },
285 { "<C-u>", ACTION(DELETE_LINE_BEGIN
) },
286 { "<C-v>", ACTION(INSERT_VERBATIM
) },
287 { "<C-w>", ACTION(DELETE_WORD_PREV
) },
288 { "<C-e>", ACTION(CURSOR_LINE_END
) },
289 { "<C-a>", ACTION(CURSOR_LINE_START
) },
290 { "<Delete>", ACTION(DELETE_CHAR_NEXT
) },
291 { "<Escape>", ACTION(MODE_NORMAL
) },
292 { 0 /* empty last element, array terminator */ },
295 static const KeyBinding bindings_insert
[] = {
296 { "<C-d>", ALIAS("<vis-operator-shift-left><vis-operator-shift-left>") },
297 { "<C-i>", ALIAS("<Tab>") },
298 { "<C-j>", ALIAS("<vis-insert-verbatim>u000a") },
299 { "<C-m>", ALIAS("<Enter>") },
300 { "<C-r>", ACTION(INSERT_REGISTER
) },
301 { "<C-t>", ALIAS("<vis-operator-shift-right><vis-operator-shift-right>") },
302 { "<C-x><C-e>", ACTION(WINDOW_SLIDE_UP
) },
303 { "<C-x><C-y>", ACTION(WINDOW_SLIDE_DOWN
) },
304 { "<Enter>", ACTION(INSERT_NEWLINE
) },
305 { "<Escape>", ACTION(MODE_NORMAL
) },
306 { "<S-Tab>", ACTION(SELECTIONS_ALIGN_INDENT_LEFT
) },
307 { "<Tab>", ACTION(INSERT_TAB
) },
308 { 0 /* empty last element, array terminator */ },
311 static const KeyBinding bindings_replace
[] = {
312 { 0 /* empty last element, array terminator */ },
315 /* For each mode we list a all key bindings, if a key is bound in more than
316 * one array the first definition is used and further ones are ignored. */
317 static const KeyBinding
**default_bindings
[] = {
318 [VIS_MODE_OPERATOR_PENDING
] = (const KeyBinding
*[]){
320 bindings_textobjects
,
325 [VIS_MODE_NORMAL
] = (const KeyBinding
*[]){
333 [VIS_MODE_VISUAL
] = (const KeyBinding
*[]){
336 bindings_textobjects
,
342 [VIS_MODE_VISUAL_LINE
] = (const KeyBinding
*[]){
343 bindings_visual_line
,
346 [VIS_MODE_INSERT
] = (const KeyBinding
*[]){
352 [VIS_MODE_REPLACE
] = (const KeyBinding
*[]){