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