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

unix.superglobalmegacorp.com

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