# 2.11BSD#431 - /usr/src/new/PORT/B/src/bed/ins2.c

##### Functions

    atdedent          X
    fiddle            X
    hackhack          X
    ins_char          X
    ins_newline       X
    nexthole          X

       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: }

#### Defined functions

atdedent defined in line 280; used 1 times

- in line 211

fiddle defined in line 196; used 1 times

- in line 107

hackhack defined in line 251; used 1 times

- in line 217

ins_char defined in line 21; used 2 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 629-633(2)

ins_newline defined in line 98; used 5 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 638
- in /usr/src/new/PORT/B/src/bed/edit.c line 149, 157
- in /usr/src/new/PORT/B/src/bed/que2.c line 62, 385

nexthole defined in line 324; used 1 times

- in line 221

#### Defined variables

rcsid defined in line 2; never used

Last modified: 1985-08-27 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1043 |