Annotation of 43BSDReno/usr.bin/ex/ex_v.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_v.c      7.9 (Berkeley) 3/9/87";
                      9: #endif not lint
                     10: 
                     11: #include "ex.h"
                     12: #include "ex_re.h"
                     13: #include "ex_tty.h"
                     14: #include "ex_vis.h"
                     15: 
                     16: /*
                     17:  * Entry points to open and visual from command mode processor.
                     18:  * The open/visual code breaks down roughly as follows:
                     19:  *
                     20:  * ex_v.c      entry points, checking of terminal characteristics
                     21:  *
                     22:  * ex_vadj.c   logical screen control, use of intelligent operations
                     23:  *             insert/delete line and coordination with screen image;
                     24:  *             updating of screen after changes.
                     25:  *
                     26:  * ex_vget.c   input of single keys and reading of input lines
                     27:  *             from the echo area, handling of \ escapes on input for
                     28:  *             uppercase only terminals, handling of memory for repeated
                     29:  *             commands and small saved texts from inserts and partline
                     30:  *             deletes, notification of multi line changes in the echo
                     31:  *             area.
                     32:  *
                     33:  * ex_vmain.c  main command decoding, some command processing.
                     34:  *
                     35:  * ex_voperate.c   decoding of operator/operand sequences and
                     36:  *             contextual scans, implementation of word motions.
                     37:  *
                     38:  * ex_vops.c   major operator interfaces, undos, motions, deletes,
                     39:  *             changes, opening new lines, shifts, replacements and yanks
                     40:  *             coordinating logical and physical changes.
                     41:  *
                     42:  * ex_vops2.c  subroutines for operator interfaces in ex_vops.c,
                     43:  *             insert mode, read input line processing at lowest level.
                     44:  *
                     45:  * ex_vops3.c  structured motion definitions of ( ) { } and [ ] operators,
                     46:  *             indent for lisp routines, () and {} balancing. 
                     47:  *
                     48:  * ex_vput.c   output routines, clearing, physical mapping of logical cursor
                     49:  *             positioning, cursor motions, handling of insert character
                     50:  *             and delete character functions of intelligent and unintelligent
                     51:  *             terminals, visual mode tracing routines (for debugging),
                     52:  *             control of screen image and its updating.
                     53:  *
                     54:  * ex_vwind.c  window level control of display, forward and backward rolls,
                     55:  *             absolute motions, contextual displays, line depth determination
                     56:  */
                     57: 
                     58: jmp_buf venv;
                     59: int    winch();
                     60: 
                     61: /*
                     62:  * Enter open mode
                     63:  */
                     64: #ifdef u370
                     65: char   atube[TUBESIZE+LBSIZE];
                     66: #endif
                     67: oop()
                     68: {
                     69:        register char *ic;
                     70: #ifndef u370
                     71:        char atube[TUBESIZE + LBSIZE];
                     72: #endif
                     73:        ttymode f;      /* mjm: was register */
                     74: 
                     75:        if (setjmp(venv)) {
                     76:                setsize();
                     77:                initev = (char *)0;
                     78:                inopen = 0;
                     79:                addr1 = addr2 = dot;
                     80:        }
                     81: #ifdef SIGWINCH
                     82:        (void)signal(SIGWINCH, winch);
                     83: #endif
                     84:        ovbeg();
                     85:        if (peekchar() == '/') {
                     86:                ignore(compile(ex_getchar(), 1));
                     87:                savere(scanre);
                     88:                if (execute(0, dot) == 0)
                     89:                        error("Fail|Pattern not found on addressed line");
                     90:                ic = loc1;
                     91:                if (ic > linebuf && *ic == 0)
                     92:                        ic--;
                     93:        } else {
                     94:                getDOT();
                     95:                ic = vskipwh(linebuf);
                     96:        }
                     97:        newline();
                     98: 
                     99:        /*
                    100:         * If overstrike then have to HARDOPEN
                    101:         * else if can move cursor up off current line can use CRTOPEN (~~vi1)
                    102:         * otherwise (ugh) have to use ONEOPEN (like adm3)
                    103:         */
                    104:        if (OS && !EO)
                    105:                bastate = HARDOPEN;
                    106:        else if (CA || UP)
                    107:                bastate = CRTOPEN;
                    108:        else
                    109:                bastate = ONEOPEN;
                    110:        setwind();
                    111: 
                    112:        /*
                    113:         * To avoid bombing on glass-crt's when the line is too long
                    114:         * pretend that such terminals are 160 columns wide.
                    115:         * If a line is too wide for display, we will dynamically
                    116:         * switch to hardcopy open mode.
                    117:         */
                    118:        if (state != CRTOPEN)
                    119:                WCOLS = TUBECOLS;
                    120:        if (!inglobal)
                    121:                savevis();
                    122:        vok(atube);
                    123:        if (state != CRTOPEN)
                    124:                COLUMNS = WCOLS;
                    125:        Outchar = vputchar;
                    126:        f = ostart();
                    127:        if (state == CRTOPEN) {
                    128:                if (outcol == UKCOL)
                    129:                        outcol = 0;
                    130:                vmoveitup(1, 1);
                    131:        } else
                    132:                outline = destline = WBOT;
                    133:        vshow(dot, NOLINE);
                    134:        vnline(ic);
                    135:        vmain();
                    136:        if (state != CRTOPEN)
                    137:                vclean();
                    138:        Command = "open";
                    139:        ovend(f);
                    140: #ifdef SIGWINCH
                    141:        (void)signal(SIGWINCH, SIG_DFL);
                    142: #endif
                    143: }
                    144: 
                    145: ovbeg()
                    146: {
                    147: 
                    148:        if (!value(OPEN))
                    149:                error("Can't use open/visual unless open option is set");
                    150:        if (inopen)
                    151:                error("Recursive open/visual not allowed");
                    152:        Vlines = lineDOL();
                    153:        fixzero();
                    154:        setdot();
                    155:        pastwh();
                    156:        dot = addr2;
                    157: }
                    158: 
                    159: ovend(f)
                    160:        ttymode f;
                    161: {
                    162: 
                    163:        splitw++;
                    164:        vgoto(WECHO, 0);
                    165:        vclreol();
                    166:        vgoto(WECHO, 0);
                    167:        holdcm = 0;
                    168:        splitw = 0;
                    169:        ostop(f);
                    170:        setoutt();
                    171:        undvis();
                    172:        COLUMNS = OCOLUMNS;
                    173:        inopen = 0;
                    174:        flusho();
                    175:        netchHAD(Vlines);
                    176: }
                    177: 
                    178: /*
                    179:  * Enter visual mode
                    180:  */
                    181: vop()
                    182: {
                    183:        register int c;
                    184: #ifndef u370
                    185:        char atube[TUBESIZE + LBSIZE];
                    186: #endif
                    187:        ttymode f;      /* mjm: was register */
                    188: 
                    189:        if (!CA && UP == NOSTR) {
                    190:                if (initev) {
                    191: toopen:
                    192:                        merror("[Using open mode]");
                    193:                        putNFL();
                    194:                        oop();
                    195:                        return;
                    196:                }
                    197:                error("Visual needs addressible cursor or upline capability");
                    198:        }
                    199:        if (OS && !EO) {
                    200:                if (initev)
                    201:                        goto toopen;
                    202:                error("Can't use visual on a terminal which overstrikes");
                    203:        }
                    204:        if (!CL) {
                    205:                if (initev)
                    206:                        goto toopen;
                    207:                error("Visual requires clear screen capability");
                    208:        }
                    209:        if (NS && !SF) {
                    210:                if (initev)
                    211:                        goto toopen;
                    212:                error("Visual requires scrolling");
                    213:        }
                    214:        if (setjmp(venv)) {
                    215:                setsize();
                    216:                initev = (char *)0;
                    217:                inopen = 0;
                    218:                addr1 = addr2 = dot;
                    219:        }
                    220: #ifdef SIGWINCH
                    221:        (void)signal(SIGWINCH, winch);
                    222: #endif
                    223:        ovbeg();
                    224:        bastate = VISUAL;
                    225:        c = 0;
                    226:        if (any(peekchar(), "+-^."))
                    227:                c = ex_getchar();
                    228:        pastwh();
                    229:        vsetsiz(isdigit(peekchar()) ? getnum() : value(WINDOW));
                    230:        setwind();
                    231:        newline();
                    232:        vok(atube);
                    233:        if (!inglobal)
                    234:                savevis();
                    235:        Outchar = vputchar;
                    236:        vmoving = 0;
                    237:        f = ostart();
                    238:        if (initev == 0) {
                    239:                vcontext(dot, c);
                    240:                vnline(NOSTR);
                    241:        }
                    242:        vmain();
                    243:        Command = "visual";
                    244:        ovend(f);
                    245: #ifdef SIGWINCH
                    246:        (void)signal(SIGWINCH, SIG_DFL);
                    247: #endif
                    248: }
                    249: 
                    250: /*
                    251:  * Hack to allow entry to visual with
                    252:  * empty buffer since routines internally
                    253:  * demand at least one line.
                    254:  */
                    255: fixzero()
                    256: {
                    257: 
                    258:        if (dol == zero) {
                    259:                register bool ochng = chng;
                    260: 
                    261:                vdoappend("");
                    262:                if (!ochng)
                    263:                        ex_sync();
                    264:                addr1 = addr2 = one;
                    265:        } else if (addr2 == zero)
                    266:                addr2 = one;
                    267: }
                    268: 
                    269: /*
                    270:  * Save lines before visual between unddol and truedol.
                    271:  * Accomplish this by throwing away current [unddol,truedol]
                    272:  * and then saving all the lines in the buffer and moving
                    273:  * unddol back to dol.  Don't do this if in a global.
                    274:  *
                    275:  * If you do
                    276:  *     g/xxx/vi.
                    277:  * and then do a
                    278:  *     :e xxxx
                    279:  * at some point, and then quit from the visual and undo
                    280:  * you get the old file back.  Somewhat weird.
                    281:  */
                    282: savevis()
                    283: {
                    284: 
                    285:        if (inglobal)
                    286:                return;
                    287:        truedol = unddol;
                    288:        saveall();
                    289:        unddol = dol;
                    290:        undkind = UNDNONE;
                    291: }
                    292: 
                    293: /*
                    294:  * Restore a sensible state after a visual/open, moving the saved
                    295:  * stuff back to [unddol,dol], and killing the partial line kill indicators.
                    296:  */
                    297: undvis()
                    298: {
                    299: 
                    300:        if (ruptible)
                    301:                signal(SIGINT, onintr);
                    302:        squish();
                    303:        pkill[0] = pkill[1] = 0;
                    304:        unddol = truedol;
                    305:        unddel = zero;
                    306:        undap1 = one;
                    307:        undap2 = dol + 1;
                    308:        undkind = UNDALL;
                    309:        if (undadot <= zero || undadot > dol)
                    310:                undadot = zero+1;
                    311: }
                    312: 
                    313: /*
                    314:  * Set the window parameters based on the base state bastate
                    315:  * and the available buffer space.
                    316:  */
                    317: setwind()
                    318: {
                    319: 
                    320:        WCOLS = COLUMNS;
                    321:        switch (bastate) {
                    322: 
                    323:        case ONEOPEN:
                    324:                if (AM)
                    325:                        WCOLS--;
                    326:                /* fall into ... */
                    327: 
                    328:        case HARDOPEN:
                    329:                basWTOP = WTOP = WBOT = WECHO = 0;
                    330:                ex_ZERO = 0;
                    331:                holdcm++;
                    332:                break;
                    333: 
                    334:        case CRTOPEN:
                    335:                basWTOP = LINES - 2;
                    336:                /* fall into */
                    337: 
                    338:        case VISUAL:
                    339:                ex_ZERO = LINES - TUBESIZE / WCOLS;
                    340:                if (ex_ZERO < 0)
                    341:                        ex_ZERO = 0;
                    342:                if (ex_ZERO > basWTOP)
                    343:                        error("Screen too large for internal buffer");
                    344:                WTOP = basWTOP; WBOT = LINES - 2; WECHO = LINES - 1;
                    345:                break;
                    346:        }
                    347:        state = bastate;
                    348:        basWLINES = WLINES = WBOT - WTOP + 1;
                    349: }
                    350: 
                    351: /*
                    352:  * Can we hack an open/visual on this terminal?
                    353:  * If so, then divide the screen buffer up into lines,
                    354:  * and initialize a bunch of state variables before we start.
                    355:  */
                    356: vok(atube)
                    357:        register char *atube;
                    358: {
                    359:        register int i;
                    360: 
                    361:        if (WCOLS == 1000)
                    362:                serror("Don't know enough about your terminal to use %s", Command);
                    363:        if (WCOLS > TUBECOLS)
                    364:                error("Terminal too wide");
                    365:        if (WLINES >= TUBELINES || WCOLS * (WECHO - ex_ZERO + 1) > TUBESIZE)
                    366:                error("Screen too large");
                    367: 
                    368:        vtube0 = atube;
                    369:        vclrbyte(atube, WCOLS * (WECHO - ex_ZERO + 1));
                    370:        for (i = 0; i < ex_ZERO; i++)
                    371:                vtube[i] = (char *) 0;
                    372:        for (; i <= WECHO; i++)
                    373:                vtube[i] = atube, atube += WCOLS;
                    374:        for (; i < TUBELINES; i++)
                    375:                vtube[i] = (char *) 0;
                    376:        vutmp = atube;
                    377:        vundkind = VNONE;
                    378:        vUNDdot = 0;
                    379:        OCOLUMNS = COLUMNS;
                    380:        inopen = 1;
                    381: #ifdef CBREAK
                    382:        signal(SIGINT, vintr);
                    383: #endif
                    384:        vmoving = 0;
                    385:        splitw = 0;
                    386:        doomed = 0;
                    387:        holdupd = 0;
                    388:        Peek_key = 0;
                    389:        vcnt = vcline = 0;
                    390:        if (ex_vSCROLL == 0)
                    391:                ex_vSCROLL = (value(WINDOW)+1)/2; /* round up so dft=6,11 */
                    392: }
                    393: 
                    394: #ifdef CBREAK
                    395: vintr()
                    396: {
                    397:        extern jmp_buf readbuf;
                    398:        extern int doingread;
                    399: 
                    400:        signal(SIGINT, vintr);
                    401:        if (vcatch)
                    402:                onintr();
                    403:        ungetkey(ATTN);
                    404:        draino();
                    405:        if (doingread) {
                    406:                doingread = 0;
                    407:                longjmp(readbuf, 1);
                    408:        }
                    409: }
                    410: #endif
                    411: 
                    412: /*
                    413:  * Set the size of the screen to size lines, to take effect the
                    414:  * next time the screen is redrawn.
                    415:  */
                    416: vsetsiz(size)
                    417:        int size;
                    418: {
                    419:        register int b;
                    420: 
                    421:        if (bastate != VISUAL)
                    422:                return;
                    423:        b = LINES - 1 - size;
                    424:        if (b >= LINES - 1)
                    425:                b = LINES - 2;
                    426:        if (b < 0)
                    427:                b = 0;
                    428:        basWTOP = b;
                    429:        basWLINES = WBOT - b + 1;
                    430: }
                    431: 
                    432: #ifdef SIGWINCH
                    433: winch()
                    434: {
                    435:        vsave();
                    436:        ignore(setty(normf));
                    437:        longjmp(venv, 1);
                    438: }
                    439: #endif

unix.superglobalmegacorp.com

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