119304Speter/*-
219304Speter * Copyright (c) 1992, 1993, 1994
319304Speter *	The Regents of the University of California.  All rights reserved.
419304Speter * Copyright (c) 1992, 1993, 1994, 1995, 1996
519304Speter *	Keith Bostic.  All rights reserved.
619304Speter *
719304Speter * See the LICENSE file for redistribution information.
819304Speter */
919304Speter
1019304Speter#include "config.h"
1119304Speter
1219304Speter#ifndef lint
13254225Speterstatic const char sccsid[] = "$Id: v_cmd.c,v 10.9 1996/03/28 15:18:39 bostic Exp $";
1419304Speter#endif /* not lint */
1519304Speter
1619304Speter#include <sys/types.h>
1719304Speter#include <sys/queue.h>
1819304Speter#include <sys/time.h>
1919304Speter
2019304Speter#include <bitstring.h>
2119304Speter#include <limits.h>
2219304Speter#include <stdio.h>
2319304Speter
2419304Speter#include "../common/common.h"
2519304Speter#include "vi.h"
2619304Speter
2719304Speter/*
2819304Speter * This array maps keystrokes to vi command functions.  It is known
2919304Speter * in ex/ex_usage.c that it takes four columns to name a vi character.
3019304Speter */
3119304SpeterVIKEYS const vikeys [MAXVIKEY + 1] = {
3219304Speter/* 000 NUL -- The code in vi.c expects key 0 to be undefined. */
3319304Speter	{NULL},
3419304Speter/* 001  ^A */
3519304Speter	{v_searchw,	V_ABS|V_CNT|V_MOVE|V_KEYW|VM_CUTREQ|VM_RCM_SET,
3619304Speter	    "[count]^A",
3719304Speter	    "^A search forward for cursor word"},
3819304Speter/* 002  ^B */
3919304Speter	{v_pageup,	V_CNT|VM_RCM_SET,
4019304Speter	    "[count]^B",
4119304Speter	    "^B scroll up by screens"},
4219304Speter/* 003  ^C */
4319304Speter	{NULL,		0,
4419304Speter	    "^C",
4519304Speter	    "^C interrupt an operation (e.g. read, write, search)"},
4619304Speter/* 004  ^D */
4719304Speter	{v_hpagedown,	V_CNT|VM_RCM_SET,
4819304Speter	    "[count]^D",
4919304Speter	    "^D scroll down by half screens (setting count)"},
5019304Speter/* 005  ^E */
5119304Speter	{v_linedown,	V_CNT,
5219304Speter	    "[count]^E",
5319304Speter	    "^E scroll down by lines"},
5419304Speter/* 006  ^F */
5519304Speter	{v_pagedown,	V_CNT|VM_RCM_SET,
5619304Speter	    "[count]^F",
5719304Speter	    "^F scroll down by screens"},
5819304Speter/* 007  ^G */
5919304Speter	{v_status,	0,
6019304Speter	    "^G",
6119304Speter	    "^G file status"},
6219304Speter/* 010  ^H */
6319304Speter	{v_left,	V_CNT|V_MOVE|VM_RCM_SET,
6419304Speter	    "[count]^H",
6519304Speter	    "^H move left by characters"},
6619304Speter/* 011  ^I */
6719304Speter	{NULL},
6819304Speter/* 012  ^J */
6919304Speter	{v_down,	V_CNT|V_MOVE|VM_LMODE|VM_RCM,
7019304Speter	    "[count]^J",
7119304Speter	    "^J move down by lines"},
7219304Speter/* 013  ^K */
7319304Speter	{NULL},
7419304Speter/* 014  ^L */
7519304Speter	{v_redraw,	0,
7619304Speter	    "^L",
7719304Speter	    "^L redraw screen"},
7819304Speter/* 015  ^M */
7919304Speter	{v_cr,		V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB,
8019304Speter	    "[count]^M",
8119304Speter	    "^M move down by lines (to first non-blank)"},
8219304Speter/* 016  ^N */
8319304Speter	{v_down,	V_CNT|V_MOVE|VM_LMODE|VM_RCM,
8419304Speter	    "[count]^N",
8519304Speter	    "^N move down by lines"},
8619304Speter/* 017  ^O */
8719304Speter	{NULL},
8819304Speter/* 020  ^P */
8919304Speter	{v_up,		V_CNT|V_MOVE|VM_LMODE|VM_RCM,
9019304Speter	    "[count]^P",
9119304Speter	    "^P move up by lines"},
9219304Speter/* 021  ^Q -- same as ^V if not used for hardware flow control. */
9319304Speter	{NULL},
9419304Speter/* 022  ^R */
9519304Speter	{v_redraw,	0,
9619304Speter	    "^R",
9719304Speter	    "^R redraw screen"},
9819304Speter/* 023  ^S -- not available, used for hardware flow control. */
9919304Speter	{NULL},
10019304Speter/* 024  ^T */
10119304Speter	{v_tagpop,	V_ABS|VM_RCM_SET,
10219304Speter	    "^T",
10319304Speter	    "^T tag pop"},
10419304Speter/* 025  ^U */
10519304Speter	{v_hpageup,	V_CNT|VM_RCM_SET,
10619304Speter	    "[count]^U",
10719304Speter	    "^U half page up (set count)"},
10819304Speter/* 026  ^V */
10919304Speter	{NULL,		0,
11019304Speter	    "^V",
11119304Speter	    "^V input a literal character"},
11219304Speter/* 027  ^W */
11319304Speter	{v_screen,	0,
11419304Speter	    "^W",
11519304Speter	    "^W move to next screen"},
11619304Speter/* 030  ^X */
11719304Speter	{NULL},
11819304Speter/* 031  ^Y */
11919304Speter	{v_lineup,	V_CNT,
12019304Speter	    "[count]^Y",
12119304Speter	    "^Y page up by lines"},
12219304Speter/* 032  ^Z */
12319304Speter	{v_suspend,	V_SECURE,
12419304Speter	    "^Z",
12519304Speter	    "^Z suspend editor"},
12619304Speter/* 033  ^[ */
12719304Speter	{NULL,		0,
12819304Speter	    "^[ <escape>",
12919304Speter	    "^[ <escape> exit input mode, cancel partial commands"},
13019304Speter/* 034  ^\ */
13119304Speter	{v_exmode,	0,
13219304Speter	    "^\\",
13319304Speter	    " ^\\ switch to ex mode"},
13419304Speter/* 035  ^] */
13519304Speter	{v_tagpush,	V_ABS|V_KEYW|VM_RCM_SET,
13619304Speter	    "^]",
13719304Speter	    "^] tag push cursor word"},
13819304Speter/* 036  ^^ */
13919304Speter	{v_switch,	0,
14019304Speter	    "^^",
14119304Speter	    "^^ switch to previous file"},
14219304Speter/* 037  ^_ */
14319304Speter	{NULL},
14419304Speter/* 040 ' ' */
14519304Speter	{v_right,	V_CNT|V_MOVE|VM_RCM_SET,
14619304Speter	    "[count]' '",
14719304Speter	    "   <space> move right by columns"},
14819304Speter/* 041   ! */
14919304Speter	{v_filter,	V_CNT|V_DOT|V_MOTION|V_SECURE|VM_RCM_SET,
15019304Speter	    "[count]![count]motion command(s)",
15119304Speter	    " ! filter through command(s) to motion"},
15219304Speter/* 042   " */
15319304Speter	{NULL},
15419304Speter/* 043   # */
15519304Speter	{v_increment,	V_CHAR|V_CNT|V_DOT|VM_RCM_SET,
15619304Speter	    "[count]# +|-|#",
15719304Speter	    " # number increment/decrement"},
15819304Speter/* 044   $ */
15919304Speter	{v_dollar,	V_CNT|V_MOVE|VM_RCM_SETLAST,
16019304Speter	    " [count]$",
16119304Speter	    " $ move to last column"},
16219304Speter/* 045   % */
16319304Speter	{v_match,	V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
16419304Speter	    "%",
16519304Speter	    " % move to match"},
16619304Speter/* 046   & */
16719304Speter	{v_again,	0,
16819304Speter	    "&",
16919304Speter	    " & repeat substitution"},
17019304Speter/* 047   ' */
17119304Speter	{v_fmark,	V_ABS_L|V_CHAR|V_MOVE|VM_LMODE|VM_RCM_SET,
17219304Speter	    "'['a-z]",
17319304Speter	    " ' move to mark (to first non-blank)"},
17419304Speter/* 050   ( */
17519304Speter	{v_sentenceb,	V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
17619304Speter	    "[count](",
17719304Speter	    " ( move back sentence"},
17819304Speter/* 051   ) */
17919304Speter	{v_sentencef,	V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
18019304Speter	    "[count])",
18119304Speter	    " ) move forward sentence"},
18219304Speter/* 052   * */
18319304Speter	{NULL},
18419304Speter/* 053   + */
18519304Speter	{v_down,	V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB,
18619304Speter	    "[count]+",
18719304Speter	    " + move down by lines (to first non-blank)"},
18819304Speter/* 054   , */
18919304Speter	{v_chrrepeat,	V_CNT|V_MOVE|VM_RCM_SET,
19019304Speter	    "[count],",
19119304Speter	    " , reverse last F, f, T or t search"},
19219304Speter/* 055   - */
19319304Speter	{v_up,		V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB,
19419304Speter	    "[count]-",
19519304Speter	    " - move up by lines (to first non-blank)"},
19619304Speter/* 056   . */
19719304Speter	{NULL,		0,
19819304Speter	    ".",
19919304Speter	    " . repeat the last command"},
20019304Speter/* 057   / */
20119304Speter	{v_searchf,	V_ABS_C|V_MOVE|VM_CUTREQ|VM_RCM_SET,
20219304Speter	    "/RE[/ offset]",
20319304Speter	    " / search forward"},
20419304Speter/* 060   0 */
20519304Speter	{v_zero,	V_MOVE|VM_RCM_SET,
20619304Speter	    "0",
20719304Speter	    " 0 move to first character"},
20819304Speter/* 061   1 */
20919304Speter	{NULL},
21019304Speter/* 062   2 */
21119304Speter	{NULL},
21219304Speter/* 063   3 */
21319304Speter	{NULL},
21419304Speter/* 064   4 */
21519304Speter	{NULL},
21619304Speter/* 065   5 */
21719304Speter	{NULL},
21819304Speter/* 066   6 */
21919304Speter	{NULL},
22019304Speter/* 067   7 */
22119304Speter	{NULL},
22219304Speter/* 070   8 */
22319304Speter	{NULL},
22419304Speter/* 071   9 */
22519304Speter	{NULL},
22619304Speter/* 072   : */
22719304Speter	{v_ex,		0,
22819304Speter	    ":command [| command] ...",
22919304Speter	    " : ex command"},
23019304Speter/* 073   ; */
23119304Speter	{v_chrepeat,	V_CNT|V_MOVE|VM_RCM_SET,
23219304Speter	    "[count];",
23319304Speter	    " ; repeat last F, f, T or t search"},
23419304Speter/* 074   < */
23519304Speter	{v_shiftl,	V_CNT|V_DOT|V_MOTION|VM_RCM_SET,
23619304Speter	    "[count]<[count]motion",
23719304Speter	    " < shift lines left to motion"},
23819304Speter/* 075   = */
23919304Speter	{NULL},
24019304Speter/* 076   > */
24119304Speter	{v_shiftr,	V_CNT|V_DOT|V_MOTION|VM_RCM_SET,
24219304Speter	    "[count]>[count]motion",
24319304Speter	    " > shift lines right to motion"},
24419304Speter/* 077   ? */
24519304Speter	{v_searchb,	V_ABS_C|V_MOVE|VM_CUTREQ|VM_RCM_SET,
24619304Speter	    "?RE[? offset]",
24719304Speter	    " ? search backward"},
24819304Speter/* 100   @ */
24919304Speter	{v_at,		V_CNT|V_RBUF|VM_RCM_SET,
25019304Speter	    "@buffer",
25119304Speter	    " @ execute buffer"},
25219304Speter/* 101   A */
25319304Speter	{v_iA,		V_CNT|V_DOT|VM_RCM_SET,
25419304Speter	    "[count]A",
25519304Speter	    " A append to the line"},
25619304Speter/* 102   B */
25719304Speter	{v_wordB,	V_CNT|V_MOVE|VM_RCM_SET,
25819304Speter	    "[count]B",
25919304Speter	    " B move back bigword"},
26019304Speter/* 103   C */
26119304Speter	{NULL,		0,
26219304Speter	    "[buffer][count]C",
26319304Speter	    " C change to end-of-line"},
26419304Speter/* 104   D */
26519304Speter	{NULL,		0,
26619304Speter	    "[buffer]D",
26719304Speter	    " D delete to end-of-line"},
26819304Speter/* 105   E */
26919304Speter	{v_wordE,	V_CNT|V_MOVE|VM_RCM_SET,
27019304Speter	    "[count]E",
27119304Speter	    " E move to end of bigword"},
27219304Speter/* 106   F */
27319304Speter	{v_chF,		V_CHAR|V_CNT|V_MOVE|VM_RCM_SET,
27419304Speter	    "[count]F character",
27519304Speter	    " F character in line backward search"},
27619304Speter/* 107   G */
27719304Speter	{v_lgoto,	V_ABS_L|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETFNB,
27819304Speter	    "[count]G",
27919304Speter	    " G move to line"},
28019304Speter/* 110   H */
28119304Speter	{v_home,	V_ABS_L|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB,
28219304Speter	    "[count]H",
28319304Speter	    " H move to count lines from screen top"},
28419304Speter/* 111   I */
28519304Speter	{v_iI,		V_CNT|V_DOT|VM_RCM_SET,
28619304Speter	    "[count]I",
28719304Speter	    " I insert before first nonblank"},
28819304Speter/* 112   J */
28919304Speter	{v_join,	V_CNT|V_DOT|VM_RCM_SET,
29019304Speter	    "[count]J",
29119304Speter	    " J join lines"},
29219304Speter/* 113   K */
29319304Speter	{NULL},
29419304Speter/* 114   L */
29519304Speter	{v_bottom,	V_ABS_L|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB,
29619304Speter	    "[count]L",
29719304Speter	    " L move to screen bottom"},
29819304Speter/* 115   M */
29919304Speter	{v_middle,	V_ABS_L|V_CNT|V_MOVE|VM_LMODE|VM_RCM_SETNNB,
30019304Speter	    "M",
30119304Speter	    " M move to screen middle"},
30219304Speter/* 116   N */
30319304Speter	{v_searchN,	V_ABS_C|V_MOVE|VM_CUTREQ|VM_RCM_SET,
30419304Speter	    "n",
30519304Speter	    " N reverse last search"},
30619304Speter/* 117   O */
30719304Speter	{v_iO,		V_CNT|V_DOT|VM_RCM_SET,
30819304Speter	    "[count]O",
30919304Speter	    " O insert above line"},
31019304Speter/* 120   P */
31119304Speter	{v_Put,		V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
31219304Speter	    "[buffer]P",
31319304Speter	    " P insert before cursor from buffer"},
31419304Speter/* 121   Q */
31519304Speter	{v_exmode,	0,
31619304Speter	    "Q",
31719304Speter	    " Q switch to ex mode"},
31819304Speter/* 122   R */
31919304Speter	{v_Replace,	V_CNT|V_DOT|VM_RCM_SET,
32019304Speter	    "[count]R",
32119304Speter	    " R replace characters"},
32219304Speter/* 123   S */
32319304Speter	{NULL,		0,
32419304Speter	    "[buffer][count]S",
32519304Speter	    " S substitute for the line(s)"},
32619304Speter/* 124   T */
32719304Speter	{v_chT,		V_CHAR|V_CNT|V_MOVE|VM_RCM_SET,
32819304Speter	    "[count]T character",
32919304Speter	    " T before character in line backward search"},
33019304Speter/* 125   U */
33119304Speter	{v_Undo,	VM_RCM_SET,
33219304Speter	    "U",
33319304Speter	    " U Restore the current line"},
33419304Speter/* 126   V */
33519304Speter	{NULL},
33619304Speter/* 127   W */
33719304Speter	{v_wordW,	V_CNT|V_MOVE|VM_RCM_SET,
33819304Speter	    "[count]W",
33919304Speter	    " W move to next bigword"},
34019304Speter/* 130   X */
34119304Speter	{v_Xchar,	V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
34219304Speter	    "[buffer][count]X",
34319304Speter	    " X delete character before cursor"},
34419304Speter/* 131   Y */
34519304Speter	{NULL,		0,
34619304Speter	    "[buffer][count]Y",
34719304Speter	    " Y copy line"},
34819304Speter/* 132   Z */
34919304Speter	{v_zexit,	0,
35019304Speter	    "ZZ",
35119304Speter	    "ZZ save file and exit"},
35219304Speter/* 133   [ */
35319304Speter	{v_sectionb,	V_ABS|V_CNT|V_MOVE|VM_RCM_SET,
35419304Speter	    "[[",
35519304Speter	    "[[ move back section"},
35619304Speter/* 134   \ */
35719304Speter	{NULL},
35819304Speter/* 135   ] */
35919304Speter	{v_sectionf,	V_ABS|V_CNT|V_MOVE|VM_RCM_SET,
36019304Speter	    "]]",
36119304Speter	    "]] move forward section"},
36219304Speter/* 136   ^ */
36319304Speter	/*
36419304Speter	 * DON'T set the VM_RCM_SETFNB flag, the function has to do the work
36519304Speter	 * anyway, in case it's a motion component.  DO set VM_RCM_SET, so
36619304Speter	 * that any motion that's part of a command is preserved.
36719304Speter	 */
36819304Speter	{v_first,	V_CNT|V_MOVE|VM_RCM_SET,
36919304Speter	    "^",
37019304Speter	    " ^ move to first non-blank"},
37119304Speter/* 137   _ */
37219304Speter	/*
37319304Speter	 * Needs both to set the VM_RCM_SETFNB flag, and to do the work
37419304Speter	 * in the function, in case it's a delete.
37519304Speter	 */
37619304Speter	{v_cfirst,	V_CNT|V_MOVE|VM_RCM_SETFNB,
37719304Speter	    "_",
37819304Speter	    " _ move to first non-blank"},
37919304Speter/* 140   ` */
38019304Speter	{v_bmark,	V_ABS_C|V_CHAR|V_MOVE|VM_CUTREQ|VM_RCM_SET,
38119304Speter	    "`[`a-z]",
38219304Speter	    " ` move to mark"},
38319304Speter/* 141   a */
38419304Speter	{v_ia,		V_CNT|V_DOT|VM_RCM_SET,
38519304Speter	    "[count]a",
38619304Speter	    " a append after cursor"},
38719304Speter/* 142   b */
38819304Speter	{v_wordb,	V_CNT|V_MOVE|VM_RCM_SET,
38919304Speter	    "[count]b",
39019304Speter	    " b move back word"},
39119304Speter/* 143   c */
39219304Speter	{v_change,	V_CNT|V_DOT|V_MOTION|V_OBUF|VM_RCM_SET,
39319304Speter	    "[buffer][count]c[count]motion",
39419304Speter	    " c change to motion"},
39519304Speter/* 144   d */
39619304Speter	{v_delete,	V_CNT|V_DOT|V_MOTION|V_OBUF|VM_RCM_SET,
39719304Speter	    "[buffer][count]d[count]motion",
39819304Speter	    " d delete to motion"},
39919304Speter/* 145   e */
40019304Speter	{v_worde,	V_CNT|V_MOVE|VM_RCM_SET,
40119304Speter	    "[count]e",
40219304Speter	    " e move to end of word"},
40319304Speter/* 146   f */
40419304Speter	{v_chf,		V_CHAR|V_CNT|V_MOVE|VM_RCM_SET,
40519304Speter	    "[count]f character",
40619304Speter	    " f character in line forward search"},
40719304Speter/* 147   g */
40819304Speter	{NULL},
40919304Speter/* 150   h */
41019304Speter	{v_left,	V_CNT|V_MOVE|VM_RCM_SET,
41119304Speter	    "[count]h",
41219304Speter	    " h move left by columns"},
41319304Speter/* 151   i */
41419304Speter	{v_ii,		V_CNT|V_DOT|VM_RCM_SET,
41519304Speter	    "[count]i",
41619304Speter	    " i insert before cursor"},
41719304Speter/* 152   j */
41819304Speter	{v_down,	V_CNT|V_MOVE|VM_LMODE|VM_RCM,
41919304Speter	    "[count]j",
42019304Speter	    " j move down by lines"},
42119304Speter/* 153   k */
42219304Speter	{v_up,		V_CNT|V_MOVE|VM_LMODE|VM_RCM,
42319304Speter	    "[count]k",
42419304Speter	    " k move up by lines"},
42519304Speter/* 154   l */
42619304Speter	{v_right,	V_CNT|V_MOVE|VM_RCM_SET,
42719304Speter	    "[count]l",
42819304Speter	    " l move right by columns"},
42919304Speter/* 155   m */
43019304Speter	{v_mark,	V_CHAR,
43119304Speter	    "m[a-z]",
43219304Speter	    " m set mark"},
43319304Speter/* 156   n */
43419304Speter	{v_searchn,	V_ABS_C|V_MOVE|VM_CUTREQ|VM_RCM_SET,
43519304Speter	    "n",
43619304Speter	    " n repeat last search"},
43719304Speter/* 157   o */
43819304Speter	{v_io,		V_CNT|V_DOT|VM_RCM_SET,
43919304Speter	    "[count]o",
44019304Speter	    " o append after line"},
44119304Speter/* 160   p */
44219304Speter	{v_put,		V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
44319304Speter	    "[buffer]p",
44419304Speter	    " p insert after cursor from buffer"},
44519304Speter/* 161   q */
44619304Speter	{NULL},
44719304Speter/* 162   r */
44819304Speter	{v_replace,	V_CNT|V_DOT|VM_RCM_SET,
44919304Speter	    "[count]r character",
45019304Speter	    " r replace character"},
45119304Speter/* 163   s */
45219304Speter	{v_subst,	V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
45319304Speter	    "[buffer][count]s",
45419304Speter	    " s substitute character"},
45519304Speter/* 164   t */
45619304Speter	{v_cht,		V_CHAR|V_CNT|V_MOVE|VM_RCM_SET,
45719304Speter	    "[count]t character",
45819304Speter	    " t before character in line forward search"},
45919304Speter/* 165   u */
46019304Speter	/*
46119304Speter	 * DON'T set the V_DOT flag, it' more complicated than that.
46219304Speter	 * See vi/vi.c for details.
46319304Speter	 */
46419304Speter	{v_undo,	VM_RCM_SET,
46519304Speter	    "u",
46619304Speter	    " u undo last change"},
46719304Speter/* 166   v */
46819304Speter	{NULL},
46919304Speter/* 167   w */
47019304Speter	{v_wordw,	V_CNT|V_MOVE|VM_RCM_SET,
47119304Speter	    "[count]w",
47219304Speter	    " w move to next word"},
47319304Speter/* 170   x */
47419304Speter	{v_xchar,	V_CNT|V_DOT|V_OBUF|VM_RCM_SET,
47519304Speter	    "[buffer][count]x",
47619304Speter	    " x delete character"},
47719304Speter/* 171   y */
47819304Speter	{v_yank,	V_CNT|V_DOT|V_MOTION|V_OBUF|VM_RCM_SET,
47919304Speter	    "[buffer][count]y[count]motion",
48019304Speter	    " y copy text to motion into a cut buffer"},
48119304Speter/* 172   z */
48219304Speter	/*
48319304Speter	 * DON'T set the V_CHAR flag, the char isn't required,
48419304Speter	 * so it's handled specially in getcmd().
48519304Speter	 */
48619304Speter	{v_z, 		V_ABS_L|V_CNT|VM_RCM_SETFNB,
48719304Speter	    "[line]z[window_size][-|.|+|^|<CR>]",
48819304Speter	    " z reposition the screen"},
48919304Speter/* 173   { */
49019304Speter	{v_paragraphb,	V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
49119304Speter	    "[count]{",
49219304Speter	    " { move back paragraph"},
49319304Speter/* 174   | */
49419304Speter	{v_ncol,	V_CNT|V_MOVE|VM_RCM_SET,
49519304Speter	    "[count]|",
49619304Speter	    " | move to column"},
49719304Speter/* 175   } */
49819304Speter	{v_paragraphf,	V_ABS|V_CNT|V_MOVE|VM_CUTREQ|VM_RCM_SET,
49919304Speter	    "[count]}",
50019304Speter	    " } move forward paragraph"},
50119304Speter/* 176   ~ */
50219304Speter	{v_ulcase,	V_CNT|V_DOT|VM_RCM_SET,
50319304Speter	    "[count]~",
50419304Speter	    " ~ reverse case"},
50519304Speter};
506