BSD 4_3_Reno release
[unix-history] / usr / src / usr.bin / ex / ex_vops2.c
index 1296919..55eb719 100644 (file)
@@ -1,5 +1,13 @@
-/* Copyright (c) 1980 Regents of the University of California */
-static char *sccsid = "@(#)ex_vops2.c  4.2 %G%";
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
+#ifndef lint
+static char *sccsid = "@(#)ex_vops2.c  6.10 (Berkeley) 1/2/88";
+#endif not lint
+
 #include "ex.h"
 #include "ex_tty.h"
 #include "ex_vis.h"
 #include "ex.h"
 #include "ex_tty.h"
 #include "ex_vis.h"
@@ -9,8 +17,8 @@ static char *sccsid = "@(#)ex_vops2.c  4.2 %G%";
  * and mostly, insert mode (and a subroutine
  * to read an input line, including in the echo area.)
  */
  * and mostly, insert mode (and a subroutine
  * to read an input line, including in the echo area.)
  */
-char   *vUA1, *vUA2;
-char   *vUD1, *vUD2;
+extern char    *vUA1, *vUA2;           /* mjm: extern; also in ex_vops.c */
+extern char    *vUD1, *vUD2;           /* mjm: extern; also in ex_vops.c */
 
 /*
  * Obleeperate characters in hardcopy
 
 /*
  * Obleeperate characters in hardcopy
@@ -23,7 +31,7 @@ bleep(i, cp)
 
        i -= column(cp);
        do
 
        i -= column(cp);
        do
-               putchar('\\' | QUOTE);
+               ex_putchar('\\' | QUOTE);
        while (--i >= 0);
        rubble = 1;
 }
        while (--i >= 0);
        rubble = 1;
 }
@@ -67,7 +75,7 @@ takeout(BUF)
                wcursor = cursor;
                cursor = cp;
        }
                wcursor = cursor;
                cursor = cp;
        }
-       setBUF(BUF);
+       ex_setBUF(BUF);
        if ((BUF[0] & (QUOTE|TRIM)) == OVERBUF)
                beep();
 }
        if ((BUF[0] & (QUOTE|TRIM)) == OVERBUF)
                beep();
 }
@@ -104,14 +112,17 @@ bool      gobbled;
 char   *ogcursor;
 
 vappend(ch, cnt, indent)
 char   *ogcursor;
 
 vappend(ch, cnt, indent)
-       char ch;
+       int ch;         /* mjm: char --> int */
        int cnt, indent;
 {
        register int i;
        register char *gcursor;
        bool escape;
        int cnt, indent;
 {
        register int i;
        register char *gcursor;
        bool escape;
-       int repcnt;
+       int repcnt, savedoomed;
        short oldhold = hold;
        short oldhold = hold;
+#ifdef SIGWINCH
+       int oldmask;
+#endif
 
        /*
         * Before a move in hardopen when the line is dirty
 
        /*
         * Before a move in hardopen when the line is dirty
@@ -201,6 +212,9 @@ vappend(ch, cnt, indent)
         */
        gobblebl = 0;
 
         */
        gobblebl = 0;
 
+#ifdef SIGWINCH
+       oldmask = sigblock(sigmask(SIGWINCH));
+#endif
        /*
         * Text gathering loop.
         * New text goes into genbuf starting at gcursor.
        /*
         * Text gathering loop.
         * New text goes into genbuf starting at gcursor.
@@ -212,7 +226,7 @@ vappend(ch, cnt, indent)
                if (ch == 'r' && repcnt == 0)
                        escape = 0;
                else {
                if (ch == 'r' && repcnt == 0)
                        escape = 0;
                else {
-                       gcursor = vgetline(repcnt, gcursor, &escape);
+                       gcursor = vgetline(repcnt, gcursor, &escape, ch);
 
                        /*
                         * After an append, stick information
 
                        /*
                         * After an append, stick information
@@ -260,7 +274,7 @@ vappend(ch, cnt, indent)
 
                                Outchar = vinschar;
                                hold |= HOLDQIK;
 
                                Outchar = vinschar;
                                hold |= HOLDQIK;
-                               printf("%s", genbuf);
+                               ex_printf("%s", genbuf);
                                hold = oldhold;
                                Outchar = vputchar;
                        }
                                hold = oldhold;
                                Outchar = vputchar;
                        }
@@ -277,6 +291,7 @@ vappend(ch, cnt, indent)
                 */
                if (state != HARDOPEN) {
                        DEPTH(vcline) = 0;
                 */
                if (state != HARDOPEN) {
                        DEPTH(vcline) = 0;
+                       savedoomed = doomed;
                        if (doomed > 0) {
                                register int cind = cindent();
 
                        if (doomed > 0) {
                                register int cind = cindent();
 
@@ -284,6 +299,12 @@ vappend(ch, cnt, indent)
                                doomed = 0;
                        }
                        i = vreopen(LINE(vcline), lineDOT(), vcline);
                                doomed = 0;
                        }
                        i = vreopen(LINE(vcline), lineDOT(), vcline);
+#ifdef TRACE
+                       if (trace)
+                               fprintf(trace, "restoring doomed from %d to %d\n", doomed, savedoomed);
+#endif
+                       if (ch == 'R')
+                               doomed = savedoomed;
                }
 
                /*
                }
 
                /*
@@ -371,6 +392,9 @@ vappend(ch, cnt, indent)
        doomed = 0;
        wcursor = cursor;
        vmove();
        doomed = 0;
        wcursor = cursor;
        vmove();
+#ifdef SIGWINCH
+       (void)sigsetmask(oldmask);
+#endif
 }
 
 /*
 }
 
 /*
@@ -396,17 +420,19 @@ back1()
  * are careful about the way we do this so that it is
  * repeatable.  (I.e. so that your kill doesn't happen,
  * when you repeat an insert if it was escaped with \ the
  * are careful about the way we do this so that it is
  * repeatable.  (I.e. so that your kill doesn't happen,
  * when you repeat an insert if it was escaped with \ the
- * first time you did it.
+ * first time you did it.  commch is the command character
+ * involved, including the prompt for readline.
  */
 char *
  */
 char *
-vgetline(cnt, gcursor, aescaped)
+vgetline(cnt, gcursor, aescaped, commch)
        int cnt;
        register char *gcursor;
        bool *aescaped;
        int cnt;
        register char *gcursor;
        bool *aescaped;
+       char commch;
 {
        register int c, ch;
        register char *cp;
 {
        register int c, ch;
        register char *cp;
-       int x, y, iwhite;
+       int x, y, iwhite, backsl=0;
        char *iglobp;
        char cstr[2];
        int (*OO)() = Outchar;
        char *iglobp;
        char cstr[2];
        int (*OO)() = Outchar;
@@ -437,6 +463,7 @@ vgetline(cnt, gcursor, aescaped)
                vprepins();
        }
        for (;;) {
                vprepins();
        }
        for (;;) {
+               backsl = 0;
                if (gobblebl)
                        gobblebl--;
                if (cnt != 0) {
                if (gobblebl)
                        gobblebl--;
                if (cnt != 0) {
@@ -449,7 +476,7 @@ vgetline(cnt, gcursor, aescaped)
                        c &= (QUOTE|TRIM);
                ch = c;
                maphopcnt = 0;
                        c &= (QUOTE|TRIM);
                ch = c;
                maphopcnt = 0;
-               if (vglobp == 0 && Peekkey == 0)
+               if (vglobp == 0 && Peek_key == 0 && commch != 'r')
                        while ((ch = map(c, immacs)) != c) {
                                c = ch;
                                if (!value(REMAP))
                        while ((ch = map(c, immacs)) != c) {
                                c = ch;
                                if (!value(REMAP))
@@ -467,12 +494,12 @@ vgetline(cnt, gcursor, aescaped)
                         */
 #ifndef USG3TTY
                        if (c == tty.sg_erase)
                         */
 #ifndef USG3TTY
                        if (c == tty.sg_erase)
-                               c = CTRL(h);
+                               c = CTRL('h');
                        else if (c == tty.sg_kill)
                                c = -1;
 #else
                        if (c == tty.c_cc[VERASE])
                        else if (c == tty.sg_kill)
                                c = -1;
 #else
                        if (c == tty.c_cc[VERASE])
-                               c = CTRL(h);
+                               c = CTRL('h');
                        else if (c == tty.c_cc[VKILL])
                                c = -1;
 #endif
                        else if (c == tty.c_cc[VKILL])
                                c = -1;
 #endif
@@ -500,7 +527,7 @@ vgetline(cnt, gcursor, aescaped)
                         *              This is hard because stuff has
                         *              already been saved for repeat.
                         */
                         *              This is hard because stuff has
                         *              already been saved for repeat.
                         */
-                       case CTRL(h):
+                       case CTRL('h'):
 bakchar:
                                cp = gcursor - 1;
                                if (cp < ogcursor) {
 bakchar:
                                cp = gcursor - 1;
                                if (cp < ogcursor) {
@@ -521,7 +548,7 @@ bakchar:
                        /*
                         * ^W           Back up a white/non-white word.
                         */
                        /*
                         * ^W           Back up a white/non-white word.
                         */
-                       case CTRL(w):
+                       case CTRL('w'):
                                wdkind = 1;
                                for (cp = gcursor; cp > ogcursor && isspace(cp[-1]); cp--)
                                        continue;
                                wdkind = 1;
                                for (cp = gcursor; cp > ogcursor && isspace(cp[-1]); cp--)
                                        continue;
@@ -556,22 +583,24 @@ vbackup:
                         */
                        case '\\':
                                x = destcol, y = destline;
                         */
                        case '\\':
                                x = destcol, y = destline;
-                               putchar('\\');
+                               ex_putchar('\\');
                                vcsync();
                                c = getkey();
 #ifndef USG3TTY
                                vcsync();
                                c = getkey();
 #ifndef USG3TTY
-                               if (c == tty.sg_erase || c == tty.sg_kill) {
+                               if (c == tty.sg_erase || c == tty.sg_kill)
 #else
                                if (c == tty.c_cc[VERASE]
 #else
                                if (c == tty.c_cc[VERASE]
-                                   || c == tty.c_cc[VKILL]) {
+                                   || c == tty.c_cc[VKILL])
 #endif
 #endif
+                               {
                                        vgoto(y, x);
                                        if (doomed >= 0)
                                                doomed++;
                                        goto def;
                                }
                                ungetkey(c), c = '\\';
                                        vgoto(y, x);
                                        if (doomed >= 0)
                                                doomed++;
                                        goto def;
                                }
                                ungetkey(c), c = '\\';
-                               goto noput;
+                               backsl = 1;
+                               break;
 
                        /*
                         * ^Q           Super quote following character
 
                        /*
                         * ^Q           Super quote following character
@@ -581,10 +610,10 @@ vbackup:
                         *
                         * ^V           Synonym for ^Q
                         */
                         *
                         * ^V           Synonym for ^Q
                         */
-                       case CTRL(q):
-                       case CTRL(v):
+                       case CTRL('q'):
+                       case CTRL('v'):
                                x = destcol, y = destline;
                                x = destcol, y = destline;
-                               putchar('^');
+                               ex_putchar('^');
                                vgoto(y, x);
                                c = getkey();
 #ifdef TIOCSETC
                                vgoto(y, x);
                                c = getkey();
 #ifdef TIOCSETC
@@ -609,21 +638,25 @@ vbackup:
                                gobbled = 1;
                                continue;
                        }
                                gobbled = 1;
                                continue;
                        }
-                       if (/* c <= ' ' && */ value(WRAPMARGIN) &&
-                               outcol >= OCOLUMNS - value(WRAPMARGIN)) {
+                       if (value(WRAPMARGIN) &&
+                               (outcol >= OCOLUMNS - value(WRAPMARGIN) ||
+                                backsl && outcol==0) &&
+                               commch != 'r') {
                                /*
                                 * At end of word and hit wrapmargin.
                                 * Move the word to next line and keep going.
                                 */
                                wdkind = 1;
                                *gcursor++ = c;
                                /*
                                 * At end of word and hit wrapmargin.
                                 * Move the word to next line and keep going.
                                 */
                                wdkind = 1;
                                *gcursor++ = c;
+                               if (backsl)
+                                       *gcursor++ = getkey();
                                *gcursor = 0;
                                /*
                                 * Find end of previous word if we are past it.
                                 */
                                for (cp=gcursor; cp>ogcursor && isspace(cp[-1]); cp--)
                                        ;
                                *gcursor = 0;
                                /*
                                 * Find end of previous word if we are past it.
                                 */
                                for (cp=gcursor; cp>ogcursor && isspace(cp[-1]); cp--)
                                        ;
-                               if (outcol - (gcursor-cp) >= OCOLUMNS - value(WRAPMARGIN)) {
+                               if (outcol+(backsl?OCOLUMNS:0) - (gcursor-cp) >= OCOLUMNS - value(WRAPMARGIN)) {
                                        /*
                                         * Find beginning of previous word.
                                         */
                                        /*
                                         * Find beginning of previous word.
                                         */
@@ -665,22 +698,22 @@ vbackup:
                 */
                cstr[0] = c;
                if (anyabbrs && gcursor > ogcursor && !wordch(cstr) && wordch(gcursor-1)) {
                 */
                cstr[0] = c;
                if (anyabbrs && gcursor > ogcursor && !wordch(cstr) && wordch(gcursor-1)) {
-                               int wdtype, abno;
-
-                               cstr[1] = 0;
-                               wdkind = 1;
-                               cp = gcursor - 1;
-                               for (wdtype = wordch(cp - 1);
-                                   cp > ogcursor && wordof(wdtype, cp - 1); cp--)
-                                       ;
-                               *gcursor = 0;
-                               for (abno=0; abbrevs[abno].mapto; abno++) {
-                                       if (eq(cp, abbrevs[abno].cap)) {
-                                               macpush(cstr, 0);
-                                               macpush(abbrevs[abno].mapto);
-                                               goto vbackup;
-                                       }
+                       int wdtype, abno;
+
+                       cstr[1] = 0;
+                       wdkind = 1;
+                       cp = gcursor - 1;
+                       for (wdtype = wordch(cp - 1);
+                           cp > ogcursor && wordof(wdtype, cp - 1); cp--)
+                               ;
+                       *gcursor = 0;
+                       for (abno=0; abbrevs[abno].mapto; abno++) {
+                               if (eq(cp, abbrevs[abno].cap)) {
+                                       macpush(cstr, 0);
+                                       macpush(abbrevs[abno].mapto, 1);
+                                       goto vbackup;
                                }
                                }
+                       }
                }
 
                switch (c) {
                }
 
                switch (c) {
@@ -716,8 +749,8 @@ vbackup:
                 *              Unless in repeat where this means these
                 *              were superquoted in.
                 */
                 *              Unless in repeat where this means these
                 *              were superquoted in.
                 */
-               case CTRL(d):
-               case CTRL(t):
+               case CTRL('d'):
+               case CTRL('t'):
                        if (vglobp)
                                goto def;
                        /* fall into ... */
                        if (vglobp)
                                goto def;
                        /* fall into ... */
@@ -725,11 +758,11 @@ vbackup:
                /*
                 * ^D|QUOTE     Is a backtab (in a repeated command).
                 */
                /*
                 * ^D|QUOTE     Is a backtab (in a repeated command).
                 */
-               case CTRL(d) | QUOTE:
+               case CTRL('d') | QUOTE:
                        *gcursor = 0;
                        cp = vpastwh(genbuf);
                        c = whitecnt(genbuf);
                        *gcursor = 0;
                        cp = vpastwh(genbuf);
                        c = whitecnt(genbuf);
-                       if (ch == CTRL(t)) {
+                       if (ch == CTRL('t')) {
                                /*
                                 * ^t just generates new indent replacing
                                 * current white space rounded up to soft
                                /*
                                 * ^t just generates new indent replacing
                                 * current white space rounded up to soft
@@ -790,9 +823,10 @@ vbackup:
                                continue;
                        }
 def:
                                continue;
                        }
 def:
-                       putchar(c);
-                       flush();
-noput:
+                       if (!backsl) {
+                               ex_putchar(c);
+                               flush();
+                       }
                        if (gcursor > &genbuf[LBSIZE - 2])
                                error("Line too long");
                        *gcursor++ = c & TRIM;
                        if (gcursor > &genbuf[LBSIZE - 2])
                                error("Line too long");
                        *gcursor++ = c & TRIM;