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