|
|
1.1 root 1: /* Copyright (c) 1981 Regents of the University of California */
2: static char *sccsid = "@(#)ex_v.c 7.4 6/18/83";
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: extern jmp_buf readbuf;
363: extern int doingread;
364:
365: signal(SIGINT, vintr);
366: if (vcatch)
367: onintr();
368: ungetkey(ATTN);
369: draino();
370: if (doingread) {
371: doingread = 0;
372: longjmp(readbuf, 1);
373: }
374: }
375: #endif
376:
377: /*
378: * Set the size of the screen to size lines, to take effect the
379: * next time the screen is redrawn.
380: */
381: vsetsiz(size)
382: int size;
383: {
384: register int b;
385:
386: if (bastate != VISUAL)
387: return;
388: b = LINES - 1 - size;
389: if (b >= LINES - 1)
390: b = LINES - 2;
391: if (b < 0)
392: b = 0;
393: basWTOP = b;
394: basWLINES = WBOT - b + 1;
395: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.