root/src/keymap.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. create_default_keymap_section
  2. create_default_keymap
  3. load_keymap_from_section
  4. load_setup_get_full_config_name
  5. load_setup_init_config_from_file
  6. load_setup_get_keymap_profile_config
  7. keymap_load
  8. keymap_free

   1 /*
   2    Default values and initialization of keybinding engine
   3 
   4    Copyright (C) 2009-2021
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Vitja Makarov, 2005
   9    Ilia Maslakov <il.smind@gmail.com>, 2009, 2010
  10    Andrew Borodin <aborodin@vmail.ru>, 2010-2021
  11 
  12    This file is part of the Midnight Commander.
  13 
  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.
  18 
  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.
  23 
  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/>.
  26  */
  27 
  28 #include <config.h>
  29 
  30 #include "lib/global.h"
  31 
  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 */
  37 
  38 #include "args.h"               /* mc_args__keymap_file */
  39 
  40 #include "keymap.h"
  41 
  42 /*** global variables ****************************************************************************/
  43 
  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
  66 
  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
  84 
  85 /*** file scope macro definitions ****************************************************************/
  86 
  87 /*** file scope type declarations ****************************************************************/
  88 
  89 /* default keymaps in ini (key=value) format */
  90 typedef struct global_keymap_ini_t
  91 {
  92     const char *key;
  93     const char *value;
  94 } global_keymap_ini_t;
  95 
  96 /*** file scope variables ************************************************************************/
  97 
  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}
 151 };
 152 
 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}
 184 };
 185 
 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}
 225 };
 226 
 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}
 244 };
 245 
 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}
 258 };
 259 
 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}
 293 };
 294 
 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}
 309 };
 310 
 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}
 319 };
 320 
 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}
 344 };
 345 
 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}
 366 };
 367 
 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}
 380 };
 381 #endif /* ENABLE_EXT2FS_ATTR */
 382 
 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}
 486 };
 487 
 488 /* emacs keyboard layout emulation */
 489 static const global_keymap_ini_t default_editor_x_keymap[] = {
 490     {NULL, NULL}
 491 };
 492 #endif /* USE_INTERNAL_EDIT */
 493 
 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}
 535 };
 536 
 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}
 571 };
 572 
 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}
 618 };
 619 #endif
 620 
 621 /*** file scope macro definitions ****************************************************************/
 622 
 623 /*** file scope type declarations ****************************************************************/
 624 
 625 /*** file scope variables ************************************************************************/
 626 
 627 /* --------------------------------------------------------------------------------------------- */
 628 /*** file scope functions ************************************************************************/
 629 /* --------------------------------------------------------------------------------------------- */
 630 
 631 static void
 632 create_default_keymap_section (mc_config_t * keymap, const char *section,
     /* [previous][next][first][last][top][bottom][index][help]  */
 633                                const global_keymap_ini_t * k)
 634 {
 635     size_t i;
 636 
 637     for (i = 0; k[i].key != NULL; i++)
 638         mc_config_set_string_raw (keymap, section, k[i].key, k[i].value);
 639 }
 640 
 641 /* --------------------------------------------------------------------------------------------- */
 642 
 643 static mc_config_t *
 644 create_default_keymap (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 645 {
 646     mc_config_t *keymap;
 647 
 648     keymap = mc_config_init (NULL, TRUE);
 649 
 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
 673 
 674     return keymap;
 675 }
 676 
 677 /* --------------------------------------------------------------------------------------------- */
 678 
 679 static void
 680 load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg)
     /* [previous][next][first][last][top][bottom][index][help]  */
 681 {
 682     gchar **profile_keys, **keys;
 683 
 684     if (section_name == NULL)
 685         return;
 686 
 687     keys = mc_config_get_keys (cfg, section_name, NULL);
 688 
 689     for (profile_keys = keys; *profile_keys != NULL; profile_keys++)
 690     {
 691         gchar **values;
 692 
 693         values = mc_config_get_string_list (cfg, section_name, *profile_keys, NULL);
 694         if (values != NULL)
 695         {
 696             long action;
 697 
 698             action = keybind_lookup_action (*profile_keys);
 699             if (action > 0)
 700             {
 701                 gchar **curr_values;
 702 
 703                 for (curr_values = values; *curr_values != NULL; curr_values++)
 704                     keybind_cmd_bind (keymap, *curr_values, action);
 705             }
 706 
 707             g_strfreev (values);
 708         }
 709     }
 710 
 711     g_strfreev (keys);
 712 }
 713 
 714 /* --------------------------------------------------------------------------------------------- */
 715 /**
 716  * Get name of config file.
 717  *
 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.
 720  *
 721  * @return newly allocated string with config name or NULL if file is not found.
 722  */
 723 
 724 static char *
 725 load_setup_get_full_config_name (const char *subdir, const char *config_file_name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 726 {
 727     /*
 728        TODO: IMHO, in future, this function shall be placed in mcconfig module.
 729      */
 730     char *lc_basename, *ret;
 731     char *file_name;
 732 
 733     if (config_file_name == NULL)
 734         return NULL;
 735 
 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);
 741 
 742     canonicalize_pathname (file_name);
 743 
 744     if (g_path_is_absolute (file_name))
 745         return file_name;
 746 
 747     lc_basename = g_path_get_basename (file_name);
 748     g_free (file_name);
 749 
 750     if (lc_basename == NULL)
 751         return NULL;
 752 
 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);
 757 
 758     if (exist_file (ret))
 759     {
 760         g_free (lc_basename);
 761         canonicalize_pathname (ret);
 762         return ret;
 763     }
 764     g_free (ret);
 765 
 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);
 770 
 771     g_free (lc_basename);
 772 
 773     if (exist_file (ret))
 774     {
 775         canonicalize_pathname (ret);
 776         return ret;
 777     }
 778 
 779     g_free (ret);
 780     return NULL;
 781 }
 782 
 783 /* --------------------------------------------------------------------------------------------- */
 784 /**
 785   Create new mc_config object from specified ini-file or
 786   append data to existing mc_config object from ini-file
 787 */
 788 
 789 static void
 790 load_setup_init_config_from_file (mc_config_t ** config, const char *fname, gboolean read_only)
     /* [previous][next][first][last][top][bottom][index][help]  */
 791 {
 792     /*
 793        TODO: IMHO, in future, this function shall be placed in mcconfig module.
 794      */
 795     if (exist_file (fname))
 796     {
 797         if (*config != NULL)
 798             mc_config_read_file (*config, fname, read_only, TRUE);
 799         else
 800             *config = mc_config_init (fname, read_only);
 801     }
 802 }
 803 
 804 /* --------------------------------------------------------------------------------------------- */
 805 
 806 static mc_config_t *
 807 load_setup_get_keymap_profile_config (gboolean load_from_file)
     /* [previous][next][first][last][top][bottom][index][help]  */
 808 {
 809     /*
 810        TODO: IMHO, in future, this function shall be placed in mcconfig module.
 811      */
 812     mc_config_t *keymap_config;
 813     char *share_keymap, *sysconfig_keymap;
 814     char *fname, *fname2;
 815 
 816     /* 0) Create default keymap */
 817     keymap_config = create_default_keymap ();
 818     if (!load_from_file)
 819         return keymap_config;
 820 
 821     /* load and merge global keymaps */
 822 
 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);
 826 
 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);
 831 
 832     /* then load and merge one of user-defined keymap */
 833 
 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)
 837     {
 838         load_setup_init_config_from_file (&keymap_config, fname, TRUE);
 839         goto done;
 840     }
 841     g_free (fname);
 842 
 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)
 846     {
 847         load_setup_init_config_from_file (&keymap_config, fname, TRUE);
 848         goto done;
 849     }
 850 
 851     MC_PTR_FREE (fname);
 852 
 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)
 859     {
 860         load_setup_init_config_from_file (&keymap_config, fname, TRUE);
 861         goto done;
 862     }
 863     g_free (fname);
 864 
 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);
 868 
 869   done:
 870     g_free (fname);
 871     g_free (sysconfig_keymap);
 872     g_free (share_keymap);
 873 
 874     return keymap_config;
 875 }
 876 
 877 /* --------------------------------------------------------------------------------------------- */
 878 /*** public functions ****************************************************************************/
 879 /* --------------------------------------------------------------------------------------------- */
 880 
 881 void
 882 keymap_load (gboolean load_from_file)
     /* [previous][next][first][last][top][bottom][index][help]  */
 883 {
 884     /*
 885      * Load keymap from GLOBAL_KEYMAP_FILE before ${XDG_CONFIG_HOME}/mc/mc.keymap, so that the user
 886      * definitions override global settings.
 887      */
 888     mc_config_t *mc_global_keymap;
 889 
 890     mc_global_keymap = load_setup_get_keymap_profile_config (load_from_file);
 891 
 892     if (mc_global_keymap != NULL)
 893     {
 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)
 897 
 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
 920 
 921 #undef LOAD_KEYMAP
 922         mc_config_deinit (mc_global_keymap);
 923     }
 924 
 925 #define SET_MAP(m) \
 926     m##_map = (global_keymap_t *) m##_keymap->data
 927 
 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
 950 
 951 #undef SET_MAP
 952 }
 953 
 954 /* --------------------------------------------------------------------------------------------- */
 955 
 956 void
 957 keymap_free (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 958 {
 959 #define FREE_KEYMAP(km) \
 960     if (km##_keymap != NULL) \
 961         g_array_free (km##_keymap, TRUE)
 962 
 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
 985 
 986 #undef FREE_KEYMAP
 987 }
 988 
 989 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */