1b8ba871bSPeter Wemm /*-
2b8ba871bSPeter Wemm * Copyright (c) 1992, 1993, 1994
3b8ba871bSPeter Wemm * The Regents of the University of California. All rights reserved.
4b8ba871bSPeter Wemm * Copyright (c) 1992, 1993, 1994, 1995, 1996
5b8ba871bSPeter Wemm * Keith Bostic. All rights reserved.
6b8ba871bSPeter Wemm *
7b8ba871bSPeter Wemm * See the LICENSE file for redistribution information.
8b8ba871bSPeter Wemm */
9b8ba871bSPeter Wemm
10b8ba871bSPeter Wemm #include "config.h"
11b8ba871bSPeter Wemm
12b8ba871bSPeter Wemm #include <sys/types.h>
13b8ba871bSPeter Wemm #include <sys/queue.h>
14f0957ccaSPeter Wemm #include <sys/time.h>
15b8ba871bSPeter Wemm
16b8ba871bSPeter Wemm #include <bitstring.h>
17b8ba871bSPeter Wemm #include <ctype.h>
18b8ba871bSPeter Wemm #include <limits.h>
19b8ba871bSPeter Wemm #include <stdio.h>
20b8ba871bSPeter Wemm #include <stdlib.h>
21b8ba871bSPeter Wemm #include <string.h>
22b8ba871bSPeter Wemm
23b8ba871bSPeter Wemm #include "../common/common.h"
24b8ba871bSPeter Wemm
25b8ba871bSPeter Wemm /*
26b8ba871bSPeter Wemm * ex_map -- :map[!] [input] [replacement]
27b8ba871bSPeter Wemm * Map a key/string or display mapped keys.
28b8ba871bSPeter Wemm *
29b8ba871bSPeter Wemm * Historical note:
30b8ba871bSPeter Wemm * Historic vi maps were fairly bizarre, and likely to differ in
31b8ba871bSPeter Wemm * very subtle and strange ways from this implementation. Two
32b8ba871bSPeter Wemm * things worth noting are that vi would often hang or drop core
33b8ba871bSPeter Wemm * if the map was strange enough (ex: map X "xy$@x^V), or, simply
34b8ba871bSPeter Wemm * not work. One trick worth remembering is that if you put a
35b8ba871bSPeter Wemm * mark at the start of the map, e.g. map X mx"xy ...), or if you
36b8ba871bSPeter Wemm * put the map in a .exrc file, things would often work much better.
37b8ba871bSPeter Wemm * No clue why.
38b8ba871bSPeter Wemm *
39*c271fa92SBaptiste Daroussin * PUBLIC: int ex_map(SCR *, EXCMD *);
40b8ba871bSPeter Wemm */
41b8ba871bSPeter Wemm int
ex_map(SCR * sp,EXCMD * cmdp)42f0957ccaSPeter Wemm ex_map(SCR *sp, EXCMD *cmdp)
43b8ba871bSPeter Wemm {
44b8ba871bSPeter Wemm seq_t stype;
45b8ba871bSPeter Wemm CHAR_T *input, *p;
46b8ba871bSPeter Wemm
47b8ba871bSPeter Wemm stype = FL_ISSET(cmdp->iflags, E_C_FORCE) ? SEQ_INPUT : SEQ_COMMAND;
48b8ba871bSPeter Wemm
49b8ba871bSPeter Wemm switch (cmdp->argc) {
50b8ba871bSPeter Wemm case 0:
51b8ba871bSPeter Wemm if (seq_dump(sp, stype, 1) == 0)
52b8ba871bSPeter Wemm msgq(sp, M_INFO, stype == SEQ_INPUT ?
53b8ba871bSPeter Wemm "132|No input map entries" :
54b8ba871bSPeter Wemm "133|No command map entries");
55b8ba871bSPeter Wemm return (0);
56b8ba871bSPeter Wemm case 2:
57b8ba871bSPeter Wemm input = cmdp->argv[0]->bp;
58b8ba871bSPeter Wemm break;
59b8ba871bSPeter Wemm default:
60b8ba871bSPeter Wemm abort();
61b8ba871bSPeter Wemm }
62b8ba871bSPeter Wemm
63b8ba871bSPeter Wemm /*
64b8ba871bSPeter Wemm * If the mapped string is #[0-9]* (and wasn't quoted) then store the
65b8ba871bSPeter Wemm * function key mapping. If the screen specific routine has been set,
66b8ba871bSPeter Wemm * call it as well. Note, the SEQ_FUNCMAP type is persistent across
67b8ba871bSPeter Wemm * screen types, maybe the next screen type will get it right.
68b8ba871bSPeter Wemm */
69b8ba871bSPeter Wemm if (input[0] == '#' && isdigit(input[1])) {
70b8ba871bSPeter Wemm for (p = input + 2; isdigit(*p); ++p);
71b8ba871bSPeter Wemm if (p[0] != '\0')
72b8ba871bSPeter Wemm goto nofunc;
73b8ba871bSPeter Wemm
74b8ba871bSPeter Wemm if (seq_set(sp, NULL, 0, input, cmdp->argv[0]->len,
75b8ba871bSPeter Wemm cmdp->argv[1]->bp, cmdp->argv[1]->len, stype,
76b8ba871bSPeter Wemm SEQ_FUNCMAP | SEQ_USERDEF))
77b8ba871bSPeter Wemm return (1);
78b8ba871bSPeter Wemm return (sp->gp->scr_fmap == NULL ? 0 :
79b8ba871bSPeter Wemm sp->gp->scr_fmap(sp, stype, input, cmdp->argv[0]->len,
80b8ba871bSPeter Wemm cmdp->argv[1]->bp, cmdp->argv[1]->len));
81b8ba871bSPeter Wemm }
82b8ba871bSPeter Wemm
83b8ba871bSPeter Wemm /* Some single keys may not be remapped in command mode. */
84b8ba871bSPeter Wemm nofunc: if (stype == SEQ_COMMAND && input[1] == '\0')
85b8ba871bSPeter Wemm switch (KEY_VAL(sp, input[0])) {
86b8ba871bSPeter Wemm case K_COLON:
87b8ba871bSPeter Wemm case K_ESCAPE:
88b8ba871bSPeter Wemm case K_NL:
89b8ba871bSPeter Wemm msgq(sp, M_ERR,
90b8ba871bSPeter Wemm "134|The %s character may not be remapped",
91b8ba871bSPeter Wemm KEY_NAME(sp, input[0]));
92b8ba871bSPeter Wemm return (1);
93b8ba871bSPeter Wemm }
94b8ba871bSPeter Wemm return (seq_set(sp, NULL, 0, input, cmdp->argv[0]->len,
95b8ba871bSPeter Wemm cmdp->argv[1]->bp, cmdp->argv[1]->len, stype, SEQ_USERDEF));
96b8ba871bSPeter Wemm }
97b8ba871bSPeter Wemm
98b8ba871bSPeter Wemm /*
99b8ba871bSPeter Wemm * ex_unmap -- (:unmap[!] key)
100b8ba871bSPeter Wemm * Unmap a key.
101b8ba871bSPeter Wemm *
102*c271fa92SBaptiste Daroussin * PUBLIC: int ex_unmap(SCR *, EXCMD *);
103b8ba871bSPeter Wemm */
104b8ba871bSPeter Wemm int
ex_unmap(SCR * sp,EXCMD * cmdp)105f0957ccaSPeter Wemm ex_unmap(SCR *sp, EXCMD *cmdp)
106b8ba871bSPeter Wemm {
107b8ba871bSPeter Wemm if (seq_delete(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len,
108b8ba871bSPeter Wemm FL_ISSET(cmdp->iflags, E_C_FORCE) ? SEQ_INPUT : SEQ_COMMAND)) {
109f0957ccaSPeter Wemm msgq_wstr(sp, M_INFO,
110b8ba871bSPeter Wemm cmdp->argv[0]->bp, "135|\"%s\" isn't currently mapped");
111b8ba871bSPeter Wemm return (1);
112b8ba871bSPeter Wemm }
113b8ba871bSPeter Wemm return (0);
114b8ba871bSPeter Wemm }
115