NeoMutt  2025-12-11-980-ge38c27
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 "keymap.h"
45#include "menu.h"
46#include "module_data.h"
47#include "notify.h"
48
53{
54 struct MenuDefinitionArray mda;
55 bool all_menus;
56 bool all_keys;
58 const char *key;
59};
60
64enum CommandResult parse_dump(const struct Command *cmd, struct Buffer *line,
65 const struct ParseContext *pc, struct ParseError *pe)
66{
67 struct Buffer *err = pe->message;
68
69 struct Buffer *token = buf_pool_get();
70 const struct MenuDefinition *md = NULL;
72
73 if (MoreArgs(line))
74 {
75 parse_extract_token(token, line, TOKEN_NONE);
76
77 if (MoreArgs(line))
78 {
79 /* More arguments potentially means the user is using the
80 * ::command_t :bind command thus we delegate the task. */
81 goto done;
82 }
83
84 if (!mutt_str_equal(buf_string(token), "all"))
85 {
86 md = menu_find_by_name(buf_string(token));
87 if (!md)
88 {
89 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
90 buf_printf(err, _("%s: no such menu"), buf_string(token));
91 goto done;
92 }
93 }
94 }
95
96 dump_bind_macro(cmd, md, token, err);
98
99done:
100 buf_pool_release(&token);
101 return rc;
102}
103
116char *parse_keymap(const struct Command *cmd, struct MenuDefinitionArray *mda,
117 struct Buffer *line, struct Buffer *err)
118{
119 struct Buffer *token = buf_pool_get();
120 char *q = NULL;
121 char *result = NULL;
122
123 /* menu name */
124 parse_extract_token(token, line, TOKEN_NONE);
125 char *p = token->data;
126 if (MoreArgs(line))
127 {
128 while (true)
129 {
130 q = strchr(p, ',');
131 if (q)
132 *q = '\0';
133
134 struct MenuDefinition *md = menu_find_by_name(p);
135 if (!md)
136 {
137 buf_printf(err, _("%s: no such menu"), p);
138 goto done;
139 }
140 ARRAY_ADD(mda, md);
141 if (q)
142 p = q + 1;
143 else
144 break;
145 }
146 /* key sequence */
147 parse_extract_token(token, line, TOKEN_NONE);
148
149 if (buf_at(token, 0) == '\0')
150 {
151 buf_printf(err, _("%s: null key sequence"), cmd->name);
152 }
153 else if (MoreArgs(line))
154 {
155 result = buf_strdup(token);
156 goto done;
157 }
158 }
159 else
160 {
161 buf_printf(err, _("%s: too few arguments"), cmd->name);
162 }
163done:
164 buf_pool_release(&token);
165 return result;
166}
167
176void parse_menu(struct MenuDefinitionArray *menus, const char *s, struct Buffer *err)
177{
178 char *menu_names_dup = mutt_str_dup(s);
179 char *marker = menu_names_dup;
180 char *menu_name = NULL;
181
182 while ((menu_name = mutt_str_sep(&marker, ",")))
183 {
184 struct MenuDefinition *md = menu_find_by_name(menu_name);
185 if (!md)
186 {
187 buf_printf(err, _("%s: no such menu"), menu_name);
188 break;
189 }
190 else
191 {
192 ARRAY_ADD(menus, md);
193 }
194 }
195
196 FREE(&menu_names_dup);
197}
198
205enum CommandResult parse_push(const struct Command *cmd, struct Buffer *line,
206 const struct ParseContext *pc, struct ParseError *pe)
207{
208 struct Buffer *err = pe->message;
209
210 if (!MoreArgs(line))
211 {
212 buf_printf(err, _("%s: too few arguments"), cmd->name);
213 return MUTT_CMD_WARNING;
214 }
215
216 struct Buffer *token = buf_pool_get();
218
220 if (MoreArgs(line))
221 {
222 buf_printf(err, _("%s: too many arguments"), cmd->name);
223 goto done;
224 }
225
227 rc = MUTT_CMD_SUCCESS;
228
229done:
230 buf_pool_release(&token);
231 return rc;
232}
233
242enum CommandResult parse_bind(const struct Command *cmd, struct Buffer *line,
243 const struct ParseContext *pc, struct ParseError *pe)
244{
245 struct Buffer *err = pe->message;
246
247 if (StartupComplete)
248 {
249 // Save and restore the offset in `line` because parse_dump() might change it
250 char *dptr = line->dptr;
251 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
252 {
253 return MUTT_CMD_SUCCESS;
254 }
255 if (!buf_is_empty(err))
256 {
257 return MUTT_CMD_ERROR;
258 }
259 line->dptr = dptr;
260 }
261
262 struct Buffer *token = buf_pool_get();
263 struct Buffer *keystr = NULL;
264
265 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
267
268 char *key = parse_keymap(cmd, &mda, line, err);
269 if (!key)
270 goto done;
271
272 /* function to execute */
273 parse_extract_token(token, line, TOKEN_NONE);
274 if (MoreArgs(line))
275 {
276 buf_printf(err, _("%s: too many arguments"), cmd->name);
277 goto done;
278 }
279
280 rc = MUTT_CMD_SUCCESS;
281
282 if (mutt_istr_equal("noop", buf_string(token)))
283 {
284 keystr = buf_pool_get();
285 struct MenuDefinition **mdp = NULL;
286 ARRAY_FOREACH(mdp, &mda)
287 {
288 struct MenuDefinition *md = *mdp;
289
290 km_bind(md, key, OP_NULL, NULL, NULL, NULL); /* the 'unbind' command */
291
292 buf_reset(keystr);
293 keymap_expand_string(key, keystr);
294 mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", md->name, buf_string(keystr));
295
296 int op = km_get_op_menu(md->id, buf_string(token));
297
298 struct EventBinding ev_b = { md, key, op };
300 }
301 }
302 else
303 {
304 keystr = buf_pool_get();
305 struct MenuDefinition **mdp = NULL;
306 ARRAY_FOREACH(mdp, &mda)
307 {
308 struct MenuDefinition *md = *mdp;
309
310 int op = OP_NULL;
311 struct SubMenu **ptr = NULL;
312 ARRAY_FOREACH(ptr, &md->submenus)
313 {
314 struct SubMenu *sm = *ptr;
315 const struct MenuFuncOp *mfo = NULL;
316 for (int j = 0; sm->functions[j].name; j++)
317 {
318 mfo = &sm->functions[j];
319 if (mutt_str_equal(buf_string(token), mfo->name))
320 {
321 op = mfo->op;
322 break;
323 }
324 }
325 if (op != OP_NULL)
326 break;
327 }
328
329 if (op == OP_NULL)
330 {
331 buf_printf(err, _("%s: no such function: %s"), cmd->name, buf_string(token));
332 rc = MUTT_CMD_ERROR;
333 goto done;
334 }
335
336 rc = km_bind(md, key, op, NULL, NULL, err);
337 if (rc == MUTT_CMD_SUCCESS)
338 {
339 buf_reset(keystr);
340 keymap_expand_string(key, keystr);
341 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", md->name, buf_string(keystr));
342
343 struct EventBinding ev_b = { md, key, op };
345 }
346 }
347 }
348
349done:
350 FREE(&key);
351 ARRAY_FREE(&mda);
352 buf_pool_release(&keystr);
353 buf_pool_release(&token);
354 return rc;
355}
356
362{
363 bool success = false;
364
365 const struct MenuDefinition *md_generic = generic_get_menu_definition();
366 if (!md || (md == md_generic))
367 {
368 km_bind(md_generic, "<enter>", OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
369 km_bind(md_generic, "<return>", OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
370 km_bind(md_generic, ":", OP_ENTER_COMMAND, NULL, NULL, NULL);
371 km_bind(md_generic, "?", OP_HELP, NULL, NULL, NULL);
372 km_bind(md_generic, "q", OP_EXIT, NULL, NULL, NULL);
373 success = true;
374 }
375
376 const struct MenuDefinition *md_index = index_get_menu_definition();
377 if (!md || (md == md_index))
378 {
379 km_bind(md_index, "<enter>", OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
380 km_bind(md_index, "<return>", OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
381 km_bind(md_index, "q", OP_EXIT, NULL, NULL, NULL);
382 success = true;
383 }
384
385 const struct MenuDefinition *md_editor = editor_get_menu_definition();
386 if (!md || (md == md_editor))
387 {
388 km_bind(md_editor, "<backspace>", OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
389 km_bind(md_editor, "\177", OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
390 success = true;
391 }
392
393 const struct MenuDefinition *md_pager = pager_get_menu_definition();
394 if (!md || (md == md_pager))
395 {
396 km_bind(md_pager, ":", OP_ENTER_COMMAND, NULL, NULL, NULL);
397 km_bind(md_pager, "?", OP_HELP, NULL, NULL, NULL);
398 km_bind(md_pager, "q", OP_EXIT, NULL, NULL, NULL);
399 success = true;
400 }
401
402 if (success)
403 {
404 mutt_debug(LL_NOTIFY, "NT_BINDING_ADD set defaults\n");
405 struct EventBinding ev_b = { md, NULL, OP_NULL };
407 }
408}
409
416{
417 switch (ev)
418 {
419 case NT_BINDING_ADD:
420 return "NT_BINDING_ADD";
422 return "NT_BINDING_DELETE";
423 case NT_MACRO_ADD:
424 return "NT_MACRO_ADD";
425 case NT_MACRO_DELETE:
426 return "NT_MACRO_DELETE";
427 default:
428 return "UNKNOWN";
429 }
430}
431
455bool parse_unbind_args(const struct Command *cmd, struct Buffer *line,
456 struct Buffer *err, struct ParseUnbind *args)
457{
458 if (!cmd || !line || !err || !args)
459 return false;
460
461 if (!MoreArgs(line))
462 {
463 buf_printf(err, _("%s: too few arguments"), cmd->name);
464 return false;
465 }
466
467 struct Buffer *token = buf_pool_get();
468 bool rc = false;
469
470 parse_extract_token(token, line, TOKEN_NONE);
471 if (mutt_str_equal(buf_string(token), "*"))
472 {
473 args->all_menus = true;
474
475 if (MoreArgs(line))
476 {
477 // `unbind * key`
478 // `unmacro * key`
479 parse_extract_token(token, line, TOKEN_NONE);
480 if (mutt_str_equal(buf_string(token), "*"))
481 args->all_keys = true;
482 else
483 args->key = buf_strdup(token);
484 }
485 else
486 {
487 // `unbind *`
488 // `unmacro *`
489 args->all_keys = true;
490 args->restore_defaults = (cmd->id == CMD_UNBIND);
491 }
492 }
493 else
494 {
495 if (mutt_str_equal(buf_string(token), "*"))
496 {
497 args->all_menus = true;
498 }
499 else
500 {
501 parse_menu(&args->mda, buf_string(token), err);
502 if (!buf_is_empty(err))
503 goto done;
504 }
505
506 if (MoreArgs(line))
507 {
508 parse_extract_token(token, line, TOKEN_NONE);
509 if (mutt_str_equal(buf_string(token), "*"))
510 {
511 // `unbind menu *`
512 // `unmacro menu *`
513 args->all_keys = true;
514 }
515 else
516 {
517 // `unbind menu key`
518 // `unmacro menu key`
519 args->key = buf_strdup(token);
520 }
521 }
522 else
523 {
524 // `unbind menu`
525 // `unmacro menu`
526 args->all_keys = true;
527 args->restore_defaults = (cmd->id == CMD_UNBIND);
528 }
529 }
530
531 if (MoreArgs(line))
532 {
533 buf_printf(err, _("%s: too many arguments"), cmd->name);
534 goto done;
535 }
536
537 rc = true;
538
539done:
540 buf_pool_release(&token);
541 return rc;
542}
543
554bool parse_unbind_exec(const struct Command *cmd, struct ParseUnbind *args, struct Buffer *err)
555{
556 if (!cmd || !args || !err)
557 return false;
558
560 keycode_t key_bytes[KEY_SEQ_MAX_LEN] = { 0 };
561 int key_len = 0;
562 if (args->key)
563 {
564 key_len = parse_keys(args->key, key_bytes, KEY_SEQ_MAX_LEN);
565 if (key_len == 0)
566 return false;
567 }
568
569 bool success = false;
570 struct Buffer *keystr = buf_pool_get();
572 struct MenuDefinition **mdp = NULL;
573 ARRAY_FOREACH(mdp, &mod_data->menu_defs)
574 {
575 struct MenuDefinition *md = *mdp;
576 bool menu_success = false;
577
578 if (!args->all_menus)
579 {
580 bool found = false;
581 struct MenuDefinition **mdp2 = NULL;
582 ARRAY_FOREACH(mdp2, &args->mda)
583 {
584 if ((*mdp2)->id == md->id)
585 {
586 found = true;
587 break;
588 }
589 }
590 if (!found)
591 continue;
592 }
593
594 struct SubMenu **smp = ARRAY_GET(&md->submenus, 0);
595 if (!smp || !*smp)
596 continue;
597
598 struct SubMenu *sm = *smp;
599
600 struct Keymap *km = NULL;
601 struct Keymap *km_tmp = NULL;
602 STAILQ_FOREACH_SAFE(km, &sm->keymaps, entries, km_tmp)
603 {
604 bool match = args->all_keys || ((key_len == km->len) &&
605 (memcmp(km->keys, key_bytes, km->len) == 0));
606 if ((cmd->id == CMD_UNMACRO) && (km->op != OP_MACRO))
607 match = false;
608 if ((cmd->id == CMD_UNBIND) && (km->op == OP_MACRO))
609 match = false;
610
611 if (match)
612 {
613 STAILQ_REMOVE(&sm->keymaps, km, Keymap, entries);
614 keymap_free(&km);
615 success = true;
616 menu_success = true;
617
618 if (!args->all_keys && !args->all_menus)
619 {
620 buf_reset(keystr);
621 keymap_expand_string(args->key, keystr);
622 mutt_debug(LL_NOTIFY, "%s: %s %s\n", notify_binding_name(nb),
623 md->name, buf_string(keystr));
624
625 struct EventBinding ev_b = { md, args->key, OP_NULL };
626 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
627 }
628 }
629 }
630
631 if (args->all_keys && !args->all_menus)
632 {
633 if (menu_success)
634 {
635 buf_reset(keystr);
636 keymap_expand_string(args->key, keystr);
637 mutt_debug(LL_NOTIFY, "%s: %s %s\n", notify_binding_name(nb), md->name,
638 buf_string(keystr));
639
640 struct EventBinding ev_b = { md, args->key, OP_NULL };
641 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
642 }
643
644 if (args->restore_defaults)
646 }
647 }
648
649 if (args->all_menus && args->all_keys)
650 {
651 if (success)
652 {
653 buf_reset(keystr);
654 keymap_expand_string(args->key, keystr);
655 mutt_debug(LL_NOTIFY, "%s: ALL %s\n", notify_binding_name(nb), buf_string(keystr));
656
657 struct EventBinding ev_b = { NULL, args->key, OP_NULL };
658 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
659 }
660
661 if (args->restore_defaults)
663 }
664
665 buf_pool_release(&keystr);
666 return true;
667}
668
676enum CommandResult parse_unbind(const struct Command *cmd, struct Buffer *line,
677 const struct ParseContext *pc, struct ParseError *pe)
678{
679 struct Buffer *err = pe->message;
680
681 struct ParseUnbind args = { 0 };
683
684 if (!parse_unbind_args(cmd, line, err, &args))
685 goto done;
686
687 rc = MUTT_CMD_ERROR;
688 if (parse_unbind_exec(cmd, &args, err))
689 rc = MUTT_CMD_SUCCESS;
690
691done:
692 ARRAY_FREE(&args.mda);
693 FREE(&args.key);
694 return rc;
695}
696
703enum CommandResult parse_macro(const struct Command *cmd, struct Buffer *line,
704 const struct ParseContext *pc, struct ParseError *pe)
705{
706 struct Buffer *err = pe->message;
707
708 if (StartupComplete)
709 {
710 // Save and restore the offset in `line` because parse_dump() might change it
711 char *dptr = line->dptr;
712 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
713 {
714 return MUTT_CMD_SUCCESS;
715 }
716 if (!buf_is_empty(err))
717 {
718 return MUTT_CMD_ERROR;
719 }
720 line->dptr = dptr;
721 }
722
723 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
724 struct Buffer *token = buf_pool_get();
725 struct Buffer *keystr = NULL;
727
728 char *key = parse_keymap(cmd, &mda, line, err);
729 if (!key)
730 goto done;
731
733 /* make sure the macro sequence is not an empty string */
734 if (buf_at(token, 0) == '\0')
735 {
736 buf_strcpy(err, _("macro: empty key sequence"));
737 }
738 else
739 {
740 if (MoreArgs(line))
741 {
742 char *seq = mutt_str_dup(buf_string(token));
744
745 if (MoreArgs(line))
746 {
747 buf_printf(err, _("%s: too many arguments"), cmd->name);
748 }
749 else
750 {
751 keystr = buf_pool_get();
752 struct MenuDefinition **mdp = NULL;
753 ARRAY_FOREACH(mdp, &mda)
754 {
755 struct MenuDefinition *md = *mdp;
756
757 rc = km_bind(md, key, OP_MACRO, seq, token->data, NULL);
758 if (rc == MUTT_CMD_SUCCESS)
759 {
760 buf_reset(keystr);
761 keymap_expand_string(key, keystr);
762 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
763
764 struct EventBinding ev_b = { md, key, OP_MACRO };
766 continue;
767 }
768 }
769 }
770
771 FREE(&seq);
772 }
773 else
774 {
775 keystr = buf_pool_get();
776 struct MenuDefinition **mdp = NULL;
777 ARRAY_FOREACH(mdp, &mda)
778 {
779 struct MenuDefinition *md = *mdp;
780
781 rc = km_bind(md, key, OP_MACRO, token->data, NULL, NULL);
782 if (rc == MUTT_CMD_SUCCESS)
783 {
784 buf_reset(keystr);
785 keymap_expand_string(key, keystr);
786 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
787
788 struct EventBinding ev_b = { md, key, OP_MACRO };
790 continue;
791 }
792 }
793 }
794 }
795
796done:
797 FREE(&key);
798 ARRAY_FREE(&mda);
799 buf_pool_release(&keystr);
800 buf_pool_release(&token);
801 return rc;
802}
803
810enum CommandResult parse_exec(const struct Command *cmd, struct Buffer *line,
811 const struct ParseContext *pc, struct ParseError *pe)
812{
813 struct Buffer *err = pe->message;
814
815 if (!MoreArgs(line))
816 {
817 buf_printf(err, _("%s: too few arguments"), cmd->name);
818 return MUTT_CMD_WARNING;
819 }
820
821 struct Buffer *token = buf_pool_get();
823
824 int ops[128] = { 0 };
825 int nops = 0;
826 char *function = NULL;
827
828 do
829 {
830 parse_extract_token(token, line, TOKEN_NONE);
831 function = token->data;
832
833 const enum MenuType mtype = menu_get_current_type();
834 ops[nops] = km_get_op_menu(mtype, function);
835 if (ops[nops] == OP_NULL)
836 {
838 mutt_error(_("%s: no such function"), function);
839 goto done;
840 }
841 nops++;
842 } while (MoreArgs(line) && nops < countof(ops));
843
844 while (nops)
845 mutt_push_macro_event(0, ops[--nops]);
846
847 rc = MUTT_CMD_SUCCESS;
848
849done:
850 buf_pool_release(&token);
851 return rc;
852}
#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:168
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:89
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:298
char buf_at(const struct Buffer *buf, size_t offset)
Return the character at the given offset.
Definition buffer.c:674
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:577
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
@ CMD_UNMACRO
:unmacro
Definition command.h:138
@ CMD_UNBIND
:unbind
Definition command.h:131
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 * editor_get_menu_definition(void)
Get the Editor Menu Definition.
Definition functions.c:575
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 MoreArgs(buf)
Definition extract.h:32
@ TOKEN_CONDENSE
^(char) to control chars (macros)
Definition extract.h:52
@ TOKEN_NONE
No flags are set.
Definition extract.h:50
void generic_tokenize_push_string(char *s)
Parse and queue a 'push' command.
Definition get.c:352
void mutt_flushinp(void)
MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.
Definition get.c:81
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition get.c:173
Get a key from the user.
#define KEY_SEQ_MAX_LEN
Maximum number of keys in a key sequence, e.g. abc
Definition get.h:48
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:242
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:810
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:703
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:205
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:64
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:676
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
struct MenuDefinition * generic_get_menu_definition(void)
Get the Generic Menu Definition.
Definition functions.c:177
Convenience wrapper for the gui headers.
struct MenuDefinition * index_get_menu_definition(void)
Get the Index Menu Definition.
Definition functions.c:4089
GUI manage the main index (list of emails)
const char * notify_binding_name(enum NotifyBinding ev)
Get the name for a NotifyBinding.
Definition commands.c:415
void set_default_bindings(const struct MenuDefinition *md)
Set some safe default keybindings.
Definition commands.c:361
bool parse_unbind_exec(const struct Command *cmd, struct ParseUnbind *args, struct Buffer *err)
Execute the 'unbind' or 'unmacro' command.
Definition commands.c:554
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:116
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:455
void parse_menu(struct MenuDefinitionArray *menus, const char *s, struct Buffer *err)
Parse menu-names into an array.
Definition commands.c:176
Parse key binding commands.
enum CommandResult km_bind(const struct MenuDefinition *md, const char *key_str, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition menu.c:52
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:389
Dump key bindings.
void keymap_expand_string(const char *str, struct Buffer *buf)
Get a human-readable key string.
Definition keymap.c:265
void keymap_free(struct Keymap **pptr)
Free a Keymap.
Definition keymap.c:145
size_t parse_keys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition keymap.c:336
int km_get_op_menu(int mtype, const char *func)
Get the OpCode for a Function from a Menu.
Definition menu.c:198
struct MenuDefinition * menu_find_by_name(const char *name)
Find a Menu Definition by its name.
Definition menu.c:251
Key private Module data.
Key binding notifications.
NotifyBinding
Key Binding notification types.
Definition notify.h:47
@ NT_MACRO_ADD
Key macro has been added.
Definition notify.h:50
@ NT_MACRO_DELETE
Key macro has been deleted.
Definition notify.h:51
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition notify.h:49
@ NT_BINDING_ADD
Key binding has been added.
Definition notify.h:48
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:80
Maniplate Menus and SubMenus.
@ MODULE_ID_KEY
ModuleKey, Key mappings
Definition module_api.h:74
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:678
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:666
char * mutt_str_sep(char **stringp, const char *delim)
Find first occurrence of any of delim characters in *stringp.
Definition string.c:190
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition notify_type.h:40
struct MenuDefinition * pager_get_menu_definition(void)
Get the Pager Menu Definition.
Definition functions.c:1115
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:162
enum CommandId id
ID of the Command.
Definition command.h:163
A key binding Event.
Definition notify.h:33
const char * key
Key string being bound (for new bind/macro)
Definition notify.h:35
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition notify.h:36
Key private Module data.
Definition module_data.h:34
struct MenuDefinitionArray menu_defs
All registered Menus.
Definition module_data.h:39
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
short op
Operation to perform.
Definition keymap.h:46
Functions for a Dialog or Window.
Definition menudef.h:44
struct SubMenuArray submenus
Parts making up the Menu.
Definition menudef.h:47
const char * name
Menu name, e.g. "alias".
Definition menudef.h:46
int id
Menu ID, e.g. MENU_ALIAS.
Definition menudef.h:45
Mapping between a function and an operation.
Definition menu.h:37
const char * name
Name of the function.
Definition menu.h:38
int op
Operation, e.g. OP_DELETE.
Definition menu.h:39
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:58
bool restore_defaults
Restore fallback bindings after unbind.
Definition commands.c:57
bool all_keys
Command affects all key bindings.
Definition commands.c:56
Collection of related functions.
Definition menudef.h:33
const struct MenuFuncOp * functions
All available functions.
Definition menudef.h:35
struct KeymapList keymaps
All keybindings.
Definition menudef.h:36
MenuType
Types of GUI selections.
Definition type.h:33