always set the return screen to something, and do it immediately so
[nvi.git] / ex / ex_map.c
blob65736aaeb68f0646af26bb124939e3079874ff72
1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
6 */
8 #ifndef lint
9 static char sccsid[] = "$Id: ex_map.c,v 8.6 1993/12/02 10:48:12 bostic Exp $ (Berkeley) $Date: 1993/12/02 10:48:12 $";
10 #endif /* not lint */
12 #include <sys/types.h>
14 #include <ctype.h>
15 #include <stdlib.h>
16 #include <string.h>
18 #include "vi.h"
19 #include "seq.h"
20 #include "excmd.h"
23 * ex_map -- :map[!] [input] [replacement]
24 * Map a key/string or display mapped keys.
26 * Historical note:
27 * Historic vi maps were fairly bizarre, and likely to differ in
28 * very subtle and strange ways from this implementation. Two
29 * things worth noting are that vi would often hang or drop core
30 * if the map was strange enough (ex: map X "xy$@x^V), or, simply
31 * not work. One trick worth remembering is that if you put a
32 * mark at the start of the map, e.g. map X mx"xy ...), or if you
33 * put the map in a .exrc file, things would often work much better.
34 * No clue why.
36 int
37 ex_map(sp, ep, cmdp)
38 SCR *sp;
39 EXF *ep;
40 EXCMDARG *cmdp;
42 enum seqtype stype;
43 CHAR_T *input;
44 size_t nlen;
45 int key;
46 char *name, buf[10];
48 stype = F_ISSET(cmdp, E_FORCE) ? SEQ_INPUT : SEQ_COMMAND;
50 switch (cmdp->argc) {
51 case 0:
52 if (seq_dump(sp, stype, 1) == 0)
53 msgq(sp, M_INFO, "No %s map entries.",
54 stype == SEQ_INPUT ? "input" : "command");
55 return (0);
56 case 2:
57 input = cmdp->argv[0]->bp;
58 break;
59 default:
60 abort();
64 * If the mapped string is #[0-9] (and wasn't quoted in any
65 * way, then map to a function key.
67 nlen = 0;
68 if (input[0] == '#' && isdigit(input[1]) && !input[2]) {
69 key = atoi(input + 1);
70 nlen = snprintf(buf, sizeof(buf), "f%d", key);
71 #ifdef notdef
72 if (FKEY[key]) { /* CCC */
73 input = FKEY[key];
74 name = buf;
75 } else {
76 msgq(sp, M_ERR, "This terminal has no %s key.", buf);
77 return (1);
79 #else
80 name = NULL;
81 #endif
82 } else {
83 name = NULL;
85 /* Some single keys may not be remapped in command mode. */
86 if (stype == SEQ_COMMAND && input[1] == '\0')
87 switch (term_key_val(sp, input[0])) {
88 case K_COLON:
89 case K_CR:
90 case K_ESCAPE:
91 case K_NL:
92 msgq(sp, M_ERR,
93 "The %s character may not be remapped.",
94 charname(sp, input[0]));
95 return (1);
98 return (seq_set(sp, name, nlen, input, cmdp->argv[0]->len,
99 cmdp->argv[1]->bp, cmdp->argv[1]->len, stype, 1));
103 * ex_unmap -- (:unmap[!] key)
104 * Unmap a key.
107 ex_unmap(sp, ep, cmdp)
108 SCR *sp;
109 EXF *ep;
110 EXCMDARG *cmdp;
112 if (seq_delete(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len,
113 F_ISSET(cmdp, E_FORCE) ? SEQ_INPUT : SEQ_COMMAND)) {
114 msgq(sp, M_INFO, "\"%s\" isn't mapped.", cmdp->argv[0]->bp);
115 return (1);
117 return (0);
121 * map_save --
122 * Save the mapped sequences to a file.
125 map_save(sp, fp)
126 SCR *sp;
127 FILE *fp;
129 if (seq_save(sp, fp, "map ", SEQ_COMMAND))
130 return (1);
131 return (seq_save(sp, fp, "map! ", SEQ_INPUT));