|
|
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.8 (Berkeley) 6/7/85"; ! 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: int resize; ! 75: ! 76: if (resize = setjmp(venv)) { ! 77: setsize(); ! 78: initev = (char *)0; ! 79: inopen = 0; ! 80: addr1 = addr2 = dot; ! 81: } ! 82: (void)signal(SIGWINCH, winch); ! 83: ovbeg(); ! 84: if (peekchar() == '/') { ! 85: ignore(compile(getchar(), 1)); ! 86: savere(scanre); ! 87: if (execute(0, dot) == 0) ! 88: error("Fail|Pattern not found on addressed line"); ! 89: ic = loc1; ! 90: if (ic > linebuf && *ic == 0) ! 91: ic--; ! 92: } else { ! 93: getDOT(); ! 94: ic = vskipwh(linebuf); ! 95: } ! 96: newline(); ! 97: ! 98: /* ! 99: * If overstrike then have to HARDOPEN ! 100: * else if can move cursor up off current line can use CRTOPEN (~~vi1) ! 101: * otherwise (ugh) have to use ONEOPEN (like adm3) ! 102: */ ! 103: if (OS && !EO) ! 104: bastate = HARDOPEN; ! 105: else if (CA || UP) ! 106: bastate = CRTOPEN; ! 107: else ! 108: bastate = ONEOPEN; ! 109: setwind(); ! 110: ! 111: /* ! 112: * To avoid bombing on glass-crt's when the line is too long ! 113: * pretend that such terminals are 160 columns wide. ! 114: * If a line is too wide for display, we will dynamically ! 115: * switch to hardcopy open mode. ! 116: */ ! 117: if (state != CRTOPEN) ! 118: WCOLS = TUBECOLS; ! 119: if (!inglobal) ! 120: savevis(); ! 121: vok(atube); ! 122: if (state != CRTOPEN) ! 123: COLUMNS = WCOLS; ! 124: Outchar = vputchar; ! 125: f = ostart(); ! 126: if (state == CRTOPEN) { ! 127: if (outcol == UKCOL) ! 128: outcol = 0; ! 129: vmoveitup(1, 1); ! 130: } else ! 131: outline = destline = WBOT; ! 132: vshow(dot, NOLINE); ! 133: vnline(ic); ! 134: vmain(); ! 135: if (state != CRTOPEN) ! 136: vclean(); ! 137: Command = "open"; ! 138: ovend(f); ! 139: (void)signal(SIGWINCH, SIG_DFL); ! 140: } ! 141: ! 142: ovbeg() ! 143: { ! 144: ! 145: if (!value(OPEN)) ! 146: error("Can't use open/visual unless open option is set"); ! 147: if (inopen) ! 148: error("Recursive open/visual not allowed"); ! 149: Vlines = lineDOL(); ! 150: fixzero(); ! 151: setdot(); ! 152: pastwh(); ! 153: dot = addr2; ! 154: } ! 155: ! 156: ovend(f) ! 157: ttymode f; ! 158: { ! 159: ! 160: splitw++; ! 161: vgoto(WECHO, 0); ! 162: vclreol(); ! 163: vgoto(WECHO, 0); ! 164: holdcm = 0; ! 165: splitw = 0; ! 166: ostop(f); ! 167: setoutt(); ! 168: undvis(); ! 169: COLUMNS = OCOLUMNS; ! 170: inopen = 0; ! 171: flusho(); ! 172: netchHAD(Vlines); ! 173: } ! 174: ! 175: /* ! 176: * Enter visual mode ! 177: */ ! 178: vop() ! 179: { ! 180: register int c; ! 181: #ifndef u370 ! 182: char atube[TUBESIZE + LBSIZE]; ! 183: #endif ! 184: ttymode f; /* mjm: was register */ ! 185: int resize; ! 186: ! 187: if (!CA && UP == NOSTR) { ! 188: if (initev) { ! 189: toopen: ! 190: merror("[Using open mode]"); ! 191: putNFL(); ! 192: oop(); ! 193: return; ! 194: } ! 195: error("Visual needs addressible cursor or upline capability"); ! 196: } ! 197: if (OS && !EO) { ! 198: if (initev) ! 199: goto toopen; ! 200: error("Can't use visual on a terminal which overstrikes"); ! 201: } ! 202: if (!CL) { ! 203: if (initev) ! 204: goto toopen; ! 205: error("Visual requires clear screen capability"); ! 206: } ! 207: if (NS && !SF) { ! 208: if (initev) ! 209: goto toopen; ! 210: error("Visual requires scrolling"); ! 211: } ! 212: if (resize = setjmp(venv)) { ! 213: setsize(); ! 214: initev = (char *)0; ! 215: inopen = 0; ! 216: addr1 = addr2 = dot; ! 217: } ! 218: (void)signal(SIGWINCH, winch); ! 219: ovbeg(); ! 220: bastate = VISUAL; ! 221: c = 0; ! 222: if (any(peekchar(), "+-^.")) ! 223: c = getchar(); ! 224: pastwh(); ! 225: vsetsiz(isdigit(peekchar()) ? getnum() : value(WINDOW)); ! 226: setwind(); ! 227: newline(); ! 228: vok(atube); ! 229: if (!inglobal) ! 230: savevis(); ! 231: Outchar = vputchar; ! 232: vmoving = 0; ! 233: f = ostart(); ! 234: if (initev == 0) { ! 235: vcontext(dot, c); ! 236: vnline(NOSTR); ! 237: } ! 238: vmain(); ! 239: Command = "visual"; ! 240: ovend(f); ! 241: (void)signal(SIGWINCH, SIG_DFL); ! 242: } ! 243: ! 244: /* ! 245: * Hack to allow entry to visual with ! 246: * empty buffer since routines internally ! 247: * demand at least one line. ! 248: */ ! 249: fixzero() ! 250: { ! 251: ! 252: if (dol == zero) { ! 253: register bool ochng = chng; ! 254: ! 255: vdoappend(""); ! 256: if (!ochng) ! 257: sync(); ! 258: addr1 = addr2 = one; ! 259: } else if (addr2 == zero) ! 260: addr2 = one; ! 261: } ! 262: ! 263: /* ! 264: * Save lines before visual between unddol and truedol. ! 265: * Accomplish this by throwing away current [unddol,truedol] ! 266: * and then saving all the lines in the buffer and moving ! 267: * unddol back to dol. Don't do this if in a global. ! 268: * ! 269: * If you do ! 270: * g/xxx/vi. ! 271: * and then do a ! 272: * :e xxxx ! 273: * at some point, and then quit from the visual and undo ! 274: * you get the old file back. Somewhat weird. ! 275: */ ! 276: savevis() ! 277: { ! 278: ! 279: if (inglobal) ! 280: return; ! 281: truedol = unddol; ! 282: saveall(); ! 283: unddol = dol; ! 284: undkind = UNDNONE; ! 285: } ! 286: ! 287: /* ! 288: * Restore a sensible state after a visual/open, moving the saved ! 289: * stuff back to [unddol,dol], and killing the partial line kill indicators. ! 290: */ ! 291: undvis() ! 292: { ! 293: ! 294: if (ruptible) ! 295: signal(SIGINT, onintr); ! 296: squish(); ! 297: pkill[0] = pkill[1] = 0; ! 298: unddol = truedol; ! 299: unddel = zero; ! 300: undap1 = one; ! 301: undap2 = dol + 1; ! 302: undkind = UNDALL; ! 303: if (undadot <= zero || undadot > dol) ! 304: undadot = zero+1; ! 305: } ! 306: ! 307: /* ! 308: * Set the window parameters based on the base state bastate ! 309: * and the available buffer space. ! 310: */ ! 311: setwind() ! 312: { ! 313: ! 314: WCOLS = COLUMNS; ! 315: switch (bastate) { ! 316: ! 317: case ONEOPEN: ! 318: if (AM) ! 319: WCOLS--; ! 320: /* fall into ... */ ! 321: ! 322: case HARDOPEN: ! 323: basWTOP = WTOP = WBOT = WECHO = 0; ! 324: ZERO = 0; ! 325: holdcm++; ! 326: break; ! 327: ! 328: case CRTOPEN: ! 329: basWTOP = LINES - 2; ! 330: /* fall into */ ! 331: ! 332: case VISUAL: ! 333: ZERO = LINES - TUBESIZE / WCOLS; ! 334: if (ZERO < 0) ! 335: ZERO = 0; ! 336: if (ZERO > basWTOP) ! 337: error("Screen too large for internal buffer"); ! 338: WTOP = basWTOP; WBOT = LINES - 2; WECHO = LINES - 1; ! 339: break; ! 340: } ! 341: state = bastate; ! 342: basWLINES = WLINES = WBOT - WTOP + 1; ! 343: } ! 344: ! 345: /* ! 346: * Can we hack an open/visual on this terminal? ! 347: * If so, then divide the screen buffer up into lines, ! 348: * and initialize a bunch of state variables before we start. ! 349: */ ! 350: vok(atube) ! 351: register char *atube; ! 352: { ! 353: register int i; ! 354: ! 355: if (WCOLS == 1000) ! 356: serror("Don't know enough about your terminal to use %s", Command); ! 357: if (WCOLS > TUBECOLS) ! 358: error("Terminal too wide"); ! 359: if (WLINES >= TUBELINES || WCOLS * (WECHO - ZERO + 1) > TUBESIZE) ! 360: error("Screen too large"); ! 361: ! 362: vtube0 = atube; ! 363: vclrbyte(atube, WCOLS * (WECHO - ZERO + 1)); ! 364: for (i = 0; i < ZERO; i++) ! 365: vtube[i] = (char *) 0; ! 366: for (; i <= WECHO; i++) ! 367: vtube[i] = atube, atube += WCOLS; ! 368: for (; i < TUBELINES; i++) ! 369: vtube[i] = (char *) 0; ! 370: vutmp = atube; ! 371: vundkind = VNONE; ! 372: vUNDdot = 0; ! 373: OCOLUMNS = COLUMNS; ! 374: inopen = 1; ! 375: #ifdef CBREAK ! 376: signal(SIGINT, vintr); ! 377: #endif ! 378: vmoving = 0; ! 379: splitw = 0; ! 380: doomed = 0; ! 381: holdupd = 0; ! 382: Peekkey = 0; ! 383: vcnt = vcline = 0; ! 384: if (vSCROLL == 0) ! 385: vSCROLL = (value(WINDOW)+1)/2; /* round up so dft=6,11 */ ! 386: } ! 387: ! 388: #ifdef CBREAK ! 389: vintr() ! 390: { ! 391: extern jmp_buf readbuf; ! 392: extern int doingread; ! 393: ! 394: signal(SIGINT, vintr); ! 395: if (vcatch) ! 396: onintr(); ! 397: ungetkey(ATTN); ! 398: draino(); ! 399: if (doingread) { ! 400: doingread = 0; ! 401: longjmp(readbuf, 1); ! 402: } ! 403: } ! 404: #endif ! 405: ! 406: /* ! 407: * Set the size of the screen to size lines, to take effect the ! 408: * next time the screen is redrawn. ! 409: */ ! 410: vsetsiz(size) ! 411: int size; ! 412: { ! 413: register int b; ! 414: ! 415: if (bastate != VISUAL) ! 416: return; ! 417: b = LINES - 1 - size; ! 418: if (b >= LINES - 1) ! 419: b = LINES - 2; ! 420: if (b < 0) ! 421: b = 0; ! 422: basWTOP = b; ! 423: basWLINES = WBOT - b + 1; ! 424: } ! 425: ! 426: winch() ! 427: { ! 428: vsave(); ! 429: setty(normf); ! 430: longjmp(venv, 1); ! 431: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.