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

Defined functions

fixzero defined in line 248; used 3 times
oop defined in line 66; used 2 times
ovbeg defined in line 141; used 2 times
ovend defined in line 155; used 2 times
savevis defined in line 275; used 3 times
setwind defined in line 310; used 2 times
undvis defined in line 290; used 2 times
vintr defined in line 388; used 3 times
vok defined in line 349; used 2 times
vop defined in line 177; used 1 times
vsetsiz defined in line 409; used 4 times
winch defined in line 425; used 4 times

Defined variables

atube defined in line 64; used 11 times
sccsid defined in line 8; never used
venv defined in line 57; used 3 times
Last modified: 1994-12-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3836
Valid CSS Valid XHTML 1.0 Strict