diff options
Diffstat (limited to 'src/keymap.c')
-rw-r--r-- | src/keymap.c | 989 |
1 files changed, 989 insertions, 0 deletions
diff --git a/src/keymap.c b/src/keymap.c new file mode 100644 index 0000000..d9c395a --- /dev/null +++ b/src/keymap.c @@ -0,0 +1,989 @@ +/* + Default values and initialization of keybinding engine + + Copyright (C) 2009-2022 + Free Software Foundation, Inc. + + Written by: + Vitja Makarov, 2005 + Ilia Maslakov <il.smind@gmail.com>, 2009, 2010 + Andrew Borodin <aborodin@vmail.ru>, 2010-2021 + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include "lib/global.h" + +#include "lib/fileloc.h" +#include "lib/keybind.h" +#include "lib/mcconfig.h" /* mc_config_t */ +#include "lib/util.h" +#include "lib/widget.h" /* dialog_map, input_map, listbox_map, menu_map, radio_map */ + +#include "args.h" /* mc_args__keymap_file */ + +#include "keymap.h" + +/*** global variables ****************************************************************************/ + +GArray *filemanager_keymap = NULL; +GArray *filemanager_x_keymap = NULL; +GArray *panel_keymap = NULL; +GArray *dialog_keymap = NULL; +GArray *menu_keymap = NULL; +GArray *input_keymap = NULL; +GArray *listbox_keymap = NULL; +GArray *radio_keymap = NULL; +GArray *tree_keymap = NULL; +GArray *help_keymap = NULL; +#ifdef ENABLE_EXT2FS_ATTR +GArray *chattr_keymap = NULL; +#endif +#ifdef USE_INTERNAL_EDIT +GArray *editor_keymap = NULL; +GArray *editor_x_keymap = NULL; +#endif +GArray *viewer_keymap = NULL; +GArray *viewer_hex_keymap = NULL; +#ifdef USE_DIFF_VIEW +GArray *diff_keymap = NULL; +#endif + +const global_keymap_t *filemanager_map = NULL; +const global_keymap_t *filemanager_x_map = NULL; +const global_keymap_t *panel_map = NULL; +const global_keymap_t *tree_map = NULL; +const global_keymap_t *help_map = NULL; +#ifdef ENABLE_EXT2FS_ATTR +const global_keymap_t *chattr_map = NULL; +#endif +#ifdef USE_INTERNAL_EDIT +const global_keymap_t *editor_map = NULL; +const global_keymap_t *editor_x_map = NULL; +#endif +const global_keymap_t *viewer_map = NULL; +const global_keymap_t *viewer_hex_map = NULL; +#ifdef USE_DIFF_VIEW +const global_keymap_t *diff_map = NULL; +#endif + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/* default keymaps in ini (key=value) format */ +typedef struct global_keymap_ini_t +{ + const char *key; + const char *value; +} global_keymap_ini_t; + +/*** file scope variables ************************************************************************/ + +/* midnight */ +static const global_keymap_ini_t default_filemanager_keymap[] = { + {"ChangePanel", "tab; ctrl-i"}, + {"Help", "f1"}, + {"UserMenu", "f2"}, + {"View", "f3"}, + {"Edit", "f4"}, + {"Copy", "f5"}, + {"Move", "f6"}, + {"MakeDir", "f7"}, + {"Delete", "f8"}, + {"Menu", "f9"}, + {"Quit", "f10"}, + {"MenuLastSelected", "f19"}, + {"QuitQuiet", "f20"}, + {"History", "alt-h"}, + {"EditorViewerHistory", "alt-shift-e"}, + {"DirSize", "ctrl-space"}, + /* Copy useful information to the command line */ + {"PutCurrentPath", "alt-a"}, + {"PutOtherPath", "alt-shift-a"}, + {"PutCurrentSelected", "alt-enter; ctrl-enter"}, + {"PutCurrentFullSelected", "ctrl-shift-enter"}, + {"CdQuick", "alt-c"}, + /* To access the directory hotlist */ + {"HotList", "ctrl-backslash"}, + /* Suspend */ + {"Suspend", "ctrl-z"}, + /* The filtered view command */ + {"ViewFiltered", "alt-exclamation"}, + /* Find file */ + {"Find", "alt-question"}, + /* Panel refresh */ + {"Reread", "ctrl-r"}, + /* Switch listing between long, user defined and full formats */ + /* Swap panels */ + {"Swap", "ctrl-u"}, + /* Resize panels */ + {"SplitEqual", "alt-equal"}, + {"SplitMore", "alt-shift-right"}, + {"SplitLess", "alt-shift-left"}, + /* View output */ + {"Shell", "ctrl-o"}, + {"ShowHidden", "alt-dot"}, + {"SplitVertHoriz", "alt-comma"}, + {"ExtendedKeyMap", "ctrl-x"}, + /* Select/unselect group */ + {"Select", "kpplus"}, + {"Unselect", "kpminus"}, + {"SelectInvert", "kpasterisk"}, + /* List of screens */ + {"ScreenList", "alt-prime"}, + {NULL, NULL} +}; + +static const global_keymap_ini_t default_filemanager_x_keymap[] = { + {"CompareDirs", "d"}, +#ifdef USE_DIFF_VIEW + {"CompareFiles", "ctrl-d"}, +#endif /* USE_DIFF_VIEW */ +#ifdef ENABLE_VFS + {"VfsList", "a"}, +#endif /* ENABLE_VFS */ + {"PutCurrentPath", "p"}, + {"PutOtherPath", "ctrl-p"}, + {"PutCurrentTagged", "t"}, + {"PutOtherTagged", "ctrl-t"}, + {"ChangeMode", "c"}, + {"ChangeOwn", "o"}, +#ifdef ENABLE_EXT2FS_ATTR + {"ChangeAttributes", "e"}, +#endif /* ENABLE_EXT2FS_ATTR */ + {"PutCurrentLink", "r"}, + {"PutOtherLink", "ctrl-r"}, + {"Link", "l"}, + {"LinkSymbolic", "s"}, + {"LinkSymbolicRelative", "v"}, + {"LinkSymbolicEdit", "ctrl-s"}, + {"PanelInfo", "i"}, + {"PanelQuickView", "q"}, + {"HotListAdd", "h"}, +#ifdef ENABLE_BACKGROUND + {"Jobs", "j"}, +#endif /* ENABLE_BACKGROUND */ + {"ExternalPanelize", "!"}, + {NULL, NULL} +}; + +/* panel */ +static const global_keymap_ini_t default_panel_keymap[] = { + {"CycleListingFormat", "alt-t"}, + {"PanelOtherCd", "alt-o"}, + {"PanelOtherCdLink", "alt-l"}, + {"CopySingle", "f15"}, + {"DeleteSingle", "f18"}, + {"Enter", "enter"}, + {"EditNew", "f14"}, + {"MoveSingle", "f16"}, + {"SelectInvert", "alt-asterisk"}, + {"Select", "alt-plus"}, + {"Unselect", "alt-minus"}, + {"ViewRaw", "f13"}, + {"CdChild", "ctrl-pgdn"}, + {"CdParent", "ctrl-pgup"}, + {"History", "alt-shift-h"}, + {"HistoryNext", "alt-u"}, + {"HistoryPrev", "alt-y"}, + {"BottomOnScreen", "alt-j"}, + {"MiddleOnScreen", "alt-r"}, + {"TopOnScreen", "alt-g"}, + {"Mark", "insert; ctrl-t"}, + {"MarkDown", "shift-down"}, + {"MarkUp", "shift-up"}, + {"Up", "up; ctrl-p"}, + {"Down", "down; ctrl-n"}, + {"Left", "left"}, + {"Right", "right"}, + {"Top", "alt-lt; home; a1"}, + {"Bottom", "alt-gt; end; c1"}, + {"PageDown", "pgdn; ctrl-v"}, + {"PageUp", "pgup; alt-v"}, +#ifdef HAVE_CHARSET + {"SelectCodepage", "alt-e"}, +#endif + {"Search", "ctrl-s; alt-s"}, + {"PanelOtherSync", "alt-i"}, + {NULL, NULL} +}; + +/* dialog */ +static const global_keymap_ini_t default_dialog_keymap[] = { + {"Ok", "enter"}, + {"Cancel", "f10; esc; ctrl-g"}, + {"Up", "up; left"}, + {"Down", "down; right"}, +#if 0 + {"Left", "up; left"}, + {"Right", "down; right"}, +#endif + {"Help", "f1"}, + {"Suspend", "ctrl-z"}, + {"Refresh", "ctrl-l"}, + {"ScreenList", "alt-prime"}, + {"ScreenNext", "alt-rbrace"}, + {"ScreenPrev", "alt-lbrace"}, + {NULL, NULL} +}; + +/* menubar */ +static const global_keymap_ini_t default_menu_keymap[] = { + {"Help", "f1"}, + {"Left", "left; ctrl-b"}, + {"Right", "right; ctrl-f"}, + {"Up", "up; ctrl-p"}, + {"Down", "down; ctrl-n"}, + {"Home", "home; alt-lt; ctrl-a"}, + {"End", "end; alt-gt; ctrl-e"}, + {"Enter", "enter"}, + {"Quit", "f10; ctrl-g; esc"}, + {NULL, NULL} +}; + +/* input line */ +static const global_keymap_ini_t default_input_keymap[] = { + /* Motion */ + {"Home", "ctrl-a; alt-lt; home; a1"}, + {"End", "ctrl-e; alt-gt; end; c1"}, + {"Left", "left; alt-left; ctrl-b"}, + {"Right", "right; alt-right; ctrl-f"}, + {"WordLeft", "ctrl-left; alt-b"}, + {"WordRight", "ctrl-right; alt-f"}, + /* Mark */ + {"MarkLeft", "shift-left"}, + {"MarkRight", "shift-right"}, + {"MarkToWordBegin", "ctrl-shift-left"}, + {"MarkToWordEnd", "ctrl-shift-right"}, + {"MarkToHome", "shift-home"}, + {"MarkToEnd", "shift-end"}, + /* Editing */ + {"Backspace", "backspace; ctrl-h"}, + {"Delete", "delete; ctrl-d"}, + {"DeleteToWordEnd", "alt-d"}, + {"DeleteToWordBegin", "alt-backspace"}, + /* Region manipulation */ + {"Remove", "ctrl-w"}, + {"Store", "alt-w"}, + {"Yank", "ctrl-y"}, + {"DeleteToEnd", "ctrl-k"}, + /* History */ + {"History", "alt-h"}, + {"HistoryPrev", "alt-p; ctrl-down"}, + {"HistoryNext", "alt-n; ctrl-up"}, + /* Completion */ + {"Complete", "alt-tab"}, + {NULL, NULL} +}; + +/* listbox */ +static const global_keymap_ini_t default_listbox_keymap[] = { + {"Up", "up; ctrl-p"}, + {"Down", "down; ctrl-n"}, + {"Top", "home; alt-lt; a1"}, + {"Bottom", "end; alt-gt; c1"}, + {"PageUp", "pgup; alt-v"}, + {"PageDown", "pgdn; ctrl-v"}, + {"Delete", "delete; d"}, + {"Clear", "shift-delete; shift-d"}, + {"View", "f3"}, + {"Edit", "f4"}, + {"Enter", "enter"}, + {NULL, NULL} +}; + +/* radio */ +static const global_keymap_ini_t default_radio_keymap[] = { + {"Up", "up; ctrl-p"}, + {"Down", "down; ctrl-n"}, + {"Top", "home; alt-lt; a1"}, + {"Bottom", "end; alt-gt; c1"}, + {"Select", "space"}, + {NULL, NULL} +}; + +/* tree */ +static const global_keymap_ini_t default_tree_keymap[] = { + {"Help", "f1"}, + {"Rescan", "f2; ctrl-r"}, + {"Forget", "f3"}, + {"ToggleNavigation", "f4"}, + {"Copy", "f5"}, + {"Move", "f6"}, +#if 0 + {"MakeDir", "f7"}, +#endif + {"Delete", "f8; delete"}, + {"Up", "up; ctrl-p"}, + {"Down", "down; ctrl-n"}, + {"Left", "left"}, + {"Right", "right"}, + {"Top", "home; alt-lt; a1"}, + {"Bottom", "end; alt-gt; c1"}, + {"PageUp", "pgup; alt-v"}, + {"PageDown", "pgdn; ctrl-v"}, + {"Enter", "enter"}, + {"Search", "ctrl-s; alt-s"}, + {NULL, NULL} +}; + +/* help */ +static const global_keymap_ini_t default_help_keymap[] = { + {"Help", "f1"}, + {"Index", "f2; c"}, + {"Back", "f3; left; l"}, + {"Quit", "f10; esc"}, + {"Up", "up; ctrl-p"}, + {"Down", "down; ctrl-n"}, + {"PageDown", "f; space; pgdn; ctrl-v"}, + {"PageUp", "b; pgup; alt-v; backspace"}, + {"HalfPageDown", "d"}, + {"HalfPageUp", "u"}, + {"Top", "home; ctrl-home; ctrl-pgup; a1; alt-lt; g"}, + {"Bottom", "end; ctrl-end; ctrl-pgdn; c1; alt-gt; shift-g"}, + {"Enter", "right; enter"}, + {"LinkNext", "tab"}, + {"LinkPrev", "alt-tab"}, + {"NodeNext", "n"}, + {"NodePrev", "p"}, + {NULL, NULL} +}; + +#ifdef ENABLE_EXT2FS_ATTR +/* chattr dialog */ +static const global_keymap_ini_t default_chattr_keymap[] = { + {"Up", "up; left; ctrl-p"}, + {"Down", "down; right; ctrl-n"}, + {"Top", "home; alt-lt; a1"}, + {"Bottom", "end; alt-gt; c1"}, + {"PageUp", "pgup; alt-v"}, + {"PageDown", "pgdn; ctrl-v"}, + {"Mark", "t; shift-t"}, + {"MarkAndDown", "insert"}, + {NULL, NULL} +}; +#endif /* ENABLE_EXT2FS_ATTR */ + +#ifdef USE_INTERNAL_EDIT +static const global_keymap_ini_t default_editor_keymap[] = { + {"Enter", "enter"}, + {"Return", "shift-enter; ctrl-enter; ctrl-shift-enter"}, /* useful for pasting multiline text */ + {"Tab", "tab; shift-tab; ctrl-tab; ctrl-shift-tab"}, /* ditto */ + {"BackSpace", "backspace; ctrl-h"}, + {"Delete", "delete; ctrl-d"}, + {"Left", "left"}, + {"Right", "right"}, + {"Up", "up"}, + {"Down", "down"}, + {"Home", "home"}, + {"End", "end"}, + {"PageUp", "pgup"}, + {"PageDown", "pgdn"}, + {"WordLeft", "ctrl-left; ctrl-z"}, + {"WordRight", "ctrl-right; ctrl-x"}, + {"InsertOverwrite", "insert"}, + {"Help", "f1"}, + {"Save", "f2"}, + {"Mark", "f3"}, + {"Replace", "f4"}, + {"Copy", "f5"}, + {"Move", "f6"}, + {"Search", "f7"}, + {"Remove", "f8; ctrl-delete"}, + {"Menu", "f9"}, + {"Quit", "f10; esc"}, + {"UserMenu", "f11"}, + {"SaveAs", "f12; ctrl-f2"}, + {"MarkColumn", "f13"}, + {"ReplaceContinue", "f14; ctrl-f4"}, + {"InsertFile", "f15"}, + {"SearchContinue", "f17; ctrl-f7"}, + {"EditNew", "ctrl-n"}, + {"DeleteToWordBegin", "alt-backspace"}, + {"DeleteToWordEnd", "alt-d"}, + {"DeleteLine", "ctrl-y"}, + {"DeleteToEnd", "ctrl-k"}, + {"Undo", "ctrl-u; ctrl-backspace"}, + {"Redo", "alt-r"}, +#ifdef HAVE_CHARSET + {"SelectCodepage", "alt-e"}, +#endif + {"Goto", "alt-l; alt-shift-l"}, + {"Refresh", "ctrl-l"}, + {"Shell", "ctrl-o"}, + {"Top", "ctrl-home; ctrl-pgup; alt-lt"}, + {"Bottom", "ctrl-end; ctrl-pgdn; alt-gt"}, + {"TopOnScreen", "ctrl-pgup"}, + {"BottomOnScreen", "ctrl-pgdn"}, + {"ScrollUp", "ctrl-up"}, + {"ScrollDown", "ctrl-down"}, + {"Store", "ctrl-insert"}, + {"Paste", "shift-insert"}, + {"Cut", "shift-delete"}, + {"BlockSave", "ctrl-f"}, + {"MarkLeft", "shift-left"}, + {"MarkRight", "shift-right"}, + {"MarkUp", "shift-up"}, + {"MarkDown", "shift-down"}, + {"MarkPageUp", "shift-pgup"}, + {"MarkPageDown", "shift-pgdn"}, + {"MarkToWordBegin", "ctrl-shift-left"}, + {"MarkToWordEnd", "ctrl-shift-right"}, + {"MarkToHome", "shift-home"}, + {"MarkToEnd", "shift-end"}, + {"MarkToFileBegin", "ctrl-shift-home"}, + {"MarkToFileEnd", "ctrl-shift-end"}, + {"MarkToPageBegin", "ctrl-shift-pgup"}, + {"MarkToPageEnd", "ctrl-shift-pgdn"}, + {"MarkScrollUp", "ctrl-shift-up"}, + {"MarkScrollDown", "ctrl-shift-down"}, + {"MarkColumnLeft", "alt-left"}, + {"MarkColumnRight", "alt-right"}, + {"MarkColumnUp", "alt-up"}, + {"MarkColumnDown", "alt-down"}, + {"MarkColumnPageUp", "alt-pgup"}, + {"MarkColumnPageDown", "alt-pgdn"}, + {"InsertLiteral", "ctrl-q"}, + {"Complete", "alt-tab"}, + {"MatchBracket", "alt-b"}, + {"ParagraphFormat", "alt-p"}, + {"Bookmark", "alt-k"}, + {"BookmarkFlush", "alt-o"}, + {"BookmarkNext", "alt-j"}, + {"BookmarkPrev", "alt-i"}, + {"MacroStartStopRecord", "ctrl-r"}, + {"MacroExecute", "ctrl-a"}, + {"ShowNumbers", "alt-n"}, + {"ShowTabTws", "alt-underline"}, + {"SyntaxOnOff", "ctrl-s"}, + {"Find", "alt-enter"}, + {"FilePrev", "alt-minus"}, + {"FileNext", "alt-plus"}, + {"Sort", "alt-t"}, + {"Mail", "alt-m"}, + {"ExternalCommand", "alt-u"}, +#ifdef HAVE_ASPELL + {"SpellCheckCurrentWord", "ctrl-p"}, +#endif + {"ExtendedKeyMap", "ctrl-x"}, + {NULL, NULL} +}; + +/* emacs keyboard layout emulation */ +static const global_keymap_ini_t default_editor_x_keymap[] = { + {NULL, NULL} +}; +#endif /* USE_INTERNAL_EDIT */ + +/* viewer */ +static const global_keymap_ini_t default_viewer_keymap[] = { + {"Help", "f1"}, + {"WrapMode", "f2"}, + {"Quit", "f3; f10; q; esc"}, + {"HexMode", "f4"}, + {"Goto", "f5"}, + {"Search", "f7"}, + {"SearchContinue", "f17; n"}, + {"MagicMode", "f8"}, + {"NroffMode", "f9"}, + {"Home", "ctrl-a"}, + {"End", "ctrl-e"}, + {"Left", "h; left"}, + {"Right", "l; right"}, + {"LeftQuick", "ctrl-left"}, + {"RightQuick", "ctrl-right"}, + {"Up", "k; y; insert; up; ctrl-p"}, + {"Down", "j; e; delete; down; enter; ctrl-n"}, + {"PageDown", "f; space; pgdn; ctrl-v"}, + {"PageUp", "b; pgup; alt-v; backspace"}, + {"HalfPageDown", "d"}, + {"HalfPageUp", "u"}, + {"Top", "home; ctrl-home; ctrl-pgup; a1; alt-lt; g"}, + {"Bottom", "end; ctrl-end; ctrl-pgdn; c1; alt-gt; shift-g"}, + {"BookmarkGoto", "m"}, + {"Bookmark", "r"}, + {"FileNext", "ctrl-f"}, + {"FilePrev", "ctrl-b"}, +#ifdef HAVE_CHARSET + {"SelectCodepage", "alt-e"}, +#endif + {"Shell", "ctrl-o"}, + {"Ruler", "alt-r"}, + {"SearchForward", "slash"}, + {"SearchBackward", "question"}, + {"SearchForwardContinue", "ctrl-s"}, + {"SearchBackwardContinue", "ctrl-r"}, + {"SearchOppositeContinue", "shift-n"}, + {"History", "alt-shift-e"}, + {NULL, NULL} +}; + +/* hex viewer */ +static const global_keymap_ini_t default_viewer_hex_keymap[] = { + {"Help", "f1"}, + {"HexEditMode", "f2"}, + {"Quit", "f3; f10; q; esc"}, + {"HexMode", "f4"}, + {"Goto", "f5"}, + {"Save", "f6"}, + {"Search", "f7"}, + {"SearchContinue", "f17; n"}, + {"MagicMode", "f8"}, + {"NroffMode", "f9"}, + {"ToggleNavigation", "tab"}, + {"Home", "ctrl-a; home"}, + {"End", "ctrl-e; end"}, + {"Left", "b; left"}, + {"Right", "f; right"}, + {"Up", "k; y; up"}, + {"Down", "j; delete; down"}, + {"PageDown", "pgdn; ctrl-v"}, + {"PageUp", "pgup; alt-v"}, + {"Top", "ctrl-home; ctrl-pgup; a1; alt-lt; g"}, + {"Bottom", "ctrl-end; ctrl-pgdn; c1; alt-gt; shift-g"}, +#ifdef HAVE_CHARSET + {"SelectCodepage", "alt-e"}, +#endif + {"Shell", "ctrl-o"}, + {"SearchForward", "slash"}, + {"SearchBackward", "question"}, + {"SearchForwardContinue", "ctrl-s"}, + {"SearchBackwardContinue", "ctrl-r"}, + {"SearchOppositeContinue", "shift-n"}, + {"History", "alt-shift-e"}, + {NULL, NULL} +}; + +#ifdef USE_DIFF_VIEW +/* diff viewer */ +static const global_keymap_ini_t default_diff_keymap[] = { + {"ShowSymbols", "alt-s; s"}, + {"ShowNumbers", "alt-n; l"}, + {"SplitFull", "f"}, + {"SplitEqual", "equal"}, + {"SplitMore", "gt"}, + {"SplitLess", "lt"}, + {"Tab2", "2"}, + {"Tab3", "3"}, + {"Tab4", "4"}, + {"Tab8", "8"}, + {"Swap", "ctrl-u"}, + {"Redo", "ctrl-r"}, + {"HunkNext", "n; enter; space"}, + {"HunkPrev", "p; backspace"}, + {"Goto", "g; shift-g"}, + {"Save", "f2"}, + {"Edit", "f4"}, + {"EditOther", "f14"}, + {"Merge", "f5"}, + {"MergeOther", "f15"}, + {"Search", "f7"}, + {"SearchContinue", "f17"}, + {"Options", "f9"}, + {"Top", "ctrl-home"}, + {"Bottom", "ctrl-end"}, + {"Down", "down"}, + {"Up", "up"}, + {"LeftQuick", "ctrl-left"}, + {"RightQuick", "ctrl-right"}, + {"Left", "left"}, + {"Right", "right"}, + {"PageDown", "pgdn"}, + {"PageUp", "pgup"}, + {"Home", "home"}, + {"End", "end"}, + {"Help", "f1"}, + {"Quit", "f10; q; shift-q; esc"}, +#ifdef HAVE_CHARSET + {"SelectCodepage", "alt-e"}, +#endif + {"Shell", "ctrl-o"}, + {NULL, NULL} +}; +#endif + +/*** file scope macro definitions ****************************************************************/ + +/*** file scope type declarations ****************************************************************/ + +/*** file scope variables ************************************************************************/ + +/* --------------------------------------------------------------------------------------------- */ +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +static void +create_default_keymap_section (mc_config_t * keymap, const char *section, + const global_keymap_ini_t * k) +{ + size_t i; + + for (i = 0; k[i].key != NULL; i++) + mc_config_set_string_raw (keymap, section, k[i].key, k[i].value); +} + +/* --------------------------------------------------------------------------------------------- */ + +static mc_config_t * +create_default_keymap (void) +{ + mc_config_t *keymap; + + keymap = mc_config_init (NULL, TRUE); + + create_default_keymap_section (keymap, KEYMAP_SECTION_FILEMANAGER, default_filemanager_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_FILEMANAGER_EXT, + default_filemanager_x_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_PANEL, default_panel_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_DIALOG, default_dialog_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_MENU, default_menu_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_INPUT, default_input_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_LISTBOX, default_listbox_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_RADIO, default_radio_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_TREE, default_tree_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_HELP, default_help_keymap); +#ifdef ENABLE_EXT2FS_ATTR + create_default_keymap_section (keymap, KEYMAP_SECTION_HELP, default_chattr_keymap); +#endif +#ifdef USE_INTERNAL_EDIT + create_default_keymap_section (keymap, KEYMAP_SECTION_EDITOR, default_editor_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_EDITOR_EXT, default_editor_x_keymap); +#endif + create_default_keymap_section (keymap, KEYMAP_SECTION_VIEWER, default_viewer_keymap); + create_default_keymap_section (keymap, KEYMAP_SECTION_VIEWER_HEX, default_viewer_hex_keymap); +#ifdef USE_DIFF_VIEW + create_default_keymap_section (keymap, KEYMAP_SECTION_DIFFVIEWER, default_diff_keymap); +#endif + + return keymap; +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +load_keymap_from_section (const char *section_name, GArray * keymap, mc_config_t * cfg) +{ + gchar **profile_keys, **keys; + + if (section_name == NULL) + return; + + keys = mc_config_get_keys (cfg, section_name, NULL); + + for (profile_keys = keys; *profile_keys != NULL; profile_keys++) + { + gchar **values; + + values = mc_config_get_string_list (cfg, section_name, *profile_keys, NULL); + if (values != NULL) + { + long action; + + action = keybind_lookup_action (*profile_keys); + if (action > 0) + { + gchar **curr_values; + + for (curr_values = values; *curr_values != NULL; curr_values++) + keybind_cmd_bind (keymap, *curr_values, action); + } + + g_strfreev (values); + } + } + + g_strfreev (keys); +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Get name of config file. + * + * @param subdir If not NULL, config is also searched in specified subdir. + * @param config_file_name If relative, file if searched in standard paths. + * + * @return newly allocated string with config name or NULL if file is not found. + */ + +static char * +load_setup_get_full_config_name (const char *subdir, const char *config_file_name) +{ + /* + TODO: IMHO, in future, this function shall be placed in mcconfig module. + */ + char *lc_basename, *ret; + char *file_name; + + if (config_file_name == NULL) + return NULL; + + /* check for .keymap suffix */ + if (g_str_has_suffix (config_file_name, ".keymap")) + file_name = g_strdup (config_file_name); + else + file_name = g_strconcat (config_file_name, ".keymap", (char *) NULL); + + canonicalize_pathname (file_name); + + if (g_path_is_absolute (file_name)) + return file_name; + + lc_basename = g_path_get_basename (file_name); + g_free (file_name); + + if (lc_basename == NULL) + return NULL; + + if (subdir != NULL) + ret = g_build_filename (mc_config_get_path (), subdir, lc_basename, (char *) NULL); + else + ret = g_build_filename (mc_config_get_path (), lc_basename, (char *) NULL); + + if (exist_file (ret)) + { + g_free (lc_basename); + canonicalize_pathname (ret); + return ret; + } + g_free (ret); + + if (subdir != NULL) + ret = g_build_filename (mc_global.share_data_dir, subdir, lc_basename, (char *) NULL); + else + ret = g_build_filename (mc_global.share_data_dir, lc_basename, (char *) NULL); + + g_free (lc_basename); + + if (exist_file (ret)) + { + canonicalize_pathname (ret); + return ret; + } + + g_free (ret); + return NULL; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + Create new mc_config object from specified ini-file or + append data to existing mc_config object from ini-file +*/ + +static void +load_setup_init_config_from_file (mc_config_t ** config, const char *fname, gboolean read_only) +{ + /* + TODO: IMHO, in future, this function shall be placed in mcconfig module. + */ + if (exist_file (fname)) + { + if (*config != NULL) + mc_config_read_file (*config, fname, read_only, TRUE); + else + *config = mc_config_init (fname, read_only); + } +} + +/* --------------------------------------------------------------------------------------------- */ + +static mc_config_t * +load_setup_get_keymap_profile_config (gboolean load_from_file) +{ + /* + TODO: IMHO, in future, this function shall be placed in mcconfig module. + */ + mc_config_t *keymap_config; + char *share_keymap, *sysconfig_keymap; + char *fname, *fname2; + + /* 0) Create default keymap */ + keymap_config = create_default_keymap (); + if (!load_from_file) + return keymap_config; + + /* load and merge global keymaps */ + + /* 1) /usr/share/mc (mc_global.share_data_dir) */ + share_keymap = g_build_filename (mc_global.share_data_dir, GLOBAL_KEYMAP_FILE, (char *) NULL); + load_setup_init_config_from_file (&keymap_config, share_keymap, TRUE); + + /* 2) /etc/mc (mc_global.sysconfig_dir) */ + sysconfig_keymap = + g_build_filename (mc_global.sysconfig_dir, GLOBAL_KEYMAP_FILE, (char *) NULL); + load_setup_init_config_from_file (&keymap_config, sysconfig_keymap, TRUE); + + /* then load and merge one of user-defined keymap */ + + /* 3) --keymap=<keymap> */ + fname = load_setup_get_full_config_name (NULL, mc_args__keymap_file); + if (fname != NULL && strcmp (fname, sysconfig_keymap) != 0 && strcmp (fname, share_keymap) != 0) + { + load_setup_init_config_from_file (&keymap_config, fname, TRUE); + goto done; + } + g_free (fname); + + /* 4) getenv("MC_KEYMAP") */ + fname = load_setup_get_full_config_name (NULL, g_getenv ("MC_KEYMAP")); + if (fname != NULL && strcmp (fname, sysconfig_keymap) != 0 && strcmp (fname, share_keymap) != 0) + { + load_setup_init_config_from_file (&keymap_config, fname, TRUE); + goto done; + } + + MC_PTR_FREE (fname); + + /* 5) main config; [Midnight Commander] -> keymap */ + fname2 = mc_config_get_string (mc_global.main_config, CONFIG_APP_SECTION, "keymap", NULL); + if (fname2 != NULL && *fname2 != '\0') + fname = load_setup_get_full_config_name (NULL, fname2); + g_free (fname2); + if (fname != NULL && strcmp (fname, sysconfig_keymap) != 0 && strcmp (fname, share_keymap) != 0) + { + load_setup_init_config_from_file (&keymap_config, fname, TRUE); + goto done; + } + g_free (fname); + + /* 6) ${XDG_CONFIG_HOME}/mc/mc.keymap */ + fname = mc_config_get_full_path (GLOBAL_KEYMAP_FILE); + load_setup_init_config_from_file (&keymap_config, fname, TRUE); + + done: + g_free (fname); + g_free (sysconfig_keymap); + g_free (share_keymap); + + return keymap_config; +} + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +void +keymap_load (gboolean load_from_file) +{ + /* + * Load keymap from GLOBAL_KEYMAP_FILE before ${XDG_CONFIG_HOME}/mc/mc.keymap, so that the user + * definitions override global settings. + */ + mc_config_t *mc_global_keymap; + + mc_global_keymap = load_setup_get_keymap_profile_config (load_from_file); + + if (mc_global_keymap != NULL) + { +#define LOAD_KEYMAP(s,km) \ + km##_keymap = g_array_new (TRUE, FALSE, sizeof (global_keymap_t)); \ + load_keymap_from_section (KEYMAP_SECTION_##s, km##_keymap, mc_global_keymap) + + LOAD_KEYMAP (FILEMANAGER, filemanager); + LOAD_KEYMAP (FILEMANAGER_EXT, filemanager_x); + LOAD_KEYMAP (PANEL, panel); + LOAD_KEYMAP (DIALOG, dialog); + LOAD_KEYMAP (MENU, menu); + LOAD_KEYMAP (INPUT, input); + LOAD_KEYMAP (LISTBOX, listbox); + LOAD_KEYMAP (RADIO, radio); + LOAD_KEYMAP (TREE, tree); + LOAD_KEYMAP (HELP, help); +#ifdef ENABLE_EXT2FS_ATTR + LOAD_KEYMAP (CHATTR, chattr); +#endif +#ifdef USE_INTERNAL_EDIT + LOAD_KEYMAP (EDITOR, editor); + LOAD_KEYMAP (EDITOR_EXT, editor_x); +#endif + LOAD_KEYMAP (VIEWER, viewer); + LOAD_KEYMAP (VIEWER_HEX, viewer_hex); +#ifdef USE_DIFF_VIEW + LOAD_KEYMAP (DIFFVIEWER, diff); +#endif + +#undef LOAD_KEYMAP + mc_config_deinit (mc_global_keymap); + } + +#define SET_MAP(m) \ + m##_map = (global_keymap_t *) m##_keymap->data + + SET_MAP (filemanager); + SET_MAP (filemanager_x); + SET_MAP (panel); + SET_MAP (dialog); + SET_MAP (menu); + SET_MAP (input); + SET_MAP (listbox); + SET_MAP (radio); + SET_MAP (tree); + SET_MAP (help); +#ifdef ENABLE_EXT2FS_ATTR + SET_MAP (chattr); +#endif +#ifdef USE_INTERNAL_EDIT + SET_MAP (editor); + SET_MAP (editor_x); +#endif + SET_MAP (viewer); + SET_MAP (viewer_hex); +#ifdef USE_DIFF_VIEW + SET_MAP (diff); +#endif + +#undef SET_MAP +} + +/* --------------------------------------------------------------------------------------------- */ + +void +keymap_free (void) +{ +#define FREE_KEYMAP(km) \ + if (km##_keymap != NULL) \ + g_array_free (km##_keymap, TRUE) + + FREE_KEYMAP (filemanager); + FREE_KEYMAP (filemanager_x); + FREE_KEYMAP (panel); + FREE_KEYMAP (dialog); + FREE_KEYMAP (menu); + FREE_KEYMAP (input); + FREE_KEYMAP (listbox); + FREE_KEYMAP (radio); + FREE_KEYMAP (tree); + FREE_KEYMAP (help); +#ifdef ENABLE_EXT2FS_ATTR + FREE_KEYMAP (chattr); +#endif +#ifdef USE_INTERNAL_EDIT + FREE_KEYMAP (editor); + FREE_KEYMAP (editor_x); +#endif + FREE_KEYMAP (viewer); + FREE_KEYMAP (viewer_hex); +#ifdef USE_DIFF_VIEW + FREE_KEYMAP (diff); +#endif + +#undef FREE_KEYMAP +} + +/* --------------------------------------------------------------------------------------------- */ |