Annotation of 3BSD/cmd/ex/ex_vops.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include "ex.h"
                      3: #include "ex_tty.h"
                      4: #include "ex_vis.h"
                      5: 
                      6: /*
                      7:  * This file defines the operation sequences which interface the
                      8:  * logical changes to the file buffer with the internal and external
                      9:  * display representations.
                     10:  */
                     11: 
                     12: /*
                     13:  * Undo.
                     14:  *
                     15:  * Undo is accomplished in two ways.  We often for small changes in the
                     16:  * current line know how (in terms of a change operator) how the change
                     17:  * occurred.  Thus on an intelligent terminal we can undo the operation
                     18:  * by another such operation, using insert and delete character
                     19:  * stuff.  The pointers vU[AD][12] index the buffer vutmp when this
                     20:  * is possible and provide the necessary information.
                     21:  *
                     22:  * The other case is that the change involved multiple lines or that
                     23:  * we have moved away from the line or forgotten how the change was
                     24:  * accomplished.  In this case we do a redisplay and hope that the
                     25:  * low level optimization routines (which don't look for winning
                     26:  * via insert/delete character) will not lose too badly.
                     27:  */
                     28: char   *vUA1, *vUA2;
                     29: char   *vUD1, *vUD2;
                     30: 
                     31: vUndo()
                     32: {
                     33: 
                     34:        /*
                     35:         * Avoid UU which clobbers ability to do u.
                     36:         */
                     37:        if (vundkind == VCAPU || vUNDdot != dot) {
                     38:                beep();
                     39:                return;
                     40:        }
                     41:        CP(vutmp, linebuf);
                     42:        vUD1 = linebuf; vUD2 = strend(linebuf);
                     43:        putmk1(dot, vUNDsav);
                     44:        getDOT();
                     45:        vUA1 = linebuf; vUA2 = strend(linebuf);
                     46:        vundkind = VCAPU;
                     47:        if (state == ONEOPEN || state == HARDOPEN) {
                     48:                vjumpto(dot, vUNDcurs, 0);
                     49:                return;
                     50:        }
                     51:        vdirty(vcline, 1);
                     52:        vsyncCL();
                     53:        vfixcurs();
                     54: }
                     55: 
                     56: vundo()
                     57: {
                     58:        register int cnt;
                     59:        register line *addr;
                     60:        register char *cp;
                     61:        char temp[LBSIZE];
                     62:        bool savenote;
                     63:        int (*OO)();
                     64:        short oldhold = hold;
                     65: 
                     66:        switch (vundkind) {
                     67: 
                     68:        case VMANYINS:
                     69:                wcursor = 0;
                     70:                addr1 = undap1;
                     71:                addr2 = undap2 - 1;
                     72:                vsave();
                     73:                YANKreg('1');
                     74:                notecnt = 0;
                     75:                /* fall into ... */
                     76: 
                     77:        case VMANY:
                     78:        case VMCHNG:
                     79:                vsave();
                     80:                addr = dot - vcline;
                     81:                notecnt = 1;
                     82:                if (undkind == UNDPUT && undap1 == undap2) {
                     83:                        beep();
                     84:                        return;
                     85:                }
                     86:                /*
                     87:                 * Undo() call below basically replaces undap1 to undap2-1
                     88:                 * with dol through unddol-1.  Hack screen image to
                     89:                 * reflect this replacement.
                     90:                 */
                     91:                vreplace(undap1 - addr, undap2 - undap1,
                     92:                    undkind == UNDPUT ? 0 : unddol - dol);
                     93:                savenote = notecnt;
                     94:                undo(1);
                     95:                if (vundkind != VMCHNG || addr != dot)
                     96:                        killU();
                     97:                vundkind = VMANY;
                     98:                cnt = dot - addr;
                     99:                if (cnt < 0 || cnt > vcnt || state != VISUAL) {
                    100:                        vjumpto(dot, NOSTR, '.');
                    101:                        return;
                    102:                }
                    103:                if (!savenote)
                    104:                        notecnt = 0;
                    105:                vcline = cnt;
                    106:                vrepaint(vmcurs);
                    107:                vmcurs = 0;
                    108:                return;
                    109: 
                    110:        case VCHNG:
                    111:        case VCAPU:
                    112:                vundkind = VCHNG;
                    113:                strcpy(temp, vutmp);
                    114:                strcpy(vutmp, linebuf);
                    115:                doomed = column(vUA2 - 1) - column(vUA1 - 1);
                    116:                strcLIN(temp);
                    117:                cp = vUA1; vUA1 = vUD1; vUD1 = cp;
                    118:                cp = vUA2; vUA2 = vUD2; vUD2 = cp;
                    119:                cursor = vUD1;
                    120:                if (state == HARDOPEN) {
                    121:                        doomed = 0;
                    122:                        vsave();
                    123:                        vopen(dot, WBOT);
                    124:                        vnline(cursor);
                    125:                        return;
                    126:                }
                    127:                /*
                    128:                 * Pseudo insert command.
                    129:                 */
                    130:                vcursat(cursor);
                    131:                OO = Outchar; Outchar = vinschar; hold |= HOLDQIK;
                    132:                vprepins();
                    133:                temp[vUA2 - linebuf] = 0;
                    134:                for (cp = &temp[vUA1 - linebuf]; *cp;)
                    135:                        putchar(*cp++);
                    136:                Outchar = OO; hold = oldhold;
                    137:                endim();
                    138:                physdc(cindent(), cindent() + doomed);
                    139:                doomed = 0;
                    140:                vdirty(vcline, 1);
                    141:                vsyncCL();
                    142:                if (cursor > linebuf && cursor >= strend(linebuf))
                    143:                        cursor--;
                    144:                vfixcurs();
                    145:                return;
                    146: 
                    147:        case VNONE:
                    148:                beep();
                    149:                return;
                    150:        }
                    151: }
                    152: 
                    153: /*
                    154:  * Initialize undo information before an append.
                    155:  */
                    156: vnoapp()
                    157: {
                    158: 
                    159:        vUD1 = vUD2 = cursor;
                    160: }
                    161: 
                    162: /*
                    163:  * All the rest of the motion sequences have one or more
                    164:  * cases to deal with.  In the case wdot == 0, operation
                    165:  * is totally within current line, from cursor to wcursor.
                    166:  * If wdot is given, but wcursor is 0, then operation affects
                    167:  * the inclusive line range.  The hardest case is when both wdot
                    168:  * and wcursor are given, then operation affects from line dot at
                    169:  * cursor to line wdot at wcursor.
                    170:  */
                    171: 
                    172: /*
                    173:  * Move is simple, except for moving onto new lines in hardcopy open mode.
                    174:  */
                    175: vmove()
                    176: {
                    177:        register int cnt;
                    178: 
                    179:        if (wdot) {
                    180:                if (wdot < one || wdot > dol) {
                    181:                        beep();
                    182:                        return;
                    183:                }
                    184:                cnt = wdot - dot;
                    185:                wdot = NOLINE;
                    186:                if (cnt)
                    187:                        killU();
                    188:                vupdown(cnt, wcursor);
                    189:                return;
                    190:        }
                    191: 
                    192:        /*
                    193:         * When we move onto a new line, save information for U undo.
                    194:         */
                    195:        if (vUNDdot != dot) {
                    196:                vUNDsav = *dot;
                    197:                vUNDcurs = wcursor;
                    198:                vUNDdot = dot;
                    199:        }
                    200: 
                    201:        /*
                    202:         * In hardcopy open, type characters to left of cursor
                    203:         * on new line, or back cursor up if its to left of where we are.
                    204:         * In any case if the current line is ``rubbled'' i.e. has trashy
                    205:         * looking overstrikes on it or \'s from deletes, we reprint
                    206:         * so it is more comprehensible (and also because we can't work
                    207:         * if we let it get more out of sync since column() won't work right.
                    208:         */
                    209:        if (state == HARDOPEN) {
                    210:                register char *cp;
                    211:                if (rubble) {
                    212:                        register int c;
                    213:                        int oldhold = hold;
                    214: 
                    215:                        sethard();
                    216:                        cp = wcursor;
                    217:                        c = *cp;
                    218:                        *cp = 0;
                    219:                        hold |= HOLDDOL;
                    220:                        vreopen(WTOP, lineDOT(), vcline);
                    221:                        hold = oldhold;
                    222:                        *cp = c;
                    223:                } else if (wcursor > cursor) {
                    224:                        vfixcurs();
                    225:                        for (cp = cursor; *cp && cp < wcursor;) {
                    226:                                register int c = *cp++ & TRIM;
                    227: 
                    228:                                putchar(c ? c : ' ');
                    229:                        }
                    230:                }
                    231:        }
                    232:        vsetcurs(wcursor);
                    233: }
                    234: 
                    235: /*
                    236:  * Delete operator.
                    237:  *
                    238:  * Hard case of deleting a range where both wcursor and wdot
                    239:  * are specified is treated as a special case of change and handled
                    240:  * by vchange (although vchange may pass it back if it degenerates
                    241:  * to a full line range delete.)
                    242:  */
                    243: vdelete(c)
                    244:        char c;
                    245: {
                    246:        register char *cp;
                    247:        register int i;
                    248: 
                    249:        if (wdot) {
                    250:                if (wcursor) {
                    251:                        vchange('d');
                    252:                        return;
                    253:                }
                    254:                if ((i = xdw()) < 0)
                    255:                        return;
                    256:                if (state != VISUAL) {
                    257:                        vgoto(LINE(0), 0);
                    258:                        vputchar('@');
                    259:                }
                    260:                wdot = dot;
                    261:                vremote(i, delete, 0);
                    262:                notenam = "delete";
                    263:                DEL[0] = 0;
                    264:                killU();
                    265:                vreplace(vcline, i, 0);
                    266:                if (wdot > dol)
                    267:                        vcline--;
                    268:                vrepaint(NOSTR);
                    269:                return;
                    270:        }
                    271:        if (wcursor < linebuf)
                    272:                wcursor = linebuf;
                    273:        if (cursor == wcursor) {
                    274:                beep();
                    275:                return;
                    276:        }
                    277:        i = vdcMID();
                    278:        cp = cursor;
                    279:        setDEL();
                    280:        CP(cp, wcursor);
                    281:        if (cp > linebuf && (cp[0] == 0 || c == '#'))
                    282:                cp--;
                    283:        if (state == HARDOPEN) {
                    284:                bleep(i, cp);
                    285:                cursor = cp;
                    286:                return;
                    287:        }
                    288:        physdc(column(cursor - 1), i);
                    289:        DEPTH(vcline) = 0;
                    290:        vreopen(LINE(vcline), lineDOT(), vcline);
                    291:        vsyncCL();
                    292:        vsetcurs(cp);
                    293: }
                    294: 
                    295: /*
                    296:  * Change operator.
                    297:  *
                    298:  * In a single line we mark the end of the changed area with '$'.
                    299:  * On multiple whole lines, we clear the lines first.
                    300:  * Across lines with both wcursor and wdot given, we delete
                    301:  * and sync then append (but one operation for undo).
                    302:  */
                    303: vchange(c)
                    304:        char c;
                    305: {
                    306:        register char *cp;
                    307:        register int i, ind, cnt;
                    308:        line *addr;
                    309: 
                    310:        if (wdot) {
                    311:                /*
                    312:                 * Change/delete of lines or across line boundaries.
                    313:                 */
                    314:                if ((cnt = xdw()) < 0)
                    315:                        return;
                    316:                getDOT();
                    317:                if (wcursor && cnt == 1) {
                    318:                        /*
                    319:                         * Not really.
                    320:                         */
                    321:                        wdot = 0;
                    322:                        if (c == 'd') {
                    323:                                vdelete(c);
                    324:                                return;
                    325:                        }
                    326:                        goto smallchange;
                    327:                }
                    328:                if (cursor && wcursor) {
                    329:                        /*
                    330:                         * Across line boundaries, but not
                    331:                         * necessarily whole lines.
                    332:                         * Construct what will be left.
                    333:                         */
                    334:                        *cursor = 0;
                    335:                        strcpy(genbuf, linebuf);
                    336:                        getline(*wdot);
                    337:                        if (strlen(genbuf) + strlen(wcursor) > LBSIZE - 2) {
                    338:                                getDOT();
                    339:                                beep();
                    340:                                return;
                    341:                        }
                    342:                        strcat(genbuf, wcursor);
                    343:                        if (c == 'd' && *vpastwh(genbuf) == 0) {
                    344:                                /*
                    345:                                 * Although this is a delete
                    346:                                 * spanning line boundaries, what
                    347:                                 * would be left is all white space,
                    348:                                 * so take it all away.
                    349:                                 */
                    350:                                wcursor = 0;
                    351:                                getDOT();
                    352:                                op = 0;
                    353:                                notpart(lastreg);
                    354:                                notpart('1');
                    355:                                vdelete(c);
                    356:                                return;
                    357:                        }
                    358:                        ind = -1;
                    359:                } else if (c == 'd' && wcursor == 0) {
                    360:                        vdelete(c);
                    361:                        return;
                    362:                } else
                    363: #ifdef LISPCODE
                    364:                        /*
                    365:                         * We are just substituting text for whole lines,
                    366:                         * so determine the first autoindent.
                    367:                         */
                    368:                        if (value(LISP) && value(AUTOINDENT))
                    369:                                ind = lindent(dot);
                    370:                        else
                    371: #endif
                    372:                                ind = whitecnt(linebuf);
                    373:                i = vcline >= 0 ? LINE(vcline) : WTOP;
                    374: 
                    375:                /*
                    376:                 * Delete the lines from the buffer,
                    377:                 * and remember how the partial stuff came about in
                    378:                 * case we are told to put.
                    379:                 */
                    380:                addr = dot;
                    381:                vremote(cnt, delete, 0);
                    382:                setpk();
                    383:                notenam = "delete";
                    384:                if (c != 'd')
                    385:                        notenam = "change";
                    386:                /*
                    387:                 * If DEL[0] were nonzero, put would put it back
                    388:                 * rather than the deleted lines.
                    389:                 */
                    390:                DEL[0] = 0;
                    391:                if (cnt > 1)
                    392:                        killU();
                    393: 
                    394:                /*
                    395:                 * Now hack the screen image coordination.
                    396:                 */
                    397:                vreplace(vcline, cnt, 0);
                    398:                wdot = NOLINE;
                    399:                noteit(0);
                    400:                vcline--;
                    401:                if (addr <= dol)
                    402:                        dot--;
                    403: 
                    404:                /*
                    405:                 * If this is a across line delete/change,
                    406:                 * cursor stays where it is; just splice together the pieces
                    407:                 * of the new line.  Otherwise generate a autoindent
                    408:                 * after a S command.
                    409:                 */
                    410:                if (ind >= 0) {
                    411:                        *genindent(ind) = 0;
                    412:                        vdoappend(genbuf);
                    413:                } else {
                    414:                        vmcurs = cursor;
                    415:                        strcLIN(genbuf);
                    416:                        vdoappend(linebuf);
                    417:                }
                    418: 
                    419:                /*
                    420:                 * Indicate a change on hardcopies by
                    421:                 * erasing the current line.
                    422:                 */
                    423:                if (c != 'd' && state != VISUAL && state != HARDOPEN) {
                    424:                        int oldhold = hold;
                    425: 
                    426:                        hold |= HOLDAT, vclrlin(i, dot), hold = oldhold;
                    427:                }
                    428: 
                    429:                /*
                    430:                 * Open the line (logically) on the screen, and 
                    431:                 * update the screen tail.  Unless we are really a delete
                    432:                 * go off and gather up inserted characters.
                    433:                 */
                    434:                vcline++;
                    435:                if (vcline < 0)
                    436:                        vcline = 0;
                    437:                vopen(dot, i);
                    438:                vsyncCL();
                    439:                noteit(1);
                    440:                if (c != 'd') {
                    441:                        if (ind >= 0) {
                    442:                                cursor = linebuf;
                    443:                                linebuf[0] = 0;
                    444:                                vfixcurs();
                    445:                        } else {
                    446:                                ind = 0;
                    447:                                vcursat(cursor);
                    448:                        }
                    449:                        vappend('x', 1, ind);
                    450:                        return;
                    451:                }
                    452:                if (*cursor == 0 && cursor > linebuf)
                    453:                        cursor--;
                    454:                vrepaint(cursor);
                    455:                return;
                    456:        }
                    457: 
                    458: smallchange:
                    459:        /*
                    460:         * The rest of this is just low level hacking on changes
                    461:         * of small numbers of characters.
                    462:         */
                    463:        if (wcursor < linebuf)
                    464:                wcursor = linebuf;
                    465:        if (cursor == wcursor) {
                    466:                beep();
                    467:                return;
                    468:        }
                    469:        i = vdcMID();
                    470:        cp = cursor;
                    471:        if (state != HARDOPEN)
                    472:                vfixcurs();
                    473: 
                    474:        /*
                    475:         * Put out the \\'s indicating changed text in hardcopy,
                    476:         * or mark the end of the change with $ if not hardcopy.
                    477:         */
                    478:        if (state == HARDOPEN) 
                    479:                bleep(i, cp);
                    480:        else {
                    481:                vcursbef(wcursor);
                    482:                putchar('$');
                    483:                i = cindent();
                    484:        }
                    485: 
                    486:        /*
                    487:         * Remember the deleted text for possible put,
                    488:         * and then prepare and execute the input portion of the change.
                    489:         */
                    490:        cursor = cp;
                    491:        setDEL();
                    492:        CP(cursor, wcursor);
                    493:        if (state != HARDOPEN) {
                    494:                vcursaft(cursor - 1);
                    495:                doomed = i - cindent();
                    496:        } else {
                    497: /*
                    498:                sethard();
                    499:                wcursor = cursor;
                    500:                cursor = linebuf;
                    501:                vgoto(outline, value(NUMBER) << 3);
                    502:                vmove();
                    503: */
                    504:                doomed = 0;
                    505:        }
                    506:        prepapp();
                    507:        vappend('c', 1, 0);
                    508: }
                    509: 
                    510: /*
                    511:  * Open new lines.
                    512:  *
                    513:  * Tricky thing here is slowopen.  This causes display updating
                    514:  * to be held off so that 300 baud dumb terminals don't lose badly.
                    515:  * This also suppressed counts, which otherwise say how many blank
                    516:  * space to open up.  Counts are also suppressed on intelligent terminals.
                    517:  * Actually counts are obsoleted, since if your terminal is slow
                    518:  * you are better off with slowopen.
                    519:  */
                    520: voOpen(c, cnt)
                    521:        char c;
                    522:        register int cnt;
                    523: {
                    524:        register int ind = 0, i;
                    525:        short oldhold = hold;
                    526: 
                    527:        if (value(SLOWOPEN) || value(REDRAW) && AL && DL)
                    528:                cnt = 1;
                    529:        vsave();
                    530:        setLAST();
                    531:        if (value(AUTOINDENT))
                    532:                ind = whitecnt(linebuf);
                    533:        if (c == 'O') {
                    534:                vcline--;
                    535:                dot--;
                    536:                if (dot > zero)
                    537:                        getDOT();
                    538:        }
                    539:        if (value(AUTOINDENT)) {
                    540: #ifdef LISPCODE
                    541:                if (value(LISP))
                    542:                        ind = lindent(dot + 1);
                    543: #endif
                    544:        }
                    545:        killU();
                    546:        prepapp();
                    547:        vundkind = VMANY;
                    548:        if (state != VISUAL)
                    549:                c = WBOT + 1;
                    550:        else {
                    551:                c = vcline < 0 ? WTOP - cnt : LINE(vcline) + DEPTH(vcline);
                    552:                if (c < ZERO)
                    553:                        c = ZERO;
                    554:                i = LINE(vcline + 1) - c;
                    555:                if (i < cnt && c <= WBOT && (!AL || !DL))
                    556:                        vinslin(c, cnt - i, vcline);
                    557:        }
                    558:        *genindent(ind) = 0;
                    559:        vdoappend(genbuf);
                    560:        vcline++;
                    561:        oldhold = hold;
                    562:        hold |= HOLDROL;
                    563:        vopen(dot, c);
                    564:        hold = oldhold;
                    565:        if (value(SLOWOPEN))
                    566:                /*
                    567:                 * Oh, so lazy!
                    568:                 */
                    569:                vscrap();
                    570:        else
                    571:                vsync1(LINE(vcline));
                    572:        cursor = linebuf;
                    573:        linebuf[0] = 0;
                    574:        vappend('o', 1, ind);
                    575: }
                    576: 
                    577: /*
                    578:  * > < and = shift operators.
                    579:  *
                    580:  * Note that =, which aligns lisp, is just a ragged sort of shift,
                    581:  * since it never distributes text between lines.
                    582:  */
                    583: char   vshnam[2] = { 'x', 0 };
                    584: 
                    585: vshftop()
                    586: {
                    587:        register line *addr;
                    588:        register int cnt;
                    589: 
                    590:        if ((cnt = xdw()) < 0)
                    591:                return;
                    592:        addr = dot;
                    593:        vremote(cnt, vshift, 0);
                    594:        vshnam[0] = op;
                    595:        notenam = vshnam;
                    596:        dot = addr;
                    597:        vreplace(vcline, cnt, cnt);
                    598:        if (state == HARDOPEN)
                    599:                vcnt = 0;
                    600:        vrepaint(NOSTR);
                    601: }
                    602: 
                    603: /*
                    604:  * !.
                    605:  *
                    606:  * Filter portions of the buffer through unix commands.
                    607:  */
                    608: vfilter()
                    609: {
                    610:        register line *addr;
                    611:        register int cnt;
                    612:        char *oglobp, d;
                    613: 
                    614:        if ((cnt = xdw()) < 0)
                    615:                return;
                    616:        if (vglobp)
                    617:                vglobp = uxb;
                    618:        if (readecho('!'))
                    619:                return;
                    620:        oglobp = globp; globp = genbuf + 1;
                    621:        d = peekc; ungetchar(0);
                    622:        CATCH
                    623:                fixech();
                    624:                unix0(0);
                    625:        ONERR
                    626:                splitw = 0;
                    627:                ungetchar(d);
                    628:                vrepaint(cursor);
                    629:                globp = oglobp;
                    630:                return;
                    631:        ENDCATCH
                    632:        ungetchar(d); globp = oglobp;
                    633:        addr = dot;
                    634:        CATCH
                    635:                vgoto(WECHO, 0); flusho();
                    636:                vremote(cnt, filter, 2);
                    637:        ONERR
                    638:                vdirty(0, LINES);
                    639:        ENDCATCH
                    640:        if (dot == zero && dol > zero)
                    641:                dot = one;
                    642:        splitw = 0;
                    643:        notenam = "";
                    644:        vreplace(vcline, cnt, undap2 - undap1);
                    645:        dot = addr;
                    646:        if (dot > dol) {
                    647:                dot--;
                    648:                vcline--;
                    649:        }
                    650:        vrepaint(NOSTR);
                    651: }
                    652: 
                    653: /*
                    654:  * Xdw exchanges dot and wdot if appropriate and also checks
                    655:  * that wdot is reasonable.  Its name comes from
                    656:  *     xchange dotand wdot
                    657:  */
                    658: xdw()
                    659: {
                    660:        register char *cp;
                    661:        register int cnt;
                    662: /*
                    663:        register int notp = 0;
                    664:  */
                    665: 
                    666:        if (wdot == NOLINE || wdot < one || wdot > dol) {
                    667:                beep();
                    668:                return (-1);
                    669:        }
                    670:        vsave();
                    671:        setLAST();
                    672:        if (dot > wdot) {
                    673:                register line *addr;
                    674: 
                    675:                vcline -= dot - wdot;
                    676:                addr = dot; dot = wdot; wdot = addr;
                    677:                cp = cursor; cursor = wcursor; wcursor = cp;
                    678:        }
                    679:        /*
                    680:         * If a region is specified but wcursor is at the begining
                    681:         * of the last line, then we move it to be the end of the
                    682:         * previous line (actually off the end).
                    683:         */
                    684:        if (cursor && wcursor == linebuf && wdot > dot) {
                    685:                wdot--;
                    686:                getDOT();
                    687:                if (vpastwh(linebuf) >= cursor)
                    688:                        wcursor = 0;
                    689:                else {
                    690:                        getline(*wdot);
                    691:                        wcursor = strend(linebuf);
                    692:                        getDOT();
                    693:                }
                    694:                /*
                    695:                 * Should prepare in caller for possible dot == wdot.
                    696:                 */
                    697:        }
                    698:        cnt = wdot - dot + 1;
                    699:        if (vreg) {
                    700:                vremote(cnt, YANKreg, vreg);
                    701: /*
                    702:                if (notp)
                    703:                        notpart(vreg);
                    704:  */
                    705:        }
                    706: 
                    707:        /*
                    708:         * Kill buffer code.  If delete operator is c or d, then save
                    709:         * the region in numbered buffers.
                    710:         *
                    711:         * BUG:                 This may be somewhat inefficient due
                    712:         *                      to the way named buffer are implemented,
                    713:         *                      necessitating some optimization.
                    714:         */
                    715:        vreg = 0;
                    716:        if (any(op, "cd")) {
                    717:                vremote(cnt, YANKreg, '1');
                    718: /*
                    719:                if (notp)
                    720:                        notpart('1');
                    721:  */
                    722:        }
                    723:        return (cnt);
                    724: }
                    725: 
                    726: /*
                    727:  * Routine for vremote to call to implement shifts.
                    728:  */
                    729: vshift()
                    730: {
                    731: 
                    732:        shift(op, 1);
                    733: }
                    734: 
                    735: /*
                    736:  * Replace a single character with the next input character.
                    737:  * A funny kind of insert.
                    738:  */
                    739: vrep(cnt)
                    740:        register int cnt;
                    741: {
                    742:        register int i, c;
                    743: 
                    744:        if (cnt > strlen(cursor)) {
                    745:                beep();
                    746:                return;
                    747:        }
                    748:        i = column(cursor + cnt - 1);
                    749:        vcursat(cursor);
                    750:        doomed = i - cindent();
                    751:        if (!vglobp) {
                    752:                c = getesc();
                    753:                if (c == 0) {
                    754:                        vfixcurs();
                    755:                        return;
                    756:                }
                    757:                ungetkey(c);
                    758:        }
                    759:        CP(vutmp, linebuf);
                    760:        vundkind = VCHNG;
                    761:        wcursor = cursor + cnt;
                    762:        vUD1 = cursor; vUD2 = wcursor;
                    763:        CP(cursor, wcursor);
                    764:        prepapp();
                    765:        vappend('r', cnt, 0);
                    766:        *lastcp++ = INS[0];
                    767:        setLAST();
                    768: }
                    769: 
                    770: /*
                    771:  * Yank.
                    772:  *
                    773:  * Yanking to string registers occurs for free (essentially)
                    774:  * in the routine xdw().
                    775:  */
                    776: vyankit()
                    777: {
                    778:        register int cnt;
                    779: 
                    780:        if (wdot) {
                    781:                if ((cnt = xdw()) < 0)
                    782:                        return;
                    783:                vremote(cnt, yank, 0);
                    784:                setpk();
                    785:                notenam = "yank";
                    786:                vundkind = VNONE;
                    787:                DEL[0] = 0;
                    788:                wdot = NOLINE;
                    789:                if (notecnt <= vcnt - vcline && notecnt < value(REPORT))
                    790:                        notecnt = 0;
                    791:                vrepaint(cursor);
                    792:                return;
                    793:        }
                    794:        takeout(DEL);
                    795: }
                    796: 
                    797: /*
                    798:  * Set pkill variables so a put can
                    799:  * know how to put back partial text.
                    800:  * This is necessary because undo needs the complete
                    801:  * line images to be saved, while a put wants to trim
                    802:  * the first and last lines.  The compromise
                    803:  * is for put to be more clever.
                    804:  */
                    805: setpk()
                    806: {
                    807: 
                    808:        if (wcursor) {
                    809:                pkill[0] = cursor;
                    810:                pkill[1] = wcursor;
                    811:        }
                    812: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.