548 lines
14 KiB
C
548 lines
14 KiB
C
/*
|
|
* 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
|
|
};
|