Annotation of researchv10no/cmd/ex/ex_voper.c, revision 1.1.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.