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

Defined functions

fixzero defined in line 228; used 3 times
oop defined in line 52; used 2 times
ovbeg defined in line 120; used 2 times
ovend defined in line 134; used 2 times
savevis defined in line 255; used 3 times
setwind defined in line 288; used 2 times
undvis defined in line 270; used 2 times
vintr defined in line 370; used 3 times
vok defined in line 331; used 2 times
vop defined in line 156; used 1 times
vsetsiz defined in line 385; used 3 times
Last modified: 1980-09-13
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1219
Valid CSS Valid XHTML 1.0 Strict