1832 lines
62 KiB
C
1832 lines
62 KiB
C
/* infomap.c -- keymaps for Info.
|
|
$Id: infomap.c,v 1.10 2004/07/30 20:43:40 karl Exp $
|
|
|
|
Copyright (C) 1993, 1997, 1998, 1999, 2001, 2002, 2003, 2004 Free Software
|
|
Foundation, Inc.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
Written by Brian Fox (bfox@ai.mit.edu). */
|
|
|
|
#include "info.h"
|
|
#include "infomap.h"
|
|
#include "funs.h"
|
|
#include "terminal.h"
|
|
|
|
#if defined(INFOKEY)
|
|
#include "infokey.h"
|
|
#include "variables.h"
|
|
#endif /* INFOKEY */
|
|
|
|
static int keymap_bind_keyseq (Keymap map, const char *keyseq,
|
|
KEYMAP_ENTRY *keyentry);
|
|
|
|
/* Return a new keymap which has all the uppercase letters mapped to run
|
|
the function info_do_lowercase_version (). */
|
|
Keymap
|
|
keymap_make_keymap (void)
|
|
{
|
|
int i;
|
|
Keymap keymap;
|
|
|
|
keymap = (Keymap)xmalloc (256 * sizeof (KEYMAP_ENTRY));
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
keymap[i].type = ISFUNC;
|
|
keymap[i].function = (InfoCommand *)NULL;
|
|
}
|
|
|
|
for (i = 'A'; i < ('Z' + 1); i++)
|
|
{
|
|
keymap[i].type = ISFUNC;
|
|
#if defined(INFOKEY)
|
|
keymap[Meta(i)].type = ISFUNC;
|
|
keymap[Meta(i)].function =
|
|
#endif /* INFOKEY */
|
|
keymap[i].function = InfoCmd(info_do_lowercase_version);
|
|
}
|
|
|
|
return (keymap);
|
|
}
|
|
|
|
#if defined(INFOKEY)
|
|
static FUNCTION_KEYSEQ *
|
|
find_function_keyseq (Keymap map, int c, Keymap rootmap)
|
|
{
|
|
FUNCTION_KEYSEQ *k;
|
|
|
|
if (map[c].type != ISFUNC)
|
|
abort();
|
|
if (map[c].function == NULL)
|
|
return NULL;
|
|
for (k = map[c].function->keys; k; k = k->next)
|
|
{
|
|
const unsigned char *p;
|
|
Keymap m = rootmap;
|
|
if (k->map != rootmap)
|
|
continue;
|
|
for (p = (unsigned char *) k->keyseq; *p && m[*p].type == ISKMAP; p++)
|
|
m = (Keymap)m[*p].function;
|
|
if (*p != c || p[1])
|
|
continue;
|
|
if (m[*p].type != ISFUNC)
|
|
abort ();
|
|
break;
|
|
}
|
|
return k;
|
|
}
|
|
|
|
static void
|
|
add_function_keyseq (InfoCommand *function,
|
|
const char *keyseq, Keymap rootmap)
|
|
{
|
|
FUNCTION_KEYSEQ *ks;
|
|
|
|
if (function == NULL ||
|
|
function == InfoCmd(info_do_lowercase_version) ||
|
|
function == InfoCmd(ea_insert))
|
|
return;
|
|
ks = (FUNCTION_KEYSEQ *)xmalloc (sizeof(FUNCTION_KEYSEQ));
|
|
ks->next = function->keys;
|
|
ks->map = rootmap;
|
|
ks->keyseq = xstrdup(keyseq);
|
|
function->keys = ks;
|
|
}
|
|
|
|
static void
|
|
remove_function_keyseq (InfoCommand *function,
|
|
const char *keyseq, Keymap rootmap)
|
|
{
|
|
|
|
FUNCTION_KEYSEQ *k, *kp;
|
|
|
|
if (function == NULL ||
|
|
function == InfoCmd(info_do_lowercase_version) ||
|
|
function == InfoCmd(ea_insert))
|
|
return;
|
|
for (kp = NULL, k = function->keys; k; kp = k, k = k->next)
|
|
if (k->map == rootmap && strcmp(k->keyseq, keyseq) == 0)
|
|
break;
|
|
if (!k)
|
|
abort ();
|
|
if (kp)
|
|
kp->next = k->next;
|
|
else
|
|
function->keys = k->next;
|
|
}
|
|
#endif /* INFOKEY */
|
|
|
|
/* Return a new keymap which is a copy of MAP. */
|
|
Keymap
|
|
keymap_copy_keymap (Keymap map, Keymap rootmap, Keymap newroot)
|
|
{
|
|
int i;
|
|
Keymap keymap;
|
|
#if defined(INFOKEY)
|
|
FUNCTION_KEYSEQ *ks;
|
|
#endif /* INFOKEY */
|
|
|
|
keymap = keymap_make_keymap ();
|
|
if (!newroot)
|
|
newroot = keymap;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
keymap[i].type = map[i].type;
|
|
switch (map[i].type)
|
|
{
|
|
case ISFUNC:
|
|
keymap[i].function = map[i].function;
|
|
#if defined(INFOKEY)
|
|
ks = find_function_keyseq (map, i, rootmap);
|
|
if (ks)
|
|
add_function_keyseq(map[i].function, ks->keyseq, newroot);
|
|
#endif /* INFOKEY */
|
|
break;
|
|
case ISKMAP:
|
|
keymap[i].function = (InfoCommand *)keymap_copy_keymap
|
|
((Keymap)map[i].function, rootmap, NULL);
|
|
break;
|
|
}
|
|
}
|
|
return (keymap);
|
|
}
|
|
|
|
/* Free the keymap and its descendants. */
|
|
void
|
|
keymap_discard_keymap (Keymap map, Keymap rootmap)
|
|
{
|
|
int i;
|
|
|
|
if (!map)
|
|
return;
|
|
if (!rootmap)
|
|
rootmap = map;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
#if defined(INFOKEY)
|
|
FUNCTION_KEYSEQ *ks;
|
|
#endif /* INFOKEY */
|
|
switch (map[i].type)
|
|
{
|
|
case ISFUNC:
|
|
#if defined(INFOKEY)
|
|
ks = find_function_keyseq(map, i, rootmap);
|
|
if (ks)
|
|
remove_function_keyseq (map[i].function, ks->keyseq, rootmap);
|
|
#endif /* INFOKEY */
|
|
break;
|
|
|
|
case ISKMAP:
|
|
keymap_discard_keymap ((Keymap)map[i].function, rootmap);
|
|
break;
|
|
|
|
}
|
|
}
|
|
free(map);
|
|
}
|
|
|
|
/* Conditionally bind key sequence. */
|
|
static int
|
|
keymap_bind_keyseq (Keymap map,
|
|
const char *keyseq, KEYMAP_ENTRY *keyentry)
|
|
{
|
|
Keymap m = map;
|
|
const unsigned char *s = (unsigned char *) keyseq;
|
|
int c;
|
|
|
|
if (s == NULL || *s == '\0') return 0;
|
|
|
|
while ((c = *s++) != '\0')
|
|
{
|
|
#if defined(INFOKEY)
|
|
FUNCTION_KEYSEQ *ks;
|
|
#endif /* INFOKEY */
|
|
switch (m[c].type)
|
|
{
|
|
case ISFUNC:
|
|
#if defined(INFOKEY)
|
|
ks = find_function_keyseq(m, c, map);
|
|
if (ks)
|
|
remove_function_keyseq (m[c].function, ks->keyseq, map);
|
|
#else /* !INFOKEY */
|
|
if (!(m[c].function == NULL || (
|
|
m != map &&
|
|
m[c].function == InfoCmd(info_do_lowercase_version))
|
|
))
|
|
return 0;
|
|
#endif /* !INFOKEY */
|
|
|
|
if (*s != '\0')
|
|
{
|
|
m[c].type = ISKMAP;
|
|
/* Here we are casting the Keymap pointer returned from
|
|
keymap_make_keymap to an InfoCommand pointer. Ugh.
|
|
This makes the `function' structure garbage
|
|
if it's actually interpreted as an InfoCommand.
|
|
Should really be using a union, and taking steps to
|
|
avoid the possible error. */
|
|
m[c].function = (InfoCommand *)keymap_make_keymap ();
|
|
}
|
|
break;
|
|
|
|
case ISKMAP:
|
|
#if defined(INFOKEY)
|
|
if (*s == '\0')
|
|
keymap_discard_keymap ((Keymap)m[c].function, map);
|
|
#else /* !INFOKEY */
|
|
if (*s == '\0')
|
|
return 0;
|
|
#endif
|
|
break;
|
|
}
|
|
if (*s != '\0')
|
|
{
|
|
m = (Keymap)m[c].function;
|
|
}
|
|
else
|
|
{
|
|
#if defined(INFOKEY)
|
|
add_function_keyseq (keyentry->function, keyseq, map);
|
|
#endif /* INFOKEY */
|
|
m[c] = *keyentry;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/* Initialize the standard info keymaps. */
|
|
|
|
Keymap info_keymap = NULL;
|
|
Keymap echo_area_keymap = NULL;
|
|
|
|
#if !defined(INFOKEY)
|
|
|
|
static void
|
|
initialize_emacs_like_keymaps ()
|
|
{
|
|
int i;
|
|
Keymap map;
|
|
|
|
if (!info_keymap)
|
|
{
|
|
info_keymap = keymap_make_keymap ();
|
|
echo_area_keymap = keymap_make_keymap ();
|
|
}
|
|
|
|
info_keymap[ESC].type = ISKMAP;
|
|
info_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
|
|
info_keymap[Control ('x')].type = ISKMAP;
|
|
info_keymap[Control ('x')].function = (InfoCommand *)keymap_make_keymap ();
|
|
|
|
/* Bind the echo area insert routines. Let's make all characters
|
|
insertable by default, regardless of which character set we might
|
|
be using. */
|
|
for (i = 0; i < 256; i++)
|
|
echo_area_keymap[i].function = ea_insert;
|
|
|
|
echo_area_keymap[ESC].type = ISKMAP;
|
|
echo_area_keymap[ESC].function = (InfoCommand *) keymap_make_keymap ();
|
|
echo_area_keymap[Control ('x')].type = ISKMAP;
|
|
echo_area_keymap[Control ('x')].function
|
|
= (InfoCommand *) keymap_make_keymap ();
|
|
|
|
/* Bind numeric arg functions for both echo area and info window maps. */
|
|
for (i = '0'; i < '9' + 1; i++)
|
|
{
|
|
((Keymap) info_keymap[ESC].function)[i].function
|
|
= ((Keymap) echo_area_keymap[ESC].function)[i].function
|
|
= info_add_digit_to_numeric_arg;
|
|
}
|
|
((Keymap) info_keymap[ESC].function)['-'].function =
|
|
((Keymap) echo_area_keymap[ESC].function)['-'].function =
|
|
info_add_digit_to_numeric_arg;
|
|
|
|
info_keymap['-'].function = info_add_digit_to_numeric_arg;
|
|
|
|
/* Bind the echo area routines. */
|
|
map = echo_area_keymap;
|
|
|
|
map[Control ('a')].function = ea_beg_of_line;
|
|
map[Control ('b')].function = ea_backward;
|
|
map[Control ('d')].function = ea_delete;
|
|
map[Control ('e')].function = ea_end_of_line;
|
|
map[Control ('f')].function = ea_forward;
|
|
map[Control ('g')].function = ea_abort;
|
|
map[Control ('h')].function = ea_rubout;
|
|
map[Control ('k')].function = ea_kill_line;
|
|
map[Control ('l')].function = info_redraw_display;
|
|
map[Control ('q')].function = ea_quoted_insert;
|
|
map[Control ('t')].function = ea_transpose_chars;
|
|
map[Control ('u')].function = info_universal_argument;
|
|
map[Control ('y')].function = ea_yank;
|
|
|
|
map[LFD].function = ea_newline;
|
|
map[RET].function = ea_newline;
|
|
map[SPC].function = ea_complete;
|
|
map[TAB].function = ea_complete;
|
|
map['?'].function = ea_possible_completions;
|
|
#ifdef __MSDOS__
|
|
/* PC users will lynch me if I don't give them their usual DEL effect... */
|
|
map[DEL].function = ea_delete;
|
|
#else
|
|
map[DEL].function = ea_rubout;
|
|
#endif
|
|
|
|
/* Bind the echo area ESC keymap. */
|
|
map = (Keymap)echo_area_keymap[ESC].function;
|
|
|
|
map[Control ('g')].function = ea_abort;
|
|
map[Control ('v')].function = ea_scroll_completions_window;
|
|
map['b'].function = ea_backward_word;
|
|
map['d'].function = ea_kill_word;
|
|
map['f'].function = ea_forward_word;
|
|
#if defined (NAMED_FUNCTIONS)
|
|
/* map['x'].function = info_execute_command; */
|
|
#endif /* NAMED_FUNCTIONS */
|
|
map['y'].function = ea_yank_pop;
|
|
map['?'].function = ea_possible_completions;
|
|
map[TAB].function = ea_tab_insert;
|
|
map[DEL].function = ea_backward_kill_word;
|
|
|
|
/* Bind the echo area Control-x keymap. */
|
|
map = (Keymap)echo_area_keymap[Control ('x')].function;
|
|
|
|
map['o'].function = info_next_window;
|
|
map[DEL].function = ea_backward_kill_line;
|
|
|
|
/* Arrow key bindings for echo area keymaps. It seems that some
|
|
terminals do not match their termcap entries, so it's best to just
|
|
define everything with both of the usual prefixes. */
|
|
map = echo_area_keymap;
|
|
keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
|
|
keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
|
|
keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
|
|
keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
|
|
keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
|
|
keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
|
|
keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
|
|
keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
|
|
keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
|
|
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
|
|
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
|
|
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
|
|
keymap_bind_keyseq (map, term_kh, &map[Control ('a')]); /* home */
|
|
keymap_bind_keyseq (map, term_ke, &map[Control ('e')]); /* end */
|
|
|
|
map = (Keymap)echo_area_keymap[ESC].function;
|
|
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
|
|
keymap_bind_keyseq (map, "\033OA", &map['b']);
|
|
keymap_bind_keyseq (map, "\033[A", &map['b']);
|
|
keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
|
|
keymap_bind_keyseq (map, "\033OB", &map['f']);
|
|
keymap_bind_keyseq (map, "\033[B", &map['f']);
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
|
|
|
|
map = (Keymap)echo_area_keymap[Control ('x')].function;
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
|
|
|
|
/* Bind commands for Info window keymaps. */
|
|
map = info_keymap;
|
|
map[TAB].function = info_move_to_next_xref;
|
|
map[LFD].function = info_select_reference_this_line;
|
|
map[RET].function = info_select_reference_this_line;
|
|
map[SPC].function = info_scroll_forward;
|
|
map[Control ('a')].function = info_beginning_of_line;
|
|
map[Control ('b')].function = info_backward_char;
|
|
map[Control ('e')].function = info_end_of_line;
|
|
map[Control ('f')].function = info_forward_char;
|
|
map[Control ('g')].function = info_abort_key;
|
|
map[Control ('h')].function = info_get_help_window;
|
|
map[Control ('l')].function = info_redraw_display;
|
|
map[Control ('n')].function = info_next_line;
|
|
map[Control ('p')].function = info_prev_line;
|
|
map[Control ('r')].function = isearch_backward;
|
|
map[Control ('s')].function = isearch_forward;
|
|
map[Control ('u')].function = info_universal_argument;
|
|
map[Control ('v')].function = info_scroll_forward_page_only;
|
|
map[','].function = info_next_index_match;
|
|
map['/'].function = info_search;
|
|
|
|
for (i = '1'; i < '9' + 1; i++)
|
|
map[i].function = info_menu_digit;
|
|
map['0'].function = info_last_menu_item;
|
|
|
|
map['<'].function = info_first_node;
|
|
map['>'].function = info_last_node;
|
|
map['?'].function = info_get_help_window;
|
|
map['['].function = info_global_prev_node;
|
|
map[']'].function = info_global_next_node;
|
|
|
|
map['b'].function = info_beginning_of_node;
|
|
map['d'].function = info_dir_node;
|
|
map['e'].function = info_end_of_node;
|
|
map['f'].function = info_xref_item;
|
|
map['g'].function = info_goto_node;
|
|
map['G'].function = info_menu_sequence;
|
|
map['h'].function = info_get_info_help_node;
|
|
map['i'].function = info_index_search;
|
|
map['I'].function = info_goto_invocation_node;
|
|
map['l'].function = info_history_node;
|
|
map['m'].function = info_menu_item;
|
|
map['n'].function = info_next_node;
|
|
map['O'].function = info_goto_invocation_node;
|
|
map['p'].function = info_prev_node;
|
|
map['q'].function = info_quit;
|
|
map['r'].function = info_xref_item;
|
|
map['s'].function = info_search;
|
|
map['S'].function = info_search_case_sensitively;
|
|
map['t'].function = info_top_node;
|
|
map['u'].function = info_up_node;
|
|
map[DEL].function = info_scroll_backward;
|
|
|
|
/* Bind members in the ESC map for Info windows. */
|
|
map = (Keymap)info_keymap[ESC].function;
|
|
map[Control ('f')].function = info_show_footnotes;
|
|
map[Control ('g')].function = info_abort_key;
|
|
map[TAB].function = info_move_to_prev_xref;
|
|
map[Control ('v')].function = info_scroll_other_window;
|
|
map['<'].function = info_beginning_of_node;
|
|
map['>'].function = info_end_of_node;
|
|
map['b'].function = info_backward_word;
|
|
map['f'].function = info_forward_word;
|
|
map['r'].function = info_move_to_window_line;
|
|
map['v'].function = info_scroll_backward_page_only;
|
|
#if defined (NAMED_FUNCTIONS)
|
|
map['x'].function = info_execute_command;
|
|
#endif /* NAMED_FUNCTIONS */
|
|
map[DEL].function = info_scroll_other_window_backward;
|
|
|
|
/* Bind members in the Control-X map for Info windows. */
|
|
map = (Keymap)info_keymap[Control ('x')].function;
|
|
|
|
map[Control ('b')].function = list_visited_nodes;
|
|
map[Control ('c')].function = info_quit;
|
|
map[Control ('f')].function = info_view_file;
|
|
map[Control ('g')].function = info_abort_key;
|
|
map[Control ('v')].function = info_view_file;
|
|
map['0'].function = info_delete_window;
|
|
map['1'].function = info_keep_one_window;
|
|
map['2'].function = info_split_window;
|
|
map['^'].function = info_grow_window;
|
|
map['b'].function = select_visited_node;
|
|
map['k'].function = info_kill_node;
|
|
map['n'].function = info_search_next;
|
|
map['N'].function = info_search_previous;
|
|
map['o'].function = info_next_window;
|
|
map['t'].function = info_tile_windows;
|
|
map['w'].function = info_toggle_wrap;
|
|
|
|
/* Arrow key bindings for Info windows keymap. */
|
|
map = info_keymap;
|
|
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
|
|
keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
|
|
keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
|
|
keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
|
|
keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
|
|
keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
|
|
keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
|
|
keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
|
|
keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
|
|
keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
|
|
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
|
|
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
|
|
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
|
|
keymap_bind_keyseq (map, term_kh, &map['b']); /* home */
|
|
keymap_bind_keyseq (map, term_ke, &map['e']); /* end */
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
|
|
|
|
map = (Keymap)info_keymap[ESC].function;
|
|
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
|
|
keymap_bind_keyseq (map, "\033OA", &map['b']);
|
|
keymap_bind_keyseq (map, "\033[A", &map['b']);
|
|
keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
|
|
keymap_bind_keyseq (map, "\033OB", &map['f']);
|
|
keymap_bind_keyseq (map, "\033[B", &map['f']);
|
|
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
|
|
keymap_bind_keyseq (map, term_kP, &map[DEL]); /* pageup */
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
|
|
|
|
/* The alternative to this definition of a `main map' key in the
|
|
`ESC map' section, is something like:
|
|
keymap_bind_keyseq (map, term_kP, &((KeyMap)map[ESC].function).map['v']);
|
|
*/
|
|
keymap_bind_keyseq (info_keymap/*sic*/, term_kP, &map['v']); /* pageup */
|
|
}
|
|
|
|
static void
|
|
initialize_vi_like_keymaps ()
|
|
{
|
|
int i;
|
|
Keymap map;
|
|
|
|
if (!info_keymap)
|
|
{
|
|
info_keymap = keymap_make_keymap ();
|
|
echo_area_keymap = keymap_make_keymap ();
|
|
}
|
|
|
|
info_keymap[ESC].type = ISKMAP;
|
|
info_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
|
|
info_keymap[Control ('x')].type = ISKMAP;
|
|
info_keymap[Control ('x')].function = (InfoCommand *)keymap_make_keymap ();
|
|
|
|
/* Bind the echo area insert routines. */
|
|
for (i = 0; i < 256; i++)
|
|
echo_area_keymap[i].function = ea_insert;
|
|
|
|
echo_area_keymap[ESC].type = ISKMAP;
|
|
echo_area_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
|
|
echo_area_keymap[Control ('x')].type = ISKMAP;
|
|
echo_area_keymap[Control ('x')].function =
|
|
(InfoCommand *)keymap_make_keymap ();
|
|
|
|
/* Bind numeric arg functions for both echo area and info window maps. */
|
|
for (i = '0'; i < '9' + 1; i++)
|
|
{
|
|
info_keymap[i].function =
|
|
((Keymap) echo_area_keymap[ESC].function)[i].function =
|
|
info_add_digit_to_numeric_arg;
|
|
}
|
|
info_keymap['-'].function =
|
|
((Keymap) echo_area_keymap[ESC].function)['-'].function =
|
|
info_add_digit_to_numeric_arg;
|
|
|
|
/* Bind the echo area routines. */
|
|
map = echo_area_keymap;
|
|
|
|
map[Control ('a')].function = ea_beg_of_line;
|
|
map[Control ('b')].function = ea_backward;
|
|
map[Control ('d')].function = ea_delete;
|
|
map[Control ('e')].function = ea_end_of_line;
|
|
map[Control ('f')].function = ea_forward;
|
|
map[Control ('g')].function = ea_abort;
|
|
map[Control ('h')].function = ea_rubout;
|
|
map[Control ('k')].function = ea_kill_line;
|
|
map[Control ('l')].function = info_redraw_display;
|
|
map[Control ('q')].function = ea_quoted_insert;
|
|
map[Control ('t')].function = ea_transpose_chars;
|
|
map[Control ('u')].function = ea_abort;
|
|
map[Control ('v')].function = ea_quoted_insert;
|
|
map[Control ('y')].function = ea_yank;
|
|
|
|
map[LFD].function = ea_newline;
|
|
map[RET].function = ea_newline;
|
|
map[SPC].function = ea_complete;
|
|
map[TAB].function = ea_complete;
|
|
map['?'].function = ea_possible_completions;
|
|
#ifdef __MSDOS__
|
|
/* PC users will lynch me if I don't give them their usual DEL effect... */
|
|
map[DEL].function = ea_delete;
|
|
#else
|
|
map[DEL].function = ea_rubout;
|
|
#endif
|
|
|
|
/* Bind the echo area ESC keymap. */
|
|
map = (Keymap)echo_area_keymap[ESC].function;
|
|
|
|
map[Control ('g')].function = ea_abort;
|
|
map[Control ('h')].function = ea_backward_kill_word;
|
|
map[Control ('v')].function = ea_scroll_completions_window;
|
|
map['0'].function = ea_beg_of_line;
|
|
map['$'].function = ea_end_of_line;
|
|
map['b'].function = ea_backward_word;
|
|
map['d'].function = ea_kill_word;
|
|
map['f'].function = ea_forward_word;
|
|
map['h'].function = ea_backward;
|
|
map['l'].function = ea_forward;
|
|
map['w'].function = ea_forward_word;
|
|
map['x'].function = ea_delete;
|
|
map['X'].function = ea_kill_word;
|
|
map['y'].function = ea_yank_pop;
|
|
map['?'].function = ea_possible_completions;
|
|
map[TAB].function = ea_tab_insert;
|
|
map[DEL].function = ea_kill_word;
|
|
|
|
/* Bind the echo area Control-x keymap. */
|
|
map = (Keymap)echo_area_keymap[Control ('x')].function;
|
|
|
|
map['o'].function = info_next_window;
|
|
map[DEL].function = ea_backward_kill_line;
|
|
|
|
/* Arrow key bindings for echo area keymaps. It seems that some
|
|
terminals do not match their termcap entries, so it's best to just
|
|
define everything with both of the usual prefixes. */
|
|
map = echo_area_keymap;
|
|
keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
|
|
keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
|
|
keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
|
|
keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
|
|
keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
|
|
keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
|
|
keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
|
|
keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
|
|
keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
|
|
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
|
|
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
|
|
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
|
|
keymap_bind_keyseq (map, term_kh, &map[Control ('a')]); /* home */
|
|
keymap_bind_keyseq (map, term_ke, &map[Control ('e')]); /* end */
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
|
|
|
|
map = (Keymap)echo_area_keymap[ESC].function;
|
|
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
|
|
keymap_bind_keyseq (map, "\033OA", &map['b']);
|
|
keymap_bind_keyseq (map, "\033[A", &map['b']);
|
|
keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
|
|
keymap_bind_keyseq (map, "\033OB", &map['f']);
|
|
keymap_bind_keyseq (map, "\033[B", &map['f']);
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
|
|
|
|
map = (Keymap)echo_area_keymap[Control ('x')].function;
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]);
|
|
|
|
/* Bind commands for Info window keymaps. */
|
|
map = info_keymap;
|
|
map[TAB].function = info_move_to_next_xref;
|
|
map[LFD].function = info_down_line;
|
|
map[RET].function = info_down_line;
|
|
map[SPC].function = info_scroll_forward;
|
|
map[Control ('a')].function = info_beginning_of_line;
|
|
map[Control ('b')].function = info_scroll_backward_page_only;
|
|
map[Control ('d')].function = info_scroll_half_screen_down;
|
|
map[Control ('e')].function = info_down_line;
|
|
map[Control ('f')].function = info_scroll_forward_page_only;
|
|
map[Control ('g')].function = info_abort_key;
|
|
map[Control ('k')].function = info_up_line;
|
|
map[Control ('l')].function = info_redraw_display;
|
|
map[Control ('n')].function = info_down_line;
|
|
map[Control ('p')].function = info_up_line;
|
|
map[Control ('r')].function = info_redraw_display;
|
|
map[Control ('s')].function = isearch_forward;
|
|
map[Control ('u')].function = info_scroll_half_screen_up;
|
|
map[Control ('v')].function = info_scroll_forward_page_only;
|
|
map[Control ('y')].function = info_up_line;
|
|
map[','].function = info_next_index_match;
|
|
map['/'].function = info_search;
|
|
|
|
for (i = '1'; i < '9' + 1; i++)
|
|
((Keymap) info_keymap[ESC].function)[i].function = info_menu_digit;
|
|
((Keymap) info_keymap[ESC].function)['0'].function = info_last_menu_item;
|
|
|
|
map['<'].function = info_first_node;
|
|
map['>'].function = info_last_node;
|
|
map['?'].function = info_search_backward;
|
|
map['['].function = info_global_prev_node;
|
|
map[']'].function = info_global_next_node;
|
|
map['\''].function = info_history_node;
|
|
|
|
map['b'].function = info_scroll_backward;
|
|
map['d'].function = info_scroll_half_screen_down;
|
|
map['e'].function = info_down_line;
|
|
map['E'].function = info_view_file;
|
|
map['f'].function = info_scroll_forward_page_only;
|
|
map['F'].function = info_scroll_forward_page_only;
|
|
map['g'].function = info_first_node;
|
|
map['G'].function = info_last_node;
|
|
map['h'].function = info_get_help_window;
|
|
map['H'].function = info_get_help_window;
|
|
map['i'].function = info_index_search;
|
|
map['I'].function = info_goto_invocation_node;
|
|
map['j'].function = info_next_line;
|
|
map['k'].function = info_prev_line;
|
|
map['l'].function = info_history_node;
|
|
map['m'].function = info_menu_item;
|
|
map['n'].function = info_search_next;
|
|
map['N'].function = info_search_previous;
|
|
map['O'].function = info_goto_invocation_node;
|
|
map['p'].function = info_prev_node;
|
|
map['q'].function = info_quit;
|
|
map['Q'].function = info_quit;
|
|
map['r'].function = info_redraw_display;
|
|
map['R'].function = info_redraw_display;
|
|
map['s'].function = info_search;
|
|
map['S'].function = info_search_case_sensitively;
|
|
map['t'].function = info_top_node;
|
|
map['u'].function = info_scroll_half_screen_up;
|
|
map['w'].function = info_scroll_backward_page_only_set_window;
|
|
map['y'].function = info_up_line;
|
|
map['z'].function = info_scroll_forward_page_only_set_window;
|
|
map['Z'].function = NULL; /* unbind, so it works to bind "ZZ" below */
|
|
map[DEL].function = info_scroll_backward;
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]);
|
|
keymap_bind_keyseq (map, ":q", &map['q']);
|
|
keymap_bind_keyseq (map, ":Q", &map['q']);
|
|
keymap_bind_keyseq (map, "ZZ", &map['q']);
|
|
|
|
/* Bind members in the ESC map for Info windows. */
|
|
map = (Keymap)info_keymap[ESC].function;
|
|
map[Control ('f')].function = info_show_footnotes;
|
|
map[Control ('g')].function = info_abort_key;
|
|
map[TAB].function = info_move_to_prev_xref;
|
|
map[SPC].function = info_scroll_forward_page_only;
|
|
map[Control ('v')].function = info_scroll_other_window;
|
|
map['<'].function = info_beginning_of_node;
|
|
map['>'].function = info_end_of_node;
|
|
map['/'].function = info_search;
|
|
map['?'].function = info_search_backward;
|
|
map['b'].function = info_beginning_of_node;
|
|
map['d'].function = info_dir_node;
|
|
map['e'].function = info_end_of_node;
|
|
map['f'].function = info_xref_item;
|
|
map['g'].function = info_select_reference_this_line;
|
|
map['h'].function = info_get_info_help_node;
|
|
map['m'].function = info_menu_item;
|
|
map['n'].function = info_search;
|
|
map['N'].function = info_search_backward;
|
|
map['r'].function = isearch_backward;
|
|
map['s'].function = isearch_forward;
|
|
map['t'].function = info_top_node;
|
|
map['v'].function = info_scroll_backward_page_only;
|
|
#if defined (NAMED_FUNCTIONS)
|
|
map['x'].function = info_execute_command;
|
|
#endif /* NAMED_FUNCTIONS */
|
|
map[DEL].function = info_scroll_other_window_backward;
|
|
|
|
/* Bind members in the Control-X map for Info windows. */
|
|
map = (Keymap)info_keymap[Control ('x')].function;
|
|
|
|
map[Control ('b')].function = list_visited_nodes;
|
|
map[Control ('c')].function = info_quit;
|
|
map[Control ('f')].function = info_view_file;
|
|
map[Control ('g')].function = info_abort_key;
|
|
map[Control ('v')].function = info_view_file;
|
|
map[LFD].function = info_select_reference_this_line;
|
|
map[RET].function = info_select_reference_this_line;
|
|
map['0'].function = info_delete_window;
|
|
map['1'].function = info_keep_one_window;
|
|
map['2'].function = info_split_window;
|
|
map['^'].function = info_grow_window;
|
|
map['b'].function = select_visited_node;
|
|
map['g'].function = info_goto_node;
|
|
map['i'].function = info_index_search;
|
|
map['I'].function = info_goto_invocation_node;
|
|
map['k'].function = info_kill_node;
|
|
map['n'].function = info_next_node;
|
|
map['o'].function = info_next_window;
|
|
map['O'].function = info_goto_invocation_node;
|
|
map['p'].function = info_prev_node;
|
|
map['r'].function = info_xref_item;
|
|
map['t'].function = info_tile_windows;
|
|
map['u'].function = info_up_node;
|
|
map['w'].function = info_toggle_wrap;
|
|
map[','].function = info_next_index_match;
|
|
keymap_bind_keyseq (info_keymap, ":e", &map[Control ('v')]);
|
|
|
|
/* Arrow key bindings for Info windows keymap. */
|
|
map = info_keymap;
|
|
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
|
|
keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
|
|
keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
|
|
keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
|
|
keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
|
|
keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
|
|
keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
|
|
keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
|
|
keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
|
|
keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
|
|
keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
|
|
keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
|
|
keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
|
|
keymap_bind_keyseq (map, term_kh, &map['b']); /* home */
|
|
keymap_bind_keyseq (map, term_ke, &map['e']); /* end */
|
|
|
|
map = (Keymap)info_keymap[ESC].function;
|
|
keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
|
|
keymap_bind_keyseq (map, "\033OA", &map['b']);
|
|
keymap_bind_keyseq (map, "\033[A", &map['b']);
|
|
keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
|
|
keymap_bind_keyseq (map, "\033OB", &map['f']);
|
|
keymap_bind_keyseq (map, "\033[B", &map['f']);
|
|
keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
|
|
keymap_bind_keyseq (map, term_kP, &map[DEL]); /* pageup */
|
|
keymap_bind_keyseq (map, term_kD, &map[DEL]); /* delete */
|
|
|
|
/* The alternative to this definition of a `main map' key in the
|
|
`ESC map' section, is something like:
|
|
keymap_bind_keyseq (map, term_kP, &((KeyMap)map[ESC].function).map['v']);
|
|
*/
|
|
keymap_bind_keyseq (info_keymap/*sic*/, term_kP, &map['v']); /* pageup */
|
|
}
|
|
|
|
void
|
|
initialize_info_keymaps ()
|
|
{
|
|
if (vi_keys_p)
|
|
initialize_vi_like_keymaps ();
|
|
else
|
|
initialize_emacs_like_keymaps ();
|
|
}
|
|
|
|
#else /* defined(INFOKEY) */
|
|
|
|
/* Make sure that we don't have too many command codes defined. */
|
|
|
|
#if A_NCOMMANDS > A_MAX_COMMAND + 1
|
|
#error "too many commands defined"
|
|
#endif
|
|
|
|
/* Initialize the keymaps from the .info keymap file. */
|
|
|
|
#define NUL '\0'
|
|
|
|
static unsigned char default_emacs_like_info_keys[] =
|
|
{
|
|
0, /* suppress-default-keybindings flag */
|
|
TAB, NUL, A_info_move_to_next_xref,
|
|
LFD, NUL, A_info_select_reference_this_line,
|
|
RET, NUL, A_info_select_reference_this_line,
|
|
SPC, NUL, A_info_scroll_forward,
|
|
CONTROL('a'), NUL, A_info_beginning_of_line,
|
|
CONTROL('b'), NUL, A_info_backward_char,
|
|
CONTROL('e'), NUL, A_info_end_of_line,
|
|
CONTROL('f'), NUL, A_info_forward_char,
|
|
CONTROL('g'), NUL, A_info_abort_key,
|
|
CONTROL('h'), NUL, A_info_get_help_window,
|
|
CONTROL('l'), NUL, A_info_redraw_display,
|
|
CONTROL('n'), NUL, A_info_next_line,
|
|
CONTROL('p'), NUL, A_info_prev_line,
|
|
CONTROL('r'), NUL, A_isearch_backward,
|
|
CONTROL('s'), NUL, A_isearch_forward,
|
|
CONTROL('u'), NUL, A_info_universal_argument,
|
|
CONTROL('v'), NUL, A_info_scroll_forward_page_only,
|
|
',', NUL, A_info_next_index_match,
|
|
'/', NUL, A_info_search,
|
|
'0', NUL, A_info_last_menu_item,
|
|
'1', NUL, A_info_menu_digit,
|
|
'2', NUL, A_info_menu_digit,
|
|
'3', NUL, A_info_menu_digit,
|
|
'4', NUL, A_info_menu_digit,
|
|
'5', NUL, A_info_menu_digit,
|
|
'6', NUL, A_info_menu_digit,
|
|
'7', NUL, A_info_menu_digit,
|
|
'8', NUL, A_info_menu_digit,
|
|
'9', NUL, A_info_menu_digit,
|
|
'<', NUL, A_info_first_node,
|
|
'>', NUL, A_info_last_node,
|
|
'?', NUL, A_info_get_help_window,
|
|
'[', NUL, A_info_global_prev_node,
|
|
']', NUL, A_info_global_next_node,
|
|
'b', NUL, A_info_beginning_of_node,
|
|
'd', NUL, A_info_dir_node,
|
|
'e', NUL, A_info_end_of_node,
|
|
'f', NUL, A_info_xref_item,
|
|
'g', NUL, A_info_goto_node,
|
|
'G', NUL, A_info_menu_sequence,
|
|
'h', NUL, A_info_get_info_help_node,
|
|
'i', NUL, A_info_index_search,
|
|
'l', NUL, A_info_history_node,
|
|
'm', NUL, A_info_menu_item,
|
|
'n', NUL, A_info_next_node,
|
|
'O', NUL, A_info_goto_invocation_node,
|
|
'p', NUL, A_info_prev_node,
|
|
'q', NUL, A_info_quit,
|
|
'r', NUL, A_info_xref_item,
|
|
's', NUL, A_info_search,
|
|
'S', NUL, A_info_search_case_sensitively,
|
|
't', NUL, A_info_top_node,
|
|
'u', NUL, A_info_up_node,
|
|
DEL, NUL, A_info_scroll_backward,
|
|
ESC, '0', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, CONTROL('f'), NUL, A_info_show_footnotes,
|
|
ESC, CONTROL('g'), NUL, A_info_abort_key,
|
|
ESC, TAB, NUL, A_info_move_to_prev_xref,
|
|
ESC, CONTROL('v'), NUL, A_info_scroll_other_window,
|
|
ESC, '<', NUL, A_info_beginning_of_node,
|
|
ESC, '>', NUL, A_info_end_of_node,
|
|
ESC, 'b', NUL, A_info_backward_word,
|
|
ESC, 'f', NUL, A_info_forward_word,
|
|
ESC, 'r', NUL, A_info_move_to_window_line,
|
|
ESC, 'v', NUL, A_info_scroll_backward_page_only,
|
|
Meta('0'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta(CONTROL('f')), NUL, A_info_show_footnotes,
|
|
Meta(CONTROL('g')), NUL, A_info_abort_key,
|
|
Meta(TAB), NUL, A_info_move_to_prev_xref,
|
|
Meta(CONTROL('v')), NUL, A_info_scroll_other_window,
|
|
Meta('<'), NUL, A_info_beginning_of_node,
|
|
Meta('>'), NUL, A_info_end_of_node,
|
|
Meta('b'), NUL, A_info_backward_word,
|
|
Meta('f'), NUL, A_info_forward_word,
|
|
Meta('r'), NUL, A_info_move_to_window_line,
|
|
Meta('v'), NUL, A_info_scroll_backward_page_only,
|
|
#if defined (NAMED_FUNCTIONS)
|
|
ESC, 'x', NUL, A_info_execute_command,
|
|
Meta('x'), NUL, A_info_execute_command,
|
|
#endif /* NAMED_FUNCTIONS */
|
|
|
|
CONTROL('x'), CONTROL('b'), NUL, A_list_visited_nodes,
|
|
CONTROL('x'), CONTROL('c'), NUL, A_info_quit,
|
|
CONTROL('x'), CONTROL('f'), NUL, A_info_view_file,
|
|
CONTROL('x'), CONTROL('g'), NUL, A_info_abort_key,
|
|
CONTROL('x'), CONTROL('v'), NUL, A_info_view_file,
|
|
CONTROL('x'), '0', NUL, A_info_delete_window,
|
|
CONTROL('x'), '1', NUL, A_info_keep_one_window,
|
|
CONTROL('x'), '2', NUL, A_info_split_window,
|
|
CONTROL('x'), '^', NUL, A_info_grow_window,
|
|
CONTROL('x'), 'b', NUL, A_select_visited_node,
|
|
CONTROL('x'), 'k', NUL, A_info_kill_node,
|
|
CONTROL('x'), 'n', NUL, A_info_search_next,
|
|
CONTROL('x'), 'N', NUL, A_info_search_previous,
|
|
CONTROL('x'), 'o', NUL, A_info_next_window,
|
|
CONTROL('x'), 't', NUL, A_info_tile_windows,
|
|
CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
|
|
|
|
/* Arrow key bindings for info keymaps. It seems that some
|
|
terminals do not match their termcap entries, so it's best to just
|
|
define everything with both of the usual prefixes. */
|
|
|
|
SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_backward_page_only,
|
|
SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_forward_page_only,
|
|
SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_line,
|
|
'\033', 'O', 'A', NUL, A_info_prev_line,
|
|
'\033', '[', 'A', NUL, A_info_prev_line,
|
|
SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_line,
|
|
'\033', 'O', 'B', NUL, A_info_next_line,
|
|
'\033', '[', 'B', NUL, A_info_next_line,
|
|
SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_forward_char,
|
|
'\033', 'O', 'C', NUL, A_info_forward_char,
|
|
'\033', '[', 'C', NUL, A_info_forward_char,
|
|
SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_backward_char,
|
|
'\033', 'O', 'D', NUL, A_info_backward_char,
|
|
'\033', '[', 'D', NUL, A_info_backward_char,
|
|
SK_ESCAPE, SK_HOME, NUL, A_info_beginning_of_node,
|
|
SK_ESCAPE, SK_END, NUL, A_info_end_of_node,
|
|
SK_ESCAPE, SK_DELETE, NUL, A_info_scroll_backward,
|
|
|
|
ESC, SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_other_window_backward,
|
|
ESC, SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_other_window,
|
|
ESC, SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_line,
|
|
ESC, '\033', 'O', 'A', NUL, A_info_prev_line,
|
|
ESC, '\033', '[', 'A', NUL, A_info_prev_line,
|
|
ESC, SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_line,
|
|
ESC, '\033', 'O', 'B', NUL, A_info_next_line,
|
|
ESC, '\033', '[', 'B', NUL, A_info_next_line,
|
|
ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_forward_word,
|
|
ESC, '\033', 'O', 'C', NUL, A_info_forward_word,
|
|
ESC, '\033', '[', 'C', NUL, A_info_forward_word,
|
|
ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_backward_word,
|
|
ESC, '\033', 'O', 'D', NUL, A_info_backward_word,
|
|
ESC, '\033', '[', 'D', NUL, A_info_backward_word,
|
|
};
|
|
|
|
static unsigned char default_emacs_like_ea_keys[] =
|
|
{
|
|
0, /* suppress-default-keybindings flag */
|
|
ESC, '0', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('0'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, CONTROL('g'), NUL, A_ea_abort,
|
|
ESC, CONTROL('v'), NUL, A_ea_scroll_completions_window,
|
|
ESC, 'b', NUL, A_ea_backward_word,
|
|
ESC, 'd', NUL, A_ea_kill_word,
|
|
ESC, 'f', NUL, A_ea_forward_word,
|
|
ESC, 'y', NUL, A_ea_yank_pop,
|
|
ESC, '?', NUL, A_ea_possible_completions,
|
|
ESC, TAB, NUL, A_ea_tab_insert,
|
|
ESC, DEL, NUL, A_ea_backward_kill_word,
|
|
Meta(CONTROL('g')), NUL, A_ea_abort,
|
|
Meta(CONTROL('v')), NUL, A_ea_scroll_completions_window,
|
|
Meta('b'), NUL, A_ea_backward_word,
|
|
Meta('d'), NUL, A_ea_kill_word,
|
|
Meta('f'), NUL, A_ea_forward_word,
|
|
Meta('y'), NUL, A_ea_yank_pop,
|
|
Meta('?'), NUL, A_ea_possible_completions,
|
|
Meta(TAB), NUL, A_ea_tab_insert,
|
|
Meta(DEL), NUL, A_ea_backward_kill_word,
|
|
CONTROL('a'), NUL, A_ea_beg_of_line,
|
|
CONTROL('b'), NUL, A_ea_backward,
|
|
CONTROL('d'), NUL, A_ea_delete,
|
|
CONTROL('e'), NUL, A_ea_end_of_line,
|
|
CONTROL('f'), NUL, A_ea_forward,
|
|
CONTROL('g'), NUL, A_ea_abort,
|
|
CONTROL('h'), NUL, A_ea_rubout,
|
|
/* CONTROL('k') */
|
|
SK_ESCAPE, SK_LITERAL, NUL, A_ea_kill_line,
|
|
CONTROL('l'), NUL, A_info_redraw_display,
|
|
CONTROL('q'), NUL, A_ea_quoted_insert,
|
|
CONTROL('t'), NUL, A_ea_transpose_chars,
|
|
CONTROL('u'), NUL, A_info_universal_argument,
|
|
CONTROL('y'), NUL, A_ea_yank,
|
|
LFD, NUL, A_ea_newline,
|
|
RET, NUL, A_ea_newline,
|
|
SPC, NUL, A_ea_complete,
|
|
TAB, NUL, A_ea_complete,
|
|
'?', NUL, A_ea_possible_completions,
|
|
#ifdef __MSDOS__
|
|
/* PC users will lynch me if I don't give them their usual DEL
|
|
effect... */
|
|
DEL, NUL, A_ea_delete,
|
|
#else
|
|
DEL, NUL, A_ea_rubout,
|
|
#endif
|
|
#if defined (NAMED_FUNCTIONS)
|
|
/* ESC, 'x', NUL, A_info_execute_command, */
|
|
/* Meta('x'), NUL, A_info_execute_command, */
|
|
#endif /* NAMED_FUNCTIONS */
|
|
CONTROL('x'), 'o', NUL, A_info_next_window,
|
|
CONTROL('x'), DEL, NUL, A_ea_backward_kill_line,
|
|
|
|
/* Arrow key bindings for echo area keymaps. It seems that some
|
|
terminals do not match their termcap entries, so it's best to just
|
|
define everything with both of the usual prefixes. */
|
|
|
|
SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward,
|
|
'\033', 'O', 'C', NUL, A_ea_forward,
|
|
'\033', '[', 'C', NUL, A_ea_forward,
|
|
SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward,
|
|
'\033', 'O', 'D', NUL, A_ea_backward,
|
|
'\033', '[', 'D', NUL, A_ea_backward,
|
|
ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward_word,
|
|
ESC, '\033', 'O', 'C', NUL, A_ea_forward_word,
|
|
ESC, '\033', '[', 'C', NUL, A_ea_forward_word,
|
|
ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward_word,
|
|
ESC, '\033', 'O', 'D', NUL, A_ea_backward_word,
|
|
ESC, '\033', '[', 'D', NUL, A_ea_backward_word,
|
|
#ifdef __MSDOS__
|
|
SK_ESCAPE, SK_DELETE, NUL, A_ea_delete,
|
|
#else
|
|
SK_ESCAPE, SK_DELETE, NUL, A_ea_rubout,
|
|
#endif
|
|
SK_ESCAPE, SK_HOME, NUL, A_ea_beg_of_line,
|
|
SK_ESCAPE, SK_END, NUL, A_ea_end_of_line,
|
|
ESC, SK_ESCAPE, SK_DELETE, NUL, A_ea_backward_kill_word,
|
|
CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
|
|
};
|
|
|
|
static unsigned char default_vi_like_info_keys[] =
|
|
{
|
|
0, /* suppress-default-keybindings flag */
|
|
'0', NUL, A_info_add_digit_to_numeric_arg,
|
|
'1', NUL, A_info_add_digit_to_numeric_arg,
|
|
'2', NUL, A_info_add_digit_to_numeric_arg,
|
|
'3', NUL, A_info_add_digit_to_numeric_arg,
|
|
'4', NUL, A_info_add_digit_to_numeric_arg,
|
|
'5', NUL, A_info_add_digit_to_numeric_arg,
|
|
'6', NUL, A_info_add_digit_to_numeric_arg,
|
|
'7', NUL, A_info_add_digit_to_numeric_arg,
|
|
'8', NUL, A_info_add_digit_to_numeric_arg,
|
|
'9', NUL, A_info_add_digit_to_numeric_arg,
|
|
'-', NUL, A_info_add_digit_to_numeric_arg,
|
|
TAB, NUL, A_info_move_to_next_xref,
|
|
LFD, NUL, A_info_down_line,
|
|
RET, NUL, A_info_down_line,
|
|
SPC, NUL, A_info_scroll_forward,
|
|
CONTROL('a'), NUL, A_info_beginning_of_line,
|
|
CONTROL('b'), NUL, A_info_scroll_backward_page_only,
|
|
CONTROL('d'), NUL, A_info_scroll_half_screen_down,
|
|
CONTROL('e'), NUL, A_info_down_line,
|
|
CONTROL('f'), NUL, A_info_scroll_forward_page_only,
|
|
CONTROL('g'), NUL, A_info_abort_key,
|
|
CONTROL('k'), NUL, A_info_up_line,
|
|
CONTROL('l'), NUL, A_info_redraw_display,
|
|
CONTROL('n'), NUL, A_info_down_line,
|
|
CONTROL('p'), NUL, A_info_up_line,
|
|
CONTROL('r'), NUL, A_info_redraw_display,
|
|
CONTROL('s'), NUL, A_isearch_forward,
|
|
CONTROL('u'), NUL, A_info_scroll_half_screen_up,
|
|
CONTROL('v'), NUL, A_info_scroll_forward_page_only,
|
|
CONTROL('y'), NUL, A_info_up_line,
|
|
',', NUL, A_info_next_index_match,
|
|
'/', NUL, A_info_search,
|
|
ESC, '0', NUL, A_info_last_menu_item,
|
|
ESC, '1', NUL, A_info_menu_digit,
|
|
ESC, '2', NUL, A_info_menu_digit,
|
|
ESC, '3', NUL, A_info_menu_digit,
|
|
ESC, '4', NUL, A_info_menu_digit,
|
|
ESC, '5', NUL, A_info_menu_digit,
|
|
ESC, '6', NUL, A_info_menu_digit,
|
|
ESC, '7', NUL, A_info_menu_digit,
|
|
ESC, '8', NUL, A_info_menu_digit,
|
|
ESC, '9', NUL, A_info_menu_digit,
|
|
Meta('0'), NUL, A_info_last_menu_item,
|
|
Meta('1'), NUL, A_info_menu_digit,
|
|
Meta('2'), NUL, A_info_menu_digit,
|
|
Meta('3'), NUL, A_info_menu_digit,
|
|
Meta('4'), NUL, A_info_menu_digit,
|
|
Meta('5'), NUL, A_info_menu_digit,
|
|
Meta('6'), NUL, A_info_menu_digit,
|
|
Meta('7'), NUL, A_info_menu_digit,
|
|
Meta('8'), NUL, A_info_menu_digit,
|
|
Meta('9'), NUL, A_info_menu_digit,
|
|
'<', NUL, A_info_first_node,
|
|
'>', NUL, A_info_last_node,
|
|
'?', NUL, A_info_search_backward,
|
|
'[', NUL, A_info_global_prev_node,
|
|
']', NUL, A_info_global_next_node,
|
|
'\'', NUL, A_info_history_node,
|
|
'b', NUL, A_info_scroll_backward,
|
|
'd', NUL, A_info_scroll_half_screen_down,
|
|
'e', NUL, A_info_down_line,
|
|
'E', NUL, A_info_view_file,
|
|
':', 'e', NUL, A_info_view_file,
|
|
'f', NUL, A_info_scroll_forward_page_only,
|
|
'F', NUL, A_info_scroll_forward_page_only,
|
|
'g', NUL, A_info_first_node,
|
|
'G', NUL, A_info_last_node,
|
|
'h', NUL, A_info_get_help_window,
|
|
'H', NUL, A_info_get_help_window,
|
|
'i', NUL, A_info_index_search,
|
|
'I', NUL, A_info_goto_invocation_node,
|
|
'j', NUL, A_info_next_line,
|
|
'k', NUL, A_info_prev_line,
|
|
'l', NUL, A_info_history_node,
|
|
'm', NUL, A_info_menu_item,
|
|
'n', NUL, A_info_search_next,
|
|
'N', NUL, A_info_search_previous,
|
|
'O', NUL, A_info_goto_invocation_node,
|
|
'p', NUL, A_info_prev_node,
|
|
'q', NUL, A_info_quit,
|
|
'Q', NUL, A_info_quit,
|
|
':', 'q', NUL, A_info_quit,
|
|
':', 'Q', NUL, A_info_quit,
|
|
'Z', 'Z', NUL, A_info_quit,
|
|
'r', NUL, A_info_redraw_display,
|
|
'R', NUL, A_info_redraw_display,
|
|
's', NUL, A_info_search,
|
|
'S', NUL, A_info_search_case_sensitively,
|
|
't', NUL, A_info_top_node,
|
|
'u', NUL, A_info_scroll_half_screen_up,
|
|
'w', NUL, A_info_scroll_backward_page_only_set_window,
|
|
'y', NUL, A_info_up_line,
|
|
'z', NUL, A_info_scroll_forward_page_only_set_window,
|
|
DEL, NUL, A_info_scroll_backward,
|
|
ESC, CONTROL('f'), NUL, A_info_show_footnotes,
|
|
ESC, CONTROL('g'), NUL, A_info_abort_key,
|
|
ESC, TAB, NUL, A_info_move_to_prev_xref,
|
|
ESC, SPC, NUL, A_info_scroll_forward_page_only,
|
|
ESC, CONTROL('v'), NUL, A_info_scroll_other_window,
|
|
ESC, '<', NUL, A_info_beginning_of_node,
|
|
ESC, '>', NUL, A_info_end_of_node,
|
|
ESC, '/', NUL, A_info_search,
|
|
ESC, '?', NUL, A_info_search_backward,
|
|
ESC, 'b', NUL, A_info_beginning_of_node,
|
|
ESC, 'd', NUL, A_info_dir_node,
|
|
ESC, 'e', NUL, A_info_end_of_node,
|
|
ESC, 'f', NUL, A_info_xref_item,
|
|
ESC, 'g', NUL, A_info_select_reference_this_line,
|
|
ESC, 'h', NUL, A_info_get_info_help_node,
|
|
ESC, 'm', NUL, A_info_menu_item,
|
|
ESC, 'n', NUL, A_info_search,
|
|
ESC, 'N', NUL, A_info_search_backward,
|
|
ESC, 'r', NUL, A_isearch_backward,
|
|
ESC, 's', NUL, A_isearch_forward,
|
|
ESC, 't', NUL, A_info_top_node,
|
|
ESC, 'v', NUL, A_info_scroll_backward_page_only,
|
|
#if defined (NAMED_FUNCTIONS)
|
|
ESC, 'x', NUL, A_info_execute_command,
|
|
Meta('x'), NUL, A_info_execute_command,
|
|
#endif /* NAMED_FUNCTIONS */
|
|
ESC, DEL, NUL, A_info_scroll_other_window_backward,
|
|
CONTROL('x'), CONTROL('b'), NUL, A_list_visited_nodes,
|
|
CONTROL('x'), CONTROL('c'), NUL, A_info_quit,
|
|
CONTROL('x'), CONTROL('f'), NUL, A_info_view_file,
|
|
CONTROL('x'), CONTROL('g'), NUL, A_info_abort_key,
|
|
CONTROL('x'), CONTROL('v'), NUL, A_info_view_file,
|
|
CONTROL('x'), LFD, NUL, A_info_select_reference_this_line,
|
|
CONTROL('x'), RET, NUL, A_info_select_reference_this_line,
|
|
CONTROL('x'), '0', NUL, A_info_delete_window,
|
|
CONTROL('x'), '1', NUL, A_info_keep_one_window,
|
|
CONTROL('x'), '2', NUL, A_info_split_window,
|
|
CONTROL('x'), '^', NUL, A_info_grow_window,
|
|
CONTROL('x'), 'b', NUL, A_select_visited_node,
|
|
CONTROL('x'), 'g', NUL, A_info_goto_node,
|
|
CONTROL('x'), 'i', NUL, A_info_index_search,
|
|
CONTROL('x'), 'I', NUL, A_info_goto_invocation_node,
|
|
CONTROL('x'), 'k', NUL, A_info_kill_node,
|
|
CONTROL('x'), 'n', NUL, A_info_next_node,
|
|
CONTROL('x'), 'o', NUL, A_info_next_window,
|
|
CONTROL('x'), 'O', NUL, A_info_goto_invocation_node,
|
|
CONTROL('x'), 'p', NUL, A_info_prev_node,
|
|
CONTROL('x'), 'r', NUL, A_info_xref_item,
|
|
CONTROL('x'), 't', NUL, A_info_tile_windows,
|
|
CONTROL('x'), 'u', NUL, A_info_up_node,
|
|
CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
|
|
CONTROL('x'), ',', NUL, A_info_next_index_match,
|
|
|
|
/* Arrow key bindings for info keymaps. It seems that some
|
|
terminals do not match their termcap entries, so it's best to just
|
|
define everything with both of the usual prefixes. */
|
|
|
|
SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_backward_page_only,
|
|
SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_forward_page_only,
|
|
SK_ESCAPE, SK_UP_ARROW, NUL, A_info_up_line,
|
|
'\033', 'O', 'A', NUL, A_info_up_line,
|
|
'\033', '[', 'A', NUL, A_info_up_line,
|
|
SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_down_line,
|
|
'\033', 'O', 'B', NUL, A_info_down_line,
|
|
'\033', '[', 'B', NUL, A_info_down_line,
|
|
SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_scroll_forward_page_only,
|
|
'\033', 'O', 'C', NUL, A_info_scroll_forward_page_only,
|
|
'\033', '[', 'C', NUL, A_info_scroll_forward_page_only,
|
|
SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_scroll_backward_page_only,
|
|
'\033', 'O', 'D', NUL, A_info_scroll_backward_page_only,
|
|
'\033', '[', 'D', NUL, A_info_scroll_backward_page_only,
|
|
SK_ESCAPE, SK_HOME, NUL, A_info_beginning_of_node,
|
|
SK_ESCAPE, SK_END, NUL, A_info_end_of_node,
|
|
ESC, SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_other_window,
|
|
ESC, SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_other_window_backward,
|
|
ESC, SK_ESCAPE, SK_DELETE, NUL, A_info_scroll_other_window_backward,
|
|
ESC, SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_node,
|
|
ESC, '\033', 'O', 'A', NUL, A_info_prev_node,
|
|
ESC, '\033', '[', 'A', NUL, A_info_prev_node,
|
|
ESC, SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_node,
|
|
ESC, '\033', 'O', 'B', NUL, A_info_next_node,
|
|
ESC, '\033', '[', 'B', NUL, A_info_next_node,
|
|
ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_xref_item,
|
|
ESC, '\033', 'O', 'C', NUL, A_info_xref_item,
|
|
ESC, '\033', '[', 'C', NUL, A_info_xref_item,
|
|
ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_beginning_of_node,
|
|
ESC, '\033', 'O', 'D', NUL, A_info_beginning_of_node,
|
|
ESC, '\033', '[', 'D', NUL, A_info_beginning_of_node,
|
|
CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
|
|
};
|
|
|
|
static unsigned char default_vi_like_ea_keys[] =
|
|
{
|
|
0, /* suppress-default-keybindings flag */
|
|
ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
|
|
Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
|
|
ESC, CONTROL('g'), NUL, A_ea_abort,
|
|
ESC, CONTROL('h'), NUL, A_ea_backward_kill_word,
|
|
ESC, CONTROL('v'), NUL, A_ea_scroll_completions_window,
|
|
ESC, '0', NUL, A_ea_beg_of_line,
|
|
ESC, '$', NUL, A_ea_end_of_line,
|
|
ESC, 'b', NUL, A_ea_backward_word,
|
|
ESC, 'd', NUL, A_ea_kill_word,
|
|
ESC, 'f', NUL, A_ea_forward_word,
|
|
ESC, 'h', NUL, A_ea_forward,
|
|
ESC, 'l', NUL, A_ea_backward,
|
|
ESC, 'w', NUL, A_ea_forward_word,
|
|
ESC, 'x', NUL, A_ea_delete,
|
|
ESC, 'X', NUL, A_ea_kill_word,
|
|
ESC, 'y', NUL, A_ea_yank_pop,
|
|
ESC, '?', NUL, A_ea_possible_completions,
|
|
ESC, TAB, NUL, A_ea_tab_insert,
|
|
ESC, DEL, NUL, A_ea_kill_word,
|
|
Meta(CONTROL('g')), NUL, A_ea_abort,
|
|
Meta(CONTROL('h')), NUL, A_ea_backward_kill_word,
|
|
Meta(CONTROL('v')), NUL, A_ea_scroll_completions_window,
|
|
Meta('0'), NUL, A_ea_beg_of_line,
|
|
Meta('$'), NUL, A_ea_end_of_line,
|
|
Meta('b'), NUL, A_ea_backward_word,
|
|
Meta('d'), NUL, A_ea_kill_word,
|
|
Meta('f'), NUL, A_ea_forward_word,
|
|
Meta('h'), NUL, A_ea_forward,
|
|
Meta('l'), NUL, A_ea_backward,
|
|
Meta('w'), NUL, A_ea_forward_word,
|
|
Meta('x'), NUL, A_ea_delete,
|
|
Meta('X'), NUL, A_ea_kill_word,
|
|
Meta('y'), NUL, A_ea_yank_pop,
|
|
Meta('?'), NUL, A_ea_possible_completions,
|
|
Meta(TAB), NUL, A_ea_tab_insert,
|
|
Meta(DEL), NUL, A_ea_kill_word,
|
|
CONTROL('a'), NUL, A_ea_beg_of_line,
|
|
CONTROL('b'), NUL, A_ea_backward,
|
|
CONTROL('d'), NUL, A_ea_delete,
|
|
CONTROL('e'), NUL, A_ea_end_of_line,
|
|
CONTROL('f'), NUL, A_ea_forward,
|
|
CONTROL('g'), NUL, A_ea_abort,
|
|
CONTROL('h'), NUL, A_ea_rubout,
|
|
/* CONTROL('k') */
|
|
SK_ESCAPE, SK_LITERAL, NUL, A_ea_kill_line,
|
|
CONTROL('l'), NUL, A_info_redraw_display,
|
|
CONTROL('q'), NUL, A_ea_quoted_insert,
|
|
CONTROL('t'), NUL, A_ea_transpose_chars,
|
|
CONTROL('u'), NUL, A_ea_abort,
|
|
CONTROL('v'), NUL, A_ea_quoted_insert,
|
|
CONTROL('y'), NUL, A_ea_yank,
|
|
LFD, NUL, A_ea_newline,
|
|
RET, NUL, A_ea_newline,
|
|
SPC, NUL, A_ea_complete,
|
|
TAB, NUL, A_ea_complete,
|
|
'?', NUL, A_ea_possible_completions,
|
|
#ifdef __MSDOS__
|
|
/* PC users will lynch me if I don't give them their usual DEL
|
|
effect... */
|
|
DEL, NUL, A_ea_delete,
|
|
#else
|
|
DEL, NUL, A_ea_rubout,
|
|
#endif
|
|
CONTROL('x'), 'o', NUL, A_info_next_window,
|
|
CONTROL('x'), DEL, NUL, A_ea_backward_kill_line,
|
|
|
|
/* Arrow key bindings for echo area keymaps. It seems that some
|
|
terminals do not match their termcap entries, so it's best to just
|
|
define everything with both of the usual prefixes. */
|
|
|
|
SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward,
|
|
'\033', 'O', 'C', NUL, A_ea_forward,
|
|
'\033', '[', 'C', NUL, A_ea_forward,
|
|
SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward,
|
|
'\033', 'O', 'D', NUL, A_ea_backward,
|
|
'\033', '[', 'D', NUL, A_ea_backward,
|
|
SK_ESCAPE, SK_HOME, NUL, A_ea_beg_of_line,
|
|
SK_ESCAPE, SK_END, NUL, A_ea_end_of_line,
|
|
#ifdef __MSDOS__
|
|
SK_ESCAPE, SK_DELETE, NUL, A_ea_delete,
|
|
#else
|
|
SK_DELETE, SK_DELETE, NUL, A_ea_rubout,
|
|
#endif
|
|
ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward_word,
|
|
ESC, '\033', 'O', 'C', NUL, A_ea_forward_word,
|
|
ESC, '\033', '[', 'C', NUL, A_ea_forward_word,
|
|
ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward_word,
|
|
ESC, '\033', 'O', 'D', NUL, A_ea_backward_word,
|
|
ESC, '\033', '[', 'D', NUL, A_ea_backward_word,
|
|
ESC, SK_ESCAPE, SK_DELETE, NUL, A_ea_kill_word,
|
|
CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
|
|
};
|
|
|
|
static unsigned char *user_info_keys;
|
|
static unsigned int user_info_keys_len;
|
|
static unsigned char *user_ea_keys;
|
|
static unsigned int user_ea_keys_len;
|
|
static unsigned char *user_vars;
|
|
static unsigned int user_vars_len;
|
|
|
|
/*
|
|
* Return the size of a file, or 0 if the size can't be determined.
|
|
*/
|
|
static unsigned long
|
|
filesize(int f)
|
|
{
|
|
long pos = lseek(f, 0L, SEEK_CUR);
|
|
long sz = -1L;
|
|
if (pos != -1L)
|
|
{
|
|
sz = lseek(f, 0L, SEEK_END);
|
|
lseek(f, pos, SEEK_SET);
|
|
}
|
|
return sz == -1L ? 0L : sz;
|
|
}
|
|
|
|
/* Get an integer from a infokey file.
|
|
Integers are stored as two bytes, low order first, in radix INFOKEY_RADIX.
|
|
*/
|
|
static int
|
|
getint(unsigned char **sp)
|
|
{
|
|
int n;
|
|
|
|
if ( !((*sp)[0] < INFOKEY_RADIX && (*sp)[1] < INFOKEY_RADIX) )
|
|
return -1;
|
|
n = (*sp)[0] + (*sp)[1] * INFOKEY_RADIX;
|
|
*sp += 2;
|
|
return n;
|
|
}
|
|
|
|
|
|
/* Fetch the contents of the standard infokey file "$HOME/.info". Return
|
|
true if ok, false if not. */
|
|
static int
|
|
fetch_user_maps(void)
|
|
{
|
|
char *filename = NULL;
|
|
char *homedir;
|
|
int f;
|
|
unsigned char *buf;
|
|
unsigned long len;
|
|
long nread;
|
|
unsigned char *p;
|
|
int n;
|
|
|
|
/* Find and open file. */
|
|
if ((filename = getenv("INFOKEY")) != NULL)
|
|
filename = xstrdup(filename);
|
|
else if ((homedir = getenv("HOME")) != NULL)
|
|
{
|
|
filename = xmalloc(strlen(homedir) + 2 + strlen(INFOKEY_FILE));
|
|
strcpy(filename, homedir);
|
|
strcat(filename, "/");
|
|
strcat(filename, INFOKEY_FILE);
|
|
}
|
|
#ifdef __MSDOS__
|
|
/* Poor baby, she doesn't have a HOME... */
|
|
else
|
|
filename = xstrdup(INFOKEY_FILE); /* try current directory */
|
|
#endif
|
|
if (filename == NULL || (f = open(filename, O_RDONLY)) == (-1))
|
|
{
|
|
if (filename && errno != ENOENT)
|
|
{
|
|
info_error(filesys_error_string(filename, errno),
|
|
NULL, NULL);
|
|
free(filename);
|
|
}
|
|
return 0;
|
|
}
|
|
SET_BINARY (f);
|
|
|
|
/* Ensure that the file is a reasonable size. */
|
|
len = filesize(f);
|
|
if (len < INFOKEY_NMAGIC + 2 || len > 100 * 1024)
|
|
{
|
|
/* Bad file (a valid file must have at least 9 chars, and
|
|
more than 100 KB is a problem). */
|
|
if (len < INFOKEY_NMAGIC + 2)
|
|
info_error((char *) _("Ignoring invalid infokey file `%s' - too small"),
|
|
filename, NULL);
|
|
else
|
|
info_error((char *) _("Ignoring invalid infokey file `%s' - too big"),
|
|
filename, NULL);
|
|
close(f);
|
|
free(filename);
|
|
return 0;
|
|
}
|
|
|
|
/* Read the file into a buffer. */
|
|
buf = (unsigned char *)xmalloc((int)len);
|
|
nread = read(f, buf, (unsigned int) len);
|
|
close(f);
|
|
if ((unsigned int) nread != len)
|
|
{
|
|
info_error((char *) _("Error reading infokey file `%s' - short read"),
|
|
filename, NULL);
|
|
free(buf);
|
|
free(filename);
|
|
return 0;
|
|
}
|
|
|
|
/* Check the header, trailer, and version of the file to increase
|
|
our confidence that the contents are valid. */
|
|
if ( buf[0] != INFOKEY_MAGIC_S0
|
|
|| buf[1] != INFOKEY_MAGIC_S1
|
|
|| buf[2] != INFOKEY_MAGIC_S2
|
|
|| buf[3] != INFOKEY_MAGIC_S3
|
|
|| buf[len - 4] != INFOKEY_MAGIC_E0
|
|
|| buf[len - 3] != INFOKEY_MAGIC_E1
|
|
|| buf[len - 2] != INFOKEY_MAGIC_E2
|
|
|| buf[len - 1] != INFOKEY_MAGIC_E3
|
|
)
|
|
{
|
|
info_error((char *) _("Invalid infokey file `%s' (bad magic numbers) -- run infokey to update it"),
|
|
filename, NULL);
|
|
free(filename);
|
|
return 0;
|
|
}
|
|
if (len < INFOKEY_NMAGIC + strlen(VERSION) + 1
|
|
|| strcmp(VERSION, (char *) (buf + 4)) != 0)
|
|
{
|
|
info_error
|
|
((char *) _("Your infokey file `%s' is out of date -- run infokey to update it"),
|
|
filename, NULL);
|
|
free(filename);
|
|
return 0;
|
|
}
|
|
|
|
/* Extract the pieces. */
|
|
for (p = buf + 4 + strlen(VERSION) + 1;
|
|
(unsigned int) (p - buf) < len - 4;
|
|
p += n)
|
|
{
|
|
int s = *p++;
|
|
|
|
n = getint(&p);
|
|
if (n < 0 || (unsigned int) n > len - 4 - (p - buf))
|
|
{
|
|
info_error((char *) _("Invalid infokey file `%s' (bad section length) -- run infokey to update it"),
|
|
filename, NULL);
|
|
free(filename);
|
|
return 0;
|
|
}
|
|
|
|
switch (s)
|
|
{
|
|
case INFOKEY_SECTION_INFO:
|
|
user_info_keys = p;
|
|
user_info_keys_len = n;
|
|
break;
|
|
case INFOKEY_SECTION_EA:
|
|
user_ea_keys = p;
|
|
user_ea_keys_len = n;
|
|
break;
|
|
case INFOKEY_SECTION_VAR:
|
|
user_vars = p;
|
|
user_vars_len = n;
|
|
break;
|
|
default:
|
|
info_error((char *) _("Invalid infokey file `%s' (bad section code) -- run infokey to update it"),
|
|
filename, NULL);
|
|
free(filename);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
free(filename);
|
|
return 1;
|
|
}
|
|
|
|
/* Decode special key sequences from the infokey file. Return zero
|
|
if the key sequence includes special keys which the terminal
|
|
doesn't define.
|
|
*/
|
|
static int
|
|
decode_keys(unsigned char *src, unsigned int slen,
|
|
unsigned char *dst, unsigned int dlen)
|
|
{
|
|
unsigned char *s = src;
|
|
unsigned char *d = dst;
|
|
|
|
#define To_dst(c) do { \
|
|
if ((unsigned int) (d - dst) < dlen) *d++ = (c); \
|
|
} while (0)
|
|
|
|
while ((unsigned int) (s - src) < slen)
|
|
{
|
|
unsigned char c = ISMETA(*s) ? UNMETA(*s) : *s;
|
|
|
|
if (c == SK_ESCAPE)
|
|
{
|
|
char *t;
|
|
static char lit[] = { SK_ESCAPE, NUL };
|
|
|
|
switch ((unsigned int) (s + 1 - src) < slen ? s[1] : '\0')
|
|
{
|
|
case SK_RIGHT_ARROW: t = term_kr; break;
|
|
case SK_LEFT_ARROW: t = term_kl; break;
|
|
case SK_UP_ARROW: t = term_ku; break;
|
|
case SK_DOWN_ARROW: t = term_kd; break;
|
|
case SK_PAGE_UP: t = term_kP; break;
|
|
case SK_PAGE_DOWN: t = term_kN; break;
|
|
case SK_HOME: t = term_kh; break;
|
|
case SK_END: t = term_ke; break;
|
|
case SK_DELETE: t = term_kx; break;
|
|
case SK_INSERT: t = term_ki; break;
|
|
case SK_LITERAL:
|
|
default: t = lit; break;
|
|
}
|
|
if (t == NULL)
|
|
return 0;
|
|
while (*t)
|
|
To_dst(ISMETA(*s) ? Meta(*t++) : *t++);
|
|
s += 2;
|
|
}
|
|
else
|
|
{
|
|
if (ISMETA(*s))
|
|
To_dst(Meta(*s++));
|
|
else
|
|
To_dst(*s++);
|
|
}
|
|
}
|
|
|
|
To_dst('\0');
|
|
|
|
return 1;
|
|
|
|
#undef To_dst
|
|
|
|
}
|
|
|
|
/* Convert an infokey file section to keymap bindings. Return false if
|
|
the default bindings are to be suppressed. */
|
|
static int
|
|
section_to_keymaps(Keymap map, unsigned char *table, unsigned int len)
|
|
{
|
|
int stop;
|
|
unsigned char *p;
|
|
unsigned char *seq = NULL;
|
|
unsigned int seqlen = 0;
|
|
enum { getseq, gotseq, getaction } state = getseq;
|
|
|
|
stop = len > 0 ? table[0] : 0;
|
|
|
|
for (p = table + 1; (unsigned int) (p - table) < len; p++)
|
|
{
|
|
switch (state)
|
|
{
|
|
case getseq:
|
|
if (*p)
|
|
{
|
|
seq = p;
|
|
state = gotseq;
|
|
}
|
|
break;
|
|
|
|
case gotseq:
|
|
if (!*p)
|
|
{
|
|
seqlen = p - seq;
|
|
state = getaction;
|
|
}
|
|
break;
|
|
|
|
case getaction:
|
|
{
|
|
unsigned int action = *p;
|
|
unsigned char keyseq[256];
|
|
KEYMAP_ENTRY ke;
|
|
|
|
state = getseq;
|
|
/* If decode_keys returns zero, it
|
|
means that seq includes keys which
|
|
the terminal doesn't support, like
|
|
PageDown. In that case, don't bind
|
|
the key sequence. */
|
|
if (decode_keys(seq, seqlen, keyseq,
|
|
sizeof keyseq))
|
|
{
|
|
keyseq[sizeof keyseq - 1] = '\0';
|
|
ke.type = ISFUNC;
|
|
ke.function =
|
|
action < A_NCOMMANDS
|
|
? &function_doc_array[action]
|
|
: NULL;
|
|
keymap_bind_keyseq(map,
|
|
(const char *) keyseq, &ke);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (state != getseq)
|
|
info_error((char *) _("Bad data in infokey file -- some key bindings ignored"),
|
|
NULL, NULL);
|
|
return !stop;
|
|
}
|
|
|
|
/* Convert an infokey file section to variable settings.
|
|
*/
|
|
static void
|
|
section_to_vars(unsigned char *table, unsigned int len)
|
|
{
|
|
enum { getvar, gotvar, getval, gotval } state = getvar;
|
|
unsigned char *var = NULL;
|
|
unsigned char *val = NULL;
|
|
unsigned char *p;
|
|
|
|
for (p = table; (unsigned int) (p - table) < len; p++)
|
|
{
|
|
switch (state)
|
|
{
|
|
case getvar:
|
|
if (*p)
|
|
{
|
|
var = p;
|
|
state = gotvar;
|
|
}
|
|
break;
|
|
|
|
case gotvar:
|
|
if (!*p)
|
|
state = getval;
|
|
break;
|
|
|
|
case getval:
|
|
if (*p)
|
|
{
|
|
val = p;
|
|
state = gotval;
|
|
}
|
|
break;
|
|
|
|
case gotval:
|
|
if (!*p)
|
|
{
|
|
set_variable_to_value((char *) var, (char *) val);
|
|
state = getvar;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (state != getvar)
|
|
info_error((char *) _("Bad data in infokey file -- some var settings ignored"),
|
|
NULL, NULL);
|
|
}
|
|
|
|
void
|
|
initialize_info_keymaps (void)
|
|
{
|
|
int i;
|
|
int suppress_info_default_bindings = 0;
|
|
int suppress_ea_default_bindings = 0;
|
|
|
|
if (!info_keymap)
|
|
{
|
|
info_keymap = keymap_make_keymap ();
|
|
echo_area_keymap = keymap_make_keymap ();
|
|
}
|
|
|
|
/* Bind the echo area insert routines. */
|
|
for (i = 0; i < 256; i++)
|
|
if (isprint (i))
|
|
echo_area_keymap[i].function = InfoCmd(ea_insert);
|
|
|
|
/* Get user-defined keys and variables. */
|
|
if (fetch_user_maps())
|
|
{
|
|
if (user_info_keys_len && user_info_keys[0])
|
|
suppress_info_default_bindings = 1;
|
|
if (user_ea_keys_len && user_ea_keys[0])
|
|
suppress_ea_default_bindings = 1;
|
|
}
|
|
|
|
/* Apply the default bindings, unless the user says to suppress
|
|
them. */
|
|
if (vi_keys_p)
|
|
{
|
|
if (!suppress_info_default_bindings)
|
|
section_to_keymaps(info_keymap, default_vi_like_info_keys,
|
|
sizeof(default_vi_like_info_keys));
|
|
if (!suppress_ea_default_bindings)
|
|
section_to_keymaps(echo_area_keymap, default_vi_like_ea_keys,
|
|
sizeof(default_vi_like_ea_keys));
|
|
}
|
|
else
|
|
{
|
|
if (!suppress_info_default_bindings)
|
|
section_to_keymaps(info_keymap, default_emacs_like_info_keys,
|
|
sizeof(default_emacs_like_info_keys));
|
|
if (!suppress_ea_default_bindings)
|
|
section_to_keymaps(echo_area_keymap, default_emacs_like_ea_keys,
|
|
sizeof(default_emacs_like_ea_keys));
|
|
}
|
|
|
|
/* If the user specified custom bindings, apply them on top of the
|
|
default ones. */
|
|
if (user_info_keys_len)
|
|
section_to_keymaps(info_keymap, user_info_keys, user_info_keys_len);
|
|
|
|
if (user_ea_keys_len)
|
|
section_to_keymaps(echo_area_keymap, user_ea_keys, user_ea_keys_len);
|
|
|
|
if (user_vars_len)
|
|
section_to_vars(user_vars, user_vars_len);
|
|
}
|
|
|
|
#endif /* defined(INFOKEY) */
|
|
/* vim: set sw=2 cino={1s>2sn-s^-se-s: */
|