#include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: map.c,v 1.25 2009/12/30 22:37:40 christos Exp $");
#endif
#endif
#include <stdlib.h>
#include "el.h"
private void map_print_key(EditLine *, el_action_t *, const Char *);
private void map_print_some_keys(EditLine *, el_action_t *, Int, Int);
private void map_print_all_keys(EditLine *);
private void map_init_nls(EditLine *);
private void map_init_meta(EditLine *);
private const el_action_t el_map_emacs[] = {
EM_SET_MARK,
ED_MOVE_TO_BEG,
ED_PREV_CHAR,
ED_TTY_SIGINT,
EM_DELETE_OR_LIST,
ED_MOVE_TO_END,
ED_NEXT_CHAR,
ED_UNASSIGNED,
EM_DELETE_PREV_CHAR,
ED_UNASSIGNED,
ED_NEWLINE,
ED_KILL_LINE,
ED_CLEAR_SCREEN,
ED_NEWLINE,
ED_NEXT_HISTORY,
ED_TTY_FLUSH_OUTPUT,
ED_PREV_HISTORY,
ED_TTY_START_OUTPUT,
ED_REDISPLAY,
ED_TTY_STOP_OUTPUT,
ED_TRANSPOSE_CHARS,
EM_KILL_LINE,
ED_QUOTED_INSERT,
EM_KILL_REGION,
ED_SEQUENCE_LEAD_IN,
EM_YANK,
ED_TTY_SIGTSTP,
EM_META_NEXT,
ED_TTY_SIGQUIT,
ED_TTY_DSUSP,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_DIGIT,
ED_DIGIT,
ED_DIGIT,
ED_DIGIT,
ED_DIGIT,
ED_DIGIT,
ED_DIGIT,
ED_DIGIT,
ED_DIGIT,
ED_DIGIT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
EM_DELETE_PREV_CHAR,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_DELETE_PREV_WORD,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_CLEAR_SCREEN,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
EM_COPY_PREV_WORD,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_PREV_WORD,
EM_CAPITOL_CASE,
EM_DELETE_NEXT_WORD,
ED_UNASSIGNED,
EM_NEXT_WORD,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
EM_LOWER_CASE,
ED_UNASSIGNED,
ED_SEARCH_NEXT_HISTORY,
ED_SEQUENCE_LEAD_IN,
ED_SEARCH_PREV_HISTORY,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
EM_UPPER_CASE,
ED_UNASSIGNED,
EM_COPY_REGION,
ED_COMMAND,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_SEQUENCE_LEAD_IN,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_PREV_WORD,
EM_CAPITOL_CASE,
EM_DELETE_NEXT_WORD,
ED_UNASSIGNED,
EM_NEXT_WORD,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
EM_LOWER_CASE,
ED_UNASSIGNED,
ED_SEARCH_NEXT_HISTORY,
ED_UNASSIGNED,
ED_SEARCH_PREV_HISTORY,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
EM_UPPER_CASE,
ED_UNASSIGNED,
EM_COPY_REGION,
ED_COMMAND,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_DELETE_PREV_WORD
};
private const el_action_t el_map_vi_insert[] = {
#ifdef KSHVI
ED_UNASSIGNED,
ED_INSERT,
ED_INSERT,
ED_INSERT,
VI_LIST_OR_EOF,
ED_INSERT,
ED_INSERT,
ED_INSERT,
VI_DELETE_PREV_CHAR,
ED_INSERT,
ED_NEWLINE,
ED_INSERT,
ED_INSERT,
ED_NEWLINE,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_TTY_START_OUTPUT,
ED_INSERT,
ED_TTY_STOP_OUTPUT,
ED_INSERT,
VI_KILL_LINE_PREV,
ED_QUOTED_INSERT,
ED_DELETE_PREV_WORD,
ED_INSERT,
ED_INSERT,
ED_INSERT,
VI_COMMAND_MODE,
ED_TTY_SIGQUIT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
#else
ED_UNASSIGNED,
ED_MOVE_TO_BEG,
ED_PREV_CHAR,
ED_TTY_SIGINT,
VI_LIST_OR_EOF,
ED_MOVE_TO_END,
ED_NEXT_CHAR,
ED_UNASSIGNED,
VI_DELETE_PREV_CHAR,
ED_UNASSIGNED,
ED_NEWLINE,
ED_KILL_LINE,
ED_CLEAR_SCREEN,
ED_NEWLINE,
ED_NEXT_HISTORY,
ED_TTY_FLUSH_OUTPUT,
ED_PREV_HISTORY,
ED_TTY_START_OUTPUT,
ED_REDISPLAY,
ED_TTY_STOP_OUTPUT,
ED_TRANSPOSE_CHARS,
VI_KILL_LINE_PREV,
ED_QUOTED_INSERT,
ED_DELETE_PREV_WORD,
ED_UNASSIGNED,
ED_TTY_DSUSP,
ED_TTY_SIGTSTP,
VI_COMMAND_MODE,
ED_TTY_SIGQUIT,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
#endif
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
VI_DELETE_PREV_CHAR,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT,
ED_INSERT
};
private const el_action_t el_map_vi_command[] = {
ED_UNASSIGNED,
ED_MOVE_TO_BEG,
ED_UNASSIGNED,
ED_TTY_SIGINT,
ED_UNASSIGNED,
ED_MOVE_TO_END,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_DELETE_PREV_CHAR,
ED_UNASSIGNED,
ED_NEWLINE,
ED_KILL_LINE,
ED_CLEAR_SCREEN,
ED_NEWLINE,
ED_NEXT_HISTORY,
ED_TTY_FLUSH_OUTPUT,
ED_PREV_HISTORY,
ED_TTY_START_OUTPUT,
ED_REDISPLAY,
ED_TTY_STOP_OUTPUT,
ED_UNASSIGNED,
VI_KILL_LINE_PREV,
ED_UNASSIGNED,
ED_DELETE_PREV_WORD,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
EM_META_NEXT,
ED_TTY_SIGQUIT,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_NEXT_CHAR,
ED_UNASSIGNED,
ED_UNASSIGNED,
VI_COMMENT_OUT,
ED_MOVE_TO_END,
VI_MATCH,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_NEXT_HISTORY,
VI_REPEAT_PREV_CHAR,
ED_PREV_HISTORY,
VI_REDO,
VI_SEARCH_PREV,
VI_ZERO,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_ARGUMENT_DIGIT,
ED_COMMAND,
VI_REPEAT_NEXT_CHAR,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
VI_SEARCH_NEXT,
VI_ALIAS,
VI_ADD_AT_EOL,
VI_PREV_BIG_WORD,
VI_CHANGE_TO_EOL,
ED_KILL_LINE,
VI_END_BIG_WORD,
VI_PREV_CHAR,
VI_TO_HISTORY_LINE,
ED_UNASSIGNED,
VI_INSERT_AT_BOL,
ED_SEARCH_NEXT_HISTORY,
ED_SEARCH_PREV_HISTORY,
ED_UNASSIGNED,
ED_UNASSIGNED,
VI_REPEAT_SEARCH_PREV,
ED_SEQUENCE_LEAD_IN,
VI_PASTE_PREV,
ED_UNASSIGNED,
VI_REPLACE_MODE,
VI_SUBSTITUTE_LINE,
VI_TO_PREV_CHAR,
VI_UNDO_LINE,
ED_UNASSIGNED,
VI_NEXT_BIG_WORD,
ED_DELETE_PREV_CHAR,
VI_YANK_END,
ED_UNASSIGNED,
ED_SEQUENCE_LEAD_IN,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_MOVE_TO_BEG,
VI_HISTORY_WORD,
ED_UNASSIGNED,
VI_ADD,
VI_PREV_WORD,
VI_CHANGE_META,
VI_DELETE_META,
VI_END_WORD,
VI_NEXT_CHAR,
ED_UNASSIGNED,
ED_PREV_CHAR,
VI_INSERT,
ED_NEXT_HISTORY,
ED_PREV_HISTORY,
ED_NEXT_CHAR,
ED_UNASSIGNED,
VI_REPEAT_SEARCH_NEXT,
ED_UNASSIGNED,
VI_PASTE_NEXT,
ED_UNASSIGNED,
VI_REPLACE_CHAR,
VI_SUBSTITUTE_CHAR,
VI_TO_NEXT_CHAR,
VI_UNDO,
VI_HISTEDIT,
VI_NEXT_WORD,
ED_DELETE_NEXT_CHAR,
VI_YANK,
ED_UNASSIGNED,
ED_UNASSIGNED,
VI_TO_COLUMN,
ED_UNASSIGNED,
VI_CHANGE_CASE,
ED_DELETE_PREV_CHAR,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_SEQUENCE_LEAD_IN,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_SEQUENCE_LEAD_IN,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED,
ED_UNASSIGNED
};
protected int
map_init(EditLine *el)
{
#ifdef MAP_DEBUG
if (sizeof(el_map_emacs) != N_KEYS * sizeof(el_action_t))
EL_ABORT((el->errfile, "Emacs map incorrect\n"));
if (sizeof(el_map_vi_command) != N_KEYS * sizeof(el_action_t))
EL_ABORT((el->errfile, "Vi command map incorrect\n"));
if (sizeof(el_map_vi_insert) != N_KEYS * sizeof(el_action_t))
EL_ABORT((el->errfile, "Vi insert map incorrect\n"));
#endif
el->el_map.alt = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
if (el->el_map.alt == NULL)
return (-1);
el->el_map.key = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
if (el->el_map.key == NULL)
return (-1);
el->el_map.emacs = el_map_emacs;
el->el_map.vic = el_map_vi_command;
el->el_map.vii = el_map_vi_insert;
el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) *
EL_NUM_FCNS);
if (el->el_map.help == NULL)
return (-1);
(void) memcpy(el->el_map.help, help__get(),
sizeof(el_bindings_t) * EL_NUM_FCNS);
el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) *
EL_NUM_FCNS);
if (el->el_map.func == NULL)
return (-1);
memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS);
el->el_map.nfunc = EL_NUM_FCNS;
#ifdef VIDEFAULT
map_init_vi(el);
#else
map_init_emacs(el);
#endif
return (0);
}
protected void
map_end(EditLine *el)
{
el_free((ptr_t) el->el_map.alt);
el->el_map.alt = NULL;
el_free((ptr_t) el->el_map.key);
el->el_map.key = NULL;
el->el_map.emacs = NULL;
el->el_map.vic = NULL;
el->el_map.vii = NULL;
el_free((ptr_t) el->el_map.help);
el->el_map.help = NULL;
el_free((ptr_t) el->el_map.func);
el->el_map.func = NULL;
}
private void
map_init_nls(EditLine *el)
{
int i;
el_action_t *map = el->el_map.key;
for (i = 0200; i <= 0377; i++)
if (Isprint(i))
map[i] = ED_INSERT;
}
private void
map_init_meta(EditLine *el)
{
Char buf[3];
int i;
el_action_t *map = el->el_map.key;
el_action_t *alt = el->el_map.alt;
for (i = 0; i <= 0377 && map[i] != EM_META_NEXT; i++)
continue;
if (i > 0377) {
for (i = 0; i <= 0377 && alt[i] != EM_META_NEXT; i++)
continue;
if (i > 0377) {
i = 033;
if (el->el_map.type == MAP_VI)
map = alt;
} else
map = alt;
}
buf[0] = (Char) i;
buf[2] = 0;
for (i = 0200; i <= 0377; i++)
switch (map[i]) {
case ED_INSERT:
case ED_UNASSIGNED:
case ED_SEQUENCE_LEAD_IN:
break;
default:
buf[1] = i & 0177;
key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD);
break;
}
map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
}
protected void
map_init_vi(EditLine *el)
{
int i;
el_action_t *key = el->el_map.key;
el_action_t *alt = el->el_map.alt;
const el_action_t *vii = el->el_map.vii;
const el_action_t *vic = el->el_map.vic;
el->el_map.type = MAP_VI;
el->el_map.current = el->el_map.key;
key_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = vii[i];
alt[i] = vic[i];
}
map_init_meta(el);
map_init_nls(el);
tty_bind_char(el, 1);
term_bind_arrow(el);
}
protected void
map_init_emacs(EditLine *el)
{
int i;
Char buf[3];
el_action_t *key = el->el_map.key;
el_action_t *alt = el->el_map.alt;
const el_action_t *emacs = el->el_map.emacs;
el->el_map.type = MAP_EMACS;
el->el_map.current = el->el_map.key;
key_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = emacs[i];
alt[i] = ED_UNASSIGNED;
}
map_init_meta(el);
map_init_nls(el);
buf[0] = CONTROL('X');
buf[1] = CONTROL('X');
buf[2] = 0;
key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
tty_bind_char(el, 1);
term_bind_arrow(el);
}
protected int
map_set_editor(EditLine *el, Char *editor)
{
if (Strcmp(editor, STR("emacs")) == 0) {
map_init_emacs(el);
return (0);
}
if (Strcmp(editor, STR("vi")) == 0) {
map_init_vi(el);
return (0);
}
return (-1);
}
protected int
map_get_editor(EditLine *el, const Char **editor)
{
if (editor == NULL)
return (-1);
switch (el->el_map.type) {
case MAP_EMACS:
*editor = STR("emacs");
return (0);
case MAP_VI:
*editor = STR("vi");
return (0);
}
return (-1);
}
private void
map_print_key(EditLine *el, el_action_t *map, const Char *in)
{
char outbuf[EL_BUFSIZ];
el_bindings_t *bp, *ep;
if (in[0] == '\0' || in[1] == '\0') {
(void) key__decode_str(in, outbuf, sizeof(outbuf), "");
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
if (bp->func == map[(unsigned char) *in]) {
(void) fprintf(el->el_outfile,
"%s\t->\t" FSTR "\n", outbuf, bp->name);
return;
}
} else
key_print(el, in);
}
private void
map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
{
el_bindings_t *bp, *ep;
Char firstbuf[2], lastbuf[2];
char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
firstbuf[0] = first;
firstbuf[1] = 0;
lastbuf[0] = last;
lastbuf[1] = 0;
if (map[first] == ED_UNASSIGNED) {
if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"%-15s-> is undefined\n", unparsbuf);
}
return;
}
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++) {
if (bp->func == map[first]) {
if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, "%-15s-> " FSTR "\n",
unparsbuf, bp->name);
} else {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) key__decode_str(lastbuf, extrabuf,
sizeof(extrabuf), STRQQ);
(void) fprintf(el->el_outfile,
"%-4s to %-7s-> " FSTR "\n",
unparsbuf, extrabuf, bp->name);
}
return;
}
}
#ifdef MAP_DEBUG
if (map == el->el_map.key) {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf);
(void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n",
first, el->el_map.key[first]);
} else {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf);
(void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n",
first, el->el_map.alt[first]);
}
#endif
EL_ABORT((el->el_errfile, "Error printing keys\n"));
}
private void
map_print_all_keys(EditLine *el)
{
int prev, i;
(void) fprintf(el->el_outfile, "Standard key bindings\n");
prev = 0;
for (i = 0; i < N_KEYS; i++) {
if (el->el_map.key[prev] == el->el_map.key[i])
continue;
map_print_some_keys(el, el->el_map.key, prev, i - 1);
prev = i;
}
map_print_some_keys(el, el->el_map.key, prev, i - 1);
(void) fprintf(el->el_outfile, "Alternative key bindings\n");
prev = 0;
for (i = 0; i < N_KEYS; i++) {
if (el->el_map.alt[prev] == el->el_map.alt[i])
continue;
map_print_some_keys(el, el->el_map.alt, prev, i - 1);
prev = i;
}
map_print_some_keys(el, el->el_map.alt, prev, i - 1);
(void) fprintf(el->el_outfile, "Multi-character bindings\n");
key_print(el, STR(""));
(void) fprintf(el->el_outfile, "Arrow key bindings\n");
term_print_arrow(el, STR(""));
}
protected int
map_bind(EditLine *el, int argc, const Char **argv)
{
el_action_t *map;
int ntype, rem;
const Char *p;
Char inbuf[EL_BUFSIZ];
Char outbuf[EL_BUFSIZ];
const Char *in = NULL;
Char *out = NULL;
el_bindings_t *bp, *ep;
int cmd;
int key;
if (argv == NULL)
return (-1);
map = el->el_map.key;
ntype = XK_CMD;
key = rem = 0;
for (argc = 1; (p = argv[argc]) != NULL; argc++)
if (p[0] == '-')
switch (p[1]) {
case 'a':
map = el->el_map.alt;
break;
case 's':
ntype = XK_STR;
break;
#ifdef notyet
case 'c':
ntype = XK_EXE;
break;
#endif
case 'k':
key = 1;
break;
case 'r':
rem = 1;
break;
case 'v':
map_init_vi(el);
return (0);
case 'e':
map_init_emacs(el);
return (0);
case 'l':
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
(void) fprintf(el->el_outfile,
"" FSTR "\n\t" FSTR "\n",
bp->name, bp->description);
return (0);
default:
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid switch `%c'.\n",
argv[0], p[1]);
}
else
break;
if (argv[argc] == NULL) {
map_print_all_keys(el);
return (0);
}
if (key)
in = argv[argc++];
else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid \\ or ^ in instring.\n",
argv[0]);
return (-1);
}
if (rem) {
if (key) {
(void) term_clear_arrow(el, in);
return (-1);
}
if (in[1])
(void) key_delete(el, in);
else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
(void) key_delete(el, in);
else
map[(unsigned char) *in] = ED_UNASSIGNED;
return (0);
}
if (argv[argc] == NULL) {
if (key)
term_print_arrow(el, in);
else
map_print_key(el, map, in);
return (0);
}
#ifdef notyet
if (argv[argc + 1] != NULL) {
bindkey_usage();
return (-1);
}
#endif
switch (ntype) {
case XK_STR:
case XK_EXE:
if ((out = parse__string(outbuf, argv[argc])) == NULL) {
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid \\ or ^ in outstring.\n", argv[0]);
return (-1);
}
if (key)
term_set_arrow(el, in, key_map_str(el, out), ntype);
else
key_add(el, in, key_map_str(el, out), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
break;
case XK_CMD:
if ((cmd = parse_cmd(el, argv[argc])) == -1) {
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid command `" FSTR "'.\n",
argv[0], argv[argc]);
return (-1);
}
if (key)
term_set_arrow(el, in, key_map_str(el, out), ntype);
else {
if (in[1]) {
key_add(el, in, key_map_cmd(el, cmd), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
} else {
key_clear(el, map, in);
map[(unsigned char) *in] = cmd;
}
}
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
break;
}
return (0);
}
protected int
map_addfunc(EditLine *el, const Char *name, const Char *help, el_func_t func)
{
void *p;
int nf = el->el_map.nfunc + 1;
if (name == NULL || help == NULL || func == NULL)
return (-1);
if ((p = el_realloc(el->el_map.func, nf * sizeof(el_func_t))) == NULL)
return (-1);
el->el_map.func = (el_func_t *) p;
if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t)))
== NULL)
return (-1);
el->el_map.help = (el_bindings_t *) p;
nf = el->el_map.nfunc;
el->el_map.func[nf] = func;
el->el_map.help[nf].name = name;
el->el_map.help[nf].func = nf;
el->el_map.help[nf].description = help;
el->el_map.nfunc++;
return (0);
}