Annotation of 3BSD/cmd/ex/ex_vwind.c, revision 1.1.1.1

1.1       root        1: /* Copyright (c) 1979 Regents of the University of California */
                      2: #include "ex.h"
                      3: #include "ex_tty.h"
                      4: #include "ex_vis.h"
                      5: 
                      6: /*
                      7:  * Routines to adjust the window, showing specified lines
                      8:  * in certain positions on the screen, and scrolling in both
                      9:  * directions.  Code here is very dependent on mode (open versus visual).
                     10:  */
                     11: 
                     12: /*
                     13:  * Move in a nonlocal way to line addr.
                     14:  * If it isn't on screen put it in specified context.
                     15:  * New position for cursor is curs.
                     16:  * Like most routines here, we vsave().
                     17:  */
                     18: vmoveto(addr, curs, context)
                     19:        register line *addr;
                     20:        char *curs;
                     21:        char context;
                     22: {
                     23: 
                     24:        markit(addr);
                     25:        vsave();
                     26:        vjumpto(addr, curs, context);
                     27: }
                     28: 
                     29: /*
                     30:  * Vjumpto is like vmoveto, but doesn't mark previous
                     31:  * context or save linebuf as current line.
                     32:  */
                     33: vjumpto(addr, curs, context)
                     34:        register line *addr;
                     35:        char *curs;
                     36:        char context;
                     37: {
                     38: 
                     39:        noteit(0);
                     40:        if (context != 0)
                     41:                vcontext(addr, context);
                     42:        else
                     43:                vshow(addr, NOLINE);
                     44:        noteit(1);
                     45:        vnline(curs);
                     46: }
                     47: 
                     48: /*
                     49:  * Go up or down cnt (negative is up) to new position curs.
                     50:  */
                     51: vupdown(cnt, curs)
                     52:        register int cnt;
                     53:        char *curs;
                     54: {
                     55: 
                     56:        if (cnt > 0)
                     57:                vdown(cnt, 0, 0);
                     58:        else if (cnt < 0)
                     59:                vup(-cnt, 0, 0);
                     60:        if (vcnt == 0)
                     61:                vrepaint(curs);
                     62:        else
                     63:                vnline(curs);
                     64: }
                     65: 
                     66: /*
                     67:  * Go up cnt lines, afterwards preferring to be ind
                     68:  * logical lines from the top of the screen.
                     69:  * If scroll, then we MUST use a scroll.
                     70:  * Otherwise clear and redraw if motion is far.
                     71:  */
                     72: vup(cnt, ind, scroll)
                     73:        register int cnt, ind;
                     74:        bool scroll;
                     75: {
                     76:        register int i, tot;
                     77: 
                     78:        if (dot == one) {
                     79:                beep();
                     80:                return;
                     81:        }
                     82:        vsave();
                     83:        i = lineDOT() - 1;
                     84:        if (cnt > i) {
                     85:                ind -= cnt - i;
                     86:                if (ind < 0)
                     87:                        ind = 0;
                     88:                cnt = i;
                     89:        }
                     90:        if (!scroll && cnt <= vcline) {
                     91:                vshow(dot - cnt, NOLINE);
                     92:                return;
                     93:        }
                     94:        cnt -= vcline, dot -= vcline, vcline = 0;
                     95:        if (hold & HOLDWIG)
                     96:                goto contxt;
                     97:        if (state == VISUAL && !AL && !SR &&
                     98:            cnt <= WTOP - ZERO && vfit(dot - cnt, cnt) <= WTOP - ZERO)
                     99:                goto okr;
                    100:        tot = WECHO - ZERO;
                    101:        if (state != VISUAL || (!AL && !SR) || (!scroll && (cnt > tot || vfit(dot - cnt, cnt) > tot / 3 + 1))) {
                    102:                if (ind > basWLINES / 2)
                    103:                        ind = basWLINES / 3;
                    104: contxt:
                    105:                vcontext(dot + ind - cnt, '.');
                    106:                return;
                    107:        }
                    108: okr:
                    109:        vrollR(cnt);
                    110:        if (scroll) {
                    111:                vcline += ind, dot += ind;
                    112:                if (vcline >= vcnt)
                    113:                        dot -= vcline - vcnt + 1, vcline = vcnt - 1;
                    114:                getDOT();
                    115:        }
                    116: }
                    117: 
                    118: /*
                    119:  * Like vup, but scrolling down.
                    120:  */
                    121: vdown(cnt, ind, scroll)
                    122:        register int cnt, ind;
                    123:        bool scroll;
                    124: {
                    125:        register int i, tot;
                    126: 
                    127:        if (dot == dol) {
                    128:                beep();
                    129:                return;
                    130:        }
                    131:        vsave();
                    132:        i = dol - dot;
                    133:        if (cnt > i) {
                    134:                ind -= cnt - i;
                    135:                if (ind < 0)
                    136:                        ind = 0;
                    137:                cnt = i;
                    138:        }
                    139:        i = vcnt - vcline - 1;
                    140:        if (!scroll && cnt <= i) {
                    141:                vshow(dot + cnt, NOLINE);
                    142:                return;
                    143:        }
                    144:        cnt -= i, dot += i, vcline += i;
                    145:        if (hold & HOLDWIG)
                    146:                goto dcontxt;
                    147:        if (!scroll) {
                    148:                tot = WECHO - ZERO;
                    149:                if (state != VISUAL || cnt - tot > 0 || vfit(dot, cnt) > tot / 3 + 1) {
                    150: dcontxt:
                    151:                        vcontext(dot + cnt, '.');
                    152:                        return;
                    153:                }
                    154:        }
                    155:        if (cnt > 0)
                    156:                vroll(cnt);
                    157:        if (state == VISUAL && scroll) {
                    158:                vcline -= ind, dot -= ind;
                    159:                if (vcline < 0)
                    160:                        dot -= vcline, vcline = 0;
                    161:                getDOT();
                    162:        }
                    163: }
                    164: 
                    165: /*
                    166:  * Show line addr in context where on the screen.
                    167:  * Work here is in determining new top line implied by
                    168:  * this placement of line addr, since we always draw from the top.
                    169:  */
                    170: vcontext(addr, where)
                    171:        register line *addr;
                    172:        char where;
                    173: {
                    174:        register line *top;
                    175: 
                    176:        getline(*addr);
                    177:        if (state != VISUAL)
                    178:                top = addr;
                    179:        else switch (where) {
                    180: 
                    181:        case '^':
                    182:                addr = vback(addr, basWLINES - vdepth());
                    183:                getline(*addr);
                    184:                /* fall into ... */
                    185: 
                    186:        case '-':
                    187:                top = vback(addr, basWLINES - vdepth());
                    188:                getline(*addr);
                    189:                break;
                    190: 
                    191:        case '.':
                    192:                top = vback(addr, basWLINES / 2 - vdepth());
                    193:                getline(*addr);
                    194:                break;
                    195: 
                    196:        default:
                    197:                top = addr;
                    198:                break;
                    199:        }
                    200:        if (state == ONEOPEN && LINE(0) == WBOT)
                    201:                vup1();
                    202:        vcnt = vcline = 0;
                    203:        vclean();
                    204:        if (state == CRTOPEN)
                    205:                vup1();
                    206:        vshow(addr, top);
                    207: }
                    208: 
                    209: /*
                    210:  * Get a clean line.  If we are in a hard open
                    211:  * we may be able to reuse the line we are on
                    212:  * if it is blank.  This is a real win.
                    213:  */
                    214: vclean()
                    215: {
                    216: 
                    217:        if (state != VISUAL && state != CRTOPEN) {
                    218:                destcol = 0;
                    219:                if (!ateopr())
                    220:                        vup1();
                    221:                vcnt = 0;
                    222:        }
                    223: }
                    224: 
                    225: /*
                    226:  * Show line addr with the specified top line on the screen.
                    227:  * Top may be 0; in this case have vcontext compute the top
                    228:  * (and call us recursively).  Eventually, we clear the screen
                    229:  * (or its open mode equivalent) and redraw.
                    230:  */
                    231: vshow(addr, top)
                    232:        line *addr, *top;
                    233: {
                    234: #ifndef CBREAK
                    235:        register bool fried = 0;
                    236: #endif
                    237:        register int cnt = addr - dot;
                    238:        register int i = vcline + cnt;
                    239:        short oldhold = hold;
                    240: 
                    241:        if (state != HARDOPEN && state != ONEOPEN && i >= 0 && i < vcnt) {
                    242:                dot = addr;
                    243:                getDOT();
                    244:                vcline = i;
                    245:                return;
                    246:        }
                    247:        if (state != VISUAL) {
                    248:                dot = addr;
                    249:                vopen(dot, WBOT);
                    250:                return;
                    251:        }
                    252:        if (top == 0) {
                    253:                vcontext(addr, '.');
                    254:                return;
                    255:        }
                    256:        dot = top;
                    257: #ifndef CBREAK
                    258:        if (vcookit(2))
                    259:                fried++, vcook();
                    260: #endif
                    261:        oldhold = hold;
                    262:        hold |= HOLDAT;
                    263:        vclear();
                    264:        vreset(0);
                    265:        vredraw(WTOP);
                    266:        /* error if vcline >= vcnt ! */
                    267:        vcline = addr - top;
                    268:        dot = addr;
                    269:        getDOT();
                    270:        hold = oldhold;
                    271:        vsync(LASTLINE);
                    272: #ifndef CBREAK
                    273:        if (fried)
                    274:                flusho(), vraw();
                    275: #endif
                    276: }
                    277: 
                    278: /*
                    279:  * reset the state.
                    280:  * If inecho then leave us at the beginning of the echo
                    281:  * area;  we are called this way in the middle of a :e escape
                    282:  * from visual, e.g.
                    283:  */
                    284: vreset(inecho)
                    285:        bool inecho;
                    286: {
                    287: 
                    288:        vcnt = vcline = 0;
                    289:        WTOP = basWTOP;
                    290:        WLINES = basWLINES;
                    291:        if (inecho)
                    292:                splitw = 1, vgoto(WECHO, 0);
                    293: }
                    294: 
                    295: /*
                    296:  * Starting from which line preceding tp uses almost (but not more
                    297:  * than) cnt physical lines?
                    298:  */
                    299: line *
                    300: vback(tp, cnt)
                    301:        register int cnt;
                    302:        register line *tp;
                    303: {
                    304:        register int d;
                    305: 
                    306:        if (cnt > 0)
                    307:                for (; tp > one; tp--) {
                    308:                        getline(tp[-1]);
                    309:                        d = vdepth();
                    310:                        if (d > cnt)
                    311:                                break;
                    312:                        cnt -= d;
                    313:                }
                    314:        return (tp);
                    315: }
                    316: 
                    317: /*
                    318:  * How much scrolling will it take to roll cnt lines starting at tp?
                    319:  */
                    320: vfit(tp, cnt)
                    321:        register line *tp;
                    322:        int cnt;
                    323: {
                    324:        register int j;
                    325: 
                    326:        j = 0;
                    327:        while (cnt > 0) {
                    328:                cnt--;
                    329:                getline(tp[cnt]);
                    330:                j += vdepth();
                    331:        }
                    332:        if (tp > dot)
                    333:                j -= WBOT - LASTLINE;
                    334:        return (j);
                    335: }
                    336: 
                    337: /*
                    338:  * Roll cnt lines onto the screen.
                    339:  */
                    340: vroll(cnt)
                    341:        register int cnt;
                    342: {
                    343: #ifndef CBREAK
                    344:        register bool fried = 0;
                    345: #endif
                    346:        short oldhold = hold;
                    347: 
                    348: #ifdef ADEBUG
                    349:        if (trace)
                    350:                tfixnl(), fprintf(trace, "vroll(%d)\n", cnt);
                    351: #endif
                    352:        if (state != VISUAL)
                    353:                hold |= HOLDAT|HOLDROL;
                    354:        if (WBOT == WECHO) {
                    355:                vcnt = 0;
                    356:                if (state == ONEOPEN)
                    357:                        vup1();
                    358:        }
                    359: #ifndef CBREAK
                    360:        if (vcookit(cnt))
                    361:                fried++, vcook();
                    362: #endif
                    363:        for (; cnt > 0 && Peekkey != ATTN; cnt--) {
                    364:                dot++, vcline++;
                    365:                vopen(dot, LASTLINE);
                    366:                vscrap();
                    367:        }
                    368:        hold = oldhold;
                    369:        if (state == HARDOPEN)
                    370:                sethard();
                    371:        vsyncCL();
                    372: #ifndef CBREAK
                    373:        if (fried)
                    374:                flusho(), vraw();
                    375: #endif
                    376: }
                    377: 
                    378: /*
                    379:  * Roll backwards (scroll up).
                    380:  */
                    381: vrollR(cnt)
                    382:        register int cnt;
                    383: {
                    384:        register bool fried = 0;
                    385:        short oldhold = hold;
                    386: 
                    387: #ifdef ADEBUG
                    388:        if (trace)
                    389:                tfixnl(), fprintf(trace, "vrollR(%d), dot=%d\n", cnt, lineDOT());
                    390: #endif
                    391: #ifndef CBREAK
                    392:        if (vcookit(cnt))
                    393:                fried++, vcook();
                    394: #endif
                    395:        if (WBOT == WECHO)
                    396:                vcnt = 0;
                    397:        heldech = 0;
                    398:        hold |= HOLDAT|HOLDECH;
                    399:        for (; cnt > 0 && Peekkey != ATTN; cnt--) {
                    400:                dot--;
                    401:                vopen(dot, WTOP);
                    402:                vscrap();
                    403:        }
                    404:        hold = oldhold;
                    405:        if (heldech)
                    406:                vclrech(0);
                    407:        vsync(LINE(vcnt-1));
                    408: #ifndef CBREAK
                    409:        if (fried)
                    410:                flusho(), vraw();
                    411: #endif
                    412: }
                    413: 
                    414: /*
                    415:  * Go into cooked mode (allow interrupts) during
                    416:  * a scroll if we are at less than 1200 baud and not
                    417:  * a 'vi' command, of if we are in a 'vi' command and the
                    418:  * scroll is more than 2 full screens.
                    419:  *
                    420:  * BUG:                An interrupt during a scroll in this way
                    421:  *             dumps to command mode.
                    422:  */
                    423: vcookit(cnt)
                    424:        register int cnt;
                    425: {
                    426: 
                    427:        return (cnt > 1 && (ospeed < B1200 && !initev || cnt > LINES * 2));
                    428: }
                    429: 
                    430: /*
                    431:  * Determine displayed depth of current line.
                    432:  */
                    433: vdepth()
                    434: {
                    435:        register int d;
                    436: 
                    437:        d = (column(NOSTR) + WCOLS - 1 + (Putchar == listchar) + IN) / WCOLS;
                    438: #ifdef ADEBUG
                    439:        if (trace)
                    440:                tfixnl(), fprintf(trace, "vdepth returns %d\n", d == 0 ? 1 : d);
                    441: #endif
                    442:        return (d == 0 ? 1 : d);
                    443: }
                    444: 
                    445: /*
                    446:  * Move onto a new line, with cursor at position curs.
                    447:  */
                    448: vnline(curs)
                    449:        char *curs;
                    450: {
                    451: 
                    452:        if (curs)
                    453:                wcursor = curs;
                    454:        else if (vmoving)
                    455:                wcursor = vfindcol(vmovcol);
                    456:        else
                    457:                wcursor = vskipwh(linebuf);
                    458:        cursor = linebuf;
                    459:        vmove();
                    460: }

unix.superglobalmegacorp.com

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