]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/nvi/ex/ex_cmd.c
Update nvi to 2.2.0
[FreeBSD/FreeBSD.git] / contrib / nvi / ex / ex_cmd.c
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.
6  *
7  * See the LICENSE file for redistribution information.
8  */
9
10 #include "config.h"
11
12 #include <sys/types.h>
13 #include <sys/queue.h>
14 #include <sys/time.h>
15
16 #include <bitstring.h>
17 #include <limits.h>
18 #include <stdio.h>
19
20 #include "../common/common.h"
21
22 /*
23  * This array maps ex command names to command functions.
24  *
25  * The order in which command names are listed below is important --
26  * ambiguous abbreviations are resolved to be the first possible match,
27  * e.g. "r" means "read", not "rewind", because "read" is listed before
28  * "rewind".
29  *
30  * The syntax of the ex commands is unbelievably irregular, and a special
31  * case from beginning to end.  Each command has an associated "syntax
32  * script" which describes the "arguments" that are possible.  The script
33  * syntax is as follows:
34  *
35  *      !               -- ! flag
36  *      1               -- flags: [+-]*[pl#][+-]*
37  *      2               -- flags: [-.+^]
38  *      3               -- flags: [-.+^=]
39  *      b               -- buffer
40  *      c[01+a]         -- count (0-N, 1-N, signed 1-N, address offset)
41  *      f[N#][or]       -- file (a number or N, optional or required)
42  *      l               -- line
43  *      S               -- string with file name expansion
44  *      s               -- string
45  *      W               -- word string
46  *      w[N#][or]       -- word (a number or N, optional or required)
47  */
48 EXCMDLIST const cmds[] = {
49 /* C_SCROLL */
50         {L("\004"),     ex_pr,          E_ADDR2,
51             "",
52             "^D",
53             "scroll lines"},
54 /* C_BANG */
55         {L("!"),                ex_bang,        E_ADDR2_NONE|E_SECURE,
56             "S",
57             "[line [,line]] ! command",
58             "filter lines through commands or run commands"},
59 /* C_HASH */
60         {L("#"),                ex_number,      E_ADDR2|E_CLRFLAG,
61             "ca1",
62             "[line [,line]] # [count] [l]",
63             "display numbered lines"},
64 /* C_SUBAGAIN */
65         {L("&"),                ex_subagain,    E_ADDR2|E_ADDR_ZERO,
66             "s",
67             "[line [,line]] & [cgr] [count] [#lp]",
68             "repeat the last subsitution"},
69 /* C_STAR */
70         {L("*"),                ex_at,          0,
71             "b",
72             "* [buffer]",
73             "execute a buffer"},
74 /* C_SHIFTL */
75         {L("<"),                ex_shiftl,      E_ADDR2|E_AUTOPRINT,
76             "ca1",
77             "[line [,line]] <[<...] [count] [flags]",
78             "shift lines left"},
79 /* C_EQUAL */
80         {L("="),                ex_equal,       E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF,
81             "1",
82             "[line] = [flags]",
83             "display line number"},
84 /* C_SHIFTR */
85         {L(">"),                ex_shiftr,      E_ADDR2|E_AUTOPRINT,
86             "ca1",
87             "[line [,line]] >[>...] [count] [flags]",
88             "shift lines right"},
89 /* C_AT */
90         {L("@"),                ex_at,          E_ADDR2,
91             "b",
92             "@ [buffer]",
93             "execute a buffer"},
94 /* C_APPEND */
95         {L("append"),   ex_append,      E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF,
96             "!",
97             "[line] a[ppend][!]",
98             "append input to a line"},
99 /* C_ABBR */
100         {L("abbreviate"),       ex_abbr,        0,
101             "W",
102             "ab[brev] [word replace]",
103             "specify an input abbreviation"},
104 /* C_ARGS */
105         {L("args"),     ex_args,        0,
106             "",
107             "ar[gs]",
108             "display file argument list"},
109 /* C_BG */
110         {L("bg"),               ex_bg,          E_VIONLY,
111             "",
112             "bg",
113             "put a foreground screen into the background"},
114 /* C_CHANGE */
115         {L("change"),   ex_change,      E_ADDR2|E_ADDR_ZERODEF,
116             "!ca",
117             "[line [,line]] c[hange][!] [count]",
118             "change lines to input"},
119 /* C_CD */
120         {L("cd"),               ex_cd,          0,
121             "!f1o",
122             "cd[!] [directory]",
123             "change the current directory"},
124 /* C_CHDIR */
125         {L("chdir"),    ex_cd,          0,
126             "!f1o",
127             "chd[ir][!] [directory]",
128             "change the current directory"},
129 /* C_COPY */
130         {L("copy"),     ex_copy,        E_ADDR2|E_AUTOPRINT,
131             "l1",
132             "[line [,line]] co[py] line [flags]",
133             "copy lines elsewhere in the file"},
134 /* C_CSCOPE */
135         {L("cscope"),      ex_cscope,      0,
136             "!s",
137             "cs[cope] command [args]",
138             "create a set of tags using a cscope command"},
139 /*
140  * !!!
141  * Adding new commands starting with 'd' may break the delete command code
142  * in ex_cmd() (the ex parser).  Read through the comments there, first.
143  */
144 /* C_DELETE */
145         {L("delete"),   ex_delete,      E_ADDR2|E_AUTOPRINT,
146             "bca1",
147             "[line [,line]] d[elete][flags] [buffer] [count] [flags]",
148             "delete lines from the file"},
149 /* C_DISPLAY */
150         {L("display"),  ex_display,     0,
151             "w1r",
152             "display b[uffers] | c[onnections] | s[creens] | t[ags]",
153             "display buffers, connections, screens or tags"},
154 /* C_EDIT */
155         {L("edit"),     ex_edit,        E_NEWSCREEN,
156             "f1o",
157             "[Ee][dit][!] [+cmd] [file]",
158             "begin editing another file"},
159 /* C_EX */
160         {L("ex"),               ex_edit,        E_NEWSCREEN,
161             "f1o",
162             "[Ee]x[!] [+cmd] [file]",
163             "begin editing another file"},
164 /* C_EXUSAGE */
165         {L("exusage"),  ex_usage,       0,
166             "w1o",
167             "[exu]sage [command]",
168             "display ex command usage statement"},
169 /* C_FILE */
170         {L("file"),     ex_file,        0,
171             "f1o",
172             "f[ile] [name]",
173             "display (and optionally set) file name"},
174 /* C_FG */
175         {L("fg"),               ex_fg,          E_NEWSCREEN|E_VIONLY,
176             "f1o",
177             "[Ff]g [file]",
178             "bring a backgrounded screen into the foreground"},
179 /* C_GLOBAL */
180         {L("global"),   ex_global,      E_ADDR2_ALL,
181             "!s",
182             "[line [,line]] g[lobal][!] [;/]RE[;/] [commands]",
183             "execute a global command on lines matching an RE"},
184 /* C_HELP */
185         {L("help"),     ex_help,        0,
186             "",
187             "he[lp]",
188             "display help statement"},
189 /* C_INSERT */
190         {L("insert"),   ex_insert,      E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF,
191             "!",
192             "[line] i[nsert][!]",
193             "insert input before a line"},
194 /* C_JOIN */
195         {L("join"),     ex_join,        E_ADDR2|E_AUTOPRINT,
196             "!ca1",
197             "[line [,line]] j[oin][!] [count] [flags]",
198             "join lines into a single line"},
199 /* C_K */
200         {L("k"),                ex_mark,        E_ADDR1,
201             "w1r",
202             "[line] k key",
203             "mark a line position"},
204 /* C_LIST */
205         {L("list"),     ex_list,        E_ADDR2|E_CLRFLAG,
206             "ca1",
207             "[line [,line]] l[ist] [count] [#]",
208             "display lines in an unambiguous form"},
209 /* C_MOVE */
210         {L("move"),     ex_move,        E_ADDR2|E_AUTOPRINT,
211             "l",
212             "[line [,line]] m[ove] line",
213             "move lines elsewhere in the file"},
214 /* C_MARK */
215         {L("mark"),     ex_mark,        E_ADDR1,
216             "w1r",
217             "[line] ma[rk] key",
218             "mark a line position"},
219 /* C_MAP */
220         {L("map"),              ex_map,         0,
221             "!W",
222             "map[!] [keys replace]",
223             "map input or commands to one or more keys"},
224 /* C_MKEXRC */
225         {L("mkexrc"),   ex_mkexrc,      0,
226             "!f1r",
227             "mkexrc[!] file",
228             "write a .exrc file"},
229 /* C_NEXT */
230         {L("next"),     ex_next,        E_NEWSCREEN,
231             "!fN",
232             "[Nn][ext][!] [+cmd] [file ...]",
233             "edit (and optionally specify) the next file"},
234 /* C_NUMBER */
235         {L("number"),   ex_number,      E_ADDR2|E_CLRFLAG,
236             "ca1",
237             "[line [,line]] nu[mber] [count] [l]",
238             "change display to number lines"},
239 /* C_OPEN */
240         {L("open"),     ex_open,        E_ADDR1,
241             "s",
242             "[line] o[pen] [/RE/] [flags]",
243             "enter \"open\" mode (not implemented)"},
244 /* C_PRINT */
245         {L("print"),    ex_pr,          E_ADDR2|E_CLRFLAG,
246             "ca1",
247             "[line [,line]] p[rint] [count] [#l]",
248             "display lines"},
249 /* C_PRESERVE */
250         {L("preserve"), ex_preserve,    0,
251             "",
252             "pre[serve]",
253             "preserve an edit session for recovery"},
254 /* C_PREVIOUS */
255         {L("previous"), ex_prev,        E_NEWSCREEN,
256             "!",
257             "[Pp]rev[ious][!]",
258             "edit the previous file in the file argument list"},
259 /* C_PUT */
260         {L("put"),              ex_put, 
261             E_ADDR1|E_AUTOPRINT|E_ADDR_ZERO|E_ADDR_ZERODEF,
262             "b",
263             "[line] pu[t] [buffer]",
264             "append a cut buffer to the line"},
265 /* C_QUIT */
266         {L("quit"),     ex_quit,        0,
267             "!",
268             "q[uit][!]",
269             "exit ex/vi"},
270 /* C_READ */
271         {L("read"),     ex_read,        E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF,
272             "s",
273             "[line] r[ead] [!cmd | [file]]",
274             "append input from a command or file to the line"},
275 /* C_RECOVER */
276         {L("recover"),  ex_recover,     0,
277             "!f1r",
278             "recover[!] file",
279             "recover a saved file"},
280 /* C_RESIZE */
281         {L("resize"),   ex_resize,      E_VIONLY,
282             "c+",
283             "resize [+-]rows",
284             "grow or shrink the current screen"},
285 /* C_REWIND */
286         {L("rewind"),   ex_rew,         0,
287             "!",
288             "rew[ind][!]",
289             "re-edit all the files in the file argument list"},
290 /*
291  * !!!
292  * Adding new commands starting with 's' may break the substitute command code
293  * in ex_cmd() (the ex parser).  Read through the comments there, first.
294  */
295 /* C_SUBSTITUTE */
296         {L("s"),                ex_s,           E_ADDR2|E_ADDR_ZERO,
297             "s",
298             "[line [,line]] s [[/;]RE[/;]repl[/;] [cgr] [count] [#lp]]",
299             "substitute on lines matching an RE"},
300 /* C_SCRIPT */
301         {L("script"),   ex_script,      E_SECURE,
302             "!f1o",
303             "sc[ript][!] [file]",
304             "run a shell in a screen"},
305 /* C_SET */
306         {L("set"),              ex_set,         0,
307             "wN",
308             "se[t] [option[=[value]]...] [nooption ...] [option? ...] [all]",
309             "set options (use \":set all\" to see all options)"},
310 /* C_SHELL */
311         {L("shell"),    ex_shell,       E_SECURE,
312             "",
313             "sh[ell]",
314             "suspend editing and run a shell"},
315 /* C_SOURCE */
316         {L("source"),   ex_source,      0,
317             "f1r",
318             "so[urce] file",
319             "read a file of ex commands"},
320 /* C_STOP */
321         {L("stop"),     ex_stop,        E_SECURE,
322             "!",
323             "st[op][!]",
324             "suspend the edit session"},
325 /* C_SUSPEND */
326         {L("suspend"),  ex_stop,        E_SECURE,
327             "!",
328             "su[spend][!]",
329             "suspend the edit session"},
330 /* C_T */
331         {L("t"),                ex_copy,        E_ADDR2|E_AUTOPRINT,
332             "l1",
333             "[line [,line]] t line [flags]",
334             "copy lines elsewhere in the file"},
335 /* C_TAG */
336         {L("tag"),              ex_tag_push,    E_NEWSCREEN,
337             "!w1o",
338             "[Tt]a[g][!] [string]",
339             "edit the file containing the tag"},
340 /* C_TAGNEXT */
341         {L("tagnext"),  ex_tag_next,    0,
342             "!",
343             "tagn[ext][!]",
344             "move to the next tag"},
345 /* C_TAGPOP */
346         {L("tagpop"),   ex_tag_pop,     0,
347             "!w1o",
348             "tagp[op][!] [number | file]",
349             "return to the previous group of tags"},
350 /* C_TAGPREV */
351         {L("tagprev"),  ex_tag_prev,    0,
352             "!",
353             "tagpr[ev][!]",
354             "move to the previous tag"},
355 /* C_TAGTOP */
356         {L("tagtop"),   ex_tag_top,     0,
357             "!",
358             "tagt[op][!]",
359             "discard all tags"},
360 /* C_UNDO */
361         {L("undo"),     ex_undo,        E_AUTOPRINT,
362             "",
363             "u[ndo]",
364             "undo the most recent change"},
365 /* C_UNABBREVIATE */
366         {L("unabbreviate"),ex_unabbr,   0,
367             "w1r",
368             "una[bbrev] word",
369             "delete an abbreviation"},
370 /* C_UNMAP */
371         {L("unmap"),    ex_unmap,       0,
372             "!w1r",
373             "unm[ap][!] word",
374             "delete an input or command map"},
375 /* C_V */
376         {L("v"),                ex_v,           E_ADDR2_ALL,
377             "s",
378             "[line [,line]] v [;/]RE[;/] [commands]",
379             "execute a global command on lines NOT matching an RE"},
380 /* C_VERSION */
381         {L("version"),  ex_version,     0,
382             "",
383             "version",
384             "display the program version information"},
385 /* C_VISUAL_EX */
386         {L("visual"),   ex_visual,      E_ADDR1|E_ADDR_ZERODEF,
387             "2c11",
388             "[line] vi[sual] [-|.|+|^] [window_size] [flags]",
389             "enter visual (vi) mode from ex mode"},
390 /* C_VISUAL_VI */
391         {L("visual"),   ex_edit,        E_NEWSCREEN,
392             "f1o",
393             "[Vv]i[sual][!] [+cmd] [file]",
394             "edit another file (from vi mode only)"},
395 /* C_VIUSAGE */
396         {L("viusage"),  ex_viusage,     0,
397             "w1o",
398             "[viu]sage [key]",
399             "display vi key usage statement"},
400 /* C_VSPLIT */
401         {L("vsplit"),   ex_edit,        E_VIONLY,
402             "f1o",
403             "vs[plit] [+cmd] [file]",
404             "split the current screen vertically"},
405 /* C_WRITE */
406         {L("write"),    ex_write,       E_ADDR2_ALL|E_ADDR_ZERODEF,
407             "!s",
408             "[line [,line]] w[rite][!] [ !cmd | [>>] [file]]",
409             "write the file"},
410 /* C_WN */
411         {L("wn"),               ex_wn,          E_ADDR2_ALL|E_ADDR_ZERODEF,
412             "!s",
413             "[line [,line]] wn[!] [>>] [file]",
414             "write the file and switch to the next file"},
415 /* C_WQ */
416         {L("wq"),               ex_wq,          E_ADDR2_ALL|E_ADDR_ZERODEF,
417             "!s",
418             "[line [,line]] wq[!] [>>] [file]",
419             "write the file and exit"},
420 /* C_XIT */
421         {L("xit"),              ex_xit,         E_ADDR2_ALL|E_ADDR_ZERODEF,
422             "!f1o",
423             "[line [,line]] x[it][!] [file]",
424             "exit"},
425 /* C_YANK */
426         {L("yank"),     ex_yank,        E_ADDR2,
427             "bca",
428             "[line [,line]] ya[nk] [buffer] [count]",
429             "copy lines to a cut buffer"},
430 /* C_Z */
431         {L("z"),                ex_z,           E_ADDR1,
432             "3c01",
433             "[line] z [-|.|+|^|=] [count] [flags]",
434             "display different screens of the file"},
435 /* C_SUBTILDE */
436         {L("~"),                ex_subtilde,    E_ADDR2|E_ADDR_ZERO,
437             "s",
438             "[line [,line]] ~ [cgr] [count] [#lp]",
439             "replace previous RE with previous replacement string,"},
440         {NULL},
441 };