Annotation of 40BSD/cmd/ex/ex_v.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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