Subversion Repositories planix.SVN

Rev

Rev 118 | Details | Compare with Previous | Last modification | View Log | RSS feed

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