193142Sru/* infomap.c -- keymaps for Info.
2146520Sru   $Id: infomap.c,v 1.10 2004/07/30 20:43:40 karl Exp $
321495Sjmacd
4146520Sru   Copyright (C) 1993, 1997, 1998, 1999, 2001, 2002, 2003, 2004 Free Software
5114477Sru   Foundation, Inc.
621495Sjmacd
721495Sjmacd   This program is free software; you can redistribute it and/or modify
821495Sjmacd   it under the terms of the GNU General Public License as published by
921495Sjmacd   the Free Software Foundation; either version 2, or (at your option)
1021495Sjmacd   any later version.
1121495Sjmacd
1221495Sjmacd   This program is distributed in the hope that it will be useful,
1321495Sjmacd   but WITHOUT ANY WARRANTY; without even the implied warranty of
1421495Sjmacd   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1521495Sjmacd   GNU General Public License for more details.
1621495Sjmacd
1721495Sjmacd   You should have received a copy of the GNU General Public License
1821495Sjmacd   along with this program; if not, write to the Free Software
1921495Sjmacd   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2021495Sjmacd
2121495Sjmacd   Written by Brian Fox (bfox@ai.mit.edu). */
2221495Sjmacd
2342664Smarkm#include "info.h"
2421495Sjmacd#include "infomap.h"
2521495Sjmacd#include "funs.h"
2642664Smarkm#include "terminal.h"
2721495Sjmacd
2893142Sru#if defined(INFOKEY)
2993142Sru#include "infokey.h"
3093142Sru#include "variables.h"
3193142Sru#endif /* INFOKEY */
3293142Sru
33146520Srustatic int keymap_bind_keyseq (Keymap map, const char *keyseq,
34146520Sru    KEYMAP_ENTRY *keyentry);
35146520Sru
3621495Sjmacd/* Return a new keymap which has all the uppercase letters mapped to run
3721495Sjmacd   the function info_do_lowercase_version (). */
3821495SjmacdKeymap
39146520Srukeymap_make_keymap (void)
4021495Sjmacd{
4193142Sru  int i;
4221495Sjmacd  Keymap keymap;
4321495Sjmacd
4421495Sjmacd  keymap = (Keymap)xmalloc (256 * sizeof (KEYMAP_ENTRY));
4521495Sjmacd
4621495Sjmacd  for (i = 0; i < 256; i++)
4721495Sjmacd    {
4821495Sjmacd      keymap[i].type = ISFUNC;
4993142Sru      keymap[i].function = (InfoCommand *)NULL;
5021495Sjmacd    }
5121495Sjmacd
5221495Sjmacd  for (i = 'A'; i < ('Z' + 1); i++)
5321495Sjmacd    {
5421495Sjmacd      keymap[i].type = ISFUNC;
5593142Sru#if defined(INFOKEY)
5693142Sru      keymap[Meta(i)].type = ISFUNC;
5793142Sru      keymap[Meta(i)].function =
5893142Sru#endif /* INFOKEY */
5993142Sru      keymap[i].function = InfoCmd(info_do_lowercase_version);
6021495Sjmacd    }
6121495Sjmacd
6221495Sjmacd  return (keymap);
6321495Sjmacd}
6421495Sjmacd
65114477Sru#if defined(INFOKEY)
66114477Srustatic FUNCTION_KEYSEQ *
67146520Srufind_function_keyseq (Keymap map, int c, Keymap rootmap)
68114477Sru{
69114477Sru  FUNCTION_KEYSEQ *k;
70114477Sru
71114477Sru  if (map[c].type != ISFUNC)
72114477Sru    abort();
73114477Sru  if (map[c].function == NULL)
74114477Sru    return NULL;
75114477Sru  for (k = map[c].function->keys; k; k = k->next)
76114477Sru    {
77114477Sru      const unsigned char *p;
78114477Sru      Keymap m = rootmap;
79114477Sru      if (k->map != rootmap)
80114477Sru	continue;
81146520Sru      for (p = (unsigned char *) k->keyseq; *p && m[*p].type == ISKMAP; p++)
82114477Sru	m = (Keymap)m[*p].function;
83114477Sru      if (*p != c || p[1])
84114477Sru	continue;
85114477Sru      if (m[*p].type != ISFUNC)
86114477Sru	abort ();
87114477Sru      break;
88114477Sru    }
89114477Sru  return k;
90114477Sru}
91114477Sru
92114477Srustatic void
93146520Sruadd_function_keyseq (InfoCommand *function,
94146520Sru    const char *keyseq, Keymap rootmap)
95114477Sru{
96114477Sru  FUNCTION_KEYSEQ *ks;
97114477Sru
98114477Sru  if (function == NULL ||
99114477Sru      function == InfoCmd(info_do_lowercase_version) ||
100114477Sru      function == InfoCmd(ea_insert))
101114477Sru    return;
102114477Sru  ks = (FUNCTION_KEYSEQ *)xmalloc (sizeof(FUNCTION_KEYSEQ));
103114477Sru  ks->next = function->keys;
104114477Sru  ks->map = rootmap;
105114477Sru  ks->keyseq = xstrdup(keyseq);
106114477Sru  function->keys = ks;
107114477Sru}
108114477Sru
109114477Srustatic void
110146520Sruremove_function_keyseq (InfoCommand *function,
111146520Sru    const char *keyseq, Keymap rootmap)
112114477Sru{
113114477Sru
114114477Sru  FUNCTION_KEYSEQ *k, *kp;
115114477Sru
116114477Sru  if (function == NULL ||
117114477Sru      function == InfoCmd(info_do_lowercase_version) ||
118114477Sru      function == InfoCmd(ea_insert))
119114477Sru    return;
120114477Sru  for (kp = NULL, k = function->keys; k; kp = k, k = k->next)
121114477Sru    if (k->map == rootmap && strcmp(k->keyseq, keyseq) == 0)
122114477Sru      break;
123114477Sru  if (!k)
124114477Sru    abort ();
125114477Sru  if (kp)
126114477Sru    kp->next = k->next;
127114477Sru  else
128114477Sru    function->keys = k->next;
129114477Sru}
130114477Sru#endif /* INFOKEY */
131116530Sru
13221495Sjmacd/* Return a new keymap which is a copy of MAP. */
13321495SjmacdKeymap
134146520Srukeymap_copy_keymap (Keymap map, Keymap rootmap, Keymap newroot)
13521495Sjmacd{
13693142Sru  int i;
13721495Sjmacd  Keymap keymap;
138114477Sru#if defined(INFOKEY)
139114477Sru  FUNCTION_KEYSEQ *ks;
140114477Sru#endif /* INFOKEY */
14121495Sjmacd
14221495Sjmacd  keymap = keymap_make_keymap ();
143114477Sru  if (!newroot)
144114477Sru    newroot = keymap;
14521495Sjmacd
14621495Sjmacd  for (i = 0; i < 256; i++)
14721495Sjmacd    {
14821495Sjmacd      keymap[i].type = map[i].type;
149114477Sru      switch (map[i].type)
150114477Sru	{
151114477Sru	case ISFUNC:
152114477Sru	  keymap[i].function = map[i].function;
153114477Sru#if defined(INFOKEY)
154146520Sru	  ks = find_function_keyseq (map, i, rootmap);
155114477Sru	  if (ks)
156114477Sru	    add_function_keyseq(map[i].function, ks->keyseq, newroot);
157114477Sru#endif /* INFOKEY */
158114477Sru	  break;
159114477Sru	case ISKMAP:
160146520Sru	  keymap[i].function = (InfoCommand *)keymap_copy_keymap
161146520Sru            ((Keymap)map[i].function, rootmap, NULL);
162114477Sru	  break;
163114477Sru	}
16421495Sjmacd    }
16521495Sjmacd  return (keymap);
16621495Sjmacd}
16721495Sjmacd
16856164Sru/* Free the keymap and its descendants. */
16921495Sjmacdvoid
170146520Srukeymap_discard_keymap (Keymap map, Keymap rootmap)
17121495Sjmacd{
17293142Sru  int i;
17321495Sjmacd
17421495Sjmacd  if (!map)
17521495Sjmacd    return;
176114477Sru  if (!rootmap)
177114477Sru    rootmap = map;
17821495Sjmacd
17921495Sjmacd  for (i = 0; i < 256; i++)
18021495Sjmacd    {
181114477Sru#if defined(INFOKEY)
182114477Sru      FUNCTION_KEYSEQ *ks;
183114477Sru#endif /* INFOKEY */
18421495Sjmacd      switch (map[i].type)
18542664Smarkm        {
18642664Smarkm        case ISFUNC:
187114477Sru#if defined(INFOKEY)
188114477Sru	  ks = find_function_keyseq(map, i, rootmap);
189114477Sru	  if (ks)
190114477Sru	    remove_function_keyseq (map[i].function, ks->keyseq, rootmap);
191114477Sru#endif /* INFOKEY */
19242664Smarkm          break;
19321495Sjmacd
19442664Smarkm        case ISKMAP:
195114477Sru          keymap_discard_keymap ((Keymap)map[i].function, rootmap);
19642664Smarkm          break;
19721495Sjmacd
19842664Smarkm        }
19921495Sjmacd    }
200114477Sru  free(map);
20121495Sjmacd}
20221495Sjmacd
20342664Smarkm/* Conditionally bind key sequence. */
204146520Srustatic int
205146520Srukeymap_bind_keyseq (Keymap map,
206146520Sru    const char *keyseq, KEYMAP_ENTRY *keyentry)
20742664Smarkm{
20893142Sru  Keymap m = map;
209146520Sru  const unsigned char *s = (unsigned char *) keyseq;
21093142Sru  int c;
21142664Smarkm
21242664Smarkm  if (s == NULL || *s == '\0') return 0;
21342664Smarkm
21442664Smarkm  while ((c = *s++) != '\0')
21542664Smarkm    {
216114477Sru#if defined(INFOKEY)
217114477Sru      FUNCTION_KEYSEQ *ks;
218114477Sru#endif /* INFOKEY */
21942664Smarkm      switch (m[c].type)
22042664Smarkm        {
22142664Smarkm        case ISFUNC:
222114477Sru#if defined(INFOKEY)
223114477Sru	  ks = find_function_keyseq(m, c, map);
224114477Sru	  if (ks)
225114477Sru	    remove_function_keyseq (m[c].function, ks->keyseq, map);
226114477Sru#else /* !INFOKEY */
22793142Sru          if (!(m[c].function == NULL || (
22893142Sru                m != map &&
22993142Sru                m[c].function == InfoCmd(info_do_lowercase_version))
23093142Sru	      ))
23142664Smarkm            return 0;
232114477Sru#endif /* !INFOKEY */
23342664Smarkm
23442664Smarkm          if (*s != '\0')
23542664Smarkm            {
23642664Smarkm              m[c].type = ISKMAP;
237114477Sru              /* Here we are casting the Keymap pointer returned from
238114477Sru                 keymap_make_keymap to an InfoCommand pointer.  Ugh.
239114477Sru                 This makes the `function' structure garbage
240114477Sru                 if it's actually interpreted as an InfoCommand.
241114477Sru                 Should really be using a union, and taking steps to
242114477Sru                 avoid the possible error.  */
24393142Sru              m[c].function = (InfoCommand *)keymap_make_keymap ();
24442664Smarkm            }
24542664Smarkm          break;
24642664Smarkm
24742664Smarkm        case ISKMAP:
248114477Sru#if defined(INFOKEY)
249114477Sru	  if (*s == '\0')
250114477Sru	    keymap_discard_keymap ((Keymap)m[c].function, map);
251114477Sru#else /* !INFOKEY */
25242664Smarkm          if (*s == '\0')
25342664Smarkm            return 0;
254114477Sru#endif
25542664Smarkm          break;
25642664Smarkm        }
25742664Smarkm      if (*s != '\0')
25842664Smarkm        {
25942664Smarkm          m = (Keymap)m[c].function;
26042664Smarkm        }
26142664Smarkm      else
26242664Smarkm        {
26393142Sru#if defined(INFOKEY)
264114477Sru	  add_function_keyseq (keyentry->function, keyseq, map);
26593142Sru#endif /* INFOKEY */
26642664Smarkm          m[c] = *keyentry;
26742664Smarkm        }
26842664Smarkm    }
26942664Smarkm
27042664Smarkm  return 1;
27142664Smarkm}
27242664Smarkm
27321495Sjmacd/* Initialize the standard info keymaps. */
27421495Sjmacd
27556164SruKeymap info_keymap = NULL;
27656164SruKeymap echo_area_keymap = NULL;
27721495Sjmacd
27893142Sru#if !defined(INFOKEY)
27993142Sru
28056164Srustatic void
28156164Sruinitialize_emacs_like_keymaps ()
28221495Sjmacd{
28356164Sru  int i;
28421495Sjmacd  Keymap map;
28521495Sjmacd
28621495Sjmacd  if (!info_keymap)
28721495Sjmacd    {
28821495Sjmacd      info_keymap = keymap_make_keymap ();
28921495Sjmacd      echo_area_keymap = keymap_make_keymap ();
29021495Sjmacd    }
29121495Sjmacd
29256164Sru  info_keymap[ESC].type = ISKMAP;
29393142Sru  info_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
29456164Sru  info_keymap[Control ('x')].type = ISKMAP;
29593142Sru  info_keymap[Control ('x')].function = (InfoCommand *)keymap_make_keymap ();
29656164Sru
29756164Sru  /* Bind the echo area insert routines.  Let's make all characters
29856164Sru     insertable by default, regardless of which character set we might
29956164Sru     be using.  */
30056164Sru  for (i = 0; i < 256; i++)
30156164Sru    echo_area_keymap[i].function = ea_insert;
30256164Sru
30356164Sru  echo_area_keymap[ESC].type = ISKMAP;
30493142Sru  echo_area_keymap[ESC].function = (InfoCommand *) keymap_make_keymap ();
30556164Sru  echo_area_keymap[Control ('x')].type = ISKMAP;
30656164Sru  echo_area_keymap[Control ('x')].function
30793142Sru    = (InfoCommand *) keymap_make_keymap ();
30856164Sru
30921495Sjmacd  /* Bind numeric arg functions for both echo area and info window maps. */
31021495Sjmacd  for (i = '0'; i < '9' + 1; i++)
31121495Sjmacd    {
31256164Sru      ((Keymap) info_keymap[ESC].function)[i].function
31356164Sru        = ((Keymap) echo_area_keymap[ESC].function)[i].function
31456164Sru        = info_add_digit_to_numeric_arg;
31521495Sjmacd    }
31621495Sjmacd  ((Keymap) info_keymap[ESC].function)['-'].function =
31721495Sjmacd    ((Keymap) echo_area_keymap[ESC].function)['-'].function =
31821495Sjmacd      info_add_digit_to_numeric_arg;
31921495Sjmacd
32056164Sru  info_keymap['-'].function = info_add_digit_to_numeric_arg;
32156164Sru
32221495Sjmacd  /* Bind the echo area routines. */
32321495Sjmacd  map = echo_area_keymap;
32421495Sjmacd
32521495Sjmacd  map[Control ('a')].function = ea_beg_of_line;
32621495Sjmacd  map[Control ('b')].function = ea_backward;
32721495Sjmacd  map[Control ('d')].function = ea_delete;
32821495Sjmacd  map[Control ('e')].function = ea_end_of_line;
32921495Sjmacd  map[Control ('f')].function = ea_forward;
33021495Sjmacd  map[Control ('g')].function = ea_abort;
33121495Sjmacd  map[Control ('h')].function = ea_rubout;
33221495Sjmacd  map[Control ('k')].function = ea_kill_line;
33321495Sjmacd  map[Control ('l')].function = info_redraw_display;
33421495Sjmacd  map[Control ('q')].function = ea_quoted_insert;
33521495Sjmacd  map[Control ('t')].function = ea_transpose_chars;
33621495Sjmacd  map[Control ('u')].function = info_universal_argument;
33721495Sjmacd  map[Control ('y')].function = ea_yank;
33821495Sjmacd
33921495Sjmacd  map[LFD].function = ea_newline;
34021495Sjmacd  map[RET].function = ea_newline;
34121495Sjmacd  map[SPC].function = ea_complete;
34221495Sjmacd  map[TAB].function = ea_complete;
34321495Sjmacd  map['?'].function = ea_possible_completions;
34456164Sru#ifdef __MSDOS__
34556164Sru  /* PC users will lynch me if I don't give them their usual DEL effect...  */
34656164Sru  map[DEL].function = ea_delete;
34756164Sru#else
34821495Sjmacd  map[DEL].function = ea_rubout;
34956164Sru#endif
35021495Sjmacd
35121495Sjmacd  /* Bind the echo area ESC keymap. */
35221495Sjmacd  map = (Keymap)echo_area_keymap[ESC].function;
35321495Sjmacd
35421495Sjmacd  map[Control ('g')].function = ea_abort;
35521495Sjmacd  map[Control ('v')].function = ea_scroll_completions_window;
35621495Sjmacd  map['b'].function = ea_backward_word;
35721495Sjmacd  map['d'].function = ea_kill_word;
35821495Sjmacd  map['f'].function = ea_forward_word;
35921495Sjmacd#if defined (NAMED_FUNCTIONS)
36021495Sjmacd  /* map['x'].function = info_execute_command; */
36121495Sjmacd#endif /* NAMED_FUNCTIONS */
36221495Sjmacd  map['y'].function = ea_yank_pop;
36321495Sjmacd  map['?'].function = ea_possible_completions;
36421495Sjmacd  map[TAB].function = ea_tab_insert;
36521495Sjmacd  map[DEL].function = ea_backward_kill_word;
36621495Sjmacd
36721495Sjmacd  /* Bind the echo area Control-x keymap. */
36821495Sjmacd  map = (Keymap)echo_area_keymap[Control ('x')].function;
36921495Sjmacd
37021495Sjmacd  map['o'].function = info_next_window;
37121495Sjmacd  map[DEL].function = ea_backward_kill_line;
37221495Sjmacd
37342664Smarkm  /* Arrow key bindings for echo area keymaps.  It seems that some
37442664Smarkm     terminals do not match their termcap entries, so it's best to just
37542664Smarkm     define everything with both of the usual prefixes.  */
37642664Smarkm  map = echo_area_keymap;
37742664Smarkm  keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
37842664Smarkm  keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
37942664Smarkm  keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
38042664Smarkm  keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
38142664Smarkm  keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
38242664Smarkm  keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
38342664Smarkm  keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
38442664Smarkm  keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
38542664Smarkm  keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
38642664Smarkm  keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
38742664Smarkm  keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
38842664Smarkm  keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
38993142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);	/* delete */
39093142Sru  keymap_bind_keyseq (map, term_kh, &map[Control ('a')]); /* home */
39193142Sru  keymap_bind_keyseq (map, term_ke, &map[Control ('e')]); /* end */
39242664Smarkm
39342664Smarkm  map = (Keymap)echo_area_keymap[ESC].function;
39442664Smarkm  keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
39542664Smarkm  keymap_bind_keyseq (map, "\033OA", &map['b']);
39642664Smarkm  keymap_bind_keyseq (map, "\033[A", &map['b']);
39742664Smarkm  keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
39842664Smarkm  keymap_bind_keyseq (map, "\033OB", &map['f']);
39942664Smarkm  keymap_bind_keyseq (map, "\033[B", &map['f']);
40093142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);	/* delete */
40142664Smarkm
40293142Sru  map = (Keymap)echo_area_keymap[Control ('x')].function;
40393142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);	/* delete */
40493142Sru
40521495Sjmacd  /* Bind commands for Info window keymaps. */
40621495Sjmacd  map = info_keymap;
40721495Sjmacd  map[TAB].function = info_move_to_next_xref;
40821495Sjmacd  map[LFD].function = info_select_reference_this_line;
40921495Sjmacd  map[RET].function = info_select_reference_this_line;
41021495Sjmacd  map[SPC].function = info_scroll_forward;
41121495Sjmacd  map[Control ('a')].function = info_beginning_of_line;
41221495Sjmacd  map[Control ('b')].function = info_backward_char;
41321495Sjmacd  map[Control ('e')].function = info_end_of_line;
41421495Sjmacd  map[Control ('f')].function = info_forward_char;
41521495Sjmacd  map[Control ('g')].function = info_abort_key;
41621495Sjmacd  map[Control ('h')].function = info_get_help_window;
41721495Sjmacd  map[Control ('l')].function = info_redraw_display;
41821495Sjmacd  map[Control ('n')].function = info_next_line;
41921495Sjmacd  map[Control ('p')].function = info_prev_line;
42021495Sjmacd  map[Control ('r')].function = isearch_backward;
42121495Sjmacd  map[Control ('s')].function = isearch_forward;
42221495Sjmacd  map[Control ('u')].function = info_universal_argument;
42393142Sru  map[Control ('v')].function = info_scroll_forward_page_only;
42421495Sjmacd  map[','].function = info_next_index_match;
42556164Sru  map['/'].function = info_search;
42621495Sjmacd
42721495Sjmacd  for (i = '1'; i < '9' + 1; i++)
42821495Sjmacd    map[i].function = info_menu_digit;
42921495Sjmacd  map['0'].function = info_last_menu_item;
43021495Sjmacd
43121495Sjmacd  map['<'].function = info_first_node;
43221495Sjmacd  map['>'].function = info_last_node;
43321495Sjmacd  map['?'].function = info_get_help_window;
43421495Sjmacd  map['['].function = info_global_prev_node;
43521495Sjmacd  map[']'].function = info_global_next_node;
43621495Sjmacd
43721495Sjmacd  map['b'].function = info_beginning_of_node;
43821495Sjmacd  map['d'].function = info_dir_node;
43921495Sjmacd  map['e'].function = info_end_of_node;
44021495Sjmacd  map['f'].function = info_xref_item;
44121495Sjmacd  map['g'].function = info_goto_node;
44256164Sru  map['G'].function = info_menu_sequence;
44321495Sjmacd  map['h'].function = info_get_info_help_node;
44421495Sjmacd  map['i'].function = info_index_search;
44556164Sru  map['I'].function = info_goto_invocation_node;
44621495Sjmacd  map['l'].function = info_history_node;
44721495Sjmacd  map['m'].function = info_menu_item;
44821495Sjmacd  map['n'].function = info_next_node;
44956164Sru  map['O'].function = info_goto_invocation_node;
45021495Sjmacd  map['p'].function = info_prev_node;
45121495Sjmacd  map['q'].function = info_quit;
45221495Sjmacd  map['r'].function = info_xref_item;
45321495Sjmacd  map['s'].function = info_search;
45456164Sru  map['S'].function = info_search_case_sensitively;
45521495Sjmacd  map['t'].function = info_top_node;
45621495Sjmacd  map['u'].function = info_up_node;
45721495Sjmacd  map[DEL].function = info_scroll_backward;
45821495Sjmacd
45921495Sjmacd  /* Bind members in the ESC map for Info windows. */
46021495Sjmacd  map = (Keymap)info_keymap[ESC].function;
46121495Sjmacd  map[Control ('f')].function = info_show_footnotes;
46221495Sjmacd  map[Control ('g')].function = info_abort_key;
46321495Sjmacd  map[TAB].function = info_move_to_prev_xref;
46421495Sjmacd  map[Control ('v')].function = info_scroll_other_window;
46521495Sjmacd  map['<'].function = info_beginning_of_node;
46621495Sjmacd  map['>'].function = info_end_of_node;
46721495Sjmacd  map['b'].function = info_backward_word;
46821495Sjmacd  map['f'].function = info_forward_word;
46921495Sjmacd  map['r'].function = info_move_to_window_line;
47093142Sru  map['v'].function = info_scroll_backward_page_only;
47121495Sjmacd#if defined (NAMED_FUNCTIONS)
47221495Sjmacd  map['x'].function = info_execute_command;
47321495Sjmacd#endif /* NAMED_FUNCTIONS */
47456164Sru  map[DEL].function = info_scroll_other_window_backward;
47521495Sjmacd
47621495Sjmacd  /* Bind members in the Control-X map for Info windows. */
47721495Sjmacd  map = (Keymap)info_keymap[Control ('x')].function;
47821495Sjmacd
47921495Sjmacd  map[Control ('b')].function = list_visited_nodes;
48021495Sjmacd  map[Control ('c')].function = info_quit;
48121495Sjmacd  map[Control ('f')].function = info_view_file;
48221495Sjmacd  map[Control ('g')].function = info_abort_key;
48321495Sjmacd  map[Control ('v')].function = info_view_file;
48421495Sjmacd  map['0'].function = info_delete_window;
48521495Sjmacd  map['1'].function = info_keep_one_window;
48621495Sjmacd  map['2'].function = info_split_window;
48721495Sjmacd  map['^'].function = info_grow_window;
48821495Sjmacd  map['b'].function = select_visited_node;
48921495Sjmacd  map['k'].function = info_kill_node;
49056164Sru  map['n'].function = info_search_next;
49156164Sru  map['N'].function = info_search_previous;
49221495Sjmacd  map['o'].function = info_next_window;
49321495Sjmacd  map['t'].function = info_tile_windows;
49421495Sjmacd  map['w'].function = info_toggle_wrap;
49521787Sjmacd
49642664Smarkm  /* Arrow key bindings for Info windows keymap. */
49742664Smarkm  map = info_keymap;
49842664Smarkm  keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
49942664Smarkm  keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
50042664Smarkm  keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
50142664Smarkm  keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
50242664Smarkm  keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
50342664Smarkm  keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
50442664Smarkm  keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
50542664Smarkm  keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
50642664Smarkm  keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
50742664Smarkm  keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
50842664Smarkm  keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
50942664Smarkm  keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
51042664Smarkm  keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
51193142Sru  keymap_bind_keyseq (map, term_kh, &map['b']);	/* home */
51293142Sru  keymap_bind_keyseq (map, term_ke, &map['e']);	/* end */
51393142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);	/* delete */
51421495Sjmacd
51542664Smarkm  map = (Keymap)info_keymap[ESC].function;
51642664Smarkm  keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
51742664Smarkm  keymap_bind_keyseq (map, "\033OA", &map['b']);
51842664Smarkm  keymap_bind_keyseq (map, "\033[A", &map['b']);
51942664Smarkm  keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
52042664Smarkm  keymap_bind_keyseq (map, "\033OB", &map['f']);
52142664Smarkm  keymap_bind_keyseq (map, "\033[B", &map['f']);
52242664Smarkm  keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
52356164Sru  keymap_bind_keyseq (map, term_kP, &map[DEL]); /* pageup */
52493142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);	/* delete */
52542664Smarkm
52642664Smarkm  /* The alternative to this definition of a `main map' key in the
52742664Smarkm     `ESC map' section, is something like:
52842664Smarkm    keymap_bind_keyseq (map, term_kP, &((KeyMap)map[ESC].function).map['v']);
52942664Smarkm  */
53042664Smarkm  keymap_bind_keyseq (info_keymap/*sic*/, term_kP, &map['v']); /* pageup */
53121787Sjmacd}
53256164Sru
53356164Srustatic void
53456164Sruinitialize_vi_like_keymaps ()
53556164Sru{
53693142Sru  int i;
53756164Sru  Keymap map;
53856164Sru
53956164Sru  if (!info_keymap)
54056164Sru    {
54156164Sru      info_keymap = keymap_make_keymap ();
54256164Sru      echo_area_keymap = keymap_make_keymap ();
54356164Sru    }
54456164Sru
54556164Sru  info_keymap[ESC].type = ISKMAP;
54693142Sru  info_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
54756164Sru  info_keymap[Control ('x')].type = ISKMAP;
54893142Sru  info_keymap[Control ('x')].function = (InfoCommand *)keymap_make_keymap ();
54956164Sru
55056164Sru  /* Bind the echo area insert routines. */
55156164Sru  for (i = 0; i < 256; i++)
55256164Sru    echo_area_keymap[i].function = ea_insert;
55356164Sru
55456164Sru  echo_area_keymap[ESC].type = ISKMAP;
55593142Sru  echo_area_keymap[ESC].function = (InfoCommand *)keymap_make_keymap ();
55656164Sru  echo_area_keymap[Control ('x')].type = ISKMAP;
55756164Sru  echo_area_keymap[Control ('x')].function =
55893142Sru    (InfoCommand *)keymap_make_keymap ();
55956164Sru
56056164Sru  /* Bind numeric arg functions for both echo area and info window maps. */
56156164Sru  for (i = '0'; i < '9' + 1; i++)
56256164Sru    {
56356164Sru      info_keymap[i].function =
56456164Sru        ((Keymap) echo_area_keymap[ESC].function)[i].function =
56556164Sru	info_add_digit_to_numeric_arg;
56656164Sru    }
56756164Sru  info_keymap['-'].function =
56856164Sru    ((Keymap) echo_area_keymap[ESC].function)['-'].function =
56956164Sru      info_add_digit_to_numeric_arg;
57056164Sru
57156164Sru  /* Bind the echo area routines. */
57256164Sru  map = echo_area_keymap;
57356164Sru
57456164Sru  map[Control ('a')].function = ea_beg_of_line;
57556164Sru  map[Control ('b')].function = ea_backward;
57656164Sru  map[Control ('d')].function = ea_delete;
57756164Sru  map[Control ('e')].function = ea_end_of_line;
57856164Sru  map[Control ('f')].function = ea_forward;
57956164Sru  map[Control ('g')].function = ea_abort;
58056164Sru  map[Control ('h')].function = ea_rubout;
58156164Sru  map[Control ('k')].function = ea_kill_line;
58256164Sru  map[Control ('l')].function = info_redraw_display;
58356164Sru  map[Control ('q')].function = ea_quoted_insert;
58456164Sru  map[Control ('t')].function = ea_transpose_chars;
58556164Sru  map[Control ('u')].function = ea_abort;
58656164Sru  map[Control ('v')].function = ea_quoted_insert;
58756164Sru  map[Control ('y')].function = ea_yank;
58856164Sru
58956164Sru  map[LFD].function = ea_newline;
59056164Sru  map[RET].function = ea_newline;
59156164Sru  map[SPC].function = ea_complete;
59256164Sru  map[TAB].function = ea_complete;
59356164Sru  map['?'].function = ea_possible_completions;
59456164Sru#ifdef __MSDOS__
59556164Sru  /* PC users will lynch me if I don't give them their usual DEL effect...  */
59656164Sru  map[DEL].function = ea_delete;
59756164Sru#else
59856164Sru  map[DEL].function = ea_rubout;
59956164Sru#endif
60056164Sru
60156164Sru  /* Bind the echo area ESC keymap. */
60256164Sru  map = (Keymap)echo_area_keymap[ESC].function;
60356164Sru
60456164Sru  map[Control ('g')].function = ea_abort;
60556164Sru  map[Control ('h')].function = ea_backward_kill_word;
60656164Sru  map[Control ('v')].function = ea_scroll_completions_window;
60756164Sru  map['0'].function = ea_beg_of_line;
60856164Sru  map['$'].function = ea_end_of_line;
60956164Sru  map['b'].function = ea_backward_word;
61056164Sru  map['d'].function = ea_kill_word;
61156164Sru  map['f'].function = ea_forward_word;
612114477Sru  map['h'].function = ea_backward;
613114477Sru  map['l'].function = ea_forward;
61456164Sru  map['w'].function = ea_forward_word;
61556164Sru  map['x'].function = ea_delete;
61656164Sru  map['X'].function = ea_kill_word;
61756164Sru  map['y'].function = ea_yank_pop;
61856164Sru  map['?'].function = ea_possible_completions;
61956164Sru  map[TAB].function = ea_tab_insert;
62056164Sru  map[DEL].function = ea_kill_word;
62156164Sru
62256164Sru  /* Bind the echo area Control-x keymap. */
62356164Sru  map = (Keymap)echo_area_keymap[Control ('x')].function;
62456164Sru
62556164Sru  map['o'].function = info_next_window;
62656164Sru  map[DEL].function = ea_backward_kill_line;
62756164Sru
62856164Sru  /* Arrow key bindings for echo area keymaps.  It seems that some
62956164Sru     terminals do not match their termcap entries, so it's best to just
63056164Sru     define everything with both of the usual prefixes.  */
63156164Sru  map = echo_area_keymap;
63256164Sru  keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
63356164Sru  keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
63456164Sru  keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
63556164Sru  keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
63656164Sru  keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
63756164Sru  keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
63856164Sru  keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
63956164Sru  keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
64056164Sru  keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
64156164Sru  keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
64256164Sru  keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
64356164Sru  keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
64493142Sru  keymap_bind_keyseq (map, term_kh, &map[Control ('a')]); /* home */
64593142Sru  keymap_bind_keyseq (map, term_ke, &map[Control ('e')]); /* end */
64693142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);	/* delete */
64756164Sru
64856164Sru  map = (Keymap)echo_area_keymap[ESC].function;
64956164Sru  keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
65056164Sru  keymap_bind_keyseq (map, "\033OA", &map['b']);
65156164Sru  keymap_bind_keyseq (map, "\033[A", &map['b']);
65256164Sru  keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
65356164Sru  keymap_bind_keyseq (map, "\033OB", &map['f']);
65456164Sru  keymap_bind_keyseq (map, "\033[B", &map['f']);
65593142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);	/* delete */
65656164Sru
65793142Sru  map = (Keymap)echo_area_keymap[Control ('x')].function;
65893142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);
65993142Sru
66056164Sru  /* Bind commands for Info window keymaps. */
66156164Sru  map = info_keymap;
66256164Sru  map[TAB].function = info_move_to_next_xref;
66356164Sru  map[LFD].function = info_down_line;
66456164Sru  map[RET].function = info_down_line;
66556164Sru  map[SPC].function = info_scroll_forward;
66656164Sru  map[Control ('a')].function = info_beginning_of_line;
66793142Sru  map[Control ('b')].function = info_scroll_backward_page_only;
66856164Sru  map[Control ('d')].function = info_scroll_half_screen_down;
66956164Sru  map[Control ('e')].function = info_down_line;
67093142Sru  map[Control ('f')].function = info_scroll_forward_page_only;
67156164Sru  map[Control ('g')].function = info_abort_key;
67256164Sru  map[Control ('k')].function = info_up_line;
67356164Sru  map[Control ('l')].function = info_redraw_display;
67456164Sru  map[Control ('n')].function = info_down_line;
67556164Sru  map[Control ('p')].function = info_up_line;
67656164Sru  map[Control ('r')].function = info_redraw_display;
67756164Sru  map[Control ('s')].function = isearch_forward;
67856164Sru  map[Control ('u')].function = info_scroll_half_screen_up;
67993142Sru  map[Control ('v')].function = info_scroll_forward_page_only;
68056164Sru  map[Control ('y')].function = info_up_line;
68156164Sru  map[','].function = info_next_index_match;
68256164Sru  map['/'].function = info_search;
68356164Sru
68456164Sru  for (i = '1'; i < '9' + 1; i++)
68556164Sru    ((Keymap) info_keymap[ESC].function)[i].function = info_menu_digit;
68656164Sru  ((Keymap) info_keymap[ESC].function)['0'].function = info_last_menu_item;
68756164Sru
68856164Sru  map['<'].function = info_first_node;
68956164Sru  map['>'].function = info_last_node;
69056164Sru  map['?'].function = info_search_backward;
69156164Sru  map['['].function = info_global_prev_node;
69256164Sru  map[']'].function = info_global_next_node;
69356164Sru  map['\''].function = info_history_node;
69456164Sru
69556164Sru  map['b'].function = info_scroll_backward;
69656164Sru  map['d'].function = info_scroll_half_screen_down;
69756164Sru  map['e'].function = info_down_line;
69856164Sru  map['E'].function = info_view_file;
69993142Sru  map['f'].function = info_scroll_forward_page_only;
70093142Sru  map['F'].function = info_scroll_forward_page_only;
70156164Sru  map['g'].function = info_first_node;
70256164Sru  map['G'].function = info_last_node;
70356164Sru  map['h'].function = info_get_help_window;
70456164Sru  map['H'].function = info_get_help_window;
70556164Sru  map['i'].function = info_index_search;
70656164Sru  map['I'].function = info_goto_invocation_node;
707146520Sru  map['j'].function = info_next_line;
708146520Sru  map['k'].function = info_prev_line;
70956164Sru  map['l'].function = info_history_node;
71056164Sru  map['m'].function = info_menu_item;
71156164Sru  map['n'].function = info_search_next;
71256164Sru  map['N'].function = info_search_previous;
71356164Sru  map['O'].function = info_goto_invocation_node;
71456164Sru  map['p'].function = info_prev_node;
71556164Sru  map['q'].function = info_quit;
71656164Sru  map['Q'].function = info_quit;
71756164Sru  map['r'].function = info_redraw_display;
71856164Sru  map['R'].function = info_redraw_display;
71956164Sru  map['s'].function = info_search;
72056164Sru  map['S'].function = info_search_case_sensitively;
72156164Sru  map['t'].function = info_top_node;
72256164Sru  map['u'].function = info_scroll_half_screen_up;
72393142Sru  map['w'].function = info_scroll_backward_page_only_set_window;
72456164Sru  map['y'].function = info_up_line;
72593142Sru  map['z'].function = info_scroll_forward_page_only_set_window;
72656164Sru  map['Z'].function = NULL;	/* unbind, so it works to bind "ZZ" below */
72756164Sru  map[DEL].function = info_scroll_backward;
72893142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);
72956164Sru  keymap_bind_keyseq (map, ":q", &map['q']);
73056164Sru  keymap_bind_keyseq (map, ":Q", &map['q']);
73156164Sru  keymap_bind_keyseq (map, "ZZ", &map['q']);
73256164Sru
73356164Sru  /* Bind members in the ESC map for Info windows. */
73456164Sru  map = (Keymap)info_keymap[ESC].function;
73556164Sru  map[Control ('f')].function = info_show_footnotes;
73656164Sru  map[Control ('g')].function = info_abort_key;
73756164Sru  map[TAB].function = info_move_to_prev_xref;
73893142Sru  map[SPC].function = info_scroll_forward_page_only;
73956164Sru  map[Control ('v')].function = info_scroll_other_window;
74056164Sru  map['<'].function = info_beginning_of_node;
74156164Sru  map['>'].function = info_end_of_node;
74256164Sru  map['/'].function = info_search;
74356164Sru  map['?'].function = info_search_backward;
74456164Sru  map['b'].function = info_beginning_of_node;
74556164Sru  map['d'].function = info_dir_node;
74656164Sru  map['e'].function = info_end_of_node;
74756164Sru  map['f'].function = info_xref_item;
74856164Sru  map['g'].function = info_select_reference_this_line;
74956164Sru  map['h'].function = info_get_info_help_node;
75056164Sru  map['m'].function = info_menu_item;
75156164Sru  map['n'].function = info_search;
75256164Sru  map['N'].function = info_search_backward;
75356164Sru  map['r'].function = isearch_backward;
75456164Sru  map['s'].function = isearch_forward;
75556164Sru  map['t'].function = info_top_node;
75693142Sru  map['v'].function = info_scroll_backward_page_only;
75756164Sru#if defined (NAMED_FUNCTIONS)
75856164Sru  map['x'].function = info_execute_command;
75956164Sru#endif /* NAMED_FUNCTIONS */
76056164Sru  map[DEL].function = info_scroll_other_window_backward;
76156164Sru
76256164Sru  /* Bind members in the Control-X map for Info windows. */
76356164Sru  map = (Keymap)info_keymap[Control ('x')].function;
76456164Sru
76556164Sru  map[Control ('b')].function = list_visited_nodes;
76656164Sru  map[Control ('c')].function = info_quit;
76756164Sru  map[Control ('f')].function = info_view_file;
76856164Sru  map[Control ('g')].function = info_abort_key;
76956164Sru  map[Control ('v')].function = info_view_file;
77056164Sru  map[LFD].function = info_select_reference_this_line;
77156164Sru  map[RET].function = info_select_reference_this_line;
77256164Sru  map['0'].function = info_delete_window;
77356164Sru  map['1'].function = info_keep_one_window;
77456164Sru  map['2'].function = info_split_window;
77556164Sru  map['^'].function = info_grow_window;
77656164Sru  map['b'].function = select_visited_node;
77756164Sru  map['g'].function = info_goto_node;
77856164Sru  map['i'].function = info_index_search;
77956164Sru  map['I'].function = info_goto_invocation_node;
78056164Sru  map['k'].function = info_kill_node;
78156164Sru  map['n'].function = info_next_node;
78256164Sru  map['o'].function = info_next_window;
78356164Sru  map['O'].function = info_goto_invocation_node;
78456164Sru  map['p'].function = info_prev_node;
78556164Sru  map['r'].function = info_xref_item;
78656164Sru  map['t'].function = info_tile_windows;
78756164Sru  map['u'].function = info_up_node;
78856164Sru  map['w'].function = info_toggle_wrap;
78956164Sru  map[','].function = info_next_index_match;
79056164Sru  keymap_bind_keyseq (info_keymap, ":e", &map[Control ('v')]);
79156164Sru
79256164Sru  /* Arrow key bindings for Info windows keymap. */
79356164Sru  map = info_keymap;
79456164Sru  keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
79556164Sru  keymap_bind_keyseq (map, term_ku, &map[Control ('p')]); /* up */
79656164Sru  keymap_bind_keyseq (map, "\033OA", &map[Control ('p')]);
79756164Sru  keymap_bind_keyseq (map, "\033[A", &map[Control ('p')]);
79856164Sru  keymap_bind_keyseq (map, term_kd, &map[Control ('n')]); /* down */
79956164Sru  keymap_bind_keyseq (map, "\033OB", &map[Control ('n')]);
80056164Sru  keymap_bind_keyseq (map, "\033[B", &map[Control ('n')]);
80156164Sru  keymap_bind_keyseq (map, term_kr, &map[Control ('f')]); /* right */
80256164Sru  keymap_bind_keyseq (map, "\033OC", &map[Control ('f')]);
80356164Sru  keymap_bind_keyseq (map, "\033[C", &map[Control ('f')]);
80456164Sru  keymap_bind_keyseq (map, term_kl, &map[Control ('b')]); /* left */
80556164Sru  keymap_bind_keyseq (map, "\033OD", &map[Control ('b')]);
80656164Sru  keymap_bind_keyseq (map, "\033[D", &map[Control ('b')]);
80793142Sru  keymap_bind_keyseq (map, term_kh, &map['b']);	/* home */
80893142Sru  keymap_bind_keyseq (map, term_ke, &map['e']);	/* end */
80956164Sru
81056164Sru  map = (Keymap)info_keymap[ESC].function;
81156164Sru  keymap_bind_keyseq (map, term_kl, &map['b']); /* left */
81256164Sru  keymap_bind_keyseq (map, "\033OA", &map['b']);
81356164Sru  keymap_bind_keyseq (map, "\033[A", &map['b']);
81456164Sru  keymap_bind_keyseq (map, term_kr, &map['f']); /* right */
81556164Sru  keymap_bind_keyseq (map, "\033OB", &map['f']);
81656164Sru  keymap_bind_keyseq (map, "\033[B", &map['f']);
81756164Sru  keymap_bind_keyseq (map, term_kN, &map[Control ('v')]); /* pagedown */
81856164Sru  keymap_bind_keyseq (map, term_kP, &map[DEL]); /* pageup */
81993142Sru  keymap_bind_keyseq (map, term_kD, &map[DEL]);	/* delete */
82056164Sru
82156164Sru  /* The alternative to this definition of a `main map' key in the
82256164Sru     `ESC map' section, is something like:
82356164Sru    keymap_bind_keyseq (map, term_kP, &((KeyMap)map[ESC].function).map['v']);
82456164Sru  */
82556164Sru  keymap_bind_keyseq (info_keymap/*sic*/, term_kP, &map['v']); /* pageup */
82656164Sru}
82756164Sru
82856164Sruvoid
82956164Sruinitialize_info_keymaps ()
83056164Sru{
83156164Sru  if (vi_keys_p)
83256164Sru    initialize_vi_like_keymaps ();
83356164Sru  else
83456164Sru    initialize_emacs_like_keymaps ();
83556164Sru}
83656164Sru
83793142Sru#else /* defined(INFOKEY) */
83893142Sru
83993142Sru/* Make sure that we don't have too many command codes defined. */
84093142Sru
84193142Sru#if A_NCOMMANDS > A_MAX_COMMAND + 1
84293142Sru#error "too many commands defined"
84393142Sru#endif
84493142Sru
84593142Sru/* Initialize the keymaps from the .info keymap file. */
84693142Sru
84793142Sru#define NUL	'\0'
84893142Sru
84993142Srustatic unsigned char default_emacs_like_info_keys[] =
85093142Sru{
85193142Sru	0,	/* suppress-default-keybindings flag */
85293142Sru	TAB, NUL,			A_info_move_to_next_xref,
85393142Sru	LFD, NUL,			A_info_select_reference_this_line,
85493142Sru	RET, NUL,			A_info_select_reference_this_line,
85593142Sru	SPC, NUL,			A_info_scroll_forward,
85693142Sru	CONTROL('a'), NUL,		A_info_beginning_of_line,
85793142Sru	CONTROL('b'), NUL,		A_info_backward_char,
85893142Sru	CONTROL('e'), NUL,		A_info_end_of_line,
85993142Sru	CONTROL('f'), NUL,		A_info_forward_char,
86093142Sru	CONTROL('g'), NUL,		A_info_abort_key,
86193142Sru	CONTROL('h'), NUL,		A_info_get_help_window,
86293142Sru	CONTROL('l'), NUL,		A_info_redraw_display,
86393142Sru	CONTROL('n'), NUL,		A_info_next_line,
86493142Sru	CONTROL('p'), NUL,		A_info_prev_line,
86593142Sru	CONTROL('r'), NUL,		A_isearch_backward,
86693142Sru	CONTROL('s'), NUL,		A_isearch_forward,
86793142Sru	CONTROL('u'), NUL,		A_info_universal_argument,
86893142Sru	CONTROL('v'), NUL,		A_info_scroll_forward_page_only,
86993142Sru	',', NUL,			A_info_next_index_match,
87093142Sru	'/', NUL,			A_info_search,
87193142Sru	'0', NUL,			A_info_last_menu_item,
87293142Sru	'1', NUL,			A_info_menu_digit,
87393142Sru	'2', NUL,			A_info_menu_digit,
87493142Sru	'3', NUL,			A_info_menu_digit,
87593142Sru	'4', NUL,			A_info_menu_digit,
87693142Sru	'5', NUL,			A_info_menu_digit,
87793142Sru	'6', NUL,			A_info_menu_digit,
87893142Sru	'7', NUL,			A_info_menu_digit,
87993142Sru	'8', NUL,			A_info_menu_digit,
88093142Sru	'9', NUL,			A_info_menu_digit,
88193142Sru	'<', NUL,			A_info_first_node,
88293142Sru	'>', NUL,			A_info_last_node,
88393142Sru	'?', NUL,			A_info_get_help_window,
88493142Sru	'[', NUL,			A_info_global_prev_node,
88593142Sru	']', NUL,			A_info_global_next_node,
88693142Sru	'b', NUL,			A_info_beginning_of_node,
88793142Sru	'd', NUL,			A_info_dir_node,
88893142Sru	'e', NUL,			A_info_end_of_node,
88993142Sru	'f', NUL,			A_info_xref_item,
89093142Sru	'g', NUL,			A_info_goto_node,
89193142Sru	'G', NUL,			A_info_menu_sequence,
89293142Sru	'h', NUL,			A_info_get_info_help_node,
89393142Sru	'i', NUL,			A_info_index_search,
89493142Sru	'l', NUL,			A_info_history_node,
89593142Sru	'm', NUL,			A_info_menu_item,
89693142Sru	'n', NUL,			A_info_next_node,
89793142Sru	'O', NUL,			A_info_goto_invocation_node,
89893142Sru	'p', NUL,			A_info_prev_node,
89993142Sru	'q', NUL,			A_info_quit,
90093142Sru	'r', NUL,			A_info_xref_item,
90193142Sru	's', NUL,			A_info_search,
90293142Sru	'S', NUL,			A_info_search_case_sensitively,
90393142Sru	't', NUL,			A_info_top_node,
90493142Sru	'u', NUL,			A_info_up_node,
90593142Sru	DEL, NUL,			A_info_scroll_backward,
90693142Sru	ESC, '0', NUL,			A_info_add_digit_to_numeric_arg,
90793142Sru	ESC, '1', NUL,			A_info_add_digit_to_numeric_arg,
90893142Sru	ESC, '2', NUL,			A_info_add_digit_to_numeric_arg,
90993142Sru	ESC, '3', NUL,			A_info_add_digit_to_numeric_arg,
91093142Sru	ESC, '4', NUL,			A_info_add_digit_to_numeric_arg,
91193142Sru	ESC, '5', NUL,			A_info_add_digit_to_numeric_arg,
91293142Sru	ESC, '6', NUL,			A_info_add_digit_to_numeric_arg,
91393142Sru	ESC, '7', NUL,			A_info_add_digit_to_numeric_arg,
91493142Sru	ESC, '8', NUL,			A_info_add_digit_to_numeric_arg,
91593142Sru	ESC, '9', NUL,			A_info_add_digit_to_numeric_arg,
91693142Sru	ESC, '-', NUL,			A_info_add_digit_to_numeric_arg,
91793142Sru	ESC, CONTROL('f'), NUL,		A_info_show_footnotes,
91893142Sru	ESC, CONTROL('g'), NUL,		A_info_abort_key,
91993142Sru	ESC, TAB, NUL,			A_info_move_to_prev_xref,
92093142Sru	ESC, CONTROL('v'), NUL,		A_info_scroll_other_window,
92193142Sru	ESC, '<', NUL,			A_info_beginning_of_node,
92293142Sru	ESC, '>', NUL,			A_info_end_of_node,
92393142Sru	ESC, 'b', NUL,			A_info_backward_word,
92493142Sru	ESC, 'f', NUL,			A_info_forward_word,
92593142Sru	ESC, 'r', NUL,			A_info_move_to_window_line,
92693142Sru	ESC, 'v', NUL,			A_info_scroll_backward_page_only,
92793142Sru	Meta('0'), NUL,			A_info_add_digit_to_numeric_arg,
92893142Sru	Meta('1'), NUL,			A_info_add_digit_to_numeric_arg,
92993142Sru	Meta('2'), NUL,			A_info_add_digit_to_numeric_arg,
93093142Sru	Meta('3'), NUL,			A_info_add_digit_to_numeric_arg,
93193142Sru	Meta('4'), NUL,			A_info_add_digit_to_numeric_arg,
93293142Sru	Meta('5'), NUL,			A_info_add_digit_to_numeric_arg,
93393142Sru	Meta('6'), NUL,			A_info_add_digit_to_numeric_arg,
93493142Sru	Meta('7'), NUL,			A_info_add_digit_to_numeric_arg,
93593142Sru	Meta('8'), NUL,			A_info_add_digit_to_numeric_arg,
93693142Sru	Meta('9'), NUL,			A_info_add_digit_to_numeric_arg,
93793142Sru	Meta('-'), NUL,			A_info_add_digit_to_numeric_arg,
93893142Sru	Meta(CONTROL('f')), NUL,	A_info_show_footnotes,
93993142Sru	Meta(CONTROL('g')), NUL,	A_info_abort_key,
94093142Sru	Meta(TAB), NUL,			A_info_move_to_prev_xref,
94193142Sru	Meta(CONTROL('v')), NUL,	A_info_scroll_other_window,
94293142Sru	Meta('<'), NUL,			A_info_beginning_of_node,
94393142Sru	Meta('>'), NUL,			A_info_end_of_node,
94493142Sru	Meta('b'), NUL,			A_info_backward_word,
94593142Sru	Meta('f'), NUL,			A_info_forward_word,
94693142Sru	Meta('r'), NUL,			A_info_move_to_window_line,
94793142Sru	Meta('v'), NUL,			A_info_scroll_backward_page_only,
94893142Sru#if defined (NAMED_FUNCTIONS)
94993142Sru	ESC, 'x', NUL,			A_info_execute_command,
95093142Sru	Meta('x'), NUL,			A_info_execute_command,
95193142Sru#endif /* NAMED_FUNCTIONS */
95293142Sru
95393142Sru	CONTROL('x'), CONTROL('b'), NUL,	A_list_visited_nodes,
95493142Sru	CONTROL('x'), CONTROL('c'), NUL,	A_info_quit,
95593142Sru	CONTROL('x'), CONTROL('f'), NUL,	A_info_view_file,
95693142Sru	CONTROL('x'), CONTROL('g'), NUL,	A_info_abort_key,
95793142Sru	CONTROL('x'), CONTROL('v'), NUL,	A_info_view_file,
95893142Sru	CONTROL('x'), '0', NUL,		A_info_delete_window,
95993142Sru	CONTROL('x'), '1', NUL,		A_info_keep_one_window,
96093142Sru	CONTROL('x'), '2', NUL,		A_info_split_window,
96193142Sru	CONTROL('x'), '^', NUL,		A_info_grow_window,
96293142Sru	CONTROL('x'), 'b', NUL,		A_select_visited_node,
96393142Sru	CONTROL('x'), 'k', NUL,		A_info_kill_node,
96493142Sru	CONTROL('x'), 'n', NUL,		A_info_search_next,
96593142Sru	CONTROL('x'), 'N', NUL,		A_info_search_previous,
96693142Sru	CONTROL('x'), 'o', NUL,		A_info_next_window,
96793142Sru	CONTROL('x'), 't', NUL,		A_info_tile_windows,
96893142Sru	CONTROL('x'), 'w', NUL,		A_info_toggle_wrap,
96993142Sru
97093142Sru/*	Arrow key bindings for info keymaps.  It seems that some
97193142Sru	terminals do not match their termcap entries, so it's best to just
97293142Sru	define everything with both of the usual prefixes.  */
97393142Sru
97493142Sru	SK_ESCAPE, SK_PAGE_UP, NUL,		A_info_scroll_backward_page_only,
97593142Sru	SK_ESCAPE, SK_PAGE_DOWN, NUL,		A_info_scroll_forward_page_only,
97693142Sru	SK_ESCAPE, SK_UP_ARROW, NUL,		A_info_prev_line,
97793142Sru	'\033', 'O', 'A', NUL,			A_info_prev_line,
97893142Sru	'\033', '[', 'A', NUL,			A_info_prev_line,
97993142Sru	SK_ESCAPE, SK_DOWN_ARROW, NUL,		A_info_next_line,
98093142Sru	'\033', 'O', 'B', NUL,			A_info_next_line,
98193142Sru	'\033', '[', 'B', NUL,			A_info_next_line,
98293142Sru	SK_ESCAPE, SK_RIGHT_ARROW, NUL,		A_info_forward_char,
98393142Sru	'\033', 'O', 'C', NUL,			A_info_forward_char,
98493142Sru	'\033', '[', 'C', NUL,			A_info_forward_char,
98593142Sru	SK_ESCAPE, SK_LEFT_ARROW, NUL,		A_info_backward_char,
98693142Sru	'\033', 'O', 'D', NUL,			A_info_backward_char,
98793142Sru	'\033', '[', 'D', NUL,			A_info_backward_char,
98893142Sru	SK_ESCAPE, SK_HOME, NUL,		A_info_beginning_of_node,
98993142Sru	SK_ESCAPE, SK_END, NUL,			A_info_end_of_node,
99093142Sru	SK_ESCAPE, SK_DELETE, NUL,		A_info_scroll_backward,
99193142Sru
99293142Sru	ESC, SK_ESCAPE, SK_PAGE_UP, NUL,	A_info_scroll_other_window_backward,
99393142Sru	ESC, SK_ESCAPE, SK_PAGE_DOWN, NUL,	A_info_scroll_other_window,
99493142Sru	ESC, SK_ESCAPE, SK_UP_ARROW, NUL,	A_info_prev_line,
99593142Sru	ESC, '\033', 'O', 'A', NUL,		A_info_prev_line,
99693142Sru	ESC, '\033', '[', 'A', NUL,		A_info_prev_line,
99793142Sru	ESC, SK_ESCAPE, SK_DOWN_ARROW, NUL,	A_info_next_line,
99893142Sru	ESC, '\033', 'O', 'B', NUL,		A_info_next_line,
99993142Sru	ESC, '\033', '[', 'B', NUL,		A_info_next_line,
100093142Sru	ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL,	A_info_forward_word,
100193142Sru	ESC, '\033', 'O', 'C', NUL,		A_info_forward_word,
100293142Sru	ESC, '\033', '[', 'C', NUL,		A_info_forward_word,
100393142Sru	ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL,	A_info_backward_word,
100493142Sru	ESC, '\033', 'O', 'D', NUL,		A_info_backward_word,
100593142Sru	ESC, '\033', '[', 'D', NUL,		A_info_backward_word,
100693142Sru};
100793142Sru
100893142Srustatic unsigned char default_emacs_like_ea_keys[] =
100993142Sru{
101093142Sru	0,	/* suppress-default-keybindings flag */
101193142Sru	ESC, '0', NUL,			A_info_add_digit_to_numeric_arg,
101293142Sru	ESC, '1', NUL,			A_info_add_digit_to_numeric_arg,
101393142Sru	ESC, '2', NUL,			A_info_add_digit_to_numeric_arg,
101493142Sru	ESC, '3', NUL,			A_info_add_digit_to_numeric_arg,
101593142Sru	ESC, '4', NUL,			A_info_add_digit_to_numeric_arg,
101693142Sru	ESC, '5', NUL,			A_info_add_digit_to_numeric_arg,
101793142Sru	ESC, '6', NUL,			A_info_add_digit_to_numeric_arg,
101893142Sru	ESC, '7', NUL,			A_info_add_digit_to_numeric_arg,
101993142Sru	ESC, '8', NUL,			A_info_add_digit_to_numeric_arg,
102093142Sru	ESC, '9', NUL,			A_info_add_digit_to_numeric_arg,
102193142Sru	ESC, '-', NUL,			A_info_add_digit_to_numeric_arg,
102293142Sru	Meta('0'), NUL,			A_info_add_digit_to_numeric_arg,
102393142Sru	Meta('1'), NUL,			A_info_add_digit_to_numeric_arg,
102493142Sru	Meta('2'), NUL,			A_info_add_digit_to_numeric_arg,
102593142Sru	Meta('3'), NUL,			A_info_add_digit_to_numeric_arg,
102693142Sru	Meta('4'), NUL,			A_info_add_digit_to_numeric_arg,
102793142Sru	Meta('5'), NUL,			A_info_add_digit_to_numeric_arg,
102893142Sru	Meta('6'), NUL,			A_info_add_digit_to_numeric_arg,
102993142Sru	Meta('7'), NUL,			A_info_add_digit_to_numeric_arg,
103093142Sru	Meta('8'), NUL,			A_info_add_digit_to_numeric_arg,
103193142Sru	Meta('9'), NUL,			A_info_add_digit_to_numeric_arg,
103293142Sru	Meta('-'), NUL,			A_info_add_digit_to_numeric_arg,
103393142Sru	ESC, CONTROL('g'), NUL,		A_ea_abort,
103493142Sru	ESC, CONTROL('v'), NUL,		A_ea_scroll_completions_window,
103593142Sru	ESC, 'b', NUL,			A_ea_backward_word,
103693142Sru	ESC, 'd', NUL,			A_ea_kill_word,
103793142Sru	ESC, 'f', NUL,			A_ea_forward_word,
103893142Sru	ESC, 'y', NUL,			A_ea_yank_pop,
103993142Sru	ESC, '?', NUL,			A_ea_possible_completions,
104093142Sru	ESC, TAB, NUL,			A_ea_tab_insert,
104193142Sru	ESC, DEL, NUL,			A_ea_backward_kill_word,
104293142Sru	Meta(CONTROL('g')), NUL,	A_ea_abort,
104393142Sru	Meta(CONTROL('v')), NUL,	A_ea_scroll_completions_window,
104493142Sru	Meta('b'), NUL,			A_ea_backward_word,
104593142Sru	Meta('d'), NUL,			A_ea_kill_word,
104693142Sru	Meta('f'), NUL,			A_ea_forward_word,
104793142Sru	Meta('y'), NUL,			A_ea_yank_pop,
104893142Sru	Meta('?'), NUL,			A_ea_possible_completions,
104993142Sru	Meta(TAB), NUL,			A_ea_tab_insert,
105093142Sru	Meta(DEL), NUL,			A_ea_backward_kill_word,
105193142Sru	CONTROL('a'), NUL,		A_ea_beg_of_line,
105293142Sru	CONTROL('b'), NUL,		A_ea_backward,
105393142Sru	CONTROL('d'), NUL,		A_ea_delete,
105493142Sru	CONTROL('e'), NUL,		A_ea_end_of_line,
105593142Sru	CONTROL('f'), NUL,		A_ea_forward,
105693142Sru	CONTROL('g'), NUL,		A_ea_abort,
105793142Sru	CONTROL('h'), NUL,		A_ea_rubout,
105893142Sru/*	CONTROL('k') */
105993142Sru	SK_ESCAPE, SK_LITERAL, NUL,	A_ea_kill_line,
106093142Sru	CONTROL('l'), NUL,		A_info_redraw_display,
106193142Sru	CONTROL('q'), NUL,		A_ea_quoted_insert,
106293142Sru	CONTROL('t'), NUL,		A_ea_transpose_chars,
106393142Sru	CONTROL('u'), NUL,		A_info_universal_argument,
106493142Sru	CONTROL('y'), NUL,		A_ea_yank,
106593142Sru	LFD, NUL,			A_ea_newline,
106693142Sru	RET, NUL,			A_ea_newline,
106793142Sru	SPC, NUL,			A_ea_complete,
106893142Sru	TAB, NUL,			A_ea_complete,
106993142Sru	'?', NUL,			A_ea_possible_completions,
107093142Sru#ifdef __MSDOS__
107193142Sru        /* PC users will lynch me if I don't give them their usual DEL
107293142Sru	   effect...  */
107393142Sru	DEL, NUL,			A_ea_delete,
107493142Sru#else
107593142Sru	DEL, NUL,			A_ea_rubout,
107693142Sru#endif
107793142Sru#if defined (NAMED_FUNCTIONS)
107893142Sru  /* 	ESC, 'x', NUL,			A_info_execute_command, */
107993142Sru  /* 	Meta('x'), NUL,			A_info_execute_command, */
108093142Sru#endif /* NAMED_FUNCTIONS */
108193142Sru	CONTROL('x'), 'o', NUL,		A_info_next_window,
108293142Sru  	CONTROL('x'), DEL, NUL,		A_ea_backward_kill_line,
108393142Sru
108493142Sru/*	Arrow key bindings for echo area keymaps.  It seems that some
108593142Sru	terminals do not match their termcap entries, so it's best to just
108693142Sru	define everything with both of the usual prefixes.  */
108793142Sru
108893142Sru	SK_ESCAPE, SK_RIGHT_ARROW, NUL,		A_ea_forward,
108993142Sru	'\033', 'O', 'C', NUL,			A_ea_forward,
109093142Sru	'\033', '[', 'C', NUL,			A_ea_forward,
109193142Sru	SK_ESCAPE, SK_LEFT_ARROW, NUL,		A_ea_backward,
109293142Sru	'\033', 'O', 'D', NUL,			A_ea_backward,
109393142Sru	'\033', '[', 'D', NUL,			A_ea_backward,
109493142Sru	ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL,	A_ea_forward_word,
109593142Sru	ESC, '\033', 'O', 'C', NUL,		A_ea_forward_word,
109693142Sru	ESC, '\033', '[', 'C', NUL,		A_ea_forward_word,
109793142Sru	ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL,	A_ea_backward_word,
109893142Sru	ESC, '\033', 'O', 'D', NUL,		A_ea_backward_word,
109993142Sru	ESC, '\033', '[', 'D', NUL,		A_ea_backward_word,
110093142Sru#ifdef __MSDOS__
110193142Sru	SK_ESCAPE, SK_DELETE, NUL,		A_ea_delete,
110293142Sru#else
110393142Sru	SK_ESCAPE, SK_DELETE, NUL,		A_ea_rubout,
110493142Sru#endif
110593142Sru	SK_ESCAPE, SK_HOME, NUL,		A_ea_beg_of_line,
110693142Sru	SK_ESCAPE, SK_END, NUL,			A_ea_end_of_line,
110793142Sru	ESC, SK_ESCAPE, SK_DELETE, NUL,		A_ea_backward_kill_word,
110893142Sru	CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
110993142Sru};
111093142Sru
111193142Srustatic unsigned char default_vi_like_info_keys[] =
111293142Sru{
111393142Sru	0,	/* suppress-default-keybindings flag */
111493142Sru	'0', NUL,			A_info_add_digit_to_numeric_arg,
111593142Sru	'1', NUL,			A_info_add_digit_to_numeric_arg,
111693142Sru	'2', NUL,			A_info_add_digit_to_numeric_arg,
111793142Sru	'3', NUL,			A_info_add_digit_to_numeric_arg,
111893142Sru	'4', NUL,			A_info_add_digit_to_numeric_arg,
111993142Sru	'5', NUL,			A_info_add_digit_to_numeric_arg,
112093142Sru	'6', NUL,			A_info_add_digit_to_numeric_arg,
112193142Sru	'7', NUL,			A_info_add_digit_to_numeric_arg,
112293142Sru	'8', NUL,			A_info_add_digit_to_numeric_arg,
112393142Sru	'9', NUL,			A_info_add_digit_to_numeric_arg,
112493142Sru	'-', NUL,			A_info_add_digit_to_numeric_arg,
112593142Sru	TAB, NUL,			A_info_move_to_next_xref,
112693142Sru	LFD, NUL,			A_info_down_line,
112793142Sru	RET, NUL,			A_info_down_line,
112893142Sru	SPC, NUL,			A_info_scroll_forward,
112993142Sru	CONTROL('a'), NUL,		A_info_beginning_of_line,
113093142Sru	CONTROL('b'), NUL,		A_info_scroll_backward_page_only,
113193142Sru	CONTROL('d'), NUL,		A_info_scroll_half_screen_down,
113293142Sru	CONTROL('e'), NUL,		A_info_down_line,
113393142Sru	CONTROL('f'), NUL,		A_info_scroll_forward_page_only,
113493142Sru	CONTROL('g'), NUL,		A_info_abort_key,
113593142Sru	CONTROL('k'), NUL,		A_info_up_line,
113693142Sru	CONTROL('l'), NUL,		A_info_redraw_display,
113793142Sru	CONTROL('n'), NUL,		A_info_down_line,
113893142Sru	CONTROL('p'), NUL,		A_info_up_line,
113993142Sru	CONTROL('r'), NUL,		A_info_redraw_display,
114093142Sru	CONTROL('s'), NUL,		A_isearch_forward,
114193142Sru	CONTROL('u'), NUL,		A_info_scroll_half_screen_up,
114293142Sru	CONTROL('v'), NUL,		A_info_scroll_forward_page_only,
114393142Sru	CONTROL('y'), NUL,		A_info_up_line,
114493142Sru	',', NUL,			A_info_next_index_match,
114593142Sru	'/', NUL,			A_info_search,
114693142Sru	ESC, '0', NUL,			A_info_last_menu_item,
114793142Sru	ESC, '1', NUL,			A_info_menu_digit,
114893142Sru	ESC, '2', NUL,			A_info_menu_digit,
114993142Sru	ESC, '3', NUL,			A_info_menu_digit,
115093142Sru	ESC, '4', NUL,			A_info_menu_digit,
115193142Sru	ESC, '5', NUL,			A_info_menu_digit,
115293142Sru	ESC, '6', NUL,			A_info_menu_digit,
115393142Sru	ESC, '7', NUL,			A_info_menu_digit,
115493142Sru	ESC, '8', NUL,			A_info_menu_digit,
115593142Sru	ESC, '9', NUL,			A_info_menu_digit,
115693142Sru	Meta('0'), NUL,			A_info_last_menu_item,
115793142Sru	Meta('1'), NUL,			A_info_menu_digit,
115893142Sru	Meta('2'), NUL,			A_info_menu_digit,
115993142Sru	Meta('3'), NUL,			A_info_menu_digit,
116093142Sru	Meta('4'), NUL,			A_info_menu_digit,
116193142Sru	Meta('5'), NUL,			A_info_menu_digit,
116293142Sru	Meta('6'), NUL,			A_info_menu_digit,
116393142Sru	Meta('7'), NUL,			A_info_menu_digit,
116493142Sru	Meta('8'), NUL,			A_info_menu_digit,
116593142Sru	Meta('9'), NUL,			A_info_menu_digit,
116693142Sru	'<', NUL,			A_info_first_node,
116793142Sru	'>', NUL,			A_info_last_node,
116893142Sru	'?', NUL,			A_info_search_backward,
116993142Sru	'[', NUL,			A_info_global_prev_node,
117093142Sru	']', NUL,			A_info_global_next_node,
117193142Sru	'\'', NUL,			A_info_history_node,
117293142Sru	'b', NUL,			A_info_scroll_backward,
117393142Sru	'd', NUL,			A_info_scroll_half_screen_down,
117493142Sru	'e', NUL,			A_info_down_line,
117593142Sru	'E', NUL,			A_info_view_file,
117693142Sru	':', 'e', NUL,			A_info_view_file,
117793142Sru	'f', NUL,			A_info_scroll_forward_page_only,
117893142Sru	'F', NUL,			A_info_scroll_forward_page_only,
117993142Sru	'g', NUL,			A_info_first_node,
118093142Sru	'G', NUL,			A_info_last_node,
118193142Sru	'h', NUL,			A_info_get_help_window,
118293142Sru	'H', NUL,			A_info_get_help_window,
118393142Sru	'i', NUL,			A_info_index_search,
118493142Sru	'I', NUL,			A_info_goto_invocation_node,
1185146520Sru	'j', NUL,			A_info_next_line,
1186146520Sru	'k', NUL,			A_info_prev_line,
118793142Sru	'l', NUL,			A_info_history_node,
118893142Sru	'm', NUL,			A_info_menu_item,
118993142Sru	'n', NUL,			A_info_search_next,
119093142Sru	'N', NUL,			A_info_search_previous,
119193142Sru	'O', NUL,			A_info_goto_invocation_node,
119293142Sru	'p', NUL,			A_info_prev_node,
119393142Sru	'q', NUL,			A_info_quit,
119493142Sru	'Q', NUL,			A_info_quit,
119593142Sru	':', 'q', NUL,			A_info_quit,
119693142Sru	':', 'Q', NUL,			A_info_quit,
119793142Sru	'Z', 'Z', NUL,			A_info_quit,
119893142Sru	'r', NUL,			A_info_redraw_display,
119993142Sru	'R', NUL,			A_info_redraw_display,
120093142Sru	's', NUL,			A_info_search,
120193142Sru	'S', NUL,			A_info_search_case_sensitively,
120293142Sru	't', NUL,			A_info_top_node,
120393142Sru	'u', NUL,			A_info_scroll_half_screen_up,
120493142Sru	'w', NUL,			A_info_scroll_backward_page_only_set_window,
120593142Sru	'y', NUL,			A_info_up_line,
120693142Sru	'z', NUL,			A_info_scroll_forward_page_only_set_window,
120793142Sru	DEL, NUL,			A_info_scroll_backward,
120893142Sru	ESC, CONTROL('f'), NUL,		A_info_show_footnotes,
120993142Sru	ESC, CONTROL('g'), NUL,		A_info_abort_key,
121093142Sru	ESC, TAB, NUL,			A_info_move_to_prev_xref,
121193142Sru	ESC, SPC, NUL,			A_info_scroll_forward_page_only,
121293142Sru	ESC, CONTROL('v'), NUL,		A_info_scroll_other_window,
121393142Sru	ESC, '<', NUL,			A_info_beginning_of_node,
121493142Sru	ESC, '>', NUL,			A_info_end_of_node,
121593142Sru	ESC, '/', NUL,			A_info_search,
121693142Sru	ESC, '?', NUL,			A_info_search_backward,
121793142Sru	ESC, 'b', NUL,			A_info_beginning_of_node,
121893142Sru	ESC, 'd', NUL,			A_info_dir_node,
121993142Sru	ESC, 'e', NUL,			A_info_end_of_node,
122093142Sru	ESC, 'f', NUL,			A_info_xref_item,
122193142Sru	ESC, 'g', NUL,			A_info_select_reference_this_line,
122293142Sru	ESC, 'h', NUL,			A_info_get_info_help_node,
122393142Sru	ESC, 'm', NUL,			A_info_menu_item,
122493142Sru	ESC, 'n', NUL,			A_info_search,
122593142Sru	ESC, 'N', NUL,			A_info_search_backward,
122693142Sru	ESC, 'r', NUL,			A_isearch_backward,
122793142Sru	ESC, 's', NUL,			A_isearch_forward,
122893142Sru	ESC, 't', NUL,			A_info_top_node,
122993142Sru	ESC, 'v', NUL,			A_info_scroll_backward_page_only,
123093142Sru#if defined (NAMED_FUNCTIONS)
123193142Sru	ESC, 'x', NUL,			A_info_execute_command,
123293142Sru	Meta('x'), NUL,			A_info_execute_command,
123393142Sru#endif /* NAMED_FUNCTIONS */
123493142Sru	ESC, DEL, NUL,			A_info_scroll_other_window_backward,
123593142Sru	CONTROL('x'), CONTROL('b'), NUL,	A_list_visited_nodes,
123693142Sru	CONTROL('x'), CONTROL('c'), NUL,	A_info_quit,
123793142Sru	CONTROL('x'), CONTROL('f'), NUL,	A_info_view_file,
123893142Sru	CONTROL('x'), CONTROL('g'), NUL,	A_info_abort_key,
123993142Sru	CONTROL('x'), CONTROL('v'), NUL,	A_info_view_file,
124093142Sru	CONTROL('x'), LFD, NUL,		A_info_select_reference_this_line,
124193142Sru	CONTROL('x'), RET, NUL,		A_info_select_reference_this_line,
124293142Sru	CONTROL('x'), '0', NUL,		A_info_delete_window,
124393142Sru	CONTROL('x'), '1', NUL,		A_info_keep_one_window,
124493142Sru	CONTROL('x'), '2', NUL,		A_info_split_window,
124593142Sru	CONTROL('x'), '^', NUL,		A_info_grow_window,
124693142Sru	CONTROL('x'), 'b', NUL,		A_select_visited_node,
124793142Sru	CONTROL('x'), 'g', NUL,		A_info_goto_node,
124893142Sru	CONTROL('x'), 'i', NUL,		A_info_index_search,
124993142Sru	CONTROL('x'), 'I', NUL,		A_info_goto_invocation_node,
125093142Sru	CONTROL('x'), 'k', NUL,		A_info_kill_node,
125193142Sru	CONTROL('x'), 'n', NUL,		A_info_next_node,
125293142Sru	CONTROL('x'), 'o', NUL,		A_info_next_window,
125393142Sru	CONTROL('x'), 'O', NUL,		A_info_goto_invocation_node,
125493142Sru	CONTROL('x'), 'p', NUL,		A_info_prev_node,
125593142Sru	CONTROL('x'), 'r', NUL,		A_info_xref_item,
125693142Sru	CONTROL('x'), 't', NUL,		A_info_tile_windows,
125793142Sru	CONTROL('x'), 'u', NUL,		A_info_up_node,
125893142Sru	CONTROL('x'), 'w', NUL,		A_info_toggle_wrap,
125993142Sru	CONTROL('x'), ',', NUL,		A_info_next_index_match,
126093142Sru
126193142Sru/*	Arrow key bindings for info keymaps.  It seems that some
126293142Sru	terminals do not match their termcap entries, so it's best to just
126393142Sru	define everything with both of the usual prefixes.  */
126493142Sru
126593142Sru	SK_ESCAPE, SK_PAGE_UP, NUL,		A_info_scroll_backward_page_only,
126693142Sru	SK_ESCAPE, SK_PAGE_DOWN, NUL,		A_info_scroll_forward_page_only,
126793142Sru	SK_ESCAPE, SK_UP_ARROW, NUL,		A_info_up_line,
126893142Sru	'\033', 'O', 'A', NUL,			A_info_up_line,
126993142Sru	'\033', '[', 'A', NUL,			A_info_up_line,
127093142Sru	SK_ESCAPE, SK_DOWN_ARROW, NUL,		A_info_down_line,
127193142Sru	'\033', 'O', 'B', NUL,			A_info_down_line,
127293142Sru	'\033', '[', 'B', NUL,			A_info_down_line,
127393142Sru	SK_ESCAPE, SK_RIGHT_ARROW, NUL,		A_info_scroll_forward_page_only,
127493142Sru	'\033', 'O', 'C', NUL,			A_info_scroll_forward_page_only,
127593142Sru	'\033', '[', 'C', NUL,			A_info_scroll_forward_page_only,
127693142Sru	SK_ESCAPE, SK_LEFT_ARROW, NUL,		A_info_scroll_backward_page_only,
127793142Sru	'\033', 'O', 'D', NUL,			A_info_scroll_backward_page_only,
127893142Sru	'\033', '[', 'D', NUL,			A_info_scroll_backward_page_only,
127993142Sru	SK_ESCAPE, SK_HOME, NUL,		A_info_beginning_of_node,
128093142Sru	SK_ESCAPE, SK_END, NUL,			A_info_end_of_node,
128193142Sru	ESC, SK_ESCAPE, SK_PAGE_DOWN, NUL,	A_info_scroll_other_window,
128293142Sru	ESC, SK_ESCAPE, SK_PAGE_UP, NUL,	A_info_scroll_other_window_backward,
128393142Sru	ESC, SK_ESCAPE, SK_DELETE, NUL,		A_info_scroll_other_window_backward,
128493142Sru	ESC, SK_ESCAPE, SK_UP_ARROW, NUL,	A_info_prev_node,
128593142Sru	ESC, '\033', 'O', 'A', NUL,		A_info_prev_node,
128693142Sru	ESC, '\033', '[', 'A', NUL,		A_info_prev_node,
128793142Sru	ESC, SK_ESCAPE, SK_DOWN_ARROW, NUL,	A_info_next_node,
128893142Sru	ESC, '\033', 'O', 'B', NUL,		A_info_next_node,
128993142Sru	ESC, '\033', '[', 'B', NUL,		A_info_next_node,
129093142Sru	ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL,	A_info_xref_item,
129193142Sru	ESC, '\033', 'O', 'C', NUL,		A_info_xref_item,
129293142Sru	ESC, '\033', '[', 'C', NUL,		A_info_xref_item,
129393142Sru	ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL,	A_info_beginning_of_node,
129493142Sru	ESC, '\033', 'O', 'D', NUL,		A_info_beginning_of_node,
129593142Sru	ESC, '\033', '[', 'D', NUL,		A_info_beginning_of_node,
129693142Sru	CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
129793142Sru};
129893142Sru
129993142Srustatic unsigned char default_vi_like_ea_keys[] =
130093142Sru{
130193142Sru	0,	/* suppress-default-keybindings flag */
130293142Sru	ESC, '1', NUL,			A_info_add_digit_to_numeric_arg,
130393142Sru	ESC, '2', NUL,			A_info_add_digit_to_numeric_arg,
130493142Sru	ESC, '3', NUL,			A_info_add_digit_to_numeric_arg,
130593142Sru	ESC, '4', NUL,			A_info_add_digit_to_numeric_arg,
130693142Sru	ESC, '5', NUL,			A_info_add_digit_to_numeric_arg,
130793142Sru	ESC, '6', NUL,			A_info_add_digit_to_numeric_arg,
130893142Sru	ESC, '7', NUL,			A_info_add_digit_to_numeric_arg,
130993142Sru	ESC, '8', NUL,			A_info_add_digit_to_numeric_arg,
131093142Sru	ESC, '9', NUL,			A_info_add_digit_to_numeric_arg,
131193142Sru	ESC, '-', NUL,			A_info_add_digit_to_numeric_arg,
131293142Sru	Meta('1'), NUL,			A_info_add_digit_to_numeric_arg,
131393142Sru	Meta('2'), NUL,			A_info_add_digit_to_numeric_arg,
131493142Sru	Meta('3'), NUL,			A_info_add_digit_to_numeric_arg,
131593142Sru	Meta('4'), NUL,			A_info_add_digit_to_numeric_arg,
131693142Sru	Meta('5'), NUL,			A_info_add_digit_to_numeric_arg,
131793142Sru	Meta('6'), NUL,			A_info_add_digit_to_numeric_arg,
131893142Sru	Meta('7'), NUL,			A_info_add_digit_to_numeric_arg,
131993142Sru	Meta('8'), NUL,			A_info_add_digit_to_numeric_arg,
132093142Sru	Meta('9'), NUL,			A_info_add_digit_to_numeric_arg,
132193142Sru	Meta('-'), NUL,			A_info_add_digit_to_numeric_arg,
132293142Sru	ESC, CONTROL('g'), NUL,		A_ea_abort,
132393142Sru	ESC, CONTROL('h'), NUL,		A_ea_backward_kill_word,
132493142Sru	ESC, CONTROL('v'), NUL,		A_ea_scroll_completions_window,
132593142Sru	ESC, '0', NUL,			A_ea_beg_of_line,
132693142Sru	ESC, '$', NUL,			A_ea_end_of_line,
132793142Sru	ESC, 'b', NUL,			A_ea_backward_word,
132893142Sru	ESC, 'd', NUL,			A_ea_kill_word,
132993142Sru	ESC, 'f', NUL,			A_ea_forward_word,
133093142Sru	ESC, 'h', NUL,			A_ea_forward,
133193142Sru	ESC, 'l', NUL,			A_ea_backward,
133293142Sru	ESC, 'w', NUL,			A_ea_forward_word,
133393142Sru	ESC, 'x', NUL,			A_ea_delete,
133493142Sru	ESC, 'X', NUL,			A_ea_kill_word,
133593142Sru	ESC, 'y', NUL,			A_ea_yank_pop,
133693142Sru	ESC, '?', NUL,			A_ea_possible_completions,
133793142Sru	ESC, TAB, NUL,			A_ea_tab_insert,
133893142Sru	ESC, DEL, NUL,			A_ea_kill_word,
133993142Sru	Meta(CONTROL('g')), NUL,	A_ea_abort,
134093142Sru	Meta(CONTROL('h')), NUL,	A_ea_backward_kill_word,
134193142Sru	Meta(CONTROL('v')), NUL,	A_ea_scroll_completions_window,
134293142Sru	Meta('0'), NUL,			A_ea_beg_of_line,
134393142Sru	Meta('$'), NUL,			A_ea_end_of_line,
134493142Sru	Meta('b'), NUL,			A_ea_backward_word,
134593142Sru	Meta('d'), NUL,			A_ea_kill_word,
134693142Sru	Meta('f'), NUL,			A_ea_forward_word,
134793142Sru	Meta('h'), NUL,			A_ea_forward,
134893142Sru	Meta('l'), NUL,			A_ea_backward,
134993142Sru	Meta('w'), NUL,			A_ea_forward_word,
135093142Sru	Meta('x'), NUL,			A_ea_delete,
135193142Sru	Meta('X'), NUL,			A_ea_kill_word,
135293142Sru	Meta('y'), NUL,			A_ea_yank_pop,
135393142Sru	Meta('?'), NUL,			A_ea_possible_completions,
135493142Sru	Meta(TAB), NUL,			A_ea_tab_insert,
135593142Sru	Meta(DEL), NUL,			A_ea_kill_word,
135693142Sru	CONTROL('a'), NUL,		A_ea_beg_of_line,
135793142Sru	CONTROL('b'), NUL,		A_ea_backward,
135893142Sru	CONTROL('d'), NUL,		A_ea_delete,
135993142Sru	CONTROL('e'), NUL,		A_ea_end_of_line,
136093142Sru	CONTROL('f'), NUL,		A_ea_forward,
136193142Sru	CONTROL('g'), NUL,		A_ea_abort,
136293142Sru	CONTROL('h'), NUL,		A_ea_rubout,
136393142Sru/*	CONTROL('k') */
136493142Sru	SK_ESCAPE, SK_LITERAL, NUL,	A_ea_kill_line,
136593142Sru	CONTROL('l'), NUL,		A_info_redraw_display,
136693142Sru	CONTROL('q'), NUL,		A_ea_quoted_insert,
136793142Sru	CONTROL('t'), NUL,		A_ea_transpose_chars,
136893142Sru	CONTROL('u'), NUL,		A_ea_abort,
136993142Sru	CONTROL('v'), NUL,		A_ea_quoted_insert,
137093142Sru	CONTROL('y'), NUL,		A_ea_yank,
137193142Sru	LFD, NUL,			A_ea_newline,
137293142Sru	RET, NUL,			A_ea_newline,
137393142Sru	SPC, NUL,			A_ea_complete,
137493142Sru	TAB, NUL,			A_ea_complete,
137593142Sru	'?', NUL,			A_ea_possible_completions,
137693142Sru#ifdef __MSDOS__
137793142Sru        /* PC users will lynch me if I don't give them their usual DEL
137893142Sru	   effect...  */
137993142Sru	DEL, NUL,			A_ea_delete,
138093142Sru#else
138193142Sru	DEL, NUL,			A_ea_rubout,
138293142Sru#endif
138393142Sru	CONTROL('x'), 'o', NUL,		A_info_next_window,
138493142Sru  	CONTROL('x'), DEL, NUL,		A_ea_backward_kill_line,
138593142Sru
138693142Sru  /* Arrow key bindings for echo area keymaps.  It seems that some
138793142Sru     terminals do not match their termcap entries, so it's best to just
138893142Sru     define everything with both of the usual prefixes.  */
138993142Sru
139093142Sru	SK_ESCAPE, SK_RIGHT_ARROW, NUL,		A_ea_forward,
139193142Sru	'\033', 'O', 'C', NUL,			A_ea_forward,
139293142Sru	'\033', '[', 'C', NUL,			A_ea_forward,
139393142Sru	SK_ESCAPE, SK_LEFT_ARROW, NUL,		A_ea_backward,
139493142Sru	'\033', 'O', 'D', NUL,			A_ea_backward,
139593142Sru	'\033', '[', 'D', NUL,			A_ea_backward,
139693142Sru	SK_ESCAPE, SK_HOME, NUL,		A_ea_beg_of_line,
139793142Sru	SK_ESCAPE, SK_END, NUL,			A_ea_end_of_line,
139893142Sru#ifdef __MSDOS__
139993142Sru	SK_ESCAPE, SK_DELETE, NUL,		A_ea_delete,
140093142Sru#else
140193142Sru	SK_DELETE, SK_DELETE, NUL,		A_ea_rubout,
140293142Sru#endif
140393142Sru	ESC, SK_ESCAPE, SK_RIGHT_ARROW, NUL,	A_ea_forward_word,
140493142Sru	ESC, '\033', 'O', 'C', NUL,		A_ea_forward_word,
140593142Sru	ESC, '\033', '[', 'C', NUL,		A_ea_forward_word,
140693142Sru	ESC, SK_ESCAPE, SK_LEFT_ARROW, NUL,	A_ea_backward_word,
140793142Sru	ESC, '\033', 'O', 'D', NUL,		A_ea_backward_word,
140893142Sru	ESC, '\033', '[', 'D', NUL,		A_ea_backward_word,
140993142Sru	ESC, SK_ESCAPE, SK_DELETE, NUL,		A_ea_kill_word,
141093142Sru	CONTROL('x'), SK_ESCAPE, SK_DELETE, NUL,A_ea_backward_kill_line,
141193142Sru};
141293142Sru
141393142Srustatic unsigned char *user_info_keys;
141493142Srustatic unsigned int user_info_keys_len;
141593142Srustatic unsigned char *user_ea_keys;
141693142Srustatic unsigned int user_ea_keys_len;
141793142Srustatic unsigned char *user_vars;
141893142Srustatic unsigned int user_vars_len;
141993142Sru
142093142Sru/*
142193142Sru * Return the size of a file, or 0 if the size can't be determined.
142293142Sru */
142393142Srustatic unsigned long
1424146520Srufilesize(int f)
142593142Sru{
142693142Sru	long pos = lseek(f, 0L, SEEK_CUR);
142793142Sru	long sz = -1L;
142893142Sru	if (pos != -1L)
142993142Sru	{
143093142Sru		sz = lseek(f, 0L, SEEK_END);
143193142Sru		lseek(f, pos, SEEK_SET);
143293142Sru	}
143393142Sru	return sz == -1L ? 0L : sz;
143493142Sru}
143593142Sru
143693142Sru/* Get an integer from a infokey file.
143793142Sru   Integers are stored as two bytes, low order first, in radix INFOKEY_RADIX.
143893142Sru */
143993142Srustatic int
1440146520Srugetint(unsigned char **sp)
144193142Sru{
144293142Sru	int n;
144393142Sru
144493142Sru	if ( !((*sp)[0] < INFOKEY_RADIX && (*sp)[1] < INFOKEY_RADIX) )
144593142Sru		return -1;
144693142Sru	n = (*sp)[0] + (*sp)[1] * INFOKEY_RADIX;
144793142Sru	*sp += 2;
144893142Sru	return n;
144993142Sru}
145093142Sru
145193142Sru
145293142Sru/* Fetch the contents of the standard infokey file "$HOME/.info".  Return
145393142Sru   true if ok, false if not.  */
145493142Srustatic int
1455146520Srufetch_user_maps(void)
145693142Sru{
145793142Sru	char *filename = NULL;
145893142Sru	char *homedir;
145993142Sru	int f;
146093142Sru	unsigned char *buf;
146193142Sru	unsigned long len;
146293142Sru	long nread;
146393142Sru	unsigned char *p;
146493142Sru	int n;
146593142Sru
146693142Sru	/* Find and open file. */
146793142Sru	if ((filename = getenv("INFOKEY")) != NULL)
146893142Sru		filename = xstrdup(filename);
146993142Sru	else if ((homedir = getenv("HOME")) != NULL)
147093142Sru	{
147193142Sru		filename = xmalloc(strlen(homedir) + 2 + strlen(INFOKEY_FILE));
147293142Sru		strcpy(filename, homedir);
147393142Sru		strcat(filename, "/");
147493142Sru		strcat(filename, INFOKEY_FILE);
147593142Sru	}
147693142Sru#ifdef __MSDOS__
147793142Sru	/* Poor baby, she doesn't have a HOME...  */
147893142Sru	else
147993142Sru		filename = xstrdup(INFOKEY_FILE); /* try current directory */
148093142Sru#endif
148193142Sru	if (filename == NULL || (f = open(filename, O_RDONLY)) == (-1))
148293142Sru	{
1483116530Sru		if (filename && errno != ENOENT)
148493142Sru		{
1485146520Sru			info_error(filesys_error_string(filename, errno),
1486146520Sru                            NULL, NULL);
148793142Sru			free(filename);
148893142Sru		}
148993142Sru		return 0;
149093142Sru	}
149193142Sru	SET_BINARY (f);
149293142Sru
149393142Sru	/* Ensure that the file is a reasonable size. */
149493142Sru	len = filesize(f);
149593142Sru	if (len < INFOKEY_NMAGIC + 2 || len > 100 * 1024)
149693142Sru	{
149793142Sru		/* Bad file (a valid file must have at least 9 chars, and
149893142Sru		   more than 100 KB is a problem). */
149993142Sru		if (len < INFOKEY_NMAGIC + 2)
1500146520Sru			info_error((char *) _("Ignoring invalid infokey file `%s' - too small"),
1501146520Sru				   filename, NULL);
150293142Sru		else
1503146520Sru			info_error((char *) _("Ignoring invalid infokey file `%s' - too big"),
1504146520Sru				   filename, NULL);
150593142Sru		close(f);
150693142Sru		free(filename);
150793142Sru		return 0;
150893142Sru	}
150993142Sru
151093142Sru	/* Read the file into a buffer. */
151193142Sru	buf = (unsigned char *)xmalloc((int)len);
151293142Sru	nread = read(f, buf, (unsigned int) len);
151393142Sru	close(f);
1514146520Sru	if ((unsigned int) nread != len)
151593142Sru	{
1516146520Sru		info_error((char *) _("Error reading infokey file `%s' - short read"),
1517146520Sru                    filename, NULL);
151893142Sru		free(buf);
151993142Sru		free(filename);
152093142Sru		return 0;
152193142Sru	}
152293142Sru
152393142Sru	/* Check the header, trailer, and version of the file to increase
152493142Sru	   our confidence that the contents are valid.  */
152593142Sru	if (	buf[0] != INFOKEY_MAGIC_S0
152693142Sru		|| buf[1] != INFOKEY_MAGIC_S1
152793142Sru		|| buf[2] != INFOKEY_MAGIC_S2
152893142Sru		|| buf[3] != INFOKEY_MAGIC_S3
152993142Sru		|| buf[len - 4] != INFOKEY_MAGIC_E0
153093142Sru		|| buf[len - 3] != INFOKEY_MAGIC_E1
153193142Sru		|| buf[len - 2] != INFOKEY_MAGIC_E2
153293142Sru		|| buf[len - 1] != INFOKEY_MAGIC_E3
153393142Sru	)
153493142Sru	{
1535146520Sru		info_error((char *) _("Invalid infokey file `%s' (bad magic numbers) -- run infokey to update it"),
1536146520Sru                    filename, NULL);
153793142Sru		free(filename);
153893142Sru		return 0;
153993142Sru	}
1540146520Sru	if (len < INFOKEY_NMAGIC + strlen(VERSION) + 1
1541146520Sru            || strcmp(VERSION, (char *) (buf + 4)) != 0)
154293142Sru	{
1543146520Sru		info_error
1544146520Sru                  ((char *) _("Your infokey file `%s' is out of date -- run infokey to update it"),
1545146520Sru                    filename, NULL);
154693142Sru		free(filename);
154793142Sru		return 0;
154893142Sru	}
154993142Sru
155093142Sru	/* Extract the pieces.  */
1551146520Sru	for (p = buf + 4 + strlen(VERSION) + 1;
1552146520Sru             (unsigned int) (p - buf) < len - 4;
1553146520Sru             p += n)
155493142Sru	{
155593142Sru		int s = *p++;
155693142Sru
155793142Sru		n = getint(&p);
1558146520Sru		if (n < 0 || (unsigned int) n > len - 4 - (p - buf))
155993142Sru		{
1560146520Sru			info_error((char *) _("Invalid infokey file `%s' (bad section length) -- run infokey to update it"),
1561146520Sru                            filename, NULL);
156293142Sru			free(filename);
156393142Sru			return 0;
156493142Sru		}
156593142Sru
156693142Sru		switch (s)
156793142Sru		{
156893142Sru		case INFOKEY_SECTION_INFO:
156993142Sru			user_info_keys = p;
157093142Sru			user_info_keys_len = n;
157193142Sru			break;
157293142Sru		case INFOKEY_SECTION_EA:
157393142Sru			user_ea_keys = p;
157493142Sru			user_ea_keys_len = n;
157593142Sru			break;
157693142Sru		case INFOKEY_SECTION_VAR:
157793142Sru			user_vars = p;
157893142Sru			user_vars_len = n;
157993142Sru			break;
158093142Sru		default:
1581146520Sru			info_error((char *) _("Invalid infokey file `%s' (bad section code) -- run infokey to update it"),
1582146520Sru                            filename, NULL);
158393142Sru			free(filename);
158493142Sru			return 0;
158593142Sru		}
158693142Sru	}
158793142Sru
158893142Sru	free(filename);
158993142Sru	return 1;
159093142Sru}
159193142Sru
159293142Sru/* Decode special key sequences from the infokey file.  Return zero
159393142Sru   if the key sequence includes special keys which the terminal
159493142Sru   doesn't define.
159593142Sru */
159693142Srustatic int
1597146520Srudecode_keys(unsigned char *src, unsigned int slen,
1598146520Sru    unsigned char *dst, unsigned int dlen)
159993142Sru{
160093142Sru	unsigned char *s = src;
160193142Sru	unsigned char *d = dst;
160293142Sru
1603146520Sru#define To_dst(c) do { \
1604146520Sru  if ((unsigned int) (d - dst) < dlen) *d++ = (c); \
1605146520Sru} while (0)
160693142Sru
1607146520Sru	while ((unsigned int) (s - src) < slen)
160893142Sru	{
160993142Sru		unsigned char c = ISMETA(*s) ? UNMETA(*s) : *s;
161093142Sru
161193142Sru		if (c == SK_ESCAPE)
161293142Sru		{
1613146520Sru			char *t;
161493142Sru			static char lit[] = { SK_ESCAPE, NUL };
161593142Sru
1616146520Sru			switch ((unsigned int) (s + 1 - src) < slen ? s[1] : '\0')
161793142Sru			{
161893142Sru			case SK_RIGHT_ARROW:	t = term_kr; break;
161993142Sru			case SK_LEFT_ARROW:	t = term_kl; break;
162093142Sru			case SK_UP_ARROW:	t = term_ku; break;
162193142Sru			case SK_DOWN_ARROW:	t = term_kd; break;
162293142Sru			case SK_PAGE_UP:	t = term_kP; break;
162393142Sru			case SK_PAGE_DOWN:	t = term_kN; break;
162493142Sru			case SK_HOME:		t = term_kh; break;
162593142Sru			case SK_END:		t = term_ke; break;
162693142Sru			case SK_DELETE:		t = term_kx; break;
162793142Sru			case SK_INSERT:		t = term_ki; break;
162893142Sru			case SK_LITERAL:
162993142Sru			default:		t = lit; break;
163093142Sru			}
163193142Sru			if (t == NULL)
163293142Sru				return 0;
163393142Sru			while (*t)
163493142Sru				To_dst(ISMETA(*s) ? Meta(*t++) : *t++);
163593142Sru			s += 2;
163693142Sru		}
163793142Sru		else
163893142Sru		{
163993142Sru			if (ISMETA(*s))
164093142Sru				To_dst(Meta(*s++));
164193142Sru			else
164293142Sru				To_dst(*s++);
164393142Sru		}
164493142Sru	}
164593142Sru
164693142Sru	To_dst('\0');
164793142Sru
164893142Sru	return 1;
164993142Sru
165093142Sru#undef To_dst
165193142Sru
165293142Sru}
165393142Sru
165493142Sru/* Convert an infokey file section to keymap bindings.  Return false if
165593142Sru   the default bindings are to be suppressed.  */
165693142Srustatic int
1657146520Srusection_to_keymaps(Keymap map, unsigned char *table, unsigned int len)
165893142Sru{
165993142Sru	int stop;
166093142Sru	unsigned char *p;
1661146520Sru	unsigned char *seq = NULL;
1662146520Sru	unsigned int seqlen = 0;
166393142Sru	enum { getseq, gotseq, getaction } state = getseq;
166493142Sru
166593142Sru	stop = len > 0 ? table[0] : 0;
166693142Sru
1667146520Sru	for (p = table + 1; (unsigned int) (p - table) < len; p++)
166893142Sru	{
166993142Sru		switch (state)
167093142Sru		{
167193142Sru		case getseq:
167293142Sru			if (*p)
167393142Sru			{
167493142Sru				seq = p;
167593142Sru				state = gotseq;
167693142Sru			}
167793142Sru			break;
167893142Sru
167993142Sru		case gotseq:
168093142Sru			if (!*p)
168193142Sru			{
168293142Sru				seqlen = p - seq;
168393142Sru				state = getaction;
168493142Sru			}
168593142Sru			break;
168693142Sru
168793142Sru		case getaction:
168893142Sru			{
168993142Sru				unsigned int action = *p;
169093142Sru				unsigned char keyseq[256];
169193142Sru				KEYMAP_ENTRY ke;
169293142Sru
169393142Sru				state = getseq;
169493142Sru				/* If decode_keys returns zero, it
169593142Sru				   means that seq includes keys which
169693142Sru				   the terminal doesn't support, like
169793142Sru				   PageDown.  In that case, don't bind
169893142Sru				   the key sequence.  */
169993142Sru				if (decode_keys(seq, seqlen, keyseq,
170093142Sru						sizeof keyseq))
170193142Sru				{
170293142Sru					keyseq[sizeof keyseq - 1] = '\0';
170393142Sru					ke.type = ISFUNC;
170493142Sru					ke.function =
170593142Sru					  action < A_NCOMMANDS
170693142Sru					  ? &function_doc_array[action]
170793142Sru					  : NULL;
1708146520Sru					keymap_bind_keyseq(map,
1709146520Sru                                            (const char *) keyseq, &ke);
171093142Sru				}
171193142Sru			}
171293142Sru			break;
171393142Sru		}
171493142Sru	}
171593142Sru	if (state != getseq)
1716146520Sru		info_error((char *) _("Bad data in infokey file -- some key bindings ignored"),
1717146520Sru                    NULL, NULL);
171893142Sru	return !stop;
171993142Sru}
172093142Sru
172193142Sru/* Convert an infokey file section to variable settings.
172293142Sru */
172393142Srustatic void
1724146520Srusection_to_vars(unsigned char *table, unsigned int len)
172593142Sru{
172693142Sru	enum { getvar, gotvar, getval, gotval } state = getvar;
172793142Sru	unsigned char *var = NULL;
172893142Sru	unsigned char *val = NULL;
172993142Sru	unsigned char *p;
173093142Sru
1731146520Sru	for (p = table; (unsigned int) (p - table) < len; p++)
173293142Sru	  {
173393142Sru	    switch (state)
173493142Sru	      {
173593142Sru	      case getvar:
173693142Sru		if (*p)
173793142Sru		  {
173893142Sru		    var = p;
173993142Sru		    state = gotvar;
174093142Sru		  }
174193142Sru		break;
174293142Sru
174393142Sru	      case gotvar:
174493142Sru		if (!*p)
174593142Sru		  state = getval;
174693142Sru		break;
174793142Sru
174893142Sru	      case getval:
174993142Sru		if (*p)
175093142Sru		  {
175193142Sru		    val = p;
175293142Sru		    state = gotval;
175393142Sru		  }
175493142Sru		break;
175593142Sru
175693142Sru	      case gotval:
175793142Sru		if (!*p)
175893142Sru		  {
1759146520Sru		    set_variable_to_value((char *) var, (char *) val);
176093142Sru		    state = getvar;
176193142Sru		  }
176293142Sru		break;
176393142Sru	      }
176493142Sru	  }
176593142Sru      if (state != getvar)
1766146520Sru	info_error((char *) _("Bad data in infokey file -- some var settings ignored"),
1767146520Sru            NULL, NULL);
176893142Sru}
176993142Sru
177093142Sruvoid
1771146520Sruinitialize_info_keymaps (void)
177293142Sru{
177393142Sru  int i;
177493142Sru  int suppress_info_default_bindings = 0;
177593142Sru  int suppress_ea_default_bindings = 0;
177693142Sru
177793142Sru  if (!info_keymap)
177893142Sru    {
177993142Sru      info_keymap = keymap_make_keymap ();
178093142Sru      echo_area_keymap = keymap_make_keymap ();
178193142Sru    }
178293142Sru
178393142Sru  /* Bind the echo area insert routines. */
178493142Sru  for (i = 0; i < 256; i++)
178593142Sru    if (isprint (i))
178693142Sru      echo_area_keymap[i].function = InfoCmd(ea_insert);
178793142Sru
178893142Sru  /* Get user-defined keys and variables.  */
178993142Sru  if (fetch_user_maps())
179093142Sru    {
179193142Sru      if (user_info_keys_len && user_info_keys[0])
179293142Sru	suppress_info_default_bindings = 1;
179393142Sru      if (user_ea_keys_len && user_ea_keys[0])
179493142Sru	suppress_ea_default_bindings = 1;
179593142Sru    }
179693142Sru
179793142Sru  /* Apply the default bindings, unless the user says to suppress
179893142Sru     them.  */
179993142Sru  if (vi_keys_p)
180093142Sru    {
180193142Sru      if (!suppress_info_default_bindings)
180293142Sru	section_to_keymaps(info_keymap, default_vi_like_info_keys,
180393142Sru			   sizeof(default_vi_like_info_keys));
180493142Sru      if (!suppress_ea_default_bindings)
180593142Sru	  section_to_keymaps(echo_area_keymap, default_vi_like_ea_keys,
180693142Sru			     sizeof(default_vi_like_ea_keys));
180793142Sru    }
180893142Sru  else
180993142Sru    {
181093142Sru      if (!suppress_info_default_bindings)
181193142Sru	section_to_keymaps(info_keymap, default_emacs_like_info_keys,
181293142Sru			   sizeof(default_emacs_like_info_keys));
181393142Sru      if (!suppress_ea_default_bindings)
181493142Sru	  section_to_keymaps(echo_area_keymap, default_emacs_like_ea_keys,
181593142Sru			     sizeof(default_emacs_like_ea_keys));
181693142Sru    }
181793142Sru
181893142Sru  /* If the user specified custom bindings, apply them on top of the
181993142Sru     default ones.  */
182093142Sru  if (user_info_keys_len)
182193142Sru    section_to_keymaps(info_keymap, user_info_keys, user_info_keys_len);
182293142Sru
182393142Sru  if (user_ea_keys_len)
182493142Sru    section_to_keymaps(echo_area_keymap, user_ea_keys, user_ea_keys_len);
182593142Sru
182693142Sru  if (user_vars_len)
182793142Sru    section_to_vars(user_vars, user_vars_len);
182893142Sru}
182993142Sru
183093142Sru#endif /* defined(INFOKEY) */
1831114477Sru/* vim: set sw=2 cino={1s>2sn-s^-se-s: */
1832