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

Defined functions

fixzero defined in line 220; used 3 times
oop defined in line 56; used 2 times
ovbeg defined in line 122; used 2 times
ovend defined in line 136; used 2 times
savevis defined in line 247; used 3 times
setwind defined in line 282; used 2 times
undvis defined in line 262; used 2 times
vintr defined in line 360; used 3 times
vok defined in line 321; used 2 times
vop defined in line 158; used 1 times

Defined variables

atube defined in line 54; used 11 times
sccsid defined in line 2; never used
Last modified: 1981-09-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1299
Valid CSS Valid XHTML 1.0 Strict