Annotation of researchv10no/cmd/ex/ex_voper.c, revision 1.1

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

unix.superglobalmegacorp.com

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