|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.