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