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