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