unstack, sort: cleanup and improvement
[minix.git] / commands / elvis / tio.c
blob66bd2618367e1b8905756b568188a0a60f9e7fbd
1 /* tio.c */
3 /* Author:
4 * Steve Kirkendall
5 * 14407 SW Teal Blvd. #C
6 * Beaverton, OR 97005
7 * kirkenda@cs.pdx.edu
8 */
11 /* This file contains terminal I/O functions */
13 #include "config.h"
14 #include "vi.h"
15 #include "ctype.h"
18 /* This function reads in a line from the terminal. */
19 int vgets(prompt, buf, bsize)
20 char prompt; /* the prompt character, or '\0' for none */
21 char *buf; /* buffer into which the string is read */
22 int bsize; /* size of the buffer */
24 int len; /* how much we've read so far */
25 int ch; /* a character from the user */
26 int quoted; /* is the next char quoted? */
27 int tab; /* column position of cursor */
28 char widths[132]; /* widths of characters */
29 int word; /* index of first letter of word */
30 #ifndef NO_DIGRAPH
31 int erased; /* 0, or first char of a digraph */
32 #endif
34 /* show the prompt */
35 move(LINES - 1, 0);
36 tab = 0;
37 if (prompt)
39 addch(prompt);
40 tab = 1;
42 clrtoeol();
43 refresh();
45 /* read in the line */
46 #ifndef NO_DIGRAPH
47 erased =
48 #endif
49 quoted = len = 0;
50 for (;;)
52 #ifndef NO_ABBR
53 if (quoted || mode == MODE_EX)
55 ch = getkey(0);
57 else
59 /* maybe expand an abbreviation while getting key */
60 for (word = len; --word >= 0 && isalnum(buf[word]); )
63 word++;
64 ch = getabkey(WHEN_EX, &buf[word], len - word);
66 #else
67 ch = getkey(0);
68 #endif
69 #ifndef NO_EXTENSIONS
70 if (ch == ctrl('O'))
72 ch = getkey(quoted ? 0 : WHEN_EX);
74 #endif
76 /* some special conversions */
77 if (ch == ctrl('D') && len == 0)
78 ch = ctrl('[');
79 #ifndef NO_DIGRAPH
80 if (*o_digraph && erased != 0 && ch != '\b')
82 ch = digraph(erased, ch);
83 erased = 0;
85 #endif
87 /* inhibit detection of special chars (except ^J) after a ^V */
88 if (quoted && ch != '\n')
90 ch |= 256;
93 /* process the character */
94 switch(ch)
96 case ctrl('V'):
97 qaddch('^');
98 qaddch('\b');
99 quoted = TRUE;
100 break;
102 case ctrl('['):
103 return -1;
105 case '\n':
106 #if OSK
107 case '\l':
108 #else
109 case '\r':
110 #endif
111 clrtoeol();
112 goto BreakBreak;
114 case '\b':
115 if (len > 0)
117 len--;
118 #ifndef NO_DIGRAPH
119 erased = buf[len];
120 #endif
121 for (ch = widths[len]; ch > 0; ch--)
122 addch('\b');
123 if (mode == MODE_EX)
125 clrtoeol();
127 tab -= widths[len];
129 else
131 return -1;
133 break;
135 default:
136 /* strip off quotation bit */
137 if (ch & 256)
139 ch &= ~256;
140 qaddch(' ');
141 qaddch('\b');
144 /* add & echo the char */
145 if (len < bsize - 1)
147 if (ch == '\t' && !quoted)
149 widths[len] = *o_tabstop - (tab % *o_tabstop);
150 addstr(" " + 8 - widths[len]);
151 tab += widths[len];
153 else if (ch > 0 && ch < ' ') /* > 0 by GB */
155 addch('^');
156 addch(ch + '@');
157 widths[len] = 2;
158 tab += 2;
160 else if (ch == '\177')
162 addch('^');
163 addch('?');
164 widths[len] = 2;
165 tab += 2;
167 else
169 addch(ch);
170 widths[len] = 1;
171 tab++;
173 buf[len++] = ch;
175 else
177 beep();
179 quoted = FALSE;
182 BreakBreak:
183 refresh();
184 buf[len] = '\0';
185 return len;
189 static int manymsgs; /* This variable keeps msgs from overwriting each other */
190 static char pmsg[80]; /* previous message (waiting to be displayed) */
193 static int showmsg()
195 /* if there is no message to show, then don't */
196 if (!manymsgs)
197 return FALSE;
199 /* display the message */
200 move(LINES - 1, 0);
201 if (*pmsg)
203 standout();
204 qaddch(' ');
205 qaddstr(pmsg);
206 qaddch(' ');
207 standend();
209 clrtoeol();
211 manymsgs = FALSE;
212 return TRUE;
216 void endmsgs()
218 if (manymsgs)
220 showmsg();
221 addch('\n');
225 /* Write a message in an appropriate way. This should really be a varargs
226 * function, but there is no such thing as vwprintw. Hack!!!
228 * In MODE_EX or MODE_COLON, the message is written immediately, with a
229 * newline at the end.
231 * In MODE_VI, the message is stored in a character buffer. It is not
232 * displayed until getkey() is called. msg() will call getkey() itself,
233 * if necessary, to prevent messages from being lost.
235 * msg("") - clears the message line
236 * msg("%s %d", ...) - does a printf onto the message line
238 /*VARARGS1*/
239 void msg(fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
240 char *fmt;
241 long arg1, arg2, arg3, arg4, arg5, arg6, arg7;
243 if (mode != MODE_VI)
245 sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
246 qaddstr(pmsg);
247 addch('\n');
248 exrefresh();
250 else
252 /* wait for keypress between consecutive msgs */
253 if (manymsgs)
255 getkey(WHEN_MSG);
258 /* real message */
259 sprintf(pmsg, fmt, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
260 if (*fmt)
262 manymsgs = TRUE;
268 /* This function calls refresh() if the option exrefresh is set */
269 void exrefresh()
271 char *scan;
273 /* If this ex command wrote ANYTHING set exwrote so vi's : command
274 * can tell that it must wait for a user keystroke before redrawing.
276 for (scan=kbuf; scan<stdscr; scan++)
277 if (*scan == '\n')
278 exwrote = TRUE;
280 /* now we do the refresh thing */
281 if (*o_exrefresh)
283 refresh();
285 else
287 wqrefresh();
289 if (mode != MODE_VI)
291 manymsgs = FALSE;
296 /* This structure is used to store maps and abbreviations. The distinction
297 * between them is that maps are stored in the list referenced by the "maps"
298 * pointer, while abbreviations are referenced by the "abbrs" pointer.
300 typedef struct _map
302 struct _map *next; /* another abbreviation */
303 short len; /* length of the "rawin" characters */
304 short flags; /* various flags */
305 char *label; /* label of the map/abbr, or NULL */
306 char *rawin; /* the "rawin" characters */
307 char *cooked;/* the "cooked" characters */
308 } MAP;
310 static char keybuf[KEYBUFSIZE];
311 static int cend; /* end of input characters */
312 static int user; /* from user through end are chars typed by user */
313 static int next; /* index of the next character to be returned */
314 static MAP *match; /* the matching map, found by countmatch() */
315 static MAP *maps; /* the map table */
316 #ifndef NO_ABBR
317 static MAP *abbrs; /* the abbreviation table */
318 #endif
322 /* ring the terminal's bell */
323 void beep()
325 /* do a visible/audible bell */
326 if (*o_flash)
328 do_VB();
329 refresh();
331 else if (*o_errorbells)
333 ttywrite("\007", 1);
336 /* discard any buffered input, and abort macros */
337 next = user = cend;
342 /* This function replaces a "rawin" character sequence with the "cooked" version,
343 * by modifying the internal type-ahead buffer.
345 void execmap(rawlen, cookedstr, visual)
346 int rawlen; /* length of rawin text -- string to delete */
347 char *cookedstr; /* the cooked text -- string to insert */
348 int visual; /* boolean -- chars to be executed in visual mode? */
350 int cookedlen;
351 char *src, *dst;
352 int i;
354 /* find the length of the cooked string */
355 cookedlen = strlen(cookedstr);
356 #ifndef NO_EXTENSIONS
357 if (visual)
359 cookedlen *= 2;
361 #endif
363 /* if too big to fit in type-ahead buffer, then don't do it */
364 if (cookedlen + (cend - next) - rawlen > KEYBUFSIZE)
366 return;
369 /* shift to make room for cookedstr at the front of keybuf */
370 src = &keybuf[next + rawlen];
371 dst = &keybuf[cookedlen];
372 i = cend - (next + rawlen);
373 if (src >= dst)
375 while (i-- > 0)
377 *dst++ = *src++;
380 else
382 src += i;
383 dst += i;
384 while (i-- > 0)
386 *--dst = *--src;
390 /* insert cookedstr, and adjust offsets */
391 cend += cookedlen - rawlen - next;
392 user += cookedlen - rawlen - next;
393 next = 0;
394 for (dst = keybuf, src = cookedstr; *src; )
396 #ifndef NO_EXTENSIONS
397 if (visual)
399 *dst++ = ctrl('O');
400 cookedlen--;
402 #endif
403 *dst++ = *src++;
406 #ifdef DEBUG2
408 #include <stdio.h>
409 FILE *debout;
410 int i;
412 debout = fopen("debug.out", "a");
413 fprintf(debout, "After execmap(%d, \"%s\", %d)...\n", rawlen, cookedstr, visual);
414 for (i = 0; i < cend; i++)
416 if (i == next) fprintf(debout, "(next)");
417 if (i == user) fprintf(debout, "(user)");
418 if (UCHAR(keybuf[i]) < ' ')
419 fprintf(debout, "^%c", keybuf[i] ^ '@');
420 else
421 fprintf(debout, "%c", keybuf[i]);
423 fprintf(debout, "(end)\n");
424 fclose(debout);
426 #endif
429 /* This function calls ttyread(). If necessary, it will also redraw the screen,
430 * change the cursor shape, display the mode, and update the ruler. If the
431 * number of characters read is 0, and we didn't time-out, then it exits because
432 * we've apparently reached the end of an EX script.
434 static int fillkeybuf(when, timeout)
435 int when; /* mixture of WHEN_XXX flags */
436 int timeout;/* timeout in 1/10 second increments, or 0 */
438 int nkeys;
439 #ifndef NO_SHOWMODE
440 static int oldwhen; /* "when" from last time */
441 static int oldleft;
442 static long oldtop;
443 static long oldnlines;
444 char *str;
445 #endif
446 #ifndef NO_CURSORSHAPE
447 static int oldcurs;
448 #endif
450 #ifdef DEBUG
451 watch();
452 #endif
455 #ifndef NO_CURSORSHAPE
456 /* make sure the cursor is the right shape */
457 if (has_CQ)
459 if (when != oldcurs)
461 switch (when)
463 case WHEN_EX: do_CX(); break;
464 case WHEN_VICMD: do_CV(); break;
465 case WHEN_VIINP: do_CI(); break;
466 case WHEN_VIREP: do_CR(); break;
468 oldcurs = when;
471 #endif
473 #ifndef NO_SHOWMODE
474 /* if "showmode" then say which mode we're in */
475 if (*o_smd && (when & WHENMASK))
477 /* redraw the screen before we check to see whether the
478 * "showmode" message needs to be redrawn.
480 redraw(cursor, !(when & WHEN_VICMD));
482 /* now the "topline" test should be valid */
483 if (when != oldwhen || topline != oldtop || leftcol != oldleft || nlines != oldnlines)
485 oldwhen = when;
486 oldtop = topline;
487 oldleft = leftcol;
488 oldnlines = nlines;
490 if (when & WHEN_VICMD) str = "Command";
491 else if (when & WHEN_VIINP) str = " Input ";
492 else if (when & WHEN_VIREP) str = "Replace";
493 else if (when & WHEN_REP1) str = " Rep 1 ";
494 else if (when & WHEN_CUT) str = "BufName";
495 else if (when & WHEN_MARK) str = "Mark AZ";
496 else if (when & WHEN_CHAR) str = "Dest Ch";
497 else str = (char *)0;
499 if (str)
501 move(LINES - 1, COLS - 10);
502 standout();
503 qaddstr(str);
504 standend();
508 #endif
510 #ifndef NO_EXTENSIONS
511 /* maybe display the ruler */
512 if (*o_ruler && (when & (WHEN_VICMD|WHEN_VIINP|WHEN_VIREP)))
514 char buf[20];
516 redraw(cursor, !(when & WHEN_VICMD));
517 pfetch(markline(cursor));
518 sprintf(buf, "%7ld,%-4d", markline(cursor), 1 + idx2col(cursor, ptext, when & (WHEN_VIINP|WHEN_VIREP)));
519 move(LINES - 1, COLS - 22);
520 addstr(buf);
522 #endif
524 /* redraw, so the cursor is in the right place */
525 if (when & WHENMASK)
527 redraw(cursor, !(when & (WHENMASK & ~(WHEN_VIREP|WHEN_VIINP))));
530 /* Okay, now we can finally read the rawin keystrokes */
531 refresh();
532 nkeys = ttyread(keybuf + cend, sizeof keybuf - cend, timeout);
534 /* if nkeys == 0 then we've reached EOF of an ex script. */
535 if (nkeys == 0 && timeout == 0)
537 tmpabort(TRUE);
538 move(LINES - 1, 0);
539 clrtoeol();
540 refresh();
541 endwin();
542 exit(1);
545 cend += nkeys;
546 user += nkeys;
547 return nkeys;
551 /* This function counts the number of maps that could match the characters
552 * between &keybuf[next] and &keybuf[cend], including incomplete matches.
553 * The longest comlete match is remembered via the "match" variable.
555 static int countmatch(when)
556 int when; /* mixture of WHEN_XXX flags */
558 MAP *map;
559 int count;
561 /* clear the "match" variable */
562 match = (MAP *)0;
564 /* check every map */
565 for (count = 0, map = maps; map; map = map->next)
567 /* can't match if wrong mode */
568 if ((map->flags & when) == 0)
570 continue;
573 /* would this be a complete match? */
574 if (map->len <= cend - next)
576 /* Yes, it would be. Now does it really match? */
577 if (!strncmp(map->rawin, &keybuf[next], map->len))
579 count++;
581 /* if this is the longest complete match,
582 * then remember it.
584 if (!match || match->len < map->len)
586 match = map;
590 else
592 /* No, it wouldn't. But check for partial match */
593 if (!strncmp(map->rawin, &keybuf[next], cend - next))
595 count++;
599 return count;
603 #ifndef NO_ABBR
604 /* This function checks to see whether a word is an abbreviation. If it is,
605 * then an appropriate number of backspoace characters is inserted into the
606 * type-ahead buffer, followed by the expanded form of the abbreviation.
608 static void expandabbr(word, wlen)
609 char *word;
610 int wlen;
612 MAP *abbr;
614 /* if the next character wouldn't end the word, then don't expand */
615 if (isalnum(keybuf[next]) || keybuf[next] == ctrl('V'))
617 return;
620 /* find the abbreviation, if any */
621 for (abbr = abbrs;
622 abbr && (abbr->len != wlen || strncmp(abbr->rawin, word, wlen));
623 abbr = abbr->next)
627 /* If an abbreviation was found, then expand it by inserting the long
628 * version into the type-ahead buffer, and then inserting (in front of
629 * the long version) enough backspaces to erase to the short version.
631 if (abbr)
633 execmap(0, abbr->cooked, FALSE);
634 while (wlen > 15)
636 execmap(0, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", FALSE);
637 wlen -= 15;
639 if (wlen > 0)
641 execmap(0, "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b" + 15 - wlen, FALSE);
645 #endif
648 /* This function calls getabkey() without attempting to expand abbreviations */
649 int getkey(when)
650 int when; /* mixture of WHEN_XXX flags */
652 return getabkey(when, "", 0);
656 /* This is it. This function returns keystrokes one-at-a-time, after mapping
657 * and abbreviations have been taken into account.
659 int getabkey(when, word, wlen)
660 int when; /* mixture of WHEN_XXX flags */
661 char *word; /* a word that may need to be expanded as an abbr */
662 int wlen; /* length of "word" -- since "word" might not have \0 */
664 int matches;
666 /* if this key is needed for delay between multiple error messages,
667 * then reset the manymsgs flag and abort any mapped key sequence.
669 if (showmsg())
671 if (when == WHEN_MSG)
673 #ifndef CRUNCH
674 if (!*o_more)
676 refresh();
677 return ' ';
679 #endif
680 qaddstr("[More...]");
681 refresh();
682 execmap(user, "", FALSE);
686 #ifdef DEBUG
687 /* periodically check for screwed up internal tables */
688 watch();
689 #endif
691 /* if buffer empty, read some characters without timeout */
692 if (next >= cend)
694 next = user = cend = 0;
695 fillkeybuf(when, 0);
698 /* try to map the key, unless already mapped and not ":set noremap" */
699 if (next >= user || *o_remap)
705 matches = countmatch(when);
706 } while (matches > 1 && fillkeybuf(when, *o_keytime) > 0);
707 if (matches == 1)
709 execmap(match->len, match->cooked,
710 (match->flags & WHEN_INMV) != 0
711 && (when & (WHEN_VIINP|WHEN_VIREP)) != 0);
713 } while (*o_remap && matches == 1);
716 #ifndef NO_ABBR
717 /* try to expand an abbreviation, except in visual command mode */
718 if (wlen > 0 && (mode & (WHEN_EX|WHEN_VIINP|WHEN_VIREP)) != 0)
720 expandabbr(word, wlen);
722 #endif
724 /* ERASEKEY should always be mapped to '\b'. */
725 if (keybuf[next] == ERASEKEY)
727 keybuf[next] = '\b';
730 /* return the next key */
731 return keybuf[next++];
734 /* This function maps or unmaps a key */
735 void mapkey(rawin, cooked, when, name)
736 char *rawin; /* the input key sequence, before mapping */
737 char *cooked;/* after mapping -- or NULL to remove map */
738 short when; /* bitmap of when mapping should happen */
739 char *name; /* name of the key, NULL for no name, "abbr" for abbr */
741 MAP **head; /* head of list of maps or abbreviations */
742 MAP *scan; /* used for scanning through the list */
743 MAP *prev; /* used during deletions */
745 /* Is this a map or an abbreviation? Choose the right list. */
746 #ifndef NO_ABBR
747 head = ((!name || strcmp(name, "abbr")) ? &maps : &abbrs);
748 #else
749 head = &maps;
750 #endif
752 /* try to find the map in the list */
753 for (scan = *head, prev = (MAP *)0;
754 scan && (strcmp(rawin, scan->rawin) ||
755 !(scan->flags & when & (WHEN_EX|WHEN_VICMD|WHEN_VIINP|WHEN_VIREP)));
756 prev = scan, scan = scan->next)
760 /* trying to map? (not unmap) */
761 if (cooked && *cooked)
763 /* if map starts with "visual ", then mark it as a visual map */
764 if (head == &maps && !strncmp(cooked, "visual ", 7))
766 cooked += 7;
767 when |= WHEN_INMV;
770 /* "visual" maps always work in input mode */
771 if (when & WHEN_INMV)
773 when |= WHEN_VIINP|WHEN_VIREP|WHEN_POPUP;
776 /* if not already in the list, then allocate a new structure */
777 if (!scan)
779 scan = (MAP *)malloc(sizeof(MAP));
780 scan->len = strlen(rawin);
781 scan->rawin = malloc(scan->len + 1);
782 strcpy(scan->rawin, rawin);
783 scan->flags = when;
784 scan->label = name;
785 if (*head)
787 prev->next = scan;
789 else
791 *head = scan;
793 scan->next = (MAP *)0;
795 else /* recycle old structure */
797 free(scan->cooked);
799 scan->cooked = malloc(strlen(cooked) + 1);
800 strcpy(scan->cooked, cooked);
802 else /* unmapping */
804 /* if nothing to unmap, then exit silently */
805 if (!scan)
807 return;
810 /* unlink the structure from the list */
811 if (prev)
813 prev->next = scan->next;
815 else
817 *head = scan->next;
820 /* free it, and the strings that it refers to */
821 free(scan->rawin);
822 free(scan->cooked);
823 free(scan);
828 /* This function returns a printable version of a string. It uses tmpblk.c */
829 char *printable(str)
830 char *str; /* the string to convert */
832 char *build; /* used for building the string */
834 for (build = tmpblk.c; *str; str++)
836 #if AMIGA
837 if (*str == '\233')
839 *build++ = '<';
840 *build++ = 'C';
841 *build++ = 'S';
842 *build++ = 'I';
843 *build++ = '>';
844 } else
845 #endif
846 if (UCHAR(*str) < ' ' || *str == '\177')
848 *build++ = '^';
849 *build++ = *str ^ '@';
851 else
853 *build++ = *str;
856 *build = '\0';
857 return tmpblk.c;
860 /* This function displays the contents of either the map table or the
861 * abbreviation table. User commands call this function as follows:
862 * :map dumpkey(WHEN_VICMD, FALSE);
863 * :map! dumpkey(WHEN_VIREP|WHEN_VIINP, FALSE);
864 * :abbr dumpkey(WHEN_VIINP|WHEN_VIREP, TRUE);
865 * :abbr! dumpkey(WHEN_EX|WHEN_VIINP|WHEN_VIREP, TRUE);
867 void dumpkey(when, abbr)
868 int when; /* WHEN_XXXX of mappings to be dumped */
869 int abbr; /* boolean: dump abbreviations instead of maps? */
871 MAP *scan;
872 char *str;
873 int len;
875 #ifndef NO_ABBR
876 for (scan = (abbr ? abbrs : maps); scan; scan = scan->next)
877 #else
878 for (scan = maps; scan; scan = scan->next)
879 #endif
881 /* skip entries that don't match "when" */
882 if ((scan->flags & when) == 0)
884 continue;
887 /* dump the key label, if any */
888 if (!abbr)
890 len = 8;
891 if (scan->label)
893 qaddstr(scan->label);
894 len -= strlen(scan->label);
898 qaddch(' ');
899 } while (len-- > 0);
902 /* dump the rawin version */
903 str = printable(scan->rawin);
904 qaddstr(str);
905 len = strlen(str);
908 qaddch(' ');
909 } while (len++ < 8);
911 /* dump the mapped version */
912 #ifndef NO_EXTENSIONS
913 if ((scan->flags & WHEN_INMV) && (when & (WHEN_VIINP|WHEN_VIREP)))
915 qaddstr("visual ");
917 #endif
918 str = printable(scan->cooked);
919 qaddstr(str);
920 addch('\n');
921 exrefresh();
925 #ifndef NO_MKEXRC
927 static safequote(str)
928 char *str;
930 char *build;
932 build = tmpblk.c + strlen(tmpblk.c);
933 while (*str)
935 if (*str <= ' ' && *str >= 1 || *str == '|')
937 *build++ = ctrl('V');
939 *build++ = *str++;
941 *build = '\0';
944 /* This function saves the contents of either the map table or the
945 * abbreviation table into a file. Both the "bang" and "no bang" versions
946 * are saved.
947 * :map dumpkey(WHEN_VICMD, FALSE);
948 * :map! dumpkey(WHEN_VIREP|WHEN_VIINP, FALSE);
949 * :abbr dumpkey(WHEN_VIINP|WHEN_VIREP, TRUE);
950 * :abbr! dumpkey(WHEN_EX|WHEN_VIINP|WHEN_VIREP, TRUE);
952 savemaps(fd, abbr)
953 int fd; /* file descriptor of an open file to write to */
954 int abbr; /* boolean: do abbr table? (else do map table) */
956 MAP *scan;
957 char *str;
958 int bang;
959 int when;
960 int len;
962 # ifndef NO_ABBR
963 for (scan = (abbr ? abbrs : maps); scan; scan = scan->next)
964 # else
965 for (scan = maps; scan; scan = scan->next)
966 # endif
968 /* skip maps that have labels, except for function keys */
969 if (scan->label && *scan->label != '#')
971 continue;
974 for (bang = 0; bang < 2; bang++)
976 /* decide which "when" flags we want */
977 # ifndef NO_ABBR
978 if (abbr)
979 when = (bang ? WHEN_EX|WHEN_VIINP|WHEN_VIREP : WHEN_VIINP|WHEN_VIREP);
980 else
981 # endif
982 when = (bang ? WHEN_VIREP|WHEN_VIINP : WHEN_VICMD);
984 /* skip entries that don't match "when" */
985 if ((scan->flags & when) == 0)
987 continue;
990 /* write a "map" or "abbr" command name */
991 # ifndef NO_ABBR
992 if (abbr)
993 strcpy(tmpblk.c, "abbr");
994 else
995 # endif
996 strcpy(tmpblk.c, "map");
998 /* maybe write a bang. Definitely write a space */
999 if (bang)
1000 strcat(tmpblk.c, "! ");
1001 else
1002 strcat(tmpblk.c, " ");
1004 /* write the rawin version */
1005 # ifndef NO_FKEY
1006 if (scan->label)
1007 strcat(tmpblk.c, scan->label);
1008 else
1009 # endif
1010 safequote(scan->rawin);
1011 strcat(tmpblk.c, " ");
1013 /* dump the mapped version */
1014 # ifndef NO_EXTENSIONS
1015 if ((scan->flags & WHEN_INMV) && (when & (WHEN_VIINP|WHEN_VIREP)))
1017 strcat(tmpblk.c, "visual ");
1019 # endif
1020 safequote(scan->cooked);
1021 strcat(tmpblk.c, "\n");
1022 twrite(fd, tmpblk.c, strlen(tmpblk.c));
1026 #endif