Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!cmcl2!nrl-cmf!ames!necntc!ncoast!allbery From: nwd@j.cc.purdue.edu (Daniel Lawrence) Newsgroups: comp.sources.misc Subject: MicroEmacs 3.9 (Part 8 of 16) Message-ID: <5655@ncoast.UUCP> Date: Sat, 14-Nov-87 16:11:14 EST Article-I.D.: ncoast.5655 Posted: Sat Nov 14 16:11:14 1987 Date-Received: Tue, 17-Nov-87 03:12:22 EST Sender: allbery@ncoast.UUCP Lines: 2450 Approved: allbery@ncoast.UUCP X-Archive: comp.sources.misc/microemacs-3.9/7 # This is a shar archive. # Remove everything above this line. # Run the file through sh, not csh. # (type `sh mes.8') # If you do not see the message # `mes.8 completed!' # then the file was incomplete. echo extracting - line.c sed 's/^X//' > line.c << 'FRIDAY_NIGHT' X/* X * The functions in this file are a general set of line management utilities. X * They are the only routines that touch the text. They also touch the buffer X * and window structures, to make sure that the necessary updating gets done. X * There are routines in this file that handle the kill buffer too. It isn't X * here for any good reason. X * X * Note that this code only updates the dot and mark values in the window list. X * Since all the code acts on the current window, the buffer that we are X * editing must be being displayed, which means that "b_nwnd" is non zero, X * which means that the dot and mark values in the buffer headers are nonsense. X */ X X#include X#include "estruct.h" X#include "edef.h" X XKILL *ykbuf; /* ptr to current kill buffer chunk being yanked */ Xint ykboff; /* offset into that chunk */ X X/* X * This routine allocates a block of memory large enough to hold a LINE X * containing "used" characters. The block is always rounded up a bit. Return X * a pointer to the new block, or NULL if there isn't any memory left. Print a X * message in the message line if no space. X */ XLINE *lalloc(used) X Xregister int used; X X{ X register LINE *lp; X register int size; X char *malloc(); X X size = (used+NBLOCK-1) & ~(NBLOCK-1); X if (size == 0) /* Assume that an empty */ X size = NBLOCK; /* line is for type-in. */ X if ((lp = (LINE *) malloc(sizeof(LINE)+size)) == NULL) { X mlwrite("[OUT OF MEMORY]"); X return (NULL); X } X lp->l_size = size; X lp->l_used = used; X return (lp); X} X X/* X * Delete line "lp". Fix all of the links that might point at it (they are X * moved to offset 0 of the next line. Unlink the line from whatever buffer it X * might be in. Release the memory. The buffers are updated too; the magic X * conditions described in the above comments don't hold here. X */ Xlfree(lp) Xregister LINE *lp; X{ X register BUFFER *bp; X register WINDOW *wp; X X wp = wheadp; X while (wp != NULL) { X if (wp->w_linep == lp) X wp->w_linep = lp->l_fp; X if (wp->w_dotp == lp) { X wp->w_dotp = lp->l_fp; X wp->w_doto = 0; X } X if (wp->w_markp == lp) { X wp->w_markp = lp->l_fp; X wp->w_marko = 0; X } X wp = wp->w_wndp; X } X bp = bheadp; X while (bp != NULL) { X if (bp->b_nwnd == 0) { X if (bp->b_dotp == lp) { X bp->b_dotp = lp->l_fp; X bp->b_doto = 0; X } X if (bp->b_markp == lp) { X bp->b_markp = lp->l_fp; X bp->b_marko = 0; X } X } X bp = bp->b_bufp; X } X lp->l_bp->l_fp = lp->l_fp; X lp->l_fp->l_bp = lp->l_bp; X free((char *) lp); X} X X/* X * This routine gets called when a character is changed in place in the current X * buffer. It updates all of the required flags in the buffer and window X * system. The flag used is passed as an argument; if the buffer is being X * displayed in more than 1 window we change EDIT t HARD. Set MODE if the X * mode line needs to be updated (the "*" has to be set). X */ Xlchange(flag) Xregister int flag; X{ X register WINDOW *wp; X X if (curbp->b_nwnd != 1) /* Ensure hard. */ X flag = WFHARD; X if ((curbp->b_flag&BFCHG) == 0) { /* First change, so */ X flag |= WFMODE; /* update mode lines. */ X curbp->b_flag |= BFCHG; X } X wp = wheadp; X while (wp != NULL) { X if (wp->w_bufp == curbp) X wp->w_flag |= flag; X wp = wp->w_wndp; X } X} X Xinsspace(f, n) /* insert spaces forward into text */ X Xint f, n; /* default flag and numeric argument */ X X{ X linsert(n, ' '); X backchar(f, n); X} X X/* X * linstr -- Insert a string at the current point X */ X Xlinstr(instr) Xchar *instr; X{ X register int status = TRUE; X char tmpc; X X if (instr != NULL) X while ((tmpc = *instr) && status == TRUE) { X status = (tmpc == '\n'? lnewline(): linsert(1, tmpc)); X X /* Insertion error? */ X if (status != TRUE) { X mlwrite("%%Out of memory while inserting"); X break; X } X instr++; X } X return(status); X} X X/* X * Insert "n" copies of the character "c" at the current location of dot. In X * the easy case all that happens is the text is stored in the line. In the X * hard case, the line has to be reallocated. When the window list is updated, X * take special care; I screwed it up once. You always update dot in the X * current window. You update mark, and a dot in another window, if it is X * greater than the place where you did the insert. Return TRUE if all is X * well, and FALSE on errors. X */ X Xlinsert(n, c) X{ X register char *cp1; X register char *cp2; X register LINE *lp1; X register LINE *lp2; X register LINE *lp3; X register int doto; X register int i; X register WINDOW *wp; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X lchange(WFEDIT); X lp1 = curwp->w_dotp; /* Current line */ X if (lp1 == curbp->b_linep) { /* At the end: special */ X if (curwp->w_doto != 0) { X mlwrite("bug: linsert"); X return (FALSE); X } X if ((lp2=lalloc(n)) == NULL) /* Allocate new line */ X return (FALSE); X lp3 = lp1->l_bp; /* Previous line */ X lp3->l_fp = lp2; /* Link in */ X lp2->l_fp = lp1; X lp1->l_bp = lp2; X lp2->l_bp = lp3; X for (i=0; il_text[i] = c; X curwp->w_dotp = lp2; X curwp->w_doto = n; X return (TRUE); X } X doto = curwp->w_doto; /* Save for later. */ X if (lp1->l_used+n > lp1->l_size) { /* Hard: reallocate */ X if ((lp2=lalloc(lp1->l_used+n)) == NULL) X return (FALSE); X cp1 = &lp1->l_text[0]; X cp2 = &lp2->l_text[0]; X while (cp1 != &lp1->l_text[doto]) X *cp2++ = *cp1++; X cp2 += n; X while (cp1 != &lp1->l_text[lp1->l_used]) X *cp2++ = *cp1++; X lp1->l_bp->l_fp = lp2; X lp2->l_fp = lp1->l_fp; X lp1->l_fp->l_bp = lp2; X lp2->l_bp = lp1->l_bp; X free((char *) lp1); X } else { /* Easy: in place */ X lp2 = lp1; /* Pretend new line */ X lp2->l_used += n; X cp2 = &lp1->l_text[lp1->l_used]; X cp1 = cp2-n; X while (cp1 != &lp1->l_text[doto]) X *--cp2 = *--cp1; X } X for (i=0; il_text[doto+i] = c; X wp = wheadp; /* Update windows */ X while (wp != NULL) { X if (wp->w_linep == lp1) X wp->w_linep = lp2; X if (wp->w_dotp == lp1) { X wp->w_dotp = lp2; X if (wp==curwp || wp->w_doto>doto) X wp->w_doto += n; X } X if (wp->w_markp == lp1) { X wp->w_markp = lp2; X if (wp->w_marko > doto) X wp->w_marko += n; X } X wp = wp->w_wndp; X } X return (TRUE); X} X X/* X * Overwrite a character into the current line at the current position X * X */ X Xlowrite(c) X Xchar c; /* character to overwrite on current position */ X X{ X if (curwp->w_doto < curwp->w_dotp->l_used && X (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' || X (curwp->w_doto) % 8 == 7)) X ldelete(1L, FALSE); X return(linsert(1, c)); X} X X/* X * lover -- Overwrite a string at the current point X */ X Xlover(ostr) X Xchar *ostr; X X{ X register int status = TRUE; X char tmpc; X X if (ostr != NULL) X while ((tmpc = *ostr) && status == TRUE) { X status = (tmpc == '\n'? lnewline(): lowrite(tmpc)); X X /* Insertion error? */ X if (status != TRUE) { X mlwrite("%%Out of memory while overwriting"); X break; X } X ostr++; X } X return(status); X} X X/* X * Insert a newline into the buffer at the current location of dot in the X * current window. The funny ass-backwards way it does things is not a botch; X * it just makes the last line in the file not a special case. Return TRUE if X * everything works out and FALSE on error (memory allocation failure). The X * update of dot and mark is a bit easier then in the above case, because the X * split forces more updating. X */ Xlnewline() X{ X register char *cp1; X register char *cp2; X register LINE *lp1; X register LINE *lp2; X register int doto; X register WINDOW *wp; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X lchange(WFHARD); X lp1 = curwp->w_dotp; /* Get the address and */ X doto = curwp->w_doto; /* offset of "." */ X if ((lp2=lalloc(doto)) == NULL) /* New first half line */ X return (FALSE); X cp1 = &lp1->l_text[0]; /* Shuffle text around */ X cp2 = &lp2->l_text[0]; X while (cp1 != &lp1->l_text[doto]) X *cp2++ = *cp1++; X cp2 = &lp1->l_text[0]; X while (cp1 != &lp1->l_text[lp1->l_used]) X *cp2++ = *cp1++; X lp1->l_used -= doto; X lp2->l_bp = lp1->l_bp; X lp1->l_bp = lp2; X lp2->l_bp->l_fp = lp2; X lp2->l_fp = lp1; X wp = wheadp; /* Windows */ X while (wp != NULL) { X if (wp->w_linep == lp1) X wp->w_linep = lp2; X if (wp->w_dotp == lp1) { X if (wp->w_doto < doto) X wp->w_dotp = lp2; X else X wp->w_doto -= doto; X } X if (wp->w_markp == lp1) { X if (wp->w_marko < doto) X wp->w_markp = lp2; X else X wp->w_marko -= doto; X } X wp = wp->w_wndp; X } X return (TRUE); X} X X/* X * This function deletes "n" bytes, starting at dot. It understands how do deal X * with end of lines, etc. It returns TRUE if all of the characters were X * deleted, and FALSE if they were not (because dot ran into the end of the X * buffer. The "kflag" is TRUE if the text should be put in the kill buffer. X */ Xldelete(n, kflag) X Xlong n; /* # of chars to delete */ Xint kflag; /* put killed text in kill buffer flag */ X X{ X register char *cp1; X register char *cp2; X register LINE *dotp; X register int doto; X register int chunk; X register WINDOW *wp; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X while (n != 0) { X dotp = curwp->w_dotp; X doto = curwp->w_doto; X if (dotp == curbp->b_linep) /* Hit end of buffer. */ X return (FALSE); X chunk = dotp->l_used-doto; /* Size of chunk. */ X if (chunk > n) X chunk = n; X if (chunk == 0) { /* End of line, merge. */ X lchange(WFHARD); X if (ldelnewline() == FALSE X || (kflag!=FALSE && kinsert('\n')==FALSE)) X return (FALSE); X --n; X continue; X } X lchange(WFEDIT); X cp1 = &dotp->l_text[doto]; /* Scrunch text. */ X cp2 = cp1 + chunk; X if (kflag != FALSE) { /* Kill? */ X while (cp1 != cp2) { X if (kinsert(*cp1) == FALSE) X return (FALSE); X ++cp1; X } X cp1 = &dotp->l_text[doto]; X } X while (cp2 != &dotp->l_text[dotp->l_used]) X *cp1++ = *cp2++; X dotp->l_used -= chunk; X wp = wheadp; /* Fix windows */ X while (wp != NULL) { X if (wp->w_dotp==dotp && wp->w_doto>=doto) { X wp->w_doto -= chunk; X if (wp->w_doto < doto) X wp->w_doto = doto; X } X if (wp->w_markp==dotp && wp->w_marko>=doto) { X wp->w_marko -= chunk; X if (wp->w_marko < doto) X wp->w_marko = doto; X } X wp = wp->w_wndp; X } X n -= chunk; X } X return (TRUE); X} X X/* getctext: grab and return a string with the text of X the current line X*/ X Xchar *getctext() X X{ X register LINE *lp; /* line to copy */ X register int size; /* length of line to return */ X register char *sp; /* string pointer into line */ X register char *dp; /* string pointer into returned line */ X char rline[NSTRING]; /* line to return */ X X /* find the contents of the current line and its length */ X lp = curwp->w_dotp; X sp = lp->l_text; X size = lp->l_used; X if (size >= NSTRING) X size = NSTRING - 1; X X /* copy it across */ X dp = rline; X while (size--) X *dp++ = *sp++; X *dp = 0; X return(rline); X} X X/* putctext: replace the current line with the passed in text */ X Xputctext(iline) X Xchar *iline; /* contents of new line */ X X{ X register int status; X X /* delete the current line */ X curwp->w_doto = 0; /* starting at the beginning of the line */ X if ((status = killtext(TRUE, 1)) != TRUE) X return(status); X X /* insert the new line */ X if ((status = linstr(iline)) != TRUE) X return(status); X status = lnewline(); X backline(TRUE, 1); X return(status); X} X X/* X * Delete a newline. Join the current line with the next line. If the next line X * is the magic header line always return TRUE; merging the last line with the X * header line can be thought of as always being a successful operation, even X * if nothing is done, and this makes the kill buffer work "right". Easy cases X * can be done by shuffling data around. Hard cases require that lines be moved X * about in memory. Return FALSE on error and TRUE if all looks ok. Called by X * "ldelete" only. X */ Xldelnewline() X{ X register char *cp1; X register char *cp2; X register LINE *lp1; X register LINE *lp2; X register LINE *lp3; X register WINDOW *wp; X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X lp1 = curwp->w_dotp; X lp2 = lp1->l_fp; X if (lp2 == curbp->b_linep) { /* At the buffer end. */ X if (lp1->l_used == 0) /* Blank line. */ X lfree(lp1); X return (TRUE); X } X if (lp2->l_used <= lp1->l_size-lp1->l_used) { X cp1 = &lp1->l_text[lp1->l_used]; X cp2 = &lp2->l_text[0]; X while (cp2 != &lp2->l_text[lp2->l_used]) X *cp1++ = *cp2++; X wp = wheadp; X while (wp != NULL) { X if (wp->w_linep == lp2) X wp->w_linep = lp1; X if (wp->w_dotp == lp2) { X wp->w_dotp = lp1; X wp->w_doto += lp1->l_used; X } X if (wp->w_markp == lp2) { X wp->w_markp = lp1; X wp->w_marko += lp1->l_used; X } X wp = wp->w_wndp; X } X lp1->l_used += lp2->l_used; X lp1->l_fp = lp2->l_fp; X lp2->l_fp->l_bp = lp1; X free((char *) lp2); X return (TRUE); X } X if ((lp3=lalloc(lp1->l_used+lp2->l_used)) == NULL) X return (FALSE); X cp1 = &lp1->l_text[0]; X cp2 = &lp3->l_text[0]; X while (cp1 != &lp1->l_text[lp1->l_used]) X *cp2++ = *cp1++; X cp1 = &lp2->l_text[0]; X while (cp1 != &lp2->l_text[lp2->l_used]) X *cp2++ = *cp1++; X lp1->l_bp->l_fp = lp3; X lp3->l_fp = lp2->l_fp; X lp2->l_fp->l_bp = lp3; X lp3->l_bp = lp1->l_bp; X wp = wheadp; X while (wp != NULL) { X if (wp->w_linep==lp1 || wp->w_linep==lp2) X wp->w_linep = lp3; X if (wp->w_dotp == lp1) X wp->w_dotp = lp3; X else if (wp->w_dotp == lp2) { X wp->w_dotp = lp3; X wp->w_doto += lp1->l_used; X } X if (wp->w_markp == lp1) X wp->w_markp = lp3; X else if (wp->w_markp == lp2) { X wp->w_markp = lp3; X wp->w_marko += lp1->l_used; X } X wp = wp->w_wndp; X } X free((char *) lp1); X free((char *) lp2); X return (TRUE); X} X X/* X * Delete all of the text saved in the kill buffer. Called by commands when a X * new kill context is being created. The kill buffer array is released, just X * in case the buffer has grown to immense size. No errors. X */ Xkdelete() X{ X KILL *kp; /* ptr to scan kill buffer chunk list */ X X if (kbufh != NULL) { X X /* first, delete all the chunks */ X kbufp = kbufh; X while (kbufp != NULL) { X kp = kbufp->d_next; X free(kbufp); X kbufp = kp; X } X X /* and reset all the kill buffer pointers */ X kbufh = kbufp = NULL; X kused = KBLOCK; X } X} X X/* X * Insert a character to the kill buffer, allocating new chunks as needed. X * Return TRUE if all is well, and FALSE on errors. X */ X Xkinsert(c) X Xint c; /* character to insert in the kill buffer */ X X{ X KILL *nchunk; /* ptr to newly malloced chunk */ X X /* check to see if we need a new chunk */ X if (kused >= KBLOCK) { X if ((nchunk = (KILL *)malloc(sizeof(KILL))) == NULL) X return(FALSE); X if (kbufh == NULL) /* set head ptr if first time */ X kbufh = nchunk; X if (kbufp != NULL) /* point the current to this new one */ X kbufp->d_next = nchunk; X kbufp = nchunk; X kbufp->d_next = NULL; X kused = 0; X } X X /* and now insert the character */ X kbufp->d_chunk[kused++] = c; X return(TRUE); X} X X/* X * Yank text back from the kill buffer. This is really easy. All of the work X * is done by the standard insert routines. All you do is run the loop, and X * check for errors. Bound to "C-Y". X */ Xyank(f, n) X{ X register int c; X register int i; X register char *sp; /* pointer into string to insert */ X KILL *kp; /* pointer into kill buffer */ X X if (curbp->b_mode&MDVIEW) /* don't allow this command if */ X return(rdonly()); /* we are in read only mode */ X if (n < 0) X return (FALSE); X /* make sure there is something to yank */ X if (kbufh == NULL) X return(TRUE); /* not an error, just nothing */ X X /* for each time.... */ X while (n--) { X kp = kbufh; X while (kp != NULL) { X if (kp->d_next == NULL) X i = kused; X else X i = KBLOCK; X sp = kp->d_chunk; X while (i--) { X if ((c = *sp++) == '\n') { X if (lnewline() == FALSE) X return (FALSE); X } else { X if (linsert(1, c) == FALSE) X return (FALSE); X } X } X kp = kp->d_next; X } X } X return (TRUE); X} FRIDAY_NIGHT echo extracting - lock.c sed 's/^X//' > lock.c << 'FRIDAY_NIGHT' X/* LOCK: File locking command routines for MicroEMACS X written by Daniel Lawrence X */ X X#include X#include "estruct.h" X#include "edef.h" X X#if FILOCK X#if BSD X#include X Xextern int sys_nerr; /* number of system error messages defined */ Xextern char *sys_errlist[]; /* list of message texts */ Xextern int errno; /* current error */ X Xchar *lname[NLOCKS]; /* names of all locked files */ Xint numlocks; /* # of current locks active */ X X/* lockchk: check a file for locking and add it to the list */ X Xlockchk(fname) X Xchar *fname; /* file to check for a lock */ X X{ X register int i; /* loop indexes */ X register int status; /* return status */ X char *undolock(); X X /* check to see if that file is already locked here */ X if (numlocks > 0) X for (i=0; i < numlocks; ++i) X if (strcmp(fname, lname[i]) == 0) X return(TRUE); X X /* if we have a full locking table, bitch and leave */ X if (numlocks == NLOCKS) { X mlwrite("LOCK ERROR: Lock table full"); X return(ABORT); X } X X /* next, try to lock it */ X status = lock(fname); X if (status == ABORT) /* file is locked, no override */ X return(ABORT); X if (status == FALSE) /* locked, overriden, dont add to table */ X return(TRUE); X X /* we have now locked it, add it to our table */ X lname[++numlocks - 1] = (char *)malloc(strlen(fname) + 1); X if (lname[numlocks - 1] == NULL) { /* malloc failure */ X undolock(fname); /* free the lock */ X mlwrite("Cannot lock, out of memory"); X --numlocks; X return(ABORT); X } X X /* everthing is cool, add it to the table */ X strcpy(lname[numlocks-1], fname); X return(TRUE); X} X X/* lockrel: release all the file locks so others may edit */ X Xlockrel() X X{ X register int i; /* loop index */ X register int status; /* status of locks */ X register int s; /* status of one unlock */ X X status = TRUE; X if (numlocks > 0) X for (i=0; i < numlocks; ++i) { X if ((s = unlock(lname[i])) != TRUE) X status = s; X free(lname[i]); X } X numlocks = 0; X return(status); X} X X/* lock: Check and lock a file from access by others X returns TRUE = files was not locked and now is X FALSE = file was locked and overridden X ABORT = file was locked, abort command X*/ X Xlock(fname) X Xchar *fname; /* file name to lock */ X X{ X register char *locker; /* lock error message */ X register int status; /* return status */ X char msg[NSTRING]; /* message string */ X char *dolock(); X X /* attempt to lock the file */ X locker = dolock(fname); X if (locker == NULL) /* we win */ X return(TRUE); X X /* file failed...abort */ X if (strncmp(locker, "LOCK", 4) == 0) { X lckerror(locker); X return(ABORT); X } X X /* someone else has it....override? */ X strcpy(msg, "File in use by "); X strcat(msg, locker); X strcat(msg, ", overide?"); X status = mlyesno(msg); /* ask them */ X if (status == TRUE) X return(FALSE); X else X return(ABORT); X} X X/* unlock: Unlock a file X this only warns the user if it fails X */ X Xunlock(fname) X Xchar *fname; /* file to unlock */ X X{ X register char *locker; /* undolock return string */ X char *undolock(); X X /* unclock and return */ X locker = undolock(fname); X if (locker == NULL) X return(TRUE); X X /* report the error and come back */ X lckerror(locker); X return(FALSE); X} X Xlckerror(errstr) /* report a lock error */ X Xchar *errstr; /* lock error string to print out */ X X{ X char obuf[NSTRING]; /* output buffer for error message */ X X strcpy(obuf, errstr); X strcat(obuf, " - "); X if (errno < sys_nerr) X strcat(obuf, sys_errlist[errno]); X else X strcat(obuf, "[can not get system error message]"); X mlwrite(obuf); X} X#endif X#else Xlckhello() /* dummy function */ X{ X} X#endif FRIDAY_NIGHT echo extracting - main.c sed 's/^X//' > main.c << 'FRIDAY_NIGHT' X/* X * MicroEMACS 3.9 X * written by Dave G. Conroy. X * substatially modified by Daniel M. Lawrence X * X * (C)opyright 1987 by Daniel M. Lawrence X * MicroEMACS 3.9 can be copied and distributed freely for any X * non-commercial purposes. MicroEMACS 3.9 can only be incorporated X * into commercial software with the permission of the current author. X * X * This file contains the main driving routine, and some keyboard processing X * code, for the MicroEMACS screen editor. X * X * REVISION HISTORY: X * X * 1.0 Steve Wilhite, 30-Nov-85 X * - Removed the old LK201 and VT100 logic. Added code to support the X * DEC Rainbow keyboard (which is a LK201 layout) using the the Level X * 1 Console In ROM INT. See "rainbow.h" for the function key defs X * Steve Wilhite, 1-Dec-85 X * - massive cleanup on code in display.c and search.c X * X * 2.0 George Jones, 12-Dec-85 X * - Ported to Amiga. X * X * 3.0 Daniel Lawrence, 29-Dec-85 X * - rebound keys/added new fast buffered I/O for AMIGA X * - added META- repeat commands X * - added reposition default to center screen (yeah!) X * - changed exit with modified buffers message X * - made filesave tell us what it is doing X * - changed search string entry to terminate with X * so we can use in search/replace strings X * - updated version number in mode line to 3.0 X * 12-Jan-86 X * - Added code to reconize the search/replace functions X * - Added code to perform search/replace & query functions X * 14-Jan-86 X * - moved search logic to separate function in search.c X * - added replace and query replace functions X * - separated out control key expansions to be used by others in search.c X * 15-Jan-86 X * - changed "visiting" to finding X * - changed yes/no responses to not need return X * - cleaned up various messages X * 16-jan-86 X * - fixed spurious spawn message in MSDOS X * - added ^X-S synonym to save command X * - moved escape to shell to ^X-C X * 21-jan-86 X * - added code to suspend shell under BSD X * 22-jan-86 X * - added function key support (SPEC) under MSDOS X * - Abort now prints [Aborted] on message line X * 23-jan-86 X * - Added modes and commands to set/unset them X * 24-jan-86 X * - Added Goto Line command X * - added Rename Buffer command X * 28-jan-86 X * - added goto beginning and end of paragraph commands (META-P/META-N) X * - re-wrote kdelete to use realloc. Gained MUCH speed here when X * doing large wipes on both UNIX and MSDOS. Changed kill buffer X * allocation block size from 256 bytes to 1 k X * 29-jan-86 X * - moved extern function declarations to efunc.h X * - made name[] name binding table X * 30-jan-86 X * - fixed Previous/Next paragraph command not to wrap around EOF X * - added Fill Paragraph command (META-Q) X * 4-feb-86 X * - added code to properly display long lines, scrolling them right X * to left X * 5-feb-85 X * - rewrote code to right/left scroll...much better X * - added shifted arrow keys on IBMPC X * 6-feb-85 X * - add option to allow forward-word to jump to beginning of X * next word instead of end of current one. This is different from X * other emacs' but can be configured off in estruct.h X * - added VIEW mode to allow a buffer to be read only X * (-v switch on command line will activate this) X * - changed quick exit to write out ALL changed buffers!!! X * MAKE SURE YOU KNOW THIS WHEN META-Zing X * 10-feb-86 X * - added handling of lines longer than allowed on file read in X * (they wrap on additional lines) X * - made having space clear the message line and NOT insert itself X * a configuration option in ed.h X * 11-feb-86 X * - added Describe-command and Help commands. X * 13-feb-86 X * - added View file command (^X ^V) and finished HELP command X * 14-feb-86 X * - added option to let main loop skip update if type ahead commands X * are queued up X * 16-feb-86 X * - added Insert File command X * 17-feb-86 X * - added scroll next window up/down commands X * 18-feb-86 X * - added CMODE indentation X * - re-arranged header files to standardize extern and global X * definitions X * - changed version number to 3.2 X * - added numeric arguments to search, reverse search and X * search and replace X * 24-feb-86 X * - added Bind To Key function (^C for now) to allow the user X * to change his command keys X * - added Unbind key function (M-^C for now) X * - added execute named command to execute unbound commands (M-X) X * - added describe bindings command (not bound) X * - changed version number to 3.3 X * 25-feb-86 X * - scrapped CERROR mode (too many compilers) X * - added EXACT mode for case sensitive searchers X * 26-feb-86 X * - added command completion on execute named command and X * all routined grabbing a command name X * - adding execute-command-line command and its support functions X * (in preparation for sourcing files) X * - added Execute Buffer command X * 27-feb-86 X * - added execute(source) file command and added code to automatically X * execute emacs.rc (or .emacsrc on UNIX) before initial read in X * - changed version number to 3.4 X * 4-mar-86 X * - changed word delete to be consistant with word move (it gets X * rid of the inter word space now) This is configurable with the X * NFWORD symbol in estruct.h X * - added B_ACTIVE entry to the buffer table. Let emacs read multiple X * file names from the command line and only read them in as needed X * 5-mar-85 X * - rewrote command line parser to get rid of my patchy code X * - changed version number to 3.5 X * 1-apr-86 X * - added support for Aztec C 3.20e under MSDOS X * - fixed bug in mlwrite on ADM3's and their ilk under V7 X * - added insertion of pounds in column one under CMODE X * - changed version number to 3.6 X * 3-apr-86 X * - added next-buffer command (^X-X) X * 5-apr-86 X * - added kill paragraph command (M-^W) X * - changed fill-paragraph to leave 2 spaces after a period at the X * end of a word. X * - added OVERWRITE mode X * 7-apr-86 X * - fixed overwrite mode to handle tabs X * 8-apr-86 X * - added add/delete global mode (M & ^M) commands X * 9-apr-86 X * - added insert space command X * - moved bindings around ^C insert space X * M-K bind-to-key X * INSERT insert space X * DELETE forwdel X * - added hunt forward and hunt reverse commands X * 10-apr-86 X * - fixed bug in DOBUF with non-terminated command string X * 15-apr-86 X * - fixed tab expansion bug in DISPLAY which hung the AMIGA X * (sent in by Dawn Banks) X * - fixed curcol problen if forwline/backline during keyboard X * macro execution (sent in by Ernst Christen) X * - added AMIGA function/cursor key support X * - fixed nonterminating replacement bug X * - fixed word wrapping problems X * 16-apr-86 X * - updated documentation and froze development for 3.6 net release X * 23-apr-86 version 3.6a X * - added foreground and background colors. Setable with the X * add mode commands for the moment X * 24-apr-86 X * - added command to pipe CLI output to a buffer X * 25-apr-86 X * - added Dana Hoggatt's code to replace Lattice's sick system() X * function. Now we no longer care what the switchar is. X * - cleaned up the positioning on several of the spawing commands X * 26-apr-86 X * - added an output flush in vttidy(). Unix really appreciates this. X * - added filter-buffer (^X#) command to send a buffer through X * a DOS filter X * - made automatic CMODE on .c and .h file compilation dependant X * in estruct.h X * 1-may-86 X * - optimized some code in update(). It certainly need a lot more. X * - added Aztec profiling capabilities. These are conditional on X * the APROF symbol in estruct.h X * 2-may-86 X * - added (u)ndo command in query-replace. undoes last repalce. X * 6-may-86 X * - re-organized and wrote the update() function in display.c X * Now my color hacks are in the right places and the code can be X * understood. X * [Released version 3.6f for BETA test sites] X * 8-may-86 X * - fixed bug in new display routine to wrap cursor on extended X * lines at the right time X * - modified the buffer-position command to give reasonable info X * 9-may-86 X * - improved the word wrap algorithm as not to discard non-space X * delimiters. The backscan now looks for white space rather than X * !inword(). X * [Released version 3.6g to Krannert] X * 10-may-86 X * - Added IBMPC.C an IBM-PC specific display driver. This makes paging X * 4-6 times faster. Also made some conditional changes to DISPLAY.C X * to eliminate the pscreen[] if using the PC driver. X * [changed version number to 3.6i] X * 12-may-86 X * - added delete-window (^X 0) command to dispose of a single window X * - fixed problem with multiple prefixes from a command line which X * was reported by John Gamble X * 14-may-86 X * - Added Aztec support for the IBMPC display driver. Had to X * readjust some includes and defines for this. X * - fixed bug in delete-window. X * - fixed some bizarre behavior with the cursor after coming back X * from spawn calls. X * [changed version number to 3.7 freezing development for net release] X * 15-may-86 X * - (that didn't last long...) Added execute-macro-(1 thru 20) commands X * to execute macro buffers (named "[Macro nn]") X * - changed BFTEMP to BFINVS and cleaned up treatment of invisible X * buffers. X * 16-may-86 X * - added store-macro (unbound) to store any executed command lines to X * macro buffer. X * - added clear-message-line (unbound) command to do just that X * - added resize-window command to change a window's size to the X * specified argument X * - improved help's logic not to re-read the file if it was already X * in a buffer X * - added MAGIC mode to all structures and command tables, but the X * regular expression code that John Gamble is writing is not ready. X * 18-may-86 X * - added interactive prompt requests in command line execution (i.e. X * while executing a macro, a parameter starting with an at sign (@) X * causes emacs to prompt with the rest of the parameter and return X * the resulting input as the value of the parameter). X * - added arguments to split-current-window to force the cursor into X * the upper or lower window. X * 20-may-86 X * - added support for the Microsoft C compiler as per the changes X * sent in by Oliver Sharp X * - made some upgrades and fixes for VMS sent in by Guy Streeter X * 21-may-86 X * - fixed an Aztec bug in ttgetc by clearing the upper byte X * - fixed buf in CMODE with #preprocesser input (bug fix submitted by X * Willis of unknown path) X * - added support of alternative startup file ( @ ) in X * the command line X * - added ^Q quoting in interactive input (mlreplyt()). X * - added re-binding of meta-prefix and ctlx-prefix X * 22-may-86 X * - reorganized getkey routines to make more sense and let prefix X * binding work properly. X * 23-may-86 X * - checked new code on BSD4.2 and made a few fixes X * - added optional fence matching while in CMODE X * - added goto and search command line arguments by Mike Spitzer X * 26-may-86 X * - added parameter fetching from buffers X * 27-may-86 X * - fixed some HP150 bugs...... X * 31-may-86 X * - Added Wang PC keyboard support from modifications by X * Sid Shapiro @ Wang Institute X * - Fixed some reverse video bugs with code submitted by Peter Chubb X * - Fixed bug in nextbuffer reported by Dave Forslund X * - added system V support (USG) from Linwood Varney X * 2-jun-86 X * - changed defines to just define one Unix define (for example, X * just define BSD for Unix BSD 4.2) X * - Added Incremental search functions written by D. R. Banks X * in file ISEARCH.C X * - added insert-string (unbound) command to help the macro X * language out. X * - added unmark-buffer (M-~) command to turn off the current buffers X * change flag X * - fixed nxtarg to truncate strings longer than asked for max length X * 4-jun-86 X * - added special characters in command line tokens. Tilde (~) is X * the special lead-in character for "nrtb". X * - Fixed bad ifdef in Aztec code so it could look at HOME dir X * for startup, help, and emacs.rc files X * 6-jun-86 X * - make delete word commands clear the kill buffer if not after another X * kill command X * 11-jun-86 X * - made ~@ in string arguments pass as char(192) to nxtarg() so one can X * quote @ at the beginning of string arguments X * - changed buffer size vars in listbuffers() to long (for big files) X * - re-wrote buffer-position command to be much faster X * 12-jun-86 X * - added count-words (M-^C) command to count the words/chars and X * lines in a region X * - changed regions so they could be larger than 65535 (short -> X * long in the REGION structure) X * - changed ldelete() and all callers to use a long size. The kill X * buffer will still have a problem >65535 that can not be solved X * until I restructure it. X * - grouped paragraph commands and word count together under symbol X * WORDPRO to allow them to be conditionally made (or not) X * 13-jun-86 X * - re-wrote kill buffer routines again. Now they support an unlimited X * size kill buffer, and are (in theory) faster. X * - changed delete-next-word (M-D) to not eat the newline after a word, X * instead it checks and eats a newline at the cursor. X * 17-jun-86 X * - added numeric argument to next/previous-window to access the nth X * window from the top/bottom X * - added support for the Data General 10 MSDOS machine X * - added save-window (unbound) and restore-window (unbound) commands X * for the use of the menu script. Save-window remembers which window X * is current, and restore-window returns the cursor to that window. X * 20-jun-86 X * - fixed a bug with the fence matching locking up near the beginning X * of a buffer X * - added argument to update to selectively force a complete update X * - added update-screen (unbound) command so macros can force a X * screen update X * 21-jun-86 X * - rearranged token() and nxtarg() calls so that command names and X * repeat counts could also be prompted and fetched from buffers X * [this broke later with the exec re-write....] X * - added write-message (unbound) command to write out a message X * on the message line (for macros) X * - changed ifdef's so that color modes are recognized as legal in X * b/w version, and simply do nothing (allowing us to use the same X * script files) X * [Released version 3.7 on July 1 to the net and elswhere] X * 2-jul-86 X * - Changed search string terminator to always be the meta character X * even if it is rebound. X * 3-jul-86 X * - removed extra calls to set color in startup code. This caused the X * original current window to always be the global colors. X * 7-jul-86 X * - Fixed bugs in mlreplyt() to work properly with all terminators X * including control and spec characters X * 22-jul-86 X * - fixed replaces() so that it will return FALSE properly on the X * input of the replacement string. X * - added a definition for FAILED as a return type..... X * - changed version number to 3.7b X * 23-jul-86 X * - fixed o -> 0 problem in TERMIO.C X * - made ^U universal-argument re-bindable X * - wrote atoi() for systems (like Aztec) where it acts strangely X * - changed version number to 3.7c X * 25-jul-86 X * - make ^G abort-command rebindable X * 29-jul-86 X * - added HP110 Portable Computer support X * - changed version number to 3.7d X * 30-jul-86 X * - Fixed a couple of errors in the new VMS code as pointer X * out by Ken Shacklford X * - split terminal open/close routines into screen and keyboard X * open/close routines X * - closed the keyboard during all disk I/O so that OS errors X * can be respoded to correctly (especially on the HP150) X * - changed version number to 3.7e X * 31-jul-86 X * - added label-function-key (unbound) command under symbol FLABEL X * (primarily for the HP150) X * 4-aug-86 X * - added fixes for Microsoft C as suggested by ihnp4!ihuxm!gmd1 X * <> X * 8-aug-86 X * - fixed beginning misspelling error everywhere X * - fixed some more MSC errors X * - changed version number to 3.7g X * 20-aug-86 X * - fixed CMODE .h scanning bug X * - changed version number to 3.7h X * 30-aug-86 X * - fixed killing renamed [list] buffer (it can't) as submitted X * by James Aldridge X * - Added code to allow multiple lines to display during X * vertical retrace X * [total disaster....yanked it back out] X * 9-sep-86 X * - added M-A (apropos) command to list commands containing a substring. X * - fixed an inefficiency in the display update code submitted X * by William W. Carlson (wwc@pur-ee) X * 10-sep-86 X * - added Dana Hoggatt's code for encryption and spliced it into the X * proper commands. CRYPT mode now triggers encryption. X * - added -k flag to allow encryption key (no spaces) in command line X * 14-sep-86 X * - added missing lastflag/thisflag processing to docmd() X * - changed version to 3.7i and froze for partial release via mail X * and BBS X * 05-oct-86 X * - changed some strcpys in MAIN.C to strncpys as suggested by John X * Gamble X * - replaces SEARCH.C and ISEARCH.C with versions modified by X * John Gamble X * 10-oct-86 X * - removed references to lflick....it just won't work that way. X * - removed defines LAT2 and LAT3...the code no longer is Lattice X * version dependant. X * 14-oct-86 X * - changed spawn so that it will not not pause if executed from X * a command line X * 15-oct-86 X * - added argument concatination (+) to the macro parsing X * - added [] as fence pairs X * 16-oct-86 X * - rewrote all macro line parsing routines and rearranged the X * mlreply code. Saved 6K!!! Have blazed the path for expanding X * the command language. X * 17-oct-86 X * - added new keyboard macro routines (plus a new level to the X * input character function) X * 22-oct-86 X * - improved EGA cursor problems X * - added -r (restricted) switch to command line for BBS use X * 06-nov-86 X * - fixed terminator declarations from char to int in getarg() and X * nxtarg() in EXEC.C as pointed out by John Gamble X * 07-nov-86 X * - made wordrap() user callable as wrap-word (M-FNW) and changed X * the getckey() routine so that illegal keystrokes (too many X * prefixes set) could be used for internal bindings. When word X * wrap conditions are met, the keystroke M-FNW is executed. Added X * word wrap check/call to newline(). X * 11-nov-86 X * - added and checked support for Mark Williams C 86 X * 12-nov-86 X * - added goto-matching-fence (M-^F) command to jump to a matching X * fence "({[]})" or beep if there is none. This can reframe the X * screen. X * - added code and structure elements to support change-screen-size X * command (M-^S) to change the number of lines being used by X * MicroEMACS. X * 15-nov-86 X * - finished debugging change-screen-size X * 17-nov-86 X * - Incorporated in James Turner's modifications for the Atari ST X * 23-sep-86 X * - added support for the Atari ST line of computers (jmt) X * - added a '\r' to the end of each line on output and strip X * it on input for the SHOW function from the desktop X * - added 3 new mode functions (HIREZ, MEDREZ, and LOREZ); X * chgrez routine in TERM structure; and MULTREZ define in X * ESTRUCT.H to handle multiple screen resolutions X * [note....ST still not running under Lattice yet...] X * 25-nov-86 X * - Made the filter-buffer (^X-#) command not work on VIEW mode X * buffers X * - Made the quick-exit (M-Z) command throw out a newline after X * each message so they could be seen. X * 26-nov-86 X * - fixed a couple of bugs in change-screen-size (M-^S) command X * - changed file read behavior on long lines and last lines X * with no newline (it no longer throws the partial line out) X * - [as suggested by Dave Tweten] Made adding a ^Z to the end X * of an output file under MSDOS configurable under the X * CTRL-Z symbol in ESTRUCT.H X * - [Dave Tweten] Spawn will look up the "TMP" environment variable X * for use during various pipeing commands. X * - [Dave Tweten] changed pipe command under MSDOS to use '>>' X * instead of '>' X * 04-dec-86 X * - moved processing of '@' and '#' so that they can be outside X * the quotes in an argument, and added hooks to process '%' for X * environment and user variables. X * - modified IBMPC.C to sense the graphics adapter (CGA and MONO) X * at runtime to cut down on the number of versions. X * 05-dec-86 X * - changed macro directive character to "!" instead of "$" (see X * below) and fixed the standard .rc file to comply. X * - added code to interpret environment variables ($vars). Added X * hooks for built in functions (&func). So, to recap: X * X * @ prompt and return a string from the user X * # get the next line from a buffer and advance X * % get user variable X * $ get environment variable X * & evaluate function X * X * - allowed repeat counts to be any of the above X * - added code to allow insert-string (unbound) to use its X * repeat count properly X * - added set (^X-A) command to set variables. Only works on X * environmental vars yet. X * 9-dec-86 X * - added some code for user defined variables...more to come X * - added options for malloc() memory pool tracking X * - preliminary user variables (%) working X * - changed terminal calls to macro's (to prepare for the new X * terminal drivers) X * 15-dec-86 X * - changed previous-line (^P) and next-line (^N) to return a X * FALSE at the end or beginning of the file so repeated X * macros involving them terminate properly! X * - added code for $CURCOL and $CURLINE X * 20-dec-86 X * - set (^X-A) now works with all vars X * - added some new functions X * &ADD &SUB &TIMES &DIV &MOD &NEG &CAT X * - once again rearranged functions to control macro execution. Did X * away with getarg() X * 23-dec-86 X * - added string functions X * &LEFt &RIGht &MID X * 31-dec-86 X * - added many logical functions X * &NOT &EQUal &LESs &GREater X * - added string functions X * &SEQual &SLEss &SGReater X * - added variable indirection with &INDirect X * - made fixes to allow recursive macro executions X * (improved speed during macro execution as well) X * 3-jan-87 X * - added $FLICKER to control flicker supression X * - made spawn commands restricted X * - cleaned up lots of unintentional int<->char problems X * 4-jan-87 X * - Fixed broken pipe-command (^X-@) command under MSDOS X * - added !IF !ELSE !ENDIF directives and changed the X * name of !END to !ENDM....real slick stuff X * 5-jan-87 X * - quick-exit (M-Z) aborts on any filewrite errors X * 8-jan-87 X * - debugged a lot of the new directive and evaluation code. X * BEWARE of stack space overflows! (increasing stack to X * 16K under MSDOS) X * - removed non-standard DEC Rainbow keyboard support...let someone X * PLEASE implement this in the standard manner using key bindings X * and send the results to me. X * - added change-screen-width () command and $CURWIDTH variable X * 11-jan-87 X * - fixed an incredibly deeply buried bug in vtputc and combined X * it with vtpute (saving about 200 bytes!) X * 16-jan-87 X * - added code to handle controlling multiple screen resolutions... X * allowed the IBM-PC driver to force Mono or CGA modes. X * - added current buffer name and filename variables X * $cbufname and $cfname X * 18-jan-87 X * - added $sres variable to control screen resolution X * - added $debug variable to control macro debugging code (no longer X * is this activated by GLOBAL spell mode) X * - fixed bug in -g command line option X * - Released Version 3.8 to BBSNET X * 21-jan-87 X * - added $status variable to record return status of last command X * 2-feb-87 X * - added ATARI 1040 support...runs in all three modes right now X * - added $palette var with palette value in it X * - undefined "register" in BIND.C and INPUT.C for ST520 & LATTICE X * to get around a nasty Lattice bug X * 4-feb-87 X * - added, debugged code for switching all 1040ST color modes, added X * code for HIGH monochrome mode as well, DENSE still pending X * 5-feb-87 X * - with John Gamble, found and corrected the infamous bad matching X * fence problems. X * - added error return check in various add/delete mode commands X * 10-feb-87 X * - re-arrange code in docmd() so that labels are stored in X * macro buffers X * - fixed !RETURN to only return if (execlevel == 0) [If we are X * currently executing] X * 14-feb-87 X * - added to outp() calls in the EGA driver to fix a bug in the BIOS X * - adding code for 1040ST 40 line DENSE mode (not complete) X * 25-feb-87 X * - added auto-save "ASAVE" mode....variables $asave and $acount X * control the frequency of saving and count until next save X * - added &and and &or as functions for logical anding and oring X * - added string length &LEN, upper and lower case string funtions X * &LOWER and &UPPER X * 27-feb-87 X * - added $lastkey last keystroke struck and X * $curchar character under cursor X * 28-feb-87 X * - added code for trim-line (^X^T) command and table entries X * for the entab-line (^X^E) and detab-line (^X^D) commands. X * These are conditional on AEDIT (Advanced editing) in estruct.h X * 18-mar-87 X * - finished above three commands X * - added $version environment variable to return the current X * MicroEMACS version number X * - added $discmd emvironment variable. This is a logical flag that X * indicates if emacs should be echoing commands on the command line. X * real useful in order to stop flashing macros and .rc files X * - added $progname environment variable. this always returns the X * string "MicroEMACS". OEM's should change this so that macros can X * tell if they are running on an unmodified emacs or not. X * - fixed a minor bug in the CGA/MONO detection routine in IBMPC.C X * 20-mar-87 X * - integrated EGAPC.C into IBMPC.C and eliminated the file. Now an X * EGA user can switch from EGA to CGA modes at will X * - A LOT of little fixes and corrections sent in by John Ruply X * 25-mar-87 X * - Fixed buffer variables so they will work when referencing the X * current buffer X * 26-mar-87 X * - Fixed atoi() to be more reasonable. trailing whitespace ignored, X * only one leading sign, no non-digits allowed after the sign. X * - fixed buffer variables to go from the point to the end of X * line. X * 28-mar-87 X * - fixed bugs with 8 bit chars as submited by Jari Salminen X * - replace AZTEC/MSDOS agetc() with a1getc() which won't strip X * the high order bit X * 30-mar-87 X * - changed list-buffers (^X^B) so that with any argument, it will X * also list the normally invisable buffers X * - added store-procedure and execute-procedure/run (M-^E) X * commands to store and execute named procedures. X * 31-mar-87 X * - Fixed infinite loop in ^X-X command (when [LIST] is the X * only buffer left) as pointed out by John Maline X * - made filenames in getfile() always lower case as pointed X * out by John Maline X * 2-apr-87 X * - Fixed buffer variables so they would work on non-current displayed X * buffers. They should now work with ALL buffers.... X * 3-apr-87 X * - Yanked AZTEC profiling code....not very useful X * - Modified IBMPC driver so it will not start in EGA mode X * - allow the next-buffer (^X-X) command to have a preceding X * non-negative argument. X * 14-apr-87 X * - added John Gamble's modified search.c. The code has cut apx X * 200-300 bytes off the executable. X * - added the &RND function to generate a random integer between X * 1 and its arguments value. Also $SEED is availible as the X * random number seed. X * - changed the -k command line switch so if there is no argument, X * it will prompt for one when the file is read X * 15-apr-87 X * - added 20 bytes of buffer in getval()'s local argument alloc so X * when it returns a value, it has enough stack space to do at least X * one strcpy() before stomping on the returned value. ALWAYS call X * getval() ONLY from within a strcpy() call. X * - made $curcol return a 1 based value instead of a zero based one. X * [changed this back later for 3.8o it was simply wrong.....] X * 16-apr-87 X * - re-wrote strncpy() for AZTEC & MSDOS so it null terminates the X * string. X * - changed pipe() to pipecmd() to avoid conflicts with various X * UNIX systems X * 24-apr-87 X * - changed open parameters on AMIGA window open to 0/0/640/200 X * [Froze and released v3.8i via BBS net] X * 14-may-87 X * - added nop (M-FNC) that gets called on every command loop X * - added $wline, returns and sets # lines in current window X * - added $cwline, returns and set current line within window X * - added $target, returns/sets target for line moves X * - added $search, returns/sets default search string X * - added $replace, returns/sets default replace string X * - added $match, returns last matched string in magic search X * 29-may-87 X * - rewrote word deletes to not kill trailing non-whitespace after X * the last word. Also a zero argument will cause it to just delete X * the word and nothing else. X * - more fixes for the search pattern environment variables X * 30-may-87 X * - forced all windows to redraw on a width change X * 2-jun-87 X * - forced clear-message-line to overide $discmd X * - added mlforce() routine and call it in clear-message-line, X * write-message and when $debug is TRUE X * - recoded the startup sequence in main()....Much Better... X * 4-jun-87 X * - forced interactive arguments ( @"question" ) to ALWAYS be echoed X * regardless of the setting of $discmd. X * 7-jun-87 X * - started adding support for Turbo C under MSDOS X * 11-jun-87 X * - words now include ONLY upper/lower case alphas and digits X * - fixed some more bugs with the startup..(ORed in the global modes) X * - took more limits off the self-insert list.... X * 16-jun-87 X * - macro debugging now displays the name of the current macro. X * - fixed a problem in expandp() in search.c that kept high-byte X * characters from working in search strings X * 18-jun-87 X * - added &sindex function which searches for string 2 X * within string 1 X * [released verion 3.8o internally] X * 19-jun-87 X * - added $cmode and $gmode to return and set the mode of the X * current buffer and the global mode X * - separated findvar() out from setvar() so it could be used in X * the !LOOP directive (which got canned....read on) X * - %No such variable message now types the name of the offending X * variable X * 22-jun-87 X * - fixed startup bug when editing the startup file X * - added the !LOOP