Annotation of 43BSD/ucb/ex/ex_voper.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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