Annotation of 43BSD/contrib/B/src/bed/goto.c, revision 1.1

1.1     ! root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
        !             2: static char rcsid[] = "$Header: goto.c,v 2.4 85/08/22 16:03:06 timo Exp $";
        !             3: 
        !             4: /*
        !             5:  * B editor -- Random access focus positioning.
        !             6:  */
        !             7: 
        !             8: #include "b.h"
        !             9: #include "feat.h"
        !            10: #include "erro.h"
        !            11: #include "node.h"
        !            12: #include "gram.h"
        !            13: #include "supr.h"
        !            14: 
        !            15: 
        !            16: extern int winheight;
        !            17: extern int winstart;
        !            18: 
        !            19: 
        !            20: #define BEFORE (-1)
        !            21: #define INSIDE 0
        !            22: #define BEYOND 1
        !            23: 
        !            24: 
        !            25: /*
        !            26:  * Random cursor positioning (e.g., with a mouse).
        !            27:  */
        !            28: 
        !            29: Visible bool
        !            30: gotocursor(ep)
        !            31:        environ *ep;
        !            32: {
        !            33:        int y;
        !            34:        int x;
        !            35: 
        !            36:        if (!sense(&y, &x))
        !            37:                return No;
        !            38: #ifdef SCROLLBAR
        !            39:        if (y == winheight)
        !            40:                return gotoscrollbar(ep, y, x);
        !            41: #endif SCROLLBAR
        !            42:        if (!backtranslate(&y, &x))
        !            43:                return No;
        !            44:        if (!gotoyx(ep, y, x))
        !            45:                return No;
        !            46:        gotofix(ep, y, x);
        !            47:        return Yes;
        !            48: }
        !            49: 
        !            50: #ifdef SCROLLBAR
        !            51: 
        !            52: /*
        !            53:  * Special case for goto: user pointed at some point in the scroll bar.
        !            54:  * Go directly to the corresponding line.
        !            55:  * (The scroll bar is only present when winstart == 0; it extends from
        !            56:  * col 0 to winheight-1 inclusive.)
        !            57:  */
        !            58: 
        !            59: Hidden bool
        !            60: gotoscrollbar(ep, y, x)
        !            61:        environ *ep;
        !            62:        int y;
        !            63:        int x;
        !            64: {
        !            65:        int w;
        !            66: 
        !            67:        if (winstart != 0 || x >= winheight) { /* Not within scroll bar */
        !            68:                error(GOTO_OUT);
        !            69:                return No;
        !            70:        }
        !            71:        top(&ep->focus);
        !            72:        ep->mode = WHOLE;
        !            73:        higher(ep);
        !            74:        w = width(tree(ep->focus));
        !            75:        if (w >= 0)
        !            76:                w = 1;
        !            77:        else
        !            78:                w = 1-w;
        !            79:        if (!gotoyx(ep, x * w / winheight, 0))
        !            80:                return No;
        !            81:        oneline(ep);
        !            82:        return Yes;
        !            83: }
        !            84: 
        !            85: #endif SCROLLBAR
        !            86: 
        !            87: /*
        !            88:  * Set the focus to the smallest node or subset surrounding
        !            89:  * the position (y, x).
        !            90:  */
        !            91: 
        !            92: Visible bool
        !            93: gotoyx(ep, y, x)
        !            94:        register environ *ep;
        !            95:        register int y;
        !            96:        register int x;
        !            97: {
        !            98:        register node n;
        !            99:        register string *rp;
        !           100:        register int i;
        !           101:        register int pc;
        !           102: 
        !           103:        ep->mode = WHOLE;
        !           104:        while ((pc = poscomp(ep->focus, y, x)) != INSIDE) {
        !           105:                if (!up(&ep->focus)) {
        !           106:                        if (pc == BEFORE)
        !           107:                                ep->mode = ATBEGIN;
        !           108:                        else
        !           109:                                ep->mode = ATEND;
        !           110:                        higher(ep);
        !           111:                        return No;
        !           112:                }
        !           113:        }
        !           114:        higher(ep);
        !           115:        for (;;) {
        !           116:                switch (poscomp(ep->focus, y, x)) {
        !           117: 
        !           118:                case BEFORE:
        !           119:                        i = ichild(ep->focus);
        !           120:                        n = tree(parent(ep->focus)); /* Parent's !!! */
        !           121:                        rp = noderepr(n);
        !           122:                        if (Fw_positive(rp[i-1])) {
        !           123:                                s_up(ep);
        !           124:                                ep->s1 = ep->s2 = 2*i - 1;
        !           125:                                ep->mode = SUBSET;
        !           126:                        }
        !           127:                        else if (left(&ep->focus))
        !           128:                                ep->mode = ATEND;
        !           129:                        else
        !           130:                                ep->mode = ATBEGIN;
        !           131:                        return Yes;
        !           132: 
        !           133:                case INSIDE:
        !           134:                        n = tree(ep->focus);
        !           135:                        if (nchildren(n) >= 1 && Type(firstchild(n)) != Tex) {
        !           136:                                s_down(ep);
        !           137:                                continue;
        !           138:                        }
        !           139:                        ep->mode = WHOLE;
        !           140:                        return Yes;
        !           141: 
        !           142:                case BEYOND:
        !           143:                        if (rite(&ep->focus))
        !           144:                                continue;
        !           145:                        n = tree(parent(ep->focus)); /* Parent's !!! */
        !           146:                        rp = noderepr(n);
        !           147:                        i = ichild(ep->focus);
        !           148:                        if (Fw_positive(rp[i])) {
        !           149:                                s_up(ep);
        !           150:                                ep->s1 = ep->s2 = 2*i + 1;
        !           151:                                ep->mode = SUBSET;
        !           152:                        }
        !           153:                        else
        !           154:                                ep->mode = ATEND;
        !           155:                        return Yes;
        !           156: 
        !           157:                default:
        !           158:                        Abort();
        !           159:                        /* NOTREACHED */
        !           160: 
        !           161:                }
        !           162:        }
        !           163: }
        !           164: 
        !           165: 
        !           166: /*
        !           167:  * Deliver relative position of (y, x) with respect to focus p:
        !           168:  * BEFORE: (y, x) precedes focus;
        !           169:  * INSIDE: (y, x) contained in focus;
        !           170:  * EAFTER:  (y, x) follows focus.
        !           171:  
        !           172:  */
        !           173: 
        !           174: Hidden int
        !           175: poscomp(p, y, x)
        !           176:        register path p;
        !           177:        register int y;
        !           178:        register int x;
        !           179: {
        !           180:        register int ly;
        !           181:        register int lx;
        !           182:        register int w;
        !           183:        register string *rp;
        !           184:        register node n;
        !           185: 
        !           186:        ly = Ycoord(p);
        !           187:        lx = Xcoord(p);
        !           188:        if (y < ly || y == ly && (lx < 0 || x < lx))
        !           189:                return BEFORE;
        !           190:        n = tree(p);
        !           191:        w = width(n);
        !           192:        if (w < 0) {
        !           193:                if (y == ly) { /* Hack for position beyond end of previous line */
        !           194:                        rp = noderepr(n);
        !           195:                        if (Fw_negative(rp[0]))
        !           196:                                return BEFORE;
        !           197:                }
        !           198:                ly += -w;
        !           199:                lx = -1;
        !           200:        }
        !           201:        else {
        !           202:                if (lx >= 0)
        !           203:                        lx += w;
        !           204:        }
        !           205:        if (y < ly || y == ly && (lx < 0 || x < lx))
        !           206:                return INSIDE;
        !           207:        return BEYOND;
        !           208: }
        !           209: 
        !           210: 
        !           211: /*
        !           212:  * Position focus exactly at character indicated by (y, x) if possible.
        !           213:  * If this is the start of something larger, position focus at largest
        !           214:  * object starting here.
        !           215:  */
        !           216: 
        !           217: Visible Procedure
        !           218: gotofix(ep, y, x)
        !           219:        environ *ep;
        !           220:        int y;
        !           221:        int x;
        !           222: {
        !           223:        int fx;
        !           224:        int fy;
        !           225:        int len;
        !           226:        string repr;
        !           227: 
        !           228:        switch (ep->mode) {
        !           229: 
        !           230:        case ATBEGIN:
        !           231:        case ATEND:
        !           232:                return; /* No change; the mouse pointed in the margin. */
        !           233: 
        !           234:        case SUBSET:
        !           235:                if (ep->s1 > 1) {
        !           236:                        fx = Xcoord(ep->focus);
        !           237:                        fy = Ycoord(ep->focus);
        !           238:                        len = focoffset(ep);
        !           239:                        if (len < 0 || fy != y)
        !           240:                                return;
        !           241:                        if ((ep->s1&1) && fx + len >= x-1) {
        !           242:                                repr = noderepr(tree(ep->focus))[ep->s1/2];
        !           243:                                if ((repr && repr[0] == ' ') != (fx + len == x))
        !           244:                                        return;
        !           245:                        }
        !           246:                        else if (fx + len == x)
        !           247:                                return;
        !           248:                }
        !           249:                ep->mode = WHOLE;
        !           250:                /* Fall through */
        !           251:        case WHOLE:
        !           252:                fx = Xcoord(ep->focus);
        !           253:                fy = Ycoord(ep->focus);
        !           254:                if (y != fy)
        !           255:                        return;
        !           256:                if (x <= fx ) {
        !           257:                        for (;;) {
        !           258:                                if (ichild(ep->focus) > 1)
        !           259:                                        break;
        !           260:                                if (!up(&ep->focus))
        !           261:                                        break;
        !           262:                                repr = noderepr(tree(ep->focus))[0];
        !           263:                                if (!Fw_zero(repr)) {
        !           264:                                        s_down(ep);
        !           265:                                        break;
        !           266:                                }
        !           267:                                higher(ep);
        !           268:                        }
        !           269:                        if (issublist(symbol(tree(ep->focus))))
        !           270:                                fixsublist(ep);
        !           271:                        return;
        !           272:                }
        !           273:                fixfocus(ep, x - fx);
        !           274:                ritevhole(ep);
        !           275:                switch(ep->mode) {
        !           276:                case VHOLE:
        !           277:                        len = width(tree(ep->focus));
        !           278:                        break;
        !           279:                case FHOLE:
        !           280:                        len = fwidth(noderepr(tree(ep->focus))[ep->s1/2]);
        !           281:                        break;
        !           282:                default:
        !           283:                        return;
        !           284:                }
        !           285:                if (ep->s2 < len) {
        !           286:                        ep->mode = SUBRANGE;
        !           287:                        ep->s3 = ep->s2;
        !           288:                }
        !           289:                return;
        !           290: 
        !           291:        default:
        !           292:                Abort();
        !           293:        }
        !           294: }
        !           295: 
        !           296: 
        !           297: /*
        !           298:  * Refinement for gotoyx -- don't show right sublist of something.
        !           299:  */
        !           300:  
        !           301: Hidden Procedure
        !           302: fixsublist(ep)
        !           303:        environ *ep;
        !           304: {
        !           305:        path pa = parent(ep->focus);
        !           306:        node n;
        !           307: 
        !           308:        if (!pa)
        !           309:                return;
        !           310:        n = tree(pa);
        !           311:        if (nchildren(n) > ichild(ep->focus))
        !           312:                return;
        !           313:        if (samelevel(symbol(n), symbol(tree(ep->focus)))) {
        !           314:                ep->mode = SUBLIST;
        !           315:                ep->s3 = 1;
        !           316:        }
        !           317: }

unix.superglobalmegacorp.com

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