NeoMutt  2025-12-11-435-g4ac674
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
commands.c
Go to the documentation of this file.
1
22
28
29#include "config.h"
30#include <stdbool.h>
31#include <string.h>
32#include "mutt/lib.h"
33#include "config/lib.h"
34#include "core/lib.h"
35#include "gui/lib.h"
36#include "commands.h"
37#include "editor/lib.h"
38#include "index/lib.h"
39#include "menu/lib.h"
40#include "pager/lib.h"
41#include "parse/lib.h"
42#include "dump.h"
43#include "get.h"
44#include "init.h"
45#include "keymap.h"
46#include "menu.h"
47#include "notify.h"
48
53{
54 struct MenuDefinitionArray mda;
55 bool all_menus;
56 bool all_keys;
57 const char *key;
58};
59
63enum CommandResult parse_dump(const struct Command *cmd, struct Buffer *line,
64 const struct ParseContext *pc, struct ParseError *pe)
65{
66 struct Buffer *err = pe->message;
67
68 struct Buffer *token = buf_pool_get();
69 const struct MenuDefinition *md = NULL;
71
72 if (MoreArgs(line))
73 {
75
76 if (MoreArgs(line))
77 {
78 /* More arguments potentially means the user is using the
79 * ::command_t :bind command thus we delegate the task. */
80 goto done;
81 }
82
83 if (!mutt_str_equal(buf_string(token), "all"))
84 {
85 md = menu_find_by_name(buf_string(token));
86 if (!md)
87 {
88 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
89 buf_printf(err, _("%s: no such menu"), buf_string(token));
90 goto done;
91 }
92 }
93 }
94
95 dump_bind_macro(cmd, md, token, err);
97
98done:
99 buf_pool_release(&token);
100 return rc;
101}
102
115char *parse_keymap(const struct Command *cmd, struct MenuDefinitionArray *mda,
116 struct Buffer *line, struct Buffer *err)
117{
118 struct Buffer *token = buf_pool_get();
119 char *q = NULL;
120 char *result = NULL;
121
122 /* menu name */
124 char *p = token->data;
125 if (MoreArgs(line))
126 {
127 while (true)
128 {
129 q = strchr(p, ',');
130 if (q)
131 *q = '\0';
132
133 struct MenuDefinition *md = menu_find_by_name(p);
134 if (!md)
135 {
136 buf_printf(err, _("%s: no such menu"), p);
137 goto done;
138 }
139 ARRAY_ADD(mda, md);
140 if (q)
141 p = q + 1;
142 else
143 break;
144 }
145 /* key sequence */
147
148 if (buf_at(token, 0) == '\0')
149 {
150 buf_printf(err, _("%s: null key sequence"), cmd->name);
151 }
152 else if (MoreArgs(line))
153 {
154 result = buf_strdup(token);
155 goto done;
156 }
157 }
158 else
159 {
160 buf_printf(err, _("%s: too few arguments"), cmd->name);
161 }
162done:
163 buf_pool_release(&token);
164 return result;
165}
166
175void parse_menu(struct MenuDefinitionArray *menus, const char *s, struct Buffer *err)
176{
177 char *menu_names_dup = mutt_str_dup(s);
178 char *marker = menu_names_dup;
179 char *menu_name = NULL;
180
181 while ((menu_name = mutt_str_sep(&marker, ",")))
182 {
183 struct MenuDefinition *md = menu_find_by_name(menu_name);
184 if (!md)
185 {
186 buf_printf(err, _("%s: no such menu"), menu_name);
187 break;
188 }
189 else
190 {
191 ARRAY_ADD(menus, md);
192 }
193 }
194
195 FREE(&menu_names_dup);
196}
197
204enum CommandResult parse_push(const struct Command *cmd, struct Buffer *line,
205 const struct ParseContext *pc, struct ParseError *pe)
206{
207 struct Buffer *err = pe->message;
208
209 if (!MoreArgs(line))
210 {
211 buf_printf(err, _("%s: too few arguments"), cmd->name);
212 return MUTT_CMD_WARNING;
213 }
214
215 struct Buffer *token = buf_pool_get();
217
219 if (MoreArgs(line))
220 {
221 buf_printf(err, _("%s: too many arguments"), cmd->name);
222 goto done;
223 }
224
226 rc = MUTT_CMD_SUCCESS;
227
228done:
229 buf_pool_release(&token);
230 return rc;
231}
232
241enum CommandResult parse_bind(const struct Command *cmd, struct Buffer *line,
242 const struct ParseContext *pc, struct ParseError *pe)
243{
244 struct Buffer *err = pe->message;
245
246 if (StartupComplete)
247 {
248 // Save and restore the offset in `line` because parse_dump() might change it
249 char *dptr = line->dptr;
250 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
251 {
252 return MUTT_CMD_SUCCESS;
253 }
254 if (!buf_is_empty(err))
255 {
256 return MUTT_CMD_ERROR;
257 }
258 line->dptr = dptr;
259 }
260
261 struct Buffer *token = buf_pool_get();
262 struct Buffer *keystr = NULL;
263
264 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
266
267 char *key = parse_keymap(cmd, &mda, line, err);
268 if (!key)
269 goto done;
270
271 /* function to execute */
273 if (MoreArgs(line))
274 {
275 buf_printf(err, _("%s: too many arguments"), cmd->name);
276 goto done;
277 }
278
279 rc = MUTT_CMD_SUCCESS;
280
281 if (mutt_istr_equal("noop", buf_string(token)))
282 {
283 keystr = buf_pool_get();
284 struct MenuDefinition **mdp = NULL;
285 ARRAY_FOREACH(mdp, &mda)
286 {
287 struct MenuDefinition *md = *mdp;
288
289 km_bind(md, key, OP_NULL, NULL, NULL, NULL); /* the 'unbind' command */
290
291 buf_reset(keystr);
292 keymap_expand_string(key, keystr);
293 mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", md->name, buf_string(keystr));
294
295 int op = km_get_op_menu(md->id, buf_string(token));
296
297 struct EventBinding ev_b = { md, key, op };
299 }
300 }
301 else
302 {
303 keystr = buf_pool_get();
304 struct MenuDefinition **mdp = NULL;
305 ARRAY_FOREACH(mdp, &mda)
306 {
307 struct MenuDefinition *md = *mdp;
308
309 int op = OP_NULL;
310 struct SubMenu **ptr = NULL;
311 ARRAY_FOREACH(ptr, &md->submenus)
312 {
313 struct SubMenu *sm = *ptr;
314 const struct MenuFuncOp *mfo = NULL;
315 for (int j = 0; sm->functions[j].name; j++)
316 {
317 mfo = &sm->functions[j];
318 if (mutt_str_equal(buf_string(token), mfo->name))
319 {
320 op = mfo->op;
321 break;
322 }
323 }
324 }
325
326 rc = km_bind(md, key, op, NULL, NULL, err);
327 if (rc == MUTT_CMD_SUCCESS)
328 {
329 buf_reset(keystr);
330 keymap_expand_string(key, keystr);
331 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", md->name, buf_string(keystr));
332
333 struct EventBinding ev_b = { md, key, op };
335 }
336 }
337 }
338
339done:
340 FREE(&key);
341 ARRAY_FREE(&mda);
342 buf_pool_release(&keystr);
343 buf_pool_release(&token);
344 return rc;
345}
346
352{
353 bool success = false;
354
355 if (!md || (md == MdGeneric))
356 {
357 km_bind(MdGeneric, "<enter>", OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
358 km_bind(MdGeneric, "<return>", OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
359 km_bind(MdGeneric, ":", OP_ENTER_COMMAND, NULL, NULL, NULL);
360 km_bind(MdGeneric, "?", OP_HELP, NULL, NULL, NULL);
361 km_bind(MdGeneric, "q", OP_EXIT, NULL, NULL, NULL);
362 success = true;
363 }
364
365 if (!md || (md == MdIndex))
366 {
367 km_bind(MdIndex, "<enter>", OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
368 km_bind(MdIndex, "<return>", OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
369 km_bind(MdIndex, "q", OP_EXIT, NULL, NULL, NULL);
370 success = true;
371 }
372
373 if (!md || (md == MdEditor))
374 {
375 km_bind(MdEditor, "<backspace>", OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
376 km_bind(MdEditor, "\177", OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
377 success = true;
378 }
379
380 if (!md || (md == MdPager))
381 {
382 km_bind(MdPager, ":", OP_ENTER_COMMAND, NULL, NULL, NULL);
383 km_bind(MdPager, "?", OP_HELP, NULL, NULL, NULL);
384 km_bind(MdPager, "q", OP_EXIT, NULL, NULL, NULL);
385 success = true;
386 }
387
388 if (!md || (md == MdDialog))
389 {
390 km_bind(MdDialog, ":", OP_ENTER_COMMAND, NULL, NULL, NULL);
391 km_bind(MdDialog, "?", OP_HELP, NULL, NULL, NULL);
392 km_bind(MdDialog, "q", OP_EXIT, NULL, NULL, NULL);
393 success = true;
394 }
395
396 if (success)
397 {
398 mutt_debug(LL_NOTIFY, "NT_BINDING_ADD set defaults\n");
399 struct EventBinding ev_b = { md, NULL, OP_NULL };
401 }
402}
403
410{
411 switch (ev)
412 {
413 case NT_BINDING_ADD:
414 return "NT_BINDING_ADD";
416 return "NT_BINDING_DELETE";
417 case NT_MACRO_ADD:
418 return "NT_MACRO_ADD";
419 case NT_MACRO_DELETE:
420 return "NT_MACRO_DELETE";
421 default:
422 return "UNKNOWN";
423 }
424}
425
449bool parse_unbind_args(const struct Command *cmd, struct Buffer *line,
450 struct Buffer *err, struct ParseUnbind *args)
451{
452 if (!cmd || !line || !err || !args)
453 return false;
454
455 if (!MoreArgs(line))
456 {
457 buf_printf(err, _("%s: too few arguments"), cmd->name);
458 return false;
459 }
460
461 struct Buffer *token = buf_pool_get();
462 bool rc = false;
463
465 if (mutt_str_equal(buf_string(token), "*"))
466 {
467 args->all_menus = true;
468
469 if (MoreArgs(line))
470 {
471 // `unbind * key`
472 // `unmacro * key`
474 args->key = buf_strdup(token);
475 }
476 else
477 {
478 // `unbind *`
479 // `unmacro *`
480 args->all_keys = true;
481 }
482 }
483 else
484 {
485 parse_menu(&args->mda, buf_string(token), err);
486 if (!buf_is_empty(err))
487 goto done;
488
489 if (MoreArgs(line))
490 {
492 if (mutt_str_equal(buf_string(token), "*"))
493 {
494 // `unbind menu *`
495 // `unmacro menu *`
496 args->all_keys = true;
497 }
498 else
499 {
500 // `unbind menu key`
501 // `unmacro menu key`
502 args->key = buf_strdup(token);
503 }
504 }
505 else
506 {
507 // `unbind menu`
508 // `unmacro menu`
509 args->all_keys = true;
510 }
511 }
512
513 if (MoreArgs(line))
514 {
515 buf_printf(err, _("%s: too many arguments"), cmd->name);
516 goto done;
517 }
518
519 rc = true;
520
521done:
522 buf_pool_release(&token);
523 return rc;
524}
525
537bool parse_unbind_exec(const struct Command *cmd, struct ParseUnbind *args, struct Buffer *err)
538{
539 if (!cmd || !args || !err)
540 return false;
541
542 keycode_t key_bytes[MAX_SEQ] = { 0 };
543 int key_len = 0;
544 if (args->key)
545 {
546 key_len = parse_keys(args->key, key_bytes, MAX_SEQ);
547 if (key_len == 0)
548 return false;
549 }
550
551 bool success = false;
552 struct Buffer *keystr = buf_pool_get();
554 struct MenuDefinition **mdp = NULL;
556 {
557 struct MenuDefinition *md = *mdp;
558
559 if (!args->all_menus)
560 {
561 bool found = false;
562 struct MenuDefinition **mdp2 = NULL;
563 ARRAY_FOREACH(mdp2, &args->mda)
564 {
565 if ((*mdp2)->id == md->id)
566 {
567 found = true;
568 break;
569 }
570 }
571 if (!found)
572 continue;
573 }
574
575 struct SubMenu **smp = ARRAY_GET(&md->submenus, 0);
576 if (!smp || !*smp)
577 continue;
578
579 struct SubMenu *sm = *smp;
580
581 struct Keymap *km = NULL;
582 struct Keymap *km_tmp = NULL;
583 STAILQ_FOREACH_SAFE(km, &sm->keymaps, entries, km_tmp)
584 {
585 if (args->all_keys ||
586 ((key_len == km->len) && (memcmp(km->keys, key_bytes, km->len) == 0)))
587 {
588 STAILQ_REMOVE(&sm->keymaps, km, Keymap, entries);
589 keymap_free(&km);
590 success = true;
591
592 if (!args->all_keys && !args->all_menus)
593 {
594 buf_reset(keystr);
595 keymap_expand_string(args->key, keystr);
596 mutt_debug(LL_NOTIFY, "%s: %s %s\n", notify_binding_name(nb),
597 md->name, buf_string(keystr));
598
599 struct EventBinding ev_b = { md, args->key, OP_NULL };
600 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
601 }
602 }
603 }
604
605 if (args->all_keys && !args->all_menus && success)
606 {
607 buf_reset(keystr);
608 keymap_expand_string(args->key, keystr);
609 mutt_debug(LL_NOTIFY, "%s: %s %s\n", notify_binding_name(nb), md->name,
610 buf_string(keystr));
611
612 struct EventBinding ev_b = { md, args->key, OP_NULL };
613 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
614
615 // restore some bindings for this menu
617 }
618 }
619
620 if (args->all_menus && success)
621 {
622 buf_reset(keystr);
623 keymap_expand_string(args->key, keystr);
624 mutt_debug(LL_NOTIFY, "%s: ALL %s\n", notify_binding_name(nb), buf_string(keystr));
625
626 struct EventBinding ev_b = { NULL, args->key, OP_NULL };
627 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
628
629 // restore some bindings for all menus
631 }
632
633 buf_pool_release(&keystr);
634 return true;
635}
636
644enum CommandResult parse_unbind(const struct Command *cmd, struct Buffer *line,
645 const struct ParseContext *pc, struct ParseError *pe)
646{
647 struct Buffer *err = pe->message;
648
649 struct ParseUnbind args = { 0 };
651
652 if (!parse_unbind_args(cmd, line, err, &args))
653 goto done;
654
655 rc = MUTT_CMD_ERROR;
656 if (parse_unbind_exec(cmd, &args, err))
657 rc = MUTT_CMD_SUCCESS;
658
659done:
660 ARRAY_FREE(&args.mda);
661 FREE(&args.key);
662 return rc;
663}
664
671enum CommandResult parse_macro(const struct Command *cmd, struct Buffer *line,
672 const struct ParseContext *pc, struct ParseError *pe)
673{
674 struct Buffer *err = pe->message;
675
676 if (StartupComplete)
677 {
678 // Save and restore the offset in `line` because parse_dump() might change it
679 char *dptr = line->dptr;
680 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
681 {
682 return MUTT_CMD_SUCCESS;
683 }
684 if (!buf_is_empty(err))
685 {
686 return MUTT_CMD_ERROR;
687 }
688 line->dptr = dptr;
689 }
690
691 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
692 struct Buffer *token = buf_pool_get();
693 struct Buffer *keystr = NULL;
695
696 char *key = parse_keymap(cmd, &mda, line, err);
697 if (!key)
698 goto done;
699
701 /* make sure the macro sequence is not an empty string */
702 if (buf_at(token, 0) == '\0')
703 {
704 buf_strcpy(err, _("macro: empty key sequence"));
705 }
706 else
707 {
708 if (MoreArgs(line))
709 {
710 char *seq = mutt_str_dup(buf_string(token));
712
713 if (MoreArgs(line))
714 {
715 buf_printf(err, _("%s: too many arguments"), cmd->name);
716 }
717 else
718 {
719 keystr = buf_pool_get();
720 struct MenuDefinition **mdp = NULL;
721 ARRAY_FOREACH(mdp, &mda)
722 {
723 struct MenuDefinition *md = *mdp;
724
725 rc = km_bind(md, key, OP_MACRO, seq, token->data, NULL);
726 if (rc == MUTT_CMD_SUCCESS)
727 {
728 buf_reset(keystr);
729 keymap_expand_string(key, keystr);
730 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
731
732 struct EventBinding ev_b = { md, key, OP_MACRO };
734 continue;
735 }
736 }
737 }
738
739 FREE(&seq);
740 }
741 else
742 {
743 keystr = buf_pool_get();
744 struct MenuDefinition **mdp = NULL;
745 ARRAY_FOREACH(mdp, &mda)
746 {
747 struct MenuDefinition *md = *mdp;
748
749 rc = km_bind(md, key, OP_MACRO, token->data, NULL, NULL);
750 if (rc == MUTT_CMD_SUCCESS)
751 {
752 buf_reset(keystr);
753 keymap_expand_string(key, keystr);
754 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
755
756 struct EventBinding ev_b = { md, key, OP_MACRO };
758 continue;
759 }
760 }
761 }
762 }
763
764done:
765 FREE(&key);
766 ARRAY_FREE(&mda);
767 buf_pool_release(&keystr);
768 buf_pool_release(&token);
769 return rc;
770}
771
778enum CommandResult parse_exec(const struct Command *cmd, struct Buffer *line,
779 const struct ParseContext *pc, struct ParseError *pe)
780{
781 struct Buffer *err = pe->message;
782
783 if (!MoreArgs(line))
784 {
785 buf_printf(err, _("%s: too few arguments"), cmd->name);
786 return MUTT_CMD_WARNING;
787 }
788
789 struct Buffer *token = buf_pool_get();
791
792 int ops[128];
793 int nops = 0;
794 char *function = NULL;
795
796 do
797 {
799 function = token->data;
800
801 const enum MenuType mtype = menu_get_current_type();
802 ops[nops] = km_get_op_menu(mtype, function);
803 if (ops[nops] == OP_NULL)
804 {
806 mutt_error(_("%s: no such function"), function);
807 goto done;
808 }
809 nops++;
810 } while (MoreArgs(line) && nops < countof(ops));
811
812 while (nops)
813 mutt_push_macro_event(0, ops[--nops]);
814
815 rc = MUTT_CMD_SUCCESS;
816
817done:
818 buf_pool_release(&token);
819 return rc;
820}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_GET(head, idx)
Return the element at index.
Definition array.h:109
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
char buf_at(const struct Buffer *buf, size_t offset)
Return the character at the given offset.
Definition buffer.c:668
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
@ CMD_UNBIND
:unbind
Definition command.h:128
CommandResult
Error codes for command_t parse functions.
Definition command.h:37
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition command.h:40
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition command.h:38
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition command.h:39
Convenience wrapper for the config headers.
bool StartupComplete
When the config has been read.
Definition address.c:11
Convenience wrapper for the core headers.
struct MenuDefinition * MdEditor
Editor Menu Definition.
Definition functions.c:46
Edit a string.
int parse_extract_token(struct Buffer *dest, struct Buffer *line, TokenFlags flags)
Extract one token from a string.
Definition extract.c:49
#define TOKEN_CONDENSE
^(char) to control chars (macros)
Definition extract.h:47
#define MoreArgs(buf)
Definition extract.h:31
#define TOKEN_NO_FLAGS
No flags are set.
Definition extract.h:45
void generic_tokenize_push_string(char *s)
Parse and queue a 'push' command.
Definition get.c:309
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition get.c:65
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition get.c:146
Get a key from the user.
enum CommandResult parse_bind(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'bind' command - Implements Command::parse() -.
Definition commands.c:241
enum CommandResult parse_exec(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'exec' command - Implements Command::parse() -.
Definition commands.c:778
enum CommandResult parse_macro(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'macro' command - Implements Command::parse() -.
Definition commands.c:671
enum CommandResult parse_push(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'push' command - Implements Command::parse() -.
Definition commands.c:204
enum CommandResult parse_dump(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse 'bind' and 'macro' commands - Implements Command::parse() -.
Definition commands.c:63
enum CommandResult parse_unbind(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse the 'unbind' and 'unmacro' commands - Implements Command::parse() -.
Definition commands.c:644
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
struct MenuDefinition * MdDialog
Dialog Menu Definition.
Definition functions.c:53
struct MenuDefinition * MdGeneric
Generic Menu Definition.
Definition functions.c:50
Convenience wrapper for the gui headers.
struct MenuDefinition * MdIndex
Index Menu Definition.
Definition functions.c:80
GUI manage the main index (list of emails)
struct MenuDefinitionArray MenuDefs
All the registered Menus.
Definition init.c:42
Set up the key bindings.
const char * notify_binding_name(enum NotifyBinding ev)
Get the name for a NotifyBinding.
Definition commands.c:409
void set_default_bindings(const struct MenuDefinition *md)
Set some safe default keybindings.
Definition commands.c:351
bool parse_unbind_exec(const struct Command *cmd, struct ParseUnbind *args, struct Buffer *err)
Execute the 'unbind' or 'unmacro' command.
Definition commands.c:537
char * parse_keymap(const struct Command *cmd, struct MenuDefinitionArray *mda, struct Buffer *line, struct Buffer *err)
Parse a user-config key binding.
Definition commands.c:115
bool parse_unbind_args(const struct Command *cmd, struct Buffer *line, struct Buffer *err, struct ParseUnbind *args)
Parse the 'unbind' and 'unmacro' commands.
Definition commands.c:449
void parse_menu(struct MenuDefinitionArray *menus, const char *s, struct Buffer *err)
Parse menu-names into an array.
Definition commands.c:175
Parse key binding commands.
enum CommandResult km_bind(struct MenuDefinition *md, const char *key_str, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition menu.c:51
void dump_bind_macro(const struct Command *cmd, const struct MenuDefinition *md, struct Buffer *buf, struct Buffer *err)
Dump a Menu's binds or macros to the Pager.
Definition dump.c:387
Dump key bindings.
void keymap_expand_string(const char *str, struct Buffer *buf)
Get a human-readable key string.
Definition keymap.c:247
void keymap_free(struct Keymap **pptr)
Free a Keymap.
Definition keymap.c:127
size_t parse_keys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition keymap.c:318
int km_get_op_menu(int mtype, const char *func)
Get the OpCode for a Function from a Menu.
Definition menu.c:213
struct MenuDefinition * menu_find_by_name(const char *name)
Find a Menu Definition by its name.
Definition menu.c:264
Key binding notifications.
NotifyBinding
Key Binding notification types.
Definition notify.h:46
@ NT_MACRO_ADD
Key macro has been added.
Definition notify.h:49
@ NT_MACRO_DELETE
Key macro has been deleted.
Definition notify.h:50
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition notify.h:48
@ NT_BINDING_ADD
Key binding has been added.
Definition notify.h:47
Keymap handling.
short keycode_t
Type for key storage, the rest of neomutt works fine with int type.
Definition keymap.h:31
@ LL_NOTIFY
Log of notifications.
Definition logging2.h:50
#define countof(x)
Definition memory.h:49
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
GUI present the user with a selectable list.
enum MenuType menu_get_current_type(void)
Get the type of the current Window.
Definition menu.c:91
Maniplate Menus and SubMenus.
#define MAX_SEQ
Maximum length of a key binding sequence used for buffer in km_bind.
Definition menu.h:32
Convenience wrapper for the library headers.
#define _(a)
Definition message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition notify.c:173
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:674
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:662
char * mutt_str_sep(char **stringp, const char *delim)
Find first occurrence of any of delim characters in *stringp.
Definition string.c:190
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition notify_type.h:40
struct MenuDefinition * MdPager
Pager Menu Definition.
Definition functions.c:64
GUI display a file/email/help in a viewport with paging.
Text parsing functions.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define STAILQ_REMOVE(head, elm, type, field)
Definition queue.h:441
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
String manipulation buffer.
Definition buffer.h:36
char * dptr
Current read/write position.
Definition buffer.h:38
char * data
Pointer to data.
Definition buffer.h:37
const char * name
Name of the Command.
Definition command.h:159
enum CommandId id
ID of the Command.
Definition command.h:160
A key binding Event.
Definition notify.h:32
const char * key
Key string being bound (for new bind/macro)
Definition notify.h:34
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition notify.h:35
A keyboard mapping.
Definition keymap.h:43
keycode_t * keys
Key sequence.
Definition keymap.h:49
short len
Length of key sequence (unit: sizeof (keycode_t))
Definition keymap.h:48
Functions for a Dialog or Window.
Definition menu.h:80
const char * name
Menu name, e.g. "alias".
Definition menu.h:82
int id
Menu ID, e.g. MENU_ALIAS.
Definition menu.h:81
struct SubMenuPArray submenus
Parts making up the Menu.
Definition menu.h:83
Mapping between a function and an operation.
Definition menu.h:38
const char * name
Name of the function.
Definition menu.h:39
int op
Operation, e.g. OP_DELETE.
Definition menu.h:40
Container for Accounts, Notifications.
Definition neomutt.h:41
struct Notify * notify
Notifications handler.
Definition neomutt.h:45
Context for config parsing (history/backtrace)
Definition pcontext.h:34
Detailed error information from config parsing.
Definition perror.h:34
struct Buffer * message
Error message.
Definition perror.h:35
Parsed 'unbind' or 'unmacro' command.
Definition commands.c:53
bool all_menus
Command affects all Menus.
Definition commands.c:55
struct MenuDefinitionArray mda
Menus to work on.
Definition commands.c:54
const char * key
Key string to be removed.
Definition commands.c:57
bool all_keys
Command affects all key bindings.
Definition commands.c:56
Collection of related functions.
Definition menu.h:68
const struct MenuFuncOp * functions
All available functions.
Definition menu.h:70
struct KeymapList keymaps
All keybindings.
Definition menu.h:71
MenuType
Types of GUI selections.
Definition type.h:33