source: trunk/third/nvi/common/key.c @ 14302

Revision 14302, 23.7 KB checked in by ghudson, 25 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14301, which included commits to RCS files with non-trunk default branches.
Line 
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 "config.h"
11
12#ifndef lint
13static const char sccsid[] = "@(#)key.c 10.33 (Berkeley) 9/24/96";
14#endif /* not lint */
15
16#include <sys/types.h>
17#include <sys/queue.h>
18#include <sys/time.h>
19
20#include <bitstring.h>
21#include <ctype.h>
22#include <errno.h>
23#include <limits.h>
24#include <locale.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <unistd.h>
29
30#include "common.h"
31#include "../vi/vi.h"
32
33static int      v_event_append __P((SCR *, EVENT *));
34static int      v_event_grow __P((SCR *, int));
35static int      v_key_cmp __P((const void *, const void *));
36static void     v_keyval __P((SCR *, int, scr_keyval_t));
37static void     v_sync __P((SCR *, int));
38
39/*
40 * !!!
41 * Historic vi always used:
42 *
43 *      ^D: autoindent deletion
44 *      ^H: last character deletion
45 *      ^W: last word deletion
46 *      ^Q: quote the next character (if not used in flow control).
47 *      ^V: quote the next character
48 *
49 * regardless of the user's choices for these characters.  The user's erase
50 * and kill characters worked in addition to these characters.  Nvi wires
51 * down the above characters, but in addition permits the VEOF, VERASE, VKILL
52 * and VWERASE characters described by the user's termios structure.
53 *
54 * Ex was not consistent with this scheme, as it historically ran in tty
55 * cooked mode.  This meant that the scroll command and autoindent erase
56 * characters were mapped to the user's EOF character, and the character
57 * and word deletion characters were the user's tty character and word
58 * deletion characters.  This implementation makes it all consistent, as
59 * described above for vi.
60 *
61 * !!!
62 * This means that all screens share a special key set.
63 */
64KEYLIST keylist[] = {
65        {K_BACKSLASH,     '\\'},        /*  \ */
66        {K_CARAT,          '^'},        /*  ^ */
67        {K_CNTRLD,      '\004'},        /* ^D */
68        {K_CNTRLR,      '\022'},        /* ^R */
69        {K_CNTRLT,      '\024'},        /* ^T */
70        {K_CNTRLZ,      '\032'},        /* ^Z */
71        {K_COLON,          ':'},        /*  : */
72        {K_CR,            '\r'},        /* \r */
73        {K_ESCAPE,      '\033'},        /* ^[ */
74        {K_FORMFEED,      '\f'},        /* \f */
75        {K_HEXCHAR,     '\030'},        /* ^X */
76        {K_NL,            '\n'},        /* \n */
77        {K_RIGHTBRACE,     '}'},        /*  } */
78        {K_RIGHTPAREN,     ')'},        /*  ) */
79        {K_TAB,           '\t'},        /* \t */
80        {K_VERASE,        '\b'},        /* \b */
81        {K_VKILL,       '\025'},        /* ^U */
82        {K_VLNEXT,      '\021'},        /* ^Q */
83        {K_VLNEXT,      '\026'},        /* ^V */
84        {K_VWERASE,     '\027'},        /* ^W */
85        {K_ZERO,           '0'},        /*  0 */
86
87#define ADDITIONAL_CHARACTERS   4
88        {K_NOTUSED, 0},                 /* VEOF, VERASE, VKILL, VWERASE */
89        {K_NOTUSED, 0},
90        {K_NOTUSED, 0},
91        {K_NOTUSED, 0},
92};
93static int nkeylist =
94    (sizeof(keylist) / sizeof(keylist[0])) - ADDITIONAL_CHARACTERS;
95
96/*
97 * v_key_init --
98 *      Initialize the special key lookup table.
99 *
100 * PUBLIC: int v_key_init __P((SCR *));
101 */
102int
103v_key_init(sp)
104        SCR *sp;
105{
106        CHAR_T ch;
107        GS *gp;
108        KEYLIST *kp;
109        int cnt;
110
111        gp = sp->gp;
112
113        /*
114         * XXX
115         * 8-bit only, for now.  Recompilation should get you any 8-bit
116         * character set, as long as nul isn't a character.
117         */
118        (void)setlocale(LC_ALL, "");
119#if __linux__
120        /*
121         * In libc 4.5.26, setlocale(LC_ALL, ""), doesn't setup the table
122         * for ctype(3c) correctly.  This bug is fixed in libc 4.6.x.
123         *
124         * This code works around this problem for libc 4.5.x users.
125         * Note that this code is harmless if you're using libc 4.6.x.
126         */
127        (void)setlocale(LC_CTYPE, "");
128#endif
129        v_key_ilookup(sp);
130
131        v_keyval(sp, K_CNTRLD, KEY_VEOF);
132        v_keyval(sp, K_VERASE, KEY_VERASE);
133        v_keyval(sp, K_VKILL, KEY_VKILL);
134        v_keyval(sp, K_VWERASE, KEY_VWERASE);
135
136        /* Sort the special key list. */
137        qsort(keylist, nkeylist, sizeof(keylist[0]), v_key_cmp);
138
139        /* Initialize the fast lookup table. */
140        for (gp->max_special = 0, kp = keylist, cnt = nkeylist; cnt--; ++kp) {
141                if (gp->max_special < kp->value)
142                        gp->max_special = kp->value;
143                if (kp->ch <= MAX_FAST_KEY)
144                        gp->special_key[kp->ch] = kp->value;
145        }
146
147        /* Find a non-printable character to use as a message separator. */
148        for (ch = 1; ch <= MAX_CHAR_T; ++ch)
149                if (!isprint(ch)) {
150                        gp->noprint = ch;
151                        break;
152                }
153        if (ch != gp->noprint) {
154                msgq(sp, M_ERR, "079|No non-printable character found");
155                return (1);
156        }
157        return (0);
158}
159
160/*
161 * v_keyval --
162 *      Set key values.
163 *
164 * We've left some open slots in the keylist table, and if these values exist,
165 * we put them into place.  Note, they may reset (or duplicate) values already
166 * in the table, so we check for that first.
167 */
168static void
169v_keyval(sp, val, name)
170        SCR *sp;
171        int val;
172        scr_keyval_t name;
173{
174        KEYLIST *kp;
175        CHAR_T ch;
176        int dne;
177
178        /* Get the key's value from the screen. */
179        if (sp->gp->scr_keyval(sp, name, &ch, &dne))
180                return;
181        if (dne)
182                return;
183
184        /* Check for duplication. */
185        for (kp = keylist; kp->value != K_NOTUSED; ++kp)
186                if (kp->ch == ch) {
187                        kp->value = val;
188                        return;
189                }
190
191        /* Add a new entry. */
192        if (kp->value == K_NOTUSED) {
193                keylist[nkeylist].ch = ch;
194                keylist[nkeylist].value = val;
195                ++nkeylist;
196        }
197}
198
199/*
200 * v_key_ilookup --
201 *      Build the fast-lookup key display array.
202 *
203 * PUBLIC: void v_key_ilookup __P((SCR *));
204 */
205void
206v_key_ilookup(sp)
207        SCR *sp;
208{
209        CHAR_T ch, *p, *t;
210        GS *gp;
211        size_t len;
212
213        for (gp = sp->gp, ch = 0; ch <= MAX_FAST_KEY; ++ch)
214                for (p = gp->cname[ch].name, t = v_key_name(sp, ch),
215                    len = gp->cname[ch].len = sp->clen; len--;)
216                        *p++ = *t++;
217}
218
219/*
220 * v_key_len --
221 *      Return the length of the string that will display the key.
222 *      This routine is the backup for the KEY_LEN() macro.
223 *
224 * PUBLIC: size_t v_key_len __P((SCR *, ARG_CHAR_T));
225 */
226size_t
227v_key_len(sp, ch)
228        SCR *sp;
229        ARG_CHAR_T ch;
230{
231        (void)v_key_name(sp, ch);
232        return (sp->clen);
233}
234
235/*
236 * v_key_name --
237 *      Return the string that will display the key.  This routine
238 *      is the backup for the KEY_NAME() macro.
239 *
240 * PUBLIC: CHAR_T *v_key_name __P((SCR *, ARG_CHAR_T));
241 */
242CHAR_T *
243v_key_name(sp, ach)
244        SCR *sp;
245        ARG_CHAR_T ach;
246{
247        static const CHAR_T hexdigit[] = "0123456789abcdef";
248        static const CHAR_T octdigit[] = "01234567";
249        CHAR_T ch, *chp, mask;
250        size_t len;
251        int cnt, shift;
252
253        ch = ach;
254
255        /* See if the character was explicitly declared printable or not. */
256        if ((chp = O_STR(sp, O_PRINT)) != NULL)
257                for (; *chp != '\0'; ++chp)
258                        if (*chp == ch)
259                                goto pr;
260        if ((chp = O_STR(sp, O_NOPRINT)) != NULL)
261                for (; *chp != '\0'; ++chp)
262                        if (*chp == ch)
263                                goto nopr;
264
265        /*
266         * Historical (ARPA standard) mappings.  Printable characters are left
267         * alone.  Control characters less than 0x20 are represented as '^'
268         * followed by the character offset from the '@' character in the ASCII
269         * character set.  Del (0x7f) is represented as '^' followed by '?'.
270         *
271         * XXX
272         * The following code depends on the current locale being identical to
273         * the ASCII map from 0x40 to 0x5f (since 0x1f + 0x40 == 0x5f).  I'm
274         * told that this is a reasonable assumption...
275         *
276         * XXX
277         * This code will only work with CHAR_T's that are multiples of 8-bit
278         * bytes.
279         *
280         * XXX
281         * NB: There's an assumption here that all printable characters take
282         * up a single column on the screen.  This is not always correct.
283         */
284        if (isprint(ch)) {
285pr:             sp->cname[0] = ch;
286                len = 1;
287                goto done;
288        }
289nopr:   if (iscntrl(ch) && (ch < 0x20 || ch == 0x7f)) {
290                sp->cname[0] = '^';
291                sp->cname[1] = ch == 0x7f ? '?' : '@' + ch;
292                len = 2;
293        } else if (O_ISSET(sp, O_OCTAL)) {
294#define BITS    (sizeof(CHAR_T) * 8)
295#define SHIFT   (BITS - BITS % 3)
296#define TOPMASK (BITS % 3 == 2 ? 3 : 1) << (BITS - BITS % 3)
297                sp->cname[0] = '\\';
298                sp->cname[1] = octdigit[(ch & TOPMASK) >> SHIFT];
299                shift = SHIFT - 3;
300                for (len = 2, mask = 7 << (SHIFT - 3),
301                    cnt = BITS / 3; cnt-- > 0; mask >>= 3, shift -= 3)
302                        sp->cname[len++] = octdigit[(ch & mask) >> shift];
303        } else {
304                sp->cname[0] = '\\';
305                sp->cname[1] = 'x';
306                for (len = 2, chp = (u_int8_t *)&ch,
307                    cnt = sizeof(CHAR_T); cnt-- > 0; ++chp) {
308                        sp->cname[len++] = hexdigit[(*chp & 0xf0) >> 4];
309                        sp->cname[len++] = hexdigit[*chp & 0x0f];
310                }
311        }
312done:   sp->cname[sp->clen = len] = '\0';
313        return (sp->cname);
314}
315
316/*
317 * v_key_val --
318 *      Fill in the value for a key.  This routine is the backup
319 *      for the KEY_VAL() macro.
320 *
321 * PUBLIC: int v_key_val __P((SCR *, ARG_CHAR_T));
322 */
323int
324v_key_val(sp, ch)
325        SCR *sp;
326        ARG_CHAR_T ch;
327{
328        KEYLIST k, *kp;
329
330        k.ch = ch;
331        kp = bsearch(&k, keylist, nkeylist, sizeof(keylist[0]), v_key_cmp);
332        return (kp == NULL ? K_NOTUSED : kp->value);
333}
334
335/*
336 * v_event_push --
337 *      Push events/keys onto the front of the buffer.
338 *
339 * There is a single input buffer in ex/vi.  Characters are put onto the
340 * end of the buffer by the terminal input routines, and pushed onto the
341 * front of the buffer by various other functions in ex/vi.  Each key has
342 * an associated flag value, which indicates if it has already been quoted,
343 * and if it is the result of a mapping or an abbreviation.
344 *
345 * PUBLIC: int v_event_push __P((SCR *, EVENT *, CHAR_T *, size_t, u_int));
346 */
347int
348v_event_push(sp, p_evp, p_s, nitems, flags)
349        SCR *sp;
350        EVENT *p_evp;                   /* Push event. */
351        CHAR_T *p_s;                    /* Push characters. */
352        size_t nitems;                  /* Number of items to push. */
353        u_int flags;                    /* CH_* flags. */
354{
355        EVENT *evp;
356        GS *gp;
357        size_t total;
358
359        /* If we have room, stuff the items into the buffer. */
360        gp = sp->gp;
361        if (nitems <= gp->i_next ||
362            (gp->i_event != NULL && gp->i_cnt == 0 && nitems <= gp->i_nelem)) {
363                if (gp->i_cnt != 0)
364                        gp->i_next -= nitems;
365                goto copy;
366        }
367
368        /*
369         * If there are currently items in the queue, shift them up,
370         * leaving some extra room.  Get enough space plus a little
371         * extra.
372         */
373#define TERM_PUSH_SHIFT 30
374        total = gp->i_cnt + gp->i_next + nitems + TERM_PUSH_SHIFT;
375        if (total >= gp->i_nelem && v_event_grow(sp, MAX(total, 64)))
376                return (1);
377        if (gp->i_cnt)
378                MEMMOVE(gp->i_event + TERM_PUSH_SHIFT + nitems,
379                    gp->i_event + gp->i_next, gp->i_cnt);
380        gp->i_next = TERM_PUSH_SHIFT;
381
382        /* Put the new items into the queue. */
383copy:   gp->i_cnt += nitems;
384        for (evp = gp->i_event + gp->i_next; nitems--; ++evp) {
385                if (p_evp != NULL)
386                        *evp = *p_evp++;
387                else {
388                        evp->e_event = E_CHARACTER;
389                        evp->e_c = *p_s++;
390                        evp->e_value = KEY_VAL(sp, evp->e_c);
391                        F_INIT(&evp->e_ch, flags);
392                }
393        }
394        return (0);
395}
396
397/*
398 * v_event_append --
399 *      Append events onto the tail of the buffer.
400 */
401static int
402v_event_append(sp, argp)
403        SCR *sp;
404        EVENT *argp;
405{
406        CHAR_T *s;                      /* Characters. */
407        EVENT *evp;
408        GS *gp;
409        size_t nevents;                 /* Number of events. */
410
411        /* Grow the buffer as necessary. */
412        nevents = argp->e_event == E_STRING ? argp->e_len : 1;
413        gp = sp->gp;
414        if (gp->i_event == NULL ||
415            nevents > gp->i_nelem - (gp->i_next + gp->i_cnt))
416                v_event_grow(sp, MAX(nevents, 64));
417        evp = gp->i_event + gp->i_next + gp->i_cnt;
418        gp->i_cnt += nevents;
419
420        /* Transform strings of characters into single events. */
421        if (argp->e_event == E_STRING)
422                for (s = argp->e_csp; nevents--; ++evp) {
423                        evp->e_event = E_CHARACTER;
424                        evp->e_c = *s++;
425                        evp->e_value = KEY_VAL(sp, evp->e_c);
426                        evp->e_flags = 0;
427                }
428        else
429                *evp = *argp;
430        return (0);
431}
432
433/* Remove events from the queue. */
434#define QREM(len) {                                                     \
435        if ((gp->i_cnt -= len) == 0)                                    \
436                gp->i_next = 0;                                         \
437        else                                                            \
438                gp->i_next += len;                                      \
439}
440
441/*
442 * v_event_get --
443 *      Return the next event.
444 *
445 * !!!
446 * The flag EC_NODIGIT probably needs some explanation.  First, the idea of
447 * mapping keys is that one or more keystrokes act like a function key.
448 * What's going on is that vi is reading a number, and the character following
449 * the number may or may not be mapped (EC_MAPCOMMAND).  For example, if the
450 * user is entering the z command, a valid command is "z40+", and we don't want
451 * to map the '+', i.e. if '+' is mapped to "xxx", we don't want to change it
452 * into "z40xxx".  However, if the user enters "35x", we want to put all of the
453 * characters through the mapping code.
454 *
455 * Historical practice is a bit muddled here.  (Surprise!)  It always permitted
456 * mapping digits as long as they weren't the first character of the map, e.g.
457 * ":map ^A1 xxx" was okay.  It also permitted the mapping of the digits 1-9
458 * (the digit 0 was a special case as it doesn't indicate the start of a count)
459 * as the first character of the map, but then ignored those mappings.  While
460 * it's probably stupid to map digits, vi isn't your mother.
461 *
462 * The way this works is that the EC_MAPNODIGIT causes term_key to return the
463 * end-of-digit without "looking" at the next character, i.e. leaving it as the
464 * user entered it.  Presumably, the next term_key call will tell us how the
465 * user wants it handled.
466 *
467 * There is one more complication.  Users might map keys to digits, and, as
468 * it's described above, the commands:
469 *
470 *      :map g 1G
471 *      d2g
472 *
473 * would return the keys "d2<end-of-digits>1G", when the user probably wanted
474 * "d21<end-of-digits>G".  So, if a map starts off with a digit we continue as
475 * before, otherwise, we pretend we haven't mapped the character, and return
476 * <end-of-digits>.
477 *
478 * Now that that's out of the way, let's talk about Energizer Bunny macros.
479 * It's easy to create macros that expand to a loop, e.g. map x 3x.  It's
480 * fairly easy to detect this example, because it's all internal to term_key.
481 * If we're expanding a macro and it gets big enough, at some point we can
482 * assume it's looping and kill it.  The examples that are tough are the ones
483 * where the parser is involved, e.g. map x "ayyx"byy.  We do an expansion
484 * on 'x', and get "ayyx"byy.  We then return the first 4 characters, and then
485 * find the looping macro again.  There is no way that we can detect this
486 * without doing a full parse of the command, because the character that might
487 * cause the loop (in this case 'x') may be a literal character, e.g. the map
488 * map x "ayy"xyy"byy is perfectly legal and won't cause a loop.
489 *
490 * Historic vi tried to detect looping macros by disallowing obvious cases in
491 * the map command, maps that that ended with the same letter as they started
492 * (which wrongly disallowed "map x 'x"), and detecting macros that expanded
493 * too many times before keys were returned to the command parser.  It didn't
494 * get many (most?) of the tricky cases right, however, and it was certainly
495 * possible to create macros that ran forever.  And, even if it did figure out
496 * what was going on, the user was usually tossed into ex mode.  Finally, any
497 * changes made before vi realized that the macro was recursing were left in
498 * place.  We recover gracefully, but the only recourse the user has in an
499 * infinite macro loop is to interrupt.
500 *
501 * !!!
502 * It is historic practice that mapping characters to themselves as the first
503 * part of the mapped string was legal, and did not cause infinite loops, i.e.
504 * ":map! { {^M^T" and ":map n nz." were known to work.  The initial, matching
505 * characters were returned instead of being remapped.
506 *
507 * !!!
508 * It is also historic practice that the macro "map ] ]]^" caused a single ]
509 * keypress to behave as the command ]] (the ^ got the map past the vi check
510 * for "tail recursion").  Conversely, the mapping "map n nn^" went recursive.
511 * What happened was that, in the historic vi, maps were expanded as the keys
512 * were retrieved, but not all at once and not centrally.  So, the keypress ]
513 * pushed ]]^ on the stack, and then the first ] from the stack was passed to
514 * the ]] command code.  The ]] command then retrieved a key without entering
515 * the mapping code.  This could bite us anytime a user has a map that depends
516 * on secondary keys NOT being mapped.  I can't see any possible way to make
517 * this work in here without the complete abandonment of Rationality Itself.
518 *
519 * XXX
520 * The final issue is recovery.  It would be possible to undo all of the work
521 * that was done by the macro if we entered a record into the log so that we
522 * knew when the macro started, and, in fact, this might be worth doing at some
523 * point.  Given that this might make the log grow unacceptably (consider that
524 * cursor keys are done with maps), for now we leave any changes made in place.
525 *
526 * PUBLIC: int v_event_get __P((SCR *, EVENT *, int, u_int32_t));
527 */
528int
529v_event_get(sp, argp, timeout, flags)
530        SCR *sp;
531        EVENT *argp;
532        int timeout;
533        u_int32_t flags;
534{
535        EVENT *evp, ev;
536        GS *gp;
537        SEQ *qp;
538        int init_nomap, ispartial, istimeout, remap_cnt;
539
540        gp = sp->gp;
541
542        /* If simply checking for interrupts, argp may be NULL. */
543        if (argp == NULL)
544                argp = &ev;
545
546retry:  istimeout = remap_cnt = 0;
547
548        /*
549         * If the queue isn't empty and we're timing out for characters,
550         * return immediately.
551         */
552        if (gp->i_cnt != 0 && LF_ISSET(EC_TIMEOUT))
553                return (0);
554
555        /*
556         * If the queue is empty, we're checking for interrupts, or we're
557         * timing out for characters, get more events.
558         */
559        if (gp->i_cnt == 0 || LF_ISSET(EC_INTERRUPT | EC_TIMEOUT)) {
560                /*
561                 * If we're reading new characters, check any scripting
562                 * windows for input.
563                 */
564                if (F_ISSET(gp, G_SCRWIN) && sscr_input(sp))
565                        return (1);
566loop:           if (gp->scr_event(sp, argp,
567                    LF_ISSET(EC_INTERRUPT | EC_QUOTED | EC_RAW), timeout))
568                        return (1);
569                switch (argp->e_event) {
570                case E_ERR:
571                case E_SIGHUP:
572                case E_SIGTERM:
573                        /*
574                         * Fatal conditions cause the file to be synced to
575                         * disk immediately.
576                         */
577                        v_sync(sp, RCV_ENDSESSION | RCV_PRESERVE |
578                            (argp->e_event == E_SIGTERM ? 0: RCV_EMAIL));
579                        return (1);
580                case E_TIMEOUT:
581                        istimeout = 1;
582                        break;
583                case E_INTERRUPT:
584                        /* Set the global interrupt flag. */
585                        F_SET(sp->gp, G_INTERRUPTED);
586
587                        /*
588                         * If the caller was interested in interrupts, return
589                         * immediately.
590                         */
591                        if (LF_ISSET(EC_INTERRUPT))
592                                return (0);
593                        goto append;
594                default:
595append:                 if (v_event_append(sp, argp))
596                                return (1);
597                        break;
598                }
599        }
600
601        /*
602         * If the caller was only interested in interrupts or timeouts, return
603         * immediately.  (We may have gotten characters, and that's okay, they
604         * were queued up for later use.)
605         */
606        if (LF_ISSET(EC_INTERRUPT | EC_TIMEOUT))
607                return (0);
608         
609newmap: evp = &gp->i_event[gp->i_next];
610
611        /*
612         * If the next event in the queue isn't a character event, return
613         * it, we're done.
614         */
615        if (evp->e_event != E_CHARACTER) {
616                *argp = *evp;
617                QREM(1);
618                return (0);
619        }
620       
621        /*
622         * If the key isn't mappable because:
623         *
624         *      + ... the timeout has expired
625         *      + ... it's not a mappable key
626         *      + ... neither the command or input map flags are set
627         *      + ... there are no maps that can apply to it
628         *
629         * return it forthwith.
630         */
631        if (istimeout || F_ISSET(&evp->e_ch, CH_NOMAP) ||
632            !LF_ISSET(EC_MAPCOMMAND | EC_MAPINPUT) ||
633            evp->e_c < MAX_BIT_SEQ && !bit_test(gp->seqb, evp->e_c))
634                goto nomap;
635
636        /* Search the map. */
637        qp = seq_find(sp, NULL, evp, NULL, gp->i_cnt,
638            LF_ISSET(EC_MAPCOMMAND) ? SEQ_COMMAND : SEQ_INPUT, &ispartial);
639
640        /*
641         * If get a partial match, get more characters and retry the map.
642         * If time out without further characters, return the characters
643         * unmapped.
644         *
645         * !!!
646         * <escape> characters are a problem.  Cursor keys start with <escape>
647         * characters, so there's almost always a map in place that begins with
648         * an <escape> character.  If we timeout <escape> keys in the same way
649         * that we timeout other keys, the user will get a noticeable pause as
650         * they enter <escape> to terminate input mode.  If key timeout is set
651         * for a slow link, users will get an even longer pause.  Nvi used to
652         * simply timeout <escape> characters at 1/10th of a second, but this
653         * loses over PPP links where the latency is greater than 100Ms.
654         */
655        if (ispartial) {
656                if (O_ISSET(sp, O_TIMEOUT))
657                        timeout = (evp->e_value == K_ESCAPE ?
658                            O_VAL(sp, O_ESCAPETIME) :
659                            O_VAL(sp, O_KEYTIME)) * 100;
660                else
661                        timeout = 0;
662                goto loop;
663        }
664
665        /* If no map, return the character. */
666        if (qp == NULL) {
667nomap:          if (!isdigit(evp->e_c) && LF_ISSET(EC_MAPNODIGIT))
668                        goto not_digit;
669                *argp = *evp;
670                QREM(1);
671                return (0);
672        }
673
674        /*
675         * If looking for the end of a digit string, and the first character
676         * of the map is it, pretend we haven't seen the character.
677         */
678        if (LF_ISSET(EC_MAPNODIGIT) &&
679            qp->output != NULL && !isdigit(qp->output[0])) {
680not_digit:      argp->e_c = CH_NOT_DIGIT;
681                argp->e_value = K_NOTUSED;
682                argp->e_event = E_CHARACTER;
683                F_INIT(&argp->e_ch, 0);
684                return (0);
685        }
686
687        /* Find out if the initial segments are identical. */
688        init_nomap = !e_memcmp(qp->output, &gp->i_event[gp->i_next], qp->ilen);
689
690        /* Delete the mapped characters from the queue. */
691        QREM(qp->ilen);
692
693        /* If keys mapped to nothing, go get more. */
694        if (qp->output == NULL)
695                goto retry;
696
697        /* If remapping characters... */
698        if (O_ISSET(sp, O_REMAP)) {
699                /*
700                 * Periodically check for interrupts.  Always check the first
701                 * time through, because it's possible to set up a map that
702                 * will return a character every time, but will expand to more,
703                 * e.g. "map! a aaaa" will always return a 'a', but we'll never
704                 * get anywhere useful.
705                 */
706                if ((++remap_cnt == 1 || remap_cnt % 10 == 0) &&
707                    (gp->scr_event(sp, &ev,
708                    EC_INTERRUPT, 0) || ev.e_event == E_INTERRUPT)) {
709                        F_SET(sp->gp, G_INTERRUPTED);
710                        argp->e_event = E_INTERRUPT;
711                        return (0);
712                }
713
714                /*
715                 * If an initial part of the characters mapped, they are not
716                 * further remapped -- return the first one.  Push the rest
717                 * of the characters, or all of the characters if no initial
718                 * part mapped, back on the queue.
719                 */
720                if (init_nomap) {
721                        if (v_event_push(sp, NULL, qp->output + qp->ilen,
722                            qp->olen - qp->ilen, CH_MAPPED))
723                                return (1);
724                        if (v_event_push(sp, NULL,
725                            qp->output, qp->ilen, CH_NOMAP | CH_MAPPED))
726                                return (1);
727                        evp = &gp->i_event[gp->i_next];
728                        goto nomap;
729                }
730                if (v_event_push(sp, NULL, qp->output, qp->olen, CH_MAPPED))
731                        return (1);
732                goto newmap;
733        }
734
735        /* Else, push the characters on the queue and return one. */
736        if (v_event_push(sp, NULL, qp->output, qp->olen, CH_MAPPED | CH_NOMAP))
737                return (1);
738
739        goto nomap;
740}
741
742/*
743 * v_sync --
744 *      Walk the screen lists, sync'ing files to their backup copies.
745 */
746static void
747v_sync(sp, flags)
748        SCR *sp;
749        int flags;
750{
751        GS *gp;
752
753        gp = sp->gp;
754        for (sp = gp->dq.cqh_first; sp != (void *)&gp->dq; sp = sp->q.cqe_next)
755                rcv_sync(sp, flags);
756        for (sp = gp->hq.cqh_first; sp != (void *)&gp->hq; sp = sp->q.cqe_next)
757                rcv_sync(sp, flags);
758}
759
760/*
761 * v_event_err --
762 *      Unexpected event.
763 *
764 * PUBLIC: void v_event_err __P((SCR *, EVENT *));
765 */
766void
767v_event_err(sp, evp)
768        SCR *sp;
769        EVENT *evp;
770{
771        switch (evp->e_event) {
772        case E_CHARACTER:
773                msgq(sp, M_ERR, "276|Unexpected character event");
774                break;
775        case E_EOF:
776                msgq(sp, M_ERR, "277|Unexpected end-of-file event");
777                break;
778        case E_INTERRUPT:
779                msgq(sp, M_ERR, "279|Unexpected interrupt event");
780                break;
781        case E_QUIT:
782                msgq(sp, M_ERR, "280|Unexpected quit event");
783                break;
784        case E_REPAINT:
785                msgq(sp, M_ERR, "281|Unexpected repaint event");
786                break;
787        case E_STRING:
788                msgq(sp, M_ERR, "285|Unexpected string event");
789                break;
790        case E_TIMEOUT:
791                msgq(sp, M_ERR, "286|Unexpected timeout event");
792                break;
793        case E_WRESIZE:
794                msgq(sp, M_ERR, "316|Unexpected resize event");
795                break;
796        case E_WRITE:
797                msgq(sp, M_ERR, "287|Unexpected write event");
798                break;
799
800        /*
801         * Theoretically, none of these can occur, as they're handled at the
802         * top editor level.
803         */
804        case E_ERR:
805        case E_SIGHUP:
806        case E_SIGTERM:
807        default:
808                abort();
809        }
810
811        /* Free any allocated memory. */
812        if (evp->e_asp != NULL)
813                free(evp->e_asp);
814}
815
816/*
817 * v_event_flush --
818 *      Flush any flagged keys, returning if any keys were flushed.
819 *
820 * PUBLIC: int v_event_flush __P((SCR *, u_int));
821 */
822int
823v_event_flush(sp, flags)
824        SCR *sp;
825        u_int flags;
826{
827        GS *gp;
828        int rval;
829
830        for (rval = 0, gp = sp->gp; gp->i_cnt != 0 &&
831            F_ISSET(&gp->i_event[gp->i_next].e_ch, flags); rval = 1)
832                QREM(1);
833        return (rval);
834}
835
836/*
837 * v_event_grow --
838 *      Grow the terminal queue.
839 */
840static int
841v_event_grow(sp, add)
842        SCR *sp;
843        int add;
844{
845        GS *gp;
846        size_t new_nelem, olen;
847
848        gp = sp->gp;
849        new_nelem = gp->i_nelem + add;
850        olen = gp->i_nelem * sizeof(gp->i_event[0]);
851        BINC_RET(sp, gp->i_event, olen, new_nelem * sizeof(gp->i_event[0]));
852        gp->i_nelem = olen / sizeof(gp->i_event[0]);
853        return (0);
854}
855
856/*
857 * v_key_cmp --
858 *      Compare two keys for sorting.
859 */
860static int
861v_key_cmp(ap, bp)
862        const void *ap, *bp;
863{
864        return (((KEYLIST *)ap)->ch - ((KEYLIST *)bp)->ch);
865}
Note: See TracBrowser for help on using the repository browser.