release 3.3, Feb 2, 1980
authorMark Horton <mark@ucbvax.Berkeley.EDU>
Fri, 1 Aug 1980 14:46:44 +0000 (06:46 -0800)
committerMark Horton <mark@ucbvax.Berkeley.EDU>
Fri, 1 Aug 1980 14:46:44 +0000 (06:46 -0800)
SCCS-vsn: usr.bin/ex/ex.c 3.1
SCCS-vsn: usr.bin/ex/ex.h 3.1
SCCS-vsn: usr.bin/ex/ex_addr.c 3.1
SCCS-vsn: usr.bin/ex/ex_argv.h 3.1
SCCS-vsn: usr.bin/ex/ex_cmds.c 3.1
SCCS-vsn: usr.bin/ex/ex_cmds2.c 3.1
SCCS-vsn: usr.bin/ex/ex_cmdsub.c 3.1
SCCS-vsn: usr.bin/ex/ex_data.c 3.1
SCCS-vsn: usr.bin/ex/ex_get.c 3.1
SCCS-vsn: usr.bin/ex/ex_io.c 3.1
SCCS-vsn: usr.bin/ex/ex_put.c 3.1
SCCS-vsn: usr.bin/ex/ex_re.c 3.1
SCCS-vsn: usr.bin/ex/ex_re.h 3.1
SCCS-vsn: usr.bin/ex/ex_set.c 3.1
SCCS-vsn: usr.bin/ex/ex_subr.c 3.1
SCCS-vsn: usr.bin/ex/ex_temp.c 3.1
SCCS-vsn: usr.bin/ex/ex_temp.h 3.1
SCCS-vsn: usr.bin/ex/ex_tty.c 3.1
SCCS-vsn: usr.bin/ex/ex_tty.h 3.1
SCCS-vsn: usr.bin/ex/ex_tune.h 3.1
SCCS-vsn: usr.bin/ex/ex_v.c 3.1
SCCS-vsn: usr.bin/ex/ex_vadj.c 3.1
SCCS-vsn: usr.bin/ex/ex_vars.h 3.1
SCCS-vsn: usr.bin/ex/ex_vget.c 3.1
SCCS-vsn: usr.bin/ex/ex_vis.h 3.1
SCCS-vsn: usr.bin/ex/ex_vmain.c 3.1
SCCS-vsn: usr.bin/ex/ex_voper.c 3.1
SCCS-vsn: usr.bin/ex/ex_vops.c 3.1
SCCS-vsn: usr.bin/ex/ex_vops2.c 3.1
SCCS-vsn: usr.bin/ex/ex_vops3.c 3.1
SCCS-vsn: usr.bin/ex/ex_vput.c 3.1
SCCS-vsn: usr.bin/ex/ex_vwind.c 3.1
SCCS-vsn: usr.bin/ex/ex3.7preserve/ex3.7preserve.c 3.1
SCCS-vsn: usr.bin/ex/ex3.7recover/ex3.7recover.c 3.1
SCCS-vsn: usr.bin/ex/Makefile 3.1
SCCS-vsn: usr.bin/ex/OTHER/makefile.70 3.1
SCCS-vsn: usr.bin/ex/makeoptions 3.1
SCCS-vsn: usr.bin/ex/printf.c 3.1

26 files changed:
usr/src/usr.bin/ex/Makefile
usr/src/usr.bin/ex/OTHER/makefile.70
usr/src/usr.bin/ex/ex.c
usr/src/usr.bin/ex/ex.h
usr/src/usr.bin/ex/ex_cmds.c
usr/src/usr.bin/ex/ex_cmds2.c
usr/src/usr.bin/ex/ex_cmdsub.c
usr/src/usr.bin/ex/ex_data.c
usr/src/usr.bin/ex/ex_get.c
usr/src/usr.bin/ex/ex_io.c
usr/src/usr.bin/ex/ex_put.c
usr/src/usr.bin/ex/ex_re.c
usr/src/usr.bin/ex/ex_set.c
usr/src/usr.bin/ex/ex_subr.c
usr/src/usr.bin/ex/ex_temp.c
usr/src/usr.bin/ex/ex_tty.c
usr/src/usr.bin/ex/ex_tty.h
usr/src/usr.bin/ex/ex_tune.h
usr/src/usr.bin/ex/ex_v.c
usr/src/usr.bin/ex/ex_vars.h
usr/src/usr.bin/ex/ex_vget.c
usr/src/usr.bin/ex/ex_vmain.c
usr/src/usr.bin/ex/ex_voper.c
usr/src/usr.bin/ex/ex_vops.c
usr/src/usr.bin/ex/ex_vops2.c
usr/src/usr.bin/ex/ex_vput.c

index c62b9d7..77f5700 100644 (file)
@@ -1,4 +1,4 @@
-VERSION=3.2
+VERSION=3.3
 #
 # Ex skeletal makefile for version 7
 #
 #
 # Ex skeletal makefile for version 7
 #
index c62b9d7..77f5700 100644 (file)
@@ -1,4 +1,4 @@
-VERSION=3.2
+VERSION=3.3
 #
 # Ex skeletal makefile for version 7
 #
 #
 # Ex skeletal makefile for version 7
 #
index e74b5c0..fbb4c3a 100644 (file)
@@ -442,6 +442,10 @@ exit(i)
        int i;
 {
 
        int i;
 {
 
+# ifdef TRACE
+       if (trace)
+               fclose(trace);
+# endif
        _exit(i);
 }
 #endif
        _exit(i);
 }
 #endif
index 9493541..e7a8d3d 100644 (file)
@@ -108,11 +108,11 @@ struct    option options[NOPTS + 1];
 #      undef   putchar
 #      undef   getchar
 #else
 #      undef   putchar
 #      undef   getchar
 #else
-#ifdef VMUNIX
+# ifdef        VMUNIX
 #      define  BUFSIZ  1024
 #      define  BUFSIZ  1024
-#else
+# else
 #      define  BUFSIZ  512
 #      define  BUFSIZ  512
-#endif
+# endif
 #      define  NULL    0
 #      define  EOF     -1
 #endif
 #      define  NULL    0
 #      define  EOF     -1
 #endif
@@ -195,6 +195,11 @@ int        xchng;                  /* Suppresses multiple "No writes" in !cmd */
  * Macros
  */
 #define        CP(a, b)        (ignore(strcpy(a, b)))
  * Macros
  */
 #define        CP(a, b)        (ignore(strcpy(a, b)))
+                       /*
+                        * FIXUNDO: do we want to mung undo vars?
+                        * Usually yes unless in a macro or global.
+                        */
+#define FIXUNDO                (inopen >= 0 && (inopen || !inglobal))
 #define ckaw()         {if (chng && value(AUTOWRITE)) wop(0);}
 #define        copy(a,b,c)     Copy((char *) a, (char *) b, c)
 #define        eq(a, b)        ((a) && (b) && strcmp(a, b) == 0)
 #define ckaw()         {if (chng && value(AUTOWRITE)) wop(0);}
 #define        copy(a,b,c)     Copy((char *) a, (char *) b, c)
 #define        eq(a, b)        ((a) && (b) && strcmp(a, b) == 0)
@@ -217,9 +222,9 @@ int xchng;                  /* Suppresses multiple "No writes" in !cmd */
  * Environment like memory
  */
 char   altfile[FNSIZE];        /* Alternate file name */
  * Environment like memory
  */
 char   altfile[FNSIZE];        /* Alternate file name */
-char   direct[32];             /* Temp file goes here */
-char   shell[32];              /* Copied to be settable */
-char   ttytype[16];            /* A long and pretty name */
+char   direct[ONMSZ];          /* Temp file goes here */
+char   shell[ONMSZ];           /* Copied to be settable */
+char   ttytype[ONMSZ];         /* A long and pretty name */
 char   uxb[UXBSIZE + 2];       /* Last !command for !! */
 
 /*
 char   uxb[UXBSIZE + 2];       /* Last !command for !! */
 
 /*
index d577f89..a85b1b2 100644 (file)
@@ -526,7 +526,6 @@ quit:
                                flush();
                                unixwt(1, unixex("-i", (char *) 0, 0, 0));
                                vcontin(0);
                                flush();
                                unixwt(1, unixex("-i", (char *) 0, 0, 0));
                                vcontin(0);
-                               putpad(TI);
                                continue;
 
 /* source */
                                continue;
 
 /* source */
@@ -598,7 +597,7 @@ quit:
                                tail("version");
                                setNAEOL();
                                /* should use SCCS subst here */
                                tail("version");
                                setNAEOL();
                                /* should use SCCS subst here */
-                               printf("Version 3.2, January 4, 1980");
+                               printf("Version 3.3, February 2, 1980");
                                noonl();
                                continue;
 
                                noonl();
                                continue;
 
@@ -620,7 +619,9 @@ quit:
                case 'w':
                        c = peekchar();
                        tail(c == 'q' ? "wq" : "write");
                case 'w':
                        c = peekchar();
                        tail(c == 'q' ? "wq" : "write");
+wq:
                        if (skipwh() && peekchar() == '!') {
                        if (skipwh() && peekchar() == '!') {
+                               pofix();
                                ignchar();
                                setall();
                                unix0(0);
                                ignchar();
                                setall();
                                unix0(0);
@@ -634,6 +635,14 @@ quit:
                                goto quit;
                        continue;
 
                                goto quit;
                        continue;
 
+/* xit */
+               case 'x':
+                       tail("xit");
+                       if (!chng)
+                               goto quit;
+                       c = 'q';
+                       goto wq;
+
 /* yank */
                case 'y':
                        tail("yank");
 /* yank */
                case 'y':
                        tail("yank");
@@ -681,14 +690,15 @@ quit:
 caseline:
                        notempty();
                        if (addr2 == 0) {
 caseline:
                        notempty();
                        if (addr2 == 0) {
-                               if (dot == dol)
-                                       error("At EOF|At end-of-file");
                                if (UP != NOSTR && c == '\n' && !inglobal)
                                        c = CTRL(k);
                                if (inglobal)
                                        addr1 = addr2 = dot;
                                if (UP != NOSTR && c == '\n' && !inglobal)
                                        c = CTRL(k);
                                if (inglobal)
                                        addr1 = addr2 = dot;
-                               else
+                               else {
+                                       if (dot == dol)
+                                               error("At EOF|At end-of-file");
                                        addr1 = addr2 = dot + 1;
                                        addr1 = addr2 = dot + 1;
+                               }
                        }
                        setdot();
                        nonzero();
                        }
                        setdot();
                        nonzero();
@@ -716,6 +726,8 @@ numberit:
                case '=':
                        newline();
                        setall();
                case '=':
                        newline();
                        setall();
+                       if (inglobal == 2)
+                               pofix();
                        printf("%d", lineno(addr2));
                        noonl();
                        continue;
                        printf("%d", lineno(addr2));
                        noonl();
                        continue;
@@ -728,12 +740,11 @@ numberit:
                                filter(2);
                        } else {
                                unix0(1);
                                filter(2);
                        } else {
                                unix0(1);
-                               vnfl();
+                               pofix();
                                putpad(TE);
                                flush();
                                unixwt(1, unixex("-c", uxb, 0, 0));
                                putpad(TE);
                                flush();
                                unixwt(1, unixex("-c", uxb, 0, 0));
-                               vcontin(1);
-                               putpad(TI);
+                               vcontin(0);
                                nochng();
                        }
                        continue;
                                nochng();
                        }
                        continue;
