1 /* vi.h */
2 
3 /* Author:
4  *	Steve Kirkendall
5  *	16820 SW Tallac Way
6  *	Beaverton, OR 97006
7  *	kirkenda@jove.cs.pdx.edu, or ...uunet!tektronix!psueea!jove!kirkenda
8  */
9 
10 /* Chinese GuoBiao version:
11  *
12  *	Author: Man-Chi Pong
13  *		Department of Computer Science
14  *		The Hong Kong University of Science and Technology
15  *		Clear Water Bay, Kowloon, Hong Kong
16  *		mcpong@uxmail.ust.hk,  or mcpong@usthk.bitnet
17  *
18  *		Yongguang Zhang
19  *		Purdue University Department of Computer Sciences
20  *		West Lafayette, IN 47907
21  *		ygz@cs.purdue.edu,  or ...uunet!cs.purdue.edu!ygz
22  */
23 
24 /* This is the header file for my version of vi. */
25 
26 #define VERSION "ELVIS 1.3, by Steve Kirkendall"
27 #define COPYING	"This version of ELVIS is freely redistributable."
28 
29 #define CVERSION "CHINESE GB/BIG5 VERSION, by Man-Chi Pong and Yongguang Zhang"
30 
31 #include <errno.h>
32 extern int errno;
33 #if TOS
34 #define ENOENT (-AEFILNF)
35 #endif
36 
37 #if TOS
38 # include <types.h>
39 # define O_RDONLY	0
40 # define O_WRONLY	1
41 # define O_RDWR		2
42 #else
43 # include <sys/types.h>
44 # include <fcntl.h>
45 #endif
46 
47 #ifndef O_BINARY
48 # define O_BINARY	0
49 #endif
50 
51 #include "curses.h"
52 
53 #include "stdio.h"
54 #include "assert.h"
55 #define IsHiBitOn(byte)	((byte) & 0x80)
56 #define IsHiBitOnMark(m)	(IsHiBitOn(ptext[markidx(m)]))
57 
58 /*------------------------------------------------------------------------*/
59 /* Miscellaneous constants.						  */
60 
61 #define INFINITY	2000000001L	/* a very large integer */
62 #if MSDOS
63 # define MAXMAPS	50		/* then we have lots of specials */
64 #else
65 # define MAXMAPS	20		/* number of :map keys */
66 #endif
67 #define LONGKEY		10		/* longest possible raw :map key */
68 #define MAXDIGS		30		/* number of :digraph combos */
69 #define MAXRCLEN	4000		/* longest possible .exrc file */
70 
71 /*------------------------------------------------------------------------*/
72 /* These describe how temporary files are divided into blocks             */
73 
74 #define BLKSIZE	1024		/* size of blocks */
75 #define MAXBLKS	(BLKSIZE / sizeof(unsigned short))
76 typedef union
77 {
78 	char		c[BLKSIZE];	/* for text blocks */
79 	unsigned short	n[MAXBLKS];	/* for the header block */
80 }
81 	BLK;
82 
83 /*------------------------------------------------------------------------*/
84 /* These are used manipulate BLK buffers.                                 */
85 
86 extern BLK	hdr;		/* buffer for the header block */
87 extern BLK	blkbuf[2];	/* buffers for text blocks */
88 extern BLK	*blkget();	/* given index into hdr.c[], reads block */
89 extern BLK	*blkadd();	/* inserts a new block into hdr.c[] */
90 
91 /*------------------------------------------------------------------------*/
92 /* These are used to keep track of various flags                          */
93 extern struct _viflags
94 {
95 	short	file;		/* file flags */
96 }
97 	viflags;
98 
99 /* file flags */
100 #define NEWFILE		0x0001	/* the file was just created */
101 #define READONLY	0x0002	/* the file is read-only */
102 #define HADNUL		0x0004	/* the file contained NUL characters */
103 #define MODIFIED	0x0008	/* the file has been modified */
104 #define NOFILENAME	0x0010	/* no name is known for the current text */
105 #define ADDEDNL		0x0020	/* newlines were added to the file */
106 
107 /* macros used to set/clear/test flags */
108 #define setflag(x,y)	viflags.x |= y
109 #define clrflag(x,y)	viflags.x &= ~y
110 #define tstflag(x,y)	(viflags.x & y)
111 #define initflags()	viflags.file = 0;
112 
113 /* The options */
114 extern char	o_autoindent[1];
115 extern char	o_autowrite[1];
116 #ifndef NO_CHARATTR
117 extern char	o_charattr[1];
118 #endif
119 extern char	o_columns[3];
120 extern char	o_directory[30];
121 extern char	o_errorbells[1];
122 extern char	o_exrefresh[1];
123 #ifndef NO_SENTENCE
124 extern char	o_hideformat[1];
125 #endif
126 extern char	o_ignorecase[1];
127 #ifndef NO_EXTENSIONS
128 extern char	o_inputmode[1];
129 #endif
130 extern char	o_keytime[3];
131 extern char	o_keywordprg[80];
132 extern char	o_lines[3];
133 extern char	o_list[1];
134 #ifndef NO_MAGIC
135 extern char	o_magic[1];
136 #endif
137 #ifndef NO_SENTENCE
138 extern char	o_paragraphs[30];
139 #endif
140 #if MSDOS
141 extern char	o_pcbios[1];
142 #endif
143 extern char	o_readonly[1];
144 extern char	o_report[3];
145 extern char	o_scroll[3];
146 #ifndef NO_SENTENCE
147 extern char	o_sections[30];
148 #endif
149 extern char	o_shell[60];
150 extern char	o_showmode[1];
151 extern char	o_shiftwidth[3];
152 extern char	o_sidescroll[3];
153 extern char	o_sync[1];
154 extern char	o_tabstop[3];
155 extern char	o_term[30];
156 extern char	o_vbell[1];
157 extern char	o_warn[1];
158 extern char	o_wrapmargin[3];
159 extern char	o_wrapscan[1];
160 
161 /*------------------------------------------------------------------------*/
162 /* These help support the single-line multi-change "undo" -- shift-U      */
163 
164 extern char	U_text[BLKSIZE];
165 extern long	U_line;
166 
167 /*------------------------------------------------------------------------*/
168 /* These are used to refer to places in the text 			  */
169 
170 typedef long	MARK;
171 #define markline(x)	(long)((x) / BLKSIZE)
172 #define markidx(x)	(int)((x) & (BLKSIZE - 1))
173 #define MARK_UNSET	((MARK)0)
174 #define MARK_FIRST	((MARK)BLKSIZE)
175 #define MARK_LAST	((MARK)(nlines * BLKSIZE))
176 #define MARK_AT_LINE(x)	((MARK)((x) * BLKSIZE))
177 
178 #define NMARKS	28
179 extern MARK	mark[NMARKS];	/* marks 'a through 'z, plus mark '' */
180 extern MARK	cursor;		/* mark where line is */
181 
182 /*------------------------------------------------------------------------*/
183 /* These are used to keep track of the current & previous files.	  */
184 
185 extern long	origtime;	/* modification date&time of the current file */
186 extern char	origname[256];	/* name of the current file */
187 extern char	prevorig[256];	/* name of the preceding file */
188 extern long	prevline;	/* line number from preceding file */
189 
190 /*------------------------------------------------------------------------*/
191 /* misc housekeeping variables & functions				  */
192 
193 extern int	tmpfd;		/* fd used to access the tmp file */
194 extern long	lnum[MAXBLKS];	/* last line# of each block */
195 extern long	nlines;		/* number of lines in the file */
196 extern char	args[BLKSIZE];	/* file names given on the command line */
197 extern int	argno;		/* the current element of args[] */
198 extern int	nargs;		/* number of filenames in args */
199 extern long	changes;	/* counts changes, to prohibit short-cuts */
200 extern int	mustredraw;	/* boolean: force total redraw of screen? */
201 extern long	redrawafter;	/* line# of first line to redraw */
202 extern long	preredraw;	/* line# of last line changed, before change */
203 extern long	postredraw;	/* line# of last line changed, after change */
204 extern BLK	tmpblk;		/* a block used to accumulate changes */
205 extern long	topline;	/* file line number of top line */
206 extern int	leftcol;	/* column number of left col */
207 #define		botline	 (topline + LINES - 2)
208 #define		rightcol (leftcol + COLS - 1)
209 extern int	physcol;	/* physical column number that cursor is on */
210 extern int	physrow;	/* physical row number that cursor is on */
211 extern int	exwrote;	/* used to detect verbose ex commands */
212 extern int	doingdot;	/* boolean: are we doing the "." command? */
213 extern long	rptlines;	/* number of lines affected by a command */
214 extern char	*rptlabel;	/* description of how lines were affected */
215 extern char	*fetchline();	/* read a given line from tmp file */
216 extern char	*parseptrn();	/* isolate a regexp in a line */
217 extern MARK	paste();	/* paste from cut buffer to a given point */
218 extern char	*wildcard();	/* expand wildcards in filenames */
219 extern MARK	input();	/* inserts characters from keyboard */
220 extern char	*linespec();	/* finds the end of a /regexp/ string */
221 #define		ctrl(ch) ((ch)&037)
222 #ifndef NO_RECYCLE
223 extern long	allocate();	/* allocate a free block of the tmp file */
224 #endif
225 extern int	trapint();	/* trap handler for SIGINT */
226 
227 /*------------------------------------------------------------------------*/
228 /* macros that are used as control structures                             */
229 
230 #define BeforeAfter(before, after) for((before),bavar=1;bavar;(after),bavar=0)
231 #define ChangeText	BeforeAfter(beforedo(FALSE),afterdo())
232 
233 extern int	bavar;		/* used only in BeforeAfter macros */
234 
235 /*------------------------------------------------------------------------*/
236 /* These are the movement commands.  Each accepts a mark for the starting */
237 /* location & number and returns a mark for the destination.		  */
238 
239 extern MARK	m_up();			/* k */
240 extern MARK	m_down();		/* j */
241 extern MARK	m_right();		/* h */
242 extern MARK	m_left();		/* l */
243 extern MARK	m_toline();		/* G */
244 extern MARK	m_tocol();		/* | */
245 extern MARK	m_front();		/* ^ */
246 extern MARK	m_rear();		/* $ */
247 extern MARK	m_fword();		/* w */
248 extern MARK	m_bword();		/* b */
249 extern MARK	m_eword();		/* e */
250 extern MARK	m_fWord();		/* W */
251 extern MARK	m_bWord();		/* B */
252 extern MARK	m_eWord();		/* E */
253 extern MARK	m_fparagraph();	/* } */
254 extern MARK	m_bparagraph();	/* { */
255 extern MARK	m_fsection();		/* ]] */
256 extern MARK	m_bsection();		/* [[ */
257 extern MARK	m_match();		/* % */
258 #ifndef NO_SENTENCE
259 extern MARK	m_fsentence();	/* ) */
260 extern MARK	m_bsentence();	/* ( */
261 #endif
262 extern MARK	m_tomark();		/* 'm */
263 extern MARK	m_nsrch();		/* n */
264 extern MARK	m_Nsrch();		/* N */
265 extern MARK	m_fsrch();		/* /regexp */
266 extern MARK	m_bsrch();		/* ?regexp */
267 extern MARK	m__ch();		/* ; , */
268 extern MARK	m_fch();		/* f */
269 extern MARK	m_tch();		/* t */
270 extern MARK	m_Fch();		/* F */
271 extern MARK	m_Tch();		/* T */
272 extern MARK	m_row();		/* H L M */
273 extern MARK	m_z();		/* z */
274 extern MARK	m_scroll();		/* ^B ^F ^E ^Y ^U ^D */
275 
276 /* Some stuff that is used by movement functions... */
277 
278 extern MARK	adjmove();		/* a helper fn, used by move fns */
279 
280 /* This macro is used to set the default value of cnt */
281 #define DEFAULT(val)	if (cnt < 1) cnt = (val)
282 
283 /* These are used to minimize calls to fetchline() */
284 extern int	plen;	/* length of the line */
285 extern long	pline;	/* line number that len refers to */
286 extern long	pchgs;	/* "changes" level that len refers to */
287 extern char	*ptext;	/* text of previous line, if valid */
288 extern void	pfetch();
289 
290 /* This is used to build a MARK that corresponds to a specific point in the
291  * line that was most recently pfetch'ed.
292  */
293 #define buildmark(text)	(MARK)(BLKSIZE * pline + (int)((text) - ptext))
294 
295 
296 /*------------------------------------------------------------------------*/
297 /* These are used to handle EX commands.				  */
298 
299 #define  CMD_NULL	0	/* NOT A VALID COMMAND */
300 #define  CMD_ABBR	1	/* "define an abbreviation" */
301 #define  CMD_ARGS	2	/* "show me the args" */
302 #define  CMD_APPEND	3	/* "insert lines after this line" */
303 #define  CMD_BANG	4	/* "run a single shell command" */
304 #define  CMD_COPY	5	/* "copy the selected text to a given place" */
305 #define  CMD_CD		6	/* "change directories" */
306 #define  CMD_CHANGE	7	/* "change some lines" */
307 #define  CMD_DELETE	8	/* "delete the selected text" */
308 #define  CMD_DIGRAPH	9	/* "add a digraph, or display them all" */
309 #define  CMD_EDIT	10	/* "switch to a different file" */
310 #define  CMD_FILE	11	/* "show the file's status" */
311 #define  CMD_GLOBAL	12	/* "globally search & do a command" */
312 #define  CMD_INSERT	13	/* "insert lines before the current line" */
313 #define  CMD_JOIN	14	/* "join the selected line & the one after" */
314 #define  CMD_LIST	15	/* "print lines, making control chars visible" */
315 #define  CMD_MAP	16	/* "adjust the keyboard map" */
316 #define  CMD_MARK	17	/* "mark this line" */
317 #define  CMD_MKEXRC	18	/* "make a .exrc file" */
318 #define  CMD_MOVE	19	/* "move the selected text to a given place" */
319 #define  CMD_NEXT	20	/* "switch to next file in args" */
320 #define  CMD_PRESERVE	21	/* "act as though vi crashed" */
321 #define  CMD_PREVIOUS	22	/* "switch to the previous file in args" */
322 #define  CMD_PRINT	23	/* "print the selected text" */
323 #define  CMD_PUT	24	/* "insert any cut lines before this line" */
324 #define  CMD_QUIT	25	/* "quit without writing the file" */
325 #define  CMD_READ	26	/* "append the given file after this line */
326 #define  CMD_RECOVER	27	/* "recover file after vi crashes" - USE -r FLAG */
327 #define  CMD_REWIND	28	/* "rewind to first file" */
328 #define  CMD_SET	29	/* "set a variable's value" */
329 #define  CMD_SHELL	30	/* "run some lines through a command" */
330 #define  CMD_SHIFTL	31	/* "shift lines left" */
331 #define  CMD_SHIFTR	32	/* "shift lines right" */
332 #define  CMD_SOURCE	33	/* "interpret a file's contents as ex commands" */
333 #define  CMD_STOP	34	/* same as CMD_SUSPEND */
334 #define  CMD_SUSPEND	35	/* "suspend the vi session" */
335 #define  CMD_SUBSTITUTE	36	/* "substitute text in this line" */
336 #define  CMD_TR		37	/* "transliterate chars in the selected lines" */
337 #define  CMD_TAG	38	/* "go to a particular tag" */
338 #define  CMD_UNABBR	39	/* "remove an abbreviation definition" */
339 #define  CMD_UNDO	40	/* "undo the previous command" */
340 #define  CMD_UNMAP	41	/* "remove a key sequence map */
341 #define  CMD_VERSION	42	/* "describe which version this is" */
342 #define  CMD_VGLOBAL	43	/* "apply a cmd to lines NOT containing an RE" */
343 #define  CMD_VISUAL	44	/* "go into visual mode" */
344 #define  CMD_WQUIT	45	/* "write this file out (any case) & quit" */
345 #define  CMD_WRITE	46	/* "write the selected(?) text to a given file" */
346 #define  CMD_XIT	47	/* "write this file out (if modified) & quit" */
347 #define  CMD_YANK	48	/* "copy the selected text into the cut buffer" */
348 #ifdef DEBUG
349 # define CMD_DEBUG	49	/* access to internal data structures */
350 # define CMD_VALIDATE	50	/* check for internal consistency */
351 #endif
352 typedef int CMD;
353 
354 extern		ex();
355 extern		vi();
356 extern		doexcmd();
357 
358 extern void	cmd_append();
359 extern void	cmd_args();
360 extern void	cmd_cd();
361 extern void	cmd_delete();
362 #ifndef NO_DIGRAPH
363 extern void	cmd_digraph();
364 #endif
365 extern void	cmd_edit();
366 extern void	cmd_file();
367 extern void	cmd_global();
368 extern void	cmd_join();
369 extern void	cmd_mark();
370 extern void	cmd_list();
371 extern void	cmd_map();
372 #ifndef NO_EXTENSIONS
373 extern void	cmd_mkexrc();
374 #endif
375 extern void	cmd_next();
376 extern void	cmd_print();
377 extern void	cmd_put();
378 extern void	cmd_quit();
379 extern void	cmd_read();
380 extern void	cmd_rewind();
381 extern void	cmd_set();
382 extern void	cmd_shell();
383 extern void	cmd_shift();
384 extern void	cmd_source();
385 extern void	cmd_substitute();
386 extern void	cmd_tag();
387 extern void	cmd_undo();
388 extern void	cmd_version();
389 extern void	cmd_visual();
390 extern void	cmd_write();
391 extern void	cmd_xit();
392 extern void	cmd_move();
393 #ifdef DEBUG
394 extern void	cmd_debug();
395 extern void	cmd_validate();
396 #endif
397 
398 /*----------------------------------------------------------------------*/
399 /* These are used to handle VI commands 				*/
400 
401 extern MARK	v_1ex();	/* : */
402 extern MARK	v_mark();	/* m */
403 extern MARK	v_quit();	/* Q */
404 extern MARK	v_redraw();	/* ^L ^R */
405 extern MARK	v_ulcase();	/* ~ */
406 extern MARK	v_undo();	/* u */
407 extern MARK	v_xchar();	/* x */
408 extern MARK	v_Xchar();	/* X */
409 extern MARK	v_replace();	/* r */
410 extern MARK	v_overtype();	/* R */
411 extern MARK	v_selcut();	/* " */
412 extern MARK	v_paste();	/* p P */
413 extern MARK	v_yank();	/* y Y */
414 extern MARK	v_delete();	/* d D */
415 extern MARK	v_join();	/* J */
416 extern MARK	v_insert();	/* a A i I o O */
417 extern MARK	v_change();	/* c C */
418 extern MARK	v_subst();	/* s */
419 extern MARK	v_lshift();	/* < */
420 extern MARK	v_rshift();	/* > */
421 extern MARK	v_filter();	/* ! */
422 extern MARK	v_status();	/* ^G */
423 extern MARK	v_switch();	/* ^^ */
424 extern MARK	v_tag();	/* ^] */
425 #ifndef NO_EXTENSIONS
426 extern MARK	v_keyword();	/* ^K */
427 extern MARK	v_increment();	/* * */
428 #endif
429 extern MARK	v_xit();	/* ZZ */
430 extern MARK	v_undoline();	/* U */
431 
432 /*----------------------------------------------------------------------*/
433 /* These describe what mode we're in */
434 
435 #define MODE_EX		1	/* executing ex commands */
436 #define	MODE_VI		2	/* executing vi commands */
437 #define	MODE_COLON	3	/* executing an ex command from vi mode */
438 #define	MODE_QUIT	4
439 extern int	mode;
440 
441 #define WHEN_VICMD	1	/* getkey: we're reading a VI command */
442 #define WHEN_VIINP	2	/* getkey: we're in VI's INPUT mode */
443 #define WHEN_VIREP	4	/* getkey: we're in VI's REPLACE mode */
444 #define WHEN_EX		8	/* getkey: we're in EX mode */
445 #define WHEN_INMV	256	/* in input mode, interpret the key in VICMD mode */
446