Annotation of 43BSDTahoe/new/B/src/bed/ins2.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
                      2: static char rcsid[] = "$Header: ins2.c,v 2.4 84/10/26 12:08:24 guido Exp $";
                      3: 
                      4: /*
                      5:  * B editor -- Insert characters from keyboard.
                      6:  */
                      7: 
                      8: #include "b.h"
                      9: #include "bobj.h"
                     10: #include "node.h"
                     11: #include "supr.h"
                     12: #include "queu.h"
                     13: #include "gram.h"
                     14: #include "tabl.h"
                     15: 
                     16: 
                     17: /*
                     18:  * Insert a character.
                     19:  */
                     20: 
                     21: Visible bool
                     22: ins_char(ep, c, alt_c)
                     23:        register environ *ep;
                     24:        int c;
                     25:        int alt_c;
                     26: {
                     27:        auto queue q = Qnil;
                     28:        auto queue qf = Qnil;
                     29:        auto value copyout();
                     30:        auto string str;
                     31:        char buf[2];
                     32:        int where;
                     33:        bool spwhere;
                     34: 
                     35:        higher(ep);
                     36:        shrink(ep);
                     37:        if (index("({[`'\"", c) && !ishole(ep)) {
                     38:                /* Surround something.  Wonder what will happen! */
                     39:                qf = (queue) copyout(ep);
                     40:                if (!delbody(ep)) {
                     41:                        qrelease(qf);
                     42:                        return No;
                     43:                }
                     44:        }
                     45:        fixit(ep);
                     46:        ep->changed = Yes;
                     47:        buf[0] = c;
                     48:        buf[1] = 0;
                     49:        if (!ins_string(ep, buf, &q, alt_c))
                     50:                return No;
                     51:        if (!emptyqueue(q) || !emptyqueue(qf)) {
                     52:                /* Slight variation on app_queue */
                     53:                if (!emptyqueue(qf) && emptyqueue(q))
                     54:                        ritevhole(ep); /* Wizardry.  Why does this work? */
                     55:                spwhere = ep->spflag;
                     56:                ep->spflag = No;
                     57:                where = focoffset(ep);
                     58:                markpath(&ep->focus, 1);
                     59:                ep->spflag = spwhere;
                     60:                if (ep->mode == FHOLE && ep->s2 > 0) {
                     61:                        /* If we just caused a suggestion, insert the remains
                     62:                           after the suggested text, not after its first character. */
                     63:                        str = "";
                     64:                        if (!soften(ep, &str, 0)) {
                     65:                                ep->mode = ATEND;
                     66:                                leftvhole(ep);
                     67:                                if (symbol(tree(ep->focus)) == Hole) {
                     68:                                        ep->mode = ATBEGIN;
                     69:                                        leftvhole(ep);
                     70:                                }
                     71:                        }
                     72:                }
                     73:                if (!emptyqueue(q)) { /* Re-insert stuff queued by ins_string */
                     74:                        if (!ins_queue(ep, &q, &q))
                     75:                                return No;
                     76:                        where += spwhere;
                     77:                        spwhere = No;
                     78:                }
                     79:                if (!emptyqueue(qf)) { /* Re-insert deleted old focus */
                     80:                        firstmarked(&ep->focus, 1) || Abort();
                     81:                        fixfocus(ep, where);
                     82:                        if (!ins_queue(ep, &qf, &qf))
                     83:                                return No;
                     84:                }
                     85:                firstmarked(&ep->focus, 1) || Abort();
                     86:                unmkpath(&ep->focus, 1);
                     87:                ep->spflag = No;
                     88:                fixfocus(ep, where + spwhere);
                     89:        }
                     90:        return Yes;
                     91: }
                     92: 
                     93: 
                     94: /*
                     95:  * Insert a newline.
                     96:  */
                     97: 
                     98: Visible bool
                     99: ins_newline(ep)
                    100:        register environ *ep;
                    101: {
                    102:        register node n;
                    103:        register int sym;
                    104:        auto bool mayindent;
                    105: 
                    106:        ep->changed = Yes;
                    107:        if (!fiddle(ep, &mayindent))
                    108:                return No;
                    109:        for (;;) {
                    110:                switch (ep->mode) {
                    111: 
                    112:                case VHOLE:
                    113:                        ep->mode = ATEND;
                    114:                        continue;
                    115: 
                    116:                case FHOLE:
                    117:                        ep->s2 = lenitem(ep);
                    118:                        if (!fix_move(ep))
                    119:                                return No;
                    120:                        continue;
                    121: 
                    122:                case ATEND:
                    123:                        if (!joinstring(&ep->focus, "\n", No, 0, mayindent)) {
                    124:                                if (!move_on(ep))
                    125:                                        return No;
                    126:                                continue;
                    127:                        }
                    128:                        s_downi(ep, 2);
                    129:                        s_downi(ep, 1);
                    130:                        ep->mode = WHOLE;
                    131:                        Assert((sym = symbol(tree(ep->focus))) == Hole || sym == Optional);
                    132:                        return Yes;
                    133: 
                    134:                case ATBEGIN:
                    135:                        n = tree(ep->focus);
                    136:                        if (Type(n) == Tex) {
                    137:                                ep->mode = ATEND;
                    138:                                continue;
                    139:                        }
                    140:                        sym = symbol(n);
                    141:                        if (sym == Hole || sym == Optional) {
                    142:                                ep->mode = WHOLE;
                    143:                                continue;
                    144:                        }
                    145:                        n = nodecopy(n);
                    146:                        if (!fitstring(&ep->focus, "\n", 0)) {
                    147:                                if (!down(&ep->focus))
                    148:                                        ep->mode = ATEND;
                    149:                                noderelease(n);
                    150:                                continue;
                    151:                        }
                    152:                        s_downrite(ep);
                    153:                        if (fitnode(&ep->focus, n)) {
                    154:                                noderelease(n);
                    155:                                s_up(ep);
                    156:                                s_down(ep);
                    157:                                ep->mode = WHOLE;
                    158:                                return Yes;
                    159:                        }
                    160:                        s_up(ep);
                    161:                        s_down(ep);
                    162:                        if (!fitnode(&ep->focus, n)) {
                    163:                                noderelease(n);
                    164: #ifndef NDEBUG
                    165:                                debug("[Sorry, I don't see how to insert a newline here]");
                    166: #endif NDEBUG
                    167:                                return No;
                    168:                        }
                    169:                        noderelease(n);
                    170:                        ep->mode = ATBEGIN;
                    171:                        return Yes;
                    172: 
                    173:                case WHOLE:
                    174:                        Assert((sym = symbol(tree(ep->focus))) == Hole || sym == Optional);
                    175:                        if (!fitstring(&ep->focus, "\n", 0)) {
                    176:                                ep->mode = ATEND;
                    177:                                continue;
                    178:                        }
                    179:                        s_downi(ep, 1);
                    180:                        Assert((sym = symbol(tree(ep->focus))) == Hole || sym == Optional);
                    181:                        ep->mode = WHOLE;
                    182:                        return Yes;
                    183: 
                    184:                default:
                    185:                        Abort();
                    186: 
                    187:                }
                    188:        }
                    189: }
                    190: 
                    191: 
                    192: /*
                    193:  * Refinement for ins_newline() to do the initial processing.
                    194:  */
                    195: 
                    196: Hidden bool
                    197: fiddle(ep, pmayindent)
                    198:        register environ *ep;
                    199:        bool *pmayindent;
                    200: {
                    201:        register int level;
                    202:        auto string str = "";
                    203: 
                    204:        higher(ep);
                    205:        while (rnarrow(ep))
                    206:                ;
                    207:        fixit(ep);
                    208:        soften(ep, &str, 0);
                    209:        higher(ep);
                    210:        *pmayindent = Yes;
                    211:        if (atdedent(ep)) {
                    212:                *pmayindent = No;
                    213:                s_up(ep);
                    214:                level = Level(ep->focus);
                    215:                delfocus(&ep->focus);
                    216:                if (symbol(tree(ep->focus)) == Hole) {
                    217:                        if (hackhack(ep))
                    218:                                return Yes;
                    219:                }
                    220:                while (Level(ep->focus) >= level) {
                    221:                        if (!nexthole(ep)) {
                    222:                                ep->mode = ATEND;
                    223:                                break;
                    224:                        }
                    225:                }
                    226:                if (ep->mode == ATEND) {
                    227:                        leftvhole(ep);
                    228:                        ep->mode = ATEND;
                    229:                        while (Level(ep->focus) >= level) {
                    230:                                if (!up(&ep->focus))
                    231:                                        return No;
                    232:                        }
                    233:                }
                    234:                return Yes;
                    235:        }
                    236:        return Yes;
                    237: }
                    238: 
                    239: 
                    240: /*
                    241:  * "Hier komen de houthakkers."
                    242:  *
                    243:  * Incredibly ugly hack to delete a join whose second child begins with \n,
                    244:  * such as a suite after an IF, FOR or WHILE or  unit heading.
                    245:  * Inspects the parent node.
                    246:  * If this has rp[0] ands rp[1] both empty, replace it by its first child.
                    247:  * (caller assures this makes sense).
                    248:  * Return Yes if this happened AND rp[1] contained a \t.
                    249:  */
                    250: 
                    251: Hidden Procedure
                    252: hackhack(ep)
                    253:        environ *ep;
                    254: {
                    255:        node n;
                    256:        int ich = ichild(ep->focus);
                    257:        string *rp;
                    258: 
                    259:        if (!up(&ep->focus))
                    260:                return No;
                    261:        higher(ep);
                    262:        rp = noderepr(tree(ep->focus));
                    263:        if (!Fw_zero(rp[0]) || !Fw_zero(rp[1])) {
                    264:                s_downi(ep, ich);
                    265:                return No;
                    266:        }
                    267:        n = nodecopy(firstchild(tree(ep->focus)));
                    268:        delfocus(&ep->focus);
                    269:        replace(&ep->focus, n);
                    270:        ep->mode = ATEND;
                    271:        return rp[1] && rp[1][0] == '\t';
                    272: }
                    273:        
                    274: 
                    275: /*
                    276:  * Refinement for fiddle() to find out whether we are at a possible
                    277:  * decrease-indentation position.
                    278:  */
                    279: 
                    280: Hidden bool
                    281: atdedent(ep)
                    282:        register environ *ep;
                    283: {
                    284:        register path pa;
                    285:        register node npa;
                    286:        register int i;
                    287:        register int sym = symbol(tree(ep->focus));
                    288: 
                    289:        if (sym != Hole && sym != Optional)
                    290:                return No;
                    291:        if (ichild(ep->focus) != 1)
                    292:                return No;
                    293:        switch (ep->mode) {
                    294:        case FHOLE:
                    295:                if (ep->s1 != 1 || ep->s2 != 0)
                    296:                        return No;
                    297:                break;
                    298:        case ATBEGIN:
                    299:        case WHOLE:
                    300:        case SUBSET:
                    301:                break;
                    302:        default:
                    303:                return No;
                    304:        }
                    305:        pa = parent(ep->focus);
                    306:        if (!pa)
                    307:                return No;
                    308:        npa = tree(pa);
                    309:        if (fwidth(noderepr(npa)[0]) >= 0)
                    310:                return No;
                    311:        for (i = nchildren(npa); i > 1; --i) {
                    312:                sym = symbol(child(npa, i));
                    313:                if (sym != Hole && sym != Optional)
                    314:                        return No;
                    315:        }
                    316:        return Yes; /* Sigh! */
                    317: }
                    318: 
                    319: /*
                    320:  * Refinement for ins_node() and fiddle() to find the next hole,
                    321:  * skipping blank space only.
                    322:  */
                    323: 
                    324: Hidden bool
                    325: nexthole(ep)
                    326:        register environ *ep;
                    327: {
                    328:        register node n;
                    329:        register int ich;
                    330:        register string repr;
                    331: 
                    332:        do {
                    333:                ich = ichild(ep->focus);
                    334:                if (!up(&ep->focus))
                    335:                        return No;
                    336:                higher(ep);
                    337:                n = tree(ep->focus);
                    338:                repr = noderepr(n)[ich];
                    339:                if (!Fw_zero(repr) && !allspaces(repr))
                    340:                        return No;
                    341:        } while (ich >= nchildren(n));
                    342:        s_downi(ep, ich+1);
                    343:        return Yes;
                    344: }

unix.superglobalmegacorp.com

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