index 95deb53..fd1d68f 100644 (file)
@@ -158,11 +158,13 @@ error1(str)
                io = -1;
        }
        die = (getpid() != ppid);       /* Only children die */
                io = -1;
        }
        die = (getpid() != ppid);       /* Only children die */
+       inglobal = 0;
+       globp = vglobp = vmacp = 0;
        if (vcatch && !die) {
        if (vcatch && !die) {
-               inglobal = 0;
-               vglobp = vmacp = 0;
                inopen = 1;
                vcatch = 0;
                inopen = 1;
                vcatch = 0;
+               if (str)
+                       noonl();
                fixol();
                longjmp(vreslab,1);
        }
                fixol();
                longjmp(vreslab,1);
        }
@@ -173,8 +175,6 @@ error1(str)
        lseek(0, 0L, 2);
        if (inglobal)
                setlastchar('\n');
        lseek(0, 0L, 2);
        if (inglobal)
                setlastchar('\n');
-       inglobal = 0;
-       globp = 0;
        while (lastchar() != '\n' && lastchar() != EOF)
                ignchar();
        ungetchar(0);
        while (lastchar() != '\n' && lastchar() != EOF)
                ignchar();
        ungetchar(0);
@@ -449,7 +449,7 @@ ret:
 }
 
 /*
 }
 
 /*
- * Continue after a shell escape from open/visual.
+ * Continue after a : command from open/visual.
  */
 vcontin(ask)
        bool ask;
  */
 vcontin(ask)
        bool ask;
@@ -459,10 +459,24 @@ vcontin(ask)
                vcnt = -vcnt;
        if (inopen) {
                if (state != VISUAL) {
                vcnt = -vcnt;
        if (inopen) {
                if (state != VISUAL) {
-/*
-                       vtube[WECHO][0] = '*';
-                       vnfl();
-*/
+                       /*
+                        * We don't know what a shell command may have left on
+                        * the screen, so we move the cursor to the right place
+                        * and then put out a newline.  But this makes an extra
+                        * blank line most of the time so we only do it for :sh
+                        * since the prompt gets left on the screen.
+                        *
+                        * BUG: :!echo longer than current line \\c
+                        * will screw it up, but be reasonable!
+                        */
+                       if (state == CRTOPEN) {
+                               termreset();
+                               vgoto(WECHO, 0);
+                       }
+                       if (!ask) {
+                               putch('\r');
+                               putch('\n');
+                       }
                        return;
                }
                if (ask) {
                        return;
                }
                if (ask) {
@@ -473,17 +487,27 @@ vcontin(ask)
                vraw();
 #endif
                if (ask) {
                vraw();
 #endif
                if (ask) {
+#ifdef EATQS
                        /*
                         * Gobble ^Q/^S since the tty driver should be eating
                         * them (as far as the user can see)
                         */
                        while (peekkey() == CTRL(Q) || peekkey() == CTRL(S))
                                ignore(getkey());
                        /*
                         * Gobble ^Q/^S since the tty driver should be eating
                         * them (as far as the user can see)
                         */
                        while (peekkey() == CTRL(Q) || peekkey() == CTRL(S))
                                ignore(getkey());
-                       if(getkey() == ':')
+#endif
+                       if(getkey() == ':') {
+                               /* Ugh. Extra newlines, but no other way */
+                               putch('\n');
+                               outline = WECHO;
                                ungetkey(':');
                                ungetkey(':');
+                       }
+               }
+               vclrech(1);
+               if (ask && Peekkey != ':') {
+                       putpad(TI);
+                       putpad(VS);
+                       putpad(KS);
                }
                }
-               putpad(VS);
-               putpad(KS);
        }
 }
 
        }
 }
 
index 09c01d9..8bd125a 100644 (file)
@@ -27,21 +27,14 @@ append(f, a)
 
        nline = 0;
        dot = a;
 
        nline = 0;
        dot = a;
