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

##### Functions

    accept            X
    downarrow         X
    downline          X
    leftarrow         X
    next              X
    nextchar          X
    previous          X
    prevnext          X
    ritearrow         X
    tabstop           X
    uparrow           X
    updownarrow       X
    upline            X

##### Macros

    Left              X
    Rite              X

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

#### Defined functions

accept defined in line 379; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 623

downarrow defined in line 333; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 602

downline defined in line 355; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 610

leftarrow defined in line 171; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 574

next defined in line 226; used 2 times

- in line 208
- in /usr/src/new/PORT/B/src/bed/demo.c line 566

nextchar defined in line 241; used 2 times

- in line 71, 88

previous defined in line 216; used 2 times

- in line 184
- in /usr/src/new/PORT/B/src/bed/demo.c line 570

prevnext defined in line 22; used 2 times

- in line 220, 230

ritearrow defined in line 203; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 578

tabstop defined in line 441; used 2 times

- in line 425, 472

uparrow defined in line 326; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 598

updownarrow defined in line 307; used 2 times

- in line 330, 337

upline defined in line 340; used 1 times

- in /usr/src/new/PORT/B/src/bed/demo.c line 606

#### Defined variables

rcsid defined in line 2; never used

#### Defined macros

Left defined in line 14; used 9 times

- in line 40, 85, 132, 220, 258-262(2), 274, 289-292(2)

Rite defined in line 15; used 8 times

- in line 60, 68, 77, 90, 97-101(2), 116, 230

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