/* infomap.c -- keymaps for Info. Copyright 1993-2023 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 . 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, KEY_BACK_TAB, NUL, A_info_move_to_prev_xref, }; 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: */