#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'stevie/ops.c' <<'END_OF_FILE' X/* $Header: /nw/tony/src/stevie/src/RCS/ops.c,v 1.5 89/08/06 09:50:42 tony Exp $ X * X * Contains routines that implement the operators in vi. Everything in this X * file is called only from code in normal.c X */ X X#include "stevie.h" X#include "ops.h" X X/* X * doshift - handle a shift operation X */ Xvoid Xdoshift(op, c1, c2, num) Xint op; Xchar c1, c2; Xint num; X{ X void tabinout(); X LPTR top, bot; X int nlines; X char opchar; X X top = startop; X bot = *Curschar; X X if (lt(&bot, &top)) X pswap(&top, &bot); X X u_save(top.linep->prev, bot.linep->next); X X nlines = cntllines(&top, &bot); X *Curschar = top; X tabinout((op == LSHIFT), nlines); X X /* construct Redo buff */ X opchar = (op == LSHIFT) ? '<' : '>'; X if (num != 0) X sprintf(Redobuff, "%c%d%c%c", opchar, num, c1, c2); X else X sprintf(Redobuff, "%c%c%c", opchar, c1, c2); X X /* X * The cursor position afterward is the prior of the two positions. X */ X *Curschar = top; X X /* X * If we were on the last char of a line that got shifted left, X * then move left one so we aren't beyond the end of the line X */ X if (gchar(Curschar) == NUL && Curschar->index > 0) X Curschar->index--; X X updatescreen(); X X if (nlines > P(P_RP)) X smsg("%d lines %ced", nlines, opchar); X} X X/* X * dodelete - handle a delete operation X */ Xvoid Xdodelete(c1, c2, num) Xchar c1, c2; Xint num; X{ X LPTR top, bot; X int nlines; X int botindex; X register int n; X X /* X * Do a yank of whatever we're about to delete. If there's too much X * stuff to fit in the yank buffer, then get a confirmation before X * doing the delete. This is crude, but simple. And it avoids doing X * a delete of something we can't put back if we want. X */ X if (!doyank()) { X msg("yank buffer exceeded: press to delete anyway"); X if (vgetc() != 'y') { X msg("delete aborted"); X *Curschar = startop; X return; X } X } X X top = startop; X bot = *Curschar; X X if (lt(&bot, &top)) X pswap(&top, &bot); X X u_save(top.linep->prev, bot.linep->next); X /* Don't leave even the potential for orphan marks */ X clrmark (top.linep); X X nlines = cntllines(&top, &bot); X *Curschar = top; X cursupdate(); X X if (mtype == MLINE) { X delline(nlines, TRUE); X } else { X botindex = -1; X if (!mincl) { X botindex = bot.index; /* where it WAS */ X if (bot.index != 0) X dec(&bot); X } X X if (top.linep == bot.linep) { /* del. within line */ X n = bot.index - top.index + 1; X while (n--) X if (!delchar(TRUE)) X break; X } else { /* del. between lines */ X n = Curschar->index; X while (Curschar->index >= n) X if (!delchar(TRUE)) X break; X X top = *Curschar; X *Curschar = *nextline(Curschar); X delline(nlines-2, TRUE); X Curschar->index = 0; X n = bot.index + 1; X while (n-- && botindex) X if (!delchar(TRUE)) X break; X *Curschar = top; X (void) dojoin(FALSE); X oneright(); /* we got bumped left up above */ X } X } X X /* construct Redo buff */ X if (num != 0) X sprintf(Redobuff, "d%d%c%c", num, c1, c2); X else X sprintf(Redobuff, "d%c%c", c1, c2); X X if (mtype == MCHAR && nlines == 1) X updateline(); X else X updatescreen(); X X if (nlines > P(P_RP)) X smsg("%d fewer lines", nlines); X} X X/* X * dofilter - handle a filter operation X */ X X#define ITMP "viXXXXXX" X#define OTMP "voXXXXXX" X Xstatic char itmp[32]; Xstatic char otmp[32]; X X X/* X * dofilter - filter lines through a command given by the user X * X * We use temp files and the system() routine here. This would normally X * be done using pipes on a UNIX machine, but this is more portable to X * the machines we usually run on. The system() routine needs to be able X * to deal with redirection somehow, and should handle things like looking X * at the PATH env. variable, and adding reasonable extensions to the X * command name given by the user. All reasonable versions of system() X * do this. X */ Xvoid Xdofilter(c1, c2, num) Xchar c1, c2; Xint num; X{ X#ifdef VxWorks X emsg("Shell filtering not supported under VxWorks"); X return; X#else X X char *mktemp(); X static char *lastcmd = NULL;/* the last thing we did */ X char *buff; /* cmd buffer from getcmdln() */ X char cmdln[200]; /* filtering command line */ X LPTR top, bot; X int nlines; X X top = startop; X bot = *Curschar; X X buff = getcmdln('!'); X X if (buff == NULL) /* user backed out of the command prompt */ X return; X X if (*buff == '!') { /* use the 'last' command */ X if (lastcmd == NULL) { X emsg("No previous command"); X return; X } X buff = lastcmd; X } X X /* X * Remember the current command X */ X if (lastcmd != NULL) X free(lastcmd); X lastcmd = strsave(buff); X X if (lt(&bot, &top)) X pswap(&top, &bot); X X u_save(top.linep->prev, bot.linep->next); X X nlines = cntllines(&top, &bot); X *Curschar = top; X cursupdate(); X X /* X * 1. Form temp file names X * 2. Write the lines to a temp file X * 3. Run the filter command on the temp file X * 4. Read the output of the command into the buffer X * 5. Delete the original lines to be filtered X * 6. Remove the temp files X */ X X#ifdef TMPDIR X strcpy(itmp, TMPDIR); X strcpy(otmp, TMPDIR); X#else X itmp[0] = otmp[0] = NUL; X#endif X strcat(itmp, ITMP); X strcat(otmp, OTMP); X X if (mktemp(itmp) == NULL || mktemp(otmp) == NULL) { X emsg("Can't get temp file names"); X return; X } X X if (!writeit(itmp, &top, &bot)) { X emsg("Can't create input temp file"); X return; X } X X sprintf(cmdln, "%s <%s >%s", buff, itmp, otmp); X X if (system(cmdln) != 0) { X emsg("Filter command failed"); X remove(ITMP); X return; X } X X if (readfile(otmp, &bot, TRUE)) { X emsg("Can't read filter output"); X return; X } X X delline(nlines, TRUE); X X remove(itmp); X remove(otmp); X X /* construct Redo buff */ X if (num != 0) X sprintf(Redobuff, "d%d%c%c", num, c1, c2); X else X sprintf(Redobuff, "d%c%c", c1, c2); X X updatescreen(); X X if (nlines > P(P_RP)) X smsg("%d lines filtered", nlines); X#endif /* VxWorks */ X} X X#ifdef TILDEOP Xvoid Xdotilde(c1, c2, num) Xchar c1, c2; Xint num; X{ X LPTR top, bot; X register char c; X X /* construct Redo buff */ X if (num != 0) X sprintf(Redobuff, "~%d%c%c", num, c1, c2); X else X sprintf(Redobuff, "~%c%c", c1, c2); X X top = startop; X bot = *Curschar; X X if (lt(&bot, &top)) X pswap(&top, &bot); X X u_save(top.linep->prev, bot.linep->next); X X if (mtype == MLINE) { X top.index = 0; X bot.index = strlen(bot.linep->s); X } else { X if (!mincl) { X if (bot.index) X bot.index--; X } X } X X for (; ltoreq(&top, &bot) ;inc(&top)) { X /* X * Swap case through the range X */ X c = gchar(&top); X if (isalpha(c)) { X if (islower(c)) X c = toupper(c); X else X c = tolower(c); X X pchar(&top, c); /* Change current character. */ X CHANGED; X } X } X *Curschar = startop; X updatescreen(); X} X#endif X X/* X * dochange - handle a change operation X */ Xvoid Xdochange(c1, c2, num) Xchar c1, c2; Xint num; X{ X char sbuf[16]; X bool_t doappend; /* true if we should do append, not insert */ X bool_t at_eof; /* changing through the end of file */ X LPTR top, bot; X X top = startop; X bot = *Curschar; X X if (lt(&bot, &top)) X pswap(&top, &bot); X X doappend = endofline(&bot); X at_eof = (bot.linep->next == Fileend->linep); X X dodelete(c1, c2, num); X X if (mtype == MLINE) { X /* X * If we made a change through the last line of the file, X * then the cursor got backed up, and we need to open a X * new line forward, otherwise we go backward. X */ X if (at_eof) X opencmd(FORWARD, FALSE); X else X opencmd(BACKWARD, FALSE); X } else { X if (doappend && !lineempty()) X inc(Curschar); X } X X if (num) X sprintf(sbuf, "c%d%c%c", num, c1, c2); X else X sprintf(sbuf, "c%c%c", c1, c2); X X startinsert(sbuf, mtype == MLINE); X} X X#ifndef YBSIZE X#define YBSIZE 4096 X#endif X Xstatic char ybuf[YBSIZE]; Xstatic int ybtype = MBAD; X Xbool_t Xdoyank() X{ X LPTR top, bot; X char *yptr = ybuf; X char *ybend = &ybuf[YBSIZE-1]; X int nlines; X X top = startop; X bot = *Curschar; X X if (lt(&bot, &top)) X pswap(&top, &bot); X X nlines = cntllines(&top, &bot); X X ybtype = mtype; /* set the yank buffer type */ X X if (mtype == MLINE) { X top.index = 0; X bot.index = strlen(bot.linep->s); X /* X * The following statement checks for the special case of X * yanking a blank line at the beginning of the file. If X * not handled right, we yank an extra char (a newline). X */ X if (dec(&bot) == -1) { X ybuf[0] = NUL; X if (operator == YANK) X *Curschar = startop; X return TRUE; X } X } else { X if (!mincl) { X if (bot.index) X bot.index--; X else { /* already first column */ X if (prevchar (&bot) == NULL) { /* err check */ X ybuf[0] = NUL; /* quit */ X if (operator == YANK) X *Curschar = startop; X return TRUE; X } X bot = *( prevchar (&bot)); X } X } X } X X for (; ltoreq(&top, &bot) ;inc(&top)) { X *yptr = (gchar(&top) != NUL) ? gchar(&top) : NL; X if (++yptr >= ybend) { X msg("yank too big for buffer"); X ybtype = MBAD; X return FALSE; X } X } X X *yptr = NUL; X X if (operator == YANK) { /* restore Curschar if really doing yank */ X *Curschar = startop; X X if (nlines > P(P_RP)) X smsg("%d lines yanked", nlines); X } X X return TRUE; X} X X/* X * doput(dir) X * X * Put the yank buffer at the current location, using the direction given X * by 'dir'. X */ Xvoid Xdoput(dir) Xint dir; X{ X void inslines(); X X if (ybtype == MBAD) { X beep(); X return; X } X X u_saveline(); X X if (ybtype == MLINE) X inslines(Curschar->linep, dir, ybuf); X else { X /* X * If we did a character-oriented yank, and the buffer X * contains multiple lines, the situation is more complex. X * For the moment, we punt, and pretend the user did a X * line-oriented yank. This doesn't actually happen that X * often. X */ X if (strchr(ybuf, NL) != NULL) X inslines(Curschar->linep, dir, ybuf); X else { X char *s; X int len; X X len = strlen(Curschar->linep->s) + strlen(ybuf) + 1; X s = alloc((unsigned) len); X if (!s) return; X strcpy(s, Curschar->linep->s); X if (dir == FORWARD) X Curschar->index++; X strcpy(s + Curschar->index, ybuf); X strcat(s, &Curschar->linep->s[Curschar->index]); X free(Curschar->linep->s); X Curschar->linep->s = s; X Curschar->linep->size = len; X updateline(); X } X } X X CHANGED; X} X Xbool_t Xdojoin(join_cmd) Xbool_t join_cmd; /* handling a real "join" command? */ X{ X int scol; /* save cursor column */ X int size; /* size of the joined line */ X X if (nextline(Curschar) == NULL) /* on last line */ X return FALSE; X X if (!canincrease(size = strlen(Curschar->linep->next->s))) X return FALSE; X X while (oneright()) /* to end of line */ X ; X X strcat(Curschar->linep->s, Curschar->linep->next->s); X X /* X * Delete the following line. To do this we move the cursor X * there briefly, and then move it back. Don't back up if the X * delete made us the last line. X */ X Curschar->linep = Curschar->linep->next; X scol = Curschar->index; X X if (nextline(Curschar) != NULL) { X delline(1, TRUE); X Curschar->linep = Curschar->linep->prev; X } else X delline(1, TRUE); X X Curschar->index = scol; X X if (join_cmd) X oneright(); /* go to first char. of joined line */ X X if (join_cmd && size != 0) { X /* X * Delete leading white space on the joined line X * and insert a single space. X */ X while (gchar(Curschar) == ' ' || gchar(Curschar) == TAB) X delchar(TRUE); X inschar(' '); X } X X return TRUE; X} X Xvoid Xstartinsert(initstr, startln) Xchar *initstr; Xint startln; /* if set, insert point really at start of line */ X{ X register char *p, c; X X *Insstart = *Curschar; X if (startln) X Insstart->index = 0; X Ninsert = 0; X Insptr = Insbuff; X for (p=initstr; (c=(*p++))!='\0'; ) X *Insptr++ = c; X X if (*initstr == 'R') X State = REPLACE; X else X State = INSERT; X X if (P(P_MO)) X msg((State == INSERT) ? "Insert Mode" : "Replace Mode"); X} X/* X * tabinout(inout,num) X * X * If inout==0, add a tab to the begining of the next num lines. X * If inout==1, delete a tab from the beginning of the next num lines. X */ Xstatic void Xtabinout(inout, num) Xint inout; Xint num; X{ X int ntodo = num; X LPTR *p; X X beginline(FALSE); X while (ntodo-- > 0) { X beginline(FALSE); X if (inout == 0) X inschar(TAB); X else { X if (gchar(Curschar) == TAB) X delchar(TRUE); X } X if ( ntodo > 0 ) { X if ((p = nextline(Curschar)) != NULL) X *Curschar = *p; X else X break; X } X } X} X X/* X * inslines(lp, dir, buf) X * X * Inserts lines in the file from the given buffer. Lines are inserted X * before or after "lp" according to the given direction flag. Newlines X * in the buffer result in multiple lines being inserted. The cursor X * is left on the first of the inserted lines. X */ Xstatic void Xinslines(lp, dir, buf) XLINE *lp; Xint dir; Xchar *buf; X{ X register char *cp = buf; X register int len; X char *ep; X LINE *l, *nc = NULL; X X if (dir == BACKWARD) X lp = lp->prev; X X do { X if ((ep = strchr(cp, NL)) == NULL) X len = strlen(cp); X else X len = ep - cp; X X l = newline(len); X if (len != 0) X strncpy(l->s, cp, len); X l->s[len] = NUL; X X l->next = lp->next; X l->prev = lp; X lp->next->prev = l; X lp->next = l; X X if (nc == NULL) X nc = l; X X lp = lp->next; X X cp = ep + 1; X } while (ep != NULL); X X if (dir == BACKWARD) /* fix the top line in case we were there */ X Filemem->linep = Filetop->linep->next; X X renum(); X X updatescreen(); X Curschar->linep = nc; X Curschar->index = 0; X} END_OF_FILE if test 13287 -ne `wc -c <'stevie/ops.c'`; then echo shar: \"'stevie/ops.c'\" unpacked with wrong size! fi # end of 'stevie/ops.c' fi if test -f 'stevie/version.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'stevie/version.c'\" else echo shar: Extracting \"'stevie/version.c'\" \(14060 characters\) sed "s/^X//" >'stevie/version.c' <<'END_OF_FILE' Xstatic char RCSid[] = X"$Header: /nw/tony/src/stevie/src/RCS/version.c,v 3.69 89/08/13 11:41:58 tony Exp $"; X X/* X * Contains the declaration of the global version number variable. X * X * $Log: version.c,v $ X * X * Revision 3.69a 90/02/04 dave X * A couple of minor bugfixes, and a whole load of enhancements: X * - Added tag-stacking. X * - Added searches for sentences and paragraphs. X * - Enhancements to "help" command: X * . Navigation of help screens, not just next-screen. X * . Index of help screens. X * . Screen for MSDOS-specific features. X * . Screen for :set commands. X * . A little context-sensitivity. X * - File mode is preserved (it wasn't in previous versions). X * - UNIX-like specifications of environments variables are expanded X * in file names. (E.g.- you can say :e $HOME/autoexec.bat) X * - PC keys for Insert & Delete now work. X * - Ported to Turbo C for the PC. X * - Integrated Larry Shurr's BIOS option for the PC. X * - Added color and multi-line options for the PC, and hooks for them X * in other systems. X * - Made "ctags" a little more general. X * X * Revision 3.69 89/08/13 11:41:58 tony X * Fixed a bug that caused messages from fileinfo() (in misccmds.c) to get X * screwed up. The routine smsg() which uses the kludge approach to varargs X * didn't have enough parameters for some of the calls made to it. X * X * Revision 3.68 89/08/06 09:51:20 tony X * Misc. minor changes to make lint happier before posting to USENET. X * X * Revision 3.67 89/08/03 13:08:52 tony X * There was some code in ops.c that was duplicating the function of the X * getcmdln() routine in cmdline.c. I modified getcmdln() to be slightly X * more general, and changed dofilter() in ops.c to use it. X * X * Revision 3.66 89/08/02 20:00:12 tony X * Fixed some problems with mode lines. There were still extra screen X * redraws that needed to be avoided. There was also a problem involving X * nested calls to docmdln() that can occur when mode lines are used. X * X * Revision 3.65 89/08/02 15:50:03 tony X * Finally got around to providing full support for the "change" operator. X * Multi-line changes (like "cL" or "3cc") now work correctly. Also fixed X * a small problem with multi-line character-oriented deletes leaving the X * cursor in the wrong location (off by one character). This is mainly X * useful for multi-line changes (such as "c%") so the insert starts in X * the right place. X * X * Revision 3.64 89/08/02 12:47:04 tony X * This message intentionally left blank. X * X * Revision 3.63 89/08/02 12:43:44 tony X * I just noticed that I had used the RCS cookie for log messages in one X * of my prior version messages. This caused these version update messages X * to be duplicated in this file. I just removed that string, and the X * extra message copies that had been generated. X * X * Revision 3.62 89/08/02 12:26:20 tony X * The ^G command now shows where you are in the file list, if more than one X * file is being edited. Also, the commands ":e#" and ":e!#" (note the lack X * of a space between the command and file name) will now work. X * X * Revision 3.61 89/08/02 11:03:16 tony X * Misc. cleanups regarding tags. Also added support for the "terse" option. X * This is ignored, but improves compatibility with vi, since we no longer X * complain about an unknown option if "terse" is used. X * X * Revision 3.60 89/08/02 09:26:39 tony X * Added code to avoid screen redraws when input is being read from the X * "stuffin" buffer. This avoids extra redraws when switching to the X * alternate file, or when invoking the editor with one of the "+" options, X * or when using tags. X * X * Revision 3.59 89/08/01 16:28:31 tony X * Added better support for counts on several cursor motion commands. These X * include ^F, ^B, f, F, t, T, as well as the repeated character search X * commands (command and semi-colon). X * X * Revision 3.58 89/07/19 08:08:23 tony X * Added the ability for '~' to be an operator. If enabled (by defined TILDEOP X * in env.h), the parameter "tildeop" (or "to") may be set to turn tilde into X * an operator. X * X * Revision 3.57 89/07/13 22:47:05 tony X * Made some generic speed improvements in screen.c and some TOS-specific X * improvements in tos.c. The TOS version is now much faster at screen X * updates than before. X * X * Revision 3.56 89/07/13 14:52:03 tony X * Minor cleanups in normal.c X * X * Revision 3.55 89/07/13 14:19:12 tony X * Cleaned up the logic in getcmdln() A LOT. The routine docmdln() needs a X * similar overhaul. X * X * Revision 3.54 89/07/12 21:40:01 tony X * Lots of misc. cleanup in normal.c and cmdline.c, but nothing much in the X * way of functional improvements. One change is that things like d/foo X * will now work since searches are less of a special case now. X * X * Revision 3.53 89/07/11 16:16:08 tony X * Added general support for interrupt-handling for those environments that X * can actually generate them. Basically, long-running operations are now X * able to terminate early if an error occurs. These operations are: string X * searches, the global command (":g/.../"), and file reads. File writes X * should probably be done as well, but this is more dangerous. In all cases, X * the user is given an indication on the status line that the operation X * terminated due to an interrupt. X * X * Revision 3.52 89/07/11 12:35:09 tony X * Improved the code in dosub() and doglob() that detects quoted characters X * and delimiters in search strings and replacement patterns. The current X * code didn't allow certain valid strings to be used. The delimiter is still X * required to be '/', but it can be quoted reliably now with backslash. X * X * Revision 3.51 89/07/10 14:01:58 tony X * Removed the function addtobuff() since it was rarely used and could be X * replaced by calls to other library functions. Also removed some other X * obsolete code that was already ifdef'd out anyway. X * X * Revision 3.50 89/07/10 13:10:32 tony X * Added a workaround in normal.c to avoid problems with broken versions of X * strncpy() that don't properly deal with a count of zero. X * X * Revision 3.49 89/07/07 16:28:37 tony X * Fixed a long-standing bug with 'cw' when the cursor is positioned on a X * word with only one character. Also fixed a problems with zero-length files X * and reverse searches. X * X * Revision 3.48 89/03/22 10:26:58 tony X * Fixed some outdated uses of the ":p" command (which has been changed to X * ":N" in os2.c and dos.c. Also added macros (F7 and F8) for dos and os/2 X * to use the "cdecl" program to convert lines to and from a pseudo-english X * form. Use F7 to "explain" the declaration on the current line, and F8 to X * convert an english-style declaration to the C form. In both cases, the X * new form is placed on the next line, leaving the original line intact. X * X * Revision 3.47 89/03/11 22:44:14 tony X * General cleanup. Removed the static "rcsid" variables and the log X * strings (except in version.c). Fixed some coding style inconsistencies X * and added a few register declarations. X * X * Revision 3.46 89/02/14 09:52:07 tony X * Made a first pass at adding Robert Regn's changes, starting with the X * more portable ones. Added better support for '#' and '%' in colon X * commands, support for a configurable temp directory, and made the X * termcap code less picky about capabilities. X * X * Revision 3.45 88/11/10 09:00:06 tony X * Added support for mode lines. Strings like "vi:stuff:" or "ex:stuff:" X * occurring in the first or last 5 lines of a file cause the editor to X * pretend that "stuff" was types as a colon command. This examination X * is done only if the parameter "modelines" (or "ml") is set. This is X * not enabled, by default, because of the security implications involved. X * X * Revision 3.44 88/11/01 21:34:11 tony X * Fixed a couple of minor points for Minix, and improved the speed of X * the 'put' command dramatically. X * X * Revision 3.43 88/10/31 13:11:33 tony X * Added optional support for termcap. Initialization is done in term.c X * and also affects the system-dependent files. To enable termcap in those X * environments that support it, define the symbol "TERMCAP" in env.h X * X * Revision 3.42 88/10/27 18:30:19 tony X * Removed support for Megamax. Added '%' as an alias for '1,$'. Made the X * 'r' command more robust. Now prints the string on repeated searches. X * The ':=" command now works. Some pointer operations are now safer. X * The ":!" and ":sh" now work correctly. Re-organized the help screens X * a little. X * X * Revision 3.41 88/10/06 10:15:00 tony X * Fixed a bug involving ^Y that occurs when the cursor is on the last X * line, and the line above the screen is long. Also hacked up fileio.c X * to pass pathnames off to fixname() for system-dependent processing. X * Used under DOS & OS/2 to trim parts of the name appropriately. X * X * Revision 3.40 88/09/16 08:37:36 tony X * No longer beeps when repeated searches fail. X * X * Revision 3.39 88/09/06 06:51:07 tony X * Fixed a bug with shifts that was introduced when replace mode was added. X * X * Revision 3.38 88/08/31 20:48:28 tony X * Made another fix in search.c related to repeated searches. X * X * Revision 3.37 88/08/30 20:37:16 tony X * After much prodding from Mark, I finally added support for replace mode. X * X * Revision 3.36 88/08/26 13:46:34 tony X * Added support for the '!' (filter) operator. X * X * Revision 3.35 88/08/26 08:46:01 tony X * Misc. changes to make lint happy. X * X * Revision 3.34 88/08/25 15:13:36 tony X * Fixed a bug where the cursor didn't land on the right place after X * "beginning-of-word" searches if the word was preceded by the start X * of the line and a single character. X * X * Revision 3.33 88/08/23 12:53:08 tony X * Fixed a bug in ssearch() where repeated searches ('n' or 'N') resulted X * in dynamic memory being referenced after it was freed. X * X * Revision 3.32 88/08/17 07:37:07 tony X * Fixed a general problem in u_save() by checking both parameters for X * null values. The specific symptom was that a join on the last line of X * the file would crash the editor. X * X * Revision 3.31 88/07/09 20:39:38 tony X * Implemented the "line undo" command (i.e. 'U'). X * X * Revision 3.30 88/06/28 07:54:22 tony X * Fixed a bug involving redo's of the '~' command. The redo would just X * repeat the replacement last performed instead of switching the case of X * the current character. X * X * Revision 3.29 88/06/26 14:53:19 tony X * Added support for a simple form of the "global" command. It supports X * commands of the form "g/pat/d" or "g/pat/p", to delete or print lines X * that match the given pattern. A range spec may be used to limit the X * lines to be searched. X * X * Revision 3.28 88/06/25 21:44:22 tony X * Fixed a problem in the processing of colon commands that caused X * substitutions of patterns containing white space to fail. X * X * Revision 3.27 88/06/20 14:52:21 tony X * Merged in changes for BSD Unix sent in by Michael Lichter. X * X * Revision 3.26 88/06/10 13:44:06 tony X * Fixed a bug involving writing out files with long pathnames. A small X * fixed size buffer was being used. The space for the backup file name X * is now allocated dynamically. X * X * Revision 3.25 88/05/04 08:29:02 tony X * Fixed a minor incompatibility with vi involving the 'G' command. Also X * changed the RCS version number of version.c to match the actual version X * of the editor. X * X * Revision 1.12 88/05/03 14:39:52 tony X * Changed the screen representation of the ascii character DELETE to be X * compatible with vi. Also merged in support for DOS. X * X * Revision 1.11 88/05/02 21:38:21 tony X * The code that reads files now handles boundary/error conditions much X * better, and generates status/error messages that are compatible with X * the real vi. Also fixed a bug in repeated reverse searches that got X * inserted in the recent changes to search.c. X * X * Revision 1.10 88/05/02 07:35:41 tony X * Fixed a bug in the routine plines() that was introduced during changes X * made for the last version. X * X * Revision 1.9 88/05/01 20:10:19 tony X * Fixed some problems with auto-indent, and added support for the "number" X * parameter. X * X * Revision 1.8 88/04/30 20:00:49 tony X * Added support for the auto-indent feature. X * X * Revision 1.7 88/04/29 14:50:11 tony X * Fixed a class of bugs involving commands like "ct)" where the cursor X * motion part of the operator can fail. If the motion failed, the operator X * was continued, with the cursor position unchanged. Cases like this were X * modified to abort the operation if the motion fails. X * X * Revision 1.6 88/04/28 08:19:35 tony X * Modified Henry Spencer's regular expression library to support new X * features that couldn't be done easily with the existing interface. X * This code is now a direct part of the editor source code. The editor X * now supports the "ignorecase" parameter, and multiple substitutions X * per line, as in "1,$s/foo/bar/g". X * X * Revision 1.5 88/04/24 21:38:00 tony X * Added preliminary support for the substitute command. Full range specs. X * are supported, but only a single substitution is allowed on each line. X * X * Revision 1.4 88/04/23 20:41:01 tony X * Worked around a problem with adding lines to the end of the buffer when X * the cursor is at the bottom of the screen (in misccmds.c). Also fixed a X * bug that caused reverse searches from the start of the file to bomb. X * X * Revision 1.3 88/03/24 08:57:00 tony X * Fixed a bug in cmdline() that had to do with backspacing out of colon X * commands or searches. Searches were okay, but colon commands backed out X * one backspace too early. X * X * Revision 1.2 88/03/21 16:47:55 tony X * Fixed a bug in renum() causing problems with large files (>6400 lines). X * Also moved system-specific defines out of stevie.h and into a new file X * named env.h. This keeps volatile information outside the scope of RCS. X * X * Revision 1.1 88/03/20 21:00:39 tony X * Initial revision X * X */ X Xchar *Version = "STEVIE - Version 3.69a"; END_OF_FILE if test 14060 -ne `wc -c <'stevie/version.c'`; then echo shar: \"'stevie/version.c'\" unpacked with wrong size! fi # end of 'stevie/version.c' fi echo shar: End of archive 7 \(of 13\). cp /dev/null ark7isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 13 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0