/* infomap.c -- keymaps for Info.
Copyright 1993-2019 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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
Originally written by Brian Fox. */
#include "info.h"
#include "doc.h"
#include "funs.h"
#include "session.h"
#include "terminal.h"
#include "variables.h"
void keymap_bind_keyseq (Keymap map, int *keyseq, KEYMAP_ENTRY *keyentry);
/* Return a new Keymap. */
Keymap
keymap_make_keymap (void)
{
int i;
Keymap keymap;
keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY));
for (i = 0; i < KEYMAP_SIZE; i++)
{
keymap[i].type = ISFUNC;
keymap[i].value.function = NULL;
}
return keymap;
}
/* Record KEYSEQ, a sequence of keys terminated by 0, in the linked list of
FUNCTION_KEYSEQ hanging off FUNCTION. Label it with ROOTMAP so we know
whether the key sequence is for main operation or for the echo area. */
static void
add_function_keyseq (InfoCommand *function, int *keyseq, Keymap rootmap)
{
FUNCTION_KEYSEQ *ks, *k;
int len;
if (function == NULL ||
function == InfoCmd (info_do_lowercase_version))
return;
/* If there is already a key sequence recorded for this key map,
don't do anything. */
for (k = function->keys; k; k = k->next)
if (k->map == rootmap)
return;
ks = xmalloc (sizeof (FUNCTION_KEYSEQ));
ks->next = function->keys;
ks->map = rootmap;
for (len = 0; keyseq[len]; len++);
ks->keyseq = xmalloc ((len + 1) * sizeof (int));
memcpy (ks->keyseq, keyseq, (len + 1) * sizeof (int));
function->keys = ks;
}
/* Bind key sequence. Don't override already bound key sequences. */
void
keymap_bind_keyseq (Keymap map, int *keyseq, KEYMAP_ENTRY *keyentry)
{
Keymap m = map;
int *s = keyseq;
int c;
if (!s || *s == 0)
return;
while ((c = *s++) != '\0')
{
switch (m[c].type)
{
case ISFUNC:
if (m[c].value.function)
return; /* There is a function here already. */
if (*s != '\0')
{
m[c].type = ISKMAP;
m[c].value.keymap = keymap_make_keymap ();
}
break;
case ISKMAP:
if (*s == '\0')
return; /* The key sequence we were asked to bind is an initial
subsequence of an already-bound sequence. */
break;
}
if (*s != '\0')
{
m = m[c].value.keymap;
}
else
{
add_function_keyseq (keyentry->value.function, keyseq, map);
m[c] = *keyentry;
}
}
return;
}
/* Initialize the standard info keymaps. */
Keymap info_keymap = NULL;
Keymap echo_area_keymap = NULL;
/* 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 int default_emacs_like_info_keys[] =
{
/* Favoured command bindings come first. We want help to
report q, not C-x C-c, etc. */
'H', NUL, A_info_get_help_window,
'q', NUL, A_info_quit,
KEY_UP_ARROW, NUL, A_info_prev_line,
KEY_DOWN_ARROW, NUL, A_info_next_line,
KEY_PAGE_UP, NUL, A_info_scroll_backward,
KEY_PAGE_DOWN, NUL, A_info_scroll_forward,
KEY_HOME, NUL, A_info_beginning_of_node,
KEY_END, NUL, A_info_end_of_node,
'{', NUL, A_info_search_previous,
'}', NUL, A_info_search_next,
CONTROL('g'), NUL, A_info_abort_key,
RET, NUL, A_info_select_reference_this_line,
TAB, NUL, A_info_move_to_next_xref,
LFD, NUL, A_info_select_reference_this_line,
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('h'), NUL, A_info_scroll_backward,
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,
SPC, NUL, A_info_scroll_forward,
',', 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_display_file_info,
'>', NUL, A_info_last_node,
'?', NUL, A_info_search_backward,
'[', 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,
'I', NUL, A_info_virtual_index,
'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,
'r', NUL, A_info_xref_item,
'R', NUL, A_info_toggle_regexp,
's', NUL, A_info_search,
'S', NUL, A_info_search_case_sensitively,
't', NUL, A_info_top_node,
'u', NUL, A_info_up_node,
'x', NUL, A_info_delete_window,
KEYMAP_META('0'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('1'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('2'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('3'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('4'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('5'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('6'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('7'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('8'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('9'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('-'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META(CONTROL('f')), NUL, A_info_show_footnotes,
KEYMAP_META(CONTROL('g')), NUL, A_info_abort_key,
KEYMAP_META(TAB), NUL, A_info_move_to_prev_xref,
KEYMAP_META(CONTROL('v')), NUL, A_info_scroll_other_window,
KEYMAP_META('<'), NUL, A_info_beginning_of_node,
KEYMAP_META('>'), NUL, A_info_end_of_node,
KEYMAP_META('b'), NUL, A_info_backward_word,
KEYMAP_META('f'), NUL, A_info_forward_word,
KEYMAP_META('r'), NUL, A_info_move_to_window_line,
KEYMAP_META('v'), NUL, A_info_scroll_backward_page_only,
KEYMAP_META('x'), NUL, A_info_execute_command,
KEYMAP_META('/'), NUL, A_info_tree_search,
KEYMAP_META('}'), NUL, A_info_tree_search_next,
KEYMAP_META('{'), NUL, A_info_tree_search_previous,
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'), 'f', NUL, A_info_all_files,
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,
KEY_RIGHT_ARROW, NUL, A_info_forward_char,
KEY_LEFT_ARROW, NUL, A_info_backward_char,
KEY_DELETE, NUL, A_info_scroll_backward,
ESC, KEY_PAGE_UP, NUL, A_info_scroll_other_window_backward,
ESC, KEY_PAGE_DOWN, NUL, A_info_scroll_other_window,
ESC, KEY_UP_ARROW, NUL, A_info_prev_line,
ESC, KEY_DOWN_ARROW, NUL, A_info_next_line,
ESC, KEY_RIGHT_ARROW, NUL, A_info_forward_word,
ESC, KEY_LEFT_ARROW, NUL, A_info_backward_word,
KEY_BACK_TAB, NUL, A_info_move_to_prev_xref,
};
static int default_emacs_like_ea_keys[] =
{
KEYMAP_META('0'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('1'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('2'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('3'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('4'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('5'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('6'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('7'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('8'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('9'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('-'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META(CONTROL('g')), NUL, A_ea_abort,
KEYMAP_META(CONTROL('v')), NUL, A_ea_scroll_completions_window,
KEYMAP_META('b'), NUL, A_ea_backward_word,
KEYMAP_META('d'), NUL, A_ea_kill_word,
KEYMAP_META('f'), NUL, A_ea_forward_word,
KEYMAP_META('y'), NUL, A_ea_yank_pop,
KEYMAP_META('?'), NUL, A_ea_possible_completions,
KEYMAP_META(TAB), NUL, A_ea_tab_insert,
KEYMAP_META(KEY_DELETE), 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,
ESC, NUL, A_ea_abort,
CONTROL('h'), NUL, A_ea_rubout,
CONTROL('k'), 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,
TAB, NUL, A_ea_complete,
#ifdef __MSDOS__
/* PC users will lynch me if I don't give them their usual DEL
effect... */
KEY_DELETE, NUL, A_ea_delete,
#else
KEY_DELETE, NUL, A_ea_rubout,
#endif
CONTROL('x'), KEY_DELETE, NUL, A_ea_backward_kill_line,
KEY_RIGHT_ARROW, NUL, A_ea_forward,
KEY_LEFT_ARROW, NUL, A_ea_backward,
KEY_HOME, NUL, A_ea_beg_of_line,
KEY_END, NUL, A_ea_end_of_line,
};
static int default_vi_like_info_keys[] =
{
/* We want help to report q, not C-x C-c, etc. */
'q', NUL, A_info_quit,
'x', NUL, A_info_delete_window,
SPC, NUL, A_info_scroll_forward,
'{', NUL, A_info_search_previous,
'}', NUL, A_info_search_next,
KEY_UP_ARROW, NUL, A_info_up_line,
KEY_DOWN_ARROW, NUL, A_info_down_line,
'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,
CONTROL('a'), NUL, A_info_beginning_of_line,
CONTROL('b'), NUL, A_info_scroll_backward_page_only,
CONTROL('c'), NUL, A_info_abort_key,
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_display_file_info,
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,
KEYMAP_META('0'), NUL, A_info_last_menu_item,
KEYMAP_META('1'), NUL, A_info_menu_digit,
KEYMAP_META('2'), NUL, A_info_menu_digit,
KEYMAP_META('3'), NUL, A_info_menu_digit,
KEYMAP_META('4'), NUL, A_info_menu_digit,
KEYMAP_META('5'), NUL, A_info_menu_digit,
KEYMAP_META('6'), NUL, A_info_menu_digit,
KEYMAP_META('7'), NUL, A_info_menu_digit,
KEYMAP_META('8'), NUL, A_info_menu_digit,
KEYMAP_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_page_only,
'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,
':', 'a', NUL, A_info_all_files,
'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,
'Z', 'Z', NUL, A_info_quit,
'r', NUL, A_info_redraw_display,
'R', NUL, A_info_toggle_regexp,
'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,
KEYMAP_META(CONTROL('f')), NUL, A_info_show_footnotes,
KEYMAP_META(CONTROL('g')), NUL, A_info_abort_key,
KEYMAP_META(TAB), NUL, A_info_move_to_prev_xref,
KEYMAP_META(SPC), NUL, A_info_scroll_forward_page_only,
KEYMAP_META(CONTROL('v')), NUL, A_info_scroll_other_window,
KEYMAP_META('<'), NUL, A_info_beginning_of_node,
KEYMAP_META('>'), NUL, A_info_end_of_node,
KEYMAP_META('/'), NUL, A_info_search,
KEYMAP_META('?'), NUL, A_info_search_backward,
KEYMAP_META('b'), NUL, A_info_beginning_of_node,
KEYMAP_META('d'), NUL, A_info_dir_node,
KEYMAP_META('e'), NUL, A_info_end_of_node,
KEYMAP_META('f'), NUL, A_info_xref_item,
KEYMAP_META('g'), NUL, A_info_select_reference_this_line,
KEYMAP_META('h'), NUL, A_info_get_info_help_node,
KEYMAP_META('I'), NUL, A_info_virtual_index,
KEYMAP_META('m'), NUL, A_info_menu_item,
KEYMAP_META('n'), NUL, A_info_search,
KEYMAP_META('N'), NUL, A_info_search_backward,
KEYMAP_META('r'), NUL, A_isearch_backward,
KEYMAP_META('s'), NUL, A_isearch_forward,
KEYMAP_META('t'), NUL, A_info_top_node,
KEYMAP_META('v'), NUL, A_info_scroll_backward_page_only,
KEYMAP_META('x'), NUL, A_info_execute_command,
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'), '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,
KEY_PAGE_UP, NUL, A_info_scroll_backward,
KEY_PAGE_DOWN, NUL, A_info_scroll_forward,
KEY_DELETE, NUL, A_info_scroll_backward,
KEY_RIGHT_ARROW, NUL, A_info_scroll_forward_page_only,
KEY_LEFT_ARROW, NUL, A_info_scroll_backward_page_only,
KEY_HOME, NUL, A_info_beginning_of_node,
KEY_END, NUL, A_info_end_of_node,
ESC, KEY_PAGE_DOWN, NUL, A_info_scroll_other_window,
ESC, KEY_PAGE_UP, NUL, A_info_scroll_other_window_backward,
ESC, KEY_DELETE, NUL, A_info_scroll_other_window_backward,
ESC, KEY_UP_ARROW, NUL, A_info_prev_node,
ESC, KEY_DOWN_ARROW, NUL, A_info_next_node,
ESC, KEY_RIGHT_ARROW, NUL, A_info_xref_item,
ESC, KEY_LEFT_ARROW, NUL, A_info_beginning_of_node,
CONTROL('x'), KEY_DELETE, NUL, A_ea_backward_kill_line,
};
static int default_vi_like_ea_keys[] =
{
KEYMAP_META('1'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('2'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('3'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('4'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('5'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('6'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('7'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('8'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('9'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META('-'), NUL, A_info_add_digit_to_numeric_arg,
KEYMAP_META(CONTROL('g')), NUL, A_ea_abort,
KEYMAP_META(CONTROL('h')), NUL, A_ea_backward_kill_word,
KEYMAP_META(CONTROL('v')), NUL, A_ea_scroll_completions_window,
KEYMAP_META('0'), NUL, A_ea_beg_of_line,
KEYMAP_META('$'), NUL, A_ea_end_of_line,
KEYMAP_META('b'), NUL, A_ea_backward_word,
KEYMAP_META('d'), NUL, A_ea_kill_word,
KEYMAP_META('f'), NUL, A_ea_forward_word,
KEYMAP_META('h'), NUL, A_ea_backward,
KEYMAP_META('l'), NUL, A_ea_forward,
KEYMAP_META('w'), NUL, A_ea_forward_word,
KEYMAP_META('x'), NUL, A_ea_delete,
KEYMAP_META('X'), NUL, A_ea_kill_word,
KEYMAP_META('y'), NUL, A_ea_yank_pop,
KEYMAP_META('?'), NUL, A_ea_possible_completions,
KEYMAP_META(TAB), NUL, A_ea_tab_insert,
KEYMAP_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,
ESC, NUL, A_ea_abort,
CONTROL('h'), NUL, A_ea_rubout,
CONTROL('k'), 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,
TAB, NUL, A_ea_complete,
KEY_RIGHT_ARROW, NUL, A_ea_forward,
KEY_LEFT_ARROW, NUL, A_ea_backward,
KEY_HOME, NUL, A_ea_beg_of_line,
KEY_END, NUL, A_ea_end_of_line,
#ifdef __MSDOS__
KEY_DELETE, NUL, A_ea_delete,
#else
KEY_DELETE, NUL, A_ea_rubout,
#endif
CONTROL('x'), KEY_DELETE, NUL,A_ea_backward_kill_line,
};
/* Whether to suppress the default key bindings. */
static int sup_info, sup_ea;
/* Fetch the contents of the init file at INIT_FILE, or the standard
infokey file "$HOME/.infokey". Return non-zero if an init file was
loaded and read. */
static int
fetch_user_maps (char *init_file)
{
char *filename = NULL;
char *homedir;
FILE *inf;
/* In infokey.c */
int compile (FILE *fp, const char *filename, int *, int *);
/* Find and open file. */
if (init_file)
filename = xstrdup (init_file);
else if ((homedir = getenv ("HOME")) != NULL
#ifdef __MINGW32__
|| (homedir = getenv ("USERPROFILE")) != NULL
#endif
)
{
filename = xmalloc (strlen (homedir) + 2 + strlen (INFOKEY_FILE));
strcpy (filename, homedir);
strcat (filename, "/");
strcat (filename, INFOKEY_FILE);
}
#if defined(__MSDOS__) || defined(__MINGW32__)
/* Poor baby, she doesn't have a HOME... */
else
filename = xstrdup (INFOKEY_FILE); /* try current directory */
#endif
inf = fopen (filename, "r");
if (!inf)
{
free (filename);
if (init_file)
info_error (_("could not open init file %s"), init_file);
return 0;
}
compile (inf, filename, &sup_info, &sup_ea);
free (filename);
return 1;
}
/* Set key bindings in MAP from TABLE, which is of length LEN. */
static void
section_to_keymaps (Keymap map, int *table, unsigned int len)
{
int k;
Keymap esc_map;
int *p;
int *seq;
enum { getseq, gotseq, getaction } state = getseq;
for (p = table; (unsigned int) (p - table) < len; p++)
{
switch (state)
{
case getseq:
if (*p)
{
seq = p;
state = gotseq;
}
break;
case gotseq:
if (!*p)
state = getaction;
break;
case getaction:
{
unsigned int action = *p;
KEYMAP_ENTRY ke;
state = getseq;
ke.type = ISFUNC;
ke.value.function = action < A_NCOMMANDS ?
&function_doc_array[action]
: NULL;
keymap_bind_keyseq (map, seq, &ke);
}
break;
}
}
if (state != getseq)
abort ();
/* Go through map and bind ESC x to the same function as M-x if it is not
bound already. */
if (!map[ESC].value.function)
{
map[ESC].type = ISKMAP;
map[ESC].value.keymap = keymap_make_keymap ();
}
if (map[ESC].type != ISKMAP)
return; /* ESC is bound to a command. */
esc_map = map[ESC].value.keymap;
for (k = 1; k < KEYMAP_META_BASE; k++)
{
if (map[k + KEYMAP_META_BASE].type == ISFUNC
&& esc_map[k].value.function == 0)
{
esc_map[k].type = ISFUNC;
esc_map[k].value.function = map[k + KEYMAP_META_BASE].value.function;
}
}
return;
}
/* Read key bindings and variable settings from INIT_FILE. If INIT_FILE
is null, look for the init file in the default location. */
void
read_init_file (char *init_file)
{
int *info_keys, *ea_keys; /* Pointers to keymap tables. */
long info_keys_len, ea_keys_len; /* Sizes of keymap tables. */
int i;
if (!info_keymap)
{
info_keymap = keymap_make_keymap ();
echo_area_keymap = keymap_make_keymap ();
}
if (!vi_keys_p)
{
info_keys = default_emacs_like_info_keys;
info_keys_len = sizeof (default_emacs_like_info_keys)/sizeof (int);
ea_keys = default_emacs_like_ea_keys;
ea_keys_len = sizeof (default_emacs_like_ea_keys)/sizeof (int);
}
else
{
info_keys = default_vi_like_info_keys;
info_keys_len = sizeof (default_vi_like_info_keys)/sizeof(int);
ea_keys = default_vi_like_ea_keys;
ea_keys_len = sizeof (default_vi_like_ea_keys)/sizeof(int);
}
/* Get user-defined keys and variables. */
if (fetch_user_maps (init_file))
{
if (sup_info)
info_keys = 0; /* Suppress default bindings. */
if (sup_ea)
ea_keys = 0;
}
/* Apply the default bindings, unless the user says to suppress
them. */
if (info_keys)
section_to_keymaps (info_keymap, info_keys, info_keys_len);
if (ea_keys)
section_to_keymaps (echo_area_keymap, ea_keys, ea_keys_len);
for (i = 'A'; i < ('Z' + 1); i++)
{
if (!info_keymap[i].value.function)
{
info_keymap[i].type = ISFUNC;
info_keymap[i].value.function = InfoCmd (info_do_lowercase_version);
}
if (!info_keymap[KEYMAP_META(i)].value.function)
{
info_keymap[KEYMAP_META(i)].type = ISFUNC;
info_keymap[KEYMAP_META(i)].value.function
= InfoCmd (info_do_lowercase_version);
}
}
}
/* vim: set sw=2 cino={1s>2sn-s^-se-s: */