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