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