/* * LEVEE, or Captain Video; A vi clone * * Copyright (c) 1982-2008 David L Parsons * All rights reserved. * * Redistribution and use in source and binary forms, without or * without modification, are permitted provided that the above * copyright notice and this paragraph are duplicated in all such * forms and that any documentation, advertising materials, and * other materials related to such distribution and use acknowledge * that the software was developed by David L Parsons (orc@pell.chi.il.us). * My name may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE. */ /* global declarations */ #include "levee.h" #define GLOBALS char lastchar, /* Last character read via peekc */ ch; /* Global command char */ exec_type mode; /* editor init state */ int lastexec = 0; /* last exec command */ int contexts['z'-'`'+1]; /* Labels */ /* C O N S T A N T S */ bool adjcurr[PARA_BACK+1], adjendp[PARA_BACK+1]; /* A R G U M E N T S */ char startcmd[80] = ""; /* initial command after read */ char **argv; /* Arguments */ int argc=0, /* # arguments */ pc=0; /* Index into arguments */ #if 0 struct stat thisfile; /* status on current file, for writeout... */ #endif /* M A C R O S T U F F */ struct macrecord mbuffer[MAXMACROS]; struct tmacro mcr[NMACROS]; /* A place for executing macros */ /* S E A R C H S T U F F */ char dst[80] = "", /* last replacement pattern */ lastpatt[80] = "", /* last search pattern */ pattern[MAXPAT] = ""; /* encoded last pattern */ int RE_start[9], /* start of substitution arguments */ RE_size [9], /* size of substitution arguments */ lastp; /* end of last pattern */ struct undostack undo; /* To undo a command */ /* R A N D O M S T R I N G S */ char instring[200], /* Latest input */ filenm[80] = "", /* Filename */ altnm[80] = ""; /* Alternate filename */ char gcb[16]; /* Command buffer for mutations of insert */ char undobuf[40]; char undotmp[40]; char yankbuf[40]; HANDLE uread, /* reading from the undo stack */ uwrite; /* writing to the undo stack */ /* B U F F E R S */ char rcb[256]; /* last modification command */ char *rcp; /* this points at the end of the redo */ char core[SIZE+1]; /* data space */ struct ybuf yank; /* last deleted/yanked text */ /* STATIC INITIALIZATIONS: */ /* ttydef stuff */ #if OS_ATARI | USE_TERMCAP int LINES, COLS; #endif #if TTY_ZTERM char *TERMNAME = "zterm", *HO = "\001", /* goto top of screen */ *UP = "\002", /* move up 1 line? */ *CE = "\003", /* clear to end of line */ *CL = "\004", /* clearscreen */ *OL = "\005", /* open current line down */ *UpS = "\006", /* scroll up 1 line */ *BELL= "\007", /* ring the bell */ *CM = "yes", /* cursor movement exists */ *CURoff, *CURon; #endif /*ZTERM*/ #if TTY_ANSI #if OS_DOS char *TERMNAME = "braindamaged ansi", #else char *TERMNAME = "hardwired ansi", #endif *HO = "\033[H", *UP = "\033[A", *CE = "\033[K", *CL = "\033[H\033[J", #if OS_DOS *OL = NULL, *UpS = NULL, #else *OL = "\033[L", *UpS = "\033[L", #endif *BELL= "\007", *CM = "\033[%d;%dH", *CURoff, *CURon; #endif /*TTY_ANSI*/ #if TTY_VT52 #if OS_ATARI char *TERMNAME = "Atari ST", #else #if OS_FLEXOS char *TERMNAME = "Flexos console", #else char *TERMNAME = "hardwired vt52", #endif /*OS_FLEXOS*/ #endif /*OS_ATARI*/ *HO = "\033H", *UP = "\033A", *CE = "\033K", *CL = "\033E", *OL = "\033L", *BELL= "\007", *CM = "\033Y??", #if OS_FLEXOS *UpS = NULL, /* Reverse scrolling is painfully slow */ #else *UpS = "\033I", #endif *CURoff= "\033f", *CURon = "\033e"; #endif /*TTY_VT52*/ #if USE_TERMCAP bool CA, canUPSCROLL; char FkL, CurRT, CurLT, CurUP, CurDN; char *TERMNAME, /* will be set in termcap handling */ *HO, *UP, *CE, *CL, *OL, *BELL, *CM, *UpS, *CURoff, *CURon; #endif /*USE_TERMCAP*/ char Erasechar = ERASE, /* our erase character */ eraseline = 'X'-'@'; /* and line-kill character */ char fismod[] = "File is modified", /* File is modified message */ fisro[] = "File is readonly"; /* when you can't write the file */ char *excmds[] = { "print", /* lines to screen */ "quit", /* quit editor */ "read", /* add file to buffer */ "edit", /* replace buffer with file */ "write", /* write out file */ "wq", /* write file and quit */ "next", /* make new arglist or traverse this one */ "substitute", /* pattern */ "xit", /* write changes and quit */ "file", /* show/set file name */ "set", /* options */ "rm", /* a file */ "previous", /* back up in arglist */ "delete", /* lines from buffer */ "=", /* tell line number */ "yank", /* lines from buffer */ "put", /* back yanked lines */ "visual", /* go to visual mode */ "exec", /* go to exec mode */ "insert", /* text below current line */ "open", /* insert text above current line */ "change", /* lines */ "undo", /* last change */ "!", /* shell escape */ "map", /* keyboard macro */ "unmap", /* keyboard macro */ "source", /* read commands from file */ "version", /* print version # */ "args", /* print argument list */ "rewind", /* rewind argument list */ NULL }; char wordset[] = "0123456789$_#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; char spaces[] = { TAB,EOL,' ',0 }; int shiftwidth = 4, #if USE_TERMCAP | OS_ATARI dofscroll, #else dofscroll = LINES/2, #endif tabsize = 8; int autoindent = YES, autocopy = NO, autowrite = YES, wrapscan = YES, overwrite = YES, beautify = YES, list = NO, magic = YES, bell = YES, #if OS_ATARI mapslash, #endif ignorecase = NO; struct variable vars[]={ {"terminal", "", VSTR, V_CONST, (void*)&TERMNAME }, {"shiftwidth","sw", VINT, 0, (void*)&shiftwidth }, {"scroll", "", VINT, 0, (void*)&dofscroll }, {"tabsize", "ts", VINT, V_DISPLAY, (void*)&tabsize }, {"autoindent","ai", VBOOL, 0, (void*)&autoindent }, {"autocopy", "ac", VBOOL, 0, (void*)&autocopy }, {"autowrite", "aw", VBOOL, 0, (void*)&autowrite }, {"wrapscan", "ws", VBOOL, 0, (void*)&wrapscan }, {"overwrite", "ow", VBOOL, 0, (void*)&overwrite }, {"beautify", "be", VBOOL, 0, (void*)&beautify }, {"list", "", VBOOL, V_DISPLAY, (void*)&list }, {"magic", "", VBOOL, 0, (void*)&magic }, {"ignorecase","ic", VBOOL, 0, (void*)&ignorecase }, {"bell", "", VBOOL, 0, (void*)&bell }, #if OS_ATARI {"mapslash", "ms", VBOOL, 0, (void*)&mapslash }, #endif {NULL} }; /* For movement routines */ int setstep[2] = {-1,1}; /* Where the last diddling left us */ struct coord curpos={0, 0}; /* initialize the buffer */ int bufmax = 0, /* End of file here */ lstart = 0, lend = 0, /* Start & end of current line */ ptop = 0, pend = 0, /* Top & bottom of CRT window */ curr = 0, /* Global cursor pos */ xp = 0, yp = 0, /* Cursor window position */ count = 0; /* Latest count */ bool modified= NO, /* File has been modified */ readonly= NO, /* is this file readonly? */ needchar= YES, /* Peekc flag */ deranged= NO, /* Up-arrow || down-arrow left xpos in Oz. */ indirect= NO, /* Reading from an indirect file?? */ redoing = NO, /* doing a redo? */ xerox = NO, /* making a redo buffer? */ newfile = YES, /* Editing a new file? */ newline = NO, /* Last insert/delete included a EOL */ lineonly= NO, /* Dumb terminal? */ zotscreen=NO, /* ask for [more] in execmode */ diddled = NO; /* force new window in editcore */ int macro = -1; /* Index into MCR */ char lsearch = 0; /* for N and n'ing... */ /* movement, command codes */ cmdtype movemap[256]={ /*^@*/ BAD_COMMAND, /*^A*/ DEBUG_C, /*^B*/ HARDMACRO, /*^C*/ BAD_COMMAND, /*^D*/ WINDOW_UP, /*^E*/ HARDMACRO, /*^F*/ HARDMACRO, /*^G*/ FILE_C, /*^H*/ GO_LEFT, /* also leftarrow */ /*^I*/ REDRAW_C, /*^J*/ GO_DOWN, /* also downarrow */ /*^K*/ GO_UP, /* also uparrow */ /*^L*/ GO_RIGHT, /* also rightarrow */ /*^M*/ CR_FWD, /*^N*/ BAD_COMMAND, /*^O*/ BAD_COMMAND, /*^P*/ BAD_COMMAND, /*^Q*/ BAD_COMMAND, /*^R*/ BAD_COMMAND, /*^S*/ BAD_COMMAND, /*^T*/ BAD_COMMAND, /*^U*/ WINDOW_DOWN, /*^V*/ BAD_COMMAND, /*^W*/ BAD_COMMAND, /*^X*/ BAD_COMMAND, /*^Y*/ HARDMACRO, /*^Z*/ BAD_COMMAND, /*^[*/ BAD_COMMAND, /*^\*/ BAD_COMMAND, /*^]*/ BAD_COMMAND, /*^^*/ BAD_COMMAND, /*^_*/ BAD_COMMAND, /* */ GO_RIGHT, /*! */ EXEC_C, /*" */ BAD_COMMAND, /*# */ BAD_COMMAND, /*$ */ TO_EOL, /*% */ MATCHEXPR, /*& */ RESUBST_C, /*\ */ TO_MARK_LINE, /*( */ SENT_BACK, /*) */ SENT_FWD, /** */ BAD_COMMAND, /*+ */ CR_FWD, /*, */ BAD_COMMAND, /*- */ CR_BACK, /*. */ REDO_C, /*/ */ PATT_FWD, /*0 */ TO_COL, /*1 */ BAD_COMMAND, /*2 */ BAD_COMMAND, /*3 */ BAD_COMMAND, /*4 */ BAD_COMMAND, /*5 */ BAD_COMMAND, /*6 */ BAD_COMMAND, /*7 */ BAD_COMMAND, /*8 */ BAD_COMMAND, /*9 */ BAD_COMMAND, /*: */ COLIN_C, /*; */ BAD_COMMAND, /*< */ ADJUST_C, /*= */ BAD_COMMAND, /*> */ ADJUST_C, /*? */ PATT_BACK, /*@ */ BAD_COMMAND, /*A */ A_AT_END, /*B */ BACK_WD, /*C */ HARDMACRO, /*D */ HARDMACRO, /*E */ BAD_COMMAND, /*F */ BACK_CHAR, /*G */ GLOBAL_LINE, /*H */ PAGE_BEGIN, /*I */ I_AT_NONWHITE, /*J */ JOIN_C, /*K */ BAD_COMMAND, /*L */ PAGE_END, /*M */ PAGE_MIDDLE, /*N */ BSEARCH, /*O */ OPENUP_C, /*P */ PUT_AFTER, /*Q */ EDIT_C, /*R */ BIG_REPL_C, /*S */ BAD_COMMAND, /*T */ BACKTO_CHAR, /*U */ BAD_COMMAND, /*V */ BAD_COMMAND, /*W */ FORWD, /*X */ HARDMACRO, /*Y */ HARDMACRO, /*Z */ ZZ_C, /*[ */ BAD_COMMAND, /*\ */ BAD_COMMAND, /*] */ BAD_COMMAND, /*^ */ NOTWHITE, /*_ */ BAD_COMMAND, /*` */ TO_MARK, /*a */ APPEND_C, /*b */ BACK_WD, /*c */ CHANGE_C, /*d */ DELETE_C, /*e */ FORWD, /*f */ TO_CHAR, /*g */ BAD_COMMAND, /*h */ GO_LEFT, /*i */ INSERT_C, /*j */ GO_DOWN, /*k */ GO_UP, /*l */ GO_RIGHT, /*m */ MARKER_C, /*n */ FSEARCH, /*o */ OPEN_C, /*p */ PUT_BEFORE, /*q */ BAD_COMMAND, /*r */ REPLACE_C, /*s */ HARDMACRO, /*t */ UPTO_CHAR, /*u */ UNDO_C, /*v */ BTO_WD, /*w */ TO_WD, /*x */ HARDMACRO, /*y */ YANK_C, /*z */ REWINDOW, /*{ */ PARA_BACK, /*| */ TO_COL, /*} */ PARA_FWD, /*~ */ TWIDDLE_C, /*^?*/ BAD_COMMAND, /*80*/ BAD_COMMAND, /*81*/ BAD_COMMAND, /*82*/ BAD_COMMAND, /*83*/ BAD_COMMAND, /*84*/ BAD_COMMAND, /*85*/ BAD_COMMAND, /*x6*/ BAD_COMMAND, /*x7*/ BAD_COMMAND, /*x8*/ BAD_COMMAND, /*x9*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND, /*xx*/ BAD_COMMAND };