36 #if !defined(lint) && !defined(SCCSID)
38 static char sccsid[] =
"@(#)map.c 8.1 (Berkeley) 6/4/93";
49 private void map_print_key(
EditLine *, el_action_t *,
const Char *);
50 private void map_print_some_keys(
EditLine *, el_action_t *, Int, Int);
51 private void map_print_all_keys(
EditLine *);
52 private void map_init_nls(
EditLine *);
53 private void map_init_meta(
EditLine *);
58 private const el_action_t el_map_emacs[] = {
265 ED_SEARCH_NEXT_HISTORY,
267 ED_SEARCH_PREV_HISTORY,
297 ED_SEARCH_NEXT_HISTORY,
299 ED_SEARCH_PREV_HISTORY,
325 private const el_action_t el_map_vi_insert[] = {
626 private const el_action_t el_map_vi_command[] = {
701 ED_SEARCH_NEXT_HISTORY,
702 ED_SEARCH_PREV_HISTORY,
705 VI_REPEAT_SEARCH_PREV,
737 VI_REPEAT_SEARCH_NEXT,
897 if (
sizeof(el_map_emacs) != N_KEYS *
sizeof(el_action_t))
898 EL_ABORT((el->errfile,
"Emacs map incorrect\n"));
899 if (
sizeof(el_map_vi_command) != N_KEYS *
sizeof(el_action_t))
900 EL_ABORT((el->errfile,
"Vi command map incorrect\n"));
901 if (
sizeof(el_map_vi_insert) != N_KEYS *
sizeof(el_action_t))
902 EL_ABORT((el->errfile,
"Vi insert map incorrect\n"));
905 el->el_map.alt = el_malloc(
sizeof(*el->el_map.alt) * N_KEYS);
906 if (el->el_map.alt == NULL)
908 el->el_map.key = el_malloc(
sizeof(*el->el_map.key) * N_KEYS);
909 if (el->el_map.key == NULL)
911 el->el_map.emacs = el_map_emacs;
912 el->el_map.vic = el_map_vi_command;
913 el->el_map.vii = el_map_vi_insert;
914 el->el_map.help = el_malloc(
sizeof(*el->el_map.help) * EL_NUM_FCNS);
915 if (el->el_map.help == NULL)
917 (void) memcpy(el->el_map.help, help__get(),
918 sizeof(*el->el_map.help) * EL_NUM_FCNS);
919 el->el_map.func = el_malloc(
sizeof(*el->el_map.func) * EL_NUM_FCNS);
920 if (el->el_map.func == NULL)
922 memcpy(el->el_map.func, func__get(),
sizeof(*el->el_map.func)
924 el->el_map.nfunc = EL_NUM_FCNS;
942 el_free(el->el_map.alt);
943 el->el_map.alt = NULL;
944 el_free(el->el_map.key);
945 el->el_map.key = NULL;
946 el->el_map.emacs = NULL;
947 el->el_map.vic = NULL;
948 el->el_map.vii = NULL;
949 el_free(el->el_map.help);
950 el->el_map.help = NULL;
951 el_free(el->el_map.func);
952 el->el_map.func = NULL;
964 el_action_t *map = el->el_map.key;
966 for (i = 0200; i <= 0377; i++)
980 el_action_t *map = el->el_map.key;
981 el_action_t *alt = el->el_map.alt;
983 for (i = 0; i <= 0377 && map[
i] != EM_META_NEXT; i++)
987 for (i = 0; i <= 0377 && alt[
i] != EM_META_NEXT; i++)
991 if (el->el_map.type == MAP_VI)
998 for (i = 0200; i <= 0377; i++)
1002 case ED_SEQUENCE_LEAD_IN:
1006 keymacro_add(el, buf, keymacro_map_cmd(el, (
int) map[i]), XK_CMD);
1009 map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
1020 el_action_t *key = el->el_map.key;
1021 el_action_t *alt = el->el_map.alt;
1022 const el_action_t *vii = el->el_map.vii;
1023 const el_action_t *vic = el->el_map.vic;
1025 el->el_map.type = MAP_VI;
1026 el->el_map.current = el->el_map.key;
1030 for (i = 0; i < N_KEYS; i++) {
1038 tty_bind_char(el, 1);
1039 terminal_bind_arrow(el);
1051 el_action_t *key = el->el_map.key;
1052 el_action_t *alt = el->el_map.alt;
1053 const el_action_t *emacs = el->el_map.emacs;
1055 el->el_map.type = MAP_EMACS;
1056 el->el_map.current = el->el_map.key;
1059 for (i = 0; i < N_KEYS; i++) {
1061 alt[
i] = ED_UNASSIGNED;
1067 buf[0] = CONTROL(
'X');
1068 buf[1] = CONTROL(
'X');
1070 keymacro_add(el, buf, keymacro_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
1072 tty_bind_char(el, 1);
1073 terminal_bind_arrow(el);
1081 map_set_editor(
EditLine *el, Char *editor)
1084 if (Strcmp(editor, STR(
"emacs")) == 0) {
1088 if (Strcmp(editor, STR(
"vi")) == 0) {
1100 map_get_editor(
EditLine *el,
const Char **editor)
1105 switch (el->el_map.type) {
1107 *editor = STR(
"emacs");
1110 *editor = STR(
"vi");
1121 map_print_key(
EditLine *el, el_action_t *map,
const Char *in)
1123 char outbuf[EL_BUFSIZ];
1126 if (in[0] ==
'\0' || in[1] ==
'\0') {
1127 (void) keymacro__decode_str(in, outbuf,
sizeof(outbuf),
"");
1128 ep = &el->el_map.help[el->el_map.nfunc];
1129 for (bp = el->el_map.help; bp < ep; bp++)
1130 if (bp->func == map[(
unsigned char) *in]) {
1131 (void) fprintf(el->el_outfile,
1132 "%s\t->\t" FSTR
"\n", outbuf, bp->name);
1136 keymacro_print(el, in);
1144 map_print_some_keys(
EditLine *el, el_action_t *map, Int first, Int last)
1147 Char firstbuf[2], lastbuf[2];
1148 char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
1150 firstbuf[0] = first;
1154 if (map[first] == ED_UNASSIGNED) {
1155 if (first == last) {
1156 (void) keymacro__decode_str(firstbuf, unparsbuf,
1157 sizeof(unparsbuf), STRQQ);
1158 (void) fprintf(el->el_outfile,
1159 "%-15s-> is undefined\n", unparsbuf);
1163 ep = &el->el_map.help[el->el_map.nfunc];
1164 for (bp = el->el_map.help; bp < ep; bp++) {
1165 if (bp->func == map[first]) {
1166 if (first == last) {
1167 (void) keymacro__decode_str(firstbuf, unparsbuf,
1168 sizeof(unparsbuf), STRQQ);
1169 (void) fprintf(el->el_outfile,
"%-15s-> " FSTR
"\n",
1170 unparsbuf, bp->name);
1172 (void) keymacro__decode_str(firstbuf, unparsbuf,
1173 sizeof(unparsbuf), STRQQ);
1174 (void) keymacro__decode_str(lastbuf, extrabuf,
1175 sizeof(extrabuf), STRQQ);
1176 (void) fprintf(el->el_outfile,
1177 "%-4s to %-7s-> " FSTR
"\n",
1178 unparsbuf, extrabuf, bp->name);
1184 if (map == el->el_map.key) {
1185 (void) keymacro__decode_str(firstbuf, unparsbuf,
1186 sizeof(unparsbuf), STRQQ);
1187 (void) fprintf(el->el_outfile,
1188 "BUG!!! %s isn't bound to anything.\n", unparsbuf);
1189 (void) fprintf(el->el_outfile,
"el->el_map.key[%d] == %d\n",
1190 first, el->el_map.key[first]);
1192 (void) keymacro__decode_str(firstbuf, unparsbuf,
1193 sizeof(unparsbuf), STRQQ);
1194 (void) fprintf(el->el_outfile,
1195 "BUG!!! %s isn't bound to anything.\n", unparsbuf);
1196 (void) fprintf(el->el_outfile,
"el->el_map.alt[%d] == %d\n",
1197 first, el->el_map.alt[first]);
1200 EL_ABORT((el->el_errfile,
"Error printing keys\n"));
1212 (void) fprintf(el->el_outfile,
"Standard key bindings\n");
1214 for (i = 0; i < N_KEYS; i++) {
1215 if (el->el_map.key[prev] == el->el_map.key[i])
1217 map_print_some_keys(el, el->el_map.key, prev, i - 1);
1220 map_print_some_keys(el, el->el_map.key, prev, i - 1);
1222 (void) fprintf(el->el_outfile,
"Alternative key bindings\n");
1224 for (i = 0; i < N_KEYS; i++) {
1225 if (el->el_map.alt[prev] == el->el_map.alt[i])
1227 map_print_some_keys(el, el->el_map.alt, prev, i - 1);
1230 map_print_some_keys(el, el->el_map.alt, prev, i - 1);
1232 (void) fprintf(el->el_outfile,
"Multi-character bindings\n");
1233 keymacro_print(el, STR(
""));
1234 (void) fprintf(el->el_outfile,
"Arrow key bindings\n");
1235 terminal_print_arrow(el, STR(
""));
1243 map_bind(
EditLine *el,
int argc,
const Char **argv)
1248 Char inbuf[EL_BUFSIZ];
1249 Char outbuf[EL_BUFSIZ];
1250 const Char *in = NULL;
1259 map = el->el_map.key;
1262 for (argc = 1; (p = argv[argc]) != NULL; argc++)
1266 map = el->el_map.alt;
1294 ep = &el->el_map.help[el->el_map.nfunc];
1295 for (bp = el->el_map.help; bp < ep; bp++)
1296 (void) fprintf(el->el_outfile,
1297 "" FSTR
"\n\t" FSTR
"\n",
1298 bp->name, bp->description);
1301 (void) fprintf(el->el_errfile,
1302 "" FSTR
": Invalid switch `%c'.\n",
1303 argv[0], (
int) p[1]);
1308 if (argv[argc] == NULL) {
1309 map_print_all_keys(el);
1314 else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
1315 (void) fprintf(el->el_errfile,
1316 "" FSTR
": Invalid \\ or ^ in instring.\n",
1322 (void) terminal_clear_arrow(el, in);
1326 (void) keymacro_delete(el, in);
1327 else if (map[(
unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
1328 (
void) keymacro_delete(el, in);
1330 map[(
unsigned char) *in] = ED_UNASSIGNED;
1333 if (argv[argc] == NULL) {
1335 terminal_print_arrow(el, in);
1337 map_print_key(el, map, in);
1341 if (argv[argc + 1] != NULL) {
1342 bindkeymacro_usage();
1350 if ((out = parse__string(outbuf, argv[argc])) == NULL) {
1351 (void) fprintf(el->el_errfile,
1352 "" FSTR
": Invalid \\ or ^ in outstring.\n", argv[0]);
1356 terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype);
1358 keymacro_add(el, in, keymacro_map_str(el, out), ntype);
1359 map[(
unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
1363 if ((cmd = parse_cmd(el, argv[argc])) == -1) {
1364 (void) fprintf(el->el_errfile,
1365 "" FSTR
": Invalid command `" FSTR
"'.\n",
1366 argv[0], argv[argc]);
1370 terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype);
1373 keymacro_add(el, in, keymacro_map_cmd(el, cmd), ntype);
1374 map[(
unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
1376 keymacro_clear(el, map, in);
1377 map[(
unsigned char) *in] = (el_action_t)cmd;
1383 EL_ABORT((el->el_errfile, "Bad XK_
type %d\
n", ntype));
1394 map_addfunc(
EditLine *el, const Char *
name, const Char *help, el_func_t func)
1397 size_t nf = (size_t)el->el_map.nfunc + 1;
1399 if (name == NULL || help == NULL || func == NULL)
1402 if ((p = el_realloc(el->el_map.func, nf *
1403 sizeof(*el->el_map.func))) == NULL)
1405 el->el_map.func = p;
1406 if ((p = el_realloc(el->el_map.help, nf *
sizeof(*el->el_map.help)))
1409 el->el_map.help = p;
1411 nf = (size_t)el->el_map.nfunc;
1412 el->el_map.func[nf] = func;
1414 el->el_map.help[nf].name = name;
1415 el->el_map.help[nf].func = (
int)nf;
1416 el->el_map.help[nf].description = help;