Annotation of 43BSDReno/usr.bin/ex/ex_vwind.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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