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

Defined functions

fixzero defined in line 249; used 3 times
oop defined in line 67; used 2 times
ovbeg defined in line 142; used 2 times
ovend defined in line 156; used 2 times
savevis defined in line 276; used 3 times
setwind defined in line 311; used 2 times
undvis defined in line 291; used 2 times
vintr defined in line 389; used 3 times
vok defined in line 350; used 2 times
vop defined in line 178; used 1 times
vsetsiz defined in line 410; used 4 times
winch defined in line 426; used 4 times

Defined variables

atube defined in line 65; used 11 times
sccsid defined in line 8; never used
venv defined in line 58; used 3 times
Last modified: 1985-06-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1638
Valid CSS Valid XHTML 1.0 Strict