allow use of <End> key on AT-compatible keyboards (Ruslan Ermilov <ru@FreeBSD.org>)
[nvi.git] / vi / v_cmd.c
blob1de998fe084cb2c8dce02ea80fd9273184be6536
1 /*-
2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 static const char sccsid[] = "$Id: v_cmd.c,v 10.9 1996/03/28 15:18:39 bostic Exp $ (Berkeley) $Date: 1996/03/28 15:18:39 $";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
18 #include <sys/time.h>
20 #include <bitstring.h>
21 #include <limits.h>
22 #include <stdio.h>
24 #include "../common/common.h"
25 #include "vi.h"
28 * This array maps keystrokes to vi command functions. It is known
29 * in ex/ex_usage.c that it takes four columns to name a vi character.
31 VIKEYS const vikeys [MAXVIKEY + 1] = {
32 /* 000 NUL -- The code in vi.c expects key 0 to be undefined. */
33 {NULL},
34 /* 001 ^A */
35 {v_searchw, V_ABS|V_CNT|V_MOVE|V_KEYW|VM_CUTREQ|VM_RCM_SET,
36 "[count]^A",
37 "^A search forward for cursor word"},
38 /* 002 ^B */
39 {v_pageup, V_CNT|VM_RCM_SET,
40 "[count]^B",
41 "^B scroll up by screens"},
42 /* 003 ^C */
43 {NULL, 0,
44 "^C",
45 "^C interrupt an operation (e.g. read, write, search)"},
46 /* 004 ^D */
47 {v_hpagedown, V_CNT|VM_RCM_SET,
48 "[count]^D",
49 "^D scroll down by half screens (setting count)"},
50 /* 005 ^E */
51 {v_linedown, V_CNT,
52 "[count]^E",
53 "^E scroll down by lines"},
54 /* 006 ^F */
55 {v_pagedown, V_CNT|VM_RCM_SET,
56 "[count]^F",
57 "^F scroll down by screens"},
58 /* 007 ^G */
59 {v_status, 0,
60 "^G",
61 "^G file status"},
62 /* 010 ^H */
63 {v_left, V_CNT|V_MOVE|VM_RCM_SET,
64 "[count]^H",
65 "^H move left by characters"},
66 /* 011 ^I */
67 {NULL},
68 /* 012 ^J */
69 {v_down, V_CNT|V_MOVE|VM_LMODE|VM_RCM,
70 "[count]^J",
71 "^J move down by lines"},
72 /* 013 ^K */
73 {NULL},
74 /* 014 ^L */
75 {v_redraw, 0,
76 "^L",
77 "^L redraw screen"},
78 /* 015 ^M */
79 {v_cr, V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB,
80 "[count]^M",
81 "^M move down by lines (to first non-blank)"},
82 /* 016 ^N */
83 {v_down, V_CNT|V_MOVE|VM_LMODE|VM_RCM,
84 "[count]^N",
85 "^N move down by lines"},
86 /* 017 ^O */
87 {NULL},
88 /* 020 ^P */
89 {v_up, V_CNT|V_MOVE|VM_LMODE|VM_RCM,
90 "[count]^P",
91 "^P move up by lines"},
92 /* 021 ^Q -- same as ^V if not used for hardware flow control. */
93 {NULL},
94 /* 022 ^R */
95 {v_redraw, 0,
96 "^R",
97 "^R redraw screen"},
98 /* 023 ^S -- not available, used for hardware flow control. */
99 {NULL},
100 /* 024 ^T */
101 {v_tagpop, V_ABS|VM_RCM_SET,
102 "^T",
103 "^T tag pop"},
104 /* 025 ^U */
105 {v_hpageup, V_CNT|VM_RCM_SET,
106 "[count]^U",
107 "^U half page up (set count)"},
108 /* 026 ^V */
109 {NULL, 0,
110 "^V",
111 "^V input a literal character"},
112 /* 027 ^W */
113 {v_screen, 0,
114 "^W",
115 "^W move to next screen"},
116 /* 030 ^X */
117 {NULL},
118 /* 031 ^Y */
119 {v_lineup, V_CNT,
120 "[count]^Y",
121 "^Y page up by lines"},
122 /* 032 ^Z */
123 {v_suspend, V_SECURE,
124 "^Z",
125 "^Z suspend editor"},
126 /* 033 ^[ */
127 {NULL, 0,
128 "^[ <escape>",
129 "^[ <escape> exit input mode, cancel partial commands"},
130 /* 034 ^\ */
131 {v_exmode, 0,
132 "^\\",
133 " ^\\ switch to ex mode"},
134 /* 035 ^] */
135 {v_tagpush, V_ABS|V_KEYW|VM_RCM_SET,
136 "^]",
137 "^] tag push cursor word"},
138 /* 036 ^^ */
139 {v_switch, 0,
140 "^^",
141 "^^ switch to previous file"},
142 /* 037 ^_ */
143 {NULL},
144 /* 040 ' ' */
145 {v_right, V_CNT|V_MOVE|VM_RCM_SET,
146 "[count]' '",
147 " <space> move right by columns"},
148 /* 041 ! */
149 {v_filter, V_CNT|V_DOT|V_MOTION|V_SECURE|VM_RCM_SET,
150 "[count]![count]motion command(s)",
151 " ! filter through command(s) to motion"},
152 /* 042 " */
153 {NULL},
154 /* 043 # */
155 {v_increment, V_CHAR|V_CNT|V_DOT|VM_RCM_SET,
156 "[count]# +|-|#",
157 " # number increment/decrement"},
158 /* 044 $ */
159 {v_dollar, V_CNT|V_MOVE|VM_RCM_SETLAST,
160 " [count]$",
161 " $ move to last column"},
162 /* 045 % */
163 {v_match, V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
164 "%",
165 " % move to match"},
166 /* 046 & */
167 {v_again, 0,
168 "&",
169 " & repeat substitution"},
170 /* 047 ' */
171 {v_fmark, V_ABS_L|V_CHAR|V_MOVE|VM_LMODE|VM_RCM_SET,
172 "'['a-z]",
173 " ' move to mark (to first non-blank)"},
174 /* 050 ( */
175 {v_sentenceb, V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
176 "[count](",
177 " ( move back sentence"},
178 /* 051 ) */
179 {v_sentencef, V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
180 "[count])",
181 " ) move forward sentence"},
182 /* 052 * */
183 {NULL},
184 /* 053 + */
185 {v_down, V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB,
186 "[count]+",
187 " + move down by lines (to first non-blank)"},
188 /* 054 , */
189 {v_chrrepeat, V_CNT|V_MOVE|VM_RCM_SET,
190 "[count],",
191 " , reverse last F, f, T or t search"},
192 /* 055 - */
193 {v_up, V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB,
194 "[count]-",
195 " - move up by lines (to first non-blank)"},
196 /* 056 . */
197 {NULL, 0,
198 ".",
199 " . repeat the last command"},
200 /* 057 / */
201 {v_searchf, V_ABS_C|V_MOVE|VM_CUTREQ|VM_RCM_SET,
202 "/RE[/ offset]",
203 " / search forward"},
204 /* 060 0 */
205 {v_zero, V_MOVE|VM_RCM_SET,
206 "0",
207 " 0 move to first character"},
208 /* 061 1 */
209 {NULL},
210 /* 062 2 */
211 {NULL},
212 /* 063 3 */
213 {NULL},
214 /* 064 4 */
215 {NULL},
216 /* 065 5 */
217 {NULL},
218 /* 066 6 */
219 {NULL},
220 /* 067 7 */
221 {NULL},
222 /* 070 8 */
223 {NULL},
224 /* 071 9 */
225 {NULL},
226 /* 072 : */
227 {v_ex, 0,
228 ":command [| command] ...",
229 " : ex command"},
230 /* 073 ; */
231 {v_chrepeat, V_CNT|V_MOVE|VM_RCM_SET,
232 "[count];",
233 " ; repeat last F, f, T or t search"},
234 /* 074 < */
235 {v_shiftl, V_CNT|V_DOT|V_MOTION|VM_RCM_SET,
236 "[count]<[count]motion",
237 " < shift lines left to motion"},
238 /* 075 = */
239 {NULL},
240 /* 076 > */
241 {v_shiftr, V_CNT|V_DOT|V_MOTION|VM_RCM_SET,
242 "[count]>[count]motion",
243 " > shift lines right to motion"},
244 /* 077 ? */
245 {v_searchb, V_ABS_C|V_MOVE|VM_CUTREQ|VM_RCM_SET,
246 "?RE[? offset]",
247 " ? search backward"},
248 /* 100 @ */
249 {v_at, V_CNT|V_RBUF|VM_RCM_SET,
250 "@buffer",
251 " @ execute buffer"},
252 /* 101 A */
253 {v_iA, V_CNT|V_DOT|VM_RCM_SET,
254 "[count]A",
255 " A append to the line"},
256 /* 102 B */
257 {v_wordB, V_CNT|V_MOVE|VM_RCM_SET,
258 "[count]B",
259 " B move back bigword"},
260 /* 103 C */
261 {NULL, 0,
262 "[buffer][count]C",
263 " C change to end-of-line"},
264 /* 104 D */
265 {NULL, 0,
266 "[buffer]D",
267 " D delete to end-of-line"},
268 /* 105 E */
269 {v_wordE, V_CNT|V_MOVE|VM_RCM_SET,
270 "[count]E",
271 " E move to end of bigword"},
272 /* 106 F */
273 {v_chF, V_CHAR|V_CNT|V_MOVE|VM_RCM_SET,
274 "[count]F character",
275 " F character in line backward search"},
276 /* 107 G */
277 {v_lgoto, V_ABS_L|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB,
278 "[count]G",
279 " G move to line"},
280 /* 110 H */
281 {v_home, V_ABS_L|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB,
282 "[count]H",
283 " H move to count lines from screen top"},
284 /* 111 I */
285 {v_iI, V_CNT|V_DOT|VM_RCM_SET,
286 "[count]I",
287 " I insert before first nonblank"},
288 /* 112 J */
289 {v_join, V_CNT|V_DOT|VM_RCM_SET,
290 "[count]J",
291 " J join lines"},
292 /* 113 K */
293 {NULL},
294 /* 114 L */
295 {v_bottom, V_ABS_L|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB,
296 "[count]L",
297 " L move to screen bottom"},
298 /* 115 M */
299 {v_middle, V_ABS_L|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB,
300 "M",
301 " M move to screen middle"},
302 /* 116 N */
303 {v_searchN, V_ABS_C|V_MOVE|VM_CUTREQ|VM_RCM_SET,
304 "n",
305 " N reverse last search"},
306 /* 117 O */
307 {v_iO, V_CNT|V_DOT|VM_RCM_SET,
308 "[count]O",
309 " O insert above line"},
310 /* 120 P */
311 {v_Put, V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
312 "[buffer]P",
313 " P insert before cursor from buffer"},
314 /* 121 Q */
315 {v_exmode, 0,
316 "Q",
317 " Q switch to ex mode"},
318 /* 122 R */
319 {v_Replace, V_CNT|V_DOT|VM_RCM_SET,
320 "[count]R",
321 " R replace characters"},
322 /* 123 S */
323 {NULL, 0,
324 "[buffer][count]S",
325 " S substitute for the line(s)"},
326 /* 124 T */
327 {v_chT, V_CHAR|V_CNT|V_MOVE|VM_RCM_SET,
328 "[count]T character",
329 " T before character in line backward search"},
330 /* 125 U */
331 {v_Undo, VM_RCM_SET,
332 "U",
333 " U Restore the current line"},
334 /* 126 V */
335 {NULL},
336 /* 127 W */
337 {v_wordW, V_CNT|V_MOVE|VM_RCM_SET,
338 "[count]W",
339 " W move to next bigword"},
340 /* 130 X */
341 {v_Xchar, V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
342 "[buffer][count]X",
343 " X delete character before cursor"},
344 /* 131 Y */
345 {NULL, 0,
346 "[buffer][count]Y",
347 " Y copy line"},
348 /* 132 Z */
349 {v_zexit, 0,
350 "ZZ",
351 "ZZ save file and exit"},
352 /* 133 [ */
353 {v_sectionb, V_ABS|V_CNT|V_MOVE|VM_RCM_SET,
354 "[[",
355 "[[ move back section"},
356 /* 134 \ */
357 {NULL},
358 /* 135 ] */
359 {v_sectionf, V_ABS|V_CNT|V_MOVE|VM_RCM_SET,
360 "]]",
361 "]] move forward section"},
362 /* 136 ^ */
364 * DON'T set the VM_RCM_SETFNB flag, the function has to do the work
365 * anyway, in case it's a motion component. DO set VM_RCM_SET, so
366 * that any motion that's part of a command is preserved.
368 {v_first, V_CNT|V_MOVE|VM_RCM_SET,
369 "^",
370 " ^ move to first non-blank"},
371 /* 137 _ */
373 * Needs both to set the VM_RCM_SETFNB flag, and to do the work
374 * in the function, in case it's a delete.
376 {v_cfirst, V_CNT|V_MOVE|VM_RCM_SETFNB,
377 "_",
378 " _ move to first non-blank"},
379 /* 140 ` */
380 {v_bmark, V_ABS_C|V_CHAR|V_MOVE|VM_CUTREQ|VM_RCM_SET,
381 "`[`a-z]",
382 " ` move to mark"},
383 /* 141 a */
384 {v_ia, V_CNT|V_DOT|VM_RCM_SET,
385 "[count]a",
386 " a append after cursor"},
387 /* 142 b */
388 {v_wordb, V_CNT|V_MOVE|VM_RCM_SET,
389 "[count]b",
390 " b move back word"},
391 /* 143 c */
392 {v_change, V_CNT|V_DOT|V_MOTION|V_OBUF|VM_RCM_SET,
393 "[buffer][count]c[count]motion",
394 " c change to motion"},
395 /* 144 d */
396 {v_delete, V_CNT|V_DOT|V_MOTION|V_OBUF|VM_RCM_SET,
397 "[buffer][count]d[count]motion",
398 " d delete to motion"},
399 /* 145 e */
400 {v_worde, V_CNT|V_MOVE|VM_RCM_SET,
401 "[count]e",
402 " e move to end of word"},
403 /* 146 f */
404 {v_chf, V_CHAR|V_CNT|V_MOVE|VM_RCM_SET,
405 "[count]f character",
406 " f character in line forward search"},
407 /* 147 g */
408 {NULL},
409 /* 150 h */
410 {v_left, V_CNT|V_MOVE|VM_RCM_SET,
411 "[count]h",
412 " h move left by columns"},
413 /* 151 i */
414 {v_ii, V_CNT|V_DOT|VM_RCM_SET,
415 "[count]i",
416 " i insert before cursor"},
417 /* 152 j */
418 {v_down, V_CNT|V_MOVE|VM_LMODE|VM_RCM,
419 "[count]j",
420 " j move down by lines"},
421 /* 153 k */
422 {v_up, V_CNT|V_MOVE|VM_LMODE|VM_RCM,
423 "[count]k",
424 " k move up by lines"},
425 /* 154 l */
426 {v_right, V_CNT|V_MOVE|VM_RCM_SET,
427 "[count]l",
428 " l move right by columns"},
429 /* 155 m */
430 {v_mark, V_CHAR,
431 "m[a-z]",
432 " m set mark"},
433 /* 156 n */
434 {v_searchn, V_ABS_C|V_MOVE|VM_CUTREQ|VM_RCM_SET,
435 "n",
436 " n repeat last search"},
437 /* 157 o */
438 {v_io, V_CNT|V_DOT|VM_RCM_SET,
439 "[count]o",
440 " o append after line"},
441 /* 160 p */
442 {v_put, V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
443 "[buffer]p",
444 " p insert after cursor from buffer"},
445 /* 161 q */
446 {NULL},
447 /* 162 r */
448 {v_replace, V_CNT|V_DOT|VM_RCM_SET,
449 "[count]r character",
450 " r replace character"},
451 /* 163 s */
452 {v_subst, V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
453 "[buffer][count]s",
454 " s substitute character"},
455 /* 164 t */
456 {v_cht, V_CHAR|V_CNT|V_MOVE|VM_RCM_SET,
457 "[count]t character",
458 " t before character in line forward search"},
459 /* 165 u */
461 * DON'T set the V_DOT flag, it' more complicated than that.
462 * See vi/vi.c for details.
464 {v_undo, VM_RCM_SET,
465 "u",
466 " u undo last change"},
467 /* 166 v */
468 {NULL},
469 /* 167 w */
470 {v_wordw, V_CNT|V_MOVE|VM_RCM_SET,
471 "[count]w",
472 " w move to next word"},
473 /* 170 x */
474 {v_xchar, V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
475 "[buffer][count]x",
476 " x delete character"},
477 /* 171 y */
478 {v_yank, V_CNT|V_DOT|V_MOTION|V_OBUF|VM_RCM_SET,
479 "[buffer][count]y[count]motion",
480 " y copy text to motion into a cut buffer"},
481 /* 172 z */
483 * DON'T set the V_CHAR flag, the char isn't required,
484 * so it's handled specially in getcmd().
486 {v_z, V_ABS_L|V_CNT|VM_RCM_SETFNB,
487 "[line]z[window_size][-|.|+|^|<CR>]",
488 " z reposition the screen"},
489 /* 173 { */
490 {v_paragraphb, V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
491 "[count]{",
492 " { move back paragraph"},
493 /* 174 | */
494 {v_ncol, V_CNT|V_MOVE|VM_RCM_SET,
495 "[count]|",
496 " | move to column"},
497 /* 175 } */
498 {v_paragraphf, V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
499 "[count]}",
500 " } move forward paragraph"},
501 /* 176 ~ */
502 {v_ulcase, V_CNT|V_DOT|VM_RCM_SET,
503 "[count]~",
504 " ~ reverse case"},