panels: Show archive name when entering to archive
[midnight-commander.git] / lib / keybind.c
blob451d0d757df1baf165177f6cbf64bcd40622cab8
1 /*
2 Definitions of key bindings.
4 Copyright (C) 2009, 2011
5 The Free Software Foundation, Inc.
7 Written by:
8 Vitja Makarov, 2005
9 Ilia Maslakov <il.smind@gmail.com>, 2009
10 Andrew Borodin <aborodin@vmail.ru>, 2009, 2010
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 <ctype.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/types.h>
35 #include "lib/global.h"
36 #include "lib/tty/key.h" /* KEY_M_ */
37 #include "lib/keybind.h"
39 /*** global variables ****************************************************************************/
41 /*** file scope macro definitions ****************************************************************/
43 /*** file scope type declarations ****************************************************************/
45 /*** file scope variables ************************************************************************/
47 static name_keymap_t command_names[] = {
48 /* common */
49 {"Enter", CK_Enter},
50 {"Up", CK_Up},
51 {"Down", CK_Down},
52 {"Left", CK_Left},
53 {"Right", CK_Right},
54 {"LeftQuick", CK_LeftQuick},
55 {"RightQuick", CK_RightQuick},
56 {"Home", CK_Home},
57 {"End", CK_End},
58 {"PageUp", CK_PageUp},
59 {"PageDown", CK_PageDown},
60 {"HalfPageUp", CK_HalfPageUp},
61 {"HalfPageDown", CK_HalfPageDown},
62 {"Top", CK_Top},
63 {"Bottom", CK_Bottom},
64 {"TopOnScreen", CK_TopOnScreen},
65 {"MiddleOnScreen", CK_MiddleOnScreen},
66 {"BottomOnScreen", CK_BottomOnScreen},
67 {"WordLeft", CK_WordLeft},
68 {"WordRight", CK_WordRight},
69 {"Copy", CK_Copy},
70 {"Move", CK_Move},
71 {"Delete", CK_Delete},
72 {"MakeDir", CK_MakeDir},
73 {"ChangeMode", CK_ChangeMode},
74 {"ChangeOwn", CK_ChangeOwn},
75 {"ChangeOwnAdvanced", CK_ChangeOwnAdvanced},
76 {"Remove", CK_Remove},
77 {"BackSpace", CK_BackSpace},
78 {"Redo", CK_Redo},
79 {"Clear", CK_Clear},
80 {"Menu", CK_Menu},
81 {"MenuLastSelected", CK_MenuLastSelected},
82 {"UserMenu", CK_UserMenu},
83 {"EditUserMenu", CK_EditUserMenu},
84 {"Search", CK_Search},
85 {"SearchContinue", CK_SearchContinue},
86 {"Replace", CK_Replace},
87 {"ReplaceContinue", CK_ReplaceContinue},
88 {"Help", CK_Help},
89 {"Shell", CK_Shell},
90 {"Edit", CK_Edit},
91 {"EditNew", CK_EditNew},
92 #ifdef HAVE_CHARSET
93 {"SelectCodepage", CK_SelectCodepage},
94 #endif
95 {"History", CK_History},
96 {"HistoryNext", CK_HistoryNext},
97 {"HistoryPrev", CK_HistoryPrev},
98 {"Complete", CK_Complete},
99 {"Save", CK_Save},
100 {"SaveAs", CK_SaveAs},
101 {"Goto", CK_Goto},
102 {"Reread", CK_Reread},
103 {"Refresh", CK_Refresh},
104 {"Suspend", CK_Suspend},
105 {"Swap", CK_Swap},
106 {"HotList", CK_HotList},
107 {"SelectInvert", CK_SelectInvert},
108 {"ScreenList", CK_ScreenList},
109 {"ScreenNext", CK_ScreenNext},
110 {"ScreenPrev", CK_ScreenPrev},
111 {"FileNext", CK_FileNext},
112 {"FilePrev", CK_FilePrev},
113 {"DeleteToHome", CK_DeleteToHome},
114 {"DeleteToEnd", CK_DeleteToEnd},
115 {"DeleteToWordBegin", CK_DeleteToWordBegin},
116 {"DeleteToWordEnd", CK_DeleteToWordEnd},
117 {"Cut", CK_Cut},
118 {"Store", CK_Store},
119 {"Paste", CK_Paste},
120 {"Mark", CK_Mark},
121 {"MarkLeft", CK_MarkLeft},
122 {"MarkRight", CK_MarkRight},
123 {"MarkUp", CK_MarkUp},
124 {"MarkDown", CK_MarkDown},
125 {"MarkToWordBegin", CK_MarkToWordBegin},
126 {"MarkToWordEnd", CK_MarkToWordEnd},
127 {"MarkToHome", CK_MarkToHome},
128 {"MarkToEnd", CK_MarkToEnd},
129 {"ToggleNavigation", CK_ToggleNavigation},
130 {"Sort", CK_Sort},
131 {"Options", CK_Options},
132 {"LearnKeys", CK_LearnKeys},
133 {"Bookmark", CK_Bookmark},
134 {"Quit", CK_Quit},
135 {"QuitQuiet", CK_QuitQuiet},
136 {"ExtendedKeyMap", CK_ExtendedKeyMap},
138 /* main commands */
139 #ifdef USE_INTERNAL_EDIT
140 {"EditForceInternal", CK_EditForceInternal},
141 #endif
142 {"View", CK_View},
143 {"ViewRaw", CK_ViewRaw},
144 {"ViewFile", CK_ViewFile},
145 {"ViewFiltered", CK_ViewFiltered},
146 {"Find", CK_Find},
147 {"DirSize", CK_DirSize},
148 {"PanelListingSwitch", CK_PanelListingSwitch},
149 {"CompareDirs", CK_CompareDirs},
150 #ifdef USE_DIFF_VIEW
151 {"CompareFiles", CK_CompareFiles},
152 #endif
153 {"OptionsVfs", CK_OptionsVfs},
154 {"OptionsConfirm", CK_OptionsConfirm},
155 {"OptionsDisplayBits", CK_OptionsDisplayBits},
156 {"EditExtensionsFile", CK_EditExtensionsFile},
157 {"EditFileHighlightFile", CK_EditFileHighlightFile},
158 {"LinkSymbolicEdit", CK_LinkSymbolicEdit},
159 {"ExternalPanelize", CK_ExternalPanelize},
160 {"Filter", CK_Filter},
161 #ifdef ENABLE_VFS_FISH
162 {"ConnectFish", CK_ConnectFish},
163 #endif
164 #ifdef ENABLE_VFS_FTP
165 {"ConnectFtp", CK_ConnectFtp},
166 #endif
167 #ifdef ENABLE_VFS_SMB
168 {"ConnectSmb", CK_ConnectSmb},
169 #endif
170 {"PanelInfo", CK_PanelInfo},
171 #ifdef ENABLE_BACKGROUND
172 {"Jobs", CK_Jobs},
173 #endif
174 {"OptionsLayout", CK_OptionsLayout},
175 {"Link", CK_Link},
176 {"PanelListingChange", CK_PanelListingChange},
177 {"PanelListing", CK_PanelListing},
178 #ifdef LISTMODE_EDITOR
179 {"ListMode", CK_ListMode}.
180 #endif
181 {"OptionsPanel", CK_OptionsPanel},
182 {"CdQuick", CK_CdQuick},
183 {"PanelQuickView", CK_PanelQuickView},
184 {"LinkSymbolicRelative", CK_LinkSymbolicRelative},
185 {"VfsList", CK_VfsList},
186 {"SaveSetup", CK_SaveSetup},
187 {"LinkSymbolic", CK_LinkSymbolic},
188 {"PanelTree", CK_PanelTree},
189 {"Tree", CK_Tree},
190 #ifdef ENABLE_VFS_UNDELFS
191 {"Undelete", CK_Undelete},
192 #endif
193 {"PutCurrentLink", CK_PutCurrentLink},
194 {"PutOtherLink", CK_PutOtherLink},
195 {"HotListAdd", CK_HotListAdd},
196 {"ShowHidden", CK_ShowHidden},
197 {"SplitVertHoriz", CK_SplitVertHoriz},
198 {"PutCurrentPath", CK_PutCurrentPath},
199 {"PutOtherPath", CK_PutOtherPath},
200 {"PutCurrentTagged", CK_PutCurrentTagged},
201 {"PutOtherTagged", CK_PutOtherTagged},
202 {"Select", CK_Select},
203 {"Unselect", CK_Unselect},
205 /* panel */
206 {"PanelOtherCd", CK_PanelOtherCd},
207 {"PanelOtherCdLink", CK_PanelOtherCdLink},
208 {"CopySingle", CK_CopySingle},
209 {"MoveSingle", CK_MoveSingle},
210 {"DeleteSingle", CK_DeleteSingle},
211 {"CdParent", CK_CdParent},
212 {"CdChild", CK_CdChild},
213 {"Panelize", CK_Panelize},
214 {"PanelOtherSync", CK_PanelOtherSync},
215 {"SortNext", CK_SortNext},
216 {"SortPrev", CK_SortPrev},
217 {"SortReverse", CK_SortReverse},
218 {"SortByName", CK_SortByName},
219 {"SortByExt", CK_SortByExt},
220 {"SortBySize", CK_SortBySize},
221 {"SortByMTime", CK_SortByMTime},
222 {"CdParentSmart", CK_CdParentSmart},
224 /* dialog */
225 {"Ok", CK_Ok},
226 {"Cancel", CK_Cancel},
228 /* input line */
229 {"Yank", CK_Yank},
231 /* help */
232 {"Index", CK_Index},
233 {"Back", CK_Back},
234 {"LinkNext", CK_LinkNext},
235 {"LinkPrev", CK_LinkPrev},
236 {"NodeNext", CK_NodeNext},
237 {"NodePrev", CK_NodePrev},
239 /* tree */
240 {"Forget", CK_Forget},
242 #if defined (USE_INTERNAL_EDIT) || defined (USE_DIFF_VIEW)
243 {"ShowNumbers", CK_ShowNumbers},
244 #endif
246 #ifdef USE_INTERNAL_EDIT
247 {"Tab", CK_Tab},
248 {"Undo", CK_Undo},
249 {"ScrollUp", CK_ScrollUp},
250 {"ScrollDown", CK_ScrollDown},
251 {"Return", CK_Return},
252 {"ParagraphUp", CK_ParagraphUp},
253 {"ParagraphDown", CK_ParagraphDown},
254 {"EditFile", CK_EditFile},
255 {"MarkWord", CK_MarkWord},
256 {"MarkLine", CK_MarkLine},
257 {"MarkAll", CK_MarkAll},
258 {"Unmark", CK_Unmark},
259 {"MarkColumn", CK_MarkColumn},
260 {"BlockSave", CK_BlockSave},
261 {"InsertFile", CK_InsertFile},
262 {"InsertOverwrite", CK_InsertOverwrite},
263 {"Date", CK_Date},
264 {"DeleteLine", CK_DeleteLine},
265 {"EditMail", CK_Mail},
266 {"ParagraphFormat", CK_ParagraphFormat},
267 {"MatchBracket", CK_MatchBracket},
268 {"ExternalCommand", CK_ExternalCommand},
269 {"MacroStartRecord", CK_MacroStartRecord},
270 {"MacroStopRecord", CK_MacroStopRecord},
271 {"MacroStartStopRecord", CK_MacroStartStopRecord},
272 {"MacroDelete", CK_MacroDelete},
273 {"RepeatStartStopRecord", CK_RepeatStartStopRecord},
274 {"BookmarkFlush", CK_BookmarkFlush},
275 {"BookmarkNext", CK_BookmarkNext},
276 {"BookmarkPrev", CK_BookmarkPrev},
277 {"MarkPageUp", CK_MarkPageUp},
278 {"MarkPageDown", CK_MarkPageDown},
279 {"MarkToFileBegin", CK_MarkToFileBegin},
280 {"MarkToFileEnd", CK_MarkToFileEnd},
281 {"MarkToPageBegin", CK_MarkToPageBegin},
282 {"MarkToPageEnd", CK_MarkToPageEnd},
283 {"MarkScrollUp", CK_MarkScrollUp},
284 {"MarkScrollDown", CK_MarkScrollDown},
285 {"MarkParagraphUp", CK_MarkParagraphUp},
286 {"MarkParagraphDown", CK_MarkParagraphDown},
287 {"MarkColumnPageUp", CK_MarkColumnPageUp},
288 {"MarkColumnPageDown", CK_MarkColumnPageDown},
289 {"MarkColumnLeft", CK_MarkColumnLeft},
290 {"MarkColumnRight", CK_MarkColumnRight},
291 {"MarkColumnUp", CK_MarkColumnUp},
292 {"MarkColumnDown", CK_MarkColumnDown},
293 {"MarkColumnScrollUp", CK_MarkColumnScrollUp},
294 {"MarkColumnScrollDown", CK_MarkColumnScrollDown},
295 {"MarkColumnParagraphUp", CK_MarkColumnParagraphUp},
296 {"MarkColumnParagraphDown", CK_MarkColumnParagraphDown},
297 {"BlockShiftLeft", CK_BlockShiftLeft},
298 {"BlockShiftRight", CK_BlockShiftRight},
299 {"InsertLiteral", CK_InsertLiteral},
300 {"ShowTabTws", CK_ShowTabTws},
301 {"SyntaxOnOff", CK_SyntaxOnOff},
302 {"SyntaxChoose", CK_SyntaxChoose},
303 {"ShowMargin", CK_ShowMargin},
304 {"OptionsSaveMode", CK_OptionsSaveMode},
305 {"About", CK_About},
306 /* An action to run external script from macro */
307 {"ExecuteScript", CK_PipeBlock (0)},
308 #endif /* USE_INTERNAL_EDIT */
310 /* viewer */
311 {"WrapMode", CK_WrapMode},
312 {"HexEditMode", CK_HexEditMode},
313 {"HexMode", CK_HexMode},
314 {"MagicMode", CK_MagicMode},
315 {"NroffMode", CK_NroffMode},
316 {"BookmarkGoto", CK_BookmarkGoto},
317 {"Ruler", CK_Ruler},
318 {"SearchForward", CK_SearchForward},
319 {"SearchBackward", CK_SearchBackward},
320 {"SearchForwardContinue", CK_SearchForwardContinue},
321 {"SearchBackwardContinue", CK_SearchBackwardContinue},
323 #ifdef USE_DIFF_VIEW
324 /* diff viewer */
325 {"ShowSymbols", CK_ShowSymbols},
326 {"SplitFull", CK_SplitFull},
327 {"SplitEqual", CK_SplitEqual},
328 {"SplitMore", CK_SplitMore},
329 {"SplitLess", CK_SplitLess},
330 {"Tab2", CK_Tab2},
331 {"Tab3", CK_Tab3},
332 {"Tab4", CK_Tab4},
333 {"Tab8", CK_Tab8},
334 {"HunkNext", CK_HunkNext},
335 {"HunkPrev", CK_HunkPrev},
336 {"EditOther", CK_EditOther},
337 {"Merge", CK_Merge},
338 #endif /* USE_DIFF_VIEW */
340 {NULL, CK_IgnoreKey}
343 /* *INDENT-OFF* */
344 static const size_t num_command_names = G_N_ELEMENTS (command_names) - 1;
345 /* *INDENT-ON* */
347 /*** file scope functions ************************************************************************/
348 /* --------------------------------------------------------------------------------------------- */
350 static int
351 name_keymap_comparator (const void *p1, const void *p2)
353 const name_keymap_t *m1 = (const name_keymap_t *) p1;
354 const name_keymap_t *m2 = (const name_keymap_t *) p2;
356 return g_ascii_strcasecmp (m1->name, m2->name);
359 /* --------------------------------------------------------------------------------------------- */
361 static inline void
362 sort_command_names (void)
364 static gboolean has_been_sorted = FALSE;
366 if (!has_been_sorted)
368 qsort (command_names, num_command_names,
369 sizeof (command_names[0]), &name_keymap_comparator);
370 has_been_sorted = TRUE;
374 /* --------------------------------------------------------------------------------------------- */
376 static void
377 keymap_add (GArray * keymap, long key, unsigned long cmd, const char *caption)
379 if (key != 0 && cmd != CK_IgnoreKey)
381 global_keymap_t new_bind;
383 new_bind.key = key;
384 new_bind.command = cmd;
385 g_snprintf (new_bind.caption, sizeof (new_bind.caption), "%s", caption);
386 g_array_append_val (keymap, new_bind);
390 /* --------------------------------------------------------------------------------------------- */
391 /*** public functions ****************************************************************************/
392 /* --------------------------------------------------------------------------------------------- */
394 void
395 keybind_cmd_bind (GArray * keymap, const char *keybind, unsigned long action)
397 char *caption = NULL;
398 long key;
400 key = lookup_key (keybind, &caption);
401 keymap_add (keymap, key, action, caption);
402 g_free (caption);
405 /* --------------------------------------------------------------------------------------------- */
407 unsigned long
408 keybind_lookup_action (const char *name)
410 const name_keymap_t key = { name, 0 };
411 name_keymap_t *res;
413 sort_command_names ();
415 res = bsearch (&key, command_names, num_command_names,
416 sizeof (command_names[0]), name_keymap_comparator);
418 return (res != NULL) ? res->val : CK_IgnoreKey;
421 /* --------------------------------------------------------------------------------------------- */
423 const char *
424 keybind_lookup_actionname (unsigned long action)
426 size_t i;
428 for (i = 0; command_names[i].name != NULL; i++)
429 if (command_names[i].val == action)
430 return command_names[i].name;
432 return NULL;
435 /* --------------------------------------------------------------------------------------------- */
437 const char *
438 keybind_lookup_keymap_shortcut (const global_keymap_t * keymap, unsigned long action)
440 size_t i;
442 if (keymap != NULL)
443 for (i = 0; keymap[i].key != 0; i++)
444 if (keymap[i].command == action)
445 return (keymap[i].caption[0] != '\0') ? keymap[i].caption : NULL;
447 return NULL;
450 /* --------------------------------------------------------------------------------------------- */
452 unsigned long
453 keybind_lookup_keymap_command (const global_keymap_t * keymap, long key)
455 size_t i;
457 if (keymap != NULL)
458 for (i = 0; keymap[i].key != 0; i++)
459 if (keymap[i].key == key)
460 return keymap[i].command;
462 return CK_IgnoreKey;
465 /* --------------------------------------------------------------------------------------------- */