Merge branch '4562_mcedit_macros_paste'
[midnight-commander.git] / lib / keybind.c
blobc0b882091076cab7cfbe696c6b17a62d137bb16d
1 /*
2 Definitions of key bindings.
4 Copyright (C) 2005-2024
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-2020
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 #define ADD_KEYMAP_NAME(name) \
44 { #name, CK_##name }
46 /*** file scope type declarations ****************************************************************/
48 typedef struct name_keymap_t
50 const char *name;
51 long val;
52 } name_keymap_t;
54 /*** forward declarations (file scope functions) *************************************************/
56 /*** file scope variables ************************************************************************/
58 static name_keymap_t command_names[] = {
59 /* common */
60 ADD_KEYMAP_NAME (InsertChar),
61 ADD_KEYMAP_NAME (Enter),
62 ADD_KEYMAP_NAME (ChangePanel),
63 ADD_KEYMAP_NAME (Up),
64 ADD_KEYMAP_NAME (Down),
65 ADD_KEYMAP_NAME (Left),
66 ADD_KEYMAP_NAME (Right),
67 ADD_KEYMAP_NAME (LeftQuick),
68 ADD_KEYMAP_NAME (RightQuick),
69 ADD_KEYMAP_NAME (Home),
70 ADD_KEYMAP_NAME (End),
71 ADD_KEYMAP_NAME (PageUp),
72 ADD_KEYMAP_NAME (PageDown),
73 ADD_KEYMAP_NAME (HalfPageUp),
74 ADD_KEYMAP_NAME (HalfPageDown),
75 ADD_KEYMAP_NAME (Top),
76 ADD_KEYMAP_NAME (Bottom),
77 ADD_KEYMAP_NAME (TopOnScreen),
78 ADD_KEYMAP_NAME (MiddleOnScreen),
79 ADD_KEYMAP_NAME (BottomOnScreen),
80 ADD_KEYMAP_NAME (WordLeft),
81 ADD_KEYMAP_NAME (WordRight),
82 ADD_KEYMAP_NAME (Copy),
83 ADD_KEYMAP_NAME (Move),
84 ADD_KEYMAP_NAME (Delete),
85 ADD_KEYMAP_NAME (MakeDir),
86 ADD_KEYMAP_NAME (ChangeMode),
87 ADD_KEYMAP_NAME (ChangeOwn),
88 ADD_KEYMAP_NAME (ChangeOwnAdvanced),
89 #ifdef ENABLE_EXT2FS_ATTR
90 ADD_KEYMAP_NAME (ChangeAttributes),
91 #endif
92 ADD_KEYMAP_NAME (Remove),
93 ADD_KEYMAP_NAME (BackSpace),
94 ADD_KEYMAP_NAME (Redo),
95 ADD_KEYMAP_NAME (Clear),
96 ADD_KEYMAP_NAME (Menu),
97 ADD_KEYMAP_NAME (MenuLastSelected),
98 ADD_KEYMAP_NAME (UserMenu),
99 ADD_KEYMAP_NAME (EditUserMenu),
100 ADD_KEYMAP_NAME (Search),
101 ADD_KEYMAP_NAME (SearchContinue),
102 ADD_KEYMAP_NAME (Replace),
103 ADD_KEYMAP_NAME (ReplaceContinue),
104 ADD_KEYMAP_NAME (Help),
105 ADD_KEYMAP_NAME (Shell),
106 ADD_KEYMAP_NAME (Edit),
107 ADD_KEYMAP_NAME (EditNew),
108 #ifdef HAVE_CHARSET
109 ADD_KEYMAP_NAME (SelectCodepage),
110 #endif
111 ADD_KEYMAP_NAME (EditorViewerHistory),
112 ADD_KEYMAP_NAME (History),
113 ADD_KEYMAP_NAME (HistoryNext),
114 ADD_KEYMAP_NAME (HistoryPrev),
115 ADD_KEYMAP_NAME (Complete),
116 ADD_KEYMAP_NAME (Save),
117 ADD_KEYMAP_NAME (SaveAs),
118 ADD_KEYMAP_NAME (Goto),
119 ADD_KEYMAP_NAME (Reread),
120 ADD_KEYMAP_NAME (Refresh),
121 ADD_KEYMAP_NAME (Suspend),
122 ADD_KEYMAP_NAME (Swap),
123 ADD_KEYMAP_NAME (HotList),
124 ADD_KEYMAP_NAME (SelectInvert),
125 ADD_KEYMAP_NAME (ScreenList),
126 ADD_KEYMAP_NAME (ScreenNext),
127 ADD_KEYMAP_NAME (ScreenPrev),
128 ADD_KEYMAP_NAME (FileNext),
129 ADD_KEYMAP_NAME (FilePrev),
130 ADD_KEYMAP_NAME (DeleteToHome),
131 ADD_KEYMAP_NAME (DeleteToEnd),
132 ADD_KEYMAP_NAME (DeleteToWordBegin),
133 ADD_KEYMAP_NAME (DeleteToWordEnd),
134 ADD_KEYMAP_NAME (Cut),
135 ADD_KEYMAP_NAME (Store),
136 ADD_KEYMAP_NAME (Paste),
137 ADD_KEYMAP_NAME (Mark),
138 ADD_KEYMAP_NAME (MarkLeft),
139 ADD_KEYMAP_NAME (MarkRight),
140 ADD_KEYMAP_NAME (MarkUp),
141 ADD_KEYMAP_NAME (MarkDown),
142 ADD_KEYMAP_NAME (MarkToWordBegin),
143 ADD_KEYMAP_NAME (MarkToWordEnd),
144 ADD_KEYMAP_NAME (MarkToHome),
145 ADD_KEYMAP_NAME (MarkToEnd),
146 ADD_KEYMAP_NAME (ToggleNavigation),
147 ADD_KEYMAP_NAME (Sort),
148 ADD_KEYMAP_NAME (Options),
149 ADD_KEYMAP_NAME (LearnKeys),
150 ADD_KEYMAP_NAME (Bookmark),
151 ADD_KEYMAP_NAME (Quit),
152 ADD_KEYMAP_NAME (QuitQuiet),
153 ADD_KEYMAP_NAME (ExtendedKeyMap),
155 /* main commands */
156 #ifdef USE_INTERNAL_EDIT
157 ADD_KEYMAP_NAME (EditForceInternal),
158 #endif
159 ADD_KEYMAP_NAME (View),
160 ADD_KEYMAP_NAME (ViewRaw),
161 ADD_KEYMAP_NAME (ViewFile),
162 ADD_KEYMAP_NAME (ViewFiltered),
163 ADD_KEYMAP_NAME (Find),
164 ADD_KEYMAP_NAME (DirSize),
165 ADD_KEYMAP_NAME (CompareDirs),
166 #ifdef USE_DIFF_VIEW
167 ADD_KEYMAP_NAME (CompareFiles),
168 #endif
169 ADD_KEYMAP_NAME (OptionsVfs),
170 ADD_KEYMAP_NAME (OptionsConfirm),
171 ADD_KEYMAP_NAME (OptionsDisplayBits),
172 ADD_KEYMAP_NAME (EditExtensionsFile),
173 ADD_KEYMAP_NAME (EditFileHighlightFile),
174 ADD_KEYMAP_NAME (LinkSymbolicEdit),
175 ADD_KEYMAP_NAME (ExternalPanelize),
176 ADD_KEYMAP_NAME (Filter),
177 #ifdef ENABLE_VFS_SHELL
178 ADD_KEYMAP_NAME (ConnectShell),
179 #endif
180 #ifdef ENABLE_VFS_FTP
181 ADD_KEYMAP_NAME (ConnectFtp),
182 #endif
183 #ifdef ENABLE_VFS_SFTP
184 ADD_KEYMAP_NAME (ConnectSftp),
185 #endif
186 ADD_KEYMAP_NAME (PanelInfo),
187 #ifdef ENABLE_BACKGROUND
188 ADD_KEYMAP_NAME (Jobs),
189 #endif
190 ADD_KEYMAP_NAME (OptionsLayout),
191 ADD_KEYMAP_NAME (OptionsAppearance),
192 ADD_KEYMAP_NAME (Link),
193 ADD_KEYMAP_NAME (SetupListingFormat),
194 ADD_KEYMAP_NAME (PanelListing),
195 #ifdef LISTMODE_EDITOR
196 ADD_KEYMAP_NAME (ListMode),
197 #endif
198 ADD_KEYMAP_NAME (OptionsPanel),
199 ADD_KEYMAP_NAME (CdQuick),
200 ADD_KEYMAP_NAME (PanelQuickView),
201 ADD_KEYMAP_NAME (LinkSymbolicRelative),
202 ADD_KEYMAP_NAME (VfsList),
203 ADD_KEYMAP_NAME (SaveSetup),
204 ADD_KEYMAP_NAME (LinkSymbolic),
205 ADD_KEYMAP_NAME (PanelTree),
206 ADD_KEYMAP_NAME (Tree),
207 #ifdef ENABLE_VFS_UNDELFS
208 ADD_KEYMAP_NAME (Undelete),
209 #endif
210 ADD_KEYMAP_NAME (PutCurrentLink),
211 ADD_KEYMAP_NAME (PutOtherLink),
212 ADD_KEYMAP_NAME (HotListAdd),
213 ADD_KEYMAP_NAME (ShowHidden),
214 ADD_KEYMAP_NAME (SplitVertHoriz),
215 ADD_KEYMAP_NAME (SplitEqual),
216 ADD_KEYMAP_NAME (SplitMore),
217 ADD_KEYMAP_NAME (SplitLess),
218 ADD_KEYMAP_NAME (PutCurrentPath),
219 ADD_KEYMAP_NAME (PutOtherPath),
220 ADD_KEYMAP_NAME (PutCurrentSelected),
221 ADD_KEYMAP_NAME (PutCurrentFullSelected),
222 ADD_KEYMAP_NAME (PutCurrentTagged),
223 ADD_KEYMAP_NAME (PutOtherTagged),
224 ADD_KEYMAP_NAME (Select),
225 ADD_KEYMAP_NAME (Unselect),
227 /* panel */
228 ADD_KEYMAP_NAME (SelectExt),
229 ADD_KEYMAP_NAME (ScrollLeft),
230 ADD_KEYMAP_NAME (ScrollRight),
231 ADD_KEYMAP_NAME (PanelOtherCd),
232 ADD_KEYMAP_NAME (PanelOtherCdLink),
233 ADD_KEYMAP_NAME (CopySingle),
234 ADD_KEYMAP_NAME (MoveSingle),
235 ADD_KEYMAP_NAME (DeleteSingle),
236 ADD_KEYMAP_NAME (CdParent),
237 ADD_KEYMAP_NAME (CdChild),
238 ADD_KEYMAP_NAME (Panelize),
239 ADD_KEYMAP_NAME (PanelOtherSync),
240 ADD_KEYMAP_NAME (SortNext),
241 ADD_KEYMAP_NAME (SortPrev),
242 ADD_KEYMAP_NAME (SortReverse),
243 ADD_KEYMAP_NAME (SortByName),
244 ADD_KEYMAP_NAME (SortByExt),
245 ADD_KEYMAP_NAME (SortBySize),
246 ADD_KEYMAP_NAME (SortByMTime),
247 ADD_KEYMAP_NAME (CdParentSmart),
248 ADD_KEYMAP_NAME (CycleListingFormat),
250 /* dialog */
251 ADD_KEYMAP_NAME (Ok),
252 ADD_KEYMAP_NAME (Cancel),
254 /* input line */
255 ADD_KEYMAP_NAME (Yank),
257 /* help */
258 ADD_KEYMAP_NAME (Index),
259 ADD_KEYMAP_NAME (Back),
260 ADD_KEYMAP_NAME (LinkNext),
261 ADD_KEYMAP_NAME (LinkPrev),
262 ADD_KEYMAP_NAME (NodeNext),
263 ADD_KEYMAP_NAME (NodePrev),
265 /* tree */
266 ADD_KEYMAP_NAME (Forget),
268 #if defined (USE_INTERNAL_EDIT) || defined (USE_DIFF_VIEW)
269 ADD_KEYMAP_NAME (ShowNumbers),
270 #endif
272 /* chattr dialog */
273 ADD_KEYMAP_NAME (MarkAndDown),
275 #ifdef USE_INTERNAL_EDIT
276 ADD_KEYMAP_NAME (Close),
277 ADD_KEYMAP_NAME (Tab),
278 ADD_KEYMAP_NAME (Undo),
279 ADD_KEYMAP_NAME (ScrollUp),
280 ADD_KEYMAP_NAME (ScrollDown),
281 ADD_KEYMAP_NAME (Return),
282 ADD_KEYMAP_NAME (ParagraphUp),
283 ADD_KEYMAP_NAME (ParagraphDown),
284 ADD_KEYMAP_NAME (EditFile),
285 ADD_KEYMAP_NAME (MarkWord),
286 ADD_KEYMAP_NAME (MarkLine),
287 ADD_KEYMAP_NAME (MarkAll),
288 ADD_KEYMAP_NAME (Unmark),
289 ADD_KEYMAP_NAME (MarkColumn),
290 ADD_KEYMAP_NAME (BlockSave),
291 ADD_KEYMAP_NAME (InsertFile),
292 ADD_KEYMAP_NAME (InsertOverwrite),
293 ADD_KEYMAP_NAME (Date),
294 ADD_KEYMAP_NAME (DeleteLine),
295 ADD_KEYMAP_NAME (EditMail),
296 ADD_KEYMAP_NAME (ParagraphFormat),
297 ADD_KEYMAP_NAME (MatchBracket),
298 ADD_KEYMAP_NAME (ExternalCommand),
299 ADD_KEYMAP_NAME (MacroStartRecord),
300 ADD_KEYMAP_NAME (MacroStopRecord),
301 ADD_KEYMAP_NAME (MacroStartStopRecord),
302 ADD_KEYMAP_NAME (MacroDelete),
303 ADD_KEYMAP_NAME (RepeatStartStopRecord),
304 #ifdef HAVE_ASPELL
305 ADD_KEYMAP_NAME (SpellCheck),
306 ADD_KEYMAP_NAME (SpellCheckCurrentWord),
307 ADD_KEYMAP_NAME (SpellCheckSelectLang),
308 #endif /* HAVE_ASPELL */
309 ADD_KEYMAP_NAME (BookmarkFlush),
310 ADD_KEYMAP_NAME (BookmarkNext),
311 ADD_KEYMAP_NAME (BookmarkPrev),
312 ADD_KEYMAP_NAME (MarkPageUp),
313 ADD_KEYMAP_NAME (MarkPageDown),
314 ADD_KEYMAP_NAME (MarkToFileBegin),
315 ADD_KEYMAP_NAME (MarkToFileEnd),
316 ADD_KEYMAP_NAME (MarkToPageBegin),
317 ADD_KEYMAP_NAME (MarkToPageEnd),
318 ADD_KEYMAP_NAME (MarkScrollUp),
319 ADD_KEYMAP_NAME (MarkScrollDown),
320 ADD_KEYMAP_NAME (MarkParagraphUp),
321 ADD_KEYMAP_NAME (MarkParagraphDown),
322 ADD_KEYMAP_NAME (MarkColumnPageUp),
323 ADD_KEYMAP_NAME (MarkColumnPageDown),
324 ADD_KEYMAP_NAME (MarkColumnLeft),
325 ADD_KEYMAP_NAME (MarkColumnRight),
326 ADD_KEYMAP_NAME (MarkColumnUp),
327 ADD_KEYMAP_NAME (MarkColumnDown),
328 ADD_KEYMAP_NAME (MarkColumnScrollUp),
329 ADD_KEYMAP_NAME (MarkColumnScrollDown),
330 ADD_KEYMAP_NAME (MarkColumnParagraphUp),
331 ADD_KEYMAP_NAME (MarkColumnParagraphDown),
332 ADD_KEYMAP_NAME (BlockShiftLeft),
333 ADD_KEYMAP_NAME (BlockShiftRight),
334 ADD_KEYMAP_NAME (InsertLiteral),
335 ADD_KEYMAP_NAME (ShowTabTws),
336 ADD_KEYMAP_NAME (SyntaxOnOff),
337 ADD_KEYMAP_NAME (SyntaxChoose),
338 ADD_KEYMAP_NAME (ShowMargin),
339 ADD_KEYMAP_NAME (OptionsSaveMode),
340 ADD_KEYMAP_NAME (About),
341 /* An action to run external script from macro */
342 {"ExecuteScript", CK_PipeBlock (0)},
343 ADD_KEYMAP_NAME (WindowMove),
344 ADD_KEYMAP_NAME (WindowResize),
345 ADD_KEYMAP_NAME (WindowFullscreen),
346 ADD_KEYMAP_NAME (WindowList),
347 ADD_KEYMAP_NAME (WindowNext),
348 ADD_KEYMAP_NAME (WindowPrev),
349 #endif /* USE_INTERNAL_EDIT */
351 /* viewer */
352 ADD_KEYMAP_NAME (WrapMode),
353 ADD_KEYMAP_NAME (HexEditMode),
354 ADD_KEYMAP_NAME (HexMode),
355 ADD_KEYMAP_NAME (MagicMode),
356 ADD_KEYMAP_NAME (NroffMode),
357 ADD_KEYMAP_NAME (BookmarkGoto),
358 ADD_KEYMAP_NAME (Ruler),
359 ADD_KEYMAP_NAME (SearchForward),
360 ADD_KEYMAP_NAME (SearchBackward),
361 ADD_KEYMAP_NAME (SearchForwardContinue),
362 ADD_KEYMAP_NAME (SearchBackwardContinue),
363 ADD_KEYMAP_NAME (SearchOppositeContinue),
365 #ifdef USE_DIFF_VIEW
366 /* diff viewer */
367 ADD_KEYMAP_NAME (ShowSymbols),
368 ADD_KEYMAP_NAME (SplitFull),
369 ADD_KEYMAP_NAME (Tab2),
370 ADD_KEYMAP_NAME (Tab3),
371 ADD_KEYMAP_NAME (Tab4),
372 ADD_KEYMAP_NAME (Tab8),
373 ADD_KEYMAP_NAME (HunkNext),
374 ADD_KEYMAP_NAME (HunkPrev),
375 ADD_KEYMAP_NAME (EditOther),
376 ADD_KEYMAP_NAME (Merge),
377 ADD_KEYMAP_NAME (MergeOther),
378 #endif /* USE_DIFF_VIEW */
380 {NULL, CK_IgnoreKey}
383 /* *INDENT-OFF* */
384 static const size_t num_command_names = G_N_ELEMENTS (command_names) - 1;
385 /* *INDENT-ON* */
387 /* --------------------------------------------------------------------------------------------- */
388 /*** file scope functions ************************************************************************/
389 /* --------------------------------------------------------------------------------------------- */
391 static int
392 name_keymap_comparator (const void *p1, const void *p2)
394 const name_keymap_t *m1 = (const name_keymap_t *) p1;
395 const name_keymap_t *m2 = (const name_keymap_t *) p2;
397 return g_ascii_strcasecmp (m1->name, m2->name);
400 /* --------------------------------------------------------------------------------------------- */
402 static inline void
403 sort_command_names (void)
405 static gboolean has_been_sorted = FALSE;
407 if (!has_been_sorted)
409 qsort (command_names, num_command_names,
410 sizeof (command_names[0]), &name_keymap_comparator);
411 has_been_sorted = TRUE;
415 /* --------------------------------------------------------------------------------------------- */
417 static void
418 keymap_add (GArray *keymap, long key, long cmd, const char *caption)
420 if (key != 0 && cmd != CK_IgnoreKey)
422 global_keymap_t new_bind;
424 new_bind.key = key;
425 new_bind.command = cmd;
426 g_snprintf (new_bind.caption, sizeof (new_bind.caption), "%s", caption);
427 g_array_append_val (keymap, new_bind);
431 /* --------------------------------------------------------------------------------------------- */
432 /*** public functions ****************************************************************************/
433 /* --------------------------------------------------------------------------------------------- */
435 void
436 keybind_cmd_bind (GArray *keymap, const char *keybind, long action)
438 char *caption = NULL;
439 long key;
441 key = tty_keyname_to_keycode (keybind, &caption);
442 keymap_add (keymap, key, action, caption);
443 g_free (caption);
446 /* --------------------------------------------------------------------------------------------- */
448 long
449 keybind_lookup_action (const char *name)
451 const name_keymap_t key = { name, 0 };
452 name_keymap_t *res;
454 sort_command_names ();
456 res = bsearch (&key, command_names, num_command_names,
457 sizeof (command_names[0]), name_keymap_comparator);
459 return (res != NULL) ? res->val : CK_IgnoreKey;
462 /* --------------------------------------------------------------------------------------------- */
464 const char *
465 keybind_lookup_actionname (long action)
467 size_t i;
469 for (i = 0; command_names[i].name != NULL; i++)
470 if (command_names[i].val == action)
471 return command_names[i].name;
473 return NULL;
476 /* --------------------------------------------------------------------------------------------- */
478 const char *
479 keybind_lookup_keymap_shortcut (const global_keymap_t *keymap, long action)
481 if (keymap != NULL)
483 size_t i;
485 for (i = 0; keymap[i].key != 0; i++)
486 if (keymap[i].command == action)
487 return (keymap[i].caption[0] != '\0') ? keymap[i].caption : NULL;
489 return NULL;
492 /* --------------------------------------------------------------------------------------------- */
494 long
495 keybind_lookup_keymap_command (const global_keymap_t *keymap, long key)
497 if (keymap != NULL)
499 size_t i;
501 for (i = 0; keymap[i].key != 0; i++)
502 if (keymap[i].key == key)
503 return keymap[i].command;
506 return CK_IgnoreKey;
509 /* --------------------------------------------------------------------------------------------- */