Annotation of 43BSDTahoe/ucb/ex/ex_voper.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1980 Regents of the University of California.
        !             3:  * All rights reserved.  The Berkeley software License Agreement
        !             4:  * specifies the terms and conditions for redistribution.
        !             5:  */
        !             6: 
        !             7: #ifndef lint
        !             8: static char *sccsid = "@(#)ex_voper.c  7.6 (Berkeley) 1/2/88";
        !             9: #endif not lint
        !            10: 
        !            11: #include "ex.h"
        !            12: #include "ex_tty.h"
        !            13: #include "ex_vis.h"
        !            14: 
        !            15: #define        blank()         isspace(wcursor[0])
        !            16: #define        forbid(a)       if (a) goto errlab;
        !            17: 
        !            18: char   vscandir[2] =   { '/', 0 };
        !            19: 
        !            20: /*
        !            21:  * Decode an operator/operand type command.
        !            22:  * Eventually we switch to an operator subroutine in ex_vops.c.
        !            23:  * The work here is setting up a function variable to point
        !            24:  * to the routine we want, and manipulation of the variables
        !            25:  * wcursor and wdot, which mark the other end of the affected
        !            26:  * area.  If wdot is zero, then the current line is the other end,
        !            27:  * and if wcursor is zero, then the first non-blank location of the
        !            28:  * other line is implied.
        !            29:  */
        !            30: operate(c, cnt)
        !            31:        register int c, cnt;
        !            32: {
        !            33:        register int i;
        !            34:        int (*moveop)(), (*deleteop)();
        !            35:        register int (*opf)();
        !            36:        bool subop = 0;
        !            37:        char *oglobp, *ocurs;
        !            38:        register line *addr;
        !            39:        line *odot;
        !            40:        static char lastFKND, lastFCHR;
        !            41:        short d;
        !            42: 
        !            43:        moveop = vmove, deleteop = vdelete;
        !            44:        wcursor = cursor;
        !            45:        wdot = NOLINE;
        !            46:        notecnt = 0;
        !            47:        dir = 1;
        !            48:        switch (c) {
        !            49: 
        !            50:        /*
        !            51:         * d            delete operator.
        !            52:         */
        !            53:        case 'd':
        !            54:                moveop = vdelete;
        !            55:                deleteop = beep;
        !            56:                break;
        !            57: 
        !            58:        /*
        !            59:         * s            substitute characters, like c\040, i.e. change space.
        !            60:         */
        !            61:        case 's':
        !            62:                ungetkey(' ');
        !            63:                subop++;
        !            64:                /* fall into ... */
        !            65: 
        !            66:        /*
        !            67:         * c            Change operator.
        !            68:         */
        !            69:        case 'c':
        !            70:                if (c == 'c' && workcmd[0] == 'C' || workcmd[0] == 'S')
        !            71:                        subop++;
        !            72:                moveop = vchange;
        !            73:                deleteop = beep;
        !            74:                break;
        !            75: 
        !            76:        /*
        !            77:         * !            Filter through a UNIX command.
        !            78:         */
        !            79:        case '!':
        !            80:                moveop = vfilter;
        !            81:                deleteop = beep;
        !            82:                break;
        !            83: 
        !            84:        /*
        !            85:         * y            Yank operator.  Place specified text so that it
        !            86:         *              can be put back with p/P.  Also yanks to named buffers.
        !            87:         */
        !            88:        case 'y':
        !            89:                moveop = vyankit;
        !            90:                deleteop = beep;
        !            91:                break;
        !            92: 
        !            93:        /*
        !            94:         * =            Reformat operator (for LISP).
        !            95:         */
        !            96: #ifdef LISPCODE
        !            97:        case '=':
        !            98:                forbid(!value(LISP));
        !            99:                /* fall into ... */
        !           100: #endif
        !           101: 
        !           102:        /*
        !           103:         * >            Right shift operator.
        !           104:         * <            Left shift operator.
        !           105:         */
        !           106:        case '<':
        !           107:        case '>':
        !           108:                moveop = vshftop;
        !           109:                deleteop = beep;
        !           110:                break;
        !           111: 
        !           112:        /*
        !           113:         * r            Replace character under cursor with single following
        !           114:         *              character.
        !           115:         */
        !           116:        case 'r':
        !           117:                vmacchng(1);
        !           118:                vrep(cnt);
        !           119:                return;
        !           120: 
        !           121:        default:
        !           122:                goto nocount;
        !           123:        }
        !           124:        vmacchng(1);
        !           125:        /*
        !           126:         * Had an operator, so accept another count.
        !           127:         * Multiply counts together.
        !           128:         */
        !           129:        if (isdigit(peekkey()) && peekkey() != '0') {
        !           130:                cnt *= vgetcnt();
        !           131:                Xcnt = cnt;
        !           132:                forbid (cnt <= 0);
        !           133:        }
        !           134: 
        !           135:        /*
        !           136:         * Get next character, mapping it and saving as
        !           137:         * part of command for repeat.
        !           138:         */
        !           139:        c = map(getesc(),arrows);
        !           140:        if (c == 0)
        !           141:                return;
        !           142:        if (!subop)
        !           143:                *lastcp++ = c;
        !           144: nocount:
        !           145:        opf = moveop;
        !           146:        switch (c) {
        !           147: 
        !           148:        /*
        !           149:         * b            Back up a word.
        !           150:         * B            Back up a word, liberal definition.
        !           151:         */
        !           152:        case 'b':
        !           153:        case 'B':
        !           154:                dir = -1;
        !           155:                /* fall into ... */
        !           156: 
        !           157:        /*
        !           158:         * w            Forward a word.
        !           159:         * W            Forward a word, liberal definition.
        !           160:         */
        !           161:        case 'W':
        !           162:        case 'w':
        !           163:                wdkind = c & ' ';
        !           164:                forbid(lfind(2, cnt, opf, (line *) 0) < 0);
        !           165:                vmoving = 0;
        !           166:                break;
        !           167: 
        !           168:        /*
        !           169:         * E            to end of following blank/nonblank word
        !           170:         */
        !           171:        case 'E':
        !           172:                wdkind = 0;
        !           173:                goto ein;
        !           174: 
        !           175:        /*
        !           176:         * e            To end of following word.
        !           177:         */
        !           178:        case 'e':
        !           179:                wdkind = 1;
        !           180: ein:
        !           181:                forbid(lfind(3, cnt - 1, opf, (line *) 0) < 0);
        !           182:                vmoving = 0;
        !           183:                break;
        !           184: 
        !           185:        /*
        !           186:         * (            Back an s-expression.
        !           187:         */
        !           188:        case '(':
        !           189:                dir = -1;
        !           190:                /* fall into... */
        !           191: 
        !           192:        /*
        !           193:         * )            Forward an s-expression.
        !           194:         */
        !           195:        case ')':
        !           196:                forbid(lfind(0, cnt, opf, (line *) 0) < 0);
        !           197:                markDOT();
        !           198:                break;
        !           199: 
        !           200:        /*
        !           201:         * {            Back an s-expression, but don't stop on atoms.
        !           202:         *              In text mode, a paragraph.  For C, a balanced set
        !           203:         *              of {}'s.
        !           204:         */
        !           205:        case '{':
        !           206:                dir = -1;
        !           207:                /* fall into... */
        !           208: 
        !           209:        /*
        !           210:         * }            Forward an s-expression, but don't stop on atoms.
        !           211:         *              In text mode, back paragraph.  For C, back a balanced
        !           212:         *              set of {}'s.
        !           213:         */
        !           214:        case '}':
        !           215:                forbid(lfind(1, cnt, opf, (line *) 0) < 0);
        !           216:                markDOT();
        !           217:                break;
        !           218: 
        !           219:        /*
        !           220:         * %            To matching () or {}.  If not at ( or { scan for
        !           221:         *              first such after cursor on this line.
        !           222:         */
        !           223:        case '%':
        !           224:                vsave();
        !           225:                i = lmatchp((line *) 0);
        !           226: #ifdef TRACE
        !           227:                if (trace)
        !           228:                        fprintf(trace, "after lmatchp in %, dot=%d, wdot=%d, dol=%d\n", lineno(dot), lineno(wdot), lineno(dol));
        !           229: #endif
        !           230:                getDOT();
        !           231:                forbid(!i);
        !           232:                if (opf != vmove)
        !           233:                        if (dir > 0)
        !           234:                                wcursor++;
        !           235:                        else
        !           236:                                cursor++;
        !           237:                else
        !           238:                        markDOT();
        !           239:                vmoving = 0;
        !           240:                break;
        !           241: 
        !           242:        /*
        !           243:         * [            Back to beginning of defun, i.e. an ( in column 1.
        !           244:         *              For text, back to a section macro.
        !           245:         *              For C, back to a { in column 1 (~~ beg of function.)
        !           246:         */
        !           247:        case '[':
        !           248:                dir = -1;
        !           249:                /* fall into ... */
        !           250: 
        !           251:        /*
        !           252:         * ]            Forward to next defun, i.e. a ( in column 1.
        !           253:         *              For text, forward section.
        !           254:         *              For C, forward to a } in column 1 (if delete or such)
        !           255:         *              or if a move to a { in column 1.
        !           256:         */
        !           257:        case ']':
        !           258:                if (!vglobp)
        !           259:                        forbid(getkey() != c);
        !           260:                forbid (Xhadcnt);
        !           261:                vsave();
        !           262:                i = lbrack(c, opf);
        !           263:                getDOT();
        !           264:                forbid(!i);
        !           265:                markDOT();
        !           266:                if (ospeed > B300)
        !           267:                        hold |= HOLDWIG;
        !           268:                break;
        !           269: 
        !           270:        /*
        !           271:         * ,            Invert last find with f F t or T, like inverse
        !           272:         *              of ;.
        !           273:         */
        !           274:        case ',':
        !           275:                forbid (lastFKND == 0);
        !           276:                c = isupper(lastFKND) ? tolower(lastFKND) : toupper(lastFKND);
        !           277:                i = lastFCHR;
        !           278:                if (vglobp == 0)
        !           279:                        vglobp = "";
        !           280:                subop++;
        !           281:                goto nocount;
        !           282: 
        !           283:        /*
        !           284:         * 0            To beginning of real line.
        !           285:         */
        !           286:        case '0':
        !           287:                wcursor = linebuf;
        !           288:                vmoving = 0;
        !           289:                break;
        !           290: 
        !           291:        /*
        !           292:         * ;            Repeat last find with f F t or T.
        !           293:         */
        !           294:        case ';':
        !           295:                forbid (lastFKND == 0);
        !           296:                c = lastFKND;
        !           297:                i = lastFCHR;
        !           298:                subop++;
        !           299:                goto nocount;
        !           300: 
        !           301:        /*
        !           302:         * F            Find single character before cursor in current line.
        !           303:         * T            Like F, but stops before character.
        !           304:         */
        !           305:        case 'F':       /* inverted find */
        !           306:        case 'T':
        !           307:                dir = -1;
        !           308:                /* fall into ... */
        !           309: 
        !           310:        /*
        !           311:         * f            Find single character following cursor in current line.
        !           312:         * t            Like f, but stope before character.
        !           313:         */
        !           314:        case 'f':       /* find */
        !           315:        case 't':
        !           316:                if (!subop) {
        !           317:                        i = getesc();
        !           318:                        if (i == 0)
        !           319:                                return;
        !           320:                        *lastcp++ = i;
        !           321:                }
        !           322:                if (vglobp == 0)
        !           323:                        lastFKND = c, lastFCHR = i;
        !           324:                for (; cnt > 0; cnt--)
        !           325:                        forbid (find(i) == 0);
        !           326:                vmoving = 0;
        !           327:                switch (c) {
        !           328: 
        !           329:                case 'T':
        !           330:                        wcursor++;
        !           331:                        break;
        !           332: 
        !           333:                case 't':
        !           334:                        wcursor--;
        !           335:                case 'f':
        !           336: fixup:
        !           337:                        if (moveop != vmove)
        !           338:                                wcursor++;
        !           339:                        break;
        !           340:                }
        !           341:                break;
        !           342: 
        !           343:        /*
        !           344:         * |            Find specified print column in current line.
        !           345:         */
        !           346:        case '|':
        !           347:                if (Pline == numbline)
        !           348:                        cnt += 8;
        !           349:                vmovcol = cnt;
        !           350:                vmoving = 1;
        !           351:                wcursor = vfindcol(cnt);
        !           352:                break;
        !           353: 
        !           354:        /*
        !           355:         * ^            To beginning of non-white space on line.
        !           356:         */
        !           357:        case '^':
        !           358:                wcursor = vskipwh(linebuf);
        !           359:                vmoving = 0;
        !           360:                break;
        !           361: 
        !           362:        /*
        !           363:         * $            To end of line.
        !           364:         */
        !           365:        case '$':
        !           366:                if (opf == vmove) {
        !           367:                        vmoving = 1;
        !           368:                        vmovcol = 20000;
        !           369:                } else
        !           370:                        vmoving = 0;
        !           371:                if (cnt > 1) {
        !           372:                        if (opf == vmove) {
        !           373:                                wcursor = 0;
        !           374:                                cnt--;
        !           375:                        } else
        !           376:                                wcursor = linebuf;
        !           377:                        /* This is wrong at EOF */
        !           378:                        wdot = dot + cnt;
        !           379:                        break;
        !           380:                }
        !           381:                if (linebuf[0]) {
        !           382:                        wcursor = strend(linebuf) - 1;
        !           383:                        goto fixup;
        !           384:                }
        !           385:                wcursor = linebuf;
        !           386:                break;
        !           387: 
        !           388:        /*
        !           389:         * h            Back a character.
        !           390:         * ^H           Back a character.
        !           391:         */
        !           392:        case 'h':
        !           393:        case CTRL('h'):
        !           394:                dir = -1;
        !           395:                /* fall into ... */
        !           396: 
        !           397:        /*
        !           398:         * space        Forward a character.
        !           399:         */
        !           400:        case 'l':
        !           401:        case ' ':
        !           402:                forbid (margin() || opf == vmove && edge());
        !           403:                while (cnt > 0 && !margin())
        !           404:                        wcursor += dir, cnt--;
        !           405:                if (margin() && opf == vmove || wcursor < linebuf)
        !           406:                        wcursor -= dir;
        !           407:                vmoving = 0;
        !           408:                break;
        !           409: 
        !           410:        /*
        !           411:         * D            Delete to end of line, short for d$.
        !           412:         */
        !           413:        case 'D':
        !           414:                cnt = INF;
        !           415:                goto deleteit;
        !           416: 
        !           417:        /*
        !           418:         * X            Delete character before cursor.
        !           419:         */
        !           420:        case 'X':
        !           421:                dir = -1;
        !           422:                /* fall into ... */
        !           423: deleteit:
        !           424:        /*
        !           425:         * x            Delete character at cursor, leaving cursor where it is.
        !           426:         */
        !           427:        case 'x':
        !           428:                if (margin())
        !           429:                        goto errlab;
        !           430:                vmacchng(1);
        !           431:                while (cnt > 0 && !margin())
        !           432:                        wcursor += dir, cnt--;
        !           433:                opf = deleteop;
        !           434:                vmoving = 0;
        !           435:                break;
        !           436: 
        !           437:        default:
        !           438:                /*
        !           439:                 * Stuttered operators are equivalent to the operator on
        !           440:                 * a line, thus turn dd into d_.
        !           441:                 */
        !           442:                if (opf == vmove || c != workcmd[0]) {
        !           443: errlab:
        !           444:                        beep();
        !           445:                        vmacp = 0;
        !           446:                        return;
        !           447:                }
        !           448:                /* fall into ... */
        !           449: 
        !           450:        /*
        !           451:         * _            Target for a line or group of lines.
        !           452:         *              Stuttering is more convenient; this is mostly
        !           453:         *              for aesthetics.
        !           454:         */
        !           455:        case '_':
        !           456:                wdot = dot + cnt - 1;
        !           457:                vmoving = 0;
        !           458:                wcursor = 0;
        !           459:                break;
        !           460: 
        !           461:        /*
        !           462:         * H            To first, home line on screen.
        !           463:         *              Count is for count'th line rather than first.
        !           464:         */
        !           465:        case 'H':
        !           466:                wdot = (dot - vcline) + cnt - 1;
        !           467:                if (opf == vmove)
        !           468:                        markit(wdot);
        !           469:                vmoving = 0;
        !           470:                wcursor = 0;
        !           471:                break;
        !           472: 
        !           473:        /*
        !           474:         * -            Backwards lines, to first non-white character.
        !           475:         */
        !           476:        case '-':
        !           477:                wdot = dot - cnt;
        !           478:                vmoving = 0;
        !           479:                wcursor = 0;
        !           480:                break;
        !           481: 
        !           482:        /*
        !           483:         * ^P           To previous line same column.  Ridiculous on the
        !           484:         *              console of the VAX since it puts console in LSI mode.
        !           485:         */
        !           486:        case 'k':
        !           487:        case CTRL('p'):
        !           488:                wdot = dot - cnt;
        !           489:                if (vmoving == 0)
        !           490:                        vmoving = 1, vmovcol = column(cursor);
        !           491:                wcursor = 0;
        !           492:                break;
        !           493: 
        !           494:        /*
        !           495:         * L            To last line on screen, or count'th line from the
        !           496:         *              bottom.
        !           497:         */
        !           498:        case 'L':
        !           499:                wdot = dot + vcnt - vcline - cnt;
        !           500:                if (opf == vmove)
        !           501:                        markit(wdot);
        !           502:                vmoving = 0;
        !           503:                wcursor = 0;
        !           504:                break;
        !           505: 
        !           506:        /*
        !           507:         * M            To the middle of the screen.
        !           508:         */
        !           509:        case 'M':
        !           510:                wdot = dot + ((vcnt + 1) / 2) - vcline - 1;
        !           511:                if (opf == vmove)
        !           512:                        markit(wdot);
        !           513:                vmoving = 0;
        !           514:                wcursor = 0;
        !           515:                break;
        !           516: 
        !           517:        /*
        !           518:         * +            Forward line, to first non-white.
        !           519:         *
        !           520:         * CR           Convenient synonym for +.
        !           521:         */
        !           522:        case '+':
        !           523:        case CR:
        !           524:                wdot = dot + cnt;
        !           525:                vmoving = 0;
        !           526:                wcursor = 0;
        !           527:                break;
        !           528: 
        !           529:        /*
        !           530:         * ^N           To next line, same column if possible.
        !           531:         *
        !           532:         * LF           Linefeed is a convenient synonym for ^N.
        !           533:         */
        !           534:        case CTRL('n'):
        !           535:        case 'j':
        !           536:        case NL:
        !           537:                wdot = dot + cnt;
        !           538:                if (vmoving == 0)
        !           539:                        vmoving = 1, vmovcol = column(cursor);
        !           540:                wcursor = 0;
        !           541:                break;
        !           542: 
        !           543:        /*
        !           544:         * n            Search to next match of current pattern.
        !           545:         */
        !           546:        case 'n':
        !           547:                vglobp = vscandir;
        !           548:                c = *vglobp++;
        !           549:                goto nocount;
        !           550: 
        !           551:        /*
        !           552:         * N            Like n but in reverse direction.
        !           553:         */
        !           554:        case 'N':
        !           555:                vglobp = vscandir[0] == '/' ? "?" : "/";
        !           556:                c = *vglobp++;
        !           557:                goto nocount;
        !           558: 
        !           559:        /*
        !           560:         * '            Return to line specified by following mark,
        !           561:         *              first white position on line.
        !           562:         *
        !           563:         * `            Return to marked line at remembered column.
        !           564:         */
        !           565:        case '\'':
        !           566:        case '`':
        !           567:                d = c;
        !           568:                c = getesc();
        !           569:                if (c == 0)
        !           570:                        return;
        !           571:                c = markreg(c);
        !           572:                forbid (c == 0);
        !           573:                wdot = getmark(c);
        !           574:                forbid (wdot == NOLINE);
        !           575:                forbid (Xhadcnt);
        !           576:                vmoving = 0;
        !           577:                wcursor = d == '`' ? ncols[c - 'a'] : 0;
        !           578:                if (opf == vmove && (wdot != dot || (d == '`' && wcursor != cursor)))
        !           579:                        markDOT();
        !           580:                if (wcursor) {
        !           581:                        vsave();
        !           582:                        getline(*wdot);
        !           583:                        if (wcursor > strend(linebuf))
        !           584:                                wcursor = 0;
        !           585:                        getDOT();
        !           586:                }
        !           587:                if (ospeed > B300)
        !           588:                        hold |= HOLDWIG;
        !           589:                break;
        !           590: 
        !           591:        /*
        !           592:         * G            Goto count'th line, or last line if no count
        !           593:         *              given.
        !           594:         */
        !           595:        case 'G':
        !           596:                if (!Xhadcnt)
        !           597:                        cnt = lineDOL();
        !           598:                wdot = zero + cnt;
        !           599:                forbid (wdot < one || wdot > dol);
        !           600:                if (opf == vmove)
        !           601:                        markit(wdot);
        !           602:                vmoving = 0;
        !           603:                wcursor = 0;
        !           604:                break;
        !           605: 
        !           606:        /*
        !           607:         * /            Scan forward for following re.
        !           608:         * ?            Scan backward for following re.
        !           609:         */
        !           610:        case '/':
        !           611:        case '?':
        !           612:                forbid (Xhadcnt);
        !           613:                vsave();
        !           614:                ocurs = cursor;
        !           615:                odot = dot;
        !           616:                wcursor = 0;
        !           617:                if (readecho(c))
        !           618:                        return;
        !           619:                if (!vglobp)
        !           620:                        vscandir[0] = genbuf[0];
        !           621:                oglobp = globp; CP(vutmp, genbuf); globp = vutmp;
        !           622:                d = peekc;
        !           623: fromsemi:
        !           624:                ungetchar(0);
        !           625:                fixech();
        !           626:                CATCH
        !           627: #ifndef CBREAK
        !           628:                        /*
        !           629:                         * Lose typeahead (ick).
        !           630:                         */
        !           631:                        vcook();
        !           632: #endif
        !           633:                        addr = address(cursor);
        !           634: #ifndef CBREAK
        !           635:                        vraw();
        !           636: #endif
        !           637:                ONERR
        !           638: #ifndef CBREAK
        !           639:                        vraw();
        !           640: #endif
        !           641: slerr:
        !           642:                        globp = oglobp;
        !           643:                        dot = odot;
        !           644:                        cursor = ocurs;
        !           645:                        ungetchar(d);
        !           646:                        splitw = 0;
        !           647:                        vclean();
        !           648:                        vjumpto(dot, ocurs, 0);
        !           649:                        return;
        !           650:                ENDCATCH
        !           651:                if (globp == 0)
        !           652:                        globp = "";
        !           653:                else if (peekc)
        !           654:                        --globp;
        !           655:                if (*globp == ';') {
        !           656:                        /* /foo/;/bar/ */
        !           657:                        globp++;
        !           658:                        dot = addr;
        !           659:                        cursor = loc1;
        !           660:                        goto fromsemi;
        !           661:                }
        !           662:                dot = odot;
        !           663:                ungetchar(d);
        !           664:                c = 0;
        !           665:                if (*globp == 'z')
        !           666:                        globp++, c = '\n';
        !           667:                if (any(*globp, "^+-."))
        !           668:                        c = *globp++;
        !           669:                i = 0;
        !           670:                while (isdigit(*globp))
        !           671:                        i = i * 10 + *globp++ - '0';
        !           672:                if (any(*globp, "^+-."))
        !           673:                        c = *globp++;
        !           674:                if (*globp) {
        !           675:                        /* random junk after the pattern */
        !           676:                        beep();
        !           677:                        goto slerr;
        !           678:                }
        !           679:                globp = oglobp;
        !           680:                splitw = 0;
        !           681:                vmoving = 0;
        !           682:                wcursor = loc1;
        !           683:                if (i != 0)
        !           684:                        vsetsiz(i);
        !           685:                if (opf == vmove) {
        !           686:                        if (state == ONEOPEN || state == HARDOPEN)
        !           687:                                outline = destline = WBOT;
        !           688:                        if (addr != dot || loc1 != cursor)
        !           689:                                markDOT();
        !           690:                        if (loc1 > linebuf && *loc1 == 0)
        !           691:                                loc1--;
        !           692:                        if (c)
        !           693:                                vjumpto(addr, loc1, c);
        !           694:                        else {
        !           695:                                vmoving = 0;
        !           696:                                if (loc1) {
        !           697:                                        vmoving++;
        !           698:                                        vmovcol = column(loc1);
        !           699:                                }
        !           700:                                getDOT();
        !           701:                                if (state == CRTOPEN && addr != dot)
        !           702:                                        vup1();
        !           703:                                vupdown(addr - dot, NOSTR);
        !           704:                        }
        !           705:                        return;
        !           706:                }
        !           707:                lastcp[-1] = 'n';
        !           708:                getDOT();
        !           709:                wdot = addr;
        !           710:                break;
        !           711:        }
        !           712:        /*
        !           713:         * Apply.
        !           714:         */
        !           715:        if (vreg && wdot == 0)
        !           716:                wdot = dot;
        !           717:        (*opf)(c);
        !           718: flusho();
        !           719:        wdot = NOLINE;
        !           720: }
        !           721: 
        !           722: /*
        !           723:  * Find single character c, in direction dir from cursor.
        !           724:  */
        !           725: find(c)
        !           726:        char c;
        !           727: {
        !           728: 
        !           729:        for(;;) {
        !           730:                if (edge())
        !           731:                        return (0);
        !           732:                wcursor += dir;
        !           733:                if (*wcursor == c)
        !           734:                        return (1);
        !           735:        }
        !           736: }
        !           737: 
        !           738: /*
        !           739:  * Do a word motion with operator op, and cnt more words
        !           740:  * to go after this.
        !           741:  */
        !           742: word(op, cnt)
        !           743:        register int (*op)();
        !           744:        int cnt;
        !           745: {
        !           746:        register int which;
        !           747:        register char *iwc;
        !           748:        register line *iwdot = wdot;
        !           749: 
        !           750:        if (dir == 1) {
        !           751:                iwc = wcursor;
        !           752:                which = wordch(wcursor);
        !           753:                while (wordof(which, wcursor)) {
        !           754:                        if (cnt == 1 && op != vmove && wcursor[1] == 0) {
        !           755:                                wcursor++;
        !           756:                                break;
        !           757:                        }
        !           758:                        if (!lnext())
        !           759:                                return (0);
        !           760:                        if (wcursor == linebuf)
        !           761:                                break;
        !           762:                }
        !           763:                /* Unless last segment of a change skip blanks */
        !           764:                if (op != vchange || cnt > 1)
        !           765:                        while (!margin() && blank())
        !           766:                                wcursor++;
        !           767:                else
        !           768:                        if (wcursor == iwc && iwdot == wdot && *iwc)
        !           769:                                wcursor++;
        !           770:                if (op == vmove && margin())
        !           771:                        wcursor--;
        !           772:        } else {
        !           773:                if (!lnext())
        !           774:                        return (0);
        !           775:                while (blank())
        !           776:                        if (!lnext())
        !           777:                                return (0);
        !           778:                if (!margin()) {
        !           779:                        which = wordch(wcursor);
        !           780:                        while (!margin() && wordof(which, wcursor))
        !           781:                                wcursor--;
        !           782:                }
        !           783:                if (wcursor < linebuf || !wordof(which, wcursor))
        !           784:                        wcursor++;
        !           785:        }
        !           786:        return (1);
        !           787: }
        !           788: 
        !           789: /*
        !           790:  * To end of word, with operator op and cnt more motions
        !           791:  * remaining after this.
        !           792:  */
        !           793: eend(op)
        !           794:        register int (*op)();
        !           795: {
        !           796:        register int which;
        !           797: 
        !           798:        if (!lnext())
        !           799:                return;
        !           800:        while (blank())
        !           801:                if (!lnext())
        !           802:                        return;
        !           803:        which = wordch(wcursor);
        !           804:        while (wordof(which, wcursor)) {
        !           805:                if (wcursor[1] == 0) {
        !           806:                        wcursor++;
        !           807:                        break;
        !           808:                }
        !           809:                if (!lnext())
        !           810:                        return;
        !           811:        }
        !           812:        if (op != vchange && op != vdelete && wcursor > linebuf)
        !           813:                wcursor--;
        !           814: }
        !           815: 
        !           816: /*
        !           817:  * Wordof tells whether the character at *wc is in a word of
        !           818:  * kind which (blank/nonblank words are 0, conservative words 1).
        !           819:  */
        !           820: wordof(which, wc)
        !           821:        char which;
        !           822:        register char *wc;
        !           823: {
        !           824: 
        !           825:        if (isspace(*wc))
        !           826:                return (0);
        !           827:        return (!wdkind || wordch(wc) == which);
        !           828: }
        !           829: 
        !           830: /*
        !           831:  * Wordch tells whether character at *wc is a word character
        !           832:  * i.e. an alfa, digit, or underscore.
        !           833:  */
        !           834: wordch(wc)
        !           835:        char *wc;
        !           836: {
        !           837:        register int c;
        !           838: 
        !           839:        c = wc[0];
        !           840:        return (isalpha(c) || isdigit(c) || c == '_');
        !           841: }
        !           842: 
        !           843: /*
        !           844:  * Edge tells when we hit the last character in the current line.
        !           845:  */
        !           846: edge()
        !           847: {
        !           848: 
        !           849:        if (linebuf[0] == 0)
        !           850:                return (1);
        !           851:        if (dir == 1)
        !           852:                return (wcursor[1] == 0);
        !           853:        else
        !           854:                return (wcursor == linebuf);
        !           855: }
        !           856: 
        !           857: /*
        !           858:  * Margin tells us when we have fallen off the end of the line.
        !           859:  */
        !           860: margin()
        !           861: {
        !           862: 
        !           863:        return (wcursor < linebuf || wcursor[0] == 0);
        !           864: }

unix.superglobalmegacorp.com

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