1 /* infomap.c -- keymaps for Info.
2 $Id: infomap.c,v 1.21 2008/06/11 09:55:42 gray Exp $
4 Copyright (C) 1993, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2007, 2008
5 Free Software Foundation, Inc.
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 Written by Brian Fox (bfox@ai.mit.edu). */
29 #include "variables.h"
32 static int keymap_bind_keyseq (Keymap map, const char *keyseq,
33 KEYMAP_ENTRY *keyentry);
35 /* Return a new keymap which has all the uppercase letters mapped to run
36 the function info_do_lowercase_version (). */
38 keymap_make_keymap (void)
43 keymap = (Keymap)xmalloc (256 * sizeof (KEYMAP_ENTRY));
45 for (i = 0; i < 256; i++)
47 keymap[i].type = ISFUNC;
48 keymap[i].function = NULL;
51 for (i = 'A'; i < ('Z' + 1); i++)
53 keymap[i].type = ISFUNC;
55 keymap[Meta(i)].type = ISFUNC;
56 keymap[Meta(i)].function =
58 keymap[i].function = InfoCmd(info_do_lowercase_version);
65 static FUNCTION_KEYSEQ *
66 find_function_keyseq (Keymap map, int c, Keymap rootmap)
70 if (map[c].type != ISFUNC)
72 if (map[c].function == NULL)
74 for (k = map[c].function->keys; k; k = k->next)
76 const unsigned char *p;
78 if (k->map != rootmap)
80 for (p = (unsigned char *) k->keyseq; *p && m[*p].type == ISKMAP; p++)
81 m = (Keymap)m[*p].function;
84 if (m[*p].type != ISFUNC)
92 add_function_keyseq (InfoCommand *function,
93 const char *keyseq, Keymap rootmap)
97 if (function == NULL ||
98 function == InfoCmd(info_do_lowercase_version) ||
99 function == InfoCmd(ea_insert))
101 ks = xmalloc (sizeof(FUNCTION_KEYSEQ));
102 ks->next = function->keys;
104 ks->keyseq = xstrdup(keyseq);
109 remove_function_keyseq (InfoCommand *function,
110 const char *keyseq, Keymap rootmap)
113 FUNCTION_KEYSEQ *k, *kp;
115 if (function == NULL ||
116 function == InfoCmd(info_do_lowercase_version) ||
117 function == InfoCmd(ea_insert))
119 for (kp = NULL, k = function->keys; k; kp = k, k = k->next)
120 if (k->map == rootmap && strcmp(k->keyseq, keyseq) == 0)
127 function->keys = k->next;
131 /* Return a new keymap which is a copy of MAP. */
133 keymap_copy_keymap (Keymap map, Keymap rootmap, Keymap newroot)
141 keymap = keymap_make_keymap ();
145 for (i = 0; i < 256; i++)
147 keymap[i].type = map[i].type;
151 keymap[i].function = map[i].function;
153 ks = find_function_keyseq (map, i, rootmap);
155 add_function_keyseq(map[i].function, ks->keyseq, newroot);
159 keymap[i].function = (InfoCommand *)keymap_copy_keymap
160 ((Keymap)map[i].function, rootmap, NULL);
167 /* Free the keymap and its descendants. */
169 keymap_discard_keymap (Keymap map, Keymap rootmap)
178 for (i = 0; i < 256; i++)
187 ks = find_function_keyseq(map, i, rootmap);
189 remove_function_keyseq (map[i].function, ks->keyseq, rootmap);
194 keymap_discard_keymap ((Keymap)map[i].function, rootmap);
202 /* Conditionally bind key sequence. */
204 keymap_bind_keyseq (Keymap map,
205 const char *keyseq, KEYMAP_ENTRY *keyentry)
208 const unsigned char *s = (unsigned char *) keyseq;
211 if (s == NULL || *s == '\0') return 0;
213 while ((c = *s++) != '\0')
222 ks = find_function_keyseq(m, c, map);
224 remove_function_keyseq (m[c].function, ks->keyseq, map);
226 if (!(m[c].function == NULL || (
228 m[c].function == InfoCmd(info_do_lowercase_version))
231 #endif /* !INFOKEY */
236 /* Here we are casting the Keymap pointer returned from
237 keymap_make_keymap to an InfoCommand pointer. Ugh.
238 This makes the `function' structure garbage
239 if it's actually interpreted as an InfoCommand.
240 Should really be using a union, and taking steps to
241 avoid the possible error. */
242 m[c].function = (InfoCommand *)keymap_make_keymap ();
249 keymap_discard_keymap ((Keymap)m[c].function, map);
258 m = (Keymap)m[c].function;
263 add_function_keyseq (keyentry->function, keyseq, map);
273 /* Initialize the standard info keymaps. */
275 Keymap info_keymap = NULL;
276 Keymap echo_area_keymap = NULL;
278 /* Make sure that we don't have too many command codes defined. */
280 #if A_NCOMMANDS > A_MAX_COMMAND + 1
281 #error "too many commands defined"
284 /* Initialize the keymaps from the .info keymap file. */
288 static unsigned char default_emacs_like_info_keys[] =
290 0, /* suppress-default-keybindings flag */
291 TAB, NUL, A_info_move_to_next_xref,
292 LFD, NUL, A_info_select_reference_this_line,
293 RET, NUL, A_info_select_reference_this_line,
294 CONTROL('a'), NUL, A_info_beginning_of_line,
295 CONTROL('b'), NUL, A_info_backward_char,
296 CONTROL('e'), NUL, A_info_end_of_line,
297 CONTROL('f'), NUL, A_info_forward_char,
298 CONTROL('h'), NUL, A_info_get_help_window,
299 CONTROL('l'), NUL, A_info_redraw_display,
300 CONTROL('n'), NUL, A_info_next_line,
301 CONTROL('p'), NUL, A_info_prev_line,
302 CONTROL('r'), NUL, A_isearch_backward,
303 CONTROL('s'), NUL, A_isearch_forward,
304 CONTROL('u'), NUL, A_info_universal_argument,
305 CONTROL('v'), NUL, A_info_scroll_forward_page_only,
306 ',', NUL, A_info_next_index_match,
307 '/', NUL, A_info_search,
308 '0', NUL, A_info_last_menu_item,
309 '1', NUL, A_info_menu_digit,
310 '2', NUL, A_info_menu_digit,
311 '3', NUL, A_info_menu_digit,
312 '4', NUL, A_info_menu_digit,
313 '5', NUL, A_info_menu_digit,
314 '6', NUL, A_info_menu_digit,
315 '7', NUL, A_info_menu_digit,
316 '8', NUL, A_info_menu_digit,
317 '9', NUL, A_info_menu_digit,
318 '<', NUL, A_info_first_node,
319 '>', NUL, A_info_last_node,
320 '?', NUL, A_info_get_help_window,
321 '[', NUL, A_info_global_prev_node,
322 ']', NUL, A_info_global_next_node,
323 'b', NUL, A_info_beginning_of_node,
324 'd', NUL, A_info_dir_node,
325 'e', NUL, A_info_end_of_node,
326 'f', NUL, A_info_xref_item,
327 'g', NUL, A_info_goto_node,
328 'G', NUL, A_info_menu_sequence,
329 'h', NUL, A_info_get_help_window,
330 'H', NUL, A_info_get_info_help_node,
331 'i', NUL, A_info_index_search,
332 'l', NUL, A_info_history_node,
333 'm', NUL, A_info_menu_item,
334 'n', NUL, A_info_next_node,
335 'O', NUL, A_info_goto_invocation_node,
336 'p', NUL, A_info_prev_node,
337 'r', NUL, A_info_xref_item,
338 'R', NUL, A_info_toggle_regexp,
339 's', NUL, A_info_search,
340 'S', NUL, A_info_search_case_sensitively,
341 't', NUL, A_info_top_node,
342 'u', NUL, A_info_up_node,
343 ESC, '0', NUL, A_info_add_digit_to_numeric_arg,
344 ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
345 ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
346 ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
347 ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
348 ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
349 ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
350 ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
351 ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
352 ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
353 ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
354 ESC, CONTROL('f'), NUL, A_info_show_footnotes,
355 ESC, CONTROL('g'), NUL, A_info_abort_key,
356 ESC, TAB, NUL, A_info_move_to_prev_xref,
357 ESC, CONTROL('v'), NUL, A_info_scroll_other_window,
358 ESC, '<', NUL, A_info_beginning_of_node,
359 ESC, '>', NUL, A_info_end_of_node,
360 ESC, 'b', NUL, A_info_backward_word,
361 ESC, 'f', NUL, A_info_forward_word,
362 ESC, 'r', NUL, A_info_move_to_window_line,
363 ESC, 'v', NUL, A_info_scroll_backward_page_only,
364 Meta('0'), NUL, A_info_add_digit_to_numeric_arg,
365 Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
366 Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
367 Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
368 Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
369 Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
370 Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
371 Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
372 Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
373 Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
374 Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
375 Meta(CONTROL('f')), NUL, A_info_show_footnotes,
376 Meta(CONTROL('g')), NUL, A_info_abort_key,
377 Meta(TAB), NUL, A_info_move_to_prev_xref,
378 Meta(CONTROL('v')), NUL, A_info_scroll_other_window,
379 Meta('<'), NUL, A_info_beginning_of_node,
380 Meta('>'), NUL, A_info_end_of_node,
381 Meta('b'), NUL, A_info_backward_word,
382 Meta('f'), NUL, A_info_forward_word,
383 Meta('r'), NUL, A_info_move_to_window_line,
384 Meta('v'), NUL, A_info_scroll_backward_page_only,
385 #if defined (NAMED_FUNCTIONS)
386 ESC, 'x', NUL, A_info_execute_command,
387 Meta('x'), NUL, A_info_execute_command,
388 #endif /* NAMED_FUNCTIONS */
390 CONTROL('x'), CONTROL('b'), NUL, A_list_visited_nodes,
391 CONTROL('x'), CONTROL('c'), NUL, A_info_quit,
392 CONTROL('x'), CONTROL('f'), NUL, A_info_view_file,
393 CONTROL('x'), CONTROL('g'), NUL, A_info_abort_key,
394 CONTROL('x'), CONTROL('v'), NUL, A_info_view_file,
395 CONTROL('x'), '0', NUL, A_info_delete_window,
396 CONTROL('x'), '1', NUL, A_info_keep_one_window,
397 CONTROL('x'), '2', NUL, A_info_split_window,
398 CONTROL('x'), '^', NUL, A_info_grow_window,
399 CONTROL('x'), 'b', NUL, A_select_visited_node,
400 CONTROL('x'), 'k', NUL, A_info_kill_node,
401 CONTROL('x'), 'n', NUL, A_info_search_next,
402 CONTROL('x'), 'N', NUL, A_info_search_previous,
403 CONTROL('x'), 'o', NUL, A_info_next_window,
404 CONTROL('x'), 't', NUL, A_info_tile_windows,
405 CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
407 /* Arrow key bindings for info keymaps. It seems that some
408 terminals do not match their termcap entries, so it's best to just
409 define everything with both of the usual prefixes. */
411 SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_backward,
412 SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_forward,
413 '\033', 'O', 'A', NUL, A_info_prev_line,
414 '\033', '[', 'A', NUL, A_info_prev_line,
415 '\033', 'O', 'B', NUL, A_info_next_line,
416 '\033', '[', 'B', NUL, A_info_next_line,
417 SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_forward_char,
418 '\033', 'O', 'C', NUL, A_info_forward_char,
419 '\033', '[', 'C', NUL, A_info_forward_char,
420 SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_backward_char,
421 '\033', 'O', 'D', NUL, A_info_backward_char,
422 '\033', '[', 'D', NUL, A_info_backward_char,
423 SK_ESCAPE, SK_HOME, NUL, A_info_beginning_of_node,
424 SK_ESCAPE, SK_END, NUL, A_info_end_of_node,
425 SK_ESCAPE, SK_DELETE, NUL, A_info_scroll_backward,
427 ESC, SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_other_window_backward,
428 ESC, SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_other_window,
429 ESC, SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_line,
430 ESC, '\033', 'O', 'A', NUL, A_info_prev_line,
431 ESC, '\033', '[', 'A', NUL, A_info_prev_line,
432 ESC, SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_line,
433 ESC, '\033', 'O', 'B', NUL, A_info_next_line,
434 ESC, '\033', '[', 'B', NUL, A_info_next_line,
435 ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_forward_word,
436 ESC, '\033', 'O', 'C', NUL, A_info_forward_word,
437 ESC, '\033', '[', 'C', NUL, A_info_forward_word,
438 ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_backward_word,
439 ESC, '\033', 'O', 'D', NUL, A_info_backward_word,
440 ESC, '\033', '[', 'D', NUL, A_info_backward_word,
442 /* We want help to report q, not C-x C-c, etc. */
443 'q', NUL, A_info_quit,
444 'x', NUL, A_info_delete_window,
445 SPC, NUL, A_info_scroll_forward,
446 DEL, NUL, A_info_scroll_backward,
447 '{', NUL, A_info_search_previous,
448 '}', NUL, A_info_search_next,
449 CONTROL('g'), NUL, A_info_abort_key,
450 SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_line,
451 SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_line,
455 static unsigned char default_emacs_like_ea_keys[] =
457 0, /* suppress-default-keybindings flag */
458 ESC, '0', NUL, A_info_add_digit_to_numeric_arg,
459 ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
460 ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
461 ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
462 ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
463 ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
464 ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
465 ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
466 ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
467 ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
468 ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
469 Meta('0'), NUL, A_info_add_digit_to_numeric_arg,
470 Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
471 Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
472 Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
473 Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
474 Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
475 Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
476 Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
477 Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
478 Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
479 Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
480 ESC, CONTROL('g'), NUL, A_ea_abort,
481 ESC, CONTROL('v'), NUL, A_ea_scroll_completions_window,
482 ESC, 'b', NUL, A_ea_backward_word,
483 ESC, 'd', NUL, A_ea_kill_word,
484 ESC, 'f', NUL, A_ea_forward_word,
485 ESC, 'y', NUL, A_ea_yank_pop,
486 ESC, '?', NUL, A_ea_possible_completions,
487 ESC, TAB, NUL, A_ea_tab_insert,
488 ESC, DEL, NUL, A_ea_backward_kill_word,
489 Meta(CONTROL('g')), NUL, A_ea_abort,
490 Meta(CONTROL('v')), NUL, A_ea_scroll_completions_window,
491 Meta('b'), NUL, A_ea_backward_word,
492 Meta('d'), NUL, A_ea_kill_word,
493 Meta('f'), NUL, A_ea_forward_word,
494 Meta('y'), NUL, A_ea_yank_pop,
495 Meta('?'), NUL, A_ea_possible_completions,
496 Meta(TAB), NUL, A_ea_tab_insert,
497 Meta(DEL), NUL, A_ea_backward_kill_word,
498 CONTROL('a'), NUL, A_ea_beg_of_line,
499 CONTROL('b'), NUL, A_ea_backward,
500 CONTROL('d'), NUL, A_ea_delete,
501 CONTROL('e'), NUL, A_ea_end_of_line,
502 CONTROL('f'), NUL, A_ea_forward,
503 CONTROL('g'), NUL, A_ea_abort,
504 CONTROL('h'), NUL, A_ea_rubout,
506 SK_ESCAPE, SK_LITERAL, NUL, A_ea_kill_line,
507 CONTROL('l'), NUL, A_info_redraw_display,
508 CONTROL('q'), NUL, A_ea_quoted_insert,
509 CONTROL('t'), NUL, A_ea_transpose_chars,
510 CONTROL('u'), NUL, A_info_universal_argument,
511 CONTROL('y'), NUL, A_ea_yank,
512 LFD, NUL, A_ea_newline,
513 RET, NUL, A_ea_newline,
514 SPC, NUL, A_ea_complete,
515 TAB, NUL, A_ea_complete,
516 '?', NUL, A_ea_possible_completions,
518 /* PC users will lynch me if I don't give them their usual DEL
520 DEL, NUL, A_ea_delete,
522 DEL, NUL, A_ea_rubout,
524 #if defined (NAMED_FUNCTIONS)
525 /* ESC, 'x', NUL, A_info_execute_command, */
526 /* Meta('x'), NUL, A_info_execute_command, */
527 #endif /* NAMED_FUNCTIONS */
528 CONTROL('x'), 'o', NUL, A_info_next_window,
529 CONTROL('x'), DEL, NUL, A_ea_backward_kill_line,
531 /* Arrow key bindings for echo area keymaps. It seems that some
532 terminals do not match their termcap entries, so it's best to just
533 define everything with both of the usual prefixes. */
535 SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward,
536 '\033', 'O', 'C', NUL, A_ea_forward,
537 '\033', '[', 'C', NUL, A_ea_forward,
538 SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward,
539 '\033', 'O', 'D', NUL, A_ea_backward,
540 '\033', '[', 'D', NUL, A_ea_backward,
541 ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward_word,
542 ESC, '\033', 'O', 'C', NUL, A_ea_forward_word,
543 ESC, '\033', '[', 'C', NUL, A_ea_forward_word,
544 ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward_word,
545 ESC, '\033', 'O', 'D', NUL, A_ea_backward_word,
546 ESC, '\033', '[', 'D', NUL, A_ea_backward_word,
548 SK_ESCAPE, SK_DELETE, NUL, A_ea_delete,
550 SK_ESCAPE, SK_DELETE, NUL, A_ea_rubout,
552 SK_ESCAPE, SK_HOME, NUL, A_ea_beg_of_line,
553 SK_ESCAPE, SK_END, NUL, A_ea_end_of_line,
554 ESC, SK_ESCAPE, SK_DELETE, NUL, A_ea_backward_kill_word,
555 CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
559 static unsigned char default_vi_like_info_keys[] =
561 0, /* suppress-default-keybindings flag */
562 '0', NUL, A_info_add_digit_to_numeric_arg,
563 '1', NUL, A_info_add_digit_to_numeric_arg,
564 '2', NUL, A_info_add_digit_to_numeric_arg,
565 '3', NUL, A_info_add_digit_to_numeric_arg,
566 '4', NUL, A_info_add_digit_to_numeric_arg,
567 '5', NUL, A_info_add_digit_to_numeric_arg,
568 '6', NUL, A_info_add_digit_to_numeric_arg,
569 '7', NUL, A_info_add_digit_to_numeric_arg,
570 '8', NUL, A_info_add_digit_to_numeric_arg,
571 '9', NUL, A_info_add_digit_to_numeric_arg,
572 '-', NUL, A_info_add_digit_to_numeric_arg,
573 TAB, NUL, A_info_move_to_next_xref,
574 LFD, NUL, A_info_down_line,
575 RET, NUL, A_info_down_line,
576 CONTROL('a'), NUL, A_info_beginning_of_line,
577 CONTROL('b'), NUL, A_info_scroll_backward_page_only,
578 CONTROL('d'), NUL, A_info_scroll_half_screen_down,
579 CONTROL('e'), NUL, A_info_down_line,
580 CONTROL('f'), NUL, A_info_scroll_forward_page_only,
581 CONTROL('k'), NUL, A_info_up_line,
582 CONTROL('l'), NUL, A_info_redraw_display,
583 CONTROL('n'), NUL, A_info_down_line,
584 CONTROL('p'), NUL, A_info_up_line,
585 CONTROL('r'), NUL, A_info_redraw_display,
586 CONTROL('s'), NUL, A_isearch_forward,
587 CONTROL('u'), NUL, A_info_scroll_half_screen_up,
588 CONTROL('v'), NUL, A_info_scroll_forward_page_only,
589 CONTROL('y'), NUL, A_info_up_line,
590 ',', NUL, A_info_next_index_match,
591 '/', NUL, A_info_search,
592 ESC, '0', NUL, A_info_last_menu_item,
593 ESC, '1', NUL, A_info_menu_digit,
594 ESC, '2', NUL, A_info_menu_digit,
595 ESC, '3', NUL, A_info_menu_digit,
596 ESC, '4', NUL, A_info_menu_digit,
597 ESC, '5', NUL, A_info_menu_digit,
598 ESC, '6', NUL, A_info_menu_digit,
599 ESC, '7', NUL, A_info_menu_digit,
600 ESC, '8', NUL, A_info_menu_digit,
601 ESC, '9', NUL, A_info_menu_digit,
602 Meta('0'), NUL, A_info_last_menu_item,
603 Meta('1'), NUL, A_info_menu_digit,
604 Meta('2'), NUL, A_info_menu_digit,
605 Meta('3'), NUL, A_info_menu_digit,
606 Meta('4'), NUL, A_info_menu_digit,
607 Meta('5'), NUL, A_info_menu_digit,
608 Meta('6'), NUL, A_info_menu_digit,
609 Meta('7'), NUL, A_info_menu_digit,
610 Meta('8'), NUL, A_info_menu_digit,
611 Meta('9'), NUL, A_info_menu_digit,
612 '<', NUL, A_info_first_node,
613 '>', NUL, A_info_last_node,
614 '?', NUL, A_info_search_backward,
615 '[', NUL, A_info_global_prev_node,
616 ']', NUL, A_info_global_next_node,
617 '\'', NUL, A_info_history_node,
618 'b', NUL, A_info_scroll_backward,
619 'd', NUL, A_info_scroll_half_screen_down,
620 'e', NUL, A_info_down_line,
621 'E', NUL, A_info_view_file,
622 ':', 'e', NUL, A_info_view_file,
623 'f', NUL, A_info_scroll_forward_page_only,
624 'F', NUL, A_info_scroll_forward_page_only,
625 'g', NUL, A_info_first_node,
626 'G', NUL, A_info_last_node,
627 'h', NUL, A_info_get_help_window,
628 'H', NUL, A_info_get_help_window,
629 'i', NUL, A_info_index_search,
630 'I', NUL, A_info_goto_invocation_node,
631 'j', NUL, A_info_next_line,
632 'k', NUL, A_info_prev_line,
633 'l', NUL, A_info_history_node,
634 'm', NUL, A_info_menu_item,
635 'n', NUL, A_info_search_next,
636 'N', NUL, A_info_search_previous,
637 'O', NUL, A_info_goto_invocation_node,
638 'p', NUL, A_info_prev_node,
639 'Q', NUL, A_info_quit,
640 ':', 'q', NUL, A_info_quit,
641 ':', 'Q', NUL, A_info_quit,
642 'Z', 'Z', NUL, A_info_quit,
643 'r', NUL, A_info_redraw_display,
644 'R', NUL, A_info_toggle_regexp,
645 's', NUL, A_info_search,
646 'S', NUL, A_info_search_case_sensitively,
647 't', NUL, A_info_top_node,
648 'u', NUL, A_info_scroll_half_screen_up,
649 'w', NUL, A_info_scroll_backward_page_only_set_window,
650 'y', NUL, A_info_up_line,
651 'z', NUL, A_info_scroll_forward_page_only_set_window,
652 ESC, CONTROL('f'), NUL, A_info_show_footnotes,
653 ESC, CONTROL('g'), NUL, A_info_abort_key,
654 ESC, TAB, NUL, A_info_move_to_prev_xref,
655 ESC, SPC, NUL, A_info_scroll_forward_page_only,
656 ESC, CONTROL('v'), NUL, A_info_scroll_other_window,
657 ESC, '<', NUL, A_info_beginning_of_node,
658 ESC, '>', NUL, A_info_end_of_node,
659 ESC, '/', NUL, A_info_search,
660 ESC, '?', NUL, A_info_search_backward,
661 ESC, 'b', NUL, A_info_beginning_of_node,
662 ESC, 'd', NUL, A_info_dir_node,
663 ESC, 'e', NUL, A_info_end_of_node,
664 ESC, 'f', NUL, A_info_xref_item,
665 ESC, 'g', NUL, A_info_select_reference_this_line,
666 ESC, 'h', NUL, A_info_get_info_help_node,
667 ESC, 'm', NUL, A_info_menu_item,
668 ESC, 'n', NUL, A_info_search,
669 ESC, 'N', NUL, A_info_search_backward,
670 ESC, 'r', NUL, A_isearch_backward,
671 ESC, 's', NUL, A_isearch_forward,
672 ESC, 't', NUL, A_info_top_node,
673 ESC, 'v', NUL, A_info_scroll_backward_page_only,
674 #if defined (NAMED_FUNCTIONS)
675 ESC, 'x', NUL, A_info_execute_command,
676 Meta('x'), NUL, A_info_execute_command,
677 #endif /* NAMED_FUNCTIONS */
678 ESC, DEL, NUL, A_info_scroll_other_window_backward,
679 CONTROL('x'), CONTROL('b'), NUL, A_list_visited_nodes,
680 CONTROL('x'), CONTROL('c'), NUL, A_info_quit,
681 CONTROL('x'), CONTROL('f'), NUL, A_info_view_file,
682 CONTROL('x'), CONTROL('g'), NUL, A_info_abort_key,
683 CONTROL('x'), CONTROL('v'), NUL, A_info_view_file,
684 CONTROL('x'), LFD, NUL, A_info_select_reference_this_line,
685 CONTROL('x'), RET, NUL, A_info_select_reference_this_line,
686 CONTROL('x'), '0', NUL, A_info_delete_window,
687 CONTROL('x'), '1', NUL, A_info_keep_one_window,
688 CONTROL('x'), '2', NUL, A_info_split_window,
689 CONTROL('x'), '^', NUL, A_info_grow_window,
690 CONTROL('x'), 'b', NUL, A_select_visited_node,
691 CONTROL('x'), 'g', NUL, A_info_goto_node,
692 CONTROL('x'), 'i', NUL, A_info_index_search,
693 CONTROL('x'), 'I', NUL, A_info_goto_invocation_node,
694 CONTROL('x'), 'k', NUL, A_info_kill_node,
695 CONTROL('x'), 'n', NUL, A_info_next_node,
696 CONTROL('x'), 'o', NUL, A_info_next_window,
697 CONTROL('x'), 'O', NUL, A_info_goto_invocation_node,
698 CONTROL('x'), 'p', NUL, A_info_prev_node,
699 CONTROL('x'), 'r', NUL, A_info_xref_item,
700 CONTROL('x'), 't', NUL, A_info_tile_windows,
701 CONTROL('x'), 'u', NUL, A_info_up_node,
702 CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
703 CONTROL('x'), ',', NUL, A_info_next_index_match,
705 /* Arrow key bindings for info keymaps. It seems that some
706 terminals do not match their termcap entries, so it's best to just
707 define everything with both of the usual prefixes. */
709 SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_backward,
710 SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_forward,
711 '\033', 'O', 'A', NUL, A_info_up_line,
712 '\033', '[', 'A', NUL, A_info_up_line,
713 '\033', 'O', 'B', NUL, A_info_down_line,
714 '\033', '[', 'B', NUL, A_info_down_line,
715 SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_scroll_forward_page_only,
716 '\033', 'O', 'C', NUL, A_info_scroll_forward_page_only,
717 '\033', '[', 'C', NUL, A_info_scroll_forward_page_only,
718 SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_scroll_backward_page_only,
719 '\033', 'O', 'D', NUL, A_info_scroll_backward_page_only,
720 '\033', '[', 'D', NUL, A_info_scroll_backward_page_only,
721 SK_ESCAPE, SK_HOME, NUL, A_info_beginning_of_node,
722 SK_ESCAPE, SK_END, NUL, A_info_end_of_node,
723 ESC, SK_ESCAPE, SK_PAGE_DOWN, NUL, A_info_scroll_other_window,
724 ESC, SK_ESCAPE, SK_PAGE_UP, NUL, A_info_scroll_other_window_backward,
725 ESC, SK_ESCAPE, SK_DELETE, NUL, A_info_scroll_other_window_backward,
726 ESC, SK_ESCAPE, SK_UP_ARROW, NUL, A_info_prev_node,
727 ESC, '\033', 'O', 'A', NUL, A_info_prev_node,
728 ESC, '\033', '[', 'A', NUL, A_info_prev_node,
729 ESC, SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_next_node,
730 ESC, '\033', 'O', 'B', NUL, A_info_next_node,
731 ESC, '\033', '[', 'B', NUL, A_info_next_node,
732 ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_info_xref_item,
733 ESC, '\033', 'O', 'C', NUL, A_info_xref_item,
734 ESC, '\033', '[', 'C', NUL, A_info_xref_item,
735 ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_info_beginning_of_node,
736 ESC, '\033', 'O', 'D', NUL, A_info_beginning_of_node,
737 ESC, '\033', '[', 'D', NUL, A_info_beginning_of_node,
738 CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
740 /* We want help to report q, not C-x C-c, etc. */
741 'q', NUL, A_info_quit,
742 'x', NUL, A_info_delete_window,
743 SPC, NUL, A_info_scroll_forward,
744 DEL, NUL, A_info_scroll_backward,
745 '{', NUL, A_info_search_previous,
746 '}', NUL, A_info_search_next,
747 CONTROL('g'), NUL, A_info_abort_key,
748 SK_ESCAPE, SK_UP_ARROW, NUL, A_info_up_line,
749 SK_ESCAPE, SK_DOWN_ARROW, NUL, A_info_down_line,
753 static unsigned char default_vi_like_ea_keys[] =
755 0, /* suppress-default-keybindings flag */
756 ESC, '1', NUL, A_info_add_digit_to_numeric_arg,
757 ESC, '2', NUL, A_info_add_digit_to_numeric_arg,
758 ESC, '3', NUL, A_info_add_digit_to_numeric_arg,
759 ESC, '4', NUL, A_info_add_digit_to_numeric_arg,
760 ESC, '5', NUL, A_info_add_digit_to_numeric_arg,
761 ESC, '6', NUL, A_info_add_digit_to_numeric_arg,
762 ESC, '7', NUL, A_info_add_digit_to_numeric_arg,
763 ESC, '8', NUL, A_info_add_digit_to_numeric_arg,
764 ESC, '9', NUL, A_info_add_digit_to_numeric_arg,
765 ESC, '-', NUL, A_info_add_digit_to_numeric_arg,
766 Meta('1'), NUL, A_info_add_digit_to_numeric_arg,
767 Meta('2'), NUL, A_info_add_digit_to_numeric_arg,
768 Meta('3'), NUL, A_info_add_digit_to_numeric_arg,
769 Meta('4'), NUL, A_info_add_digit_to_numeric_arg,
770 Meta('5'), NUL, A_info_add_digit_to_numeric_arg,
771 Meta('6'), NUL, A_info_add_digit_to_numeric_arg,
772 Meta('7'), NUL, A_info_add_digit_to_numeric_arg,
773 Meta('8'), NUL, A_info_add_digit_to_numeric_arg,
774 Meta('9'), NUL, A_info_add_digit_to_numeric_arg,
775 Meta('-'), NUL, A_info_add_digit_to_numeric_arg,
776 ESC, CONTROL('g'), NUL, A_ea_abort,
777 ESC, CONTROL('h'), NUL, A_ea_backward_kill_word,
778 ESC, CONTROL('v'), NUL, A_ea_scroll_completions_window,
779 ESC, '0', NUL, A_ea_beg_of_line,
780 ESC, '$', NUL, A_ea_end_of_line,
781 ESC, 'b', NUL, A_ea_backward_word,
782 ESC, 'd', NUL, A_ea_kill_word,
783 ESC, 'f', NUL, A_ea_forward_word,
784 ESC, 'h', NUL, A_ea_forward,
785 ESC, 'l', NUL, A_ea_backward,
786 ESC, 'w', NUL, A_ea_forward_word,
787 ESC, 'x', NUL, A_ea_delete,
788 ESC, 'X', NUL, A_ea_kill_word,
789 ESC, 'y', NUL, A_ea_yank_pop,
790 ESC, '?', NUL, A_ea_possible_completions,
791 ESC, TAB, NUL, A_ea_tab_insert,
792 ESC, DEL, NUL, A_ea_kill_word,
793 Meta(CONTROL('g')), NUL, A_ea_abort,
794 Meta(CONTROL('h')), NUL, A_ea_backward_kill_word,
795 Meta(CONTROL('v')), NUL, A_ea_scroll_completions_window,
796 Meta('0'), NUL, A_ea_beg_of_line,
797 Meta('$'), NUL, A_ea_end_of_line,
798 Meta('b'), NUL, A_ea_backward_word,
799 Meta('d'), NUL, A_ea_kill_word,
800 Meta('f'), NUL, A_ea_forward_word,
801 Meta('h'), NUL, A_ea_forward,
802 Meta('l'), NUL, A_ea_backward,
803 Meta('w'), NUL, A_ea_forward_word,
804 Meta('x'), NUL, A_ea_delete,
805 Meta('X'), NUL, A_ea_kill_word,
806 Meta('y'), NUL, A_ea_yank_pop,
807 Meta('?'), NUL, A_ea_possible_completions,
808 Meta(TAB), NUL, A_ea_tab_insert,
809 Meta(DEL), NUL, A_ea_kill_word,
810 CONTROL('a'), NUL, A_ea_beg_of_line,
811 CONTROL('b'), NUL, A_ea_backward,
812 CONTROL('d'), NUL, A_ea_delete,
813 CONTROL('e'), NUL, A_ea_end_of_line,
814 CONTROL('f'), NUL, A_ea_forward,
815 CONTROL('g'), NUL, A_ea_abort,
816 CONTROL('h'), NUL, A_ea_rubout,
818 SK_ESCAPE, SK_LITERAL, NUL, A_ea_kill_line,
819 CONTROL('l'), NUL, A_info_redraw_display,
820 CONTROL('q'), NUL, A_ea_quoted_insert,
821 CONTROL('t'), NUL, A_ea_transpose_chars,
822 CONTROL('u'), NUL, A_ea_abort,
823 CONTROL('v'), NUL, A_ea_quoted_insert,
824 CONTROL('y'), NUL, A_ea_yank,
825 LFD, NUL, A_ea_newline,
826 RET, NUL, A_ea_newline,
827 SPC, NUL, A_ea_complete,
828 TAB, NUL, A_ea_complete,
829 '?', NUL, A_ea_possible_completions,
831 /* PC users will lynch me if I don't give them their usual DEL
833 DEL, NUL, A_ea_delete,
835 DEL, NUL, A_ea_rubout,
837 CONTROL('x'), 'o', NUL, A_info_next_window,
838 CONTROL('x'), DEL, NUL, A_ea_backward_kill_line,
840 /* Arrow key bindings for echo area keymaps. It seems that some
841 terminals do not match their termcap entries, so it's best to just
842 define everything with both of the usual prefixes. */
844 SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward,
845 '\033', 'O', 'C', NUL, A_ea_forward,
846 '\033', '[', 'C', NUL, A_ea_forward,
847 SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward,
848 '\033', 'O', 'D', NUL, A_ea_backward,
849 '\033', '[', 'D', NUL, A_ea_backward,
850 SK_ESCAPE, SK_HOME, NUL, A_ea_beg_of_line,
851 SK_ESCAPE, SK_END, NUL, A_ea_end_of_line,
853 SK_ESCAPE, SK_DELETE, NUL, A_ea_delete,
855 SK_DELETE, SK_DELETE, NUL, A_ea_rubout,
857 ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL, A_ea_forward_word,
858 ESC, '\033', 'O', 'C', NUL, A_ea_forward_word,
859 ESC, '\033', '[', 'C', NUL, A_ea_forward_word,
860 ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL, A_ea_backward_word,
861 ESC, '\033', 'O', 'D', NUL, A_ea_backward_word,
862 ESC, '\033', '[', 'D', NUL, A_ea_backward_word,
863 ESC, SK_ESCAPE, SK_DELETE, NUL, A_ea_kill_word,
864 CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
868 static unsigned char *user_info_keys;
869 static unsigned int user_info_keys_len;
870 static unsigned char *user_ea_keys;
871 static unsigned int user_ea_keys_len;
872 static unsigned char *user_vars;
873 static unsigned int user_vars_len;
876 * Return the size of a file, or 0 if the size can't be determined.
881 long pos = lseek(f, 0L, SEEK_CUR);
885 sz = lseek(f, 0L, SEEK_END);
886 lseek(f, pos, SEEK_SET);
888 return sz == -1L ? 0L : sz;
891 /* Get an integer from a infokey file.
892 Integers are stored as two bytes, low order first, in radix INFOKEY_RADIX.
895 getint (unsigned char **sp)
899 if ( !((*sp)[0] < INFOKEY_RADIX && (*sp)[1] < INFOKEY_RADIX) )
901 n = (*sp)[0] + (*sp)[1] * INFOKEY_RADIX;
907 /* Fetch the contents of the standard infokey file "$HOME/.info". Return
908 true if ok, false if not. */
910 fetch_user_maps (void)
912 char *filename = NULL;
921 /* Find and open file. */
922 if ((filename = getenv("INFOKEY")) != NULL)
923 filename = xstrdup(filename);
924 else if ((homedir = getenv("HOME")) != NULL)
926 filename = xmalloc(strlen(homedir) + 2 + strlen(INFOKEY_FILE));
927 strcpy(filename, homedir);
928 strcat(filename, "/");
929 strcat(filename, INFOKEY_FILE);
932 /* Poor baby, she doesn't have a HOME... */
934 filename = xstrdup(INFOKEY_FILE); /* try current directory */
936 if (filename == NULL || (f = open(filename, O_RDONLY)) == (-1))
938 if (filename && errno != ENOENT)
940 info_error(filesys_error_string(filename, errno),
948 /* Ensure that the file is a reasonable size. */
950 if (len < INFOKEY_NMAGIC + 2 || len > 100 * 1024)
952 /* Bad file (a valid file must have at least 9 chars, and
953 more than 100 KB is a problem). */
954 if (len < INFOKEY_NMAGIC + 2)
955 info_error(_("Ignoring invalid infokey file `%s' - too small"),
958 info_error(_("Ignoring invalid infokey file `%s' - too big"),
965 /* Read the file into a buffer. */
966 buf = xmalloc((int)len);
967 nread = read(f, buf, (unsigned int) len);
969 if ((unsigned int) nread != len)
971 info_error(_("Error reading infokey file `%s' - short read"),
978 /* Check the header, trailer, and version of the file to increase
979 our confidence that the contents are valid. */
980 if ( buf[0] != INFOKEY_MAGIC_S0
981 || buf[1] != INFOKEY_MAGIC_S1
982 || buf[2] != INFOKEY_MAGIC_S2
983 || buf[3] != INFOKEY_MAGIC_S3
984 || buf[len - 4] != INFOKEY_MAGIC_E0
985 || buf[len - 3] != INFOKEY_MAGIC_E1
986 || buf[len - 2] != INFOKEY_MAGIC_E2
987 || buf[len - 1] != INFOKEY_MAGIC_E3
990 info_error(_("Invalid infokey file `%s' (bad magic numbers) -- run infokey to update it"),
995 if (len < INFOKEY_NMAGIC + strlen(VERSION) + 1
996 || strcmp(VERSION, (char *) (buf + 4)) != 0)
999 (_("Your infokey file `%s' is out of date -- run infokey to update it"),
1005 /* Extract the pieces. */
1006 for (p = buf + 4 + strlen(VERSION) + 1;
1007 (unsigned int) (p - buf) < len - 4;
1013 if (n < 0 || (unsigned int) n > len - 4 - (p - buf))
1015 info_error(_("Invalid infokey file `%s' (bad section length) -- run infokey to update it"),
1023 case INFOKEY_SECTION_INFO:
1025 user_info_keys_len = n;
1027 case INFOKEY_SECTION_EA:
1029 user_ea_keys_len = n;
1031 case INFOKEY_SECTION_VAR:
1036 info_error(_("Invalid infokey file `%s' (bad section code) -- run infokey to update it"),
1047 /* Decode special key sequences from the infokey file. Return zero
1048 if the key sequence includes special keys which the terminal
1052 decode_keys(unsigned char *src, unsigned int slen,
1053 unsigned char *dst, unsigned int dlen)
1055 unsigned char *s = src;
1056 unsigned char *d = dst;
1058 #define To_dst(c) do { \
1059 if ((unsigned int) (d - dst) < dlen) *d++ = (c); \
1062 while ((unsigned int) (s - src) < slen)
1064 unsigned char c = ISMETA(*s) ? UNMETA(*s) : *s;
1069 static char lit[] = { SK_ESCAPE, NUL };
1071 switch ((unsigned int) (s + 1 - src) < slen ? s[1] : '\0')
1073 case SK_RIGHT_ARROW: t = term_kr; break;
1074 case SK_LEFT_ARROW: t = term_kl; break;
1075 case SK_UP_ARROW: t = term_ku; break;
1076 case SK_DOWN_ARROW: t = term_kd; break;
1077 case SK_PAGE_UP: t = term_kP; break;
1078 case SK_PAGE_DOWN: t = term_kN; break;
1079 case SK_HOME: t = term_kh; break;
1080 case SK_END: t = term_ke; break;
1081 case SK_DELETE: t = term_kx; break;
1082 case SK_INSERT: t = term_ki; break;
1084 default: t = lit; break;
1089 To_dst(ISMETA(*s) ? Meta(*t++) : *t++);
1109 /* Convert an infokey file section to keymap bindings. Return false if
1110 the default bindings are to be suppressed. */
1112 section_to_keymaps(Keymap map, unsigned char *table, unsigned int len)
1116 unsigned char *seq = NULL;
1117 unsigned int seqlen = 0;
1118 enum { getseq, gotseq, getaction } state = getseq;
1120 stop = len > 0 ? table[0] : 0;
1122 for (p = table + 1; (unsigned int) (p - table) < len; p++)
1144 unsigned int action = *p;
1145 unsigned char keyseq[256];
1149 /* If decode_keys returns zero, it
1150 means that seq includes keys which
1151 the terminal doesn't support, like
1152 PageDown. In that case, don't bind
1153 the key sequence. */
1154 if (decode_keys(seq, seqlen, keyseq,
1157 keyseq[sizeof keyseq - 1] = '\0';
1160 action < A_NCOMMANDS
1161 ? &function_doc_array[action]
1163 keymap_bind_keyseq(map,
1164 (const char *) keyseq, &ke);
1170 if (state != getseq)
1171 info_error(_("Bad data in infokey file -- some key bindings ignored"),
1176 /* Convert an infokey file section to variable settings.
1179 section_to_vars(unsigned char *table, unsigned int len)
1181 enum { getvar, gotvar, getval, gotval } state = getvar;
1182 unsigned char *var = NULL;
1183 unsigned char *val = NULL;
1186 for (p = table; (unsigned int) (p - table) < len; p++)
1214 set_variable_to_value((char *) var, (char *) val);
1220 if (state != getvar)
1221 info_error(_("Bad data in infokey file -- some var settings ignored"),
1226 initialize_info_keymaps (void)
1229 int suppress_info_default_bindings = 0;
1230 int suppress_ea_default_bindings = 0;
1234 info_keymap = keymap_make_keymap ();
1235 echo_area_keymap = keymap_make_keymap ();
1238 /* Bind the echo area insert routines. */
1239 for (i = 0; i < 256; i++)
1241 echo_area_keymap[i].function = InfoCmd(ea_insert);
1243 /* Get user-defined keys and variables. */
1244 if (fetch_user_maps())
1246 if (user_info_keys_len && user_info_keys[0])
1247 suppress_info_default_bindings = 1;
1248 if (user_ea_keys_len && user_ea_keys[0])
1249 suppress_ea_default_bindings = 1;
1252 /* Apply the default bindings, unless the user says to suppress
1256 if (!suppress_info_default_bindings)
1257 section_to_keymaps(info_keymap, default_vi_like_info_keys,
1258 sizeof(default_vi_like_info_keys));
1259 if (!suppress_ea_default_bindings)
1260 section_to_keymaps(echo_area_keymap, default_vi_like_ea_keys,
1261 sizeof(default_vi_like_ea_keys));
1265 if (!suppress_info_default_bindings)
1266 section_to_keymaps(info_keymap, default_emacs_like_info_keys,
1267 sizeof(default_emacs_like_info_keys));
1268 if (!suppress_ea_default_bindings)
1269 section_to_keymaps(echo_area_keymap, default_emacs_like_ea_keys,
1270 sizeof(default_emacs_like_ea_keys));
1273 /* If the user specified custom bindings, apply them on top of the
1275 if (user_info_keys_len)
1276 section_to_keymaps(info_keymap, user_info_keys, user_info_keys_len);
1278 if (user_ea_keys_len)
1279 section_to_keymaps(echo_area_keymap, user_ea_keys, user_ea_keys_len);
1282 section_to_vars(user_vars, user_vars_len);
1285 /* vim: set sw=2 cino={1s>2sn-s^-se-s: */