2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
9 static char sccsid
[] = "$Id: key.c,v 8.25 1993/11/27 15:52:11 bostic Exp $ (Berkeley) $Date: 1993/11/27 15:52:11 $";
12 #include <sys/types.h>
26 * There are two sets of input buffers used by ex/vi. The first is the input
27 * from the user, either via the tty or an initial command supplied with the
28 * ex or edit commands or similar mechanism. The second is the the keys from
29 * the first after mapping has been done. Also, executable buffer expansions
30 * are pushed into this second buffer. The reason that there are two is that
31 * we only want to flush the latter buffer if a command fails, i.e. if the user
32 * enters "@a1G", we don't want to flush the "1G" keys because "@a" failed.
35 typedef struct _klist
{
36 char *ts
; /* Key's termcap string. */
37 char *output
; /* Corresponding vi command. */
38 char *name
; /* Name. */
41 static KLIST
const klist
[] = {
42 {"kA", "O", "insert line"},
43 {"kD", "x", "delete character"},
44 {"kd", "j", "cursor down"},
45 {"kE", "D", "delete to eol"},
46 {"kF", "\004", "scroll down"},
47 {"kH", "$", "go to eol"},
48 {"kh", "^", "go to sol"},
49 {"kI", "i", "insert at cursor"},
50 {"kL", "dd", "delete line"},
51 {"kl", "h", "cursor left"},
52 {"kN", "\006", "page down"},
53 {"kP", "\002", "page up"},
54 {"kR", "\025", "scroll up"},
55 {"kS", "dG", "delete to end of screen"},
56 {"kr", "l", "cursor right"},
57 {"ku", "k", "cursor up"},
63 * Initialize the special array and special keys. The special array
64 * has a value for each special character that we can use in a switch
73 char *sbp
, *t
, buf
[2 * 1024], sbuf
[128];
75 /* Keys that are treated specially. */
76 sp
->special
['^'] = K_CARAT
;
77 sp
->special
['\022'] = K_CNTRLR
;
78 sp
->special
['\024'] = K_CNTRLT
;
79 sp
->special
['\032'] = K_CNTRLZ
;
80 sp
->special
[':'] = K_COLON
;
81 sp
->special
['\r'] = K_CR
;
82 sp
->special
['\033'] = K_ESCAPE
;
83 sp
->special
['\f'] = K_FORMFEED
;
84 sp
->special
['\n'] = K_NL
;
85 sp
->special
[')'] = K_RIGHTPAREN
;
86 sp
->special
['}'] = K_RIGHTBRACE
;
87 sp
->special
['\t'] = K_TAB
;
88 if ((ch
= sp
->gp
->original_termios
.c_cc
[VEOF
]) == _POSIX_VDISABLE
)
90 sp
->special
[ch
] = K_VEOF
;
91 if ((ch
= sp
->gp
->original_termios
.c_cc
[VERASE
]) == _POSIX_VDISABLE
)
93 sp
->special
[ch
] = K_VERASE
;
94 if ((ch
= sp
->gp
->original_termios
.c_cc
[VKILL
]) == _POSIX_VDISABLE
)
96 sp
->special
[ch
] = K_VKILL
;
97 if ((ch
= sp
->gp
->original_termios
.c_cc
[VLNEXT
]) == _POSIX_VDISABLE
)
99 sp
->special
[ch
] = K_VLNEXT
;
100 if ((ch
= sp
->gp
->original_termios
.c_cc
[VWERASE
]) == _POSIX_VDISABLE
)
102 sp
->special
[ch
] = K_VWERASE
;
103 sp
->special
['0'] = K_ZERO
;
105 /* Special terminal keys, from the termcap entry. */
106 switch (tgetent(buf
, O_STR(sp
, O_TERM
))) {
108 msgq(sp
, M_ERR
, "%s tgetent: %s.",
109 O_STR(sp
, O_TERM
), strerror(errno
));
112 msgq(sp
, M_ERR
, "%s: unknown terminal type.",
113 O_STR(sp
, O_TERM
), strerror(errno
));
117 for (kp
= klist
; kp
->name
!= NULL
; ++kp
) {
119 if ((t
= tgetstr(kp
->ts
, &sbp
)) == NULL
)
121 if (seq_set(sp
, kp
->name
, t
, kp
->output
, SEQ_COMMAND
, 0))
129 * Push keys onto the front of a buffer.
132 term_push(sp
, ibp
, s
, len
)
140 /* If we have room, stuff the keys into the buffer. */
141 if (len
<= ibp
->next
) {
144 memmove(ibp
->buf
+ ibp
->next
, s
, len
);
148 /* Get enough space plus a little extra. */
149 nlen
= ibp
->cnt
+ len
;
150 BINC(sp
, ibp
->buf
, ibp
->len
, nlen
+ 64);
153 * If there is currently characters in the buffer,
154 * shift them up, and leave a little extra room.
156 #define TERM_PUSH_SHIFT 20
158 memmove(ibp
->buf
+ len
+ TERM_PUSH_SHIFT
,
159 ibp
->buf
+ ibp
->next
, ibp
->cnt
);
161 ibp
->buf
[TERM_PUSH_SHIFT
] = *s
;
163 memmove(ibp
->buf
+ TERM_PUSH_SHIFT
, s
, len
);
164 ibp
->next
= TERM_PUSH_SHIFT
;
169 /* Remove characters from a queue. */
170 #define QREM(q, len) { \
171 if (((q)->cnt -= len) == 0) \
182 * The flag TXT_MAPNODIGIT probably needs some explanation. First, the idea
183 * of mapping keys is that one or more keystrokes behave like a function key.
184 * What's going on is that vi is reading a number, and the character following
185 * the number may or may not be mapped (TXT_MAPCOMMAND). For example, if the
186 * user is entering the z command, a valid command is "z40+", and we don't want
187 * to map the '+', i.e. if '+' is mapped to "xxx", we don't want to change it
188 * into "z40xxx". However, if the user is entering "35x", we want to put all
189 * of the characters through the mapping code.
191 * Historical practice is a bit muddled here. (Surprise!) It always permitted
192 * mapping digits as long as they weren't the first character of the map, e.g.
193 * ":map ^A1 xxx" was okay. It also permitted the mapping of the digits 1-9
194 * (the digit 0 was a special case as it doesn't indicate the start of a count)
195 * as the first character of the map, but then ignored those mappings. While
196 * it's probably stupid to map digits, vi isn't your mother.
198 * The way this works is that the TXT_MAPNODIGIT causes term_key to return the
199 * end-of-digit without "looking" at the next character, i.e. leaving it as the
200 * user entered it. Presumably, the next term_key call will tell us how the
201 * user wants it handled.
203 * There is one more complication. Users might map keys to digits, and, as
204 * it's described above, the commands "map g 1G|d2g" would return the keys
205 * "d2<end-of-digits>1G", when the user probably wanted "d21<end-of-digits>G".
206 * So, if a map starts off with a digit we continue as before, otherwise, we
207 * pretend that we haven't mapped the character and return <end-of-digits>.
209 * Now that that's out of the way, let's talk about Energizer Bunny macros.
210 * It's easy to create macros that expand to a loop, e.g. map x 3x. It's
211 * fairly easy to detect this example, because it's all internal to term_key.
212 * If we're expanding a macro and it gets big enough, at some point we can
213 * assume it's looping and kill it. The examples that are tough are the ones
214 * where the parser is involved, e.g. map x "ayyx"byy. We do an expansion
215 * on 'x', and get "ayyx"byy. We then return the first 4 characters, and then
216 * find the looping macro again. There is no way that we can detect this
217 * without doing a full parse of the command, because the character that might
218 * cause the loop (in this case 'x') may be a literal character, e.g. the map
219 * map x "ayy"xyy"byy is perfectly legal and won't cause a loop.
221 * Historic vi tried to detect looping macros by disallowing obvious cases in
222 * the map command, maps that that ended with the same letter as they started
223 * (which wrongly disallowed map x 'x), and detecting macros that expanded too
224 * many times before keys were returned to the command parser. It didn't get
225 * many of the tricky cases right, however, and it was certainly possible to
226 * create macros that ran forever. Finally, changes made before vi realized
227 * that the macro was recursing were left in place.
229 * We handle the problem by returning no more than MAX_KEYS_WITHOUT_READ keys
230 * without reading from the terminal. If we hit the boundary, we return an
231 * error and flush both terminal buffers. This handles all of the cases, with
232 * the exception of macros that loop without returning a character. We simply
233 * count those cases and error if there are more than MAX_MACRO_EXP expansions.
236 * The final issue is recovery. It would be possible to undo all of the work
237 * that was done by the macro if we entered a record into the log so that we
238 * knew when the macro started, and, in fact, this might be worth doing at some
239 * point. For now we just flush the keys and leave any changes made in place.
242 term_key(sp
, chp
, flags
)
251 int ch
, ispartial
, ml_cnt
, nr
;
253 /* If we have expanded keys, return the next one. */
257 loop
: if (keyp
->cnt
) {
258 ch
= keyp
->buf
[keyp
->next
];
259 if (LF_ISSET(TXT_MAPNODIGIT
) && !isdigit(ch
)) {
268 * Read in more keys if none in the queue. Since no timeout
269 * is requested, s_key_read will either return 1 or will read
270 * some number of characters.
272 if (ttyp
->cnt
== 0) {
274 if (rval
= sp
->s_key_read(sp
, &nr
, 0))
277 * If there's something on the mode line that we wanted
278 * the user to see, they just entered a character so we
279 * can presume they saw it. Clear the bit before doing
280 * the refresh, the refresh routine is probably checking.
282 if (F_ISSET(sp
, S_UPDATE_MODE
)) {
283 F_CLR(sp
, S_UPDATE_MODE
);
284 if (sp
->s_refresh(sp
, sp
->ep
))
289 /* Check for mapped keys. */
290 if (LF_ISSET(TXT_MAPCOMMAND
| TXT_MAPINPUT
)) {
292 newmap
: ch
= ttyp
->buf
[ttyp
->next
];
293 if (ch
< MAX_BIT_SEQ
&& !bit_test(gp
->seqb
, ch
))
295 remap
: qp
= seq_find(sp
, NULL
, &ttyp
->buf
[ttyp
->next
], ttyp
->cnt
,
296 LF_ISSET(TXT_MAPCOMMAND
) ? SEQ_COMMAND
: SEQ_INPUT
,
299 /* If get a partial match, keep trying. */
301 if (rval
= sp
->s_key_read(sp
, &nr
, 1))
311 #define MAX_MACRO_EXP 40
312 if (++ml_cnt
> MAX_MACRO_EXP
)
315 if (LF_ISSET(TXT_MAPNODIGIT
) && !isdigit(qp
->output
[0])) {
320 QREM(ttyp
, qp
->ilen
);
321 if (O_ISSET(sp
, O_REMAP
)) {
322 if (term_push(sp
, ttyp
, qp
->output
, qp
->olen
))
326 if (term_push(sp
, keyp
, qp
->output
, qp
->olen
)) {
327 err
: msgq(sp
, M_SYSERR
, "Error: key deleted");
333 nomap
: ch
= ttyp
->buf
[ttyp
->next
];
334 if (LF_ISSET(TXT_MAPNODIGIT
) && !isdigit(ch
)) {
340 #define MAX_KEYS_WITHOUT_READ 1000
341 ret
: if (++gp
->key_cnt
> MAX_KEYS_WITHOUT_READ
) {
342 rec_err
: gp
->key_cnt
= 0;
346 "Error: command expansion too long; keys flushed.");
351 * O_BEAUTIFY eliminates all control characters except
352 * escape, form-feed, newline and tab.
354 if (LF_ISSET(TXT_BEAUTIFY
) && O_ISSET(sp
, O_BEAUTIFY
)) {
356 sp
->special
[ch
] == K_ESCAPE
||
357 sp
->special
[ch
] == K_FORMFEED
||
358 sp
->special
[ch
] == K_NL
||
359 sp
->special
[ch
] == K_TAB
) {