maint: remove dead hint files
[midnight-commander.git] / src / keymap.c
blobd9c395a6c208cf6bb1b52fcaad64ac9d9d717b3f
1 /*
2 Default values and initialization of keybinding engine
4 Copyright (C) 2009-2022
5 Free Software Foundation, Inc.
7 Written by:
8 Vitja Makarov, 2005
9 Ilia Maslakov <il.smind@gmail.com>, 2009, 2010
10 Andrew Borodin <aborodin@vmail.ru>, 2010-2021
12 This file is part of the Midnight Commander.
14 The Midnight Commander is free software: you can redistribute it
15 and/or modify it under the terms of the GNU General Public License as
16 published by the Free Software Foundation, either version 3 of the License,
17 or (at your option) any later version.
19 The Midnight Commander is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
24 You should have received a copy of the GNU General Public License
25 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include <config.h>
30 #include "lib/global.h"
32 #include "lib/fileloc.h"
33 #include "lib/keybind.h"
34 #include "lib/mcconfig.h" /* mc_config_t */
35 #include "lib/util.h"
36 #include "lib/widget.h" /* dialog_map, input_map, listbox_map, menu_map, radio_map */
38 #include "args.h" /* mc_args__keymap_file */
40 #include "keymap.h"
42 /*** global variables ****************************************************************************/
44 GArray *filemanager_keymap = NULL;
45 GArray *filemanager_x_keymap = NULL;
46 GArray *panel_keymap = NULL;
47 GArray *dialog_keymap = NULL;
48 GArray *menu_keymap = NULL;
49 GArray *input_keymap = NULL;
50 GArray *listbox_keymap = NULL;
51 GArray *radio_keymap = NULL;
52 GArray *tree_keymap = NULL;
53 GArray *help_keymap = NULL;
54 #ifdef ENABLE_EXT2FS_ATTR
55 GArray *chattr_keymap = NULL;
56 #endif
57 #ifdef USE_INTERNAL_EDIT
58 GArray *editor_keymap = NULL;
59 GArray *editor_x_keymap = NULL;
60 #endif
61 GArray *viewer_keymap = NULL;
62 GArray *viewer_hex_keymap = NULL;
63 #ifdef USE_DIFF_VIEW
64 GArray *diff_keymap = NULL;
65 #endif
67 const global_keymap_t *filemanager_map = NULL;
68 const global_keymap_t *filemanager_x_map = NULL;
69 const global_keymap_t *panel_map = NULL;
70 const global_keymap_t *tree_map = NULL;
71 const global_keymap_t *help_map = NULL;
72 #ifdef ENABLE_EXT2FS_ATTR
73 const global_keymap_t *chattr_map = NULL;
74 #endif
75 #ifdef USE_INTERNAL_EDIT
76 const global_keymap_t *editor_map = NULL;
77 const global_keymap_t *editor_x_map = NULL;
78 #endif
79 const global_keymap_t *viewer_map = NULL;
80 const global_keymap_t *viewer_hex_map = NULL;
81 #ifdef USE_DIFF_VIEW
82 const global_keymap_t *diff_map = NULL;
83 #endif
85 /*** file scope macro definitions ****************************************************************/
87 /*** file scope type declarations ****************************************************************/
89 /* default keymaps in ini (key=value) format */
90 typedef struct global_keymap_ini_t
92 const char *key;
93 const char *value;
94 } global_keymap_ini_t;
96 /*** file scope variables ************************************************************************/
98 /* midnight */
99 static const global_keymap_ini_t default_filemanager_keymap[] = {
100 {"ChangePanel", "tab; ctrl-i"},
101 {"Help", "f1"},
102 {"UserMenu", "f2"},
103 {"View", "f3"},
104 {"Edit", "f4"},
105 {"Copy", "f5"},
106 {"Move", "f6"},
107 {"MakeDir", "f7"},
108 {"Delete", "f8"},
109 {"Menu", "f9"},
110 {"Quit", "f10"},
111 {"MenuLastSelected", "f19"},
112 {"QuitQuiet", "f20"},
113 {"History", "alt-h"},
114 {"EditorViewerHistory", "alt-shift-e"},
115 {"DirSize", "ctrl-space"},
116 /* Copy useful information to the command line */
117 {"PutCurrentPath", "alt-a"},
118 {"PutOtherPath", "alt-shift-a"},
119 {"PutCurrentSelected", "alt-enter; ctrl-enter"},
120 {"PutCurrentFullSelected", "ctrl-shift-enter"},
121 {"CdQuick", "alt-c"},
122 /* To access the directory hotlist */
123 {"HotList", "ctrl-backslash"},
124 /* Suspend */
125 {"Suspend", "ctrl-z"},
126 /* The filtered view command */
127 {"ViewFiltered", "alt-exclamation"},
128 /* Find file */
129 {"Find", "alt-question"},
130 /* Panel refresh */
131 {"Reread", "ctrl-r"},
132 /* Switch listing between long, user defined and full formats */
133 /* Swap panels */
134 {"Swap", "ctrl-u"},
135 /* Resize panels */
136 {"SplitEqual", "alt-equal"},
137 {"SplitMore", "alt-shift-right"},
138 {"SplitLess", "alt-shift-left"},
139 /* View output */
140 {"Shell", "ctrl-o"},
141 {"ShowHidden", "alt-dot"},
142 {"SplitVertHoriz", "alt-comma"},
143 {"ExtendedKeyMap", "ctrl-x"},
144 /* Select/unselect group */
145 {"Select", "kpplus"},
146 {"Unselect", "kpminus"},
147 {"SelectInvert", "kpasterisk"},
148 /* List of screens */
149 {"ScreenList", "alt-prime"},
150 {NULL, NULL}
153 static const global_keymap_ini_t default_filemanager_x_keymap[] = {
154 {"CompareDirs", "d"},
155 #ifdef USE_DIFF_VIEW
156 {"CompareFiles", "ctrl-d"},
157 #endif /* USE_DIFF_VIEW */
158 #ifdef ENABLE_VFS
159 {"VfsList", "a"},
160 #endif /* ENABLE_VFS */
161 {"PutCurrentPath", "p"},
162 {"PutOtherPath", "ctrl-p"},
163 {"PutCurrentTagged", "t"},
164 {"PutOtherTagged", "ctrl-t"},
165 {"ChangeMode", "c"},
166 {"ChangeOwn", "o"},
167 #ifdef ENABLE_EXT2FS_ATTR
168 {"ChangeAttributes", "e"},
169 #endif /* ENABLE_EXT2FS_ATTR */
170 {"PutCurrentLink", "r"},
171 {"PutOtherLink", "ctrl-r"},
172 {"Link", "l"},
173 {"LinkSymbolic", "s"},
174 {"LinkSymbolicRelative", "v"},
175 {"LinkSymbolicEdit", "ctrl-s"},
176 {"PanelInfo", "i"},
177 {"PanelQuickView", "q"},
178 {"HotListAdd", "h"},
179 #ifdef ENABLE_BACKGROUND
180 {"Jobs", "j"},
181 #endif /* ENABLE_BACKGROUND */
182 {"ExternalPanelize", "!"},
183 {NULL, NULL}
186 /* panel */
187 static const global_keymap_ini_t default_panel_keymap[] = {
188 {"CycleListingFormat", "alt-t"},
189 {"PanelOtherCd", "alt-o"},
190 {"PanelOtherCdLink", "alt-l"},
191 {"CopySingle", "f15"},
192 {"DeleteSingle", "f18"},
193 {"Enter", "enter"},
194 {"EditNew", "f14"},
195 {"MoveSingle", "f16"},
196 {"SelectInvert", "alt-asterisk"},
197 {"Select", "alt-plus"},
198 {"Unselect", "alt-minus"},
199 {"ViewRaw", "f13"},
200 {"CdChild", "ctrl-pgdn"},
201 {"CdParent", "ctrl-pgup"},
202 {"History", "alt-shift-h"},
203 {"HistoryNext", "alt-u"},
204 {"HistoryPrev", "alt-y"},
205 {"BottomOnScreen", "alt-j"},
206 {"MiddleOnScreen", "alt-r"},
207 {"TopOnScreen", "alt-g"},
208 {"Mark", "insert; ctrl-t"},
209 {"MarkDown", "shift-down"},
210 {"MarkUp", "shift-up"},
211 {"Up", "up; ctrl-p"},
212 {"Down", "down; ctrl-n"},
213 {"Left", "left"},
214 {"Right", "right"},
215 {"Top", "alt-lt; home; a1"},
216 {"Bottom", "alt-gt; end; c1"},
217 {"PageDown", "pgdn; ctrl-v"},
218 {"PageUp", "pgup; alt-v"},
219 #ifdef HAVE_CHARSET
220 {"SelectCodepage", "alt-e"},
221 #endif
222 {"Search", "ctrl-s; alt-s"},
223 {"PanelOtherSync", "alt-i"},
224 {NULL, NULL}
227 /* dialog */
228 static const global_keymap_ini_t default_dialog_keymap[] = {
229 {"Ok", "enter"},
230 {"Cancel", "f10; esc; ctrl-g"},
231 {"Up", "up; left"},
232 {"Down", "down; right"},
233 #if 0
234 {"Left", "up; left"},
235 {"Right", "down; right"},
236 #endif
237 {"Help", "f1"},
238 {"Suspend", "ctrl-z"},
239 {"Refresh", "ctrl-l"},
240 {"ScreenList", "alt-prime"},
241 {"ScreenNext", "alt-rbrace"},
242 {"ScreenPrev", "alt-lbrace"},
243 {NULL, NULL}
246 /* menubar */
247 static const global_keymap_ini_t default_menu_keymap[] = {
248 {"Help", "f1"},
249 {"Left", "left; ctrl-b"},
250 {"Right", "right; ctrl-f"},
251 {"Up", "up; ctrl-p"},
252 {"Down", "down; ctrl-n"},
253 {"Home", "home; alt-lt; ctrl-a"},
254 {"End", "end; alt-gt; ctrl-e"},
255 {"Enter", "enter"},
256 {"Quit", "f10; ctrl-g; esc"},
257 {NULL, NULL}
260 /* input line */
261 static const global_keymap_ini_t default_input_keymap[] = {
262 /* Motion */
263 {"Home", "ctrl-a; alt-lt; home; a1"},
264 {"End", "ctrl-e; alt-gt; end; c1"},
265 {"Left", "left; alt-left; ctrl-b"},
266 {"Right", "right; alt-right; ctrl-f"},
267 {"WordLeft", "ctrl-left; alt-b"},
268 {"WordRight", "ctrl-right; alt-f"},
269 /* Mark */
270 {"MarkLeft", "shift-left"},
271 {"MarkRight", "shift-right"},
272 {"MarkToWordBegin", "ctrl-shift-left"},
273 {"MarkToWordEnd", "ctrl-shift-right"},
274 {"MarkToHome", "shift-home"},
275 {"MarkToEnd", "shift-end"},
276 /* Editing */
277 {"Backspace", "backspace; ctrl-h"},
278 {"Delete", "delete; ctrl-d"},
279 {"DeleteToWordEnd", "alt-d"},
280 {"DeleteToWordBegin", "alt-backspace"},
281 /* Region manipulation */
282 {"Remove", "ctrl-w"},
283 {"Store", "alt-w"},
284 {"Yank", "ctrl-y"},
285 {"DeleteToEnd", "ctrl-k"},
286 /* History */
287 {"History", "alt-h"},
288 {"HistoryPrev", "alt-p; ctrl-down"},
289 {"HistoryNext", "alt-n; ctrl-up"},
290 /* Completion */
291 {"Complete", "alt-tab"},
292 {NULL, NULL}
295 /* listbox */
296 static const global_keymap_ini_t default_listbox_keymap[] = {
297 {"Up", "up; ctrl-p"},
298 {"Down", "down; ctrl-n"},
299 {"Top", "home; alt-lt; a1"},
300 {"Bottom", "end; alt-gt; c1"},
301 {"PageUp", "pgup; alt-v"},
302 {"PageDown", "pgdn; ctrl-v"},
303 {"Delete", "delete; d"},
304 {"Clear", "shift-delete; shift-d"},
305 {"View", "f3"},
306 {"Edit", "f4"},
307 {"Enter", "enter"},
308 {NULL, NULL}
311 /* radio */
312 static const global_keymap_ini_t default_radio_keymap[] = {
313 {"Up", "up; ctrl-p"},
314 {"Down", "down; ctrl-n"},
315 {"Top", "home; alt-lt; a1"},
316 {"Bottom", "end; alt-gt; c1"},
317 {"Select", "space"},
318 {NULL, NULL}
321 /* tree */
322 static const global_keymap_ini_t default_tree_keymap[] = {
323 {"Help", "f1"},
324 {"Rescan", "f2; ctrl-r"},
325 {"Forget", "f3"},
326 {"ToggleNavigation", "f4"},
327 {"Copy", "f5"},
328 {"Move", "f6"},
329 #if 0
330 {"MakeDir", "f7"},
331 #endif
332 {"Delete", "f8; delete"},
333 {"Up", "up; ctrl-p"},
334 {"Down", "down; ctrl-n"},
335 {"Left", "left"},
336 {"Right", "right"},
337 {"Top", "home; alt-lt; a1"},
338 {"Bottom", "end; alt-gt; c1"},
339 {"PageUp", "pgup; alt-v"},
340 {"PageDown", "pgdn; ctrl-v"},
341 {"Enter", "enter"},
342 {"Search", "ctrl-s; alt-s"},
343 {NULL, NULL}
346 /* help */
347 static const global_keymap_ini_t default_help_keymap[] = {
348 {"Help", "f1"},
349 {"Index", "f2; c"},
350 {"Back", "f3; left; l"},
351 {"Quit", "f10; esc"},
352 {"Up", "up; ctrl-p"},
353 {"Down", "down; ctrl-n"},
354 {"PageDown", "f; space; pgdn; ctrl-v"},
355 {"PageUp", "b; pgup; alt-v; backspace"},
356 {"HalfPageDown", "d"},
357 {"HalfPageUp", "u"},
358 {"Top", "home; ctrl-home; ctrl-pgup; a1; alt-lt; g"},
359 {"Bottom", "end; ctrl-end; ctrl-pgdn; c1; alt-gt; shift-g"},
360 {"Enter", "right; enter"},
361 {"LinkNext", "tab"},
362 {"LinkPrev", "alt-tab"},
363 {"NodeNext", "n"},
364 {"NodePrev", "p"},
365 {NULL, NULL}
368 #ifdef ENABLE_EXT2FS_ATTR
369 /* chattr dialog */
370 static const global_keymap_ini_t default_chattr_keymap[] = {
371 {"Up", "up; left; ctrl-p"},
372 {"Down", "down; right; ctrl-n"},
373 {"Top", "home; alt-lt; a1"},
374 {"Bottom", "end; alt-gt; c1"},
375 {"PageUp", "pgup; alt-v"},
376 {"PageDown", "pgdn; ctrl-v"},
377 {"Mark", "t; shift-t"},
378 {"MarkAndDown", "insert"},
379 {NULL, NULL}
381 #endif /* ENABLE_EXT2FS_ATTR */
383 #ifdef USE_INTERNAL_EDIT
384 static const global_keymap_ini_t default_editor_keymap[] = {
385 {"Enter", "enter"},
386 {"Return", "shift-enter; ctrl-enter; ctrl-shift-enter"}, /* useful for pasting multiline text */
387 {"Tab", "tab; shift-tab; ctrl-tab; ctrl-shift-tab"}, /* ditto */
388 {"BackSpace", "backspace; ctrl-h"},
389 {"Delete", "delete; ctrl-d"},
390 {"Left", "left"},
391 {"Right", "right"},
392 {"Up", "up"},
393 {"Down", "down"},
394 {"Home", "home"},
395 {"End", "end"},
396 {"PageUp", "pgup"},
397 {"PageDown", "pgdn"},
398 {"WordLeft", "ctrl-left; ctrl-z"},
399 {"WordRight", "ctrl-right; ctrl-x"},
400 {"InsertOverwrite", "insert"},
401 {"Help", "f1"},
402 {"Save", "f2"},
403 {"Mark", "f3"},
404 {"Replace", "f4"},
405 {"Copy", "f5"},
406 {"Move", "f6"},
407 {"Search", "f7"},
408 {"Remove", "f8; ctrl-delete"},
409 {"Menu", "f9"},
410 {"Quit", "f10; esc"},
411 {"UserMenu", "f11"},
412 {"SaveAs", "f12; ctrl-f2"},
413 {"MarkColumn", "f13"},
414 {"ReplaceContinue", "f14; ctrl-f4"},
415 {"InsertFile", "f15"},
416 {"SearchContinue", "f17; ctrl-f7"},
417 {"EditNew", "ctrl-n"},
418 {"DeleteToWordBegin", "alt-backspace"},
419 {"DeleteToWordEnd", "alt-d"},
420 {"DeleteLine", "ctrl-y"},
421 {"DeleteToEnd", "ctrl-k"},
422 {"Undo", "ctrl-u; ctrl-backspace"},
423 {"Redo", "alt-r"},
424 #ifdef HAVE_CHARSET
425 {"SelectCodepage", "alt-e"},
426 #endif
427 {"Goto", "alt-l; alt-shift-l"},
428 {"Refresh", "ctrl-l"},
429 {"Shell", "ctrl-o"},
430 {"Top", "ctrl-home; ctrl-pgup; alt-lt"},
431 {"Bottom", "ctrl-end; ctrl-pgdn; alt-gt"},
432 {"TopOnScreen", "ctrl-pgup"},
433 {"BottomOnScreen", "ctrl-pgdn"},
434 {"ScrollUp", "ctrl-up"},
435 {"ScrollDown", "ctrl-down"},
436 {"Store", "ctrl-insert"},
437 {"Paste", "shift-insert"},
438 {"Cut", "shift-delete"},
439 {"BlockSave", "ctrl-f"},
440 {"MarkLeft", "shift-left"},
441 {"MarkRight", "shift-right"},
442 {"MarkUp", "shift-up"},
443 {"MarkDown", "shift-down"},
444 {"MarkPageUp", "shift-pgup"},
445 {"MarkPageDown", "shift-pgdn"},
446 {"MarkToWordBegin", "ctrl-shift-left"},
447 {"MarkToWordEnd", "ctrl-shift-right"},
448 {"MarkToHome", "shift-home"},
449 {"MarkToEnd", "shift-end"},
450 {"MarkToFileBegin", "ctrl-shift-home"},
451 {"MarkToFileEnd", "ctrl-shift-end"},
452 {"MarkToPageBegin", "ctrl-shift-pgup"},
453 {"MarkToPageEnd", "ctrl-shift-pgdn"},
454 {"MarkScrollUp", "ctrl-shift-up"},
455 {"MarkScrollDown", "ctrl-shift-down"},
456 {"MarkColumnLeft", "alt-left"},
457 {"MarkColumnRight", "alt-right"},
458 {"MarkColumnUp", "alt-up"},
459 {"MarkColumnDown", "alt-down"},
460 {"MarkColumnPageUp", "alt-pgup"},
461 {"MarkColumnPageDown", "alt-pgdn"},
462 {"InsertLiteral", "ctrl-q"},
463 {"Complete", "alt-tab"},
464 {"MatchBracket", "alt-b"},
465 {"ParagraphFormat", "alt-p"},
466 {"Bookmark", "alt-k"},
467 {"BookmarkFlush", "alt-o"},
468 {"BookmarkNext", "alt-j"},
469 {"BookmarkPrev", "alt-i"},
470 {"MacroStartStopRecord", "ctrl-r"},
471 {"MacroExecute", "ctrl-a"},
472 {"ShowNumbers", "alt-n"},
473 {"ShowTabTws", "alt-underline"},
474 {"SyntaxOnOff", "ctrl-s"},
475 {"Find", "alt-enter"},
476 {"FilePrev", "alt-minus"},
477 {"FileNext", "alt-plus"},
478 {"Sort", "alt-t"},
479 {"Mail", "alt-m"},
480 {"ExternalCommand", "alt-u"},
481 #ifdef HAVE_ASPELL
482 {"SpellCheckCurrentWord", "ctrl-p"},
483 #endif
484 {"ExtendedKeyMap", "ctrl-x"},
485 {NULL, NULL}
488 /* emacs keyboard layout emulation */
489 static const global_keymap_ini_t default_editor_x_keymap[] = {
490 {NULL, NULL}
492 #endif /* USE_INTERNAL_EDIT */
494 /* viewer */
495 static const global_keymap_ini_t default_viewer_keymap[] = {
496 {"Help", "f1"},
497 {"WrapMode", "f2"},
498 {"Quit", "f3; f10; q; esc"},
499 {"HexMode", "f4"},
500 {"Goto", "f5"},
501 {"Search", "f7"},
502 {"SearchContinue", "f17; n"},
503 {"MagicMode", "f8"},
504 {"NroffMode", "f9"},
505 {"Home", "ctrl-a"},
506 {"End", "ctrl-e"},
507 {"Left", "h; left"},
508 {"Right", "l; right"},
509 {"LeftQuick", "ctrl-left"},
510 {"RightQuick", "ctrl-right"},
511 {"Up", "k; y; insert; up; ctrl-p"},
512 {"Down", "j; e; delete; down; enter; ctrl-n"},
513 {"PageDown", "f; space; pgdn; ctrl-v"},
514 {"PageUp", "b; pgup; alt-v; backspace"},
515 {"HalfPageDown", "d"},
516 {"HalfPageUp", "u"},
517 {"Top", "home; ctrl-home; ctrl-pgup; a1; alt-lt; g"},
518 {"Bottom", "end; ctrl-end; ctrl-pgdn; c1; alt-gt; shift-g"},
519 {"BookmarkGoto", "m"},
520 {"Bookmark", "r"},
521 {"FileNext", "ctrl-f"},
522 {"FilePrev", "ctrl-b"},
523 #ifdef HAVE_CHARSET
524 {"SelectCodepage", "alt-e"},
525 #endif
526 {"Shell", "ctrl-o"},
527 {"Ruler", "alt-r"},
528 {"SearchForward", "slash"},
529 {"SearchBackward", "question"},
530 {"SearchForwardContinue", "ctrl-s"},
531 {"SearchBackwardContinue", "ctrl-r"},
532 {"SearchOppositeContinue", "shift-n"},
533 {"History", "alt-shift-e"},
534 {NULL, NULL}
537 /* hex viewer */
538 static const global_keymap_ini_t default_viewer_hex_keymap[] = {
539 {"Help", "f1"},
540 {"HexEditMode", "f2"},
541 {"Quit", "f3; f10; q; esc"},
542 {"HexMode", "f4"},
543 {"Goto", "f5"},
544 {"Save", "f6"},
545 {"Search", "f7"},
546 {"SearchContinue", "f17; n"},
547 {"MagicMode", "f8"},
548 {"NroffMode", "f9"},
549 {"ToggleNavigation", "tab"},
550 {"Home", "ctrl-a; home"},
551 {"End", "ctrl-e; end"},
552 {"Left", "b; left"},
553 {"Right", "f; right"},
554 {"Up", "k; y; up"},
555 {"Down", "j; delete; down"},
556 {"PageDown", "pgdn; ctrl-v"},
557 {"PageUp", "pgup; alt-v"},
558 {"Top", "ctrl-home; ctrl-pgup; a1; alt-lt; g"},
559 {"Bottom", "ctrl-end; ctrl-pgdn; c1; alt-gt; shift-g"},
560 #ifdef HAVE_CHARSET
561 {"SelectCodepage", "alt-e"},
562 #endif
563 {"Shell", "ctrl-o"},
564 {"SearchForward", "slash"},
565 {"SearchBackward", "question"},
566 {"SearchForwardContinue", "ctrl-s"},
567 {"SearchBackwardContinue", "ctrl-r"},
568 {"SearchOppositeContinue", "shift-n"},
569 {"History", "alt-shift-e"},
570 {NULL, NULL}
573 #ifdef USE_DIFF_VIEW
574 /* diff viewer */
575 static const global_keymap_ini_t default_diff_keymap[] = {
576 {"ShowSymbols", "alt-s; s"},
577 {"ShowNumbers", "alt-n; l"},
578 {"SplitFull", "f"},
579 {"SplitEqual", "equal"},
580 {"SplitMore", "gt"},
581 {"SplitLess", "lt"},
582 {"Tab2", "2"},
583 {"Tab3", "3"},
584 {"Tab4", "4"},
585 {"Tab8", "8"},
586 {"Swap", "ctrl-u"},
587 {"Redo", "ctrl-r"},
588 {"HunkNext", "n; enter; space"},
589 {"HunkPrev", "p; backspace"},
590 {"Goto", "g; shift-g"},
591 {"Save", "f2"},
592 {"Edit", "f4"},
593 {"EditOther", "f14"},
594 {"Merge", "f5"},
595 {"MergeOther", "f15"},
596 {"Search", "f7"},
597 {"SearchContinue", "f17"},
598 {"Options", "f9"},
599 {"Top", "ctrl-home"},
600 {"Bottom", "ctrl-end"},
601 {"Down", "down"},
602 {"Up", "up"},
603 {"LeftQuick", "ctrl-left"},
604 {"RightQuick", "ctrl-right"},
605 {"Left", "left"},
606 {"Right", "right"},
607 {"PageDown", "pgdn"},
608 {"PageUp", "pgup"},
609 {"Home", "home"},
610 {"End", "end"},
611 {"Help", "f1"},
612 {"Quit", "f10; q; shift-q; esc"},
613 #ifdef HAVE_CHARSET
614 {"SelectCodepage", "alt-e"},
615 #endif
616 {"Shell", "ctrl-o"},
617 {NULL, NULL}
619 #endif
621 /*** file scope macro definitions ****************************************************************/
623 /*** file scope type declarations ****************************************************************/
625 /*** file scope variables ************************************************************************/
627 /* --------------------------------------------------------------------------------------------- */
628 /*** file scope functions ************************************************************************/
629 /* --------------------------------------------------------------------------------------------- */
631 static void
632 create_default_keymap_section (mc_config_t * keymap, const char *section,
633 const global_keymap_ini_t * k)
635 size_t i;
637 for (i = 0; k[i].key != NULL; i++)
638 mc_config_set_string_raw (keymap, section, k[i].key, k[i].value);
641 /* --------------------------------------------------------------------------------------------- */
643 static mc_config_t *
644 create_default_keymap (void)
646 mc_config_t *keymap;
648 keymap = mc_config_init (NULL, TRUE);
650 create_default_keymap_section (keymap, KEYMAP_SECTION_FILEMANAGER, default_filemanager_keymap);
651 create_default_keymap_section (keymap, KEYMAP_SECTION_FILEMANAGER_EXT,
652 default_filemanager_x_keymap);
653 create_default_keymap_section (keymap, KEYMAP_SECTION_PANEL, default_panel_keymap);
654 create_default_keymap_section (keymap, KEYMAP_SECTION_DIALOG, default_dialog_keymap);
655 create_default_keymap_section (keymap, KEYMAP_SECTION_MENU, default_menu_keymap);
656 create_default_keymap_section (keymap, KEYMAP_SECTION_INPUT, default_input_keymap);
657 create_default_keymap_section (keymap, KEYMAP_SECTION_LISTBOX, default_listbox_keymap);
658 create_default_keymap_section (keymap, KEYMAP_SECTION_RADIO, default_radio_keymap);
659 create_default_keymap_section (keymap, KEYMAP_SECTION_TREE, default_tree_keymap);
660 create_default_keymap_section (keymap, KEYMAP_SECTION_HELP, default_help_keymap);
661 #ifdef ENABLE_EXT2FS_ATTR
662 create_default_keymap_section (keymap, KEYMAP_SECTION_HELP, default_chattr_keymap);
663 #endif
664 #ifdef USE_INTERNAL_EDIT
665 create_default_keymap_section (keymap, KEYMAP_SECTION_EDITOR, default_editor_keymap);
666 create_default_keymap_section (keymap, KEYMAP_SECTION_EDITOR_EXT, default_editor_x_keymap);
667 #endif
668 create_default_keymap_section (keymap, KEYMAP_SECTION_VIEWER, default_viewer_keymap);
669 create_default_keymap_section (keymap, KEYMAP_SECTION_VIEWER_HEX, default_viewer_hex_keymap);
670 #ifdef USE_DIFF_VIEW
671 create_default_keymap_section (keymap, KEYMAP_SECTION_DIFFVIEWER, default_diff_keymap);
672 #endif
674 return keymap;
677 /* --------------------------------------------------------------------------------------------- */
679 static void
680 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
682 gchar **profile_keys, **keys;
684 if (section_name == NULL)
685 return;
687 keys = mc_config_get_keys (cfg, section_name, NULL);
689 for (profile_keys = keys; *profile_keys != NULL; profile_keys++)
691 gchar **values;
693 values = mc_config_get_string_list (cfg, section_name, *profile_keys, NULL);
694 if (values != NULL)
696 long action;
698 action = keybind_lookup_action (*profile_keys);
699 if (action > 0)
701 gchar **curr_values;
703 for (curr_values = values; *curr_values != NULL; curr_values++)
704 keybind_cmd_bind (keymap, *curr_values, action);
707 g_strfreev (values);
711 g_strfreev (keys);
714 /* --------------------------------------------------------------------------------------------- */
716 * Get name of config file.
718 * @param subdir If not NULL, config is also searched in specified subdir.
719 * @param config_file_name If relative, file if searched in standard paths.
721 * @return newly allocated string with config name or NULL if file is not found.
724 static char *
725 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
728 TODO: IMHO, in future, this function shall be placed in mcconfig module.
730 char *lc_basename, *ret;
731 char *file_name;
733 if (config_file_name == NULL)
734 return NULL;
736 /* check for .keymap suffix */
737 if (g_str_has_suffix (config_file_name, ".keymap"))
738 file_name = g_strdup (config_file_name);
739 else
740 file_name = g_strconcat (config_file_name, ".keymap", (char *) NULL);
742 canonicalize_pathname (file_name);
744 if (g_path_is_absolute (file_name))
745 return file_name;
747 lc_basename = g_path_get_basename (file_name);
748 g_free (file_name);
750 if (lc_basename == NULL)
751 return NULL;
753 if (subdir != NULL)
754 ret = g_build_filename (mc_config_get_path (), subdir, lc_basename, (char *) NULL);
755 else
756 ret = g_build_filename (mc_config_get_path (), lc_basename, (char *) NULL);
758 if (exist_file (ret))
760 g_free (lc_basename);
761 canonicalize_pathname (ret);
762 return ret;
764 g_free (ret);
766 if (subdir != NULL)
767 ret = g_build_filename (mc_global.share_data_dir, subdir, lc_basename, (char *) NULL);
768 else
769 ret = g_build_filename (mc_global.share_data_dir, lc_basename, (char *) NULL);
771 g_free (lc_basename);
773 if (exist_file (ret))
775 canonicalize_pathname (ret);
776 return ret;
779 g_free (ret);
780 return NULL;
783 /* --------------------------------------------------------------------------------------------- */
785 Create new mc_config object from specified ini-file or
786 append data to existing mc_config object from ini-file
789 static void
790 load_setup_init_config_from_file (mc_config_t ** config, const char *fname, gboolean read_only)
793 TODO: IMHO, in future, this function shall be placed in mcconfig module.
795 if (exist_file (fname))
797 if (*config != NULL)
798 mc_config_read_file (*config, fname, read_only, TRUE);
799 else
800 *config = mc_config_init (fname, read_only);
804 /* --------------------------------------------------------------------------------------------- */
806 static mc_config_t *
807 load_setup_get_keymap_profile_config (gboolean load_from_file)
810 TODO: IMHO, in future, this function shall be placed in mcconfig module.
812 mc_config_t *keymap_config;
813 char *share_keymap, *sysconfig_keymap;
814 char *fname, *fname2;
816 /* 0) Create default keymap */
817 keymap_config = create_default_keymap ();
818 if (!load_from_file)
819 return keymap_config;
821 /* load and merge global keymaps */
823 /* 1) /usr/share/mc (mc_global.share_data_dir) */
824 share_keymap = g_build_filename (mc_global.share_data_dir, GLOBAL_KEYMAP_FILE, (char *) NULL);
825 load_setup_init_config_from_file (&keymap_config, share_keymap, TRUE);
827 /* 2) /etc/mc (mc_global.sysconfig_dir) */
828 sysconfig_keymap =
829 g_build_filename (mc_global.sysconfig_dir, GLOBAL_KEYMAP_FILE, (char *) NULL);
830 load_setup_init_config_from_file (&keymap_config, sysconfig_keymap, TRUE);
832 /* then load and merge one of user-defined keymap */
834 /* 3) --keymap=<keymap> */
835 fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file);
836 if (fname != NULL && strcmp (fname, sysconfig_keymap) != 0 && strcmp (fname, share_keymap) != 0)
838 load_setup_init_config_from_file (&keymap_config, fname, TRUE);
839 goto done;
841 g_free (fname);
843 /* 4) getenv("MC_KEYMAP") */
844 fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP"));
845 if (fname != NULL && strcmp (fname, sysconfig_keymap) != 0 && strcmp (fname, share_keymap) != 0)
847 load_setup_init_config_from_file (&keymap_config, fname, TRUE);
848 goto done;
851 MC_PTR_FREE (fname);
853 /* 5) main config; [Midnight Commander] -> keymap */
854 fname2 = mc_config_get_string (mc_global.main_config, CONFIG_APP_SECTION, "keymap", NULL);
855 if (fname2 != NULL && *fname2 != '\0')
856 fname = load_setup_get_full_config_name (NULL, fname2);
857 g_free (fname2);
858 if (fname != NULL && strcmp (fname, sysconfig_keymap) != 0 && strcmp (fname, share_keymap) != 0)
860 load_setup_init_config_from_file (&keymap_config, fname, TRUE);
861 goto done;
863 g_free (fname);
865 /* 6) ${XDG_CONFIG_HOME}/mc/mc.keymap */
866 fname = mc_config_get_full_path (GLOBAL_KEYMAP_FILE);
867 load_setup_init_config_from_file (&keymap_config, fname, TRUE);
869 done:
870 g_free (fname);
871 g_free (sysconfig_keymap);
872 g_free (share_keymap);
874 return keymap_config;
877 /* --------------------------------------------------------------------------------------------- */
878 /*** public functions ****************************************************************************/
879 /* --------------------------------------------------------------------------------------------- */
881 void
882 keymap_load (gboolean load_from_file)
885 * Load keymap from GLOBAL_KEYMAP_FILE before ${XDG_CONFIG_HOME}/mc/mc.keymap, so that the user
886 * definitions override global settings.
888 mc_config_t *mc_global_keymap;
890 mc_global_keymap = load_setup_get_keymap_profile_config (load_from_file);
892 if (mc_global_keymap != NULL)
894 #define LOAD_KEYMAP(s,km) \
895 km##_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t)); \
896 load_keymap_from_section (KEYMAP_SECTION_##s, km##_keymap, mc_global_keymap)
898 LOAD_KEYMAP (FILEMANAGER, filemanager);
899 LOAD_KEYMAP (FILEMANAGER_EXT, filemanager_x);
900 LOAD_KEYMAP (PANEL, panel);
901 LOAD_KEYMAP (DIALOG, dialog);
902 LOAD_KEYMAP (MENU, menu);
903 LOAD_KEYMAP (INPUT, input);
904 LOAD_KEYMAP (LISTBOX, listbox);
905 LOAD_KEYMAP (RADIO, radio);
906 LOAD_KEYMAP (TREE, tree);
907 LOAD_KEYMAP (HELP, help);
908 #ifdef ENABLE_EXT2FS_ATTR
909 LOAD_KEYMAP (CHATTR, chattr);
910 #endif
911 #ifdef USE_INTERNAL_EDIT
912 LOAD_KEYMAP (EDITOR, editor);
913 LOAD_KEYMAP (EDITOR_EXT, editor_x);
914 #endif
915 LOAD_KEYMAP (VIEWER, viewer);
916 LOAD_KEYMAP (VIEWER_HEX, viewer_hex);
917 #ifdef USE_DIFF_VIEW
918 LOAD_KEYMAP (DIFFVIEWER, diff);
919 #endif
921 #undef LOAD_KEYMAP
922 mc_config_deinit (mc_global_keymap);
925 #define SET_MAP(m) \
926 m##_map = (global_keymap_t *) m##_keymap->data
928 SET_MAP (filemanager);
929 SET_MAP (filemanager_x);
930 SET_MAP (panel);
931 SET_MAP (dialog);
932 SET_MAP (menu);
933 SET_MAP (input);
934 SET_MAP (listbox);
935 SET_MAP (radio);
936 SET_MAP (tree);
937 SET_MAP (help);
938 #ifdef ENABLE_EXT2FS_ATTR
939 SET_MAP (chattr);
940 #endif
941 #ifdef USE_INTERNAL_EDIT
942 SET_MAP (editor);
943 SET_MAP (editor_x);
944 #endif
945 SET_MAP (viewer);
946 SET_MAP (viewer_hex);
947 #ifdef USE_DIFF_VIEW
948 SET_MAP (diff);
949 #endif
951 #undef SET_MAP
954 /* --------------------------------------------------------------------------------------------- */
956 void
957 keymap_free (void)
959 #define FREE_KEYMAP(km) \
960 if (km##_keymap != NULL) \
961 g_array_free (km##_keymap, TRUE)
963 FREE_KEYMAP (filemanager);
964 FREE_KEYMAP (filemanager_x);
965 FREE_KEYMAP (panel);
966 FREE_KEYMAP (dialog);
967 FREE_KEYMAP (menu);
968 FREE_KEYMAP (input);
969 FREE_KEYMAP (listbox);
970 FREE_KEYMAP (radio);
971 FREE_KEYMAP (tree);
972 FREE_KEYMAP (help);
973 #ifdef ENABLE_EXT2FS_ATTR
974 FREE_KEYMAP (chattr);
975 #endif
976 #ifdef USE_INTERNAL_EDIT
977 FREE_KEYMAP (editor);
978 FREE_KEYMAP (editor_x);
979 #endif
980 FREE_KEYMAP (viewer);
981 FREE_KEYMAP (viewer_hex);
982 #ifdef USE_DIFF_VIEW
983 FREE_KEYMAP (diff);
984 #endif
986 #undef FREE_KEYMAP
989 /* --------------------------------------------------------------------------------------------- */