Annotation of 43BSD/contrib/B/src/bed/move.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
                      2: static char rcsid[] = "$Header: move.c,v 2.4 85/08/22 16:05:16 timo Exp $";
                      3: 
                      4: /*
                      5:  * B editor -- Process arrow keys in four directions, plus TAB.
                      6:  */
                      7: 
                      8: #include "b.h"
                      9: #include "bobj.h"
                     10: #include "node.h"
                     11: #include "supr.h"
                     12: #include "gram.h"
                     13: 
                     14: #define Left (-1)
                     15: #define Rite 1
                     16: 
                     17: 
                     18: /*
                     19:  * Common code for PREVIOUS and NEXT commands.
                     20:  */
                     21: 
                     22: Hidden bool
                     23: prevnext(ep, direction)
                     24:        environ *ep;
                     25: {
                     26:        node n;
                     27:        node n1;
                     28:        int nch;
                     29:        int i;
                     30:        int len;
                     31:        int sym;
                     32:        string *rp;
                     33: 
                     34:        higher(ep);
                     35:        switch (ep->mode) {
                     36:        case VHOLE:
                     37:        case FHOLE:
                     38:        case ATBEGIN:
                     39:        case ATEND:
                     40:                if (direction == Left)
                     41:                        leftvhole(ep);
                     42:                else
                     43:                        ritevhole(ep);
                     44:        }
                     45: 
                     46:        for (;;) {
                     47:                n = tree(ep->focus);
                     48:                nch = nchildren(n);
                     49:                rp = noderepr(n);
                     50: 
                     51:                switch (ep->mode) {
                     52: 
                     53:                case ATBEGIN:
                     54:                case ATEND:
                     55:                        ep->mode = WHOLE;
                     56:                        continue;
                     57: 
                     58:                case VHOLE:
                     59:                case FHOLE:
                     60:                        if (direction == Rite) {
                     61:                                if (ep->s1&1)
                     62:                                        len = Fwidth(rp[ep->s1/2]);
                     63:                                else {
                     64:                                        n1 = child(n, ep->s1/2);
                     65:                                        len = width(n1);
                     66:                                }
                     67:                        }
                     68:                        if (direction == Rite ? ep->s2 >= len : ep->s2 <= 0) {
                     69:                                ep->mode = SUBSET;
                     70:                                ep->s2 = ep->s1;
                     71:                                return nextchar(ep, direction);
                     72:                        }
                     73:                        ep->s2 += direction;
                     74:                        return Yes;
                     75: 
                     76:                case SUBRANGE:
                     77:                        if (direction == Rite) {
                     78:                                if (ep->s1&1)
                     79:                                        len = Fwidth(rp[ep->s1/2]);
                     80:                                else {
                     81:                                        n1 = child(n, ep->s1/2);
                     82:                                        len = width(n1);
                     83:                                }
                     84:                        }
                     85:                        if (direction == Left ? ep->s2 <= 0 : ep->s3 >= len-1) {
                     86:                                ep->mode = SUBSET;
                     87:                                ep->s2 = ep->s1;
                     88:                                return nextchar(ep, direction);
                     89:                        }
                     90:                        if (direction == Rite)
                     91:                                ep->s2 = ++ep->s3;
                     92:                        else
                     93:                                ep->s3 = --ep->s2;
                     94:                        return Yes;
                     95: 
                     96:                case SUBSET:
                     97:                        if (direction == Rite ? ep->s2 > 2*nch : ep->s1 <= 1) {
                     98:                                ep->mode = WHOLE;
                     99:                                continue;
                    100:                        }
                    101:                        if (direction == Rite)
                    102:                                ep->s1 = ++ep->s2;
                    103:                        else
                    104:                                ep->s2 = --ep->s1;
                    105:                        if (ep->s1&1) {
                    106:                                if (!Fw_positive(rp[ep->s1/2]) || allspaces(rp[ep->s1/2]))
                    107:                                        continue;
                    108:                        }
                    109:                        else {
                    110:                                sym = symbol(n);
                    111:                                if (downi(&ep->focus, ep->s1/2)) {
                    112:                                        n = tree(ep->focus);
                    113:                                        if (((value)n)->type == Tex)
                    114:                                                s_up(ep);
                    115:                                        else {
                    116:                                                if (ep->s1 == 2*nch && direction == Rite
                    117:                                                        && issublist(sym) && samelevel(sym, symbol(n))) {
                    118:                                                        ep->mode = SUBLIST;
                    119:                                                        ep->s3 = 1;
                    120:                                                        return Yes;
                    121:                                                }
                    122:                                                ep->mode = WHOLE;
                    123:                                                if (width(n) == 0)
                    124:                                                        continue;
                    125:                                        }
                    126:                                }
                    127:                        }
                    128:                        return Yes;
                    129: 
                    130:                case SUBLIST:
                    131:                        sym = symbol(n);
                    132:                        if (direction == Left) {
                    133:                                i = ichild(ep->focus);
                    134:                                if (!up(&ep->focus))
                    135:                                        return No;
                    136:                                higher(ep);
                    137:                                n = tree(ep->focus);
                    138:                                if (i == nchildren(n) && samelevel(sym, symbol(n))) {
                    139:                                        ep->s3 = 1;
                    140:                                        return Yes;
                    141:                                }
                    142:                                ep->mode = SUBSET;
                    143:                                ep->s1 = ep->s2 = 2*i;
                    144:                                continue;
                    145:                        }
                    146:                        for (i = ep->s3; i > 0; --i)
                    147:                                if (!downrite(&ep->focus))
                    148:                                        return No; /* Sorry... */
                    149:                        if (samelevel(sym, symbol(tree(ep->focus))))
                    150:                                ep->s3 = 1;
                    151:                        else
                    152:                                ep->mode = WHOLE;
                    153:                        return Yes;
                    154: 
                    155:                case WHOLE:
                    156:                        i = ichild(ep->focus);
                    157:                        if (!up(&ep->focus))
                    158:                                return No;
                    159:                        higher(ep);
                    160:                        ep->mode = SUBSET;
                    161:                        ep->s1 = ep->s2 = 2*i;
                    162:                        continue;
                    163: 
                    164:                default:
                    165:                        Abort();
                    166:                }
                    167:        }
                    168:        /* Not reached */
                    169: }
                    170: 
                    171: Visible bool leftarrow(ep)
                    172:        environ *ep;
                    173: {
                    174:        int w;
                    175:        bool hole;
                    176: 
                    177:        if (narrow(ep)) {
                    178:                while (narrow(ep))
                    179:                        ;
                    180:                return Yes;
                    181:        }
                    182:        hole= ep->mode == WHOLE; /* Can't narrow and still WHOLE: */
                    183:                                 /* a real hole which needs some hacking. */
                    184:        if (!previous(ep))
                    185:                return No;
                    186:        if (hole) {
                    187:                for (;;) {
                    188:                        w= focwidth(ep);
                    189:                        if (w >= 0 && w <= 1)
                    190:                                break;
                    191:                        if (!rnarrow(ep))
                    192:                                return No;
                    193:                }
                    194:                narrow(ep);
                    195:        }
                    196:        else {
                    197:                while (rnarrow(ep))
                    198:                        ;
                    199:        }
                    200:        return Yes;
                    201: }
                    202: 
                    203: Visible bool ritearrow(ep)
                    204:        environ *ep;
                    205: {
                    206:        while (narrow(ep))
                    207:                ;
                    208:        if (!next(ep))
                    209:                return No;
                    210:        while (narrow(ep))
                    211:                ;
                    212:        return Yes;
                    213: }
                    214: 
                    215: 
                    216: Visible bool
                    217: previous(ep)
                    218:        environ *ep;
                    219: {
                    220:        if (!prevnext(ep, Left))
                    221:                return No;
                    222:        return Yes;
                    223: }
                    224: 
                    225: 
                    226: Visible bool
                    227: next(ep)
                    228:        environ *ep;
                    229: {
                    230:        if (!prevnext(ep, Rite))
                    231:                return No;
                    232:        return Yes;
                    233: }
                    234: 
                    235: 
                    236: /*
                    237:  * Position focus at next or previous char relative to current position.
                    238:  * Assume current position given as SUBSET.
                    239:  */
                    240: 
                    241: Hidden bool
                    242: nextchar(ep, direction)
                    243:        register environ *ep;
                    244:        register int direction;
                    245: {
                    246:        register int ich;
                    247:        register int nch;
                    248:        register node n;
                    249:        node n1;
                    250:        register int len;
                    251:        string *rp;
                    252: 
                    253:        Assert(ep->mode == SUBSET);
                    254:        for (;;) {
                    255:                n = tree(ep->focus);
                    256:                rp = noderepr(n);
                    257:                nch = nchildren(n);
                    258:                if (direction == Left)
                    259:                        ep->s2 = --ep->s1;
                    260:                else
                    261:                        ep->s1 = ++ep->s2;
                    262:                if (direction == Left ? ep->s1 < 1 : ep->s2 > 2*nch+1) {
                    263:                        ich = ichild(ep->focus);
                    264:                        if (!up(&ep->focus))
                    265:                                return No; /* *ep is garbage now! */
                    266:                        higher(ep);
                    267:                        ep->s1 = ep->s2 = 2*ich;
                    268:                        continue;
                    269:                }
                    270:                if (ep->s1&1) {
                    271:                        len = Fwidth(rp[ep->s1/2]);
                    272:                        if (len > 0) {
                    273:                                ep->mode = SUBRANGE;
                    274:                                ep->s2 = ep->s3 = direction == Left ? len-1 : 0;
                    275:                                return Yes;
                    276:                        }
                    277:                        continue;
                    278:                }
                    279:                n1 = child(n, ep->s1/2);
                    280:                len = width(n1);
                    281:                if (len == 0)
                    282:                        continue;
                    283:                if (!downi(&ep->focus, ep->s1/2))
                    284:                        return No; /* Sorry... */
                    285:                n = tree(ep->focus);
                    286:                if (((value)n)->type == Tex) {
                    287:                        s_up(ep);
                    288:                        ep->mode = SUBRANGE;
                    289:                        ep->s2 = ep->s3 = direction == Left ? len-1 : 0;
                    290:                        return Yes;
                    291:                }
                    292:                if (direction == Left) {
                    293:                        nch = nchildren(n);
                    294:                        ep->s1 = ep->s2 = 2*(nch+1);
                    295:                }
                    296:                else
                    297:                        ep->s1 = ep->s2 = 0;
                    298:        }
                    299:        /* Not reached */
                    300: }
                    301: 
                    302: 
                    303: /*
                    304:  * Up and down arrows.
                    305:  */
                    306: 
                    307: Hidden bool
                    308: updownarrow(ep, yincr)
                    309:        environ *ep;
                    310:        int yincr;
                    311: {
                    312:        int y, x;
                    313: 
                    314:        while (narrow(ep))
                    315:                ;
                    316:        y= lineno(ep) + yincr;
                    317:        x= colno(ep);
                    318:        if (!gotoyx(ep, y, x))
                    319:                return No;
                    320:        gotofix(ep, y, x);
                    321:        while (narrow(ep))
                    322:                ;
                    323:        return Yes;
                    324: }
                    325: 
                    326: Visible bool
                    327: uparrow(ep)
                    328:        environ *ep;
                    329: {
                    330:        return updownarrow(ep, -1);
                    331: }
                    332: 
                    333: Visible bool
                    334: downarrow(ep)
                    335:        environ *ep;
                    336: {
                    337:        return updownarrow(ep, 1);
                    338: }
                    339: 
                    340: Visible bool
                    341: upline(ep)
                    342:        register environ *ep;
                    343: {
                    344:        register int y;
                    345: 
                    346:        y = lineno(ep);
                    347:        if (y <= 0)
                    348:                return No;
                    349:        if (!gotoyx(ep, y-1, 0))
                    350:                return No;
                    351:        oneline(ep);
                    352:        return Yes;
                    353: }
                    354: 
                    355: Visible bool
                    356: downline(ep)
                    357:        register environ *ep;
                    358: {
                    359:        register int w;
                    360: 
                    361:        if (!parent(ep->focus) && ep->mode == ATEND)
                    362:                return No; /* Superfluous? */
                    363:        w = -focwidth(ep);
                    364:        if (w <= 0)
                    365:                w = 1;
                    366:        if (!gotoyx(ep, lineno(ep) + w, 0))
                    367:                return No;
                    368:        oneline(ep);
                    369:        return Yes;
                    370: }
                    371: 
                    372: 
                    373: /*
                    374:  * ACCEPT command
                    375:  * move to next Hole hole or to end of suggestion or to end of line.
                    376:  */
                    377: 
                    378: 
                    379: Visible bool
                    380: accept(ep)
                    381:        environ *ep;
                    382: {
                    383:        int i;
                    384:        string repr;
                    385: 
                    386:        shrink(ep);
                    387:        switch (ep->mode) {
                    388:        case ATBEGIN:
                    389:        case ATEND:
                    390:        case FHOLE:
                    391:        case VHOLE:
                    392:                ritevhole(ep);
                    393:        }
                    394:        if (symbol(tree(ep->focus)) == Hole)
                    395:                ep->mode = ATEND;
                    396:        switch (ep->mode) {
                    397:        case ATBEGIN:
                    398:        case SUBLIST:
                    399:        case WHOLE:
                    400:                i = 1;
                    401:                break;
                    402:        case ATEND:
                    403:                i = 2*nchildren(tree(ep->focus)) + 2;
                    404:                break;
                    405:        case SUBRANGE:
                    406:        case VHOLE:
                    407:        case FHOLE:
                    408:                i = ep->s1;
                    409:                if (ep->s2 > 0 && i > 2*nchildren(tree(ep->focus)))
                    410:                        ++i; /* Kludge so after E?LSE: the focus moves to ELSE: ? */
                    411:                break;
                    412:        case SUBSET:
                    413:                i = ep->s1 - 1;
                    414:                break;
                    415:        default:
                    416:                Abort();
                    417:        }
                    418:        ep->mode = WHOLE;
                    419:        for (;;) {
                    420:                if (i/2 == nchildren(tree(ep->focus))) {
                    421:                        repr = noderepr(tree(ep->focus))[i/2];
                    422:                        if (Fw_positive(repr))
                    423:                                break;
                    424:                }
                    425:                if (tabstop(ep, i + 1))
                    426:                        return Yes;
                    427:                i = 2*ichild(ep->focus) + 1;
                    428:                if (!up(&ep->focus))
                    429:                        break;
                    430:                higher(ep);
                    431:        }
                    432:        ep->mode = ATEND;
                    433:        return Yes;
                    434: }
                    435: 
                    436: 
                    437: /*
                    438:  * Find suitable tab stops for accept.
                    439:  */
                    440:  
                    441: Hidden bool
                    442: tabstop(ep, i)
                    443:        environ *ep;
                    444:        int i;
                    445: {
                    446:        node n = tree(ep->focus);
                    447:        int nch;
                    448:        string repr;
                    449: 
                    450:        if (Type(n) == Tex)
                    451:                return No;
                    452:        nch = nchildren(n);
                    453:        if (i/2 > nch)
                    454:                return No;
                    455:        if (symbol(n) == Hole) {
                    456:                ep->mode = WHOLE;
                    457:                return Yes;
                    458:        }
                    459:        if (i < 2) {
                    460:                i = 2;
                    461:                if (width(n) < 0) {
                    462:                        repr = noderepr(n)[0];
                    463:                        if (Fw_negative(repr)) {
                    464:                                ep->mode = ATBEGIN;
                    465:                                leftvhole(ep);
                    466:                                return Yes;
                    467:                        }
                    468:                }
                    469:        }
                    470:        for (i /= 2; i <= nch; ++i) {
                    471:                s_downi(ep, i);
                    472:                if (tabstop(ep, 1))
                    473:                        return Yes;
                    474:                s_up(ep);
                    475:        }
                    476:        return No;
                    477: }

unix.superglobalmegacorp.com

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