-       /*
-        * This is probably a bug, since it's different than the other tests
-        * in appendnone, delete, and deletenone. It is known to fail for
-        * the command :g/foo/r xxx (where there is one foo and the file
-        * xxx exists) and you try to undo it. I'm leaving it in for now
-        * because I'm afraid if I change it I'll break something.
-        */
-       if (!inglobal && !inopen && f != getsub) {
+       if(FIXUNDO && !inopen && f!=getsub) {
                undap1 = undap2 = dot + 1;
                undkind = UNDCHANGE;
        }
        while ((*f)() == 0) {
                if (truedol >= endcore) {
                        if (morelines() < 0) {
                undap1 = undap2 = dot + 1;
                undkind = UNDCHANGE;
        }
        while ((*f)() == 0) {
                if (truedol >= endcore) {
                        if (morelines() < 0) {
-                               if (!inglobal && f == getsub) {
+                               if (FIXUNDO && f == getsub) {
                                        undap1 = addr1;
                                        undap2 = addr2 + 1;
                                }
                                        undap1 = addr1;
                                        undap2 = addr2 + 1;
                                }
@@ -71,7 +64,7 @@ append(f, a)
 appendnone()
 {
 
 appendnone()
 {
 
-       if (inopen >= 0 && (inopen || !inglobal)) {
+       if(FIXUNDO) {
                undkind = UNDCHANGE;
                undap1 = undap2 = addr1;
        }
                undkind = UNDCHANGE;
                undap1 = undap2 = addr1;
        }
@@ -108,7 +101,7 @@ delete(hush)
        register line *a1, *a2;
 
        nonzero();
        register line *a1, *a2;
 
        nonzero();
-       if (inopen >= 0 && (inopen || !inglobal)) {
+       if(FIXUNDO) {
                register int (*dsavint)();
 
                change();
                register int (*dsavint)();
 
                change();
@@ -157,7 +150,7 @@ delete(hush)
 deletenone()
 {
 
 deletenone()
 {
 
-       if (inopen >= 0 && (inopen || !inglobal)) {
+       if(FIXUNDO) {
                undkind = UNDCHANGE;
                squish();
                unddel = addr1;
                undkind = UNDCHANGE;
                squish();
                unddel = addr1;
@@ -172,14 +165,16 @@ squish()
 {
        register line *a1 = dol + 1, *a2 = unddol + 1, *a3 = truedol + 1;
 
 {
        register line *a1 = dol + 1, *a2 = unddol + 1, *a3 = truedol + 1;
 
-       if (inopen == -1)
-               return;
-       if (a1 < a2 && a2 < a3)
-               do
-                       *a1++ = *a2++;
-               while (a2 < a3);
-       truedol -= unddol - dol;
-       unddol = dol;
+       if(FIXUNDO) {
+               if (inopen == -1)
+                       return;
+               if (a1 < a2 && a2 < a3)
+                       do
+                               *a1++ = *a2++;
+                       while (a2 < a3);
+               truedol -= unddol - dol;
+               unddol = dol;
+       }
 }
 
 /*
 }
 
 /*
@@ -294,16 +289,18 @@ move1(cflag, addrt)
                error("Move to a moved line");
        change();
        if (!inglobal)
                error("Move to a moved line");
        change();
        if (!inglobal)
-               if (cflag) {
-                       undap1 = addrt + 1;
-                       undap2 = undap1 + lines;
-                       deletenone();
-               } else {
-                       undkind = UNDMOVE;
-                       undap1 = addr1;
-                       undap2 = addr2;
-                       unddel = addrt;
-                       squish();
+               if(FIXUNDO) {
+                       if (cflag) {
+                               undap1 = addrt + 1;
+                               undap2 = undap1 + lines;
+                               deletenone();
+                       } else {
+                               undkind = UNDMOVE;
+                               undap1 = addr1;
+                               undap2 = addr2;
+                               unddel = addrt;
+                               squish();
+                       }
                }
 }
 
                }
 }
 
@@ -333,6 +330,8 @@ put()
 {
        register int cnt;
 
 {
        register int cnt;
 
+       if (!FIXUNDO)
+               error("Cannot put inside global/macro");
        cnt = unddol - dol;
        if (cnt && inopen && pkill[0] && pkill[1]) {
                pragged(1);
        cnt = unddol - dol;
        if (cnt && inopen && pkill[0] && pkill[1]) {
                pragged(1);
@@ -397,7 +396,7 @@ shift(c, cnt)
        char *dp;
        register int i;
 
        char *dp;
        register int i;
 
-       if (!inglobal)
+       if(FIXUNDO)
                save12(), undkind = UNDCHANGE;
        cnt *= value(SHIFTWIDTH);
        for (addr = addr1; addr <= addr2; addr++) {
                save12(), undkind = UNDCHANGE;
        cnt *= value(SHIFTWIDTH);
        for (addr = addr1; addr <= addr2; addr++) {
@@ -449,11 +448,27 @@ tagfind(quick)
 {
        char cmdbuf[BUFSIZ];
        char filebuf[FNSIZE];
 {
        char cmdbuf[BUFSIZ];
        char filebuf[FNSIZE];
+       char tagfbuf[128];
        register int c, d;
        bool samef = 1;
        register int c, d;
        bool samef = 1;
-       bool notagsfile = 0;
-       short master = -1;
-       short omagic;
+       int tfcount = 0;
+       int omagic;
+       char *fn, *fne;
+#ifdef VMUNIX
+       /*
+        * We have lots of room so we bring in stdio and do
+        * a binary search on the tags file.
+        */
+# undef EOF
+# include <stdio.h>
+# undef getchar
+# undef putchar
+       FILE *iof;
+       char iofbuf[BUFSIZ];
+       long mid;       /* assumed byte offset */
+       long top, bot;  /* length of tag file */
+       struct stat sbuf;
+#endif
 
        omagic = value(MAGIC);
        if (!skipend()) {
 
        omagic = value(MAGIC);
        if (!skipend()) {
@@ -476,20 +491,76 @@ badtag:
        if (c == EOF)
                ungetchar(c);
        clrstats();
        if (c == EOF)
                ungetchar(c);
        clrstats();
-       do {
-               io = open(master ? "tags" : MASTERTAGS, 0);
-               if (master && io < 0)
-                       notagsfile = 1;
+
+       /*
+        * Loop once for each file in tags "path".
+        */
+       CP(tagfbuf, svalue(TAGS));
+       fne = tagfbuf - 1;
+       while (fne) {
+               fn = ++fne;
+               while (*fne && *fne != ' ')
+                       fne++;
+               if (*fne == 0)
+                       fne = 0;        /* done, quit after this time */
+               else
+                       *fne = 0;       /* null terminate filename */
+#ifdef VMUNIX
+               iof = fopen(fn, "r");
+               if (iof == NULL)
+                       continue;
+               tfcount++;
+               setbuf(iof, iofbuf);
+               fstat(fileno(iof), &sbuf);
+               top = sbuf.st_size;
+               if (top == 0L || iof == NULL)
+                       top = -1L;
+               bot = 0L;
+               while (top >= bot) {
+#else
+               /*
+                * Avoid stdio and scan tag file linearly.
+                */
+               io = open(fn, 0);
+               if (io<0)
+                       continue;
                while (getfile() == 0) {
                while (getfile() == 0) {
+#endif
+                       /* loop for each tags file entry */
                        register char *cp = linebuf;
                        register char *lp = lasttag;
                        char *oglobp;
 
                        register char *cp = linebuf;
                        register char *lp = lasttag;
                        char *oglobp;
 
+#ifdef VMUNIX
+                       mid = (top + bot) / 2;
+                       fseek(iof, mid, 0);
+                       if (mid > 0)    /* to get first tag in file to work */
+                               fgets(linebuf, sizeof linebuf, iof);    /* scan to next \n */
+                       fgets(linebuf, sizeof linebuf, iof);    /* get a line */
+                       linebuf[strlen(linebuf)-1] = 0; /* was '\n' */
+#endif
                        while (*cp && *lp == *cp)
                                cp++, lp++;
                        while (*cp && *lp == *cp)
                                cp++, lp++;
-                       if (*lp || !iswhite(*cp))
+                       if (*lp || !iswhite(*cp)) {
+#ifdef VMUNIX
+                               if (*lp > *cp)
+                                       bot = mid + 1;
+                               else
+                                       top = mid - 1;
+#endif
+                               /* Not this tag.  Try the next */
                                continue;
                                continue;
+                       }
+
+                       /*
+                        * We found the tag.  Decode the line in the file.
+                        */
+#ifdef VMUNIX
+                       fclose(iof);
+#else
                        close(io);
                        close(io);
+#endif
+                       /* name of file */
                        while (*cp && iswhite(*cp))
                                cp++;
                        if (!*cp)
                        while (*cp && iswhite(*cp))
                                cp++;
                        if (!*cp)
@@ -502,6 +573,7 @@ badtags:
                                cp++;
                        }
                        *lp++ = 0;
                                cp++;
                        }
                        *lp++ = 0;
+
                        if (*cp == 0)
                                goto badtags;
                        if (dol != zero) {
                        if (*cp == 0)
                                goto badtags;
                        if (dol != zero) {
@@ -520,6 +592,7 @@ badtags:
                        if (strcmp(filebuf, savedfile) || !edited) {
                                char cmdbuf2[sizeof filebuf + 10];
 
                        if (strcmp(filebuf, savedfile) || !edited) {
                                char cmdbuf2[sizeof filebuf + 10];
 
+                               /* Different file.  Do autowrite & get it. */
                                if (!quick) {
                                        ckaw();
                                        if (chng && dol > zero)
                                if (!quick) {
                                        ckaw();
                                        if (chng && dol > zero)
@@ -530,33 +603,46 @@ badtags:
                                strcat(cmdbuf2, filebuf);
                                globp = cmdbuf2;
                                d = peekc; ungetchar(0);
                                strcat(cmdbuf2, filebuf);
                                globp = cmdbuf2;
                                d = peekc; ungetchar(0);
-                               /*
-                                * BUG: if it isn't found (user edited header
-                                * line) we get left in nomagic mode.
-                                */
-                               value(MAGIC) = 0;
                                commands(1, 1);
                                peekc = d;
                                globp = oglobp;
                                value(MAGIC) = omagic;
                                samef = 0;
                        }
                                commands(1, 1);
                                peekc = d;
                                globp = oglobp;
                                value(MAGIC) = omagic;
                                samef = 0;
                        }
+
+                       /*
+                        * Look for pattern in the current file.
+                        */
                        oglobp = globp;
                        globp = cmdbuf;
                        d = peekc; ungetchar(0);
                        if (samef)
                                markpr(dot);
                        oglobp = globp;
                        globp = cmdbuf;
                        d = peekc; ungetchar(0);
                        if (samef)
                                markpr(dot);
+                       /*
+                        * BUG: if it isn't found (user edited header
+                        * line) we get left in nomagic mode.
+                        */
                        value(MAGIC) = 0;
                        commands(1, 1);
                        peekc = d;
                        globp = oglobp;
                        value(MAGIC) = omagic;
                        return;
                        value(MAGIC) = 0;
                        commands(1, 1);
                        peekc = d;
                        globp = oglobp;
                        value(MAGIC) = omagic;
                        return;
-               }
-       } while (++master == 0);
-       if (notagsfile)
+               }       /* end of "for each tag in file" */
+
+               /*
+                * No such tag in this file.  Close it and try the next.
+                */
+#ifdef VMUNIX
+               fclose(iof);
+#else
+               close(io);
+#endif
+       }       /* end of "for each file in path" */
+       if (tfcount <= 0)
                error("No tags file");
                error("No tags file");
-       serror("%s: No such tag@in tags file", lasttag);
+       else
+               serror("%s: No such tag@in tags file", lasttag);
 }
 
 /*
 }
 
 /*
@@ -566,6 +652,8 @@ badtags:
 yank()
 {
 
 yank()
 {
 
+       if (!FIXUNDO)
+               error("Can't yank inside global/macro");
        save12();
        undkind = UNDNONE;
        killcnt(addr2 - addr1 + 1);
        save12();
        undkind = UNDNONE;
        killcnt(addr2 - addr1 + 1);
@@ -787,6 +875,10 @@ undo(c)
        register line *jp, *kp;
        line *dolp1, *newdol, *newadot;
 
        register line *jp, *kp;
        line *dolp1, *newdol, *newadot;
 
+#ifdef TRACE
+       if (trace)
+               vudump("before undo");
+#endif
        if (inglobal && inopen <= 0)
                error("Can't undo in global@commands");
        if (!c)
        if (inglobal && inopen <= 0)
                error("Can't undo in global@commands");
        if (!c)
@@ -890,11 +982,15 @@ undo(c)
                if (undkind == UNDALL) {
                        dot = undadot;
                        undadot = newadot;
                if (undkind == UNDALL) {
                        dot = undadot;
                        undadot = newadot;
-               }
-               undkind = UNDCHANGE;
+               } else
+                       undkind = UNDCHANGE;
        }
        if (dot == zero && dot != dol)
                dot = one;
        }
        if (dot == zero && dot != dol)
                dot = one;
+#ifdef TRACE
+       if (trace)
+               vudump("after undo");
+#endif
 }
 
 /*
 }
 
 /*
@@ -945,7 +1041,9 @@ mapcmd(un)
        register char *p;
        register char c;
        char *dname;
        register char *p;
        register char c;
        char *dname;
+       struct maps *mp;        /* the map structure we are working on */
 
 
+       mp = exclam() ? immacs : arrows;
        if (skipend()) {
                int i;
 
        if (skipend()) {
                int i;
 
@@ -954,13 +1052,13 @@ mapcmd(un)
                        ignchar();
                if (inopen)
                        pofix();
                        ignchar();
                if (inopen)
                        pofix();
-               for (i=0; arrows[i].mapto; i++)
-                       if (arrows[i].cap) {
-                               lprintf("%s", arrows[i].descr);
+               for (i=0; mp[i].mapto; i++)
+                       if (mp[i].cap) {
+                               lprintf("%s", mp[i].descr);
                                putchar('\t');
                                putchar('\t');
-                               lprintf("%s", arrows[i].cap);
+                               lprintf("%s", mp[i].cap);
                                putchar('\t');
                                putchar('\t');
-                               lprintf("%s", arrows[i].mapto);
+                               lprintf("%s", mp[i].mapto);
                                putNFL();
                        }
                return;
                                putNFL();
                        }
                return;
@@ -980,7 +1078,7 @@ mapcmd(un)
                        ungetchar(c);
                        if (un) {
                                newline();
                        ungetchar(c);
                        if (un) {
                                newline();
-                               addmac(lhs, NOSTR, NOSTR);
+                               addmac(lhs, NOSTR, NOSTR, mp);
                                return;
                        } else
                                error("Missing rhs");
                                return;
                        } else
                                error("Missing rhs");
@@ -1020,27 +1118,29 @@ mapcmd(un)
        } else {
                dname = lhs;
        }
        } else {
                dname = lhs;
        }
-       addmac(lhs,rhs,dname);
+       addmac(lhs,rhs,dname,mp);
 }
 
 /*
  * Add a macro definition to those that already exist. The sequence of
  * chars "src" is mapped into "dest". If src is already mapped into something
  * this overrides the mapping. There is no recursion. Unmap is done by
 }
 
 /*
  * Add a macro definition to those that already exist. The sequence of
  * chars "src" is mapped into "dest". If src is already mapped into something
  * this overrides the mapping. There is no recursion. Unmap is done by
- * using NOSTR for dest.
+ * using NOSTR for dest.  Dname is what to show in listings.  mp is
+ * the structure to affect (arrows, etc).
  */
  */
-addmac(src,dest,dname)
+addmac(src,dest,dname,mp)
        register char *src, *dest, *dname;
        register char *src, *dest, *dname;
+       register struct maps *mp;
 {
        register int slot, zer;
 
 {
        register int slot, zer;
 
-       if (dest) {
+       if (dest && mp==arrows) {
                /* Make sure user doesn't screw himself */
                /*
                 * Prevent tail recursion. We really should be
                 * checking to see if src is a suffix of dest
                /* Make sure user doesn't screw himself */
                /*
                 * Prevent tail recursion. We really should be
                 * checking to see if src is a suffix of dest
-                * but we are too lazy here, so we don't bother unless
-                * src is only 1 char long.
+                * but this makes mapping involving escapes that
+                * is reasonable mess up.
                 */
                if (src[1] == 0 && src[0] == dest[strlen(dest)-1])
                        error("No tail recursion");
                 */
                if (src[1] == 0 && src[0] == dest[strlen(dest)-1])
                        error("No tail recursion");
@@ -1053,19 +1153,24 @@ addmac(src,dest,dname)
                 */
                if (isalpha(src[0]) && src[1] || any(src[0],":"))
                        error("Too dangerous to map that");
                 */
                if (isalpha(src[0]) && src[1] || any(src[0],":"))
                        error("Too dangerous to map that");
-               /*
-                * If the src were null it would cause the dest to
-                * be mapped always forever. This is not good.
-                */
-               if (src[0] == 0)
-                       error("Null lhs");
        }
        }
+       else if (dest) {
+               /* check for tail recursion in input mode: fussier */
+               if (eq(src, dest+strlen(dest)-strlen(src)))
+                       error("No tail recursion");
+       }
+       /*
+        * If the src were null it would cause the dest to
+        * be mapped always forever. This is not good.
+        */
+       if (src == NOSTR || src[0] == 0)
+               error("Missing lhs");
 
        /* see if we already have a def for src */
        zer = -1;
 
        /* see if we already have a def for src */
        zer = -1;
-       for (slot=0; arrows[slot].mapto; slot++) {
-               if (arrows[slot].cap) {
-                       if (eq(src, arrows[slot].cap))
+       for (slot=0; mp[slot].mapto; slot++) {
+               if (mp[slot].cap) {
+                       if (eq(src, mp[slot].cap))
                                break;  /* if so, reuse slot */
                } else {
                        zer = slot;     /* remember an empty slot */
                                break;  /* if so, reuse slot */
                } else {
                        zer = slot;     /* remember an empty slot */
@@ -1074,9 +1179,9 @@ addmac(src,dest,dname)
 
        if (dest == NOSTR) {
                /* unmap */
 
        if (dest == NOSTR) {
                /* unmap */
-               if (arrows[slot].cap) {
-                       arrows[slot].cap = NOSTR;
-                       arrows[slot].descr = NOSTR;
+               if (mp[slot].cap) {
+                       mp[slot].cap = NOSTR;
+                       mp[slot].descr = NOSTR;
                } else {
                        error("Not mapped|That macro wasn't mapped");
                }
                } else {
                        error("Not mapped|That macro wasn't mapped");
                }
@@ -1084,7 +1189,7 @@ addmac(src,dest,dname)
        }
 
        /* reuse empty slot, if we found one and src isn't already defined */
        }
 
        /* reuse empty slot, if we found one and src isn't already defined */
-       if (zer >= 0 && arrows[slot].mapto == 0)
+       if (zer >= 0 && mp[slot].mapto == 0)
                slot = zer;
 
        /* if not, append to end */
                slot = zer;
 
        /* if not, append to end */
@@ -1096,18 +1201,18 @@ addmac(src,dest,dname)
        if (msnext - mapspace + strlen(dest) + strlen(src) + strlen(dname) + 3 > MAXCHARMACS)
                error("Too much macro text");
        CP(msnext, src);
        if (msnext - mapspace + strlen(dest) + strlen(src) + strlen(dname) + 3 > MAXCHARMACS)
                error("Too much macro text");
        CP(msnext, src);
-       arrows[slot].cap = msnext;
+       mp[slot].cap = msnext;
        msnext += strlen(src) + 1;      /* plus 1 for null on the end */
        CP(msnext, dest);
        msnext += strlen(src) + 1;      /* plus 1 for null on the end */
        CP(msnext, dest);
-       arrows[slot].mapto = msnext;
+       mp[slot].mapto = msnext;
        msnext += strlen(dest) + 1;
        if (dname) {
                CP(msnext, dname);
        msnext += strlen(dest) + 1;
        if (dname) {
                CP(msnext, dname);
-               arrows[slot].descr = msnext;
+               mp[slot].descr = msnext;
                msnext += strlen(dname) + 1;
        } else {
                /* default descr to string user enters */
                msnext += strlen(dname) + 1;
        } else {
                /* default descr to string user enters */
-               arrows[slot].descr = src;
+               mp[slot].descr = src;
        }
 }
 
        }
 }
 
index 402d208..dd29535 100644 (file)
@@ -6,21 +6,28 @@
  * Initialization of option values.
  * The option #defines in ex_vars.h are made
  * from this file by the script makeoptions.
  * Initialization of option values.
  * The option #defines in ex_vars.h are made
  * from this file by the script makeoptions.
+ *
+ * These initializations are done char by char instead of as strings
+ * to confuse xstr so it will leave them alone.
  */
  */
-char   direct[32] =
+char   direct[ONMSZ] =
        { '/', 't', 'm', 'p' };
        { '/', 't', 'm', 'p' };
-char   sections[32] = {
-       'N', 'H', 'S', 'H',                             /* -ms macros */
-       'H', ' ', 'H', 'U'                              /* -mm macros */
-};
-char   paragraphs[32] = {
+char   paragraphs[ONMSZ] = {
        'I', 'P', 'L', 'P', 'P', 'P', 'Q', 'P',         /* -ms macros */
        'P', ' ', 'L', 'I',                             /* -mm macros */
        'b', 'p'                                        /* bare nroff */
 };
        'I', 'P', 'L', 'P', 'P', 'P', 'Q', 'P',         /* -ms macros */
        'P', ' ', 'L', 'I',                             /* -mm macros */
        'b', 'p'                                        /* bare nroff */
 };
-char   shell[32] =
+char   sections[ONMSZ] = {
+       'N', 'H', 'S', 'H',                             /* -ms macros */
+       'H', ' ', 'H', 'U'                              /* -mm macros */
+};
+char   shell[ONMSZ] =
        { '/', 'b', 'i', 'n', '/', 's', 'h' };
        { '/', 'b', 'i', 'n', '/', 's', 'h' };
-char   ttytype[16] =
+char   tags[ONMSZ] = {
+       't', 'a', 'g', 's', ' ',
+       '/', 'u', 's', 'r', '/', 'l', 'i', 'b', '/', 't', 'a', 'g', 's'
+};
+char   ttytype[ONMSZ] =
        { 'd', 'u', 'm', 'b' };
 
 short  COLUMNS = 80;
        { 'd', 'u', 'm', 'b' };
 
 short  COLUMNS = 80;
@@ -39,13 +46,13 @@ struct      option options[NOPTS + 1] = {
        "lisp",         0,      ONOFF,          0,      0,      0,
        "list",         0,      ONOFF,          0,      0,      0,
        "magic",        0,      ONOFF,          1,      1,      0,
        "lisp",         0,      ONOFF,          0,      0,      0,
        "list",         0,      ONOFF,          0,      0,      0,
        "magic",        0,      ONOFF,          1,      1,      0,
-       "mapinput",     "mi",   ONOFF,          0,      0,      0,
        "number",       "nu",   ONOFF,          0,      0,      0,
        "open",         0,      ONOFF,          1,      1,      0,
        "optimize",     "opt",  ONOFF,          0,      0,      0,
        "paragraphs",   "para", STRING,         0,      0,      paragraphs,
        "prompt",       0,      ONOFF,          1,      1,      0,
        "redraw",       0,      ONOFF,          0,      0,      0,
        "number",       "nu",   ONOFF,          0,      0,      0,
        "open",         0,      ONOFF,          1,      1,      0,
        "optimize",     "opt",  ONOFF,          0,      0,      0,
        "paragraphs",   "para", STRING,         0,      0,      paragraphs,
        "prompt",       0,      ONOFF,          1,      1,      0,
        "redraw",       0,      ONOFF,          0,      0,      0,
+       "remap",        0,      ONOFF,          1,      1,      0,
        "report",       0,      NUMERIC,        5,      5,      0,
        "scroll",       "scr",  NUMERIC,        12,     12,     0,
        "sections",     "sect", STRING,         0,      0,      sections,
        "report",       0,      NUMERIC,        5,      5,      0,
        "scroll",       "scr",  NUMERIC,        12,     12,     0,
        "sections",     "sect", STRING,         0,      0,      sections,
@@ -53,10 +60,13 @@ struct      option options[NOPTS + 1] = {
        "shiftwidth",   "sw",   NUMERIC,        TABS,   TABS,   0,
        "showmatch",    "sm",   ONOFF,          0,      0,      0,
        "slowopen",     "slow", ONOFF,          0,      0,      0,
        "shiftwidth",   "sw",   NUMERIC,        TABS,   TABS,   0,
        "showmatch",    "sm",   ONOFF,          0,      0,      0,
        "slowopen",     "slow", ONOFF,          0,      0,      0,
+       "tags",         "tag",  STRING,         0,      0,      tags,
        "tabstop",      "ts",   NUMERIC,        TABS,   TABS,   0,
        "tabstop",      "ts",   NUMERIC,        TABS,   TABS,   0,
-       "ttytype",      "tty",  OTERM,          0,      0,      ttytype,
        "term",         0,      OTERM,          0,      0,      ttytype,
        "terse",        0,      ONOFF,          0,      0,      0,
        "term",         0,      OTERM,          0,      0,      ttytype,
        "terse",        0,      ONOFF,          0,      0,      0,
+       "timeout",      "to",   ONOFF,          1,      1,      0,
+       "ttytype",      "tty",  OTERM,          0,      0,      ttytype,
+       "undomacro",    "um",   ONOFF,          1,      1,      0,
        "warn",         0,      ONOFF,          1,      1,      0,
        "window",       "wi",   NUMERIC,        23,     23,     0,
        "wrapscan",     "ws",   ONOFF,          1,      1,      0,
        "warn",         0,      ONOFF,          1,      1,      0,
        "window",       "wi",   NUMERIC,        23,     23,     0,
        "wrapscan",     "ws",   ONOFF,          1,      1,      0,
index 4d19535..873a511 100644 (file)
@@ -12,11 +12,7 @@ short        lastc = '\n';
 
 ignchar()
 {
 
 ignchar()
 {
-       register int c;
-
-       do
-               c = getcd();
-       while (c == CTRL(d));
+       ignore(getchar());
 }
 
 getchar()
 }
 
 getchar()
@@ -25,7 +21,7 @@ getchar()
 
        do
                c = getcd();
 
        do
                c = getcd();
-       while (c == CTRL(d));
+       while (!globp && c == CTRL(d));
        return (c);
 }
 
        return (c);
 }
 
@@ -39,7 +35,7 @@ again:
                return (c);
        c &= TRIM;
        if (!inopen)
                return (c);
        c &= TRIM;
        if (!inopen)
-               if (c == CTRL(d))
+               if (!globp && c == CTRL(d))
                        setlastchar('\n');
                else if (junk(c)) {
                        checkjunk(c);
                        setlastchar('\n');
                else if (junk(c)) {
                        checkjunk(c);
index d22f82e..3f0a227 100644 (file)
@@ -218,6 +218,8 @@ glob(gp)
                close(1);
                dup(pvec[1]);
                close(pvec[0]);
                close(1);
                dup(pvec[1]);
                close(pvec[0]);
+               close(2);       /* so errors don't mess up the screen */
+               open("/dev/null", 1);
                execl(svalue(SHELL), "sh", "-c", genbuf, 0);
                oerrno = errno; close(1); dup(2); errno = oerrno;
                filioerr(svalue(SHELL));
                execl(svalue(SHELL), "sh", "-c", genbuf, 0);
                oerrno = errno; close(1); dup(2); errno = oerrno;
                filioerr(svalue(SHELL));
@@ -248,7 +250,7 @@ glob(gp)
        } while (c >= 0);
        waitfor();
        if (gp->argc0 == 0)
        } while (c >= 0);
        waitfor();
        if (gp->argc0 == 0)
-               error(NOSTR);
+               error("No match");
 }
 
 /*
 }
 
 /*
@@ -346,7 +348,7 @@ rop(c)
                setdot();
        else
                setall();
                setdot();
        else
                setall();
-       if (inopen && c == 'r')
+       if (FIXUNDO && inopen && c == 'r')
                undap1 = undap2 = dot + 1;
        rop2();
        rop3(c);
                undap1 = undap2 = dot + 1;
        rop2();
        rop3(c);
@@ -389,7 +391,8 @@ other:
                                        dot = one;
                                markpr(one);
                        }
                                        dot = one;
                                markpr(one);
                        }
-               undkind = UNDNONE;
+               if(FIXUNDO)
+                       undkind = UNDNONE;
                if (inopen) {
                        vcline = 0;
                        vreplace(0, LINES, lineDOL());
                if (inopen) {
                        vcline = 0;
                        vreplace(0, LINES, lineDOL());
@@ -442,6 +445,8 @@ bool dofname;       /* if 1 call filename, else use savedfile */
                        error("Write forms are 'w' and 'w>>'");
                filename('w');
        } else {
                        error("Write forms are 'w' and 'w>>'");
                filename('w');
        } else {
+               if (savedfile[0] == 0)
+                       error("No file|No current filename");
                saddr1=addr1;
                saddr2=addr2;
                addr1=one;
                saddr1=addr1;
                saddr2=addr2;
                addr1=one;
@@ -632,7 +637,7 @@ uexp:
                        vnfl();
                if (hush == 0)
                        lprintf("!%s", uxb);
                        vnfl();
                if (hush == 0)
                        lprintf("!%s", uxb);
-               if (inopen) {
+               if (inopen && Outchar != termchar) {
                        vclreol();
                        vgoto(WECHO, 0);
                } else
                        vclreol();
                        vgoto(WECHO, 0);
                } else
@@ -779,7 +784,8 @@ filter(mode)
                addr2 = addr1 - 1;
        }
        if (mode & 1) {
                addr2 = addr1 - 1;
        }
        if (mode & 1) {
-               undap1 = undap2 = addr2+1;
+               if(FIXUNDO)
+                       undap1 = undap2 = addr2+1;
                ignore(append(getfile, addr2));
        }
        close(io);
                ignore(append(getfile, addr2));
        }
        close(io);
index c184d88..033c05b 100644 (file)
@@ -554,10 +554,25 @@ dontcr:
                }
        }
        while (outcol < destcol) {
                }
        }
        while (outcol < destcol) {
-               if (inopen && ND)
+               /*
+                * move one char to the right.  We don't use ND space
+                * because it's better to just print the char we are
+                * moving over.  There are various exceptions, however.
+                * If !inopen, vtube contains garbage.  If the char is
+                * a null or a tab we want to print a space.  Other random
+                * chars we use space for instead, too.
+                */
+#ifdef TRACE
+               if (trace)
+                       fprintf(trace, "ND: inopen=%d, i=%d, outline=%d, outcol=%d\n", inopen, i, outline, outcol);
+#endif
+               if (!inopen || vtube[outline]==NULL ||
+                       (i=vtube[outline][outcol]) < ' ')
+                       i = ' ';
+               if (insmode && ND)
                        tputs(ND, 0, plodput);
                else
                        tputs(ND, 0, plodput);
                else
-                       plodput(' ');
+                       plodput(i);
                outcol++;
                if (plodcnt < 0)
                        goto out;
                outcol++;
                if (plodcnt < 0)
                        goto out;
@@ -768,7 +783,7 @@ ostart()
 #else
        tty.sg_flags = (normf &~ (ECHO|XTABS|CRMOD)) | RAW;
 #endif
 #else
        tty.sg_flags = (normf &~ (ECHO|XTABS|CRMOD)) | RAW;
 #endif
-#ifdef TIOCGETC
+#ifdef EATQS
        nttyc.t_quitc = nttyc.t_startc = nttyc.t_stopc = '\377';
 #endif
        sTTY(1);
        nttyc.t_quitc = nttyc.t_startc = nttyc.t_stopc = '\377';
 #endif
        sTTY(1);
@@ -835,7 +850,7 @@ setty(f)
 {
        register int ot = tty.sg_flags;
 
 {
        register int ot = tty.sg_flags;
 
-#ifdef TIOCGETC
+#ifdef EATQS
        if (f == normf)
                nttyc = ottyc;
        else
        if (f == normf)
                nttyc = ottyc;
        else
@@ -851,7 +866,7 @@ gTTY(i)
 {
 
        ignore(gtty(i, &tty));
 {
 
        ignore(gtty(i, &tty));
-#ifdef TIOCGETC
+#ifdef EATQS
        ioctl(i, TIOCGETC, &ottyc);
        nttyc = ottyc;
 #endif
        ioctl(i, TIOCGETC, &ottyc);
        nttyc = ottyc;
 #endif
@@ -873,7 +888,7 @@ sTTY(i)
 #else
        stty(i, &tty);
 #endif
 #else
        stty(i, &tty);
 #endif
-#ifdef TIOCSETC
+#ifdef EATQS
        ioctl(i, TIOCSETC, &nttyc);
 #endif
 }
        ioctl(i, TIOCSETC, &nttyc);
 #endif
 }
index 93abfaa..cf06929 100644 (file)
@@ -73,6 +73,7 @@ out:
        newline();
        *gp++ = c;
        *gp++ = 0;
        newline();
        *gp++ = c;
        *gp++ = 0;
+       saveall();
        inglobal = 2;
        for (a1 = one; a1 <= dol; a1++) {
                *a1 &= ~01;
        inglobal = 2;
        for (a1 = one; a1 <= dol; a1++) {
                *a1 &= ~01;
@@ -80,7 +81,6 @@ out:
                        *a1 |= 01;
        }
        /* should use gdelete from ed to avoid n**2 here on g/.../d */
                        *a1 |= 01;
        }
        /* should use gdelete from ed to avoid n**2 here on g/.../d */
-       saveall();
        if (inopen)
                inopen = -1;
        for (a1 = one; a1 <= dol; a1++) {
        if (inopen)
                inopen = -1;
        for (a1 = one; a1 <= dol; a1++) {
@@ -115,7 +115,7 @@ substitute(c)
        int gsubf;
 
        gsubf = compsub(c);
        int gsubf;
 
        gsubf = compsub(c);
-       if (!inglobal)
+       if(FIXUNDO)
                save12(), undkind = UNDCHANGE;
        stotal = 0;
        slines = 0;
                save12(), undkind = UNDCHANGE;
        stotal = 0;
        slines = 0;
@@ -257,8 +257,10 @@ magic:
 
                case '\n':
                case EOF:
 
                case '\n':
                case EOF:
-                       ungetchar(c);
-                       goto endrhs;
+                       if (!(globp && globp[0])) {
+                               ungetchar(c);
+                               goto endrhs;
+                       }
 
                case '~':
                case '&':
 
                case '~':
                case '&':
index 721836c..bb7f2d8 100644 (file)
@@ -13,6 +13,7 @@ set()
        register struct option *op;
        register int c;
        bool no;
        register struct option *op;
        register int c;
        bool no;
+       extern short ospeed;
 
        setnoaddr();
        if (skipend()) {
 
        setnoaddr();
        if (skipend()) {
@@ -26,7 +27,7 @@ set()
                do {
                        if (cp < &optname[ONMSZ - 2])
                                *cp++ = getchar();
                do {
                        if (cp < &optname[ONMSZ - 2])
                                *cp++ = getchar();
-               } while (isalpha(peekchar()));
+               } while (isalnum(peekchar()));
                *cp = 0;
                cp = optname;
                if (eq("all", cp)) {
                *cp = 0;
                cp = optname;
                if (eq("all", cp)) {
@@ -40,6 +41,24 @@ set()
                        cp += 2;
                        no++;
                }
                        cp += 2;
                        no++;
                }
+               /* Implement w300, w1200, and w9600 specially */
+               if (eq(cp, "w300")) {
+                       if (ospeed >= B1200) {
+dontset:
+                               ignore(getchar());      /* = */
+                               ignore(getnum());       /* value */
+                               continue;
+                       }
+                       cp = "window";
+               } else if (eq(cp, "w1200")) {
+                       if (ospeed < B1200 || ospeed >= B2400)
+                               goto dontset;
+                       cp = "window";
+               } else if (eq(cp, "w9600")) {
+                       if (ospeed < B2400)
+                               goto dontset;
+                       cp = "window";
+               }
                for (op = options; op < &options[NOPTS]; op++)
                        if (eq(op->oname, cp) || op->oabbrev && eq(op->oabbrev, cp))
                                break;
                for (op = options; op < &options[NOPTS]; op++)
                        if (eq(op->oname, cp) || op->oabbrev && eq(op->oabbrev, cp))
                                break;
@@ -67,10 +86,12 @@ printone:
 
                case NUMERIC:
                        if (!isdigit(peekchar()))
 
                case NUMERIC:
                        if (!isdigit(peekchar()))
-error("Digits required@after = when assigning numeric option");
+                               error("Digits required@after =");
                        op->ovalue = getnum();
                        if (value(TABSTOP) <= 0)
                                value(TABSTOP) = TABS;
                        op->ovalue = getnum();
                        if (value(TABSTOP) <= 0)
                                value(TABSTOP) = TABS;
+                       if (op == &options[WINDOW])
+                               vsetsiz(value(WINDOW));
                        break;
 
                case STRING:
                        break;
 
                case STRING:
index 1e17f4c..babd233 100644 (file)
@@ -510,6 +510,12 @@ save(a1, a2)
 {
        register int more;
 
 {
        register int more;
 
+       if (!FIXUNDO)
+               return;
+#ifdef TRACE
+       if (trace)
+               vudump("before save");
+#endif
        undkind = UNDNONE;
        undadot = dot;
        more = (a2 - a1 + 1) - (unddol - dol);
        undkind = UNDNONE;
        undadot = dot;
        more = (a2 - a1 + 1) - (unddol - dol);
@@ -526,6 +532,10 @@ save(a1, a2)
        unddel = a1 - 1;
        undap1 = a1;
        undap2 = a2 + 1;
        unddel = a1 - 1;
        undap1 = a1;
        undap2 = a2 + 1;
+#ifdef TRACE
+       if (trace)
+               vudump("after save");
+#endif
 }
 
 save12()
 }
 
 save12()
@@ -596,11 +606,11 @@ smerror(seekpt, cp)
 #ifdef lint
 char   *std_errlist[] = {
 #else
 #ifdef lint
 char   *std_errlist[] = {
 #else
-#ifdef VMUNIX
+# ifdef VMUNIX
 char   *std_errlist[] = {
 char   *std_errlist[] = {
-#else
+# else
 short  std_errlist[] = {
 short  std_errlist[] = {
-#endif
+# endif
 #endif
        error("Error 0"),
        error("Not super-user"),
 #endif
        error("Error 0"),
        error("Not super-user"),
index e8f8780..3f4bc5a 100644 (file)
@@ -275,7 +275,11 @@ struct     rbuf {
        short   rb_next;
        char    rb_text[BUFSIZ - 2 * sizeof (short)];
 } *rbuf;
        short   rb_next;
        char    rb_text[BUFSIZ - 2 * sizeof (short)];
 } *rbuf;
+#ifdef VMUNIX
+short  rused[256];
+#else
 short  rused[32];
 short  rused[32];
+#endif
 short  rnleft;
 short  rblock;
 short  rnext;
 short  rnleft;
 short  rblock;
 short  rnext;
@@ -396,17 +400,20 @@ putreg(c)
                error("Nothing in register %c", c);
        }
        if (inopen && partreg(c)) {
                error("Nothing in register %c", c);
        }
        if (inopen && partreg(c)) {
+               if (!FIXUNDO) {
+                       splitw++; vclean(); vgoto(WECHO, 0); vreg = -1;
+                       error("Can't put partial line inside macro");
+               }
                squish();
                addr1 = addr2 = dol;
        }
                squish();
                addr1 = addr2 = dol;
        }
-       ignore(append(getREG, addr2));
+       cnt = append(getREG, addr2);
        if (inopen && partreg(c)) {
                unddol = dol;
                dol = odol;
                dot = odot;
                pragged(0);
        }
        if (inopen && partreg(c)) {
                unddol = dol;
                dol = odol;
                dot = odot;
                pragged(0);
        }
-       cnt = undap2 - undap1;
        killcnt(cnt);
        notecnt = cnt;
 }
        killcnt(cnt);
        notecnt = cnt;
 }
index 62763af..6085348 100644 (file)
@@ -50,7 +50,7 @@ setterm(type)
        putpad(TE);
        if (tgetent(ltcbuf, type) != 1) {
                unknown++;
        putpad(TE);
        if (tgetent(ltcbuf, type) != 1) {
                unknown++;
-               CP(genbuf, "xx|dumb:");
+               CP(ltcbuf, "xx|dumb:");
        }
        i = LINES = tgetnum("li");
        if (LINES <= 5)
        }
        i = LINES = tgetnum("li");
        if (LINES <= 5)
@@ -59,9 +59,9 @@ setterm(type)
                LINES = 48;
        l = LINES;
        if (ospeed < B1200)
                LINES = 48;
        l = LINES;
        if (ospeed < B1200)
-               l /= 2;
+               l = 9;  /* including the message line at the bottom */
        else if (ospeed < B2400)
        else if (ospeed < B2400)
-               l = (l * 2) / 3;
+               l = 17;
        aoftspace = tspace;
        zap();
        /*
        aoftspace = tspace;
        zap();
        /*
@@ -85,7 +85,7 @@ setterm(type)
                CA = 1, costCM = strlen(tgoto(CM, 8, 10));
        PC = xPC ? xPC[0] : 0;
        aoftspace = tspace;
                CA = 1, costCM = strlen(tgoto(CM, 8, 10));
        PC = xPC ? xPC[0] : 0;
        aoftspace = tspace;
-       CP(ttytype, longname(genbuf, type));
+       CP(ttytype, longname(ltcbuf, type));
        if (i <= 0)
                LINES = 2;
        /* proper strings to change tty type */
        if (i <= 0)
                LINES = 2;
        /* proper strings to change tty type */
index 0dc41fd..a4c6962 100644 (file)
@@ -114,13 +114,19 @@ short     WECHO;
 
 short  costCM;
 
 
 short  costCM;
 
-#define MAXNOMACS      32      /* max number of macros */
-#define MAXCHARMACS    512     /* max # of chars total in macros */
+#ifdef VMUNIX
+# define MAXNOMACS     128     /* max number of macros of each kind */
+# define MAXCHARMACS   2048    /* max # of chars total in macros */
+#else
+# define MAXNOMACS     32      /* max number of macros of each kind */
+# define MAXCHARMACS   512     /* max # of chars total in macros */
+#endif
 struct maps {
        char *cap;      /* pressing button that sends this.. */
        char *mapto;    /* .. maps to this string */
        char *descr;    /* legible description of key */
 };
 struct maps arrows[MAXNOMACS]; /* macro defs - 1st 5 built in */
 struct maps {
        char *cap;      /* pressing button that sends this.. */
        char *mapto;    /* .. maps to this string */
        char *descr;    /* legible description of key */
 };
 struct maps arrows[MAXNOMACS]; /* macro defs - 1st 5 built in */
+struct maps immacs[MAXNOMACS]; /* for while in insert mode */
 char   mapspace[MAXCHARMACS];
 char   *msnext;        /* next free location in mapspace */
 char   mapspace[MAXCHARMACS];
 char   *msnext;        /* next free location in mapspace */
index 192e9b8..ddb0869 100644 (file)
  * "/usr/lib/..." here, "/lib" will be tried only for strings.
  */
 #include "local/uparm.h"
  * "/usr/lib/..." here, "/lib" will be tried only for strings.
  */
 #include "local/uparm.h"
-#define        EXRECOVER       libpath(ex3.2recover)
-#define        EXPRESERVE      libpath(ex3.2preserve)
+#define        EXRECOVER       libpath(ex3.3recover)
+#define        EXPRESERVE      libpath(ex3.3preserve)
 #ifndef VMUNIX
 #ifndef VMUNIX
-#define        EXSTRINGS       libpath(ex3.2strings)
+#define        EXSTRINGS       libpath(ex3.3strings)
 #endif
 #endif
-#define        MASTERTAGS      libpath(tags)
 
 /*
  * If your system believes that tabs expand to a width other than
 
 /*
  * If your system believes that tabs expand to a width other than
@@ -43,7 +42,7 @@
 #define        RHSSIZE         256             /* Size of rhs of substitute */
 #define        NBRA            9               /* Number of re \( \) pairs */
 #define        TAGSIZE         32              /* Tag length */
 #define        RHSSIZE         256             /* Size of rhs of substitute */
 #define        NBRA            9               /* Number of re \( \) pairs */
 #define        TAGSIZE         32              /* Tag length */
-#define        ONMSZ           32              /* Option name size */
+#define        ONMSZ           64              /* Option name size */
 #define        GBSIZE          256             /* Buffer size */
 #define        UXBSIZE         128             /* Unix command buffer size */
 #define        VBSIZE          128             /* Partial line max size in visual */
 #define        GBSIZE          256             /* Buffer size */
 #define        UXBSIZE         128             /* Unix command buffer size */
 #define        VBSIZE          128             /* Partial line max size in visual */
index c42808b..0f8afc4 100644 (file)
@@ -318,11 +318,11 @@ vok(atube)
        vtube0 = atube;
        vclrbyte(atube, WCOLS * (WECHO - ZERO + 1));
        for (i = 0; i < ZERO; i++)
        vtube0 = atube;
        vclrbyte(atube, WCOLS * (WECHO - ZERO + 1));
        for (i = 0; i < ZERO; i++)
-               vtube[i] = (char *) -20000;
+               vtube[i] = (char *) 0;
        for (; i <= WECHO; i++)
                vtube[i] = atube, atube += WCOLS;
        for (; i < TUBELINES; i++)
        for (; i <= WECHO; i++)
                vtube[i] = atube, atube += WCOLS;
        for (; i < TUBELINES; i++)
-               vtube[i] = (char *) -20000;
+               vtube[i] = (char *) 0;
        vutmp = atube;
        vundkind = VNONE;
        vUNDdot = 0;
        vutmp = atube;
        vundkind = VNONE;
        vUNDdot = 0;
index c3bd859..af2ea9f 100644 (file)
 #define LISP            9
 #define LIST            10
 #define MAGIC           11
 #define LISP            9
 #define LIST            10
 #define MAGIC           11
-#define MAPINPUT        12
-#define NUMBER          13
-#define OPEN            14
-#define OPTIMIZE        15
-#define PARAGRAPHS      16
-#define PROMPT          17
-#define REDRAW          18
+#define NUMBER          12
+#define OPEN            13
+#define OPTIMIZE        14
+#define PARAGRAPHS      15
+#define PROMPT          16
+#define REDRAW          17
+#define REMAP           18
 #define REPORT          19
 #define SCROLL          20
 #define SECTIONS        21
 #define REPORT          19
 #define SCROLL          20
 #define SECTIONS        21
 #define SHIFTWIDTH      23
 #define SHOWMATCH       24
 #define SLOWOPEN        25
 #define SHIFTWIDTH      23
 #define SHOWMATCH       24
 #define SLOWOPEN        25
-#define TABSTOP         26
-#define TTYTYPE         27
+#define TAGS            26
+#define TABSTOP         27
 #define TERM            28
 #define TERSE           29
 #define TERM            28
 #define TERSE           29
-#define WARN            30
-#define WINDOW          31
-#define WRAPSCAN        32
-#define WRAPMARGIN      33
-#define WRITEANY        34
+#define TIMEOUT         30
+#define TTYTYPE         31
+#define UNDOMACRO       32
+#define WARN            33
+#define WINDOW          34
+#define WRAPSCAN        35
+#define WRAPMARGIN      36
+#define WRITEANY        37
 
 
-#define        NOPTS   35
+#define        NOPTS   38
index a4645a0..4135d99 100644 (file)
@@ -85,10 +85,6 @@ getATTN:
                        vundkind = VMANY;
                inopen = 1;     /* restore old setting now that macro done */
        }
                        vundkind = VMANY;
                inopen = 1;     /* restore old setting now that macro done */
        }
-#ifdef TRACE
-       if (trace)
-               fflush(trace);
-#endif
        flusho();
 again:
        if (read(0, &ch, 1) != 1) {
        flusho();
 again:
        if (read(0, &ch, 1) != 1) {
@@ -167,6 +163,11 @@ getesc()
        c = getkey();
        switch (c) {
 
        c = getkey();
        switch (c) {
 
+       case CTRL(v):
+       case CTRL(q):
+               c = getkey();
+               return (c);
+
        case ATTN:
        case QUIT:
                ungetkey(c);
        case ATTN:
        case QUIT:
                ungetkey(c);
@@ -408,10 +409,16 @@ map(c,maps)
                                         */
                                        if ((c=='#' ? peekkey() : fastpeekkey()) == 0) {
 #ifdef MDEBUG
                                         */
                                        if ((c=='#' ? peekkey() : fastpeekkey()) == 0) {
 #ifdef MDEBUG
-                                       if (trace)
-                                               fprintf(trace,"fpk=0: return %c",c);
+                                               if (trace)
+                                                       fprintf(trace,"fpk=0: return %c",c);
 #endif
 #endif
-                                               macpush(&b[1],1);
+                                               /*
+                                                * We want to be able to undo
+                                                * commands, but it's nonsense
+                                                * to undo part of an insertion
+                                                * so if in input mode don't.
+                                                */
+                                               macpush(&b[1],maps == arrows);
                                                return(c);
                                        }
                                        *q = getkey();
                                                return(c);
                                        }
                                        *q = getkey();
@@ -455,15 +462,18 @@ int canundo;
 
        if (st==0 || *st==0)
                return;
 
        if (st==0 || *st==0)
                return;
+       if (!value(UNDOMACRO))
+               canundo = 0;
 #ifdef TRACE
        if (trace)
 #ifdef TRACE
        if (trace)
-               fprintf(trace, "macpush(%s)",st);
+               fprintf(trace, "macpush(%s), canundo=%d",st,canundo);
 #endif
 #endif
-       if (strlen(vmacp) + strlen(st) > BUFSIZ)
+       if ((vmacp ? strlen(vmacp) : 0) + strlen(st) > BUFSIZ)
                error("Macro too long@ - maybe recursive?");
        if (vmacp) {
                strcpy(tmpbuf, vmacp);
                error("Macro too long@ - maybe recursive?");
        if (vmacp) {
                strcpy(tmpbuf, vmacp);
-               canundo = 0;    /* can't undo inside a macro anyway */
+               if (!FIXUNDO)
+                       canundo = 0;    /* can't undo inside a macro anyway */
        }
        strcpy(vmacbuf, st);
        if (vmacp)
        }
        strcpy(vmacbuf, st);
        if (vmacp)
@@ -471,17 +481,22 @@ int canundo;
        vmacp = vmacbuf;
        /* arrange to be able to undo the whole macro */
        if (canundo) {
        vmacp = vmacbuf;
        /* arrange to be able to undo the whole macro */
        if (canundo) {
-               inopen = -1;    /* no need to save since it had to be 1 or -1 before */
                otchng = tchng;
                vsave();
                saveall();
                otchng = tchng;
                vsave();
                saveall();
+               inopen = -1;    /* no need to save since it had to be 1 or -1 before */
                vundkind = VMANY;
        }
                vundkind = VMANY;
        }
+}
+
 #ifdef TRACE
 #ifdef TRACE
+vudump(s)
+char *s;
+{
        if (trace)
        if (trace)
-               fprintf(trace, "saveall for macro: undkind=%d, unddel=%d, undap1=%d, undap2=%d, dol=%d, unddol=%d, truedol=%d\n", undkind, lineno(unddel), lineno(undap1), lineno(undap2), lineno(dol), lineno(unddol), lineno(truedol));
-#endif
+               fprintf(trace, "%s: undkind=%d, vundkind=%d, unddel=%d, undap1=%d, undap2=%d, dot=%d, dol=%d, unddol=%d, truedol=%d\n", s, undkind, vundkind, lineno(unddel), lineno(undap1), lineno(undap2), lineno(dot), lineno(dol), lineno(unddol), lineno(truedol));
 }
 }
+#endif
 
 /*
  * Get a count from the keyed input stream.
 
 /*
  * Get a count from the keyed input stream.
@@ -515,10 +530,21 @@ fastpeekkey()
        int trapalarm();
        register int c;
 
        int trapalarm();
        register int c;
 
-       if (inopen == -1)       /* don't work inside macros! */
-               return (0);
-       signal(SIGALRM, trapalarm);
-       alarm(1);
+       /*
+        * If the user has set notimeout, we wait forever for a key.
+        * If we are in a macro we do too, but since it's already
+        * buffered internally it will return immediately.
+        * In other cases we force this to die in 1 second.
+        * This is pretty reliable (VMUNIX rounds it to .5 - 1.5 secs,
+        * but UNIX truncates it to 0 - 1 secs) but due to system delays
+        * there are times when arrow keys or very fast typing get counted
+        * as separate.  notimeout is provided for people who dislike such
+        * nondeterminism.
+        */
+       if (value(TIMEOUT) && inopen >= 0) {
+               signal(SIGALRM, trapalarm);
+               alarm(1);
+       }
        CATCH
                c = peekkey();
 #ifdef MDEBUG
        CATCH
                c = peekkey();
 #ifdef MDEBUG
index e894dee..cc763b3 100644 (file)
@@ -20,7 +20,8 @@ vmain()
        char *oglobp;
        char d;
        line *addr;
        char *oglobp;
        char d;
        line *addr;
-       int ind;
+       int ind, nlput;
+       int shouldpo = 0;
        int onumber, olist, (*OPline)(), (*OPutchar)();
 
        /*
        int onumber, olist, (*OPline)(), (*OPutchar)();
 
        /*
@@ -141,6 +142,8 @@ reread:
                                ungetkey(c);
                                goto looptop;
                        }
                                ungetkey(c);
                                goto looptop;
                        }
+                       if (!value(REMAP))
+                               break;
                } while (c != op);
 
                /*
                } while (c != op);
 
                /*
@@ -161,16 +164,23 @@ reread:
                /*
                 * ^L           Clear screen e.g. after transmission error.
                 */
                /*
                 * ^L           Clear screen e.g. after transmission error.
                 */
-               case CTRL(l):
-                       vclear();
-                       vdirty(0, vcnt);
-                       /* fall into... */
 
                /*
                 * ^R           Retype screen, getting rid of @ lines.
                 *              If in open, equivalent to ^L.
 
                /*
                 * ^R           Retype screen, getting rid of @ lines.
                 *              If in open, equivalent to ^L.
+                *              On terminals where the right arrow key sends
+                *              ^L we make ^R act like ^L, since there is no
+                *              way to get ^L.  These terminals (adm31, tvi)
+                *              are intelligent so ^R is useless.  Soroc
+                *              will probably foul this up, but nobody has
+                *              one of them.
                 */
                 */
+               case CTRL(l):
                case CTRL(r):
                case CTRL(r):
+                       if (c == CTRL(l) || (KR && *KR==CTRL(l))) {
+                               vclear();
+                               vdirty(0, vcnt);
+                       }
                        if (state != VISUAL) {
                                /*
                                 * Get a clean line, throw away the
                        if (state != VISUAL) {
                                /*
                                 * Get a clean line, throw away the
@@ -209,7 +219,9 @@ reread:
                 *              in vmacbuf, point vglobp there and punt.
                 */
                 case '@':
                 *              in vmacbuf, point vglobp there and punt.
                 */
                 case '@':
-                       c = getkey();
+                       c = getesc();
+                       if (c == 0)
+                               continue;
                        if (c == '@')
                                c = lastmac;
                        if (isupper(c))
                        if (c == '@')
                                c = lastmac;
                        if (isupper(c))
@@ -221,7 +233,7 @@ reread:
                                char tmpbuf[BUFSIZ];
 
                                regbuf(c,tmpbuf,sizeof(vmacbuf));
                                char tmpbuf[BUFSIZ];
 
                                regbuf(c,tmpbuf,sizeof(vmacbuf));
-                               macpush(tmpbuf);
+                               macpush(tmpbuf, 1);
                        ONERR
                                lastmac = 0;
                                splitw = 0;
                        ONERR
                                lastmac = 0;
                                splitw = 0;
@@ -500,7 +512,7 @@ reread:
                                mbuf[3] = 0;
                                if (isalpha(mbuf[1]))
                                        mbuf[1] ^= ' '; /* toggle the case */
                                mbuf[3] = 0;
                                if (isalpha(mbuf[1]))
                                        mbuf[1] ^= ' '; /* toggle the case */
-                               macpush(mbuf);
+                               macpush(mbuf, 1);
                        }
                        continue;
 
                        }
                        continue;
 
@@ -567,7 +579,9 @@ insrt:
                        prepapp();
                        vnoapp();
                        doomed = c == 'R' ? 10000 : 0;
                        prepapp();
                        vnoapp();
                        doomed = c == 'R' ? 10000 : 0;
-                       vundkind = VCHNG;
+                       if(FIXUNDO)
+                               vundkind = VCHNG;
+                       vmoving = 0;
                        CP(vutmp, linebuf);
 
                        /*
                        CP(vutmp, linebuf);
 
                        /*
@@ -605,6 +619,7 @@ insrt:
                                onintr();
                        /* fall into... */
 
                                onintr();
                        /* fall into... */
 
+#ifdef notdef
                /*
                 * q            Quit back to command mode, unless called as
                 *              vi on command line in which case dont do it
                /*
                 * q            Quit back to command mode, unless called as
                 *              vi on command line in which case dont do it
@@ -620,6 +635,7 @@ insrt:
                                vrepaint(cursor);
                                continue;
                        }
                                vrepaint(cursor);
                                continue;
                        }
+#endif
                        /* fall into... */
 
                /*
                        /* fall into... */
 
                /*
@@ -630,6 +646,17 @@ insrt:
                        vsave();
                        return;
 
                        vsave();
                        return;
 
+
+               /*
+                * ZZ           Like :x
+                */
+                case 'Z':
+                       forbid(getkey() != 'Z');
+                       oglobp = globp;
+                       globp = "x";
+                       vclrech(0);
+                       goto gogo;
+                       
                /*
                 * P            Put back text before cursor or before current
                 *              line.  If text was whole lines goes back
                /*
                 * P            Put back text before cursor or before current
                 *              line.  If text was whole lines goes back
@@ -644,7 +671,7 @@ insrt:
                case 'P':
                case 'p':
                        vmoving = 0;
                case 'P':
                case 'p':
                        vmoving = 0;
-                       forbid (inopen < 0);
+                       forbid (!vreg && value(UNDOMACRO) && inopen < 0);
                        /*
                         * If previous delete was partial line, use an
                         * append or insert to put it back so as to
                        /*
                         * If previous delete was partial line, use an
                         * append or insert to put it back so as to
@@ -696,6 +723,7 @@ insrt:
                         * We thus put a catch in here.  If we didn't and
                         * there was an error we would end up in command mode.
                         */
                         * We thus put a catch in here.  If we didn't and
                         * there was an error we would end up in command mode.
                         */
+                       addr = dol;     /* old dol */
                        CATCH
                                vremote(1, vreg ? putreg : put, vreg);
                        ONERR
                        CATCH
                                vremote(1, vreg ? putreg : put, vreg);
                        ONERR
@@ -707,24 +735,31 @@ insrt:
                                }
                        ENDCATCH
                        splitw = 0;
                                }
                        ENDCATCH
                        splitw = 0;
+                       nlput = dol - addr + 1;
                        if (!i) {
                                /*
                                 * Increment undap1, undap2 to make up
                                 * for their incorrect initialization in the
                                 * routine vremote before calling put/putreg.
                                 */
                        if (!i) {
                                /*
                                 * Increment undap1, undap2 to make up
                                 * for their incorrect initialization in the
                                 * routine vremote before calling put/putreg.
                                 */
-                               undap1++, undap2++;
+                               if (FIXUNDO)
+                                       undap1++, undap2++;
                                vcline++;
                                vcline++;
-                       }
+                               nlput--;
 
 
-                       /*
-                        * After a put want current line first line,
-                        * and dot was made the last line put in code run
-                        * so far.  This is why we increment vcline above,
-                        * and decrease (usually) dot here.
-                        */
-                       dot = undap1;
-                       vreplace(vcline, i, undap2 - undap1);
+                               /*
+                                * After a put want current line first line,
+                                * and dot was made the last line put in code
+                                * run so far.  This is why we increment vcline
+                                * above and decrease dot here.
+                                */
+                               dot -= nlput - 1;
+                       }
+#ifdef TRACE
+                       if (trace)
+                               fprintf(trace, "vreplace(%d, %d, %d), undap1=%d, undap2=%d, dot=%d\n", vcline, i, nlput, lineno(undap1), lineno(undap2), lineno(dot));
+#endif
+                       vreplace(vcline, i, nlput);
                        if (state != VISUAL) {
                                /*
                                 * Special case in open mode.
                        if (state != VISUAL) {
                                /*
                                 * Special case in open mode.
@@ -830,6 +865,14 @@ doinit:
                         * command mode).  This is clumsy.
                         */
                        d = peekc; ungetchar(0);
                         * command mode).  This is clumsy.
                         */
                        d = peekc; ungetchar(0);
+                       if (shouldpo) {
+                               /*
+                                * So after a "Hit return..." ":", we do
+                                * another "Hit return..." the next time
+                                */
+                               pofix();
+                               shouldpo = 0;
+                       }
                        CATCH
                                /*
                                 * Save old values of options so we can
                        CATCH
                                /*
                                 * Save old values of options so we can
@@ -892,7 +935,7 @@ fixup:
                         * a write command there, but its not
                         * worth worrying about.
                         */
                         * a write command there, but its not
                         * worth worrying about.
                         */
-                       if (tchng && tchng != i)
+                       if (FIXUNDO && tchng && tchng != i)
                                vundkind = VMANY, cursor = 0;
 
                        /*
                                vundkind = VMANY, cursor = 0;
 
                        /*
@@ -901,8 +944,10 @@ fixup:
                         */
                        if (vcnt < 0 && Peekkey == ':') {
                                getDOT();
                         */
                        if (vcnt < 0 && Peekkey == ':') {
                                getDOT();
+                               shouldpo = 1;
                                continue;
                        }
                                continue;
                        }
+                       shouldpo = 0;
 
                        /*
                         * In the case where the file being edited is
 
                        /*
                         * In the case where the file being edited is
@@ -950,8 +995,9 @@ fixup:
                                        vcnt = -vcnt;
                                        if (state == VISUAL)
                                                vclear();
                                        vcnt = -vcnt;
                                        if (state == VISUAL)
                                                vclear();
-                                       else if (state == CRTOPEN)
+                                       else if (state == CRTOPEN) {
                                                vcnt = 0;
                                                vcnt = 0;
+                                       }
                                }
 
                                /*
                                }
 
                                /*
@@ -1059,12 +1105,12 @@ vremote(cnt, f, arg)
 
        addr1 = dot;
        addr2 = dot + cnt - 1;
 
        addr1 = dot;
        addr2 = dot + cnt - 1;
-       if (inopen > 0)
-               undap1 = undap2 = dot;
        inglobal = 0;
        inglobal = 0;
+       if (FIXUNDO)
+               undap1 = undap2 = dot;
        (*f)(arg);
        inglobal = oing;
        (*f)(arg);
        inglobal = oing;
-       if (inopen > 0)
+       if (FIXUNDO)
                vundkind = VMANY;
        vmcurs = 0;
 }
                vundkind = VMANY;
        vmcurs = 0;
 }
@@ -1077,7 +1123,7 @@ vsave()
        char temp[LBSIZE];
 
        CP(temp, linebuf);
        char temp[LBSIZE];
 
        CP(temp, linebuf);
-       if (vundkind == VCHNG || vundkind == VCAPU) {
+       if (FIXUNDO && vundkind == VCHNG || vundkind == VCAPU) {
                /*
                 * If the undo state is saved in the temporary buffer
                 * vutmp, then we sync this into the temp file so that
                /*
                 * If the undo state is saved in the temporary buffer
                 * vutmp, then we sync this into the temp file so that
index f65d7b2..42812bf 100644 (file)
@@ -27,6 +27,7 @@ operate(c, cnt)
        bool subop = 0;
        char *oglobp, *ocurs;
        register line *addr;
        bool subop = 0;
        char *oglobp, *ocurs;
        register line *addr;
+       line *odot;
        static char lastFKND, lastFCHR;
        char d;
 
        static char lastFKND, lastFCHR;
        char d;
 
@@ -259,7 +260,7 @@ ein:
        case ',':
                forbid (lastFKND == 0);
                c = isupper(lastFKND) ? tolower(lastFKND) : toupper(lastFKND);
        case ',':
                forbid (lastFKND == 0);
                c = isupper(lastFKND) ? tolower(lastFKND) : toupper(lastFKND);
-               ungetkey(lastFCHR);
+               i = lastFCHR;
                if (vglobp == 0)
                        vglobp = "";
                subop++;
                if (vglobp == 0)
                        vglobp = "";
                subop++;
@@ -279,7 +280,7 @@ ein:
        case ';':
                forbid (lastFKND == 0);
                c = lastFKND;
        case ';':
                forbid (lastFKND == 0);
                c = lastFKND;
-               ungetkey(lastFCHR);
+               i = lastFCHR;
                subop++;
                goto nocount;
 
                subop++;
                goto nocount;
 
@@ -298,11 +299,12 @@ ein:
         */
        case 'f':       /* find */
        case 't':
         */
        case 'f':       /* find */
        case 't':
-               i = getesc();
-               if (i == 0)
-                       return;
-               if (!subop)
+               if (!subop) {
+                       i = getesc();
+                       if (i == 0)
+                               return;
                        *lastcp++ = i;
                        *lastcp++ = i;
+               }
                if (vglobp == 0)
                        lastFKND = c, lastFCHR = i;
                for (; cnt > 0; cnt--)
                if (vglobp == 0)
                        lastFKND = c, lastFCHR = i;
                for (; cnt > 0; cnt--)
@@ -597,13 +599,17 @@ errlab:
                        vsetsiz(Xcnt);
                vsave();
                ocurs = cursor;
                        vsetsiz(Xcnt);
                vsave();
                ocurs = cursor;
+               odot = dot;
                wcursor = 0;
                if (readecho(c))
                        return;
                if (!vglobp)
                        vscandir[0] = genbuf[0];
                oglobp = globp; CP(vutmp, genbuf); globp = vutmp;
                wcursor = 0;
                if (readecho(c))
                        return;
                if (!vglobp)
                        vscandir[0] = genbuf[0];
                oglobp = globp; CP(vutmp, genbuf); globp = vutmp;
-               d = peekc; ungetchar(0); fixech();
+               d = peekc;
+fromsemi:
+               ungetchar(0);
+               fixech();
                CATCH
 #ifndef CBREAK
                        /*
                CATCH
 #ifndef CBREAK
                        /*
@@ -619,7 +625,10 @@ errlab:
 #ifndef CBREAK
                        vraw();
 #endif
 #ifndef CBREAK
                        vraw();
 #endif
+slerr:
                        globp = oglobp;
                        globp = oglobp;
+                       dot = odot;
+                       cursor = ocurs;
                        ungetchar(d);
                        splitw = 0;
                        vclean();
                        ungetchar(d);
                        splitw = 0;
                        vclean();
@@ -630,6 +639,14 @@ errlab:
                        globp = "";
                else if (peekc)
                        --globp;
                        globp = "";
                else if (peekc)
                        --globp;
+               if (*globp == ';') {
+                       /* /foo/;/bar/ */
+                       globp++;
+                       dot = addr;
+                       cursor = loc1;
+                       goto fromsemi;
+               }
+               dot = odot;
                ungetchar(d);
                c = 0;
                if (*globp == 'z')
                ungetchar(d);
                c = 0;
                if (*globp == 'z')
@@ -639,8 +656,13 @@ errlab:
                i = 0;
                while (isdigit(*globp))
                        i = i * 10 + *globp++ - '0';
                i = 0;
                while (isdigit(*globp))
                        i = i * 10 + *globp++ - '0';
-               if (*globp)
+               if (any(*globp, "^+-."))
                        c = *globp++;
                        c = *globp++;
+               if (*globp) {
+                       /* random junk after the pattern */
+                       beep();
+                       goto slerr;
+               }
                globp = oglobp;
                splitw = 0;
                vmoving = 0;
                globp = oglobp;
                splitw = 0;
                vmoving = 0;
index 92a5f68..cb433c3 100644 (file)
@@ -81,7 +81,7 @@ vundo()
                notecnt = 1;
                if (undkind == UNDPUT && undap1 == undap2) {
                        beep();
                notecnt = 1;
                if (undkind == UNDPUT && undap1 == undap2) {
                        beep();
-                       return;
+                       break;
                }
                /*
                 * Undo() call below basically replaces undap1 to undap2-1
                }
                /*
                 * Undo() call below basically replaces undap1 to undap2-1
@@ -98,14 +98,14 @@ vundo()
                cnt = dot - addr;
                if (cnt < 0 || cnt > vcnt || state != VISUAL) {
                        vjumpto(dot, NOSTR, '.');
                cnt = dot - addr;
                if (cnt < 0 || cnt > vcnt || state != VISUAL) {
                        vjumpto(dot, NOSTR, '.');
-                       return;
+                       break;
                }
                if (!savenote)
                        notecnt = 0;
                vcline = cnt;
                vrepaint(vmcurs);
                vmcurs = 0;
                }
                if (!savenote)
                        notecnt = 0;
                vcline = cnt;
                vrepaint(vmcurs);
                vmcurs = 0;
-               return;
+               break;
 
        case VCHNG:
        case VCAPU:
 
        case VCHNG:
        case VCAPU:
@@ -122,7 +122,7 @@ vundo()
                        vsave();
                        vopen(dot, WBOT);
                        vnline(cursor);
                        vsave();
                        vopen(dot, WBOT);
                        vnline(cursor);
-                       return;
+                       break;
                }
                /*
                 * Pseudo insert command.
                }
                /*
                 * Pseudo insert command.
@@ -142,11 +142,11 @@ vundo()
                if (cursor > linebuf && cursor >= strend(linebuf))
                        cursor--;
                vfixcurs();
                if (cursor > linebuf && cursor >= strend(linebuf))
                        cursor--;
                vfixcurs();
-               return;
+               break;
 
        case VNONE:
                beep();
 
        case VNONE:
                beep();
-               return;
+               break;
        }
 }
 
        }
 }
 
@@ -544,7 +544,8 @@ voOpen(c, cnt)
        }
        killU();
        prepapp();
        }
        killU();
        prepapp();
-       vundkind = VMANY;
+       if (FIXUNDO)
+               vundkind = VMANY;
        if (state != VISUAL)
                c = WBOT + 1;
        else {
        if (state != VISUAL)
                c = WBOT + 1;
        else {
@@ -641,6 +642,13 @@ vfilter()
                dot = one;
        splitw = 0;
        notenam = "";
                dot = one;
        splitw = 0;
        notenam = "";
+       /*
+        * BUG: we shouldn't be depending on what undap2 and undap1 are,
+        * since we may be inside a macro.  What's really wanted is the
+        * number of lines we read from the filter.  However, the mistake
+        * will be an overestimate so it only results in extra work,
+        * it shouldn't cause any real screwups.
+        */
        vreplace(vcline, cnt, undap2 - undap1);
        dot = addr;
        if (dot > dol) {
        vreplace(vcline, cnt, undap2 - undap1);
        dot = addr;
        if (dot > dol) {
@@ -757,7 +765,8 @@ vrep(cnt)
                ungetkey(c);
        }
        CP(vutmp, linebuf);
                ungetkey(c);
        }
        CP(vutmp, linebuf);
-       vundkind = VCHNG;
+       if (FIXUNDO)
+               vundkind = VCHNG;
        wcursor = cursor + cnt;
        vUD1 = cursor; vUD2 = wcursor;
        CP(cursor, wcursor);
        wcursor = cursor + cnt;
        vUD1 = cursor; vUD2 = wcursor;
        CP(cursor, wcursor);
@@ -783,7 +792,8 @@ vyankit()
                vremote(cnt, yank, 0);
                setpk();
                notenam = "yank";
                vremote(cnt, yank, 0);
                setpk();
                notenam = "yank";
-               vundkind = VNONE;
+               if (FIXUNDO)
+                       vundkind = VNONE;
                DEL[0] = 0;
                wdot = NOLINE;
                if (notecnt <= vcnt - vcline && notecnt < value(REPORT))
                DEL[0] = 0;
                wdot = NOLINE;
                if (notecnt <= vcnt - vcline && notecnt < value(REPORT))
index 86334bc..8304179 100644 (file)
@@ -37,7 +37,8 @@ vdcMID()
 
        squish();
        setLAST();
 
        squish();
        setLAST();
-       vundkind = VCHNG, CP(vutmp, linebuf);
+       if (FIXUNDO)
+               vundkind = VCHNG, CP(vutmp, linebuf);
        if (wcursor < cursor)
                cp = wcursor, wcursor = cursor, cursor = cp;
        vUD1 = vUA1 = vUA2 = cursor; vUD2 = wcursor;
        if (wcursor < cursor)
                cp = wcursor, wcursor = cursor, cursor = cp;
        vUD1 = vUA1 = vUA2 = cursor; vUD2 = wcursor;
@@ -326,7 +327,7 @@ vappend(ch, cnt, indent)
                 * out dot before it changes so that undo will work
                 * correctly later.
                 */
                 * out dot before it changes so that undo will work
                 * correctly later.
                 */
-               if (vundkind == VCHNG) {
+               if (FIXUNDO && vundkind == VCHNG) {
                        vremote(1, yank, 0);
                        undap1--;
                }
                        vremote(1, yank, 0);
                        undap1--;
                }
@@ -442,9 +443,12 @@ vgetline(cnt, gcursor, aescaped)
                                goto vadone;
                }
                ch = c = getkey() & (QUOTE|TRIM);
                                goto vadone;
                }
                ch = c = getkey() & (QUOTE|TRIM);
-               if (value(MAPINPUT))
-                       while ((ch = map(c, arrows)) != c)
+               if (vglobp == 0 && Peekkey == 0)
+                       while ((ch = map(c, immacs)) != c) {
                                c = ch;
                                c = ch;
+                               if (!value(REMAP))
+                                       break;
+                       }
                if (!iglobp) {
 
                        /*
                if (!iglobp) {
 
                        /*
@@ -679,7 +683,7 @@ vbackup:
                                        CDCNT = 1;
                                        endim();
                                        back1();
                                        CDCNT = 1;
                                        endim();
                                        back1();
-                                       vputc(' ');
+                                       vputchar(' ');
                                        goto vbackup;
                                }
                        if (vglobp && vglobp - iglobp >= 2 &&
                                        goto vbackup;
                                }
                        if (vglobp && vglobp - iglobp >= 2 &&
index cadd33a..36434a3 100644 (file)
@@ -767,9 +767,12 @@ vishft()
                        goim();
                        up = tp + j * WCOLS - shft;
                        i = shft;
                        goim();
                        up = tp + j * WCOLS - shft;
                        i = shft;
-                       do
-                               vputchar(*up++);
-                       while (--i);
+                       do {
+                               if (*up)
+                                       vputchar(*up++);
+                               else
+                                       break;
+                       } while (--i);
                }
                vigotoCL(tabstart);
                i = shft - (inssiz - doomed);
                }
                vigotoCL(tabstart);
                i = shft - (inssiz - doomed);
@@ -1029,9 +1032,9 @@ vputchar(c)
        if (trace)
                tracec(c);
 #endif
        if (trace)
                tracec(c);
 #endif
-       /* Patch to fix problem of >79 chars on echo line: don't echo extras */
+       /* Fix problem of >79 chars on echo line. */
        if (destcol >= WCOLS-1 && splitw && destline == WECHO)
        if (destcol >= WCOLS-1 && splitw && destline == WECHO)
-               return;
+               pofix();
        if (destcol >= WCOLS) {
                destline += destcol / WCOLS;
                destcol %= WCOLS;
        if (destcol >= WCOLS) {
                destline += destcol / WCOLS;
                destcol %= WCOLS;