1 /* $NetBSD: ex_cmd.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */
3 * Copyright (c) 1992, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1992, 1993, 1994, 1995, 1996
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
13 #include <sys/cdefs.h>
16 static const char sccsid
[] = "Id: ex_cmd.c,v 10.25 2001/06/10 10:23:44 skimo Exp (Berkeley) Date: 2001/06/10 10:23:44 ";
19 __RCSID("$NetBSD: ex_cmd.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
22 #include <sys/types.h>
23 #include <sys/queue.h>
25 #include <bitstring.h>
29 #include "../common/common.h"
32 * This array maps ex command names to command functions.
34 * The order in which command names are listed below is important --
35 * ambiguous abbreviations are resolved to be the first possible match,
36 * e.g. "r" means "read", not "rewind", because "read" is listed before
39 * The syntax of the ex commands is unbelievably irregular, and a special
40 * case from beginning to end. Each command has an associated "syntax
41 * script" which describes the "arguments" that are possible. The script
42 * syntax is as follows:
45 * 1 -- flags: [+-]*[pl#][+-]*
49 * c[01+a] -- count (0-N, 1-N, signed 1-N, address offset)
50 * f[N#][or] -- file (a number or N, optional or required)
52 * S -- string with file name expansion
55 * w[N#][or] -- word (a number or N, optional or required)
57 EXCMDLIST
const cmds
[] = {
59 {L("\004"), ex_pr
, E_ADDR2
,
64 {L("!"), ex_bang
, E_ADDR2_NONE
|E_SECURE
,
66 "[line [,line]] ! command",
67 "filter lines through commands or run commands"},
69 {L("#"), ex_number
, E_ADDR2
|E_CLRFLAG
,
71 "[line [,line]] # [count] [l]",
72 "display numbered lines"},
74 {L("&"), ex_subagain
, E_ADDR2
|E_ADDR_ZERO
,
76 "[line [,line]] & [cgr] [count] [#lp]",
77 "repeat the last subsitution"},
84 {L("<"), ex_shiftl
, E_ADDR2
|E_AUTOPRINT
,
86 "[line [,line]] <[<...] [count] [flags]",
89 {L("="), ex_equal
, E_ADDR1
|E_ADDR_ZERO
|E_ADDR_ZERODEF
,
92 "display line number"},
94 {L(">"), ex_shiftr
, E_ADDR2
|E_AUTOPRINT
,
96 "[line [,line]] >[>...] [count] [flags]",
99 {L("@"), ex_at
, E_ADDR2
,
104 {L("append"), ex_append
, E_ADDR1
|E_ADDR_ZERO
|E_ADDR_ZERODEF
,
106 "[line] a[ppend][!]",
107 "append input to a line"},
109 {L("abbreviate"), ex_abbr
, 0,
111 "ab[brev] [word replace]",
112 "specify an input abbreviation"},
114 {L("args"), ex_args
, 0,
117 "display file argument list"},
119 {L("bg"), ex_bg
, E_VIONLY
,
122 "put a foreground screen into the background"},
124 {L("change"), ex_change
, E_ADDR2
|E_ADDR_ZERODEF
,
126 "[line [,line]] c[hange][!] [count]",
127 "change lines to input"},
132 "change the current directory"},
134 {L("chdir"), ex_cd
, 0,
136 "chd[ir][!] [directory]",
137 "change the current directory"},
139 {L("copy"), ex_copy
, E_ADDR2
|E_AUTOPRINT
,
141 "[line [,line]] co[py] line [flags]",
142 "copy lines elsewhere in the file"},
144 {L("cscope"), ex_cscope
, 0,
146 "cs[cope] command [args]",
147 "create a set of tags using a cscope command"},
150 * Adding new commands starting with 'd' may break the delete command code
151 * in ex_cmd() (the ex parser). Read through the comments there, first.
154 {L("delete"), ex_delete
, E_ADDR2
|E_AUTOPRINT
,
156 "[line [,line]] d[elete][flags] [buffer] [count] [flags]",
157 "delete lines from the file"},
159 {L("display"), ex_display
, 0,
161 "display b[uffers] | c[onnections] | s[creens] | t[ags]",
162 "display buffers, connections, screens or tags"},
164 {L("edit"), ex_edit
, E_NEWSCREEN
,
166 "[Ee][dit][!] [+cmd] [file]",
167 "begin editing another file"},
169 {L("ex"), ex_edit
, E_NEWSCREEN
,
171 "[Ee]x[!] [+cmd] [file]",
172 "begin editing another file"},
174 {L("exusage"), ex_usage
, 0,
176 "[exu]sage [command]",
177 "display ex command usage statement"},
179 {L("file"), ex_file
, 0,
182 "display (and optionally set) file name"},
184 {L("fg"), ex_fg
, E_NEWSCREEN
|E_VIONLY
,
187 "bring a backgrounded screen into the foreground"},
189 {L("global"), ex_global
, E_ADDR2_ALL
,
191 "[line [,line]] g[lobal][!] [;/]RE[;/] [commands]",
192 "execute a global command on lines matching an RE"},
194 {L("help"), ex_help
, 0,
197 "display help statement"},
199 {L("insert"), ex_insert
, E_ADDR1
|E_ADDR_ZERO
|E_ADDR_ZERODEF
,
201 "[line] i[nsert][!]",
202 "insert input before a line"},
204 {L("join"), ex_join
, E_ADDR2
|E_AUTOPRINT
,
206 "[line [,line]] j[oin][!] [count] [flags]",
207 "join lines into a single line"},
209 {L("k"), ex_mark
, E_ADDR1
,
212 "mark a line position"},
214 {L("list"), ex_list
, E_ADDR2
|E_CLRFLAG
,
216 "[line [,line]] l[ist] [count] [#]",
217 "display lines in an unambiguous form"},
219 {L("move"), ex_move
, E_ADDR2
|E_AUTOPRINT
,
221 "[line [,line]] m[ove] line",
222 "move lines elsewhere in the file"},
224 {L("mark"), ex_mark
, E_ADDR1
,
227 "mark a line position"},
229 {L("map"), ex_map
, 0,
231 "map[!] [keys replace]",
232 "map input or commands to one or more keys"},
234 {L("mkexrc"), ex_mkexrc
, 0,
237 "write a .exrc file"},
239 {L("next"), ex_next
, E_NEWSCREEN
,
241 "[Nn][ext][!] [+cmd] [file ...]",
242 "edit (and optionally specify) the next file"},
244 {L("number"), ex_number
, E_ADDR2
|E_CLRFLAG
,
246 "[line [,line]] nu[mber] [count] [l]",
247 "change display to number lines"},
249 {L("open"), ex_open
, E_ADDR1
,
251 "[line] o[pen] [/RE/] [flags]",
252 "enter \"open\" mode (not implemented)"},
254 {L("print"), ex_pr
, E_ADDR2
|E_CLRFLAG
,
256 "[line [,line]] p[rint] [count] [#l]",
259 {L("perl"), ex_perl
, E_ADDR2_ALL
|E_ADDR_ZERO
|
260 E_ADDR_ZERODEF
|E_SECURE
,
263 "run the perl interpreter with the command"},
265 {L("perldo"), ex_perl
, E_ADDR2
|E_ADDR_ZERO
|
266 E_ADDR_ZERODEF
|E_SECURE
,
269 "run the perl interpreter with the command, on each line"},
271 {L("preserve"), ex_preserve
, 0,
274 "preserve an edit session for recovery"},
276 {L("previous"), ex_prev
, E_NEWSCREEN
,
279 "edit the previous file in the file argument list"},
282 E_ADDR1
|E_AUTOPRINT
|E_ADDR_ZERO
|E_ADDR_ZERODEF
,
284 "[line] pu[t] [buffer]",
285 "append a cut buffer to the line"},
287 {L("quit"), ex_quit
, 0,
292 {L("read"), ex_read
, E_ADDR1
|E_ADDR_ZERO
|E_ADDR_ZERODEF
,
294 "[line] r[ead] [!cmd | [file]]",
295 "append input from a command or file to the line"},
297 {L("recover"), ex_recover
, 0,
300 "recover a saved file"},
302 {L("resize"), ex_resize
, E_VIONLY
,
305 "grow or shrink the current screen"},
307 {L("rewind"), ex_rew
, 0,
310 "re-edit all the files in the file argument list"},
313 {L("rtag"), ex_rtag_push
, E_NEWSCREEN
,
315 "rta[g][!] [string]",
316 "edit the file containing the tag"},
320 * Adding new commands starting with 's' may break the substitute command code
321 * in ex_cmd() (the ex parser). Read through the comments there, first.
324 {L("s"), ex_s
, E_ADDR2
|E_ADDR_ZERO
,
326 "[line [,line]] s [[/;]RE[/;]repl[/;] [cgr] [count] [#lp]]",
327 "substitute on lines matching an RE"},
329 {L("script"), ex_script
, E_SECURE
,
331 "sc[ript][!] [file]",
332 "run a shell in a screen"},
334 {L("set"), ex_set
, 0,
336 "se[t] [option[=[value]]...] [nooption ...] [option? ...] [all]",
337 "set options (use \":set all\" to see all options)"},
339 {L("shell"), ex_shell
, E_SECURE
,
342 "suspend editing and run a shell"},
344 {L("source"), ex_source
, 0,
347 "read a file of ex commands"},
349 {L("stop"), ex_stop
, E_SECURE
,
352 "suspend the edit session"},
354 {L("suspend"), ex_stop
, E_SECURE
,
357 "suspend the edit session"},
359 {L("t"), ex_copy
, E_ADDR2
|E_AUTOPRINT
,
361 "[line [,line]] t line [flags]",
362 "copy lines elsewhere in the file"},
364 {L("tag"), ex_tag_push
, E_NEWSCREEN
,
366 "[Tt]a[g][!] [string]",
367 "edit the file containing the tag"},
369 {L("tagnext"), ex_tag_next
, 0,
372 "move to the next tag"},
374 {L("tagpop"), ex_tag_pop
, 0,
376 "tagp[op][!] [number | file]",
377 "return to the previous group of tags"},
379 {L("tagprev"), ex_tag_prev
, 0,
382 "move to the previous tag"},
384 {L("tagtop"), ex_tag_top
, 0,
389 {L("tcl"), ex_tcl
, E_ADDR2_ALL
|E_ADDR_ZERO
|
390 E_ADDR_ZERODEF
|E_SECURE
,
393 "run the tcl interpreter with the command"},
395 {L("undo"), ex_undo
, E_AUTOPRINT
,
398 "undo the most recent change"},
400 {L("unabbreviate"),ex_unabbr
, 0,
403 "delete an abbreviation"},
405 {L("unmap"), ex_unmap
, 0,
408 "delete an input or command map"},
410 {L("v"), ex_v
, E_ADDR2_ALL
,
412 "[line [,line]] v [;/]RE[;/] [commands]",
413 "execute a global command on lines NOT matching an RE"},
415 {L("version"), ex_version
, 0,
418 "display the program version information"},
420 {L("visual"), ex_visual
, E_ADDR1
|E_ADDR_ZERODEF
,
422 "[line] vi[sual] [-|.|+|^] [window_size] [flags]",
423 "enter visual (vi) mode from ex mode"},
425 {L("visual"), ex_edit
, E_NEWSCREEN
,
427 "[Vv]i[sual][!] [+cmd] [file]",
428 "edit another file (from vi mode only)"},
430 {L("viusage"), ex_viusage
, 0,
433 "display vi key usage statement"},
435 {L("vsplit"), ex_edit
, E_VIONLY
,
437 "vs[plit] [+cmd] [file]",
438 "split the current screen vertically"},
440 {L("write"), ex_write
, E_ADDR2_ALL
|E_ADDR_ZERODEF
,
442 "[line [,line]] w[rite][!] [ !cmd | [>>] [file]]",
445 {L("wn"), ex_wn
, E_ADDR2_ALL
|E_ADDR_ZERODEF
,
447 "[line [,line]] wn[!] [>>] [file]",
448 "write the file and switch to the next file"},
450 {L("wq"), ex_wq
, E_ADDR2_ALL
|E_ADDR_ZERODEF
,
452 "[line [,line]] wq[!] [>>] [file]",
453 "write the file and exit"},
455 {L("xit"), ex_xit
, E_ADDR2_ALL
|E_ADDR_ZERODEF
,
457 "[line [,line]] x[it][!] [file]",
460 {L("yank"), ex_yank
, E_ADDR2
,
462 "[line [,line]] ya[nk] [buffer] [count]",
463 "copy lines to a cut buffer"},
465 {L("z"), ex_z
, E_ADDR1
,
467 "[line] z [-|.|+|^|=] [count] [flags]",
468 "display different screens of the file"},
470 {L("~"), ex_subtilde
, E_ADDR2
|E_ADDR_ZERO
,
472 "[line [,line]] ~ [cgr] [count] [#lp]",
473 "replace previous RE with previous replacement string,"},