ex_cmd.c revision 259065
11558Srgrimes/*- 293492Sphk * Copyright (c) 1992, 1993, 1994 393492Sphk * The Regents of the University of California. All rights reserved. 493492Sphk * Copyright (c) 1992, 1993, 1994, 1995, 1996 51558Srgrimes * Keith Bostic. All rights reserved. 693492Sphk * 793492Sphk * See the LICENSE file for redistribution information. 893492Sphk */ 993492Sphk 1093492Sphk#include "config.h" 111558Srgrimes 121558Srgrimes#ifndef lint 131558Srgrimesstatic const char sccsid[] = "$Id: ex_cmd.c,v 10.26 2011/07/14 15:11:16 zy Exp $"; 141558Srgrimes#endif /* not lint */ 151558Srgrimes 161558Srgrimes#include <sys/types.h> 171558Srgrimes#include <sys/queue.h> 181558Srgrimes#include <sys/time.h> 1993492Sphk 2093492Sphk#include <bitstring.h> 2193492Sphk#include <limits.h> 221558Srgrimes#include <stdio.h> 2393492Sphk 241558Srgrimes#include "../common/common.h" 251558Srgrimes 2693492Sphk/* 271558Srgrimes * This array maps ex command names to command functions. 281558Srgrimes * 291558Srgrimes * The order in which command names are listed below is important -- 301558Srgrimes * ambiguous abbreviations are resolved to be the first possible match, 311558Srgrimes * e.g. "r" means "read", not "rewind", because "read" is listed before 321558Srgrimes * "rewind". 331558Srgrimes * 3496049Sfenner * The syntax of the ex commands is unbelievably irregular, and a special 3596049Sfenner * case from beginning to end. Each command has an associated "syntax 3696049Sfenner * script" which describes the "arguments" that are possible. The script 3796049Sfenner * syntax is as follows: 3896049Sfenner * 3996049Sfenner * ! -- ! flag 4096049Sfenner * 1 -- flags: [+-]*[pl#][+-]* 4196049Sfenner * 2 -- flags: [-.+^] 4296049Sfenner * 3 -- flags: [-.+^=] 4396049Sfenner * b -- buffer 4496049Sfenner * c[01+a] -- count (0-N, 1-N, signed 1-N, address offset) 4596049Sfenner * f[N#][or] -- file (a number or N, optional or required) 4696049Sfenner * l -- line 4796049Sfenner * S -- string with file name expansion 4896049Sfenner * s -- string 4996049Sfenner * W -- word string 5096049Sfenner * w[N#][or] -- word (a number or N, optional or required) 5196049Sfenner */ 5296049SfennerEXCMDLIST const cmds[] = { 5396049Sfenner/* C_SCROLL */ 5496049Sfenner {L("\004"), ex_pr, E_ADDR2, 5596049Sfenner "", 5696049Sfenner "^D", 5796049Sfenner "scroll lines"}, 5896049Sfenner/* C_BANG */ 5996049Sfenner {L("!"), ex_bang, E_ADDR2_NONE|E_SECURE, 6096049Sfenner "S", 611558Srgrimes "[line [,line]] ! command", 621558Srgrimes "filter lines through commands or run commands"}, 6395183Scharnier/* C_HASH */ 6495183Scharnier {L("#"), ex_number, E_ADDR2|E_CLRFLAG, 6595183Scharnier "ca1", 6696049Sfenner "[line [,line]] # [count] [l]", 6794580Smarcel "display numbered lines"}, 6894580Smarcel/* C_SUBAGAIN */ 6996025Smux {L("&"), ex_subagain, E_ADDR2|E_ADDR_ZERO, 7094580Smarcel "s", 7194580Smarcel "[line [,line]] & [cgr] [count] [#lp]", 7293492Sphk "repeat the last subsitution"}, 7393492Sphk/* C_STAR */ 7496025Smux {L("*"), ex_at, 0, 75234069Srmh "b", 7696049Sfenner "* [buffer]", 7794580Smarcel "execute a buffer"}, 7894580Smarcel/* C_SHIFTL */ 7994580Smarcel {L("<"), ex_shiftl, E_ADDR2|E_AUTOPRINT, 8096049Sfenner "ca1", 8193492Sphk "[line [,line]] <[<...] [count] [flags]", 8293492Sphk "shift lines left"}, 831558Srgrimes/* C_EQUAL */ 8497746Smarcel {L("="), ex_equal, E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF, 8597746Smarcel "1", 8697746Smarcel "[line] = [flags]", 87142533Sobrien "display line number"}, 88142533Sobrien/* C_SHIFTR */ 89142533Sobrien {L(">"), ex_shiftr, E_ADDR2|E_AUTOPRINT, 90142359Sobrien "ca1", 91133814Sru "[line [,line]] >[>...] [count] [flags]", 92133814Sru "shift lines right"}, 93244320Spjd/* C_AT */ 9494580Smarcel {L("@"), ex_at, E_ADDR2, 9596049Sfenner "b", 9696049Sfenner "@ [buffer]", 97196528Slulf "execute a buffer"}, 98196528Slulf/* C_APPEND */ 99196528Slulf {L("append"), ex_append, E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF, 10093492Sphk "!", 10194580Smarcel "[line] a[ppend][!]", 102142359Sobrien "append input to a line"}, 1031558Srgrimes/* C_ABBR */ 10493717Smarcel {L("abbreviate"), ex_abbr, 0, 10593492Sphk "W", 106142359Sobrien "ab[brev] [word replace]", 1071558Srgrimes "specify an input abbreviation"}, 108142359Sobrien/* C_ARGS */ 10993492Sphk {L("args"), ex_args, 0, 110150818Smaxim "", 111150818Smaxim "ar[gs]", 11293717Smarcel "display file argument list"}, 113142359Sobrien/* C_BG */ 11493717Smarcel {L("bg"), ex_bg, E_VIONLY, 11593717Smarcel "", 11693717Smarcel "bg", 11793492Sphk "put a foreground screen into the background"}, 11893492Sphk/* C_CHANGE */ 119142359Sobrien {L("change"), ex_change, E_ADDR2|E_ADDR_ZERODEF, 120142359Sobrien "!ca", 121142359Sobrien "[line [,line]] c[hange][!] [count]", 122142359Sobrien "change lines to input"}, 12396049Sfenner/* C_CD */ 124142359Sobrien {L("cd"), ex_cd, 0, 125142359Sobrien "!f1o", 126142359Sobrien "cd[!] [directory]", 127142533Sobrien "change the current directory"}, 128142533Sobrien/* C_CHDIR */ 129142359Sobrien {L("chdir"), ex_cd, 0, 130142533Sobrien "!f1o", 131142533Sobrien "chd[ir][!] [directory]", 132142359Sobrien "change the current directory"}, 133142533Sobrien/* C_COPY */ 134142359Sobrien {L("copy"), ex_copy, E_ADDR2|E_AUTOPRINT, 135142359Sobrien "l1", 13695039Sphk "[line [,line]] co[py] line [flags]", 1371558Srgrimes "copy lines elsewhere in the file"}, 1381558Srgrimes/* C_CSCOPE */ 13996049Sfenner {L("cscope"), ex_cscope, 0, 14096049Sfenner "!s", 14196049Sfenner "cs[cope] command [args]", 14296049Sfenner "create a set of tags using a cscope command"}, 14396049Sfenner/* 14496049Sfenner * !!! 14596049Sfenner * Adding new commands starting with 'd' may break the delete command code 14696049Sfenner * in ex_cmd() (the ex parser). Read through the comments there, first. 14796049Sfenner */ 148150105Srwatson/* C_DELETE */ 149150105Srwatson {L("delete"), ex_delete, E_ADDR2|E_AUTOPRINT, 150147506Sdwhite "bca1", 15196049Sfenner "[line [,line]] d[elete][flags] [buffer] [count] [flags]", 15296049Sfenner "delete lines from the file"}, 15396049Sfenner/* C_DISPLAY */ 15496049Sfenner {L("display"), ex_display, 0, 15596049Sfenner "w1r", 156147506Sdwhite "display b[uffers] | c[onnections] | s[creens] | t[ags]", 15796049Sfenner "display buffers, connections, screens or tags"}, 15896049Sfenner/* C_EDIT */ 15996049Sfenner {L("edit"), ex_edit, E_NEWSCREEN, 16096049Sfenner "f1o", 16196049Sfenner "[Ee][dit][!] [+cmd] [file]", 16296049Sfenner "begin editing another file"}, 163147506Sdwhite/* C_EX */ 164147506Sdwhite {L("ex"), ex_edit, E_NEWSCREEN, 16596049Sfenner "f1o", 166147506Sdwhite "[Ee]x[!] [+cmd] [file]", 167147506Sdwhite "begin editing another file"}, 168147506Sdwhite/* C_EXUSAGE */ 16996049Sfenner {L("exusage"), ex_usage, 0, 17096049Sfenner "w1o", 17196049Sfenner "[exu]sage [command]", 172147506Sdwhite "display ex command usage statement"}, 17396049Sfenner/* C_FILE */ 17496049Sfenner {L("file"), ex_file, 0, 17596049Sfenner "f1o", 176147506Sdwhite "f[ile] [name]", 17796049Sfenner "display (and optionally set) file name"}, 178147506Sdwhite/* C_FG */ 17996049Sfenner {L("fg"), ex_fg, E_NEWSCREEN|E_VIONLY, 18096049Sfenner "f1o", 18196049Sfenner "[Ff]g [file]", 182244320Spjd "bring a backgrounded screen into the foreground"}, 183244320Spjd/* C_GLOBAL */ 184244320Spjd {L("global"), ex_global, E_ADDR2_ALL, 185244320Spjd "!s", 186244320Spjd "[line [,line]] g[lobal][!] [;/]RE[;/] [commands]", 187244320Spjd "execute a global command on lines matching an RE"}, 188244320Spjd/* C_HELP */ 189244320Spjd {L("help"), ex_help, 0, 190244320Spjd "", 191244320Spjd "he[lp]", 192244320Spjd "display help statement"}, 193244320Spjd/* C_INSERT */ 194244320Spjd {L("insert"), ex_insert, E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF, 195244320Spjd "!", 196244320Spjd "[line] i[nsert][!]", 197244320Spjd "insert input before a line"}, 198244320Spjd/* C_JOIN */ 199244320Spjd {L("join"), ex_join, E_ADDR2|E_AUTOPRINT, 200244320Spjd "!ca1", 201244320Spjd "[line [,line]] j[oin][!] [count] [flags]", 202244320Spjd "join lines into a single line"}, 203244320Spjd/* C_K */ 204244320Spjd {L("k"), ex_mark, E_ADDR1, 205244320Spjd "w1r", 206244320Spjd "[line] k key", 207244320Spjd "mark a line position"}, 208244320Spjd/* C_LIST */ 209244320Spjd {L("list"), ex_list, E_ADDR2|E_CLRFLAG, 210244320Spjd "ca1", 211244320Spjd "[line [,line]] l[ist] [count] [#]", 212244320Spjd "display lines in an unambiguous form"}, 213244320Spjd/* C_MOVE */ 214244320Spjd {L("move"), ex_move, E_ADDR2|E_AUTOPRINT, 215244320Spjd "l", 216244320Spjd "[line [,line]] m[ove] line", 217244320Spjd "move lines elsewhere in the file"}, 218244320Spjd/* C_MARK */ 219244320Spjd {L("mark"), ex_mark, E_ADDR1, 220244320Spjd "w1r", 221244320Spjd "[line] ma[rk] key", 222244320Spjd "mark a line position"}, 223244320Spjd/* C_MAP */ 224244320Spjd {L("map"), ex_map, 0, 225244320Spjd "!W", 226244320Spjd "map[!] [keys replace]", 227244320Spjd "map input or commands to one or more keys"}, 228244320Spjd/* C_MKEXRC */ 229244320Spjd {L("mkexrc"), ex_mkexrc, 0, 230244320Spjd "!f1r", 231244320Spjd "mkexrc[!] file", 232244321Spjd "write a .exrc file"}, 233244321Spjd/* C_NEXT */ 234244321Spjd {L("next"), ex_next, E_NEWSCREEN, 235244321Spjd "!fN", 236244321Spjd "[Nn][ext][!] [+cmd] [file ...]", 237244321Spjd "edit (and optionally specify) the next file"}, 238244321Spjd/* C_NUMBER */ 239244321Spjd {L("number"), ex_number, E_ADDR2|E_CLRFLAG, 240244321Spjd "ca1", 241244321Spjd "[line [,line]] nu[mber] [count] [l]", 242244321Spjd "change display to number lines"}, 24396025Smux/* C_OPEN */ 24496025Smux {L("open"), ex_open, E_ADDR1, 24596025Smux "s", 24696025Smux "[line] o[pen] [/RE/] [flags]", 24796025Smux "enter \"open\" mode (not implemented)"}, 248244320Spjd/* C_PRINT */ 24996025Smux {L("print"), ex_pr, E_ADDR2|E_CLRFLAG, 25096025Smux "ca1", 25196049Sfenner "[line [,line]] p[rint] [count] [#l]", 25296025Smux "display lines"}, 253244319Spjd/* C_PRESERVE */ 25493717Smarcel {L("preserve"), ex_preserve, 0, 255244319Spjd "", 25696049Sfenner "pre[serve]", 25796049Sfenner "preserve an edit session for recovery"}, 25896049Sfenner/* C_PREVIOUS */ 259244215Spjd {L("previous"), ex_prev, E_NEWSCREEN, 26096025Smux "!", 26196025Smux "[Pp]rev[ious][!]", 262244319Spjd "edit the previous file in the file argument list"}, 26396025Smux/* C_PUT */ 26496025Smux {L("put"), ex_put, 26596025Smux E_ADDR1|E_AUTOPRINT|E_ADDR_ZERO|E_ADDR_ZERODEF, 26696025Smux "b", 26796025Smux "[line] pu[t] [buffer]", 26896025Smux "append a cut buffer to the line"}, 26996025Smux/* C_QUIT */ 27096025Smux {L("quit"), ex_quit, 0, 27196025Smux "!", 27296049Sfenner "q[uit][!]", 273244320Spjd "exit ex/vi"}, 274244320Spjd/* C_READ */ 27596049Sfenner {L("read"), ex_read, E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF, 27696049Sfenner "s", 27796025Smux "[line] r[ead] [!cmd | [file]]", 27896025Smux "append input from a command or file to the line"}, 27996025Smux/* C_RECOVER */ 28096025Smux {L("recover"), ex_recover, 0, 28196025Smux "!f1r", 28296049Sfenner "recover[!] file", 28396049Sfenner "recover a saved file"}, 28496025Smux/* C_RESIZE */ 28596025Smux {L("resize"), ex_resize, E_VIONLY, 28696025Smux "c+", 28796049Sfenner "resize [+-]rows", 28896049Sfenner "grow or shrink the current screen"}, 28996025Smux/* C_REWIND */ 290174923Srwatson {L("rewind"), ex_rew, 0, 291174923Srwatson "!", 292174923Srwatson "rew[ind][!]", 293174923Srwatson "re-edit all the files in the file argument list"}, 294174923Srwatson/* 295196528Slulf * !!! 296174923Srwatson * Adding new commands starting with 's' may break the substitute command code 297174923Srwatson * in ex_cmd() (the ex parser). Read through the comments there, first. 298196528Slulf */ 299174923Srwatson/* C_SUBSTITUTE */ 300174923Srwatson {L("s"), ex_s, E_ADDR2|E_ADDR_ZERO, 301174923Srwatson "s", 302174923Srwatson "[line [,line]] s [[/;]RE[/;]repl[/;] [cgr] [count] [#lp]]", 303174923Srwatson "substitute on lines matching an RE"}, 304174923Srwatson/* C_SCRIPT */ 305174923Srwatson {L("script"), ex_script, E_SECURE, 306174923Srwatson "!f1o", 307174923Srwatson "sc[ript][!] [file]", 308174923Srwatson "run a shell in a screen"}, 309174923Srwatson/* C_SET */ 310174923Srwatson {L("set"), ex_set, 0, 311174923Srwatson "wN", 312174923Srwatson "se[t] [option[=[value]]...] [nooption ...] [option? ...] [all]", 313174923Srwatson "set options (use \":set all\" to see all options)"}, 314174923Srwatson/* C_SHELL */ 315174923Srwatson {L("shell"), ex_shell, E_SECURE, 316174923Srwatson "", 317174923Srwatson "sh[ell]", 318174923Srwatson "suspend editing and run a shell"}, 319174923Srwatson/* C_SOURCE */ 320174923Srwatson {L("source"), ex_source, 0, 321174923Srwatson "f1r", 322174923Srwatson "so[urce] file", 323174923Srwatson "read a file of ex commands"}, 324174923Srwatson/* C_STOP */ 325174923Srwatson {L("stop"), ex_stop, E_SECURE, 326174923Srwatson "!", 327244215Spjd "st[op][!]", 328174923Srwatson "suspend the edit session"}, 329174923Srwatson/* C_SUSPEND */ 330174923Srwatson {L("suspend"), ex_stop, E_SECURE, 331174923Srwatson "!", 332174923Srwatson "su[spend][!]", 333174923Srwatson "suspend the edit session"}, 334174923Srwatson/* C_T */ 335174923Srwatson {L("t"), ex_copy, E_ADDR2|E_AUTOPRINT, 336174923Srwatson "l1", 337174923Srwatson "[line [,line]] t line [flags]", 338174923Srwatson "copy lines elsewhere in the file"}, 339174923Srwatson/* C_TAG */ 340174923Srwatson {L("tag"), ex_tag_push, E_NEWSCREEN, 341174923Srwatson "!w1o", 342174923Srwatson "[Tt]a[g][!] [string]", 343174923Srwatson "edit the file containing the tag"}, 344174923Srwatson/* C_TAGNEXT */ 345174923Srwatson {L("tagnext"), ex_tag_next, 0, 346174923Srwatson "!", 347174923Srwatson "tagn[ext][!]", 348174923Srwatson "move to the next tag"}, 349174923Srwatson/* C_TAGPOP */ 350174923Srwatson {L("tagpop"), ex_tag_pop, 0, 351174923Srwatson "!w1o", 352174923Srwatson "tagp[op][!] [number | file]", 353174923Srwatson "return to the previous group of tags"}, 354174923Srwatson/* C_TAGPREV */ 355174923Srwatson {L("tagprev"), ex_tag_prev, 0, 356174923Srwatson "!", 357174923Srwatson "tagpr[ev][!]", 358174923Srwatson "move to the previous tag"}, 359174923Srwatson/* C_TAGTOP */ 360174923Srwatson {L("tagtop"), ex_tag_top, 0, 361174923Srwatson "!", 362174923Srwatson "tagt[op][!]", 363174923Srwatson "discard all tags"}, 364174923Srwatson/* C_UNDO */ 365174923Srwatson {L("undo"), ex_undo, E_AUTOPRINT, 366174923Srwatson "", 367174923Srwatson "u[ndo]", 368174923Srwatson "undo the most recent change"}, 369196528Slulf/* C_UNABBREVIATE */ 370196528Slulf {L("unabbreviate"),ex_unabbr, 0, 371196528Slulf "w1r", 372196528Slulf "una[bbrev] word", 373196528Slulf "delete an abbreviation"}, 374174923Srwatson/* C_UNMAP */ 375174923Srwatson {L("unmap"), ex_unmap, 0, 376174923Srwatson "!w1r", 377174923Srwatson "unm[ap][!] word", 378174923Srwatson "delete an input or command map"}, 379174923Srwatson/* C_V */ 380174923Srwatson {L("v"), ex_v, E_ADDR2_ALL, 381174923Srwatson "s", 382174923Srwatson "[line [,line]] v [;/]RE[;/] [commands]", 383174923Srwatson "execute a global command on lines NOT matching an RE"}, 384174923Srwatson/* C_VERSION */ 385174923Srwatson {L("version"), ex_version, 0, 386174923Srwatson "", 387174923Srwatson "version", 388174923Srwatson "display the program version information"}, 389174923Srwatson/* C_VISUAL_EX */ 390174923Srwatson {L("visual"), ex_visual, E_ADDR1|E_ADDR_ZERODEF, 391174923Srwatson "2c11", 392174923Srwatson "[line] vi[sual] [-|.|+|^] [window_size] [flags]", 393174923Srwatson "enter visual (vi) mode from ex mode"}, 394174923Srwatson/* C_VISUAL_VI */ 395174923Srwatson {L("visual"), ex_edit, E_NEWSCREEN, 396174923Srwatson "f1o", 397174923Srwatson "[Vv]i[sual][!] [+cmd] [file]", 398174923Srwatson "edit another file (from vi mode only)"}, 399174923Srwatson/* C_VIUSAGE */ 400174923Srwatson {L("viusage"), ex_viusage, 0, 401174923Srwatson "w1o", 402174923Srwatson "[viu]sage [key]", 403174923Srwatson "display vi key usage statement"}, 404174923Srwatson/* C_VSPLIT */ 405174923Srwatson {L("vsplit"), ex_edit, E_VIONLY, 406174923Srwatson "f1o", 407174923Srwatson "vs[plit] [+cmd] [file]", 408174923Srwatson "split the current screen vertically"}, 409174923Srwatson/* C_WRITE */ 410174923Srwatson {L("write"), ex_write, E_ADDR2_ALL|E_ADDR_ZERODEF, 411174923Srwatson "!s", 412174923Srwatson "[line [,line]] w[rite][!] [ !cmd | [>>] [file]]", 413174923Srwatson "write the file"}, 414174923Srwatson/* C_WN */ 415174923Srwatson {L("wn"), ex_wn, E_ADDR2_ALL|E_ADDR_ZERODEF, 416174923Srwatson "!s", 417174923Srwatson "[line [,line]] wn[!] [>>] [file]", 418174923Srwatson "write the file and switch to the next file"}, 419174923Srwatson/* C_WQ */ 420174923Srwatson {L("wq"), ex_wq, E_ADDR2_ALL|E_ADDR_ZERODEF, 421174923Srwatson "!s", 422174923Srwatson "[line [,line]] wq[!] [>>] [file]", 423174923Srwatson "write the file and exit"}, 424174923Srwatson/* C_XIT */ 425174923Srwatson {L("xit"), ex_xit, E_ADDR2_ALL|E_ADDR_ZERODEF, 426174923Srwatson "!f1o", 427174923Srwatson "[line [,line]] x[it][!] [file]", 428174923Srwatson "exit"}, 429174923Srwatson/* C_YANK */ 43093492Sphk {L("yank"), ex_yank, E_ADDR2, 431146763Sdelphij "bca", 4321558Srgrimes "[line [,line]] ya[nk] [buffer] [count]", 433244321Spjd "copy lines to a cut buffer"}, 43497340Smarcel/* C_Z */ 43594580Smarcel {L("z"), ex_z, E_ADDR1, 436174923Srwatson "3c01", 43796049Sfenner "[line] z [-|.|+|^|=] [count] [flags]", 438142533Sobrien "display different screens of the file"}, 439174923Srwatson/* C_SUBTILDE */ 440142359Sobrien {L("~"), ex_subtilde, E_ADDR2|E_ADDR_ZERO, 44194580Smarcel "s", 442174923Srwatson "[line [,line]] ~ [cgr] [count] [#lp]", 4438871Srgrimes "replace previous RE with previous replacement string,"}, 444142359Sobrien {NULL}, 44596049Sfenner}; 446142359Sobrien