Annotation of 3BSD/cmd/ex/ex_voperate.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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