xref: /freebsd/contrib/nvi/common/key.h (revision 6680e5a52f8abf059bbbd3e0be66d9dce476cdf9)
1b8ba871bSPeter Wemm /*-
2b8ba871bSPeter Wemm  * Copyright (c) 1991, 1993, 1994
3b8ba871bSPeter Wemm  *	The Regents of the University of California.  All rights reserved.
4b8ba871bSPeter Wemm  * Copyright (c) 1991, 1993, 1994, 1995, 1996
5b8ba871bSPeter Wemm  *	Keith Bostic.  All rights reserved.
6b8ba871bSPeter Wemm  *
7b8ba871bSPeter Wemm  * See the LICENSE file for redistribution information.
8b8ba871bSPeter Wemm  */
9b8ba871bSPeter Wemm 
10f0957ccaSPeter Wemm #include "multibyte.h"
11f0957ccaSPeter Wemm 
12f0957ccaSPeter Wemm #ifdef USE_WIDECHAR
13f0957ccaSPeter Wemm #define FILE2INT5(sp,buf,n,nlen,w,wlen)					    \
14f0957ccaSPeter Wemm     sp->conv.file2int(sp, n, nlen, &buf, &wlen, &w)
15f0957ccaSPeter Wemm #define INT2FILE(sp,w,wlen,n,nlen) 					    \
16f0957ccaSPeter Wemm     sp->conv.int2file(sp, w, wlen, &sp->cw, &nlen, &n)
17f0957ccaSPeter Wemm #define CHAR2INT5(sp,buf,n,nlen,w,wlen)					    \
18f0957ccaSPeter Wemm     sp->conv.sys2int(sp, n, nlen, &buf, &wlen, &w)
19f0957ccaSPeter Wemm #define INT2CHAR(sp,w,wlen,n,nlen) 					    \
20f0957ccaSPeter Wemm     sp->conv.int2sys(sp, w, wlen, &sp->cw, &nlen, &n)
21f0957ccaSPeter Wemm #define INPUT2INT5(sp,cw,n,nlen,w,wlen)					    \
22f0957ccaSPeter Wemm     sp->conv.input2int(sp, n, nlen, &(cw), &wlen, &w)
23f0957ccaSPeter Wemm #define CONST
24f0957ccaSPeter Wemm #define INTISWIDE(c)        (wctob(c) == EOF)
25*6680e5a5SBaptiste Daroussin #define XCHAR_WIDTH(sp, ch) wcwidth(ch)
26*6680e5a5SBaptiste Daroussin #define CAN_PRINT(sp, ch)   (XCHAR_WIDTH(sp, ch) > 0)
27f0957ccaSPeter Wemm #else
28f0957ccaSPeter Wemm #define FILE2INT5(sp,buf,n,nlen,w,wlen) \
29f0957ccaSPeter Wemm     (w = n, wlen = nlen, 0)
30f0957ccaSPeter Wemm #define INT2FILE(sp,w,wlen,n,nlen) \
31f0957ccaSPeter Wemm     (n = w, nlen = wlen, 0)
32f0957ccaSPeter Wemm #define CHAR2INT5(sp,buf,n,nlen,w,wlen) \
33f0957ccaSPeter Wemm     (w = n, wlen = nlen, 0)
34f0957ccaSPeter Wemm #define INT2CHAR(sp,w,wlen,n,nlen) \
35f0957ccaSPeter Wemm     (n = w, nlen = wlen, 0)
36f0957ccaSPeter Wemm #define INPUT2INT5(sp,buf,n,nlen,w,wlen) \
37f0957ccaSPeter Wemm     (w = n, wlen = nlen, 0)
38f0957ccaSPeter Wemm #define CONST               const
39f0957ccaSPeter Wemm #define INTISWIDE(c)        0
40*6680e5a5SBaptiste Daroussin #define XCHAR_WIDTH(sp, ch) 1
4137d5a7cdSPeter Wemm #define CAN_PRINT(sp, ch)   isprint(ch)
42f0957ccaSPeter Wemm #endif
43f0957ccaSPeter Wemm #define FILE2INT(sp,n,nlen,w,wlen)					    \
44f0957ccaSPeter Wemm     FILE2INT5(sp,sp->cw,n,nlen,w,wlen)
45f0957ccaSPeter Wemm #define CHAR2INT(sp,n,nlen,w,wlen)					    \
46f0957ccaSPeter Wemm     CHAR2INT5(sp,sp->cw,n,nlen,w,wlen)
47b8ba871bSPeter Wemm 
48b8ba871bSPeter Wemm /* The maximum number of columns any character can take up on a screen. */
49f0957ccaSPeter Wemm #define	MAX_CHARACTER_COLUMNS	7
50b8ba871bSPeter Wemm 
51b8ba871bSPeter Wemm /*
52b8ba871bSPeter Wemm  * Event types.
53b8ba871bSPeter Wemm  *
54b8ba871bSPeter Wemm  * The program structure depends on the event loop being able to return
55b8ba871bSPeter Wemm  * E_EOF/E_ERR multiple times -- eventually enough things will end due
56b8ba871bSPeter Wemm  * to the events that vi will reach the command level for the screen, at
57b8ba871bSPeter Wemm  * which point the exit flags will be set and vi will exit.
58b8ba871bSPeter Wemm  */
59b8ba871bSPeter Wemm typedef enum {
60b8ba871bSPeter Wemm 	E_NOTUSED = 0,			/* Not set. */
61b8ba871bSPeter Wemm 	E_CHARACTER,			/* Input character: e_c set. */
62b8ba871bSPeter Wemm 	E_EOF,				/* End of input (NOT ^D). */
63b8ba871bSPeter Wemm 	E_ERR,				/* Input error. */
64b8ba871bSPeter Wemm 	E_INTERRUPT,			/* Interrupt. */
65b8ba871bSPeter Wemm 	E_REPAINT,			/* Repaint: e_flno, e_tlno set. */
66b8ba871bSPeter Wemm 	E_SIGHUP,			/* SIGHUP. */
67b8ba871bSPeter Wemm 	E_SIGTERM,			/* SIGTERM. */
68b8ba871bSPeter Wemm 	E_STRING,			/* Input string: e_csp, e_len set. */
69b8ba871bSPeter Wemm 	E_TIMEOUT,			/* Timeout. */
70b8ba871bSPeter Wemm 	E_WRESIZE,			/* Window resize. */
71b8ba871bSPeter Wemm } e_event_t;
72b8ba871bSPeter Wemm 
73b8ba871bSPeter Wemm /*
74b8ba871bSPeter Wemm  * Character values.
75b8ba871bSPeter Wemm  */
76b8ba871bSPeter Wemm typedef enum {
77b8ba871bSPeter Wemm 	K_NOTUSED = 0,			/* Not set. */
78b8ba871bSPeter Wemm 	K_BACKSLASH,			/*  \ */
79b8ba871bSPeter Wemm 	K_CARAT,			/*  ^ */
80b8ba871bSPeter Wemm 	K_CNTRLD,			/* ^D */
81b8ba871bSPeter Wemm 	K_CNTRLR,			/* ^R */
82b8ba871bSPeter Wemm 	K_CNTRLT,			/* ^T */
83b8ba871bSPeter Wemm 	K_CNTRLZ,			/* ^Z */
84b8ba871bSPeter Wemm 	K_COLON,			/*  : */
85b8ba871bSPeter Wemm 	K_CR,				/* \r */
86b8ba871bSPeter Wemm 	K_ESCAPE,			/* ^[ */
87b8ba871bSPeter Wemm 	K_FORMFEED,			/* \f */
88b8ba871bSPeter Wemm 	K_HEXCHAR,			/* ^X */
89b8ba871bSPeter Wemm 	K_NL,				/* \n */
90b8ba871bSPeter Wemm 	K_RIGHTBRACE,			/*  } */
91b8ba871bSPeter Wemm 	K_RIGHTPAREN,			/*  ) */
92b8ba871bSPeter Wemm 	K_TAB,				/* \t */
93b8ba871bSPeter Wemm 	K_VERASE,			/* set from tty: default ^H */
94b8ba871bSPeter Wemm 	K_VKILL,			/* set from tty: default ^U */
95b8ba871bSPeter Wemm 	K_VLNEXT,			/* set from tty: default ^V */
96b8ba871bSPeter Wemm 	K_VWERASE,			/* set from tty: default ^W */
97b8ba871bSPeter Wemm 	K_ZERO				/*  0 */
98b8ba871bSPeter Wemm } e_key_t;
99b8ba871bSPeter Wemm 
100b8ba871bSPeter Wemm struct _event {
101b8ba871bSPeter Wemm 	TAILQ_ENTRY(_event) q;		/* Linked list of events. */
102b8ba871bSPeter Wemm 	e_event_t e_event;		/* Event type. */
103b8ba871bSPeter Wemm 	union {
104b8ba871bSPeter Wemm 		struct {		/* Input character. */
105b8ba871bSPeter Wemm 			CHAR_T c;	/* Character. */
106b8ba871bSPeter Wemm 			e_key_t value;	/* Key type. */
107b8ba871bSPeter Wemm 
108b8ba871bSPeter Wemm #define	CH_ABBREVIATED	0x01		/* Character is from an abbreviation. */
109b8ba871bSPeter Wemm #define	CH_MAPPED	0x02		/* Character is from a map. */
110b8ba871bSPeter Wemm #define	CH_NOMAP	0x04		/* Do not map the character. */
111b8ba871bSPeter Wemm #define	CH_QUOTED	0x08		/* Character is already quoted. */
112b8ba871bSPeter Wemm 			u_int8_t flags;
113b8ba871bSPeter Wemm 		} _e_ch;
114b8ba871bSPeter Wemm #define	e_ch	_u_event._e_ch		/* !!! The structure, not the char. */
115b8ba871bSPeter Wemm #define	e_c	_u_event._e_ch.c
116b8ba871bSPeter Wemm #define	e_value	_u_event._e_ch.value
117b8ba871bSPeter Wemm #define	e_flags	_u_event._e_ch.flags
118b8ba871bSPeter Wemm 
119b8ba871bSPeter Wemm 		struct {		/* Screen position, size. */
120b8ba871bSPeter Wemm 			size_t lno1;	/* Line number. */
121b8ba871bSPeter Wemm 			size_t cno1;	/* Column number. */
122b8ba871bSPeter Wemm 			size_t lno2;	/* Line number. */
123b8ba871bSPeter Wemm 			size_t cno2;	/* Column number. */
124b8ba871bSPeter Wemm 		} _e_mark;
125b8ba871bSPeter Wemm #define	e_lno	_u_event._e_mark.lno1	/* Single location. */
126b8ba871bSPeter Wemm #define	e_cno	_u_event._e_mark.cno1
127b8ba871bSPeter Wemm #define	e_flno	_u_event._e_mark.lno1	/* Text region. */
128b8ba871bSPeter Wemm #define	e_fcno	_u_event._e_mark.cno1
129b8ba871bSPeter Wemm #define	e_tlno	_u_event._e_mark.lno2
130b8ba871bSPeter Wemm #define	e_tcno	_u_event._e_mark.cno2
131b8ba871bSPeter Wemm 
132b8ba871bSPeter Wemm 		struct {		/* Input string. */
133b8ba871bSPeter Wemm 			CHAR_T	*asp;	/* Allocated string. */
134b8ba871bSPeter Wemm 			CHAR_T	*csp;	/* String. */
135b8ba871bSPeter Wemm 			size_t	 len;	/* String length. */
136b8ba871bSPeter Wemm 		} _e_str;
137b8ba871bSPeter Wemm #define	e_asp	_u_event._e_str.asp
138b8ba871bSPeter Wemm #define	e_csp	_u_event._e_str.csp
139b8ba871bSPeter Wemm #define	e_len	_u_event._e_str.len
140b8ba871bSPeter Wemm 	} _u_event;
141b8ba871bSPeter Wemm };
142b8ba871bSPeter Wemm 
143b8ba871bSPeter Wemm typedef struct _keylist {
144b8ba871bSPeter Wemm 	e_key_t value;			/* Special value. */
145f0957ccaSPeter Wemm 	int	ch;			/* Key. */
146b8ba871bSPeter Wemm } KEYLIST;
147b8ba871bSPeter Wemm extern KEYLIST keylist[];
148b8ba871bSPeter Wemm 
149b8ba871bSPeter Wemm 					/* Return if more keys in queue. */
150b8ba871bSPeter Wemm #define	KEYS_WAITING(sp)	((sp)->gp->i_cnt != 0)
151b8ba871bSPeter Wemm #define	MAPPED_KEYS_WAITING(sp)						\
152b8ba871bSPeter Wemm 	(KEYS_WAITING(sp) &&						\
153b8ba871bSPeter Wemm 	    F_ISSET(&sp->gp->i_event[sp->gp->i_next].e_ch, CH_MAPPED))
154b8ba871bSPeter Wemm 
155b8ba871bSPeter Wemm /*
156b8ba871bSPeter Wemm  * Ex/vi commands are generally separated by whitespace characters.  We
157b8ba871bSPeter Wemm  * can't use the standard isspace(3) macro because it returns true for
158f0957ccaSPeter Wemm  * characters like ^K in the ASCII character set.  The POSIX isblank(3)
159f0957ccaSPeter Wemm  * has the same problem for non-ASCII locale, so we need a standalone one.
160b8ba871bSPeter Wemm  */
161110d525eSBaptiste Daroussin 
162110d525eSBaptiste Daroussin static __inline int
cmdskip(CHAR_T ch)163110d525eSBaptiste Daroussin cmdskip(CHAR_T ch)
164110d525eSBaptiste Daroussin {
165110d525eSBaptiste Daroussin 	return ch == ' ' || ch == '\t';
166110d525eSBaptiste Daroussin }
167b8ba871bSPeter Wemm 
168b8ba871bSPeter Wemm /* The "standard" tab width, for displaying things to users. */
169b8ba871bSPeter Wemm #define	STANDARD_TAB	6
170b8ba871bSPeter Wemm 
171b8ba871bSPeter Wemm /* Various special characters, messages. */
172b8ba871bSPeter Wemm #define	CH_BSEARCH	'?'		/* Backward search prompt. */
173b8ba871bSPeter Wemm #define	CH_CURSOR	' '		/* Cursor character. */
174b8ba871bSPeter Wemm #define	CH_ENDMARK	'$'		/* End of a range. */
175b8ba871bSPeter Wemm #define	CH_EXPROMPT	':'		/* Ex prompt. */
176b8ba871bSPeter Wemm #define	CH_FSEARCH	'/'		/* Forward search prompt. */
177b8ba871bSPeter Wemm #define	CH_HEX		'\030'		/* Leading hex character. */
178b8ba871bSPeter Wemm #define	CH_LITERAL	'\026'		/* ASCII ^V. */
179b8ba871bSPeter Wemm #define	CH_NO		'n'		/* No. */
180b8ba871bSPeter Wemm #define	CH_NOT_DIGIT	'a'		/* A non-isdigit() character. */
181b8ba871bSPeter Wemm #define	CH_QUIT		'q'		/* Quit. */
182b8ba871bSPeter Wemm #define	CH_YES		'y'		/* Yes. */
183b8ba871bSPeter Wemm 
184b8ba871bSPeter Wemm /*
185b8ba871bSPeter Wemm  * Checking for interrupts means that we look at the bit that gets set if the
186b8ba871bSPeter Wemm  * screen code supports asynchronous events, and call back into the event code
187b8ba871bSPeter Wemm  * so that non-asynchronous screens get a chance to post the interrupt.
188b8ba871bSPeter Wemm  *
189b8ba871bSPeter Wemm  * INTERRUPT_CHECK is the number of lines "operated" on before checking for
190b8ba871bSPeter Wemm  * interrupts.
191b8ba871bSPeter Wemm  */
192b8ba871bSPeter Wemm #define	INTERRUPT_CHECK	100
193b8ba871bSPeter Wemm #define	INTERRUPTED(sp)							\
194b8ba871bSPeter Wemm 	(F_ISSET((sp)->gp, G_INTERRUPTED) ||				\
195b8ba871bSPeter Wemm 	(!v_event_get(sp, NULL, 0, EC_INTERRUPT) &&			\
196b8ba871bSPeter Wemm 	F_ISSET((sp)->gp, G_INTERRUPTED)))
197b8ba871bSPeter Wemm #define	CLR_INTERRUPT(sp)						\
198b8ba871bSPeter Wemm 	F_CLR((sp)->gp, G_INTERRUPTED)
199b8ba871bSPeter Wemm 
200b8ba871bSPeter Wemm /* Flags describing types of characters being requested. */
201b8ba871bSPeter Wemm #define	EC_INTERRUPT	0x001		/* Checking for interrupts. */
202b8ba871bSPeter Wemm #define	EC_MAPCOMMAND	0x002		/* Apply the command map. */
203b8ba871bSPeter Wemm #define	EC_MAPINPUT	0x004		/* Apply the input map. */
204b8ba871bSPeter Wemm #define	EC_MAPNODIGIT	0x008		/* Return to a digit. */
205b8ba871bSPeter Wemm #define	EC_QUOTED	0x010		/* Try to quote next character */
206b8ba871bSPeter Wemm #define	EC_RAW		0x020		/* Any next character. XXX: not used. */
207b8ba871bSPeter Wemm #define	EC_TIMEOUT	0x040		/* Timeout to next character. */
208b8ba871bSPeter Wemm 
209b8ba871bSPeter Wemm /* Flags describing text input special cases. */
210b8ba871bSPeter Wemm #define	TXT_ADDNEWLINE	0x00000001	/* Replay starts on a new line. */
211b8ba871bSPeter Wemm #define	TXT_AICHARS	0x00000002	/* Leading autoindent chars. */
212b8ba871bSPeter Wemm #define	TXT_ALTWERASE	0x00000004	/* Option: altwerase. */
213b8ba871bSPeter Wemm #define	TXT_APPENDEOL	0x00000008	/* Appending after EOL. */
214b8ba871bSPeter Wemm #define	TXT_AUTOINDENT	0x00000010	/* Autoindent set this line. */
215b8ba871bSPeter Wemm #define	TXT_BACKSLASH	0x00000020	/* Backslashes escape characters. */
216b8ba871bSPeter Wemm #define	TXT_BEAUTIFY	0x00000040	/* Only printable characters. */
217b8ba871bSPeter Wemm #define	TXT_BS		0x00000080	/* Backspace returns the buffer. */
218b8ba871bSPeter Wemm #define	TXT_CEDIT	0x00000100	/* Can return TERM_CEDIT. */
219b8ba871bSPeter Wemm #define	TXT_CNTRLD	0x00000200	/* Control-D is a command. */
220b8ba871bSPeter Wemm #define	TXT_CNTRLT	0x00000400	/* Control-T is an indent special. */
221b8ba871bSPeter Wemm #define	TXT_CR		0x00000800	/* CR returns the buffer. */
222b8ba871bSPeter Wemm #define	TXT_DOTTERM	0x00001000	/* Leading '.' terminates the input. */
223b8ba871bSPeter Wemm #define	TXT_EMARK	0x00002000	/* End of replacement mark. */
224b8ba871bSPeter Wemm #define	TXT_EOFCHAR	0x00004000	/* ICANON set, return EOF character. */
225b8ba871bSPeter Wemm #define	TXT_ESCAPE	0x00008000	/* Escape returns the buffer. */
226b8ba871bSPeter Wemm #define	TXT_FILEC	0x00010000	/* Option: filec. */
227b8ba871bSPeter Wemm #define	TXT_INFOLINE	0x00020000	/* Editing the info line. */
228b8ba871bSPeter Wemm #define	TXT_MAPINPUT	0x00040000	/* Apply the input map. */
229b8ba871bSPeter Wemm #define	TXT_NLECHO	0x00080000	/* Echo the newline. */
230b8ba871bSPeter Wemm #define	TXT_NUMBER	0x00100000	/* Number the line. */
231b8ba871bSPeter Wemm #define	TXT_OVERWRITE	0x00200000	/* Overwrite characters. */
232b8ba871bSPeter Wemm #define	TXT_PROMPT	0x00400000	/* Display a prompt. */
233b8ba871bSPeter Wemm #define	TXT_RECORD	0x00800000	/* Record for replay. */
234b8ba871bSPeter Wemm #define	TXT_REPLACE	0x01000000	/* Replace; don't delete overwrite. */
235b8ba871bSPeter Wemm #define	TXT_REPLAY	0x02000000	/* Replay the last input. */
236b8ba871bSPeter Wemm #define	TXT_RESOLVE	0x04000000	/* Resolve the text into the file. */
237b8ba871bSPeter Wemm #define	TXT_SEARCHINCR	0x08000000	/* Incremental search. */
238b8ba871bSPeter Wemm #define	TXT_SHOWMATCH	0x10000000	/* Option: showmatch. */
239b8ba871bSPeter Wemm #define	TXT_TTYWERASE	0x20000000	/* Option: ttywerase. */
240b8ba871bSPeter Wemm #define	TXT_WRAPMARGIN	0x40000000	/* Option: wrapmargin. */
241