blob: 085fc4dc68451bbdf98414ee4c119157b15f5284 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9
10/*
11 * getchar.c
12 *
13 * functions related with getting a character from the user/mapping/redo/...
14 *
15 * manipulations with redo buffer and stuff buffer
16 * mappings and abbreviations
17 */
18
19#include "vim.h"
20
21/*
22 * These buffers are used for storing:
23 * - stuffed characters: A command that is translated into another command.
24 * - redo characters: will redo the last change.
25 * - recorded chracters: for the "q" command.
26 *
27 * The bytes are stored like in the typeahead buffer:
28 * - K_SPECIAL introduces a special key (two more bytes follow). A literal
29 * K_SPECIAL is stored as K_SPECIAL KS_SPECIAL KE_FILLER.
30 * - CSI introduces a GUI termcap code (also when gui.in_use is FALSE,
31 * otherwise switching the GUI on would make mappings invalid).
32 * A literal CSI is stored as CSI KS_EXTRA KE_CSI.
33 * These translations are also done on multi-byte characters!
34 *
35 * Escaping CSI bytes is done by the system-specific input functions, called
36 * by ui_inchar().
37 * Escaping K_SPECIAL is done by inchar().
38 * Un-escaping is done by vgetc().
39 */
40
41#define MINIMAL_SIZE 20 /* minimal size for b_str */
42
43static struct buffheader redobuff = {{NULL, {NUL}}, NULL, 0, 0};
44static struct buffheader old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
45#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
46static struct buffheader save_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
47static struct buffheader save_old_redobuff = {{NULL, {NUL}}, NULL, 0, 0};
48#endif
49static struct buffheader recordbuff = {{NULL, {NUL}}, NULL, 0, 0};
50
51static int typeahead_char = 0; /* typeahead char that's not flushed */
52
53/*
54 * when block_redo is TRUE redo buffer will not be changed
55 * used by edit() to repeat insertions and 'V' command for redoing
56 */
57static int block_redo = FALSE;
58
59/*
60 * Make a hash value for a mapping.
61 * "mode" is the lower 4 bits of the State for the mapping.
62 * "c1" is the first character of the "lhs".
63 * Returns a value between 0 and 255, index in maphash.
64 * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
65 */
66#define MAP_HASH(mode, c1) (((mode) & (NORMAL + VISUAL + OP_PENDING)) ? (c1) : ((c1) ^ 0x80))
67
68/*
69 * Each mapping is put in one of the 256 hash lists, to speed up finding it.
70 */
71static mapblock_T *(maphash[256]);
72static int maphash_valid = FALSE;
73
74/*
75 * List used for abbreviations.
76 */
77static mapblock_T *first_abbr = NULL; /* first entry in abbrlist */
78
79static int KeyNoremap = FALSE; /* remapping disabled */
80
81/*
82 * variables used by vgetorpeek() and flush_buffers()
83 *
84 * typebuf.tb_buf[] contains all characters that are not consumed yet.
85 * typebuf.tb_buf[typebuf.tb_off] is the first valid character.
86 * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len - 1] is the last valid char.
87 * typebuf.tb_buf[typebuf.tb_off + typebuf.tb_len] must be NUL.
88 * The head of the buffer may contain the result of mappings, abbreviations
89 * and @a commands. The length of this part is typebuf.tb_maplen.
90 * typebuf.tb_silent is the part where <silent> applies.
91 * After the head are characters that come from the terminal.
92 * typebuf.tb_no_abbr_cnt is the number of characters in typebuf.tb_buf that
93 * should not be considered for abbreviations.
94 * Some parts of typebuf.tb_buf may not be mapped. These parts are remembered
95 * in typebuf.tb_noremap[], which is the same length as typebuf.tb_buf and
96 * contains RM_NONE for the characters that are not to be remapped.
97 * typebuf.tb_noremap[typebuf.tb_off] is the first valid flag.
98 * (typebuf has been put in globals.h, because check_termcode() needs it).
99 */
100#define RM_YES 0 /* tb_noremap: remap */
101#define RM_NONE 1 /* tb_noremap: don't remap */
102#define RM_SCRIPT 2 /* tb_noremap: remap local script mappings */
Bram Moolenaarf4b8e572004-06-24 15:53:16 +0000103#define RM_ABBR 4 /* tb_noremap: don't remap, do abbrev. */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000104
105/* typebuf.tb_buf has three parts: room in front (for result of mappings), the
106 * middle for typeahead and room for new characters (which needs to be 3 *
107 * MAXMAPLEN) for the Amiga).
108 */
109#define TYPELEN_INIT (5 * (MAXMAPLEN + 3))
110static char_u typebuf_init[TYPELEN_INIT]; /* initial typebuf.tb_buf */
111static char_u noremapbuf_init[TYPELEN_INIT]; /* initial typebuf.tb_noremap */
112
113static int last_recorded_len = 0; /* number of last recorded chars */
114
115static char_u *get_buffcont __ARGS((struct buffheader *, int));
116static void add_buff __ARGS((struct buffheader *, char_u *, long n));
117static void add_num_buff __ARGS((struct buffheader *, long));
118static void add_char_buff __ARGS((struct buffheader *, int));
119static int read_stuff __ARGS((int advance));
120static void start_stuff __ARGS((void));
121static int read_redo __ARGS((int, int));
122static void copy_redo __ARGS((int));
123static void init_typebuf __ARGS((void));
124static void gotchars __ARGS((char_u *, int));
125static void may_sync_undo __ARGS((void));
126static void closescript __ARGS((void));
127static int vgetorpeek __ARGS((int));
128static void map_free __ARGS((mapblock_T **));
129static void validate_maphash __ARGS((void));
130static void showmap __ARGS((mapblock_T *mp, int local));
131
132/*
133 * Free and clear a buffer.
134 */
135 void
136free_buff(buf)
137 struct buffheader *buf;
138{
139 struct buffblock *p, *np;
140
141 for (p = buf->bh_first.b_next; p != NULL; p = np)
142 {
143 np = p->b_next;
144 vim_free(p);
145 }
146 buf->bh_first.b_next = NULL;
147}
148
149/*
150 * Return the contents of a buffer as a single string.
151 * K_SPECIAL and CSI in the returned string are escaped.
152 */
153 static char_u *
154get_buffcont(buffer, dozero)
155 struct buffheader *buffer;
156 int dozero; /* count == zero is not an error */
157{
158 long_u count = 0;
159 char_u *p = NULL;
160 char_u *p2;
161 char_u *str;
162 struct buffblock *bp;
163
164 /* compute the total length of the string */
165 for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
166 count += (long_u)STRLEN(bp->b_str);
167
168 if ((count || dozero) && (p = lalloc(count + 1, TRUE)) != NULL)
169 {
170 p2 = p;
171 for (bp = buffer->bh_first.b_next; bp != NULL; bp = bp->b_next)
172 for (str = bp->b_str; *str; )
173 *p2++ = *str++;
174 *p2 = NUL;
175 }
176 return (p);
177}
178
179/*
180 * Return the contents of the record buffer as a single string
181 * and clear the record buffer.
182 * K_SPECIAL and CSI in the returned string are escaped.
183 */
184 char_u *
185get_recorded()
186{
187 char_u *p;
188 size_t len;
189
190 p = get_buffcont(&recordbuff, TRUE);
191 free_buff(&recordbuff);
192
193 /*
194 * Remove the characters that were added the last time, these must be the
195 * (possibly mapped) characters that stopped the recording.
196 */
197 len = STRLEN(p);
198 if ((int)len >= last_recorded_len)
199 {
200 len -= last_recorded_len;
201 p[len] = NUL;
202 }
203
204 /*
205 * When stopping recording from Insert mode with CTRL-O q, also remove the
206 * CTRL-O.
207 */
208 if (len > 0 && restart_edit != 0 && p[len - 1] == Ctrl_O)
209 p[len - 1] = NUL;
210
211 return (p);
212}
213
214/*
215 * Return the contents of the redo buffer as a single string.
216 * K_SPECIAL and CSI in the returned string are escaped.
217 */
218 char_u *
219get_inserted()
220{
221 return(get_buffcont(&redobuff, FALSE));
222}
223
224/*
225 * add string "s" after the current block of buffer "buf"
226 * K_SPECIAL and CSI should have been escaped already.
227 */
228 static void
229add_buff(buf, s, slen)
230 struct buffheader *buf;
231 char_u *s;
232 long slen; /* length of "s" or -1 */
233{
234 struct buffblock *p;
235 long_u len;
236
237 if (slen < 0)
238 slen = (long)STRLEN(s);
239 if (slen == 0) /* don't add empty strings */
240 return;
241
242 if (buf->bh_first.b_next == NULL) /* first add to list */
243 {
244 buf->bh_space = 0;
245 buf->bh_curr = &(buf->bh_first);
246 }
247 else if (buf->bh_curr == NULL) /* buffer has already been read */
248 {
249 EMSG(_("E222: Add to read buffer"));
250 return;
251 }
252 else if (buf->bh_index != 0)
253 STRCPY(buf->bh_first.b_next->b_str,
254 buf->bh_first.b_next->b_str + buf->bh_index);
255 buf->bh_index = 0;
256
257 if (buf->bh_space >= (int)slen)
258 {
259 len = (long_u)STRLEN(buf->bh_curr->b_str);
Bram Moolenaarb6356332005-07-18 21:40:44 +0000260 vim_strncpy(buf->bh_curr->b_str + len, s, (size_t)slen);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000261 buf->bh_space -= slen;
262 }
263 else
264 {
265 if (slen < MINIMAL_SIZE)
266 len = MINIMAL_SIZE;
267 else
268 len = slen;
269 p = (struct buffblock *)lalloc((long_u)(sizeof(struct buffblock) + len),
270 TRUE);
271 if (p == NULL)
272 return; /* no space, just forget it */
273 buf->bh_space = len - slen;
Bram Moolenaarb6356332005-07-18 21:40:44 +0000274 vim_strncpy(p->b_str, s, (size_t)slen);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000275
276 p->b_next = buf->bh_curr->b_next;
277 buf->bh_curr->b_next = p;
278 buf->bh_curr = p;
279 }
280 return;
281}
282
283/*
284 * Add number "n" to buffer "buf".
285 */
286 static void
287add_num_buff(buf, n)
288 struct buffheader *buf;
289 long n;
290{
291 char_u number[32];
292
293 sprintf((char *)number, "%ld", n);
294 add_buff(buf, number, -1L);
295}
296
297/*
298 * Add character 'c' to buffer "buf".
299 * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
300 */
301 static void
302add_char_buff(buf, c)
303 struct buffheader *buf;
304 int c;
305{
306#ifdef FEAT_MBYTE
307 char_u bytes[MB_MAXBYTES + 1];
308 int len;
309 int i;
310#endif
311 char_u temp[4];
312
313#ifdef FEAT_MBYTE
314 if (IS_SPECIAL(c))
315 len = 1;
316 else
317 len = (*mb_char2bytes)(c, bytes);
318 for (i = 0; i < len; ++i)
319 {
320 if (!IS_SPECIAL(c))
321 c = bytes[i];
322#endif
323
324 if (IS_SPECIAL(c) || c == K_SPECIAL || c == NUL)
325 {
326 /* translate special key code into three byte sequence */
327 temp[0] = K_SPECIAL;
328 temp[1] = K_SECOND(c);
329 temp[2] = K_THIRD(c);
330 temp[3] = NUL;
331 }
332#ifdef FEAT_GUI
333 else if (c == CSI)
334 {
335 /* Translate a CSI to a CSI - KS_EXTRA - KE_CSI sequence */
336 temp[0] = CSI;
337 temp[1] = KS_EXTRA;
338 temp[2] = (int)KE_CSI;
339 temp[3] = NUL;
340 }
341#endif
342 else
343 {
344 temp[0] = c;
345 temp[1] = NUL;
346 }
347 add_buff(buf, temp, -1L);
348#ifdef FEAT_MBYTE
349 }
350#endif
351}
352
353/*
354 * Get one byte from the stuff buffer.
355 * If advance == TRUE go to the next char.
356 * No translation is done K_SPECIAL and CSI are escaped.
357 */
358 static int
359read_stuff(advance)
360 int advance;
361{
362 char_u c;
363 struct buffblock *curr;
364
365 if (stuffbuff.bh_first.b_next == NULL) /* buffer is empty */
366 return NUL;
367
368 curr = stuffbuff.bh_first.b_next;
369 c = curr->b_str[stuffbuff.bh_index];
370
371 if (advance)
372 {
373 if (curr->b_str[++stuffbuff.bh_index] == NUL)
374 {
375 stuffbuff.bh_first.b_next = curr->b_next;
376 vim_free(curr);
377 stuffbuff.bh_index = 0;
378 }
379 }
380 return c;
381}
382
383/*
384 * Prepare the stuff buffer for reading (if it contains something).
385 */
386 static void
387start_stuff()
388{
389 if (stuffbuff.bh_first.b_next != NULL)
390 {
391 stuffbuff.bh_curr = &(stuffbuff.bh_first);
392 stuffbuff.bh_space = 0;
393 }
394}
395
396/*
397 * Return TRUE if the stuff buffer is empty.
398 */
399 int
400stuff_empty()
401{
402 return (stuffbuff.bh_first.b_next == NULL);
403}
404
405/*
406 * Set a typeahead character that won't be flushed.
407 */
408 void
409typeahead_noflush(c)
410 int c;
411{
412 typeahead_char = c;
413}
414
415/*
416 * Remove the contents of the stuff buffer and the mapped characters in the
417 * typeahead buffer (used in case of an error). If 'typeahead' is true,
418 * flush all typeahead characters (used when interrupted by a CTRL-C).
419 */
420 void
421flush_buffers(typeahead)
422 int typeahead;
423{
424 init_typebuf();
425
426 start_stuff();
427 while (read_stuff(TRUE) != NUL)
428 ;
429
430 if (typeahead) /* remove all typeahead */
431 {
432 /*
433 * We have to get all characters, because we may delete the first part
434 * of an escape sequence.
435 * In an xterm we get one char at a time and we have to get them all.
436 */
437 while (inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 10L,
438 typebuf.tb_change_cnt) != 0)
439 ;
440 typebuf.tb_off = MAXMAPLEN;
441 typebuf.tb_len = 0;
442 }
443 else /* remove mapped characters only */
444 {
445 typebuf.tb_off += typebuf.tb_maplen;
446 typebuf.tb_len -= typebuf.tb_maplen;
447 }
448 typebuf.tb_maplen = 0;
449 typebuf.tb_silent = 0;
450 cmd_silent = FALSE;
451 typebuf.tb_no_abbr_cnt = 0;
452}
453
454/*
455 * The previous contents of the redo buffer is kept in old_redobuffer.
456 * This is used for the CTRL-O <.> command in insert mode.
457 */
458 void
459ResetRedobuff()
460{
461 if (!block_redo)
462 {
463 free_buff(&old_redobuff);
464 old_redobuff = redobuff;
465 redobuff.bh_first.b_next = NULL;
466 }
467}
468
469#if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO)
470/*
471 * Save redobuff and old_redobuff to save_redobuff and save_old_redobuff.
472 * Used before executing autocommands and user functions.
473 */
474static int save_level = 0;
475
476 void
477saveRedobuff()
478{
479 char_u *s;
480
481 if (save_level++ == 0)
482 {
483 save_redobuff = redobuff;
484 redobuff.bh_first.b_next = NULL;
485 save_old_redobuff = old_redobuff;
486 old_redobuff.bh_first.b_next = NULL;
487
488 /* Make a copy, so that ":normal ." in a function works. */
489 s = get_buffcont(&save_redobuff, FALSE);
490 if (s != NULL)
491 {
492 add_buff(&redobuff, s, -1L);
493 vim_free(s);
494 }
495 }
496}
497
498/*
499 * Restore redobuff and old_redobuff from save_redobuff and save_old_redobuff.
500 * Used after executing autocommands and user functions.
501 */
502 void
503restoreRedobuff()
504{
505 if (--save_level == 0)
506 {
507 free_buff(&redobuff);
508 redobuff = save_redobuff;
509 free_buff(&old_redobuff);
510 old_redobuff = save_old_redobuff;
511 }
512}
513#endif
514
515/*
516 * Append "s" to the redo buffer.
517 * K_SPECIAL and CSI should already have been escaped.
518 */
519 void
520AppendToRedobuff(s)
521 char_u *s;
522{
523 if (!block_redo)
524 add_buff(&redobuff, s, -1L);
525}
526
527/*
528 * Append to Redo buffer literally, escaping special characters with CTRL-V.
529 * K_SPECIAL and CSI are escaped as well.
530 */
531 void
532AppendToRedobuffLit(s)
533 char_u *s;
534{
535 int c;
536 char_u *start;
537
538 if (block_redo)
539 return;
540
541 while (*s != NUL)
542 {
543 /* Put a string of normal characters in the redo buffer (that's
544 * faster). */
545 start = s;
546 while (*s >= ' '
547#ifndef EBCDIC
548 && *s < DEL /* EBCDIC: all chars above space are normal */
549#endif
550 )
551 ++s;
552
553 /* Don't put '0' or '^' as last character, just in case a CTRL-D is
554 * typed next. */
555 if (*s == NUL && (s[-1] == '0' || s[-1] == '^'))
556 --s;
557 if (s > start)
558 add_buff(&redobuff, start, (long)(s - start));
559
560 if (*s != NUL)
561 {
562 /* Handle a special or multibyte character. */
563#ifdef FEAT_MBYTE
564 if (has_mbyte)
Bram Moolenaar0fa313a2005-08-10 21:07:57 +0000565 /* Handle composing chars separately. */
566 c = mb_cptr2char_adv(&s);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000567 else
568#endif
569 c = *s++;
570 if (c < ' ' || c == DEL || (*s == NUL && (c == '0' || c == '^')))
571 add_char_buff(&redobuff, Ctrl_V);
572
573 /* CTRL-V '0' must be inserted as CTRL-V 048 (EBCDIC: xf0) */
574 if (*s == NUL && c == '0')
575#ifdef EBCDIC
576 add_buff(&redobuff, (char_u *)"xf0", 3L);
577#else
578 add_buff(&redobuff, (char_u *)"048", 3L);
579#endif
580 else
581 add_char_buff(&redobuff, c);
582 }
583 }
584}
585
586/*
587 * Append a character to the redo buffer.
588 * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
589 */
590 void
591AppendCharToRedobuff(c)
592 int c;
593{
594 if (!block_redo)
595 add_char_buff(&redobuff, c);
596}
597
598/*
599 * Append a number to the redo buffer.
600 */
601 void
602AppendNumberToRedobuff(n)
603 long n;
604{
605 if (!block_redo)
606 add_num_buff(&redobuff, n);
607}
608
609/*
610 * Append string "s" to the stuff buffer.
611 * CSI and K_SPECIAL must already have been escaped.
612 */
613 void
614stuffReadbuff(s)
615 char_u *s;
616{
617 add_buff(&stuffbuff, s, -1L);
618}
619
620 void
621stuffReadbuffLen(s, len)
622 char_u *s;
623 long len;
624{
625 add_buff(&stuffbuff, s, len);
626}
627
628#if defined(FEAT_EVAL) || defined(PROTO)
629/*
630 * Stuff "s" into the stuff buffer, leaving special key codes unmodified and
631 * escaping other K_SPECIAL and CSI bytes.
632 */
633 void
634stuffReadbuffSpec(s)
635 char_u *s;
636{
637 while (*s != NUL)
638 {
639 if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL)
640 {
641 /* Insert special key literally. */
642 stuffReadbuffLen(s, 3L);
643 s += 3;
644 }
645 else
646#ifdef FEAT_MBYTE
647 stuffcharReadbuff(mb_ptr2char_adv(&s));
648#else
649 stuffcharReadbuff(*s++);
650#endif
651 }
652}
653#endif
654
655/*
656 * Append a character to the stuff buffer.
657 * Translates special keys, NUL, CSI, K_SPECIAL and multibyte characters.
658 */
659 void
660stuffcharReadbuff(c)
661 int c;
662{
663 add_char_buff(&stuffbuff, c);
664}
665
666/*
667 * Append a number to the stuff buffer.
668 */
669 void
670stuffnumReadbuff(n)
671 long n;
672{
673 add_num_buff(&stuffbuff, n);
674}
675
676/*
677 * Read a character from the redo buffer. Translates K_SPECIAL, CSI and
678 * multibyte characters.
679 * The redo buffer is left as it is.
680 * if init is TRUE, prepare for redo, return FAIL if nothing to redo, OK
681 * otherwise
682 * if old is TRUE, use old_redobuff instead of redobuff
683 */
684 static int
685read_redo(init, old_redo)
686 int init;
687 int old_redo;
688{
689 static struct buffblock *bp;
690 static char_u *p;
691 int c;
692#ifdef FEAT_MBYTE
693 int n;
694 char_u buf[MB_MAXBYTES];
695 int i;
696#endif
697
698 if (init)
699 {
700 if (old_redo)
701 bp = old_redobuff.bh_first.b_next;
702 else
703 bp = redobuff.bh_first.b_next;
704 if (bp == NULL)
705 return FAIL;
706 p = bp->b_str;
707 return OK;
708 }
709 if ((c = *p) != NUL)
710 {
711 /* Reverse the conversion done by add_char_buff() */
712#ifdef FEAT_MBYTE
713 /* For a multi-byte character get all the bytes and return the
714 * converted character. */
715 if (has_mbyte && (c != K_SPECIAL || p[1] == KS_SPECIAL))
716 n = MB_BYTE2LEN_CHECK(c);
717 else
718 n = 1;
719 for (i = 0; ; ++i)
720#endif
721 {
722 if (c == K_SPECIAL) /* special key or escaped K_SPECIAL */
723 {
724 c = TO_SPECIAL(p[1], p[2]);
725 p += 2;
726 }
727#ifdef FEAT_GUI
728 if (c == CSI) /* escaped CSI */
729 p += 2;
730#endif
731 if (*++p == NUL && bp->b_next != NULL)
732 {
733 bp = bp->b_next;
734 p = bp->b_str;
735 }
736#ifdef FEAT_MBYTE
737 buf[i] = c;
738 if (i == n - 1) /* last byte of a character */
739 {
740 if (n != 1)
741 c = (*mb_ptr2char)(buf);
742 break;
743 }
744 c = *p;
745 if (c == NUL) /* cannot happen? */
746 break;
747#endif
748 }
749 }
750
751 return c;
752}
753
754/*
755 * Copy the rest of the redo buffer into the stuff buffer (in a slow way).
756 * If old_redo is TRUE, use old_redobuff instead of redobuff.
757 * The escaped K_SPECIAL and CSI are copied without translation.
758 */
759 static void
760copy_redo(old_redo)
761 int old_redo;
762{
763 int c;
764
765 while ((c = read_redo(FALSE, old_redo)) != NUL)
766 stuffcharReadbuff(c);
767}
768
769/*
770 * Stuff the redo buffer into the stuffbuff.
771 * Insert the redo count into the command.
772 * If "old_redo" is TRUE, the last but one command is repeated
773 * instead of the last command (inserting text). This is used for
774 * CTRL-O <.> in insert mode
775 *
776 * return FAIL for failure, OK otherwise
777 */
778 int
779start_redo(count, old_redo)
780 long count;
781 int old_redo;
782{
783 int c;
784
785 /* init the pointers; return if nothing to redo */
786 if (read_redo(TRUE, old_redo) == FAIL)
787 return FAIL;
788
789 c = read_redo(FALSE, old_redo);
790
791 /* copy the buffer name, if present */
792 if (c == '"')
793 {
794 add_buff(&stuffbuff, (char_u *)"\"", 1L);
795 c = read_redo(FALSE, old_redo);
796
797 /* if a numbered buffer is used, increment the number */
798 if (c >= '1' && c < '9')
799 ++c;
800 add_char_buff(&stuffbuff, c);
801 c = read_redo(FALSE, old_redo);
802 }
803
804#ifdef FEAT_VISUAL
805 if (c == 'v') /* redo Visual */
806 {
807 VIsual = curwin->w_cursor;
808 VIsual_active = TRUE;
809 VIsual_select = FALSE;
810 VIsual_reselect = TRUE;
811 redo_VIsual_busy = TRUE;
812 c = read_redo(FALSE, old_redo);
813 }
814#endif
815
816 /* try to enter the count (in place of a previous count) */
817 if (count)
818 {
819 while (VIM_ISDIGIT(c)) /* skip "old" count */
820 c = read_redo(FALSE, old_redo);
821 add_num_buff(&stuffbuff, count);
822 }
823
824 /* copy from the redo buffer into the stuff buffer */
825 add_char_buff(&stuffbuff, c);
826 copy_redo(old_redo);
827 return OK;
828}
829
830/*
831 * Repeat the last insert (R, o, O, a, A, i or I command) by stuffing
832 * the redo buffer into the stuffbuff.
833 * return FAIL for failure, OK otherwise
834 */
835 int
836start_redo_ins()
837{
838 int c;
839
840 if (read_redo(TRUE, FALSE) == FAIL)
841 return FAIL;
842 start_stuff();
843
844 /* skip the count and the command character */
845 while ((c = read_redo(FALSE, FALSE)) != NUL)
846 {
847 if (vim_strchr((char_u *)"AaIiRrOo", c) != NULL)
848 {
849 if (c == 'O' || c == 'o')
850 stuffReadbuff(NL_STR);
851 break;
852 }
853 }
854
855 /* copy the typed text from the redo buffer into the stuff buffer */
856 copy_redo(FALSE);
857 block_redo = TRUE;
858 return OK;
859}
860
861 void
862stop_redo_ins()
863{
864 block_redo = FALSE;
865}
866
867/*
868 * Initialize typebuf.tb_buf to point to typebuf_init.
869 * alloc() cannot be used here: In out-of-memory situations it would
870 * be impossible to type anything.
871 */
872 static void
873init_typebuf()
874{
875 if (typebuf.tb_buf == NULL)
876 {
877 typebuf.tb_buf = typebuf_init;
878 typebuf.tb_noremap = noremapbuf_init;
879 typebuf.tb_buflen = TYPELEN_INIT;
880 typebuf.tb_len = 0;
881 typebuf.tb_off = 0;
882 typebuf.tb_change_cnt = 1;
883 }
884}
885
886/*
887 * insert a string in position 'offset' in the typeahead buffer (for "@r"
888 * and ":normal" command, vgetorpeek() and check_termcode())
889 *
890 * If noremap is REMAP_YES, new string can be mapped again.
891 * If noremap is REMAP_NONE, new string cannot be mapped again.
Bram Moolenaarf4b8e572004-06-24 15:53:16 +0000892 * If noremap is REMAP_SKIP, fist char of new string cannot be mapped again,
893 * but abbreviations are allowed.
Bram Moolenaar071d4272004-06-13 20:20:40 +0000894 * If noremap is REMAP_SCRIPT, new string cannot be mapped again, except for
895 * script-local mappings.
896 * If noremap is > 0, that many characters of the new string cannot be mapped.
897 *
898 * If nottyped is TRUE, the string does not return KeyTyped (don't use when
899 * offset is non-zero!).
900 *
901 * If silent is TRUE, cmd_silent is set when the characters are obtained.
902 *
903 * return FAIL for failure, OK otherwise
904 */
905 int
906ins_typebuf(str, noremap, offset, nottyped, silent)
907 char_u *str;
908 int noremap;
909 int offset;
910 int nottyped;
911 int silent;
912{
913 char_u *s1, *s2;
914 int newlen;
915 int addlen;
916 int i;
917 int newoff;
918 int val;
919 int nrm;
920
921 init_typebuf();
922 if (++typebuf.tb_change_cnt == 0)
923 typebuf.tb_change_cnt = 1;
924
925 addlen = (int)STRLEN(str);
926 /*
927 * Easy case: there is room in front of typebuf.tb_buf[typebuf.tb_off]
928 */
929 if (offset == 0 && addlen <= typebuf.tb_off)
930 {
931 typebuf.tb_off -= addlen;
932 mch_memmove(typebuf.tb_buf + typebuf.tb_off, str, (size_t)addlen);
933 }
934 /*
935 * Need to allocate new buffer.
936 * In typebuf.tb_buf there must always be room for 3 * MAXMAPLEN + 4
937 * characters. We add some extra room to avoid having to allocate too
938 * often.
939 */
940 else
941 {
942 newoff = MAXMAPLEN + 4;
943 newlen = typebuf.tb_len + addlen + newoff + 4 * (MAXMAPLEN + 4);
944 if (newlen < 0) /* string is getting too long */
945 {
946 EMSG(_(e_toocompl)); /* also calls flush_buffers */
947 setcursor();
948 return FAIL;
949 }
950 s1 = alloc(newlen);
951 if (s1 == NULL) /* out of memory */
952 return FAIL;
953 s2 = alloc(newlen);
954 if (s2 == NULL) /* out of memory */
955 {
956 vim_free(s1);
957 return FAIL;
958 }
959 typebuf.tb_buflen = newlen;
960
961 /* copy the old chars, before the insertion point */
962 mch_memmove(s1 + newoff, typebuf.tb_buf + typebuf.tb_off,
963 (size_t)offset);
964 /* copy the new chars */
965 mch_memmove(s1 + newoff + offset, str, (size_t)addlen);
966 /* copy the old chars, after the insertion point, including the NUL at
967 * the end */
968 mch_memmove(s1 + newoff + offset + addlen,
969 typebuf.tb_buf + typebuf.tb_off + offset,
970 (size_t)(typebuf.tb_len - offset + 1));
971 if (typebuf.tb_buf != typebuf_init)
972 vim_free(typebuf.tb_buf);
973 typebuf.tb_buf = s1;
974
975 mch_memmove(s2 + newoff, typebuf.tb_noremap + typebuf.tb_off,
976 (size_t)offset);
977 mch_memmove(s2 + newoff + offset + addlen,
978 typebuf.tb_noremap + typebuf.tb_off + offset,
979 (size_t)(typebuf.tb_len - offset));
980 if (typebuf.tb_noremap != noremapbuf_init)
981 vim_free(typebuf.tb_noremap);
982 typebuf.tb_noremap = s2;
983
984 typebuf.tb_off = newoff;
985 }
986 typebuf.tb_len += addlen;
987
988 /* If noremap == REMAP_SCRIPT: do remap script-local mappings. */
989 if (noremap == REMAP_SCRIPT)
990 val = RM_SCRIPT;
Bram Moolenaarf4b8e572004-06-24 15:53:16 +0000991 else if (noremap == REMAP_SKIP)
992 val = RM_ABBR;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000993 else
994 val = RM_NONE;
995
996 /*
997 * Adjust typebuf.tb_noremap[] for the new characters:
998 * If noremap == REMAP_NONE or REMAP_SCRIPT: new characters are
999 * (sometimes) not remappable
1000 * If noremap == REMAP_YES: all the new characters are mappable
1001 * If noremap > 0: "noremap" characters are not remappable, the rest
1002 * mappable
1003 */
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00001004 if (noremap == REMAP_SKIP)
1005 nrm = 1;
1006 else if (noremap < 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001007 nrm = addlen;
1008 else
1009 nrm = noremap;
1010 for (i = 0; i < addlen; ++i)
1011 typebuf.tb_noremap[typebuf.tb_off + i + offset] =
1012 (--nrm >= 0) ? val : RM_YES;
1013
1014 /* tb_maplen and tb_silent only remember the length of mapped and/or
1015 * silent mappings at the start of the buffer, assuming that a mapped
1016 * sequence doesn't result in typed characters. */
1017 if (nottyped || typebuf.tb_maplen > offset)
1018 typebuf.tb_maplen += addlen;
1019 if (silent || typebuf.tb_silent > offset)
1020 {
1021 typebuf.tb_silent += addlen;
1022 cmd_silent = TRUE;
1023 }
1024 if (typebuf.tb_no_abbr_cnt && offset == 0) /* and not used for abbrev.s */
1025 typebuf.tb_no_abbr_cnt += addlen;
1026
1027 return OK;
1028}
1029
1030/*
1031 * Return TRUE if the typeahead buffer was changed (while waiting for a
1032 * character to arrive). Happens when a message was received from a client.
1033 * But check in a more generic way to avoid trouble: When "typebuf.tb_buf"
1034 * changed it was reallocated and the old pointer can no longer be used.
1035 * Or "typebuf.tb_off" may have been changed and we would overwrite characters
1036 * that was just added.
1037 */
1038 int
1039typebuf_changed(tb_change_cnt)
1040 int tb_change_cnt; /* old value of typebuf.tb_change_cnt */
1041{
1042 return (tb_change_cnt != 0 && (typebuf.tb_change_cnt != tb_change_cnt
1043#ifdef FEAT_CLIENTSERVER
1044 || received_from_client
1045#endif
1046 ));
1047}
1048
1049/*
1050 * Return TRUE if there are no characters in the typeahead buffer that have
1051 * not been typed (result from a mapping or come from ":normal").
1052 */
1053 int
1054typebuf_typed()
1055{
1056 return typebuf.tb_maplen == 0;
1057}
1058
1059/*
1060 * Return the number of characters that are mapped (or not typed).
1061 */
1062 int
1063typebuf_maplen()
1064{
1065 return typebuf.tb_maplen;
1066}
1067
1068/*
1069 * remove "len" characters from typebuf.tb_buf[typebuf.tb_off + offset]
1070 */
1071 void
1072del_typebuf(len, offset)
1073 int len;
1074 int offset;
1075{
1076 int i;
1077
1078 if (len == 0)
1079 return; /* nothing to do */
1080
1081 typebuf.tb_len -= len;
1082
1083 /*
1084 * Easy case: Just increase typebuf.tb_off.
1085 */
1086 if (offset == 0 && typebuf.tb_buflen - (typebuf.tb_off + len)
1087 >= 3 * MAXMAPLEN + 3)
1088 typebuf.tb_off += len;
1089 /*
1090 * Have to move the characters in typebuf.tb_buf[] and typebuf.tb_noremap[]
1091 */
1092 else
1093 {
1094 i = typebuf.tb_off + offset;
1095 /*
1096 * Leave some extra room at the end to avoid reallocation.
1097 */
1098 if (typebuf.tb_off > MAXMAPLEN)
1099 {
1100 mch_memmove(typebuf.tb_buf + MAXMAPLEN,
1101 typebuf.tb_buf + typebuf.tb_off, (size_t)offset);
1102 mch_memmove(typebuf.tb_noremap + MAXMAPLEN,
1103 typebuf.tb_noremap + typebuf.tb_off, (size_t)offset);
1104 typebuf.tb_off = MAXMAPLEN;
1105 }
1106 /* adjust typebuf.tb_buf (include the NUL at the end) */
1107 mch_memmove(typebuf.tb_buf + typebuf.tb_off + offset,
1108 typebuf.tb_buf + i + len,
1109 (size_t)(typebuf.tb_len - offset + 1));
1110 /* adjust typebuf.tb_noremap[] */
1111 mch_memmove(typebuf.tb_noremap + typebuf.tb_off + offset,
1112 typebuf.tb_noremap + i + len,
1113 (size_t)(typebuf.tb_len - offset));
1114 }
1115
1116 if (typebuf.tb_maplen > offset) /* adjust tb_maplen */
1117 {
1118 if (typebuf.tb_maplen < offset + len)
1119 typebuf.tb_maplen = offset;
1120 else
1121 typebuf.tb_maplen -= len;
1122 }
1123 if (typebuf.tb_silent > offset) /* adjust tb_silent */
1124 {
1125 if (typebuf.tb_silent < offset + len)
1126 typebuf.tb_silent = offset;
1127 else
1128 typebuf.tb_silent -= len;
1129 }
1130 if (typebuf.tb_no_abbr_cnt > offset) /* adjust tb_no_abbr_cnt */
1131 {
1132 if (typebuf.tb_no_abbr_cnt < offset + len)
1133 typebuf.tb_no_abbr_cnt = offset;
1134 else
1135 typebuf.tb_no_abbr_cnt -= len;
1136 }
1137
1138#ifdef FEAT_CLIENTSERVER
1139 /* Reset the flag that text received from a client was inserted in the
1140 * typeahead buffer. */
1141 received_from_client = FALSE;
1142#endif
1143 if (++typebuf.tb_change_cnt == 0)
1144 typebuf.tb_change_cnt = 1;
1145}
1146
1147/*
1148 * Write typed characters to script file.
1149 * If recording is on put the character in the recordbuffer.
1150 */
1151 static void
1152gotchars(s, len)
1153 char_u *s;
1154 int len;
1155{
1156 int c;
1157 char_u buf[2];
1158
1159 /* remember how many chars were last recorded */
1160 if (Recording)
1161 last_recorded_len += len;
1162
1163 buf[1] = NUL;
1164 while (len--)
1165 {
1166 /* Handle one byte at a time; no translation to be done. */
1167 c = *s++;
1168 updatescript(c);
1169
1170 if (Recording)
1171 {
1172 buf[0] = c;
1173 add_buff(&recordbuff, buf, 1L);
1174 }
1175 }
1176 may_sync_undo();
1177
1178#ifdef FEAT_EVAL
1179 /* output "debug mode" message next time in debug mode */
1180 debug_did_msg = FALSE;
1181#endif
1182
1183 /* Since characters have been typed, consider the following to be in
1184 * another mapping. Search string will be kept in history. */
1185 ++maptick;
1186}
1187
1188/*
1189 * Sync undo. Called when typed characters are obtained from the typeahead
1190 * buffer, or when a menu is used.
1191 * Do not sync:
1192 * - In Insert mode, unless cursor key has been used.
1193 * - While reading a script file.
1194 * - When no_u_sync is non-zero.
1195 */
1196 static void
1197may_sync_undo()
1198{
1199 if ((!(State & (INSERT + CMDLINE)) || arrow_used)
1200 && scriptin[curscript] == NULL && no_u_sync == 0)
1201 u_sync();
1202}
1203
1204/*
1205 * Make "typebuf" empty and allocate new buffers.
1206 * Returns FAIL when out of memory.
1207 */
1208 int
1209alloc_typebuf()
1210{
1211 typebuf.tb_buf = alloc(TYPELEN_INIT);
1212 typebuf.tb_noremap = alloc(TYPELEN_INIT);
1213 if (typebuf.tb_buf == NULL || typebuf.tb_noremap == NULL)
1214 {
1215 free_typebuf();
1216 return FAIL;
1217 }
1218 typebuf.tb_buflen = TYPELEN_INIT;
1219 typebuf.tb_off = 0;
1220 typebuf.tb_len = 0;
1221 typebuf.tb_maplen = 0;
1222 typebuf.tb_silent = 0;
1223 typebuf.tb_no_abbr_cnt = 0;
1224 if (++typebuf.tb_change_cnt == 0)
1225 typebuf.tb_change_cnt = 1;
1226 return OK;
1227}
1228
1229/*
1230 * Free the buffers of "typebuf".
1231 */
1232 void
1233free_typebuf()
1234{
1235 vim_free(typebuf.tb_buf);
1236 vim_free(typebuf.tb_noremap);
1237}
1238
1239/*
1240 * When doing ":so! file", the current typeahead needs to be saved, and
1241 * restored when "file" has been read completely.
1242 */
1243static typebuf_T saved_typebuf[NSCRIPT];
1244
1245 int
1246save_typebuf()
1247{
1248 init_typebuf();
1249 saved_typebuf[curscript] = typebuf;
1250 /* If out of memory: restore typebuf and close file. */
1251 if (alloc_typebuf() == FAIL)
1252 {
1253 closescript();
1254 return FAIL;
1255 }
1256 return OK;
1257}
1258
1259#if defined(FEAT_EVAL) || defined(FEAT_EX_EXTRA) || defined(PROTO)
1260
1261/*
1262 * Save all three kinds of typeahead, so that the user must type at a prompt.
1263 */
1264 void
1265save_typeahead(tp)
1266 tasave_T *tp;
1267{
1268 tp->save_typebuf = typebuf;
1269 tp->typebuf_valid = (alloc_typebuf() == OK);
1270 if (!tp->typebuf_valid)
1271 typebuf = tp->save_typebuf;
1272
1273 tp->save_stuffbuff = stuffbuff;
1274 stuffbuff.bh_first.b_next = NULL;
1275# ifdef USE_INPUT_BUF
1276 tp->save_inputbuf = get_input_buf();
1277# endif
1278}
1279
1280/*
1281 * Restore the typeahead to what it was before calling save_typeahead().
1282 * The allocated memory is freed, can only be called once!
1283 */
1284 void
1285restore_typeahead(tp)
1286 tasave_T *tp;
1287{
1288 if (tp->typebuf_valid)
1289 {
1290 free_typebuf();
1291 typebuf = tp->save_typebuf;
1292 }
1293
1294 free_buff(&stuffbuff);
1295 stuffbuff = tp->save_stuffbuff;
1296# ifdef USE_INPUT_BUF
1297 set_input_buf(tp->save_inputbuf);
1298# endif
1299}
1300#endif
1301
1302/*
1303 * Open a new script file for the ":source!" command.
1304 */
1305 void
1306openscript(name, directly)
1307 char_u *name;
1308 int directly; /* when TRUE execute directly */
1309{
1310 if (curscript + 1 == NSCRIPT)
1311 {
1312 EMSG(_(e_nesting));
1313 return;
1314 }
1315
1316 if (scriptin[curscript] != NULL) /* already reading script */
1317 ++curscript;
1318 /* use NameBuff for expanded name */
1319 expand_env(name, NameBuff, MAXPATHL);
1320 if ((scriptin[curscript] = mch_fopen((char *)NameBuff, READBIN)) == NULL)
1321 {
1322 EMSG2(_(e_notopen), name);
1323 if (curscript)
1324 --curscript;
1325 return;
1326 }
1327 if (save_typebuf() == FAIL)
1328 return;
1329
1330 /*
1331 * Execute the commands from the file right now when using ":source!"
1332 * after ":global" or ":argdo" or in a loop. Also when another command
1333 * follows. This means the display won't be updated. Don't do this
1334 * always, "make test" would fail.
1335 */
1336 if (directly)
1337 {
1338 oparg_T oa;
1339 int oldcurscript;
1340 int save_State = State;
1341 int save_restart_edit = restart_edit;
1342 int save_insertmode = p_im;
1343 int save_finish_op = finish_op;
1344 int save_msg_scroll = msg_scroll;
1345
1346 State = NORMAL;
1347 msg_scroll = FALSE; /* no msg scrolling in Normal mode */
1348 restart_edit = 0; /* don't go to Insert mode */
1349 p_im = FALSE; /* don't use 'insertmode' */
1350 clear_oparg(&oa);
1351 finish_op = FALSE;
1352
1353 oldcurscript = curscript;
1354 do
1355 {
1356 update_topline_cursor(); /* update cursor position and topline */
1357 normal_cmd(&oa, FALSE); /* execute one command */
1358 vpeekc(); /* check for end of file */
1359 }
1360 while (scriptin[oldcurscript] != NULL);
1361
1362 State = save_State;
1363 msg_scroll = save_msg_scroll;
1364 restart_edit = save_restart_edit;
1365 p_im = save_insertmode;
1366 finish_op = save_finish_op;
1367 }
1368}
1369
1370/*
1371 * Close the currently active input script.
1372 */
1373 static void
1374closescript()
1375{
1376 free_typebuf();
1377 typebuf = saved_typebuf[curscript];
1378
1379 fclose(scriptin[curscript]);
1380 scriptin[curscript] = NULL;
1381 if (curscript > 0)
1382 --curscript;
1383}
1384
Bram Moolenaarea408852005-06-25 22:49:46 +00001385#if defined(EXITFREE) || defined(PROTO)
1386 void
1387close_all_scripts()
1388{
1389 while (scriptin[0] != NULL)
1390 closescript();
1391}
1392#endif
1393
Bram Moolenaar071d4272004-06-13 20:20:40 +00001394#if defined(FEAT_INS_EXPAND) || defined(PROTO)
1395/*
1396 * Return TRUE when reading keys from a script file.
1397 */
1398 int
1399using_script()
1400{
1401 return scriptin[curscript] != NULL;
1402}
1403#endif
1404
1405/*
Bram Moolenaar238f4fa2005-06-27 22:25:50 +00001406 * This function is called just before doing a blocking wait. Thus after
1407 * waiting 'updatetime' for a character to arrive.
1408 */
1409 void
1410before_blocking()
1411{
1412 updatescript(0);
1413#ifdef FEAT_EVAL
1414 garbage_collect();
1415#endif
1416}
1417
1418/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00001419 * updatescipt() is called when a character can be written into the script file
1420 * or when we have waited some time for a character (c == 0)
1421 *
1422 * All the changed memfiles are synced if c == 0 or when the number of typed
1423 * characters reaches 'updatecount' and 'updatecount' is non-zero.
1424 */
1425 void
1426updatescript(c)
1427 int c;
1428{
1429 static int count = 0;
1430
1431 if (c && scriptout)
1432 putc(c, scriptout);
1433 if (c == 0 || (p_uc > 0 && ++count >= p_uc))
1434 {
1435 ml_sync_all(c == 0, TRUE);
1436 count = 0;
1437 }
1438}
1439
1440#define KL_PART_KEY -1 /* keylen value for incomplete key-code */
1441#define KL_PART_MAP -2 /* keylen value for incomplete mapping */
1442
1443static int old_char = -1; /* character put back by vungetc() */
1444static int old_mod_mask; /* mod_mask for ungotten character */
1445
1446/*
1447 * Get the next input character.
1448 * Can return a special key or a multi-byte character.
1449 * Can return NUL when called recursively, use safe_vgetc() if that's not
1450 * wanted.
1451 * This translates escaped K_SPECIAL and CSI bytes to a K_SPECIAL or CSI byte.
1452 * Collects the bytes of a multibyte character into the whole character.
1453 * Returns the modifers in the global "mod_mask".
1454 */
1455 int
1456vgetc()
1457{
1458 int c, c2;
1459#ifdef FEAT_MBYTE
1460 int n;
1461 char_u buf[MB_MAXBYTES];
1462 int i;
1463#endif
1464
1465 /*
1466 * If a character was put back with vungetc, it was already processed.
1467 * Return it directly.
1468 */
1469 if (old_char != -1)
1470 {
1471 c = old_char;
1472 old_char = -1;
1473 mod_mask = old_mod_mask;
1474 return c;
1475 }
1476
1477 mod_mask = 0x0;
1478 last_recorded_len = 0;
1479 for (;;) /* this is done twice if there are modifiers */
1480 {
1481 if (mod_mask) /* no mapping after modifier has been read */
1482 {
1483 ++no_mapping;
1484 ++allow_keys;
1485 }
1486 c = vgetorpeek(TRUE);
1487 if (mod_mask)
1488 {
1489 --no_mapping;
1490 --allow_keys;
1491 }
1492
1493 /* Get two extra bytes for special keys */
1494 if (c == K_SPECIAL
1495#ifdef FEAT_GUI
1496 || c == CSI
1497#endif
1498 )
1499 {
Bram Moolenaar19a09a12005-03-04 23:39:37 +00001500 int save_allow_keys = allow_keys;
1501
Bram Moolenaar071d4272004-06-13 20:20:40 +00001502 ++no_mapping;
Bram Moolenaar19a09a12005-03-04 23:39:37 +00001503 allow_keys = 0; /* make sure BS is not found */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001504 c2 = vgetorpeek(TRUE); /* no mapping for these chars */
1505 c = vgetorpeek(TRUE);
1506 --no_mapping;
Bram Moolenaar19a09a12005-03-04 23:39:37 +00001507 allow_keys = save_allow_keys;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001508 if (c2 == KS_MODIFIER)
1509 {
1510 mod_mask = c;
1511 continue;
1512 }
1513 c = TO_SPECIAL(c2, c);
1514
1515#if defined(FEAT_GUI_W32) && defined(FEAT_MENU) && defined(FEAT_TEAROFF)
1516 /* Handle K_TEAROFF here, the caller of vgetc() doesn't need to
1517 * know that a menu was torn off */
1518 if (c == K_TEAROFF)
1519 {
1520 char_u name[200];
1521 int i;
1522
1523 /* get menu path, it ends with a <CR> */
1524 for (i = 0; (c = vgetorpeek(TRUE)) != '\r'; )
1525 {
1526 name[i] = c;
1527 if (i < 199)
1528 ++i;
1529 }
1530 name[i] = NUL;
1531 gui_make_tearoff(name);
1532 continue;
1533 }
1534#endif
Bram Moolenaar1cd871b2004-12-19 22:46:22 +00001535#if defined(HAVE_GTK2) && defined(FEAT_MENU)
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001536 /* GTK: <F10> normally selects the menu, but it's passed until
1537 * here to allow mapping it. Intercept and invoke the GTK
1538 * behavior if it's not mapped. */
1539 if (c == K_F10 && gui.menubar != NULL)
1540 {
1541 gtk_menu_shell_select_first(GTK_MENU_SHELL(gui.menubar), FALSE);
1542 continue;
1543 }
1544#endif
1545
Bram Moolenaar071d4272004-06-13 20:20:40 +00001546#ifdef FEAT_GUI
1547 /* Translate K_CSI to CSI. The special key is only used to avoid
1548 * it being recognized as the start of a special key. */
1549 if (c == K_CSI)
1550 c = CSI;
1551#endif
1552 }
1553#ifdef MSDOS
1554 /*
1555 * If K_NUL was typed, it is replaced by K_NUL, 3 in mch_inchar().
1556 * Delete the 3 here.
1557 */
1558 else if (c == K_NUL && vpeekc() == 3)
1559 (void)vgetorpeek(TRUE);
1560#endif
1561
Bram Moolenaara88d9682005-03-25 21:45:43 +00001562 /* a keypad or special function key was not mapped, use it like
1563 * its ASCII equivalent */
1564 switch (c)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001565 {
Bram Moolenaara88d9682005-03-25 21:45:43 +00001566 case K_KPLUS: c = '+'; break;
1567 case K_KMINUS: c = '-'; break;
1568 case K_KDIVIDE: c = '/'; break;
1569 case K_KMULTIPLY: c = '*'; break;
1570 case K_KENTER: c = CAR; break;
1571 case K_KPOINT:
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001572#ifdef WIN32
Bram Moolenaara88d9682005-03-25 21:45:43 +00001573 /* Can be either '.' or a ',', *
1574 * depending on the type of keypad. */
1575 c = MapVirtualKey(VK_DECIMAL, 2); break;
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001576#else
Bram Moolenaara88d9682005-03-25 21:45:43 +00001577 c = '.'; break;
Bram Moolenaar293ee4d2004-12-09 21:34:53 +00001578#endif
Bram Moolenaara88d9682005-03-25 21:45:43 +00001579 case K_K0: c = '0'; break;
1580 case K_K1: c = '1'; break;
1581 case K_K2: c = '2'; break;
1582 case K_K3: c = '3'; break;
1583 case K_K4: c = '4'; break;
1584 case K_K5: c = '5'; break;
1585 case K_K6: c = '6'; break;
1586 case K_K7: c = '7'; break;
1587 case K_K8: c = '8'; break;
1588 case K_K9: c = '9'; break;
1589
1590 case K_XHOME:
1591 case K_ZHOME: if (mod_mask == MOD_MASK_SHIFT)
1592 {
1593 c = K_S_HOME;
1594 mod_mask = 0;
1595 }
1596 else if (mod_mask == MOD_MASK_CTRL)
1597 {
1598 c = K_C_HOME;
1599 mod_mask = 0;
1600 }
1601 else
1602 c = K_HOME;
1603 break;
1604 case K_XEND:
1605 case K_ZEND: if (mod_mask == MOD_MASK_SHIFT)
1606 {
1607 c = K_S_END;
1608 mod_mask = 0;
1609 }
1610 else if (mod_mask == MOD_MASK_CTRL)
1611 {
1612 c = K_C_END;
1613 mod_mask = 0;
1614 }
1615 else
1616 c = K_END;
1617 break;
1618
1619 case K_XUP: c = K_UP; break;
1620 case K_XDOWN: c = K_DOWN; break;
1621 case K_XLEFT: c = K_LEFT; break;
1622 case K_XRIGHT: c = K_RIGHT; break;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001623 }
1624
1625#ifdef FEAT_MBYTE
1626 /* For a multi-byte character get all the bytes and return the
1627 * converted character.
1628 * Note: This will loop until enough bytes are received!
1629 */
1630 if (has_mbyte && (n = MB_BYTE2LEN_CHECK(c)) > 1)
1631 {
1632 ++no_mapping;
1633 buf[0] = c;
1634 for (i = 1; i < n; ++i)
1635 {
1636 buf[i] = vgetorpeek(TRUE);
1637 if (buf[i] == K_SPECIAL
1638#ifdef FEAT_GUI
1639 || buf[i] == CSI
1640#endif
1641 )
1642 {
1643 /* Must be a K_SPECIAL - KS_SPECIAL - KE_FILLER sequence,
1644 * which represents a K_SPECIAL (0x80),
1645 * or a CSI - KS_EXTRA - KE_CSI sequence, which represents
1646 * a CSI (0x9B),
1647 * of a K_SPECIAL - KS_EXTRA - KE_CSI, which is CSI too. */
1648 c = vgetorpeek(TRUE);
1649 if (vgetorpeek(TRUE) == (int)KE_CSI && c == KS_EXTRA)
1650 buf[i] = CSI;
1651 }
1652 }
1653 --no_mapping;
1654 c = (*mb_ptr2char)(buf);
1655 }
1656#endif
1657
1658 return c;
1659 }
1660}
1661
1662/*
1663 * Like vgetc(), but never return a NUL when called recursively, get a key
1664 * directly from the user (ignoring typeahead).
1665 */
1666 int
1667safe_vgetc()
1668{
1669 int c;
1670
1671 c = vgetc();
1672 if (c == NUL)
1673 c = get_keystroke();
1674 return c;
1675}
1676
1677/*
1678 * Check if a character is available, such that vgetc() will not block.
1679 * If the next character is a special character or multi-byte, the returned
1680 * character is not valid!.
1681 */
1682 int
1683vpeekc()
1684{
1685 if (old_char != -1)
1686 return old_char;
1687 return vgetorpeek(FALSE);
1688}
1689
1690#if defined(FEAT_TERMRESPONSE) || defined(PROTO)
1691/*
1692 * Like vpeekc(), but don't allow mapping. Do allow checking for terminal
1693 * codes.
1694 */
1695 int
1696vpeekc_nomap()
1697{
1698 int c;
1699
1700 ++no_mapping;
1701 ++allow_keys;
1702 c = vpeekc();
1703 --no_mapping;
1704 --allow_keys;
1705 return c;
1706}
1707#endif
1708
1709#if defined(FEAT_INS_EXPAND) || defined(PROTO)
1710/*
1711 * Check if any character is available, also half an escape sequence.
1712 * Trick: when no typeahead found, but there is something in the typeahead
1713 * buffer, it must be an ESC that is recognized as the start of a key code.
1714 */
1715 int
1716vpeekc_any()
1717{
1718 int c;
1719
1720 c = vpeekc();
1721 if (c == NUL && typebuf.tb_len > 0)
1722 c = ESC;
1723 return c;
1724}
1725#endif
1726
1727/*
1728 * Call vpeekc() without causing anything to be mapped.
1729 * Return TRUE if a character is available, FALSE otherwise.
1730 */
1731 int
1732char_avail()
1733{
1734 int retval;
1735
1736 ++no_mapping;
1737 retval = vpeekc();
1738 --no_mapping;
1739 return (retval != NUL);
1740}
1741
1742 void
1743vungetc(c) /* unget one character (can only be done once!) */
1744 int c;
1745{
1746 old_char = c;
1747 old_mod_mask = mod_mask;
1748}
1749
1750/*
1751 * get a character:
1752 * 1. from the stuffbuffer
1753 * This is used for abbreviated commands like "D" -> "d$".
1754 * Also used to redo a command for ".".
1755 * 2. from the typeahead buffer
1756 * Stores text obtained previously but not used yet.
1757 * Also stores the result of mappings.
1758 * Also used for the ":normal" command.
1759 * 3. from the user
1760 * This may do a blocking wait if "advance" is TRUE.
1761 *
1762 * if "advance" is TRUE (vgetc()):
1763 * really get the character.
1764 * KeyTyped is set to TRUE in the case the user typed the key.
1765 * KeyStuffed is TRUE if the character comes from the stuff buffer.
1766 * if "advance" is FALSE (vpeekc()):
1767 * just look whether there is a character available.
1768 *
1769 * When "no_mapping" is zero, checks for mappings in the current mode.
1770 * Only returns one byte (of a multi-byte character).
1771 * K_SPECIAL and CSI may be escaped, need to get two more bytes then.
1772 */
1773 static int
1774vgetorpeek(advance)
1775 int advance;
1776{
1777 int c, c1;
1778 int keylen;
1779 char_u *s;
1780 mapblock_T *mp;
1781#ifdef FEAT_LOCALMAP
1782 mapblock_T *mp2;
1783#endif
1784 mapblock_T *mp_match;
1785 int mp_match_len = 0;
1786 int timedout = FALSE; /* waited for more than 1 second
1787 for mapping to complete */
1788 int mapdepth = 0; /* check for recursive mapping */
1789 int mode_deleted = FALSE; /* set when mode has been deleted */
1790 int local_State;
1791 int mlen;
1792 int max_mlen;
1793#ifdef FEAT_CMDL_INFO
1794 int i;
1795 int new_wcol, new_wrow;
1796#endif
1797#ifdef FEAT_GUI
1798# ifdef FEAT_MENU
1799 int idx;
1800# endif
1801 int shape_changed = FALSE; /* adjusted cursor shape */
1802#endif
1803 int n;
1804#ifdef FEAT_LANGMAP
1805 int nolmaplen;
1806#endif
1807 int old_wcol, old_wrow;
Bram Moolenaar28a37ff2005-03-15 22:28:00 +00001808 int wait_tb_len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001809
1810 /*
1811 * This function doesn't work very well when called recursively. This may
1812 * happen though, because of:
1813 * 1. The call to add_to_showcmd(). char_avail() is then used to check if
1814 * there is a character available, which calls this function. In that
1815 * case we must return NUL, to indicate no character is available.
1816 * 2. A GUI callback function writes to the screen, causing a
1817 * wait_return().
1818 * Using ":normal" can also do this, but it saves the typeahead buffer,
1819 * thus it should be OK. But don't get a key from the user then.
1820 */
1821 if (vgetc_busy
1822#ifdef FEAT_EX_EXTRA
1823 && ex_normal_busy == 0
1824#endif
1825 )
1826 return NUL;
1827
1828 local_State = get_real_state();
1829
1830 vgetc_busy = TRUE;
1831
1832 if (advance)
1833 KeyStuffed = FALSE;
1834
1835 init_typebuf();
1836 start_stuff();
1837 if (advance && typebuf.tb_maplen == 0)
1838 Exec_reg = FALSE;
1839 do
1840 {
1841/*
1842 * get a character: 1. from the stuffbuffer
1843 */
1844 if (typeahead_char != 0)
1845 {
1846 c = typeahead_char;
1847 if (advance)
1848 typeahead_char = 0;
1849 }
1850 else
1851 c = read_stuff(advance);
1852 if (c != NUL && !got_int)
1853 {
1854 if (advance)
1855 {
1856 /* KeyTyped = FALSE; When the command that stuffed something
1857 * was typed, behave like the stuffed command was typed.
1858 * needed for CTRL-W CTRl-] to open a fold, for example. */
1859 KeyStuffed = TRUE;
1860 }
1861 if (typebuf.tb_no_abbr_cnt == 0)
1862 typebuf.tb_no_abbr_cnt = 1; /* no abbreviations now */
1863 }
1864 else
1865 {
1866 /*
1867 * Loop until we either find a matching mapped key, or we
1868 * are sure that it is not a mapped key.
1869 * If a mapped key sequence is found we go back to the start to
1870 * try re-mapping.
1871 */
1872 for (;;)
1873 {
1874 /*
1875 * ui_breakcheck() is slow, don't use it too often when
1876 * inside a mapping. But call it each time for typed
1877 * characters.
1878 */
1879 if (typebuf.tb_maplen)
1880 line_breakcheck();
1881 else
1882 ui_breakcheck(); /* check for CTRL-C */
1883 keylen = 0;
1884 if (got_int)
1885 {
1886 /* flush all input */
1887 c = inchar(typebuf.tb_buf, typebuf.tb_buflen - 1, 0L,
1888 typebuf.tb_change_cnt);
1889 /*
1890 * If inchar() returns TRUE (script file was active) or we
1891 * are inside a mapping, get out of insert mode.
1892 * Otherwise we behave like having gotten a CTRL-C.
1893 * As a result typing CTRL-C in insert mode will
1894 * really insert a CTRL-C.
1895 */
1896 if ((c || typebuf.tb_maplen)
1897 && (State & (INSERT + CMDLINE)))
1898 c = ESC;
1899 else
1900 c = Ctrl_C;
1901 flush_buffers(TRUE); /* flush all typeahead */
1902
1903 /* Also record this character, it might be needed to
1904 * get out of Insert mode. */
1905 *typebuf.tb_buf = c;
1906 gotchars(typebuf.tb_buf, 1);
1907 cmd_silent = FALSE;
1908
1909 break;
1910 }
1911 else if (typebuf.tb_len > 0)
1912 {
1913 /*
1914 * Check for a mappable key sequence.
1915 * Walk through one maphash[] list until we find an
1916 * entry that matches.
1917 *
1918 * Don't look for mappings if:
1919 * - no_mapping set: mapping disabled (e.g. for CTRL-V)
1920 * - maphash_valid not set: no mappings present.
1921 * - typebuf.tb_buf[typebuf.tb_off] should not be remapped
1922 * - in insert or cmdline mode and 'paste' option set
1923 * - waiting for "hit return to continue" and CR or SPACE
1924 * typed
1925 * - waiting for a char with --more--
1926 * - in Ctrl-X mode, and we get a valid char for that mode
1927 */
1928 mp = NULL;
1929 max_mlen = 0;
1930 c1 = typebuf.tb_buf[typebuf.tb_off];
1931 if (no_mapping == 0 && maphash_valid
1932 && (no_zero_mapping == 0 || c1 != '0')
1933 && (typebuf.tb_maplen == 0
1934 || (p_remap
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00001935 && (typebuf.tb_noremap[typebuf.tb_off]
1936 & (RM_NONE|RM_ABBR)) == 0))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001937 && !(p_paste && (State & (INSERT + CMDLINE)))
1938 && !(State == HITRETURN && (c1 == CAR || c1 == ' '))
1939 && State != ASKMORE
1940 && State != CONFIRM
1941#ifdef FEAT_INS_EXPAND
1942 && !((ctrl_x_mode != 0 && vim_is_ctrl_x_key(c1))
Bram Moolenaar4be06f92005-07-29 22:36:03 +00001943 || ((compl_cont_status & CONT_LOCAL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001944 && (c1 == Ctrl_N || c1 == Ctrl_P)))
1945#endif
1946 )
1947 {
1948#ifdef FEAT_LANGMAP
1949 if (c1 == K_SPECIAL)
1950 nolmaplen = 2;
1951 else
1952 {
1953 LANGMAP_ADJUST(c1, TRUE);
1954 nolmaplen = 0;
1955 }
1956#endif
1957#ifdef FEAT_LOCALMAP
1958 /* First try buffer-local mappings. */
1959 mp = curbuf->b_maphash[MAP_HASH(local_State, c1)];
1960 mp2 = maphash[MAP_HASH(local_State, c1)];
1961 if (mp == NULL)
1962 {
1963 mp = mp2;
1964 mp2 = NULL;
1965 }
1966#else
1967 mp = maphash[MAP_HASH(local_State, c1)];
1968#endif
1969 /*
1970 * Loop until a partly matching mapping is found or
1971 * all (local) mappings have been checked.
1972 * The longest full match is remembered in "mp_match".
1973 * A full match is only accepted if there is no partly
1974 * match, so "aa" and "aaa" can both be mapped.
1975 */
1976 mp_match = NULL;
1977 mp_match_len = 0;
1978 for ( ; mp != NULL;
1979#ifdef FEAT_LOCALMAP
1980 mp->m_next == NULL ? (mp = mp2, mp2 = NULL) :
1981#endif
1982 (mp = mp->m_next))
1983 {
1984 /*
1985 * Only consider an entry if the first character
1986 * matches and it is for the current state.
1987 * Skip ":lmap" mappings if keys were mapped.
1988 */
1989 if (mp->m_keys[0] == c1
1990 && (mp->m_mode & local_State)
1991 && ((mp->m_mode & LANGMAP) == 0
1992 || typebuf.tb_maplen == 0))
1993 {
1994#ifdef FEAT_LANGMAP
1995 int nomap = nolmaplen;
1996 int c2;
1997#endif
1998 /* find the match length of this mapping */
1999 for (mlen = 1; mlen < typebuf.tb_len; ++mlen)
2000 {
2001#ifdef FEAT_LANGMAP
2002 c2 = typebuf.tb_buf[typebuf.tb_off + mlen];
2003 if (nomap > 0)
2004 --nomap;
2005 else if (c2 == K_SPECIAL)
2006 nomap = 2;
2007 else
2008 LANGMAP_ADJUST(c2, TRUE);
2009 if (mp->m_keys[mlen] != c2)
2010#else
2011 if (mp->m_keys[mlen] !=
2012 typebuf.tb_buf[typebuf.tb_off + mlen])
2013#endif
2014 break;
2015 }
2016
2017#ifdef FEAT_MBYTE
2018 /* Don't allow mapping the first byte(s) of a
2019 * multi-byte char. Happens when mapping
2020 * <M-a> and then changing 'encoding'. */
2021 if (has_mbyte && MB_BYTE2LEN(c1)
Bram Moolenaar0fa313a2005-08-10 21:07:57 +00002022 > (*mb_ptr2len)(mp->m_keys))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002023 mlen = 0;
2024#endif
2025 /*
2026 * Check an entry whether it matches.
2027 * - Full match: mlen == keylen
2028 * - Partly match: mlen == typebuf.tb_len
2029 */
2030 keylen = mp->m_keylen;
2031 if (mlen == keylen
2032 || (mlen == typebuf.tb_len
2033 && typebuf.tb_len < keylen))
2034 {
2035 /*
2036 * If only script-local mappings are
2037 * allowed, check if the mapping starts
2038 * with K_SNR.
2039 */
2040 s = typebuf.tb_noremap + typebuf.tb_off;
2041 if (*s == RM_SCRIPT
2042 && (mp->m_keys[0] != K_SPECIAL
2043 || mp->m_keys[1] != KS_EXTRA
2044 || mp->m_keys[2]
2045 != (int)KE_SNR))
2046 continue;
2047 /*
2048 * If one of the typed keys cannot be
2049 * remapped, skip the entry.
2050 */
2051 for (n = mlen; --n >= 0; )
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002052 if (*s++ & (RM_NONE|RM_ABBR))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002053 break;
2054 if (n >= 0)
2055 continue;
2056
2057 if (keylen > typebuf.tb_len)
2058 {
2059 if (!timedout)
2060 {
2061 /* break at a partly match */
2062 keylen = KL_PART_MAP;
2063 break;
2064 }
2065 }
2066 else if (keylen > mp_match_len)
2067 {
2068 /* found a longer match */
2069 mp_match = mp;
2070 mp_match_len = keylen;
2071 }
2072 }
2073 else
2074 /* No match; may have to check for
2075 * termcode at next character. */
2076 if (max_mlen < mlen)
2077 max_mlen = mlen;
2078 }
2079 }
2080
2081 /* If no partly match found, use the longest full
2082 * match. */
2083 if (keylen != KL_PART_MAP)
2084 {
2085 mp = mp_match;
2086 keylen = mp_match_len;
2087 }
2088 }
2089
2090 /* Check for match with 'pastetoggle' */
2091 if (*p_pt != NUL && mp == NULL && (State & (INSERT|NORMAL)))
2092 {
2093 for (mlen = 0; mlen < typebuf.tb_len && p_pt[mlen];
2094 ++mlen)
2095 if (p_pt[mlen] != typebuf.tb_buf[typebuf.tb_off
2096 + mlen])
2097 break;
2098 if (p_pt[mlen] == NUL) /* match */
2099 {
2100 /* write chars to script file(s) */
2101 if (mlen > typebuf.tb_maplen)
2102 gotchars(typebuf.tb_buf + typebuf.tb_off
2103 + typebuf.tb_maplen,
2104 mlen - typebuf.tb_maplen);
2105
2106 del_typebuf(mlen, 0); /* remove the chars */
2107 set_option_value((char_u *)"paste",
2108 (long)!p_paste, NULL, 0);
2109 if (!(State & INSERT))
2110 {
2111 msg_col = 0;
2112 msg_row = Rows - 1;
2113 msg_clr_eos(); /* clear ruler */
2114 }
2115 showmode();
2116 setcursor();
2117 continue;
2118 }
2119 /* Need more chars for partly match. */
2120 if (mlen == typebuf.tb_len)
2121 keylen = KL_PART_MAP;
2122 else if (max_mlen < mlen)
2123 /* no match, may have to check for termcode at
2124 * next character */
2125 max_mlen = mlen + 1;
2126 }
2127
2128 if ((mp == NULL || max_mlen >= mp_match_len)
2129 && keylen != KL_PART_MAP)
2130 {
2131 /*
2132 * When no matching mapping found or found a
2133 * non-matching mapping that matches at least what the
2134 * matching mapping matched:
2135 * Check if we have a terminal code, when:
2136 * mapping is allowed,
2137 * keys have not been mapped,
2138 * and not an ESC sequence, not in insert mode or
2139 * p_ek is on,
2140 * and when not timed out,
2141 */
2142 if ((no_mapping == 0 || allow_keys != 0)
2143 && (typebuf.tb_maplen == 0
2144 || (p_remap && typebuf.tb_noremap[
2145 typebuf.tb_off] == RM_YES))
2146 && !timedout)
2147 {
2148 keylen = check_termcode(max_mlen + 1, NULL, 0);
2149
2150 /*
2151 * When getting a partial match, but the last
2152 * characters were not typed, don't wait for a
2153 * typed character to complete the termcode.
2154 * This helps a lot when a ":normal" command ends
2155 * in an ESC.
2156 */
2157 if (keylen < 0
2158 && typebuf.tb_len == typebuf.tb_maplen)
2159 keylen = 0;
2160 }
2161 else
2162 keylen = 0;
2163 if (keylen == 0) /* no matching terminal code */
2164 {
2165#ifdef AMIGA /* check for window bounds report */
2166 if (typebuf.tb_maplen == 0 && (typebuf.tb_buf[
2167 typebuf.tb_off] & 0xff) == CSI)
2168 {
2169 for (s = typebuf.tb_buf + typebuf.tb_off + 1;
2170 s < typebuf.tb_buf + typebuf.tb_off
2171 + typebuf.tb_len
2172 && (VIM_ISDIGIT(*s) || *s == ';'
2173 || *s == ' ');
2174 ++s)
2175 ;
2176 if (*s == 'r' || *s == '|') /* found one */
2177 {
2178 del_typebuf((int)(s + 1 -
2179 (typebuf.tb_buf + typebuf.tb_off)), 0);
2180 /* get size and redraw screen */
2181 shell_resized();
2182 continue;
2183 }
2184 if (*s == NUL) /* need more characters */
2185 keylen = KL_PART_KEY;
2186 }
2187 if (keylen >= 0)
2188#endif
2189 /* When there was a matching mapping and no
2190 * termcode could be replaced after another one,
2191 * use that mapping. */
2192 if (mp == NULL)
2193 {
2194/*
2195 * get a character: 2. from the typeahead buffer
2196 */
2197 c = typebuf.tb_buf[typebuf.tb_off] & 255;
2198 if (advance) /* remove chars from tb_buf */
2199 {
2200 cmd_silent = (typebuf.tb_silent > 0);
2201 if (typebuf.tb_maplen > 0)
2202 KeyTyped = FALSE;
2203 else
2204 {
2205 KeyTyped = TRUE;
2206 /* write char to script file(s) */
2207 gotchars(typebuf.tb_buf
2208 + typebuf.tb_off, 1);
2209 }
2210 KeyNoremap = (typebuf.tb_noremap[
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002211 typebuf.tb_off]
2212 & (RM_NONE|RM_SCRIPT));
Bram Moolenaar071d4272004-06-13 20:20:40 +00002213 del_typebuf(1, 0);
2214 }
2215 break; /* got character, break for loop */
2216 }
2217 }
2218 if (keylen > 0) /* full matching terminal code */
2219 {
2220#if defined(FEAT_GUI) && defined(FEAT_MENU)
2221 if (typebuf.tb_buf[typebuf.tb_off] == K_SPECIAL
2222 && typebuf.tb_buf[typebuf.tb_off + 1]
2223 == KS_MENU)
2224 {
2225 /*
2226 * Using a menu may cause a break in undo!
2227 * It's like using gotchars(), but without
2228 * recording or writing to a script file.
2229 */
2230 may_sync_undo();
2231 del_typebuf(3, 0);
2232 idx = get_menu_index(current_menu, local_State);
2233 if (idx != MENU_INDEX_INVALID)
2234 {
2235# ifdef FEAT_VISUAL
2236 /*
2237 * In Select mode, a Visual mode menu is
2238 * used. Switch to Visual mode
2239 * temporarily. Append K_SELECT to switch
2240 * back to Select mode.
2241 */
2242 if (VIsual_active && VIsual_select)
2243 {
2244 VIsual_select = FALSE;
2245 (void)ins_typebuf(K_SELECT_STRING,
2246 REMAP_NONE, 0, TRUE, FALSE);
2247 }
2248# endif
2249 ins_typebuf(current_menu->strings[idx],
2250 current_menu->noremap[idx],
2251 0, TRUE,
2252 current_menu->silent[idx]);
2253 }
2254 }
2255#endif /* FEAT_GUI */
2256 continue; /* try mapping again */
2257 }
2258
2259 /* Partial match: get some more characters. When a
2260 * matching mapping was found use that one. */
2261 if (mp == NULL || keylen < 0)
2262 keylen = KL_PART_KEY;
2263 else
2264 keylen = mp_match_len;
2265 }
2266
2267 /* complete match */
2268 if (keylen >= 0 && keylen <= typebuf.tb_len)
2269 {
2270 /* write chars to script file(s) */
2271 if (keylen > typebuf.tb_maplen)
2272 gotchars(typebuf.tb_buf + typebuf.tb_off
2273 + typebuf.tb_maplen,
2274 keylen - typebuf.tb_maplen);
2275
2276 cmd_silent = (typebuf.tb_silent > 0);
2277 del_typebuf(keylen, 0); /* remove the mapped keys */
2278
2279 /*
2280 * Put the replacement string in front of mapstr.
2281 * The depth check catches ":map x y" and ":map y x".
2282 */
2283 if (++mapdepth >= p_mmd)
2284 {
2285 EMSG(_("E223: recursive mapping"));
2286 if (State & CMDLINE)
2287 redrawcmdline();
2288 else
2289 setcursor();
2290 flush_buffers(FALSE);
2291 mapdepth = 0; /* for next one */
2292 c = -1;
2293 break;
2294 }
2295
2296#ifdef FEAT_VISUAL
2297 /*
2298 * In Select mode, a Visual mode mapping is used.
2299 * Switch to Visual mode temporarily. Append K_SELECT
2300 * to switch back to Select mode.
2301 */
2302 if (VIsual_active && VIsual_select)
2303 {
2304 VIsual_select = FALSE;
2305 (void)ins_typebuf(K_SELECT_STRING, REMAP_NONE,
2306 0, TRUE, FALSE);
2307 }
2308#endif
2309
2310 /*
2311 * Insert the 'to' part in the typebuf.tb_buf.
2312 * If 'from' field is the same as the start of the
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002313 * 'to' field, don't remap the first character (but do
2314 * allow abbreviations).
Bram Moolenaar071d4272004-06-13 20:20:40 +00002315 * If m_noremap is set, don't remap the whole 'to'
2316 * part.
2317 */
2318 if (ins_typebuf(mp->m_str,
2319 mp->m_noremap != REMAP_YES
2320 ? mp->m_noremap
2321 : STRNCMP(mp->m_str, mp->m_keys,
Bram Moolenaarf4b8e572004-06-24 15:53:16 +00002322 (size_t)keylen) != 0
2323 ? REMAP_YES : REMAP_SKIP,
Bram Moolenaar071d4272004-06-13 20:20:40 +00002324 0, TRUE, cmd_silent || mp->m_silent) == FAIL)
2325 {
2326 c = -1;
2327 break;
2328 }
2329 continue;
2330 }
2331 }
2332
2333/*
2334 * get a character: 3. from the user - handle <Esc> in Insert mode
2335 */
2336 /*
2337 * special case: if we get an <ESC> in insert mode and there
2338 * are no more characters at once, we pretend to go out of
2339 * insert mode. This prevents the one second delay after
2340 * typing an <ESC>. If we get something after all, we may
2341 * have to redisplay the mode. That the cursor is in the wrong
2342 * place does not matter.
2343 */
2344 c = 0;
2345#ifdef FEAT_CMDL_INFO
2346 new_wcol = curwin->w_wcol;
2347 new_wrow = curwin->w_wrow;
2348#endif
2349 if ( advance
2350 && typebuf.tb_len == 1
2351 && typebuf.tb_buf[typebuf.tb_off] == ESC
2352 && !no_mapping
2353#ifdef FEAT_EX_EXTRA
2354 && ex_normal_busy == 0
2355#endif
2356 && typebuf.tb_maplen == 0
2357 && (State & INSERT)
2358 && (p_timeout || (keylen == KL_PART_KEY && p_ttimeout))
2359 && (c = inchar(typebuf.tb_buf + typebuf.tb_off
2360 + typebuf.tb_len, 3, 25L,
2361 typebuf.tb_change_cnt)) == 0)
2362 {
2363 colnr_T col = 0, vcol;
2364 char_u *ptr;
2365
2366 if (p_smd)
2367 {
2368 unshowmode(TRUE);
2369 mode_deleted = TRUE;
2370 }
2371#ifdef FEAT_GUI
2372 /* may show different cursor shape */
2373 if (gui.in_use)
2374 {
2375 int save_State;
2376
2377 save_State = State;
2378 State = NORMAL;
2379 gui_update_cursor(TRUE, FALSE);
2380 State = save_State;
2381 shape_changed = TRUE;
2382 }
2383#endif
2384 validate_cursor();
2385 old_wcol = curwin->w_wcol;
2386 old_wrow = curwin->w_wrow;
2387
2388 /* move cursor left, if possible */
2389 if (curwin->w_cursor.col != 0)
2390 {
2391 if (curwin->w_wcol > 0)
2392 {
2393 if (did_ai)
2394 {
2395 /*
2396 * We are expecting to truncate the trailing
2397 * white-space, so find the last non-white
2398 * character -- webb
2399 */
2400 col = vcol = curwin->w_wcol = 0;
2401 ptr = ml_get_curline();
2402 while (col < curwin->w_cursor.col)
2403 {
2404 if (!vim_iswhite(ptr[col]))
2405 curwin->w_wcol = vcol;
2406 vcol += lbr_chartabsize(ptr + col,
2407 (colnr_T)vcol);
2408#ifdef FEAT_MBYTE
2409 if (has_mbyte)
Bram Moolenaar0fa313a2005-08-10 21:07:57 +00002410 col += (*mb_ptr2len)(ptr + col);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002411 else
2412#endif
2413 ++col;
2414 }
2415 curwin->w_wrow = curwin->w_cline_row
2416 + curwin->w_wcol / W_WIDTH(curwin);
2417 curwin->w_wcol %= W_WIDTH(curwin);
2418 curwin->w_wcol += curwin_col_off();
2419#ifdef FEAT_MBYTE
2420 col = 0; /* no correction needed */
2421#endif
2422 }
2423 else
2424 {
2425 --curwin->w_wcol;
2426#ifdef FEAT_MBYTE
2427 col = curwin->w_cursor.col - 1;
2428#endif
2429 }
2430 }
2431 else if (curwin->w_p_wrap && curwin->w_wrow)
2432 {
2433 --curwin->w_wrow;
2434 curwin->w_wcol = W_WIDTH(curwin) - 1;
2435#ifdef FEAT_MBYTE
2436 col = curwin->w_cursor.col - 1;
2437#endif
2438 }
2439#ifdef FEAT_MBYTE
2440 if (has_mbyte && col > 0 && curwin->w_wcol > 0)
2441 {
2442 /* Correct when the cursor is on the right halve
2443 * of a double-wide character. */
2444 ptr = ml_get_curline();
2445 col -= (*mb_head_off)(ptr, ptr + col);
2446 if ((*mb_ptr2cells)(ptr + col) > 1)
2447 --curwin->w_wcol;
2448 }
2449#endif
2450 }
2451 setcursor();
2452 out_flush();
2453#ifdef FEAT_CMDL_INFO
2454 new_wcol = curwin->w_wcol;
2455 new_wrow = curwin->w_wrow;
2456#endif
2457 curwin->w_wcol = old_wcol;
2458 curwin->w_wrow = old_wrow;
2459 }
2460 if (c < 0)
2461 continue; /* end of input script reached */
2462 typebuf.tb_len += c;
2463
2464 /* buffer full, don't map */
2465 if (typebuf.tb_len >= typebuf.tb_maplen + MAXMAPLEN)
2466 {
2467 timedout = TRUE;
2468 continue;
2469 }
2470
2471#ifdef FEAT_EX_EXTRA
2472 if (ex_normal_busy > 0)
2473 {
2474# ifdef FEAT_CMDWIN
2475 static int tc = 0;
2476# endif
2477
2478 /* No typeahead left and inside ":normal". Must return
2479 * something to avoid getting stuck. When an incomplete
2480 * mapping is present, behave like it timed out. */
2481 if (typebuf.tb_len > 0)
2482 {
2483 timedout = TRUE;
2484 continue;
2485 }
2486 /* When 'insertmode' is set, ESC just beeps in Insert
2487 * mode. Use CTRL-L to make edit() return.
2488 * For the command line only CTRL-C always breaks it.
2489 * For the cmdline window: Alternate between ESC and
2490 * CTRL-C: ESC for most situations and CTRL-C to close the
2491 * cmdline window. */
2492 if (p_im && (State & INSERT))
2493 c = Ctrl_L;
2494 else if ((State & CMDLINE)
2495# ifdef FEAT_CMDWIN
2496 || (cmdwin_type > 0 && tc == ESC)
2497# endif
2498 )
2499 c = Ctrl_C;
2500 else
2501 c = ESC;
2502# ifdef FEAT_CMDWIN
2503 tc = c;
2504# endif
2505 break;
2506 }
2507#endif
2508
2509/*
2510 * get a character: 3. from the user - update display
2511 */
2512 /* In insert mode a screen update is skipped when characters
2513 * are still available. But when those available characters
2514 * are part of a mapping, and we are going to do a blocking
2515 * wait here. Need to update the screen to display the
2516 * changed text so far. */
2517 if ((State & INSERT) && advance && must_redraw != 0)
2518 {
2519 update_screen(0);
2520 setcursor(); /* put cursor back where it belongs */
2521 }
2522
2523 /*
2524 * If we have a partial match (and are going to wait for more
2525 * input from the user), show the partially matched characters
2526 * to the user with showcmd.
2527 */
2528#ifdef FEAT_CMDL_INFO
2529 i = 0;
2530#endif
2531 c1 = 0;
2532 if (typebuf.tb_len > 0 && advance && !exmode_active)
2533 {
2534 if (((State & (NORMAL | INSERT)) || State == LANGMAP)
2535 && State != HITRETURN)
2536 {
2537 /* this looks nice when typing a dead character map */
2538 if (State & INSERT
2539 && ptr2cells(typebuf.tb_buf + typebuf.tb_off
2540 + typebuf.tb_len - 1) == 1)
2541 {
2542 edit_putchar(typebuf.tb_buf[typebuf.tb_off
2543 + typebuf.tb_len - 1], FALSE);
2544 setcursor(); /* put cursor back where it belongs */
2545 c1 = 1;
2546 }
2547#ifdef FEAT_CMDL_INFO
2548 /* need to use the col and row from above here */
2549 old_wcol = curwin->w_wcol;
2550 old_wrow = curwin->w_wrow;
2551 curwin->w_wcol = new_wcol;
2552 curwin->w_wrow = new_wrow;
2553 push_showcmd();
2554 if (typebuf.tb_len > SHOWCMD_COLS)
2555 i = typebuf.tb_len - SHOWCMD_COLS;
2556 while (i < typebuf.tb_len)
2557 (void)add_to_showcmd(typebuf.tb_buf[typebuf.tb_off
2558 + i++]);
2559 curwin->w_wcol = old_wcol;
2560 curwin->w_wrow = old_wrow;
2561#endif
2562 }
2563
2564 /* this looks nice when typing a dead character map */
2565 if ((State & CMDLINE)
2566#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
2567 && cmdline_star == 0
2568#endif
2569 && ptr2cells(typebuf.tb_buf + typebuf.tb_off
2570 + typebuf.tb_len - 1) == 1)
2571 {
2572 putcmdline(typebuf.tb_buf[typebuf.tb_off
2573 + typebuf.tb_len - 1], FALSE);
2574 c1 = 1;
2575 }
2576 }
2577
2578/*
2579 * get a character: 3. from the user - get it
2580 */
Bram Moolenaar28a37ff2005-03-15 22:28:00 +00002581 wait_tb_len = typebuf.tb_len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002582 c = inchar(typebuf.tb_buf + typebuf.tb_off + typebuf.tb_len,
2583 typebuf.tb_buflen - typebuf.tb_off - typebuf.tb_len - 1,
2584 !advance
2585 ? 0
2586 : ((typebuf.tb_len == 0
2587 || !(p_timeout || (p_ttimeout
2588 && keylen == KL_PART_KEY)))
2589 ? -1L
2590 : ((keylen == KL_PART_KEY && p_ttm >= 0)
2591 ? p_ttm
2592 : p_tm)), typebuf.tb_change_cnt);
2593
2594#ifdef FEAT_CMDL_INFO
2595 if (i != 0)
2596 pop_showcmd();
2597#endif
2598 if (c1 == 1)
2599 {
2600 if (State & INSERT)
2601 edit_unputchar();
2602 if (State & CMDLINE)
2603 unputcmdline();
2604 setcursor(); /* put cursor back where it belongs */
2605 }
2606
2607 if (c < 0)
2608 continue; /* end of input script reached */
2609 if (c == NUL) /* no character available */
2610 {
2611 if (!advance)
2612 break;
Bram Moolenaar28a37ff2005-03-15 22:28:00 +00002613 if (wait_tb_len > 0) /* timed out */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002614 {
2615 timedout = TRUE;
2616 continue;
2617 }
2618 }
2619 else
2620 { /* allow mapping for just typed characters */
2621 while (typebuf.tb_buf[typebuf.tb_off
2622 + typebuf.tb_len] != NUL)
2623 typebuf.tb_noremap[typebuf.tb_off
2624 + typebuf.tb_len++] = RM_YES;
2625#ifdef USE_IM_CONTROL
2626 /* Get IM status right after getting keys, not after the
2627 * timeout for a mapping (focus may be lost by then). */
2628 vgetc_im_active = im_get_status();
2629#endif
2630 }
2631 } /* for (;;) */
2632 } /* if (!character from stuffbuf) */
2633
2634 /* if advance is FALSE don't loop on NULs */
2635 } while (c < 0 || (advance && c == NUL));
2636
2637 /*
2638 * The "INSERT" message is taken care of here:
2639 * if we return an ESC to exit insert mode, the message is deleted
2640 * if we don't return an ESC but deleted the message before, redisplay it
2641 */
2642 if (advance && p_smd && (State & INSERT))
2643 {
2644 if (c == ESC && !mode_deleted && !no_mapping)
2645 {
2646 if (typebuf.tb_len && !KeyTyped)
2647 redraw_cmdline = TRUE; /* delete mode later */
2648 else
2649 unshowmode(FALSE);
2650 }
2651 else if (c != ESC && mode_deleted)
2652 {
2653 if (typebuf.tb_len && !KeyTyped)
2654 redraw_cmdline = TRUE; /* show mode later */
2655 else
2656 showmode();
2657 }
2658 }
2659#ifdef FEAT_GUI
2660 /* may unshow different cursor shape */
2661 if (gui.in_use && shape_changed)
2662 gui_update_cursor(TRUE, FALSE);
2663#endif
2664
2665 vgetc_busy = FALSE;
2666
2667 return c;
2668}
2669
2670/*
2671 * inchar() - get one character from
2672 * 1. a scriptfile
2673 * 2. the keyboard
2674 *
2675 * As much characters as we can get (upto 'maxlen') are put in "buf" and
2676 * NUL terminated (buffer length must be 'maxlen' + 1).
2677 * Minimum for "maxlen" is 3!!!!
2678 *
2679 * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
2680 * it. When typebuf.tb_change_cnt changes (e.g., when a message is received
2681 * from a remote client) "buf" can no longer be used. "tb_change_cnt" is 0
2682 * otherwise.
2683 *
2684 * If we got an interrupt all input is read until none is available.
2685 *
2686 * If wait_time == 0 there is no waiting for the char.
2687 * If wait_time == n we wait for n msec for a character to arrive.
2688 * If wait_time == -1 we wait forever for a character to arrive.
2689 *
2690 * Return the number of obtained characters.
2691 * Return -1 when end of input script reached.
2692 */
2693 int
2694inchar(buf, maxlen, wait_time, tb_change_cnt)
2695 char_u *buf;
2696 int maxlen;
2697 long wait_time; /* milli seconds */
2698 int tb_change_cnt;
2699{
2700 int len = 0; /* init for GCC */
2701 int retesc = FALSE; /* return ESC with gotint */
2702 int script_char;
2703
2704 if (wait_time == -1L || wait_time > 100L) /* flush output before waiting */
2705 {
2706 cursor_on();
2707 out_flush();
2708#ifdef FEAT_GUI
2709 if (gui.in_use)
2710 {
2711 gui_update_cursor(FALSE, FALSE);
2712# ifdef FEAT_MOUSESHAPE
2713 if (postponed_mouseshape)
2714 update_mouseshape(-1);
2715# endif
2716 }
2717#endif
2718 }
2719
2720 /*
2721 * Don't reset these when at the hit-return prompt, otherwise a endless
2722 * recursive loop may result (write error in swapfile, hit-return, timeout
2723 * on char wait, flush swapfile, write error....).
2724 */
2725 if (State != HITRETURN)
2726 {
2727 did_outofmem_msg = FALSE; /* display out of memory message (again) */
2728 did_swapwrite_msg = FALSE; /* display swap file write error again */
2729 }
2730 undo_off = FALSE; /* restart undo now */
2731
2732 /*
2733 * first try script file
2734 * If interrupted: Stop reading script files.
2735 */
2736 script_char = -1;
2737 while (scriptin[curscript] != NULL && script_char < 0)
2738 {
2739 if (got_int || (script_char = getc(scriptin[curscript])) < 0)
2740 {
2741 /* Reached EOF.
2742 * Careful: closescript() frees typebuf.tb_buf[] and buf[] may
2743 * point inside typebuf.tb_buf[]. Don't use buf[] after this! */
2744 closescript();
2745 /*
2746 * When reading script file is interrupted, return an ESC to get
2747 * back to normal mode.
2748 * Otherwise return -1, because typebuf.tb_buf[] has changed.
2749 */
2750 if (got_int)
2751 retesc = TRUE;
2752 else
2753 return -1;
2754 }
2755 else
2756 {
2757 buf[0] = script_char;
2758 len = 1;
2759 }
2760 }
2761
2762 if (script_char < 0) /* did not get a character from script */
2763 {
2764 /*
2765 * If we got an interrupt, skip all previously typed characters and
2766 * return TRUE if quit reading script file.
2767 * Stop reading typeahead when a single CTRL-C was read,
2768 * fill_input_buf() returns this when not able to read from stdin.
2769 * Don't use buf[] here, closescript() may have freed typebuf.tb_buf[]
2770 * and buf may be pointing inside typebuf.tb_buf[].
2771 */
2772 if (got_int)
2773 {
2774#define DUM_LEN MAXMAPLEN * 3 + 3
2775 char_u dum[DUM_LEN + 1];
2776
2777 for (;;)
2778 {
2779 len = ui_inchar(dum, DUM_LEN, 0L, 0);
2780 if (len == 0 || (len == 1 && dum[0] == 3))
2781 break;
2782 }
2783 return retesc;
2784 }
2785
2786 /*
2787 * Always flush the output characters when getting input characters
2788 * from the user.
2789 */
2790 out_flush();
2791
2792 /*
2793 * Fill up to a third of the buffer, because each character may be
2794 * tripled below.
2795 */
2796 len = ui_inchar(buf, maxlen / 3, wait_time, tb_change_cnt);
2797 }
2798
2799 if (typebuf_changed(tb_change_cnt))
2800 return 0;
2801
2802 return fix_input_buffer(buf, len, script_char >= 0);
2803}
2804
2805/*
2806 * Fix typed characters for use by vgetc() and check_termcode().
2807 * buf[] must have room to triple the number of bytes!
2808 * Returns the new length.
2809 */
2810 int
2811fix_input_buffer(buf, len, script)
2812 char_u *buf;
2813 int len;
2814 int script; /* TRUE when reading from a script */
2815{
2816 int i;
2817 char_u *p = buf;
2818
2819 /*
2820 * Two characters are special: NUL and K_SPECIAL.
2821 * When compiled With the GUI CSI is also special.
2822 * Replace NUL by K_SPECIAL KS_ZERO KE_FILLER
2823 * Replace K_SPECIAL by K_SPECIAL KS_SPECIAL KE_FILLER
2824 * Replace CSI by K_SPECIAL KS_EXTRA KE_CSI
2825 * Don't replace K_SPECIAL when reading a script file.
2826 */
2827 for (i = len; --i >= 0; ++p)
2828 {
2829#ifdef FEAT_GUI
2830 /* When the GUI is used any character can come after a CSI, don't
2831 * escape it. */
2832 if (gui.in_use && p[0] == CSI && i >= 2)
2833 {
2834 p += 2;
2835 i -= 2;
2836 }
2837 /* When the GUI is not used CSI needs to be escaped. */
2838 else if (!gui.in_use && p[0] == CSI)
2839 {
2840 mch_memmove(p + 3, p + 1, (size_t)i);
2841 *p++ = K_SPECIAL;
2842 *p++ = KS_EXTRA;
2843 *p = (int)KE_CSI;
2844 len += 2;
2845 }
2846 else
2847#endif
2848 if (p[0] == NUL || (p[0] == K_SPECIAL && !script
Bram Moolenaar28a37ff2005-03-15 22:28:00 +00002849#ifdef FEAT_AUTOCMD
2850 /* timeout may generate K_CURSORHOLD */
2851 && (i < 2 || p[1] != KS_EXTRA || p[2] != (int)KE_CURSORHOLD)
2852#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002853#if defined(WIN3264) && !defined(FEAT_GUI)
2854 /* Win32 console passes modifiers */
2855 && (i < 2 || p[1] != KS_MODIFIER)
2856#endif
2857 ))
2858 {
2859 mch_memmove(p + 3, p + 1, (size_t)i);
2860 p[2] = K_THIRD(p[0]);
2861 p[1] = K_SECOND(p[0]);
2862 p[0] = K_SPECIAL;
2863 p += 2;
2864 len += 2;
2865 }
2866 }
2867 *p = NUL; /* add trailing NUL */
2868 return len;
2869}
2870
2871#if defined(USE_INPUT_BUF) || defined(PROTO)
2872/*
2873 * Return TRUE when bytes are in the input buffer or in the typeahead buffer.
2874 * Normally the input buffer would be sufficient, but the server_to_input_buf()
2875 * may insert characters in the typeahead buffer while we are waiting for
2876 * input to arrive.
2877 */
2878 int
2879input_available()
2880{
2881 return (!vim_is_input_buf_empty()
2882# ifdef FEAT_CLIENTSERVER
2883 || received_from_client
2884# endif
2885 );
2886}
2887#endif
2888
2889/*
2890 * map[!] : show all key mappings
2891 * map[!] {lhs} : show key mapping for {lhs}
2892 * map[!] {lhs} {rhs} : set key mapping for {lhs} to {rhs}
2893 * noremap[!] {lhs} {rhs} : same, but no remapping for {rhs}
2894 * unmap[!] {lhs} : remove key mapping for {lhs}
2895 * abbr : show all abbreviations
2896 * abbr {lhs} : show abbreviations for {lhs}
2897 * abbr {lhs} {rhs} : set abbreviation for {lhs} to {rhs}
2898 * noreabbr {lhs} {rhs} : same, but no remapping for {rhs}
2899 * unabbr {lhs} : remove abbreviation for {lhs}
2900 *
2901 * maptype: 0 for :map, 1 for :unmap, 2 for noremap.
2902 *
2903 * arg is pointer to any arguments. Note: arg cannot be a read-only string,
2904 * it will be modified.
2905 *
2906 * for :map mode is NORMAL + VISUAL + OP_PENDING
2907 * for :map! mode is INSERT + CMDLINE
2908 * for :cmap mode is CMDLINE
2909 * for :imap mode is INSERT
2910 * for :lmap mode is LANGMAP
2911 * for :nmap mode is NORMAL
2912 * for :vmap mode is VISUAL
2913 * for :omap mode is OP_PENDING
2914 *
2915 * for :abbr mode is INSERT + CMDLINE
2916 * for :iabbr mode is INSERT
2917 * for :cabbr mode is CMDLINE
2918 *
2919 * Return 0 for success
2920 * 1 for invalid arguments
2921 * 2 for no match
2922 * 4 for out of mem
2923 * 5 for entry not unique
2924 */
2925 int
2926do_map(maptype, arg, mode, abbrev)
2927 int maptype;
2928 char_u *arg;
2929 int mode;
2930 int abbrev; /* not a mapping but an abbreviation */
2931{
2932 char_u *keys;
2933 mapblock_T *mp, **mpp;
2934 char_u *rhs;
2935 char_u *p;
2936 int n;
2937 int len = 0; /* init for GCC */
2938 char_u *newstr;
2939 int hasarg;
2940 int haskey;
2941 int did_it = FALSE;
2942#ifdef FEAT_LOCALMAP
2943 int did_local = FALSE;
2944#endif
2945 int round;
2946 char_u *keys_buf = NULL;
2947 char_u *arg_buf = NULL;
2948 int retval = 0;
2949 int do_backslash;
2950 int hash;
2951 int new_hash;
2952 mapblock_T **abbr_table;
2953 mapblock_T **map_table;
2954 int unique = FALSE;
2955 int silent = FALSE;
2956 int noremap;
2957
2958 keys = arg;
2959 map_table = maphash;
2960 abbr_table = &first_abbr;
2961
2962 /* For ":noremap" don't remap, otherwise do remap. */
2963 if (maptype == 2)
2964 noremap = REMAP_NONE;
2965 else
2966 noremap = REMAP_YES;
2967
2968 /* Accept <buffer>, <silent>, <script> and <unique> in any order. */
2969 for (;;)
2970 {
2971#ifdef FEAT_LOCALMAP
2972 /*
2973 * Check for "<buffer>": mapping local to buffer.
2974 */
2975 if (STRNCMP(keys, "<buffer>", 8) == 0)
2976 {
2977 keys = skipwhite(keys + 8);
2978 map_table = curbuf->b_maphash;
2979 abbr_table = &curbuf->b_first_abbr;
2980 continue;
2981 }
2982#endif
2983
2984 /*
2985 * Check for "<silent>": don't echo commands.
2986 */
2987 if (STRNCMP(keys, "<silent>", 8) == 0)
2988 {
2989 keys = skipwhite(keys + 8);
2990 silent = TRUE;
2991 continue;
2992 }
2993
2994#ifdef FEAT_EVAL
2995 /*
2996 * Check for "<script>": remap script-local mappings only
2997 */
2998 if (STRNCMP(keys, "<script>", 8) == 0)
2999 {
3000 keys = skipwhite(keys + 8);
3001 noremap = REMAP_SCRIPT;
3002 continue;
3003 }
3004#endif
3005 /*
3006 * Check for "<unique>": don't overwrite an existing mapping.
3007 */
3008 if (STRNCMP(keys, "<unique>", 8) == 0)
3009 {
3010 keys = skipwhite(keys + 8);
3011 unique = TRUE;
3012 continue;
3013 }
3014 break;
3015 }
3016
3017 validate_maphash();
3018
3019 /*
3020 * find end of keys and skip CTRL-Vs (and backslashes) in it
3021 * Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'.
3022 * with :unmap white space is included in the keys, no argument possible
3023 */
3024 p = keys;
3025 do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL);
3026 while (*p && (maptype == 1 || !vim_iswhite(*p)))
3027 {
3028 if ((p[0] == Ctrl_V || (do_backslash && p[0] == '\\')) &&
3029 p[1] != NUL)
3030 ++p; /* skip CTRL-V or backslash */
3031 ++p;
3032 }
3033 if (*p != NUL)
3034 *p++ = NUL;
3035 p = skipwhite(p);
3036 rhs = p;
3037 hasarg = (*rhs != NUL);
3038 haskey = (*keys != NUL);
3039
3040 /* check for :unmap without argument */
3041 if (maptype == 1 && !haskey)
3042 {
3043 retval = 1;
3044 goto theend;
3045 }
3046
3047 /*
3048 * If mapping has been given as ^V<C_UP> say, then replace the term codes
3049 * with the appropriate two bytes. If it is a shifted special key, unshift
3050 * it too, giving another two bytes.
3051 * replace_termcodes() may move the result to allocated memory, which
3052 * needs to be freed later (*keys_buf and *arg_buf).
3053 * replace_termcodes() also removes CTRL-Vs and sometimes backslashes.
3054 */
3055 if (haskey)
3056 keys = replace_termcodes(keys, &keys_buf, TRUE, TRUE);
3057 if (hasarg)
3058 {
3059 if (STRICMP(rhs, "<nop>") == 0) /* "<Nop>" means nothing */
3060 rhs = (char_u *)"";
3061 else
3062 rhs = replace_termcodes(rhs, &arg_buf, FALSE, TRUE);
3063 }
3064
3065#ifdef FEAT_FKMAP
3066 /*
3067 * when in right-to-left mode and alternate keymap option set,
3068 * reverse the character flow in the rhs in Farsi.
3069 */
3070 if (p_altkeymap && curwin->w_p_rl)
3071 lrswap(rhs);
3072#endif
3073
3074 /*
3075 * check arguments and translate function keys
3076 */
3077 if (haskey)
3078 {
3079 len = (int)STRLEN(keys);
3080 if (len > MAXMAPLEN) /* maximum length of MAXMAPLEN chars */
3081 {
3082 retval = 1;
3083 goto theend;
3084 }
3085
3086 if (abbrev && maptype != 1)
3087 {
3088 /*
3089 * If an abbreviation ends in a keyword character, the
3090 * rest must be all keyword-char or all non-keyword-char.
3091 * Otherwise we won't be able to find the start of it in a
3092 * vi-compatible way.
3093 */
3094#ifdef FEAT_MBYTE
3095 if (has_mbyte)
3096 {
3097 int first, last;
3098 int same = -1;
3099
3100 first = vim_iswordp(keys);
3101 last = first;
Bram Moolenaar0fa313a2005-08-10 21:07:57 +00003102 p = keys + (*mb_ptr2len)(keys);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003103 n = 1;
3104 while (p < keys + len)
3105 {
3106 ++n; /* nr of (multi-byte) chars */
3107 last = vim_iswordp(p); /* type of last char */
3108 if (same == -1 && last != first)
3109 same = n - 1; /* count of same char type */
Bram Moolenaar0fa313a2005-08-10 21:07:57 +00003110 p += (*mb_ptr2len)(p);
Bram Moolenaar071d4272004-06-13 20:20:40 +00003111 }
3112 if (last && n > 2 && same >= 0 && same < n - 1)
3113 {
3114 retval = 1;
3115 goto theend;
3116 }
3117 }
3118 else
3119#endif
3120 if (vim_iswordc(keys[len - 1])) /* ends in keyword char */
3121 for (n = 0; n < len - 2; ++n)
3122 if (vim_iswordc(keys[n]) != vim_iswordc(keys[len - 2]))
3123 {
3124 retval = 1;
3125 goto theend;
3126 }
3127 /* An abbrevation cannot contain white space. */
3128 for (n = 0; n < len; ++n)
3129 if (vim_iswhite(keys[n]))
3130 {
3131 retval = 1;
3132 goto theend;
3133 }
3134 }
3135 }
3136
3137 if (haskey && hasarg && abbrev) /* if we will add an abbreviation */
3138 no_abbr = FALSE; /* reset flag that indicates there are
3139 no abbreviations */
3140
3141 if (!haskey || (maptype != 1 && !hasarg))
3142 msg_start();
3143
3144#ifdef FEAT_LOCALMAP
3145 /*
3146 * Check if a new local mapping wasn't already defined globally.
3147 */
3148 if (map_table == curbuf->b_maphash && haskey && hasarg && maptype != 1)
3149 {
3150 /* need to loop over all global hash lists */
3151 for (hash = 0; hash < 256 && !got_int; ++hash)
3152 {
3153 if (abbrev)
3154 {
3155 if (hash != 0) /* there is only one abbreviation list */
3156 break;
3157 mp = first_abbr;
3158 }
3159 else
3160 mp = maphash[hash];
3161 for ( ; mp != NULL && !got_int; mp = mp->m_next)
3162 {
3163 /* check entries with the same mode */
3164 if ((mp->m_mode & mode) != 0
3165 && mp->m_keylen == len
3166 && unique
3167 && STRNCMP(mp->m_keys, keys, (size_t)len) == 0)
3168 {
3169 if (abbrev)
3170 EMSG2(_("E224: global abbreviation already exists for %s"),
3171 mp->m_keys);
3172 else
3173 EMSG2(_("E225: global mapping already exists for %s"),
3174 mp->m_keys);
3175 retval = 5;
3176 goto theend;
3177 }
3178 }
3179 }
3180 }
3181
3182 /*
3183 * When listing global mappings, also list buffer-local ones here.
3184 */
3185 if (map_table != curbuf->b_maphash && !hasarg && maptype != 1)
3186 {
3187 /* need to loop over all global hash lists */
3188 for (hash = 0; hash < 256 && !got_int; ++hash)
3189 {
3190 if (abbrev)
3191 {
3192 if (hash != 0) /* there is only one abbreviation list */
3193 break;
3194 mp = curbuf->b_first_abbr;
3195 }
3196 else
3197 mp = curbuf->b_maphash[hash];
3198 for ( ; mp != NULL && !got_int; mp = mp->m_next)
3199 {
3200 /* check entries with the same mode */
3201 if ((mp->m_mode & mode) != 0)
3202 {
3203 if (!haskey) /* show all entries */
3204 {
3205 showmap(mp, TRUE);
3206 did_local = TRUE;
3207 }
3208 else
3209 {
3210 n = mp->m_keylen;
3211 if (STRNCMP(mp->m_keys, keys,
3212 (size_t)(n < len ? n : len)) == 0)
3213 {
3214 showmap(mp, TRUE);
3215 did_local = TRUE;
3216 }
3217 }
3218 }
3219 }
3220 }
3221 }
3222#endif
3223
3224 /*
3225 * Find an entry in the maphash[] list that matches.
3226 * For :unmap we may loop two times: once to try to unmap an entry with a
3227 * matching 'from' part, a second time, if the first fails, to unmap an
3228 * entry with a matching 'to' part. This was done to allow ":ab foo bar"
3229 * to be unmapped by typing ":unab foo", where "foo" will be replaced by
3230 * "bar" because of the abbreviation.
3231 */
3232 for (round = 0; (round == 0 || maptype == 1) && round <= 1
3233 && !did_it && !got_int; ++round)
3234 {
3235 /* need to loop over all hash lists */
3236 for (hash = 0; hash < 256 && !got_int; ++hash)
3237 {
3238 if (abbrev)
3239 {
3240 if (hash != 0) /* there is only one abbreviation list */
3241 break;
3242 mpp = abbr_table;
3243 }
3244 else
3245 mpp = &(map_table[hash]);
3246 for (mp = *mpp; mp != NULL && !got_int; mp = *mpp)
3247 {
3248
3249 if (!(mp->m_mode & mode)) /* skip entries with wrong mode */
3250 {
3251 mpp = &(mp->m_next);
3252 continue;
3253 }
3254 if (!haskey) /* show all entries */
3255 {
3256 showmap(mp, map_table != maphash);
3257 did_it = TRUE;
3258 }
3259 else /* do we have a match? */
3260 {
3261 if (round) /* second round: Try unmap "rhs" string */
3262 {
3263 n = (int)STRLEN(mp->m_str);
3264 p = mp->m_str;
3265 }
3266 else
3267 {
3268 n = mp->m_keylen;
3269 p = mp->m_keys;
3270 }
3271 if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0)
3272 {
3273 if (maptype == 1) /* delete entry */
3274 {
3275 /* Only accept a full match. For abbreviations we
3276 * ignore trailing space when matching with the
3277 * "lhs", since an abbreviation can't have
3278 * trailing space. */
3279 if (n != len && (!abbrev || round || n > len
3280 || *skipwhite(keys + n) != NUL))
3281 {
3282 mpp = &(mp->m_next);
3283 continue;
3284 }
3285 /*
3286 * We reset the indicated mode bits. If nothing is
3287 * left the entry is deleted below.
3288 */
3289 mp->m_mode &= ~mode;
3290 did_it = TRUE; /* remember we did something */
3291 }
3292 else if (!hasarg) /* show matching entry */
3293 {
3294 showmap(mp, map_table != maphash);
3295 did_it = TRUE;
3296 }
3297 else if (n != len) /* new entry is ambigious */
3298 {
3299 mpp = &(mp->m_next);
3300 continue;
3301 }
3302 else if (unique)
3303 {
3304 if (abbrev)
3305 EMSG2(_("E226: abbreviation already exists for %s"),
3306 p);
3307 else
3308 EMSG2(_("E227: mapping already exists for %s"), p);
3309 retval = 5;
3310 goto theend;
3311 }
3312 else /* new rhs for existing entry */
3313 {
3314 mp->m_mode &= ~mode; /* remove mode bits */
3315 if (mp->m_mode == 0 && !did_it) /* reuse entry */
3316 {
3317 newstr = vim_strsave(rhs);
3318 if (newstr == NULL)
3319 {
3320 retval = 4; /* no mem */
3321 goto theend;
3322 }
3323 vim_free(mp->m_str);
3324 mp->m_str = newstr;
3325 mp->m_noremap = noremap;
3326 mp->m_silent = silent;
3327 mp->m_mode = mode;
3328 did_it = TRUE;
3329 }
3330 }
3331 if (mp->m_mode == 0) /* entry can be deleted */
3332 {
3333 map_free(mpp);
3334 continue; /* continue with *mpp */
3335 }
3336
3337 /*
3338 * May need to put this entry into another hash list.
3339 */
3340 new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
3341 if (!abbrev && new_hash != hash)
3342 {
3343 *mpp = mp->m_next;
3344 mp->m_next = map_table[new_hash];
3345 map_table[new_hash] = mp;
3346
3347 continue; /* continue with *mpp */
3348 }
3349 }
3350 }
3351 mpp = &(mp->m_next);
3352 }
3353 }
3354 }
3355
3356 if (maptype == 1) /* delete entry */
3357 {
3358 if (!did_it)
3359 retval = 2; /* no match */
3360 goto theend;
3361 }
3362
3363 if (!haskey || !hasarg) /* print entries */
3364 {
3365 if (!did_it
3366#ifdef FEAT_LOCALMAP
3367 && !did_local
3368#endif
3369 )
3370 {
3371 if (abbrev)
3372 MSG(_("No abbreviation found"));
3373 else
3374 MSG(_("No mapping found"));
3375 }
3376 goto theend; /* listing finished */
3377 }
3378
3379 if (did_it) /* have added the new entry already */
3380 goto theend;
3381
3382 /*
3383 * Get here when adding a new entry to the maphash[] list or abbrlist.
3384 */
3385 mp = (mapblock_T *)alloc((unsigned)sizeof(mapblock_T));
3386 if (mp == NULL)
3387 {
3388 retval = 4; /* no mem */
3389 goto theend;
3390 }
3391
3392 /* If CTRL-C has been mapped, don't always use it for Interrupting */
3393 if (*keys == Ctrl_C)
3394 mapped_ctrl_c = TRUE;
3395
3396 mp->m_keys = vim_strsave(keys);
3397 mp->m_str = vim_strsave(rhs);
3398 if (mp->m_keys == NULL || mp->m_str == NULL)
3399 {
3400 vim_free(mp->m_keys);
3401 vim_free(mp->m_str);
3402 vim_free(mp);
3403 retval = 4; /* no mem */
3404 goto theend;
3405 }
3406 mp->m_keylen = (int)STRLEN(mp->m_keys);
3407 mp->m_noremap = noremap;
3408 mp->m_silent = silent;
3409 mp->m_mode = mode;
3410
3411 /* add the new entry in front of the abbrlist or maphash[] list */
3412 if (abbrev)
3413 {
3414 mp->m_next = *abbr_table;
3415 *abbr_table = mp;
3416 }
3417 else
3418 {
3419 n = MAP_HASH(mp->m_mode, mp->m_keys[0]);
3420 mp->m_next = map_table[n];
3421 map_table[n] = mp;
3422 }
3423
3424theend:
3425 vim_free(keys_buf);
3426 vim_free(arg_buf);
3427 return retval;
3428}
3429
3430/*
3431 * Delete one entry from the abbrlist or maphash[].
3432 * "mpp" is a pointer to the m_next field of the PREVIOUS entry!
3433 */
3434 static void
3435map_free(mpp)
3436 mapblock_T **mpp;
3437{
3438 mapblock_T *mp;
3439
3440 mp = *mpp;
3441 vim_free(mp->m_keys);
3442 vim_free(mp->m_str);
3443 *mpp = mp->m_next;
3444 vim_free(mp);
3445}
3446
3447/*
3448 * Initialize maphash[] for first use.
3449 */
3450 static void
3451validate_maphash()
3452{
3453 if (!maphash_valid)
3454 {
3455 vim_memset(maphash, 0, sizeof(maphash));
3456 maphash_valid = TRUE;
3457 }
3458}
3459
3460/*
3461 * Get the mapping mode from the command name.
3462 */
3463 int
3464get_map_mode(cmdp, forceit)
3465 char_u **cmdp;
3466 int forceit;
3467{
3468 char_u *p;
3469 int modec;
3470 int mode;
3471
3472 p = *cmdp;
3473 modec = *p++;
3474 if (modec == 'i')
3475 mode = INSERT; /* :imap */
3476 else if (modec == 'l')
3477 mode = LANGMAP; /* :lmap */
3478 else if (modec == 'c')
3479 mode = CMDLINE; /* :cmap */
3480 else if (modec == 'n' && *p != 'o') /* avoid :noremap */
3481 mode = NORMAL; /* :nmap */
3482 else if (modec == 'v')
3483 mode = VISUAL; /* :vmap */
3484 else if (modec == 'o')
3485 mode = OP_PENDING; /* :omap */
3486 else
3487 {
3488 --p;
3489 if (forceit)
3490 mode = INSERT + CMDLINE; /* :map ! */
3491 else
3492 mode = VISUAL + NORMAL + OP_PENDING;/* :map */
3493 }
3494
3495 *cmdp = p;
3496 return mode;
3497}
3498
3499/*
3500 * Clear all mappings or abbreviations.
3501 * 'abbr' should be FALSE for mappings, TRUE for abbreviations.
3502 */
3503/*ARGSUSED*/
3504 void
3505map_clear(cmdp, arg, forceit, abbr)
3506 char_u *cmdp;
3507 char_u *arg;
3508 int forceit;
3509 int abbr;
3510{
3511 int mode;
3512#ifdef FEAT_LOCALMAP
3513 int local;
3514
3515 local = (STRCMP(arg, "<buffer>") == 0);
3516 if (!local && *arg != NUL)
3517 {
3518 EMSG(_(e_invarg));
3519 return;
3520 }
3521#endif
3522
3523 mode = get_map_mode(&cmdp, forceit);
3524 map_clear_int(curbuf, mode,
3525#ifdef FEAT_LOCALMAP
3526 local,
3527#else
3528 FALSE,
3529#endif
3530 abbr);
3531}
3532
3533/*
3534 * Clear all mappings in "mode".
3535 */
3536/*ARGSUSED*/
3537 void
3538map_clear_int(buf, mode, local, abbr)
3539 buf_T *buf; /* buffer for local mappings */
3540 int mode; /* mode in which to delete */
3541 int local; /* TRUE for buffer-local mappings */
3542 int abbr; /* TRUE for abbreviations */
3543{
3544 mapblock_T *mp, **mpp;
3545 int hash;
3546 int new_hash;
3547
3548 validate_maphash();
3549
3550 for (hash = 0; hash < 256; ++hash)
3551 {
3552 if (abbr)
3553 {
3554 if (hash) /* there is only one abbrlist */
3555 break;
3556#ifdef FEAT_LOCALMAP
3557 if (local)
3558 mpp = &buf->b_first_abbr;
3559 else
3560#endif
3561 mpp = &first_abbr;
3562 }
3563 else
3564 {
3565#ifdef FEAT_LOCALMAP
3566 if (local)
3567 mpp = &buf->b_maphash[hash];
3568 else
3569#endif
3570 mpp = &maphash[hash];
3571 }
3572 while (*mpp != NULL)
3573 {
3574 mp = *mpp;
3575 if (mp->m_mode & mode)
3576 {
3577 mp->m_mode &= ~mode;
3578 if (mp->m_mode == 0) /* entry can be deleted */
3579 {
3580 map_free(mpp);
3581 continue;
3582 }
3583 /*
3584 * May need to put this entry into another hash list.
3585 */
3586 new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]);
3587 if (!abbr && new_hash != hash)
3588 {
3589 *mpp = mp->m_next;
3590#ifdef FEAT_LOCALMAP
3591 if (local)
3592 {
3593 mp->m_next = buf->b_maphash[new_hash];
3594 buf->b_maphash[new_hash] = mp;
3595 }
3596 else
3597#endif
3598 {
3599 mp->m_next = maphash[new_hash];
3600 maphash[new_hash] = mp;
3601 }
3602 continue; /* continue with *mpp */
3603 }
3604 }
3605 mpp = &(mp->m_next);
3606 }
3607 }
3608}
3609
3610 static void
3611showmap(mp, local)
3612 mapblock_T *mp;
3613 int local; /* TRUE for buffer-local map */
3614{
3615 int len = 1;
3616
3617 if (msg_didout || msg_silent != 0)
3618 msg_putchar('\n');
3619 if ((mp->m_mode & (INSERT + CMDLINE)) == INSERT + CMDLINE)
3620 msg_putchar('!'); /* :map! */
3621 else if (mp->m_mode & INSERT)
3622 msg_putchar('i'); /* :imap */
3623 else if (mp->m_mode & LANGMAP)
3624 msg_putchar('l'); /* :lmap */
3625 else if (mp->m_mode & CMDLINE)
3626 msg_putchar('c'); /* :cmap */
3627 else if ((mp->m_mode & (NORMAL + VISUAL + OP_PENDING))
3628 == NORMAL + VISUAL + OP_PENDING)
3629 msg_putchar(' '); /* :map */
3630 else
3631 {
3632 len = 0;
3633 if (mp->m_mode & NORMAL)
3634 {
3635 msg_putchar('n'); /* :nmap */
3636 ++len;
3637 }
3638 if (mp->m_mode & OP_PENDING)
3639 {
3640 msg_putchar('o'); /* :omap */
3641 ++len;
3642 }
3643 if (mp->m_mode & VISUAL)
3644 {
3645 msg_putchar('v'); /* :vmap */
3646 ++len;
3647 }
3648 }
3649 while (++len <= 3)
3650 msg_putchar(' ');
3651
3652 /* Get length of what we write */
3653 len = msg_outtrans_special(mp->m_keys, TRUE);
3654 do
3655 {
3656 msg_putchar(' '); /* padd with blanks */
3657 ++len;
3658 } while (len < 12);
3659
3660 if (mp->m_noremap == REMAP_NONE)
3661 msg_puts_attr((char_u *)"*", hl_attr(HLF_8));
3662 else if (mp->m_noremap == REMAP_SCRIPT)
3663 msg_puts_attr((char_u *)"&", hl_attr(HLF_8));
3664 else
3665 msg_putchar(' ');
3666
3667 if (local)
3668 msg_putchar('@');
3669 else
3670 msg_putchar(' ');
3671
3672 /* Use FALSE below if we only want things like <Up> to show up as such on
3673 * the rhs, and not M-x etc, TRUE gets both -- webb
3674 */
3675 if (*mp->m_str == NUL)
3676 msg_puts_attr((char_u *)"<Nop>", hl_attr(HLF_8));
3677 else
3678 msg_outtrans_special(mp->m_str, FALSE);
3679 out_flush(); /* show one line at a time */
3680}
3681
3682#if defined(FEAT_EVAL) || defined(PROTO)
3683/*
3684 * Return TRUE if a map exists that has "str" in the rhs for mode "modechars".
3685 * Recognize termcap codes in "str".
3686 * Also checks mappings local to the current buffer.
3687 */
3688 int
3689map_to_exists(str, modechars)
3690 char_u *str;
3691 char_u *modechars;
3692{
3693 int mode = 0;
3694 char_u *rhs;
3695 char_u *buf;
3696 int retval;
3697
3698 rhs = replace_termcodes(str, &buf, FALSE, TRUE);
3699
3700 if (vim_strchr(modechars, 'n') != NULL)
3701 mode |= NORMAL;
3702 if (vim_strchr(modechars, 'v') != NULL)
3703 mode |= VISUAL;
3704 if (vim_strchr(modechars, 'o') != NULL)
3705 mode |= OP_PENDING;
3706 if (vim_strchr(modechars, 'i') != NULL)
3707 mode |= INSERT;
3708 if (vim_strchr(modechars, 'l') != NULL)
3709 mode |= LANGMAP;
3710 if (vim_strchr(modechars, 'c') != NULL)
3711 mode |= CMDLINE;
3712
3713 retval = map_to_exists_mode(rhs, mode);
3714 vim_free(buf);
3715
3716 return retval;
3717}
3718#endif
3719
3720/*
3721 * Return TRUE if a map exists that has "str" in the rhs for mode "mode".
3722 * Also checks mappings local to the current buffer.
3723 */
3724 int
3725map_to_exists_mode(rhs, mode)
3726 char_u *rhs;
3727 int mode;
3728{
3729 mapblock_T *mp;
3730 int hash;
3731# ifdef FEAT_LOCALMAP
3732 int expand_buffer = FALSE;
3733
3734 validate_maphash();
3735
3736 /* Do it twice: once for global maps and once for local maps. */
3737 for (;;)
3738 {
3739# endif
3740 for (hash = 0; hash < 256; ++hash)
3741 {
3742# ifdef FEAT_LOCALMAP
3743 if (expand_buffer)
3744 mp = curbuf->b_maphash[hash];
3745 else
3746# endif
3747 mp = maphash[hash];
3748 for (; mp; mp = mp->m_next)
3749 {
3750 if ((mp->m_mode & mode)
3751 && strstr((char *)mp->m_str, (char *)rhs) != NULL)
3752 return TRUE;
3753 }
3754 }
3755# ifdef FEAT_LOCALMAP
3756 if (expand_buffer)
3757 break;
3758 expand_buffer = TRUE;
3759 }
3760# endif
3761
3762 return FALSE;
3763}
3764
3765#if defined(FEAT_CMDL_COMPL) || defined(PROTO)
3766/*
3767 * Used below when expanding mapping/abbreviation names.
3768 */
3769static int expand_mapmodes = 0;
3770static int expand_isabbrev = 0;
3771#ifdef FEAT_LOCALMAP
3772static int expand_buffer = FALSE;
3773#endif
3774
3775/*
3776 * Work out what to complete when doing command line completion of mapping
3777 * or abbreviation names.
3778 */
3779 char_u *
3780set_context_in_map_cmd(xp, cmd, arg, forceit, isabbrev, isunmap, cmdidx)
3781 expand_T *xp;
3782 char_u *cmd;
3783 char_u *arg;
3784 int forceit; /* TRUE if '!' given */
3785 int isabbrev; /* TRUE if abbreviation */
3786 int isunmap; /* TRUE if unmap/unabbrev command */
3787 cmdidx_T cmdidx;
3788{
3789 if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap)
3790 xp->xp_context = EXPAND_NOTHING;
3791 else
3792 {
3793 if (isunmap)
3794 expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev);
3795 else
3796 {
3797 expand_mapmodes = INSERT + CMDLINE;
3798 if (!isabbrev)
3799 expand_mapmodes += VISUAL + NORMAL + OP_PENDING;
3800 }
3801 expand_isabbrev = isabbrev;
3802 xp->xp_context = EXPAND_MAPPINGS;
3803#ifdef FEAT_LOCALMAP
3804 expand_buffer = FALSE;
3805#endif
3806 for (;;)
3807 {
3808#ifdef FEAT_LOCALMAP
3809 if (STRNCMP(arg, "<buffer>", 8) == 0)
3810 {
3811 expand_buffer = TRUE;
3812 arg = skipwhite(arg + 8);
3813 continue;
3814 }
3815#endif
3816 if (STRNCMP(arg, "<unique>", 8) == 0)
3817 {
3818 arg = skipwhite(arg + 8);
3819 continue;
3820 }
3821 if (STRNCMP(arg, "<silent>", 8) == 0)
3822 {
3823 arg = skipwhite(arg + 8);
3824 continue;
3825 }
3826 if (STRNCMP(arg, "<script>", 8) == 0)
3827 {
3828 arg = skipwhite(arg + 8);
3829 continue;
3830 }
3831 break;
3832 }
3833 xp->xp_pattern = arg;
3834 }
3835
3836 return NULL;
3837}
3838
3839/*
3840 * Find all mapping/abbreviation names that match regexp 'prog'.
3841 * For command line expansion of ":[un]map" and ":[un]abbrev" in all modes.
3842 * Return OK if matches found, FAIL otherwise.
3843 */
3844 int
3845ExpandMappings(regmatch, num_file, file)
3846 regmatch_T *regmatch;
3847 int *num_file;
3848 char_u ***file;
3849{
3850 mapblock_T *mp;
3851 int hash;
3852 int count;
3853 int round;
3854 char_u *p;
3855 int i;
3856
3857 validate_maphash();
3858
3859 *num_file = 0; /* return values in case of FAIL */
3860 *file = NULL;
3861
3862 /*
3863 * round == 1: Count the matches.
3864 * round == 2: Build the array to keep the matches.
3865 */
3866 for (round = 1; round <= 2; ++round)
3867 {
3868 count = 0;
3869
3870 for (i = 0; i < 4; ++i)
3871 {
3872 if (i == 0)
3873 p = (char_u *)"<silent>";
3874 else if (i == 1)
3875 p = (char_u *)"<unique>";
3876#ifdef FEAT_EVAL
3877 else if (i == 2)
3878 p = (char_u *)"<script>";
3879#endif
3880#ifdef FEAT_LOCALMAP
3881 else if (i == 3 && !expand_buffer)
3882 p = (char_u *)"<buffer>";
3883#endif
3884 else
3885 continue;
3886
3887 if (vim_regexec(regmatch, p, (colnr_T)0))
3888 {
3889 if (round == 1)
3890 ++count;
3891 else
3892 (*file)[count++] = vim_strsave(p);
3893 }
3894 }
3895
3896 for (hash = 0; hash < 256; ++hash)
3897 {
3898 if (expand_isabbrev)
3899 {
3900 if (hash) /* only one abbrev list */
3901 break; /* for (hash) */
3902 mp = first_abbr;
3903 }
3904#ifdef FEAT_LOCALMAP
3905 else if (expand_buffer)
3906 mp = curbuf->b_maphash[hash];
3907#endif
3908 else
3909 mp = maphash[hash];
3910 for (; mp; mp = mp->m_next)
3911 {
3912 if (mp->m_mode & expand_mapmodes)
3913 {
3914 p = translate_mapping(mp->m_keys, TRUE);
3915 if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0))
3916 {
3917 if (round == 1)
3918 ++count;
3919 else
3920 {
3921 (*file)[count++] = p;
3922 p = NULL;
3923 }
3924 }
3925 vim_free(p);
3926 }
3927 } /* for (mp) */
3928 } /* for (hash) */
3929
3930 if (count == 0) /* no match found */
3931 break; /* for (round) */
3932
3933 if (round == 1)
3934 {
3935 *file = (char_u **)alloc((unsigned)(count * sizeof(char_u *)));
3936 if (*file == NULL)
3937 return FAIL;
3938 }
3939 } /* for (round) */
3940
3941 /* Sort the matches */
3942 sort_strings(*file, count);
3943
3944 /* Remove multiple entries */
3945 {
3946 char_u **ptr1 = *file;
3947 char_u **ptr2 = ptr1 + 1;
3948 char_u **ptr3 = ptr1 + count;
3949
3950 while (ptr2 < ptr3)
3951 {
3952 if (STRCMP(*ptr1, *ptr2))
3953 *++ptr1 = *ptr2++;
3954 else
3955 {
3956 vim_free(*ptr2++);
3957 count--;
3958 }
3959 }
3960 }
3961
3962 *num_file = count;
3963 return (count == 0 ? FAIL : OK);
3964}
3965#endif /* FEAT_CMDL_COMPL */
3966
3967/*
3968 * Check for an abbreviation.
3969 * Cursor is at ptr[col]. When inserting, mincol is where insert started.
3970 * "c" is the character typed before check_abbr was called. It may have
3971 * ABBR_OFF added to avoid prepending a CTRL-V to it.
3972 *
3973 * Historic vi practice: The last character of an abbreviation must be an id
3974 * character ([a-zA-Z0-9_]). The characters in front of it must be all id
3975 * characters or all non-id characters. This allows for abbr. "#i" to
3976 * "#include".
3977 *
3978 * Vim addition: Allow for abbreviations that end in a non-keyword character.
3979 * Then there must be white space before the abbr.
3980 *
3981 * return TRUE if there is an abbreviation, FALSE if not
3982 */
3983 int
3984check_abbr(c, ptr, col, mincol)
3985 int c;
3986 char_u *ptr;
3987 int col;
3988 int mincol;
3989{
3990 int len;
3991 int scol; /* starting column of the abbr. */
3992 int j;
3993#ifdef FEAT_MBYTE
3994 char_u tb[MB_MAXBYTES + 4];
3995#else
3996 char_u tb[4];
3997#endif
3998 mapblock_T *mp;
3999#ifdef FEAT_LOCALMAP
4000 mapblock_T *mp2;
4001#endif
4002#ifdef FEAT_MBYTE
4003 int clen = 0; /* length in characters */
4004#endif
4005 int is_id = TRUE;
4006 int vim_abbr;
4007
4008 if (typebuf.tb_no_abbr_cnt) /* abbrev. are not recursive */
4009 return FALSE;
4010 if (KeyNoremap) /* no remapping implies no abbreviation */
4011 return FALSE;
4012
4013 /*
4014 * Check for word before the cursor: If it ends in a keyword char all
4015 * chars before it must be al keyword chars or non-keyword chars, but not
4016 * white space. If it ends in a non-keyword char we accept any characters
4017 * before it except white space.
4018 */
4019 if (col == 0) /* cannot be an abbr. */
4020 return FALSE;
4021
4022#ifdef FEAT_MBYTE
4023 if (has_mbyte)
4024 {
4025 char_u *p;
4026
4027 p = mb_prevptr(ptr, ptr + col);
4028 if (!vim_iswordp(p))
4029 vim_abbr = TRUE; /* Vim added abbr. */
4030 else
4031 {
4032 vim_abbr = FALSE; /* vi compatible abbr. */
4033 if (p > ptr)
4034 is_id = vim_iswordp(mb_prevptr(ptr, p));
4035 }
4036 clen = 1;
4037 while (p > ptr + mincol)
4038 {
4039 p = mb_prevptr(ptr, p);
4040 if (vim_isspace(*p) || (!vim_abbr && is_id != vim_iswordp(p)))
4041 {
Bram Moolenaar0fa313a2005-08-10 21:07:57 +00004042 p += (*mb_ptr2len)(p);
Bram Moolenaar071d4272004-06-13 20:20:40 +00004043 break;
4044 }
4045 ++clen;
4046 }
4047 scol = (int)(p - ptr);
4048 }
4049 else
4050#endif
4051 {
4052 if (!vim_iswordc(ptr[col - 1]))
4053 vim_abbr = TRUE; /* Vim added abbr. */
4054 else
4055 {
4056 vim_abbr = FALSE; /* vi compatible abbr. */
4057 if (col > 1)
4058 is_id = vim_iswordc(ptr[col - 2]);
4059 }
4060 for (scol = col - 1; scol > 0 && !vim_isspace(ptr[scol - 1])
4061 && (vim_abbr || is_id == vim_iswordc(ptr[scol - 1])); --scol)
4062 ;
4063 }
4064
4065 if (scol < mincol)
4066 scol = mincol;
4067 if (scol < col) /* there is a word in front of the cursor */
4068 {
4069 ptr += scol;
4070 len = col - scol;
4071#ifdef FEAT_LOCALMAP
4072 mp = curbuf->b_first_abbr;
4073 mp2 = first_abbr;
4074 if (mp == NULL)
4075 {
4076 mp = mp2;
4077 mp2 = NULL;
4078 }
4079#else
4080 mp = first_abbr;
4081#endif
4082 for ( ; mp;
4083#ifdef FEAT_LOCALMAP
4084 mp->m_next == NULL ? (mp = mp2, mp2 = NULL) :
4085#endif
4086 (mp = mp->m_next))
4087 {
4088 /* find entries with right mode and keys */
4089 if ( (mp->m_mode & State)
4090 && mp->m_keylen == len
4091 && !STRNCMP(mp->m_keys, ptr, (size_t)len))
4092 break;
4093 }
4094 if (mp != NULL)
4095 {
4096 /*
4097 * Found a match:
4098 * Insert the rest of the abbreviation in typebuf.tb_buf[].
4099 * This goes from end to start.
4100 *
4101 * Characters 0x000 - 0x100: normal chars, may need CTRL-V,
4102 * except K_SPECIAL: Becomes K_SPECIAL KS_SPECIAL KE_FILLER
4103 * Characters where IS_SPECIAL() == TRUE: key codes, need
4104 * K_SPECIAL. Other characters (with ABBR_OFF): don't use CTRL-V.
4105 *
4106 * Character CTRL-] is treated specially - it completes the
4107 * abbreviation, but is not inserted into the input stream.
4108 */
4109 j = 0;
4110 /* special key code, split up */
4111 if (c != Ctrl_RSB)
4112 {
4113 if (IS_SPECIAL(c) || c == K_SPECIAL)
4114 {
4115 tb[j++] = K_SPECIAL;
4116 tb[j++] = K_SECOND(c);
4117 tb[j++] = K_THIRD(c);
4118 }
4119 else
4120 {
4121 if (c < ABBR_OFF && (c < ' ' || c > '~'))
4122 tb[j++] = Ctrl_V; /* special char needs CTRL-V */
4123#ifdef FEAT_MBYTE
4124 if (has_mbyte)
4125 {
4126 /* if ABBR_OFF has been added, remove it here */
4127 if (c >= ABBR_OFF)
4128 c -= ABBR_OFF;
4129 j += (*mb_char2bytes)(c, tb + j);
4130 }
4131 else
4132#endif
4133 tb[j++] = c;
4134 }
4135 tb[j] = NUL;
4136 /* insert the last typed char */
4137 (void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
4138 }
4139 /* insert the to string */
4140 (void)ins_typebuf(mp->m_str, mp->m_noremap, 0, TRUE, mp->m_silent);
4141 /* no abbrev. for these chars */
4142 typebuf.tb_no_abbr_cnt += (int)STRLEN(mp->m_str) + j + 1;
4143
4144 tb[0] = Ctrl_H;
4145 tb[1] = NUL;
4146#ifdef FEAT_MBYTE
4147 if (has_mbyte)
4148 len = clen; /* Delete characters instead of bytes */
4149#endif
4150 while (len-- > 0) /* delete the from string */
4151 (void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent);
4152 return TRUE;
4153 }
4154 }
4155 return FALSE;
4156}
4157
4158/*
4159 * Write map commands for the current mappings to an .exrc file.
4160 * Return FAIL on error, OK otherwise.
4161 */
4162 int
4163makemap(fd, buf)
4164 FILE *fd;
4165 buf_T *buf; /* buffer for local mappings or NULL */
4166{
4167 mapblock_T *mp;
4168 char_u c1, c2;
4169 char_u *p;
4170 char *cmd;
4171 int abbr;
4172 int hash;
4173 int did_cpo = FALSE;
4174 int i;
4175
4176 validate_maphash();
4177
4178 /*
4179 * Do the loop twice: Once for mappings, once for abbreviations.
4180 * Then loop over all map hash lists.
4181 */
4182 for (abbr = 0; abbr < 2; ++abbr)
4183 for (hash = 0; hash < 256; ++hash)
4184 {
4185 if (abbr)
4186 {
4187 if (hash) /* there is only one abbr list */
4188 break;
4189#ifdef FEAT_LOCALMAP
4190 if (buf != NULL)
4191 mp = buf->b_first_abbr;
4192 else
4193#endif
4194 mp = first_abbr;
4195 }
4196 else
4197 {
4198#ifdef FEAT_LOCALMAP
4199 if (buf != NULL)
4200 mp = buf->b_maphash[hash];
4201 else
4202#endif
4203 mp = maphash[hash];
4204 }
4205
4206 for ( ; mp; mp = mp->m_next)
4207 {
4208 /* skip script-local mappings */
4209 if (mp->m_noremap == REMAP_SCRIPT)
4210 continue;
4211
4212 /* skip mappings that contain a <SNR> (script-local thing),
4213 * they probably don't work when loaded again */
4214 for (p = mp->m_str; *p != NUL; ++p)
4215 if (p[0] == K_SPECIAL && p[1] == KS_EXTRA
4216 && p[2] == (int)KE_SNR)
4217 break;
4218 if (*p != NUL)
4219 continue;
4220
4221 c1 = NUL;
4222 c2 = NUL;
4223 if (abbr)
4224 cmd = "abbr";
4225 else
4226 cmd = "map";
4227 switch (mp->m_mode)
4228 {
4229 case NORMAL + VISUAL + OP_PENDING:
4230 break;
4231 case NORMAL:
4232 c1 = 'n';
4233 break;
4234 case VISUAL:
4235 c1 = 'v';
4236 break;
4237 case OP_PENDING:
4238 c1 = 'o';
4239 break;
4240 case NORMAL + VISUAL:
4241 c1 = 'n';
4242 c2 = 'v';
4243 break;
4244 case VISUAL + OP_PENDING:
4245 c1 = 'v';
4246 c2 = 'o';
4247 break;
4248 case NORMAL + OP_PENDING:
4249 c1 = 'n';
4250 c2 = 'o';
4251 break;
4252 case CMDLINE + INSERT:
4253 if (!abbr)
4254 cmd = "map!";
4255 break;
4256 case CMDLINE:
4257 c1 = 'c';
4258 break;
4259 case INSERT:
4260 c1 = 'i';
4261 break;
4262 case LANGMAP:
4263 c1 = 'l';
4264 break;
4265 default:
4266 EMSG(_("E228: makemap: Illegal mode"));
4267 return FAIL;
4268 }
4269 do /* may do this twice if c2 is set */
4270 {
4271 /* When outputting <> form, need to make sure that 'cpo'
4272 * is set to the Vim default. */
4273 if (!did_cpo)
4274 {
4275 if (*mp->m_str == NUL) /* will use <Nop> */
4276 did_cpo = TRUE;
4277 else
4278 for (i = 0; i < 2; ++i)
4279 for (p = (i ? mp->m_str : mp->m_keys); *p; ++p)
4280 if (*p == K_SPECIAL || *p == NL)
4281 did_cpo = TRUE;
4282 if (did_cpo)
4283 {
4284 if (fprintf(fd, "let s:cpo_save=&cpo") < 0
4285 || put_eol(fd) < 0
4286 || fprintf(fd, "set cpo&vim") < 0
4287 || put_eol(fd) < 0)
4288 return FAIL;
4289 }
4290 }
4291 if (c1 && putc(c1, fd) < 0)
4292 return FAIL;
4293 if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0)
4294 return FAIL;
4295 if (fprintf(fd, cmd) < 0)
4296 return FAIL;
4297 if (buf != NULL && fputs(" <buffer>", fd) < 0)
4298 return FAIL;
4299 if (mp->m_silent && fputs(" <silent>", fd) < 0)
4300 return FAIL;
4301
4302 if ( putc(' ', fd) < 0
4303 || put_escstr(fd, mp->m_keys, 0) == FAIL
4304 || putc(' ', fd) < 0
4305 || put_escstr(fd, mp->m_str, 1) == FAIL
4306 || put_eol(fd) < 0)
4307 return FAIL;
4308 c1 = c2;
4309 c2 = NUL;
4310 }
4311 while (c1);
4312 }
4313 }
4314
4315 if (did_cpo)
4316 if (fprintf(fd, "let &cpo=s:cpo_save") < 0
4317 || put_eol(fd) < 0
4318 || fprintf(fd, "unlet s:cpo_save") < 0
4319 || put_eol(fd) < 0)
4320 return FAIL;
4321 return OK;
4322}
4323
4324/*
4325 * write escape string to file
4326 * "what": 0 for :map lhs, 1 for :map rhs, 2 for :set
4327 *
4328 * return FAIL for failure, OK otherwise
4329 */
4330 int
4331put_escstr(fd, strstart, what)
4332 FILE *fd;
4333 char_u *strstart;
4334 int what;
4335{
4336 char_u *str = strstart;
4337 int c;
4338 int modifiers;
4339
4340 /* :map xx <Nop> */
4341 if (*str == NUL && what == 1)
4342 {
4343 if (fprintf(fd, "<Nop>") < 0)
4344 return FAIL;
4345 return OK;
4346 }
4347
4348 for ( ; *str != NUL; ++str)
4349 {
4350#ifdef FEAT_MBYTE
4351 char_u *p;
4352
4353 /* Check for a multi-byte character, which may contain escaped
4354 * K_SPECIAL and CSI bytes */
4355 p = mb_unescape(&str);
4356 if (p != NULL)
4357 {
4358 while (*p != NUL)
Bram Moolenaar51485f02005-06-04 21:55:20 +00004359 if (fputc(*p++, fd) < 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004360 return FAIL;
4361 --str;
4362 continue;
4363 }
4364#endif
4365
4366 c = *str;
4367 /*
4368 * Special key codes have to be translated to be able to make sense
4369 * when they are read back.
4370 */
4371 if (c == K_SPECIAL && what != 2)
4372 {
4373 modifiers = 0x0;
4374 if (str[1] == KS_MODIFIER)
4375 {
4376 modifiers = str[2];
4377 str += 3;
4378 c = *str;
4379 }
4380 if (c == K_SPECIAL)
4381 {
4382 c = TO_SPECIAL(str[1], str[2]);
4383 str += 2;
4384 }
4385 if (IS_SPECIAL(c) || modifiers) /* special key */
4386 {
4387 if (fprintf(fd, (char *)get_special_key_name(c, modifiers)) < 0)
4388 return FAIL;
4389 continue;
4390 }
4391 }
4392
4393 /*
4394 * A '\n' in a map command should be written as <NL>.
4395 * A '\n' in a set command should be written as \^V^J.
4396 */
4397 if (c == NL)
4398 {
4399 if (what == 2)
4400 {
4401 if (fprintf(fd, IF_EB("\\\026\n", "\\" CTRL_V_STR "\n")) < 0)
4402 return FAIL;
4403 }
4404 else
4405 {
4406 if (fprintf(fd, "<NL>") < 0)
4407 return FAIL;
4408 }
4409 continue;
4410 }
4411
4412 /*
4413 * Some characters have to be escaped with CTRL-V to
4414 * prevent them from misinterpreted in DoOneCmd().
4415 * A space, Tab and '"' has to be escaped with a backslash to
4416 * prevent it to be misinterpreted in do_set().
4417 * A space has to be escaped with a CTRL-V when it's at the start of a
4418 * ":map" rhs.
4419 * A '<' has to be escaped with a CTRL-V to prevent it being
4420 * interpreted as the start of a special key name.
4421 * A space in the lhs of a :map needs a CTRL-V.
4422 */
4423 if (what == 2 && (vim_iswhite(c) || c == '"' || c == '\\'))
4424 {
4425 if (putc('\\', fd) < 0)
4426 return FAIL;
4427 }
4428 else if (c < ' ' || c > '~' || c == '|'
4429 || (what == 0 && c == ' ')
4430 || (what == 1 && str == strstart && c == ' ')
4431 || (what != 2 && c == '<'))
4432 {
4433 if (putc(Ctrl_V, fd) < 0)
4434 return FAIL;
4435 }
4436 if (putc(c, fd) < 0)
4437 return FAIL;
4438 }
4439 return OK;
4440}
4441
4442/*
4443 * Check all mappings for the presence of special key codes.
4444 * Used after ":set term=xxx".
4445 */
4446 void
4447check_map_keycodes()
4448{
4449 mapblock_T *mp;
4450 char_u *p;
4451 int i;
4452 char_u buf[3];
4453 char_u *save_name;
4454 int abbr;
4455 int hash;
4456#ifdef FEAT_LOCALMAP
4457 buf_T *bp;
4458#endif
4459
4460 validate_maphash();
4461 save_name = sourcing_name;
4462 sourcing_name = (char_u *)"mappings"; /* avoids giving error messages */
4463
4464#ifdef FEAT_LOCALMAP
4465 /* This this once for each buffer, and then once for global
4466 * mappings/abbreviations with bp == NULL */
4467 for (bp = firstbuf; ; bp = bp->b_next)
4468 {
4469#endif
4470 /*
4471 * Do the loop twice: Once for mappings, once for abbreviations.
4472 * Then loop over all map hash lists.
4473 */
4474 for (abbr = 0; abbr <= 1; ++abbr)
4475 for (hash = 0; hash < 256; ++hash)
4476 {
4477 if (abbr)
4478 {
4479 if (hash) /* there is only one abbr list */
4480 break;
4481#ifdef FEAT_LOCALMAP
4482 if (bp != NULL)
4483 mp = bp->b_first_abbr;
4484 else
4485#endif
4486 mp = first_abbr;
4487 }
4488 else
4489 {
4490#ifdef FEAT_LOCALMAP
4491 if (bp != NULL)
4492 mp = bp->b_maphash[hash];
4493 else
4494#endif
4495 mp = maphash[hash];
4496 }
4497 for ( ; mp != NULL; mp = mp->m_next)
4498 {
4499 for (i = 0; i <= 1; ++i) /* do this twice */
4500 {
4501 if (i == 0)
4502 p = mp->m_keys; /* once for the "from" part */
4503 else
4504 p = mp->m_str; /* and once for the "to" part */
4505 while (*p)
4506 {
4507 if (*p == K_SPECIAL)
4508 {
4509 ++p;
4510 if (*p < 128) /* for "normal" tcap entries */
4511 {
4512 buf[0] = p[0];
4513 buf[1] = p[1];
4514 buf[2] = NUL;
4515 (void)add_termcap_entry(buf, FALSE);
4516 }
4517 ++p;
4518 }
4519 ++p;
4520 }
4521 }
4522 }
4523 }
4524#ifdef FEAT_LOCALMAP
4525 if (bp == NULL)
4526 break;
4527 }
4528#endif
4529 sourcing_name = save_name;
4530}
4531
4532#ifdef FEAT_EVAL
4533/*
4534 * Check the string "keys" against the lhs of all mappings
4535 * Return pointer to rhs of mapping (mapblock->m_str)
4536 * NULL otherwise
4537 */
4538 char_u *
Bram Moolenaar686f51e2005-05-20 21:19:57 +00004539check_map(keys, mode, exact, ign_mod)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004540 char_u *keys;
4541 int mode;
4542 int exact; /* require exact match */
Bram Moolenaar686f51e2005-05-20 21:19:57 +00004543 int ign_mod; /* ignore preceding modifier */
Bram Moolenaar071d4272004-06-13 20:20:40 +00004544{
4545 int hash;
4546 int len, minlen;
4547 mapblock_T *mp;
Bram Moolenaar686f51e2005-05-20 21:19:57 +00004548 char_u *s;
Bram Moolenaar071d4272004-06-13 20:20:40 +00004549#ifdef FEAT_LOCALMAP
4550 int local;
4551#endif
4552
4553 validate_maphash();
4554
4555 len = (int)STRLEN(keys);
4556#ifdef FEAT_LOCALMAP
4557 for (local = 1; local >= 0; --local)
4558#endif
4559 /* loop over all hash lists */
4560 for (hash = 0; hash < 256; ++hash)
4561 {
4562#ifdef FEAT_LOCALMAP
4563 if (local)
4564 mp = curbuf->b_maphash[hash];
4565 else
4566#endif
4567 mp = maphash[hash];
4568 for ( ; mp != NULL; mp = mp->m_next)
4569 {
4570 /* skip entries with wrong mode, wrong length and not matching
4571 * ones */
Bram Moolenaar686f51e2005-05-20 21:19:57 +00004572 if ((mp->m_mode & mode) && (!exact || mp->m_keylen == len))
4573 {
4574 if (len > mp->m_keylen)
4575 minlen = mp->m_keylen;
4576 else
4577 minlen = len;
4578 s = mp->m_keys;
4579 if (ign_mod && s[0] == K_SPECIAL && s[1] == KS_MODIFIER
4580 && s[2] != NUL)
4581 {
4582 s += 3;
4583 if (len > mp->m_keylen - 3)
4584 minlen = mp->m_keylen - 3;
4585 }
4586 if (STRNCMP(s, keys, minlen) == 0)
4587 return mp->m_str;
4588 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00004589 }
4590 }
4591
4592 return NULL;
4593}
4594#endif
4595
Bram Moolenaarbc7aa852005-03-06 23:38:09 +00004596#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004597/*
4598 * Default mappings for some often used keys.
4599 */
4600static struct initmap
4601{
4602 char_u *arg;
4603 int mode;
4604} initmappings[] =
4605{
4606#if defined(MSDOS) || defined(MSWIN) || defined(OS2)
4607 /* Use the Windows (CUA) keybindings. */
4608# ifdef FEAT_GUI
4609 {(char_u *)"<C-PageUp> H", NORMAL+VISUAL},
4610 {(char_u *)"<C-PageUp> <C-O>H",INSERT},
4611 {(char_u *)"<C-PageDown> L$", NORMAL+VISUAL},
4612 {(char_u *)"<C-PageDown> <C-O>L<C-O>$", INSERT},
4613
4614 /* paste, copy and cut */
4615 {(char_u *)"<S-Insert> \"*P", NORMAL},
4616 {(char_u *)"<S-Insert> \"-d\"*P", VISUAL},
4617 {(char_u *)"<S-Insert> <C-R><C-O>*", INSERT+CMDLINE},
4618 {(char_u *)"<C-Insert> \"*y", VISUAL},
4619 {(char_u *)"<S-Del> \"*d", VISUAL},
4620 {(char_u *)"<C-Del> \"*d", VISUAL},
4621 {(char_u *)"<C-X> \"*d", VISUAL},
4622 /* Missing: CTRL-C (cancel) and CTRL-V (block selection) */
4623# else
4624 {(char_u *)"\316\204 H", NORMAL+VISUAL}, /* CTRL-PageUp is "H" */
4625 {(char_u *)"\316\204 \017H",INSERT}, /* CTRL-PageUp is "^OH"*/
4626 {(char_u *)"\316v L$", NORMAL+VISUAL}, /* CTRL-PageDown is "L$" */
4627 {(char_u *)"\316v \017L\017$", INSERT}, /* CTRL-PageDown ="^OL^O$"*/
4628 {(char_u *)"\316w <C-Home>", NORMAL+VISUAL},
4629 {(char_u *)"\316w <C-Home>", INSERT+CMDLINE},
4630 {(char_u *)"\316u <C-End>", NORMAL+VISUAL},
4631 {(char_u *)"\316u <C-End>", INSERT+CMDLINE},
4632
4633 /* paste, copy and cut */
4634# ifdef FEAT_CLIPBOARD
4635# ifdef DJGPP
4636 {(char_u *)"\316\122 \"*P", NORMAL}, /* SHIFT-Insert is "*P */
4637 {(char_u *)"\316\122 \"-d\"*P", VISUAL}, /* SHIFT-Insert is "-d"*P */
4638 {(char_u *)"\316\122 \022\017*", INSERT}, /* SHIFT-Insert is ^R^O* */
4639 {(char_u *)"\316\222 \"*y", VISUAL}, /* CTRL-Insert is "*y */
4640# if 0 /* Shift-Del produces the same code as Del */
4641 {(char_u *)"\316\123 \"*d", VISUAL}, /* SHIFT-Del is "*d */
4642# endif
4643 {(char_u *)"\316\223 \"*d", VISUAL}, /* CTRL-Del is "*d */
4644 {(char_u *)"\030 \"-d", VISUAL}, /* CTRL-X is "-d */
4645# else
4646 {(char_u *)"\316\324 \"*P", NORMAL}, /* SHIFT-Insert is "*P */
4647 {(char_u *)"\316\324 \"-d\"*P", VISUAL}, /* SHIFT-Insert is "-d"*P */
4648 {(char_u *)"\316\324 \022\017*", INSERT}, /* SHIFT-Insert is ^R^O* */
4649 {(char_u *)"\316\325 \"*y", VISUAL}, /* CTRL-Insert is "*y */
4650 {(char_u *)"\316\327 \"*d", VISUAL}, /* SHIFT-Del is "*d */
4651 {(char_u *)"\316\330 \"*d", VISUAL}, /* CTRL-Del is "*d */
4652 {(char_u *)"\030 \"-d", VISUAL}, /* CTRL-X is "-d */
4653# endif
4654# else
4655 {(char_u *)"\316\324 P", NORMAL}, /* SHIFT-Insert is P */
4656 {(char_u *)"\316\324 \"-dP", VISUAL}, /* SHIFT-Insert is "-dP */
4657 {(char_u *)"\316\324 \022\017\"", INSERT}, /* SHIFT-Insert is ^R^O" */
4658 {(char_u *)"\316\325 y", VISUAL}, /* CTRL-Insert is y */
4659 {(char_u *)"\316\327 d", VISUAL}, /* SHIFT-Del is d */
4660 {(char_u *)"\316\330 d", VISUAL}, /* CTRL-Del is d */
4661# endif
4662# endif
4663#endif
4664
4665#if defined(MACOS)
4666 /* Use the Standard MacOS binding. */
4667 /* paste, copy and cut */
4668 {(char_u *)"<D-v> \"*P", NORMAL},
4669 {(char_u *)"<D-v> \"-d\"*P", VISUAL},
4670 {(char_u *)"<D-v> <C-R>*", INSERT+CMDLINE},
4671 {(char_u *)"<D-c> \"*y", VISUAL},
4672 {(char_u *)"<D-x> \"*d", VISUAL},
4673 {(char_u *)"<Backspace> \"-d", VISUAL},
4674#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00004675};
Bram Moolenaarbc7aa852005-03-06 23:38:09 +00004676#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00004677
4678/*
4679 * Set up default mappings.
4680 */
4681 void
4682init_mappings()
4683{
Bram Moolenaarbc7aa852005-03-06 23:38:09 +00004684#if defined(MSDOS) || defined(MSWIN) || defined(OS2) || defined(MACOS)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004685 int i;
4686
4687 for (i = 0; i < sizeof(initmappings) / sizeof(struct initmap); ++i)
4688 add_map(initmappings[i].arg, initmappings[i].mode);
Bram Moolenaarbc7aa852005-03-06 23:38:09 +00004689#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00004690}
4691
Bram Moolenaar52b4b552005-03-07 23:00:57 +00004692#if defined(MSDOS) || defined(MSWIN) || defined(OS2) \
4693 || defined(FEAT_CMDWIN) || defined(MACOS) || defined(PROTO)
Bram Moolenaar071d4272004-06-13 20:20:40 +00004694/*
4695 * Add a mapping "map" for mode "mode".
4696 * Need to put string in allocated memory, because do_map() will modify it.
4697 */
4698 void
4699add_map(map, mode)
4700 char_u *map;
4701 int mode;
4702{
4703 char_u *s;
4704 char_u *cpo_save = p_cpo;
4705
4706 p_cpo = (char_u *)""; /* Allow <> notation */
4707 s = vim_strsave(map);
4708 if (s != NULL)
4709 {
4710 (void)do_map(0, s, mode, FALSE);
4711 vim_free(s);
4712 }
4713 p_cpo = cpo_save;
4714}
Bram Moolenaar52b4b552005-03-07 23:00:57 +00004715#endif