infomap.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. /* infomap.c -- keymaps for Info.
  2. $Id$
  3. Copyright 1993, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2007,
  4. 2008, 2011, 2012, 2013, 2014, 2015, 2016 Free Software Foundation, Inc.
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. Originally written by Brian Fox. */
  16. #include "info.h"
  17. #include "doc.h"
  18. #include "funs.h"
  19. #include "session.h"
  20. #include "terminal.h"
  21. #include "variables.h"
  22. void keymap_bind_keyseq (Keymap map, int *keyseq, KEYMAP_ENTRY *keyentry);
  23. /* Return a new Keymap. */
  24. Keymap
  25. keymap_make_keymap (void)
  26. {
  27. int i;
  28. Keymap keymap;
  29. keymap = (Keymap)xmalloc (KEYMAP_SIZE * sizeof (KEYMAP_ENTRY));
  30. for (i = 0; i < KEYMAP_SIZE; i++)
  31. {
  32. keymap[i].type = ISFUNC;
  33. keymap[i].value.function = NULL;
  34. }
  35. return keymap;
  36. }
  37. /* Record KEYSEQ, a sequence of keys terminated by 0, in the linked list of
  38. FUNCTION_KEYSEQ hanging off FUNCTION. Label it with ROOTMAP so we know
  39. whether the key sequence is for main operation or for the echo area. */
  40. static void
  41. add_function_keyseq (InfoCommand *function, int *keyseq, Keymap rootmap)
  42. {
  43. FUNCTION_KEYSEQ *ks, *k;
  44. int len;
  45. if (function == NULL ||
  46. function == InfoCmd (info_do_lowercase_version))
  47. return;
  48. /* If there is already a key sequence recorded for this key map,
  49. don't do anything. */
  50. for (k = function->keys; k; k = k->next)
  51. if (k->map == rootmap)
  52. return;
  53. ks = xmalloc (sizeof (FUNCTION_KEYSEQ));
  54. ks->next = function->keys;
  55. ks->map = rootmap;
  56. for (len = 0; keyseq[len]; len++);
  57. ks->keyseq = xmalloc ((len + 1) * sizeof (int));
  58. memcpy (ks->keyseq, keyseq, (len + 1) * sizeof (int));
  59. function->keys = ks;
  60. }
  61. /* Bind key sequence. Don't override already bound key sequences. */
  62. void
  63. keymap_bind_keyseq (Keymap map, int *keyseq, KEYMAP_ENTRY *keyentry)
  64. {
  65. Keymap m = map;
  66. int *s = keyseq;
  67. int c;
  68. if (!s || *s == 0)
  69. return;
  70. while ((c = *s++) != '\0')
  71. {
  72. switch (m[c].type)
  73. {
  74. case ISFUNC:
  75. if (m[c].value.function)
  76. return; /* There is a function here already. */
  77. if (*s != '\0')
  78. {
  79. m[c].type = ISKMAP;
  80. m[c].value.keymap = keymap_make_keymap ();
  81. }
  82. break;
  83. case ISKMAP:
  84. if (*s == '\0')
  85. return; /* The key sequence we were asked to bind is an initial
  86. subsequence of an already-bound sequence. */
  87. break;
  88. }
  89. if (*s != '\0')
  90. {
  91. m = m[c].value.keymap;
  92. }
  93. else
  94. {
  95. add_function_keyseq (keyentry->value.function, keyseq, map);
  96. m[c] = *keyentry;
  97. }
  98. }
  99. return;
  100. }
  101. /* Initialize the standard info keymaps. */
  102. Keymap info_keymap = NULL;
  103. Keymap echo_area_keymap = NULL;
  104. /* Make sure that we don't have too many command codes defined. */
  105. #if A_NCOMMANDS > A_MAX_COMMAND + 1
  106. #error "too many commands defined"
  107. #endif
  108. /* Initialize the keymaps from the .info keymap file. */
  109. #define NUL '\0'
  110. static int default_emacs_like_info_keys[] =
  111. {
  112. /* Favoured command bindings come first. We want help to
  113. report q, not C-x C-c, etc. */
  114. 'H', NUL, A_info_get_help_window,
  115. 'q', NUL, A_info_quit,
  116. KEY_UP_ARROW, NUL, A_info_prev_line,
  117. KEY_DOWN_ARROW, NUL, A_info_next_line,
  118. KEY_PAGE_UP, NUL, A_info_scroll_backward,
  119. KEY_PAGE_DOWN, NUL, A_info_scroll_forward,
  120. KEY_HOME, NUL, A_info_beginning_of_node,
  121. KEY_END, NUL, A_info_end_of_node,
  122. '{', NUL, A_info_search_previous,
  123. '}', NUL, A_info_search_next,
  124. CONTROL('g'), NUL, A_info_abort_key,
  125. RET, NUL, A_info_select_reference_this_line,
  126. TAB, NUL, A_info_move_to_next_xref,
  127. LFD, NUL, A_info_select_reference_this_line,
  128. CONTROL('a'), NUL, A_info_beginning_of_line,
  129. CONTROL('b'), NUL, A_info_backward_char,
  130. CONTROL('e'), NUL, A_info_end_of_line,
  131. CONTROL('f'), NUL, A_info_forward_char,
  132. CONTROL('h'), NUL, A_info_scroll_backward,
  133. CONTROL('l'), NUL, A_info_redraw_display,
  134. CONTROL('n'), NUL, A_info_next_line,
  135. CONTROL('p'), NUL, A_info_prev_line,
  136. CONTROL('r'), NUL, A_isearch_backward,
  137. CONTROL('s'), NUL, A_isearch_forward,
  138. CONTROL('u'), NUL, A_info_universal_argument,
  139. CONTROL('v'), NUL, A_info_scroll_forward_page_only,
  140. SPC, NUL, A_info_scroll_forward,
  141. ',', NUL, A_info_next_index_match,
  142. '/', NUL, A_info_search,
  143. '0', NUL, A_info_last_menu_item,
  144. '1', NUL, A_info_menu_digit,
  145. '2', NUL, A_info_menu_digit,
  146. '3', NUL, A_info_menu_digit,
  147. '4', NUL, A_info_menu_digit,
  148. '5', NUL, A_info_menu_digit,
  149. '6', NUL, A_info_menu_digit,
  150. '7', NUL, A_info_menu_digit,
  151. '8', NUL, A_info_menu_digit,
  152. '9', NUL, A_info_menu_digit,
  153. '<', NUL, A_info_first_node,
  154. '=', NUL, A_info_display_file_info,
  155. '>', NUL, A_info_last_node,
  156. '?', NUL, A_info_search_backward,
  157. '[', NUL, A_info_global_prev_node,
  158. ']', NUL, A_info_global_next_node,
  159. 'b', NUL, A_info_beginning_of_node,
  160. 'd', NUL, A_info_dir_node,
  161. 'e', NUL, A_info_end_of_node,
  162. 'f', NUL, A_info_xref_item,
  163. 'g', NUL, A_info_goto_node,
  164. 'G', NUL, A_info_menu_sequence,
  165. 'h', NUL, A_info_get_info_help_node,
  166. 'i', NUL, A_info_index_search,
  167. 'I', NUL, A_info_virtual_index,
  168. 'l', NUL, A_info_history_node,
  169. 'm', NUL, A_info_menu_item,
  170. 'n', NUL, A_info_next_node,
  171. 'O', NUL, A_info_goto_invocation_node,
  172. 'p', NUL, A_info_prev_node,
  173. 'r', NUL, A_info_xref_item,
  174. 'R', NUL, A_info_toggle_regexp,
  175. 's', NUL, A_info_search,
  176. 'S', NUL, A_info_search_case_sensitively,
  177. 't', NUL, A_info_top_node,
  178. 'u', NUL, A_info_up_node,
  179. 'x', NUL, A_info_delete_window,
  180. KEYMAP_META('0'), NUL, A_info_add_digit_to_numeric_arg,
  181. KEYMAP_META('1'), NUL, A_info_add_digit_to_numeric_arg,
  182. KEYMAP_META('2'), NUL, A_info_add_digit_to_numeric_arg,
  183. KEYMAP_META('3'), NUL, A_info_add_digit_to_numeric_arg,
  184. KEYMAP_META('4'), NUL, A_info_add_digit_to_numeric_arg,
  185. KEYMAP_META('5'), NUL, A_info_add_digit_to_numeric_arg,
  186. KEYMAP_META('6'), NUL, A_info_add_digit_to_numeric_arg,
  187. KEYMAP_META('7'), NUL, A_info_add_digit_to_numeric_arg,
  188. KEYMAP_META('8'), NUL, A_info_add_digit_to_numeric_arg,
  189. KEYMAP_META('9'), NUL, A_info_add_digit_to_numeric_arg,
  190. KEYMAP_META('-'), NUL, A_info_add_digit_to_numeric_arg,
  191. KEYMAP_META(CONTROL('f')), NUL, A_info_show_footnotes,
  192. KEYMAP_META(CONTROL('g')), NUL, A_info_abort_key,
  193. KEYMAP_META(TAB), NUL, A_info_move_to_prev_xref,
  194. KEYMAP_META(CONTROL('v')), NUL, A_info_scroll_other_window,
  195. KEYMAP_META('<'), NUL, A_info_beginning_of_node,
  196. KEYMAP_META('>'), NUL, A_info_end_of_node,
  197. KEYMAP_META('b'), NUL, A_info_backward_word,
  198. KEYMAP_META('f'), NUL, A_info_forward_word,
  199. KEYMAP_META('r'), NUL, A_info_move_to_window_line,
  200. KEYMAP_META('v'), NUL, A_info_scroll_backward_page_only,
  201. KEYMAP_META('x'), NUL, A_info_execute_command,
  202. KEYMAP_META('/'), NUL, A_info_tree_search,
  203. KEYMAP_META('}'), NUL, A_info_tree_search_next,
  204. KEYMAP_META('{'), NUL, A_info_tree_search_previous,
  205. CONTROL('x'), CONTROL('b'), NUL, A_list_visited_nodes,
  206. CONTROL('x'), CONTROL('c'), NUL, A_info_quit,
  207. CONTROL('x'), CONTROL('f'), NUL, A_info_view_file,
  208. CONTROL('x'), CONTROL('g'), NUL, A_info_abort_key,
  209. CONTROL('x'), CONTROL('v'), NUL, A_info_view_file,
  210. CONTROL('x'), '0', NUL, A_info_delete_window,
  211. CONTROL('x'), '1', NUL, A_info_keep_one_window,
  212. CONTROL('x'), '2', NUL, A_info_split_window,
  213. CONTROL('x'), '^', NUL, A_info_grow_window,
  214. CONTROL('x'), 'b', NUL, A_select_visited_node,
  215. CONTROL('x'), 'f', NUL, A_info_all_files,
  216. CONTROL('x'), 'n', NUL, A_info_search_next,
  217. CONTROL('x'), 'N', NUL, A_info_search_previous,
  218. CONTROL('x'), 'o', NUL, A_info_next_window,
  219. CONTROL('x'), 't', NUL, A_info_tile_windows,
  220. CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
  221. KEY_RIGHT_ARROW, NUL, A_info_forward_char,
  222. KEY_LEFT_ARROW, NUL, A_info_backward_char,
  223. KEY_DELETE, NUL, A_info_scroll_backward,
  224. ESC, KEY_PAGE_UP, NUL, A_info_scroll_other_window_backward,
  225. ESC, KEY_PAGE_DOWN, NUL, A_info_scroll_other_window,
  226. ESC, KEY_UP_ARROW, NUL, A_info_prev_line,
  227. ESC, KEY_DOWN_ARROW, NUL, A_info_next_line,
  228. ESC, KEY_RIGHT_ARROW, NUL, A_info_forward_word,
  229. ESC, KEY_LEFT_ARROW, NUL, A_info_backward_word,
  230. KEY_BACK_TAB, NUL, A_info_move_to_prev_xref,
  231. };
  232. static int default_emacs_like_ea_keys[] =
  233. {
  234. KEYMAP_META('0'), NUL, A_info_add_digit_to_numeric_arg,
  235. KEYMAP_META('1'), NUL, A_info_add_digit_to_numeric_arg,
  236. KEYMAP_META('2'), NUL, A_info_add_digit_to_numeric_arg,
  237. KEYMAP_META('3'), NUL, A_info_add_digit_to_numeric_arg,
  238. KEYMAP_META('4'), NUL, A_info_add_digit_to_numeric_arg,
  239. KEYMAP_META('5'), NUL, A_info_add_digit_to_numeric_arg,
  240. KEYMAP_META('6'), NUL, A_info_add_digit_to_numeric_arg,
  241. KEYMAP_META('7'), NUL, A_info_add_digit_to_numeric_arg,
  242. KEYMAP_META('8'), NUL, A_info_add_digit_to_numeric_arg,
  243. KEYMAP_META('9'), NUL, A_info_add_digit_to_numeric_arg,
  244. KEYMAP_META('-'), NUL, A_info_add_digit_to_numeric_arg,
  245. KEYMAP_META(CONTROL('g')), NUL, A_ea_abort,
  246. KEYMAP_META(CONTROL('v')), NUL, A_ea_scroll_completions_window,
  247. KEYMAP_META('b'), NUL, A_ea_backward_word,
  248. KEYMAP_META('d'), NUL, A_ea_kill_word,
  249. KEYMAP_META('f'), NUL, A_ea_forward_word,
  250. KEYMAP_META('y'), NUL, A_ea_yank_pop,
  251. KEYMAP_META('?'), NUL, A_ea_possible_completions,
  252. KEYMAP_META(TAB), NUL, A_ea_tab_insert,
  253. KEYMAP_META(KEY_DELETE), NUL, A_ea_backward_kill_word,
  254. CONTROL('a'), NUL, A_ea_beg_of_line,
  255. CONTROL('b'), NUL, A_ea_backward,
  256. CONTROL('d'), NUL, A_ea_delete,
  257. CONTROL('e'), NUL, A_ea_end_of_line,
  258. CONTROL('f'), NUL, A_ea_forward,
  259. CONTROL('g'), NUL, A_ea_abort,
  260. ESC, NUL, A_ea_abort,
  261. CONTROL('h'), NUL, A_ea_rubout,
  262. CONTROL('k'), NUL, A_ea_kill_line,
  263. CONTROL('l'), NUL, A_info_redraw_display,
  264. CONTROL('q'), NUL, A_ea_quoted_insert,
  265. CONTROL('t'), NUL, A_ea_transpose_chars,
  266. CONTROL('u'), NUL, A_info_universal_argument,
  267. CONTROL('y'), NUL, A_ea_yank,
  268. LFD, NUL, A_ea_newline,
  269. RET, NUL, A_ea_newline,
  270. SPC, NUL, A_ea_complete,
  271. TAB, NUL, A_ea_complete,
  272. '?', NUL, A_ea_possible_completions,
  273. #ifdef __MSDOS__
  274. /* PC users will lynch me if I don't give them their usual DEL
  275. effect... */
  276. KEY_DELETE, NUL, A_ea_delete,
  277. #else
  278. KEY_DELETE, NUL, A_ea_rubout,
  279. #endif
  280. CONTROL('x'), 'o', NUL, A_info_next_window,
  281. CONTROL('x'), KEY_DELETE, NUL, A_ea_backward_kill_line,
  282. KEY_RIGHT_ARROW, NUL, A_ea_forward,
  283. KEY_LEFT_ARROW, NUL, A_ea_backward,
  284. ESC, KEY_RIGHT_ARROW, NUL, A_ea_forward_word,
  285. ESC, KEY_LEFT_ARROW, NUL, A_ea_backward_word,
  286. KEY_HOME, NUL, A_ea_beg_of_line,
  287. KEY_END, NUL, A_ea_end_of_line,
  288. ESC, KEY_DELETE, NUL, A_ea_backward_kill_word,
  289. };
  290. static int default_vi_like_info_keys[] =
  291. {
  292. /* We want help to report q, not C-x C-c, etc. */
  293. 'q', NUL, A_info_quit,
  294. 'x', NUL, A_info_delete_window,
  295. SPC, NUL, A_info_scroll_forward,
  296. '{', NUL, A_info_search_previous,
  297. '}', NUL, A_info_search_next,
  298. KEY_UP_ARROW, NUL, A_info_up_line,
  299. KEY_DOWN_ARROW, NUL, A_info_down_line,
  300. '0', NUL, A_info_add_digit_to_numeric_arg,
  301. '1', NUL, A_info_add_digit_to_numeric_arg,
  302. '2', NUL, A_info_add_digit_to_numeric_arg,
  303. '3', NUL, A_info_add_digit_to_numeric_arg,
  304. '4', NUL, A_info_add_digit_to_numeric_arg,
  305. '5', NUL, A_info_add_digit_to_numeric_arg,
  306. '6', NUL, A_info_add_digit_to_numeric_arg,
  307. '7', NUL, A_info_add_digit_to_numeric_arg,
  308. '8', NUL, A_info_add_digit_to_numeric_arg,
  309. '9', NUL, A_info_add_digit_to_numeric_arg,
  310. '-', NUL, A_info_add_digit_to_numeric_arg,
  311. TAB, NUL, A_info_move_to_next_xref,
  312. LFD, NUL, A_info_down_line,
  313. RET, NUL, A_info_down_line,
  314. CONTROL('a'), NUL, A_info_beginning_of_line,
  315. CONTROL('b'), NUL, A_info_scroll_backward_page_only,
  316. CONTROL('c'), NUL, A_info_abort_key,
  317. CONTROL('d'), NUL, A_info_scroll_half_screen_down,
  318. CONTROL('e'), NUL, A_info_down_line,
  319. CONTROL('f'), NUL, A_info_scroll_forward_page_only,
  320. CONTROL('g'), NUL, A_info_display_file_info,
  321. CONTROL('k'), NUL, A_info_up_line,
  322. CONTROL('l'), NUL, A_info_redraw_display,
  323. CONTROL('n'), NUL, A_info_down_line,
  324. CONTROL('p'), NUL, A_info_up_line,
  325. CONTROL('r'), NUL, A_info_redraw_display,
  326. CONTROL('s'), NUL, A_isearch_forward,
  327. CONTROL('u'), NUL, A_info_scroll_half_screen_up,
  328. CONTROL('v'), NUL, A_info_scroll_forward_page_only,
  329. CONTROL('y'), NUL, A_info_up_line,
  330. ',', NUL, A_info_next_index_match,
  331. '/', NUL, A_info_search,
  332. KEYMAP_META('0'), NUL, A_info_last_menu_item,
  333. KEYMAP_META('1'), NUL, A_info_menu_digit,
  334. KEYMAP_META('2'), NUL, A_info_menu_digit,
  335. KEYMAP_META('3'), NUL, A_info_menu_digit,
  336. KEYMAP_META('4'), NUL, A_info_menu_digit,
  337. KEYMAP_META('5'), NUL, A_info_menu_digit,
  338. KEYMAP_META('6'), NUL, A_info_menu_digit,
  339. KEYMAP_META('7'), NUL, A_info_menu_digit,
  340. KEYMAP_META('8'), NUL, A_info_menu_digit,
  341. KEYMAP_META('9'), NUL, A_info_menu_digit,
  342. '<', NUL, A_info_first_node,
  343. '>', NUL, A_info_last_node,
  344. '?', NUL, A_info_search_backward,
  345. '[', NUL, A_info_global_prev_node,
  346. ']', NUL, A_info_global_next_node,
  347. '\'', NUL, A_info_history_node,
  348. 'b', NUL, A_info_scroll_backward,
  349. 'd', NUL, A_info_scroll_half_screen_down,
  350. 'e', NUL, A_info_down_line,
  351. 'E', NUL, A_info_view_file,
  352. ':', 'e', NUL, A_info_view_file,
  353. 'f', NUL, A_info_scroll_forward_page_only,
  354. 'F', NUL, A_info_scroll_forward_page_only,
  355. 'g', NUL, A_info_first_node,
  356. 'G', NUL, A_info_last_node,
  357. 'h', NUL, A_info_get_help_window,
  358. 'H', NUL, A_info_get_help_window,
  359. 'i', NUL, A_info_index_search,
  360. 'I', NUL, A_info_goto_invocation_node,
  361. 'j', NUL, A_info_next_line,
  362. 'k', NUL, A_info_prev_line,
  363. 'l', NUL, A_info_history_node,
  364. 'm', NUL, A_info_menu_item,
  365. 'n', NUL, A_info_search_next,
  366. ':', 'a', NUL, A_info_all_files,
  367. 'N', NUL, A_info_search_previous,
  368. 'O', NUL, A_info_goto_invocation_node,
  369. 'p', NUL, A_info_prev_node,
  370. 'Q', NUL, A_info_quit,
  371. ':', 'q', NUL, A_info_quit,
  372. ':', 'Q', NUL, A_info_quit,
  373. 'Z', 'Z', NUL, A_info_quit,
  374. 'r', NUL, A_info_redraw_display,
  375. 'R', NUL, A_info_toggle_regexp,
  376. 's', NUL, A_info_search,
  377. 'S', NUL, A_info_search_case_sensitively,
  378. 't', NUL, A_info_top_node,
  379. 'u', NUL, A_info_scroll_half_screen_up,
  380. 'w', NUL, A_info_scroll_backward_page_only_set_window,
  381. 'y', NUL, A_info_up_line,
  382. 'z', NUL, A_info_scroll_forward_page_only_set_window,
  383. KEYMAP_META(CONTROL('f')), NUL, A_info_show_footnotes,
  384. KEYMAP_META(CONTROL('g')), NUL, A_info_abort_key,
  385. KEYMAP_META(TAB), NUL, A_info_move_to_prev_xref,
  386. KEYMAP_META(SPC), NUL, A_info_scroll_forward_page_only,
  387. KEYMAP_META(CONTROL('v')), NUL, A_info_scroll_other_window,
  388. KEYMAP_META('<'), NUL, A_info_beginning_of_node,
  389. KEYMAP_META('>'), NUL, A_info_end_of_node,
  390. KEYMAP_META('/'), NUL, A_info_search,
  391. KEYMAP_META('?'), NUL, A_info_search_backward,
  392. KEYMAP_META('b'), NUL, A_info_beginning_of_node,
  393. KEYMAP_META('d'), NUL, A_info_dir_node,
  394. KEYMAP_META('e'), NUL, A_info_end_of_node,
  395. KEYMAP_META('f'), NUL, A_info_xref_item,
  396. KEYMAP_META('g'), NUL, A_info_select_reference_this_line,
  397. KEYMAP_META('h'), NUL, A_info_get_info_help_node,
  398. KEYMAP_META('I'), NUL, A_info_virtual_index,
  399. KEYMAP_META('m'), NUL, A_info_menu_item,
  400. KEYMAP_META('n'), NUL, A_info_search,
  401. KEYMAP_META('N'), NUL, A_info_search_backward,
  402. KEYMAP_META('r'), NUL, A_isearch_backward,
  403. KEYMAP_META('s'), NUL, A_isearch_forward,
  404. KEYMAP_META('t'), NUL, A_info_top_node,
  405. KEYMAP_META('v'), NUL, A_info_scroll_backward_page_only,
  406. KEYMAP_META('x'), NUL, A_info_execute_command,
  407. CONTROL('x'), CONTROL('b'), NUL, A_list_visited_nodes,
  408. CONTROL('x'), CONTROL('c'), NUL, A_info_quit,
  409. CONTROL('x'), CONTROL('f'), NUL, A_info_view_file,
  410. CONTROL('x'), CONTROL('g'), NUL, A_info_abort_key,
  411. CONTROL('x'), CONTROL('v'), NUL, A_info_view_file,
  412. CONTROL('x'), LFD, NUL, A_info_select_reference_this_line,
  413. CONTROL('x'), RET, NUL, A_info_select_reference_this_line,
  414. CONTROL('x'), '0', NUL, A_info_delete_window,
  415. CONTROL('x'), '1', NUL, A_info_keep_one_window,
  416. CONTROL('x'), '2', NUL, A_info_split_window,
  417. CONTROL('x'), '^', NUL, A_info_grow_window,
  418. CONTROL('x'), 'b', NUL, A_select_visited_node,
  419. CONTROL('x'), 'g', NUL, A_info_goto_node,
  420. CONTROL('x'), 'i', NUL, A_info_index_search,
  421. CONTROL('x'), 'I', NUL, A_info_goto_invocation_node,
  422. CONTROL('x'), 'o', NUL, A_info_next_window,
  423. CONTROL('x'), 'O', NUL, A_info_goto_invocation_node,
  424. CONTROL('x'), 'p', NUL, A_info_prev_node,
  425. CONTROL('x'), 'r', NUL, A_info_xref_item,
  426. CONTROL('x'), 't', NUL, A_info_tile_windows,
  427. CONTROL('x'), 'u', NUL, A_info_up_node,
  428. CONTROL('x'), 'w', NUL, A_info_toggle_wrap,
  429. CONTROL('x'), ',', NUL, A_info_next_index_match,
  430. KEY_PAGE_UP, NUL, A_info_scroll_backward,
  431. KEY_PAGE_DOWN, NUL, A_info_scroll_forward,
  432. KEY_DELETE, NUL, A_info_scroll_backward,
  433. KEY_RIGHT_ARROW, NUL, A_info_scroll_forward_page_only,
  434. KEY_LEFT_ARROW, NUL, A_info_scroll_backward_page_only,
  435. KEY_HOME, NUL, A_info_beginning_of_node,
  436. KEY_END, NUL, A_info_end_of_node,
  437. ESC, KEY_PAGE_DOWN, NUL, A_info_scroll_other_window,
  438. ESC, KEY_PAGE_UP, NUL, A_info_scroll_other_window_backward,
  439. ESC, KEY_DELETE, NUL, A_info_scroll_other_window_backward,
  440. ESC, KEY_UP_ARROW, NUL, A_info_prev_node,
  441. ESC, KEY_DOWN_ARROW, NUL, A_info_next_node,
  442. ESC, KEY_RIGHT_ARROW, NUL, A_info_xref_item,
  443. ESC, KEY_LEFT_ARROW, NUL, A_info_beginning_of_node,
  444. CONTROL('x'), KEY_DELETE, NUL, A_ea_backward_kill_line,
  445. };
  446. static int default_vi_like_ea_keys[] =
  447. {
  448. KEYMAP_META('1'), NUL, A_info_add_digit_to_numeric_arg,
  449. KEYMAP_META('2'), NUL, A_info_add_digit_to_numeric_arg,
  450. KEYMAP_META('3'), NUL, A_info_add_digit_to_numeric_arg,
  451. KEYMAP_META('4'), NUL, A_info_add_digit_to_numeric_arg,
  452. KEYMAP_META('5'), NUL, A_info_add_digit_to_numeric_arg,
  453. KEYMAP_META('6'), NUL, A_info_add_digit_to_numeric_arg,
  454. KEYMAP_META('7'), NUL, A_info_add_digit_to_numeric_arg,
  455. KEYMAP_META('8'), NUL, A_info_add_digit_to_numeric_arg,
  456. KEYMAP_META('9'), NUL, A_info_add_digit_to_numeric_arg,
  457. KEYMAP_META('-'), NUL, A_info_add_digit_to_numeric_arg,
  458. KEYMAP_META(CONTROL('g')), NUL, A_ea_abort,
  459. KEYMAP_META(CONTROL('h')), NUL, A_ea_backward_kill_word,
  460. KEYMAP_META(CONTROL('v')), NUL, A_ea_scroll_completions_window,
  461. KEYMAP_META('0'), NUL, A_ea_beg_of_line,
  462. KEYMAP_META('$'), NUL, A_ea_end_of_line,
  463. KEYMAP_META('b'), NUL, A_ea_backward_word,
  464. KEYMAP_META('d'), NUL, A_ea_kill_word,
  465. KEYMAP_META('f'), NUL, A_ea_forward_word,
  466. KEYMAP_META('h'), NUL, A_ea_backward,
  467. KEYMAP_META('l'), NUL, A_ea_forward,
  468. KEYMAP_META('w'), NUL, A_ea_forward_word,
  469. KEYMAP_META('x'), NUL, A_ea_delete,
  470. KEYMAP_META('X'), NUL, A_ea_kill_word,
  471. KEYMAP_META('y'), NUL, A_ea_yank_pop,
  472. KEYMAP_META('?'), NUL, A_ea_possible_completions,
  473. KEYMAP_META(TAB), NUL, A_ea_tab_insert,
  474. KEYMAP_META(DEL), NUL, A_ea_kill_word,
  475. CONTROL('a'), NUL, A_ea_beg_of_line,
  476. CONTROL('b'), NUL, A_ea_backward,
  477. CONTROL('d'), NUL, A_ea_delete,
  478. CONTROL('e'), NUL, A_ea_end_of_line,
  479. CONTROL('f'), NUL, A_ea_forward,
  480. CONTROL('g'), NUL, A_ea_abort,
  481. ESC, NUL, A_ea_abort,
  482. CONTROL('h'), NUL, A_ea_rubout,
  483. CONTROL('k'), NUL, A_ea_kill_line,
  484. CONTROL('l'), NUL, A_info_redraw_display,
  485. CONTROL('q'), NUL, A_ea_quoted_insert,
  486. CONTROL('t'), NUL, A_ea_transpose_chars,
  487. CONTROL('u'), NUL, A_ea_abort,
  488. CONTROL('v'), NUL, A_ea_quoted_insert,
  489. CONTROL('y'), NUL, A_ea_yank,
  490. LFD, NUL, A_ea_newline,
  491. RET, NUL, A_ea_newline,
  492. SPC, NUL, A_ea_complete,
  493. TAB, NUL, A_ea_complete,
  494. '?', NUL, A_ea_possible_completions,
  495. CONTROL('x'), 'o', NUL, A_info_next_window,
  496. KEY_RIGHT_ARROW, NUL, A_ea_forward,
  497. KEY_LEFT_ARROW, NUL, A_ea_backward,
  498. KEY_HOME, NUL, A_ea_beg_of_line,
  499. KEY_END, NUL, A_ea_end_of_line,
  500. #ifdef __MSDOS__
  501. KEY_DELETE, NUL, A_ea_delete,
  502. #else
  503. KEY_DELETE, NUL, A_ea_rubout,
  504. #endif
  505. ESC, KEY_RIGHT_ARROW, NUL, A_ea_forward_word,
  506. ESC, KEY_LEFT_ARROW, NUL, A_ea_backward_word,
  507. ESC, KEY_DELETE, NUL, A_ea_kill_word,
  508. CONTROL('x'), KEY_DELETE, NUL,A_ea_backward_kill_line,
  509. };
  510. /* Whether to suppress the default key bindings. */
  511. static int sup_info, sup_ea;
  512. /* Fetch the contents of the init file at INIT_FILE, or the standard
  513. infokey file "$HOME/.infokey". Return non-zero if an init file was
  514. loaded and read. */
  515. static int
  516. fetch_user_maps (char *init_file)
  517. {
  518. char *filename = NULL;
  519. char *homedir;
  520. FILE *inf;
  521. /* In infokey.c */
  522. int compile (FILE *fp, const char *filename, int *, int *);
  523. /* Find and open file. */
  524. if (init_file)
  525. filename = xstrdup (init_file);
  526. else if ((homedir = getenv ("HOME")) != NULL
  527. #ifdef __MINGW32__
  528. || (homedir = getenv ("USERPROFILE")) != NULL
  529. #endif
  530. )
  531. {
  532. filename = xmalloc (strlen (homedir) + 2 + strlen (INFOKEY_FILE));
  533. strcpy (filename, homedir);
  534. strcat (filename, "/");
  535. strcat (filename, INFOKEY_FILE);
  536. }
  537. #if defined(__MSDOS__) || defined(__MINGW32__)
  538. /* Poor baby, she doesn't have a HOME... */
  539. else
  540. filename = xstrdup (INFOKEY_FILE); /* try current directory */
  541. #endif
  542. inf = fopen (filename, "r");
  543. if (!inf)
  544. {
  545. free (filename);
  546. if (init_file)
  547. info_error (_("could not open init file %s"), init_file);
  548. return 0;
  549. }
  550. compile (inf, filename, &sup_info, &sup_ea);
  551. free (filename);
  552. return 1;
  553. }
  554. /* Set key bindings in MAP from TABLE, which is of length LEN. */
  555. static void
  556. section_to_keymaps (Keymap map, int *table, unsigned int len)
  557. {
  558. int k;
  559. Keymap esc_map;
  560. int *p;
  561. int *seq;
  562. enum { getseq, gotseq, getaction } state = getseq;
  563. for (p = table; (unsigned int) (p - table) < len; p++)
  564. {
  565. switch (state)
  566. {
  567. case getseq:
  568. if (*p)
  569. {
  570. seq = p;
  571. state = gotseq;
  572. }
  573. break;
  574. case gotseq:
  575. if (!*p)
  576. state = getaction;
  577. break;
  578. case getaction:
  579. {
  580. unsigned int action = *p;
  581. KEYMAP_ENTRY ke;
  582. state = getseq;
  583. ke.type = ISFUNC;
  584. ke.value.function = action < A_NCOMMANDS ?
  585. &function_doc_array[action]
  586. : NULL;
  587. keymap_bind_keyseq (map, seq, &ke);
  588. }
  589. break;
  590. }
  591. }
  592. if (state != getseq)
  593. abort ();
  594. /* Go through map and bind ESC x to the same function as M-x if it is not
  595. bound already. */
  596. if (!map[ESC].value.function)
  597. {
  598. map[ESC].type = ISKMAP;
  599. map[ESC].value.keymap = keymap_make_keymap ();
  600. }
  601. if (map[ESC].type != ISKMAP)
  602. return; /* ESC is bound to a command. */
  603. esc_map = map[ESC].value.keymap;
  604. for (k = 1; k < KEYMAP_META_BASE; k++)
  605. {
  606. if (map[k + KEYMAP_META_BASE].type == ISFUNC
  607. && esc_map[k].value.function == 0)
  608. {
  609. esc_map[k].type = ISFUNC;
  610. esc_map[k].value.function = map[k + KEYMAP_META_BASE].value.function;
  611. }
  612. }
  613. return;
  614. }
  615. /* Read key bindings and variable settings from INIT_FILE. If INIT_FILE
  616. is null, look for the init file in the default location. */
  617. void
  618. read_init_file (char *init_file)
  619. {
  620. int *info_keys, *ea_keys; /* Pointers to keymap tables. */
  621. long info_keys_len, ea_keys_len; /* Sizes of keymap tables. */
  622. int i;
  623. if (!info_keymap)
  624. {
  625. info_keymap = keymap_make_keymap ();
  626. echo_area_keymap = keymap_make_keymap ();
  627. }
  628. if (!vi_keys_p)
  629. {
  630. info_keys = default_emacs_like_info_keys;
  631. info_keys_len = sizeof (default_emacs_like_info_keys)/sizeof (int);
  632. ea_keys = default_emacs_like_ea_keys;
  633. ea_keys_len = sizeof (default_emacs_like_ea_keys)/sizeof (int);
  634. }
  635. else
  636. {
  637. info_keys = default_vi_like_info_keys;
  638. info_keys_len = sizeof (default_vi_like_info_keys)/sizeof(int);
  639. ea_keys = default_vi_like_ea_keys;
  640. ea_keys_len = sizeof (default_vi_like_ea_keys)/sizeof(int);
  641. }
  642. /* Get user-defined keys and variables. */
  643. if (fetch_user_maps (init_file))
  644. {
  645. if (sup_info)
  646. info_keys = 0; /* Suppress default bindings. */
  647. if (sup_ea)
  648. ea_keys = 0;
  649. }
  650. /* Apply the default bindings, unless the user says to suppress
  651. them. */
  652. if (info_keys)
  653. section_to_keymaps (info_keymap, info_keys, info_keys_len);
  654. if (ea_keys)
  655. section_to_keymaps (echo_area_keymap, ea_keys, ea_keys_len);
  656. for (i = 'A'; i < ('Z' + 1); i++)
  657. {
  658. if (!info_keymap[i].value.function)
  659. {
  660. info_keymap[i].type = ISFUNC;
  661. info_keymap[i].value.function = InfoCmd (info_do_lowercase_version);
  662. }
  663. if (!info_keymap[KEYMAP_META(i)].value.function)
  664. {
  665. info_keymap[KEYMAP_META(i)].type = ISFUNC;
  666. info_keymap[KEYMAP_META(i)].value.function
  667. = InfoCmd (info_do_lowercase_version);
  668. }
  669. }
  670. }
  671. /* vim: set sw=2 cino={1s>2sn-s^-se-s: */