ex_cmd.c revision 256281
128273Ssteve/*- 2124355Srwatson * Copyright (c) 1992, 1993, 1994 328273Ssteve * The Regents of the University of California. All rights reserved. 428273Ssteve * Copyright (c) 1992, 1993, 1994, 1995, 1996 528273Ssteve * Keith Bostic. All rights reserved. 628273Ssteve * 728273Ssteve * See the LICENSE file for redistribution information. 828273Ssteve */ 928273Ssteve 1028273Ssteve#include "config.h" 1128273Ssteve 1228273Ssteve#ifndef lint 1328273Sstevestatic const char sccsid[] = "$Id: ex_cmd.c,v 10.26 2011/07/14 15:11:16 zy Exp $"; 1428273Ssteve#endif /* not lint */ 1528273Ssteve 1628273Ssteve#include <sys/types.h> 1728273Ssteve#include <sys/queue.h> 1828273Ssteve#include <sys/time.h> 1928273Ssteve 2028273Ssteve#include <bitstring.h> 2128273Ssteve#include <limits.h> 2228273Ssteve#include <stdio.h> 2328273Ssteve 2428273Ssteve#include "../common/common.h" 2528273Ssteve 2669059Sphantom/* 2750476Speter * This array maps ex command names to command functions. 2828273Ssteve * 29224708Srmacklem * The order in which command names are listed below is important -- 3028273Ssteve * ambiguous abbreviations are resolved to be the first possible match, 3128273Ssteve * e.g. "r" means "read", not "rewind", because "read" is listed before 3228273Ssteve * "rewind". 3328273Ssteve * 3428273Ssteve * The syntax of the ex commands is unbelievably irregular, and a special 3528273Ssteve * case from beginning to end. Each command has an associated "syntax 3628273Ssteve * script" which describes the "arguments" that are possible. The script 3769059Sphantom * syntax is as follows: 3828273Ssteve * 3969059Sphantom * ! -- ! flag 4028273Ssteve * 1 -- flags: [+-]*[pl#][+-]* 41111447Sru * 2 -- flags: [-.+^] 4228273Ssteve * 3 -- flags: [-.+^=] 4328273Ssteve * b -- buffer 4428273Ssteve * c[01+a] -- count (0-N, 1-N, signed 1-N, address offset) 4528273Ssteve * f[N#][or] -- file (a number or N, optional or required) 4628273Ssteve * l -- line 47111447Sru * S -- string with file name expansion 4870466Sru * s -- string 49111447Sru * W -- word string 50108228Sdillon * w[N#][or] -- word (a number or N, optional or required) 5170466Sru */ 52111447SruEXCMDLIST const cmds[] = { 53111447Sru/* C_SCROLL */ 54111447Sru {L("\004"), ex_pr, E_ADDR2, 55111447Sru "", 5670466Sru "^D", 57111447Sru "scroll lines"}, 58111447Sru/* C_BANG */ 59111447Sru {L("!"), ex_bang, E_ADDR2_NONE|E_SECURE, 6028273Ssteve "S", 6128273Ssteve "[line [,line]] ! command", 6228273Ssteve "filter lines through commands or run commands"}, 6328273Ssteve/* C_HASH */ 64111447Sru {L("#"), ex_number, E_ADDR2|E_CLRFLAG, 65111447Sru "ca1", 66111447Sru "[line [,line]] # [count] [l]", 67111447Sru "display numbered lines"}, 68111447Sru/* C_SUBAGAIN */ 69111447Sru {L("&"), ex_subagain, E_ADDR2|E_ADDR_ZERO, 70111447Sru "s", 71111447Sru "[line [,line]] & [cgr] [count] [#lp]", 72111447Sru "repeat the last subsitution"}, 73111447Sru/* C_STAR */ 74111447Sru {L("*"), ex_at, 0, 75111447Sru "b", 76108228Sdillon "* [buffer]", 77111447Sru "execute a buffer"}, 78111447Sru/* C_SHIFTL */ 79111447Sru {L("<"), ex_shiftl, E_ADDR2|E_AUTOPRINT, 80108228Sdillon "ca1", 8128273Ssteve "[line [,line]] <[<...] [count] [flags]", 82108228Sdillon "shift lines left"}, 83111447Sru/* C_EQUAL */ 84111447Sru {L("="), ex_equal, E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF, 85111447Sru "1", 86111447Sru "[line] = [flags]", 87111447Sru "display line number"}, 88111447Sru/* C_SHIFTR */ 89111447Sru {L(">"), ex_shiftr, E_ADDR2|E_AUTOPRINT, 90111447Sru "ca1", 91111447Sru "[line [,line]] >[>...] [count] [flags]", 92111447Sru "shift lines right"}, 93111447Sru/* C_AT */ 94111447Sru {L("@"), ex_at, E_ADDR2, 95111447Sru "b", 96111447Sru "@ [buffer]", 97111447Sru "execute a buffer"}, 98111447Sru/* C_APPEND */ 99111447Sru {L("append"), ex_append, E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF, 100111447Sru "!", 101111447Sru "[line] a[ppend][!]", 102111447Sru "append input to a line"}, 103111447Sru/* C_ABBR */ 104111447Sru {L("abbreviate"), ex_abbr, 0, 105111447Sru "W", 106111447Sru "ab[brev] [word replace]", 107111447Sru "specify an input abbreviation"}, 108108228Sdillon/* C_ARGS */ 109151202Syar {L("args"), ex_args, 0, 110111447Sru "", 111111447Sru "ar[gs]", 112111447Sru "display file argument list"}, 113111447Sru/* C_BG */ 114111447Sru {L("bg"), ex_bg, E_VIONLY, 115111447Sru "", 116111447Sru "bg", 117111447Sru "put a foreground screen into the background"}, 118111447Sru/* C_CHANGE */ 119111447Sru {L("change"), ex_change, E_ADDR2|E_ADDR_ZERODEF, 120111447Sru "!ca", 121111447Sru "[line [,line]] c[hange][!] [count]", 122108228Sdillon "change lines to input"}, 123111447Sru/* C_CD */ 124111447Sru {L("cd"), ex_cd, 0, 125111447Sru "!f1o", 126108228Sdillon "cd[!] [directory]", 127126005Spjd "change the current directory"}, 128108228Sdillon/* C_CHDIR */ 129108228Sdillon {L("chdir"), ex_cd, 0, 130108228Sdillon "!f1o", 13128273Ssteve "chd[ir][!] [directory]", 132124355Srwatson "change the current directory"}, 133124355Srwatson/* C_COPY */ 134124355Srwatson {L("copy"), ex_copy, E_ADDR2|E_AUTOPRINT, 135130582Sru "l1", 136124355Srwatson "[line [,line]] co[py] line [flags]", 137124355Srwatson "copy lines elsewhere in the file"}, 138124355Srwatson/* C_CSCOPE */ 139111447Sru {L("cscope"), ex_cscope, 0, 140111447Sru "!s", 141111447Sru "cs[cope] command [args]", 142111447Sru "create a set of tags using a cscope command"}, 143124355Srwatson/* 144111447Sru * !!! 145111447Sru * Adding new commands starting with 'd' may break the delete command code 146111447Sru * in ex_cmd() (the ex parser). Read through the comments there, first. 147111447Sru */ 148108228Sdillon/* C_DELETE */ 149135922Sbrooks {L("delete"), ex_delete, E_ADDR2|E_AUTOPRINT, 150135922Sbrooks "bca1", 151153887Sceri "[line [,line]] d[elete][flags] [buffer] [count] [flags]", 152108228Sdillon "delete lines from the file"}, 153153887Sceri/* C_DISPLAY */ 15428273Ssteve {L("display"), ex_display, 0, 155111447Sru "w1r", 156111447Sru "display b[uffers] | c[onnections] | s[creens] | t[ags]", 157111447Sru "display buffers, connections, screens or tags"}, 15876444Sbsd/* C_EDIT */ 15970466Sru {L("edit"), ex_edit, E_NEWSCREEN, 160111447Sru "f1o", 161111447Sru "[Ee][dit][!] [+cmd] [file]", 162111447Sru "begin editing another file"}, 163111447Sru/* C_EX */ 164111447Sru {L("ex"), ex_edit, E_NEWSCREEN, 165111447Sru "f1o", 166111447Sru "[Ee]x[!] [+cmd] [file]", 167111447Sru "begin editing another file"}, 16876444Sbsd/* C_EXUSAGE */ 16976444Sbsd {L("exusage"), ex_usage, 0, 17076444Sbsd "w1o", 17176444Sbsd "[exu]sage [command]", 17276444Sbsd "display ex command usage statement"}, 17376444Sbsd/* C_FILE */ 174104336Sdd {L("file"), ex_file, 0, 175104336Sdd "f1o", 17628273Ssteve "f[ile] [name]", 17728273Ssteve "display (and optionally set) file name"}, 17876444Sbsd/* C_FG */ 17976444Sbsd {L("fg"), ex_fg, E_NEWSCREEN|E_VIONLY, 180111447Sru "f1o", 18176444Sbsd "[Ff]g [file]", 18276444Sbsd "bring a backgrounded screen into the foreground"}, 183111447Sru/* C_GLOBAL */ 184108228Sdillon {L("global"), ex_global, E_ADDR2_ALL, 185111447Sru "!s", 18676444Sbsd "[line [,line]] g[lobal][!] [;/]RE[;/] [commands]", 18770466Sru "execute a global command on lines matching an RE"}, 188111447Sru/* C_HELP */ 18976444Sbsd {L("help"), ex_help, 0, 19076444Sbsd "", 19176444Sbsd "he[lp]", 19276444Sbsd "display help statement"}, 19376444Sbsd/* C_INSERT */ 19476444Sbsd {L("insert"), ex_insert, E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF, 19576444Sbsd "!", 196111447Sru "[line] i[nsert][!]", 19776444Sbsd "insert input before a line"}, 19876444Sbsd/* C_JOIN */ 19976444Sbsd {L("join"), ex_join, E_ADDR2|E_AUTOPRINT, 20076444Sbsd "!ca1", 20176444Sbsd "[line [,line]] j[oin][!] [count] [flags]", 20276444Sbsd "join lines into a single line"}, 20376444Sbsd/* C_K */ 20476444Sbsd {L("k"), ex_mark, E_ADDR1, 20576444Sbsd "w1r", 20676444Sbsd "[line] k key", 20776444Sbsd "mark a line position"}, 20876444Sbsd/* C_LIST */ 20976444Sbsd {L("list"), ex_list, E_ADDR2|E_CLRFLAG, 21076444Sbsd "ca1", 21128273Ssteve "[line [,line]] l[ist] [count] [#]", 21228273Ssteve "display lines in an unambiguous form"}, 21376444Sbsd/* C_MOVE */ 21476444Sbsd {L("move"), ex_move, E_ADDR2|E_AUTOPRINT, 21576444Sbsd "l", 21676444Sbsd "[line [,line]] m[ove] line", 21776444Sbsd "move lines elsewhere in the file"}, 21876444Sbsd/* C_MARK */ 21970466Sru {L("mark"), ex_mark, E_ADDR1, 220108228Sdillon "w1r", 221108228Sdillon "[line] ma[rk] key", 222108228Sdillon "mark a line position"}, 223108228Sdillon/* C_MAP */ 224111447Sru {L("map"), ex_map, 0, 225111447Sru "!W", 226108228Sdillon "map[!] [keys replace]", 227108228Sdillon "map input or commands to one or more keys"}, 228108228Sdillon/* C_MKEXRC */ 229108228Sdillon {L("mkexrc"), ex_mkexrc, 0, 230108228Sdillon "!f1r", 231108228Sdillon "mkexrc[!] file", 232108228Sdillon "write a .exrc file"}, 233108228Sdillon/* C_NEXT */ 234111447Sru {L("next"), ex_next, E_NEWSCREEN, 235111447Sru "!fN", 236111447Sru "[Nn][ext][!] [+cmd] [file ...]", 237111447Sru "edit (and optionally specify) the next file"}, 238111447Sru/* C_NUMBER */ 239111447Sru {L("number"), ex_number, E_ADDR2|E_CLRFLAG, 240108228Sdillon "ca1", 241108228Sdillon "[line [,line]] nu[mber] [count] [l]", 242108228Sdillon "change display to number lines"}, 243111447Sru/* C_OPEN */ 244153298Sdougb {L("open"), ex_open, E_ADDR1, 245153298Sdougb "s", 246153298Sdougb "[line] o[pen] [/RE/] [flags]", 247153298Sdougb "enter \"open\" mode (not implemented)"}, 248153298Sdougb/* C_PRINT */ 249153298Sdougb {L("print"), ex_pr, E_ADDR2|E_CLRFLAG, 250153298Sdougb "ca1", 251153298Sdougb "[line [,line]] p[rint] [count] [#l]", 252153298Sdougb "display lines"}, 253153298Sdougb/* C_PRESERVE */ 254153298Sdougb {L("preserve"), ex_preserve, 0, 255153298Sdougb "", 256111447Sru "pre[serve]", 257108228Sdillon "preserve an edit session for recovery"}, 258108228Sdillon/* C_PREVIOUS */ 259108228Sdillon {L("previous"), ex_prev, E_NEWSCREEN, 260108228Sdillon "!", 261108228Sdillon "[Pp]rev[ious][!]", 262108228Sdillon "edit the previous file in the file argument list"}, 263108228Sdillon/* C_PUT */ 264108228Sdillon {L("put"), ex_put, 265108228Sdillon E_ADDR1|E_AUTOPRINT|E_ADDR_ZERO|E_ADDR_ZERODEF, 266108228Sdillon "b", 267111447Sru "[line] pu[t] [buffer]", 268111447Sru "append a cut buffer to the line"}, 269111447Sru/* C_QUIT */ 270108228Sdillon {L("quit"), ex_quit, 0, 271108228Sdillon "!", 272111447Sru "q[uit][!]", 273111447Sru "exit ex/vi"}, 274111447Sru/* C_READ */ 275108228Sdillon {L("read"), ex_read, E_ADDR1|E_ADDR_ZERO|E_ADDR_ZERODEF, 276108228Sdillon "s", 277108228Sdillon "[line] r[ead] [!cmd | [file]]", 278108228Sdillon "append input from a command or file to the line"}, 279108228Sdillon/* C_RECOVER */ 280108228Sdillon {L("recover"), ex_recover, 0, 281111447Sru "!f1r", 282111447Sru "recover[!] file", 283111447Sru "recover a saved file"}, 28476445Sbsd/* C_RESIZE */ 285108228Sdillon {L("resize"), ex_resize, E_VIONLY, 286108228Sdillon "c+", 287111447Sru "resize [+-]rows", 288111447Sru "grow or shrink the current screen"}, 289130844Smpp/* C_REWIND */ 290117087Sbrooks {L("rewind"), ex_rew, 0, 291117087Sbrooks "!", 292117087Sbrooks "rew[ind][!]", 293117087Sbrooks "re-edit all the files in the file argument list"}, 294117087Sbrooks/* 295117087Sbrooks * !!! 296117087Sbrooks * Adding new commands starting with 's' may break the substitute command code 297117087Sbrooks * in ex_cmd() (the ex parser). Read through the comments there, first. 298117087Sbrooks */ 299117087Sbrooks/* C_SUBSTITUTE */ 300117087Sbrooks {L("s"), ex_s, E_ADDR2|E_ADDR_ZERO, 301117087Sbrooks "s", 302117087Sbrooks "[line [,line]] s [[/;]RE[/;]repl[/;] [cgr] [count] [#lp]]", 303130844Smpp "substitute on lines matching an RE"}, 304117087Sbrooks/* C_SCRIPT */ 305117087Sbrooks {L("script"), ex_script, E_SECURE, 306117087Sbrooks "!f1o", 307117087Sbrooks "sc[ript][!] [file]", 308117087Sbrooks "run a shell in a screen"}, 309117087Sbrooks/* C_SET */ 310111447Sru {L("set"), ex_set, 0, 311111447Sru "wN", 312130844Smpp "se[t] [option[=[value]]...] [nooption ...] [option? ...] [all]", 313111447Sru "set options (use \":set all\" to see all options)"}, 314111447Sru/* C_SHELL */ 315111447Sru {L("shell"), ex_shell, E_SECURE, 316111447Sru "", 317108228Sdillon "sh[ell]", 318108228Sdillon "suspend editing and run a shell"}, 319108228Sdillon/* C_SOURCE */ 320108228Sdillon {L("source"), ex_source, 0, 321108228Sdillon "f1r", 322108228Sdillon "so[urce] file", 32376445Sbsd "read a file of ex commands"}, 324111447Sru/* C_STOP */ 325111447Sru {L("stop"), ex_stop, E_SECURE, 326111447Sru "!", 327108228Sdillon "st[op][!]", 328108228Sdillon "suspend the edit session"}, 329108228Sdillon/* C_SUSPEND */ 330111447Sru {L("suspend"), ex_stop, E_SECURE, 331108228Sdillon "!", 332108228Sdillon "su[spend][!]", 333108228Sdillon "suspend the edit session"}, 334111447Sru/* C_T */ 335111447Sru {L("t"), ex_copy, E_ADDR2|E_AUTOPRINT, 336108228Sdillon "l1", 337111447Sru "[line [,line]] t line [flags]", 338111447Sru "copy lines elsewhere in the file"}, 339111447Sru/* C_TAG */ 340111447Sru {L("tag"), ex_tag_push, E_NEWSCREEN, 341111447Sru "!w1o", 342111447Sru "[Tt]a[g][!] [string]", 343111447Sru "edit the file containing the tag"}, 344108228Sdillon/* C_TAGNEXT */ 345108228Sdillon {L("tagnext"), ex_tag_next, 0, 346108228Sdillon "!", 347108228Sdillon "tagn[ext][!]", 348108228Sdillon "move to the next tag"}, 349108228Sdillon/* C_TAGPOP */ 350108228Sdillon {L("tagpop"), ex_tag_pop, 0, 35176445Sbsd "!w1o", 352108228Sdillon "tagp[op][!] [number | file]", 353108228Sdillon "return to the previous group of tags"}, 354108228Sdillon/* C_TAGPREV */ 355108228Sdillon {L("tagprev"), ex_tag_prev, 0, 35628273Ssteve "!", 357108228Sdillon "tagpr[ev][!]", 35876444Sbsd "move to the previous tag"}, 359108228Sdillon/* C_TAGTOP */ 360108228Sdillon {L("tagtop"), ex_tag_top, 0, 361111447Sru "!", 362111447Sru "tagt[op][!]", 363111447Sru "discard all tags"}, 364108228Sdillon/* C_UNDO */ 365108228Sdillon {L("undo"), ex_undo, E_AUTOPRINT, 366108228Sdillon "", 367111447Sru "u[ndo]", 368111447Sru "undo the most recent change"}, 369111447Sru/* C_UNABBREVIATE */ 370108228Sdillon {L("unabbreviate"),ex_unabbr, 0, 371108228Sdillon "w1r", 372108228Sdillon "una[bbrev] word", 37328273Ssteve "delete an abbreviation"}, 37476444Sbsd/* C_UNMAP */ 37576444Sbsd {L("unmap"), ex_unmap, 0, 37676444Sbsd "!w1r", 37776444Sbsd "unm[ap][!] word", 37876444Sbsd "delete an input or command map"}, 37928273Ssteve/* C_V */ 38028273Ssteve {L("v"), ex_v, E_ADDR2_ALL, 381108228Sdillon "s", 38276444Sbsd "[line [,line]] v [;/]RE[;/] [commands]", 38376444Sbsd "execute a global command on lines NOT matching an RE"}, 384111447Sru/* C_VERSION */ 385111447Sru {L("version"), ex_version, 0, 386111447Sru "", 387108228Sdillon "version", 388108228Sdillon "display the program version information"}, 389108228Sdillon/* C_VISUAL_EX */ 390111447Sru {L("visual"), ex_visual, E_ADDR1|E_ADDR_ZERODEF, 391111447Sru "2c11", 392111447Sru "[line] vi[sual] [-|.|+|^] [window_size] [flags]", 39328273Ssteve "enter visual (vi) mode from ex mode"}, 394108228Sdillon/* C_VISUAL_VI */ 395108228Sdillon {L("visual"), ex_edit, E_NEWSCREEN, 396108228Sdillon "f1o", 39776444Sbsd "[Vv]i[sual][!] [+cmd] [file]", 39876444Sbsd "edit another file (from vi mode only)"}, 39976444Sbsd/* C_VIUSAGE */ 40076444Sbsd {L("viusage"), ex_viusage, 0, 40176444Sbsd "w1o", 40276444Sbsd "[viu]sage [key]", 40376444Sbsd "display vi key usage statement"}, 40476444Sbsd/* C_VSPLIT */ 40576444Sbsd {L("vsplit"), ex_edit, E_VIONLY, 40676444Sbsd "f1o", 407111447Sru "vs[plit] [+cmd] [file]", 408111447Sru "split the current screen vertically"}, 409111447Sru/* C_WRITE */ 41076444Sbsd {L("write"), ex_write, E_ADDR2_ALL|E_ADDR_ZERODEF, 41170466Sru "!s", 412111447Sru "[line [,line]] w[rite][!] [ !cmd | [>>] [file]]", 413111447Sru "write the file"}, 414111447Sru/* C_WN */ 415111447Sru {L("wn"), ex_wn, E_ADDR2_ALL|E_ADDR_ZERODEF, 416111447Sru "!s", 417111447Sru "[line [,line]] wn[!] [>>] [file]", 418124355Srwatson "write the file and switch to the next file"}, 41928273Ssteve/* C_WQ */ 420224708Srmacklem {L("wq"), ex_wq, E_ADDR2_ALL|E_ADDR_ZERODEF, 421124355Srwatson "!s", 422124355Srwatson "[line [,line]] wq[!] [>>] [file]", 423124355Srwatson "write the file and exit"}, 424124355Srwatson/* C_XIT */ 425124355Srwatson {L("xit"), ex_xit, E_ADDR2_ALL|E_ADDR_ZERODEF, 426124355Srwatson "!f1o", 427111447Sru "[line [,line]] x[it][!] [file]", 428111447Sru "exit"}, 429111447Sru/* C_YANK */ 430111447Sru {L("yank"), ex_yank, E_ADDR2, 431130582Sru "bca", 432130582Sru "[line [,line]] ya[nk] [buffer] [count]", 433108228Sdillon "copy lines to a cut buffer"}, 434130582Sru/* C_Z */ 435130582Sru {L("z"), ex_z, E_ADDR1, 436130582Sru "3c01", 437124355Srwatson "[line] z [-|.|+|^|=] [count] [flags]", 438124355Srwatson "display different screens of the file"}, 439124355Srwatson/* C_SUBTILDE */ 440124355Srwatson {L("~"), ex_subtilde, E_ADDR2|E_ADDR_ZERO, 441111447Sru "s", 442111447Sru "[line [,line]] ~ [cgr] [count] [#lp]", 443111447Sru "replace previous RE with previous replacement string,"}, 444111447Sru {NULL}, 445111447Sru}; 446111447Sru