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