NeoMutt  2025-12-11-911-gd8d604
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;
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 {
74 parse_extract_token(token, line, TOKEN_NONE);
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 */
123 parse_extract_token(token, line, TOKEN_NONE);
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 */
146 parse_extract_token(token, line, TOKEN_NONE);
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 */
272 parse_extract_token(token, line, TOKEN_NONE);
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 if (op != OP_NULL)
325 break;
326 }
327
328 if (op == OP_NULL)
329 {
330 buf_printf(err, _("%s: no such function: %s"), cmd->name, buf_string(token));
331 rc = MUTT_CMD_ERROR;
332 goto done;
333 }
334
335 rc = km_bind(md, key, op, NULL, NULL, err);
336 if (rc == MUTT_CMD_SUCCESS)
337 {
338 buf_reset(keystr);
339 keymap_expand_string(key, keystr);
340 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", md->name, buf_string(keystr));
341
342 struct EventBinding ev_b = { md, key, op };
344 }
345 }
346 }
347
348done:
349 FREE(&key);
350 ARRAY_FREE(&mda);
351 buf_pool_release(&keystr);
352 buf_pool_release(&token);
353 return rc;
354}
355
361{
362 bool success = false;
363
364 if (!md || (md == MdGeneric))
365 {
366 km_bind(MdGeneric, "<enter>", OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
367 km_bind(MdGeneric, "<return>", OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
368 km_bind(MdGeneric, ":", OP_ENTER_COMMAND, NULL, NULL, NULL);
369 km_bind(MdGeneric, "?", OP_HELP, NULL, NULL, NULL);
370 km_bind(MdGeneric, "q", OP_EXIT, NULL, NULL, NULL);
371 success = true;
372 }
373
374 if (!md || (md == MdIndex))
375 {
376 km_bind(MdIndex, "<enter>", OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
377 km_bind(MdIndex, "<return>", OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
378 km_bind(MdIndex, "q", OP_EXIT, NULL, NULL, NULL);
379 success = true;
380 }
381
382 if (!md || (md == MdEditor))
383 {
384 km_bind(MdEditor, "<backspace>", OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
385 km_bind(MdEditor, "\177", OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
386 success = true;
387 }
388
389 if (!md || (md == MdPager))
390 {
391 km_bind(MdPager, ":", OP_ENTER_COMMAND, NULL, NULL, NULL);
392 km_bind(MdPager, "?", OP_HELP, NULL, NULL, NULL);
393 km_bind(MdPager, "q", OP_EXIT, NULL, NULL, NULL);
394 success = true;
395 }
396
397 if (!md || (md == MdDialog))
398 {
399 km_bind(MdDialog, ":", OP_ENTER_COMMAND, NULL, NULL, NULL);
400 km_bind(MdDialog, "?", OP_HELP, NULL, NULL, NULL);
401 km_bind(MdDialog, "q", OP_EXIT, NULL, NULL, NULL);
402 success = true;
403 }
404
405 if (success)
406 {
407 mutt_debug(LL_NOTIFY, "NT_BINDING_ADD set defaults\n");
408 struct EventBinding ev_b = { md, NULL, OP_NULL };
410 }
411}
412
419{
420 switch (ev)
421 {
422 case NT_BINDING_ADD:
423 return "NT_BINDING_ADD";
425 return "NT_BINDING_DELETE";
426 case NT_MACRO_ADD:
427 return "NT_MACRO_ADD";
428 case NT_MACRO_DELETE:
429 return "NT_MACRO_DELETE";
430 default:
431 return "UNKNOWN";
432 }
433}
434
458bool parse_unbind_args(const struct Command *cmd, struct Buffer *line,
459 struct Buffer *err, struct ParseUnbind *args)
460{
461 if (!cmd || !line || !err || !args)
462 return false;
463
464 if (!MoreArgs(line))
465 {
466 buf_printf(err, _("%s: too few arguments"), cmd->name);
467 return false;
468 }
469
470 struct Buffer *token = buf_pool_get();
471 bool rc = false;
472
473 parse_extract_token(token, line, TOKEN_NONE);
474 if (mutt_str_equal(buf_string(token), "*"))
475 {
476 args->all_menus = true;
477
478 if (MoreArgs(line))
479 {
480 // `unbind * key`
481 // `unmacro * key`
482 parse_extract_token(token, line, TOKEN_NONE);
483 args->key = buf_strdup(token);
484 }
485 else
486 {
487 // `unbind *`
488 // `unmacro *`
489 args->all_keys = true;
490 }
491 }
492 else
493 {
494 parse_menu(&args->mda, buf_string(token), err);
495 if (!buf_is_empty(err))
496 goto done;
497
498 if (MoreArgs(line))
499 {
500 parse_extract_token(token, line, TOKEN_NONE);
501 if (mutt_str_equal(buf_string(token), "*"))
502 {
503 // `unbind menu *`
504 // `unmacro menu *`
505 args->all_keys = true;
506 }
507 else
508 {
509 // `unbind menu key`
510 // `unmacro menu key`
511 args->key = buf_strdup(token);
512 }
513 }
514 else
515 {
516 // `unbind menu`
517 // `unmacro menu`
518 args->all_keys = true;
519 }
520 }
521
522 if (MoreArgs(line))
523 {
524 buf_printf(err, _("%s: too many arguments"), cmd->name);
525 goto done;
526 }
527
528 rc = true;
529
530done:
531 buf_pool_release(&token);
532 return rc;
533}
534
546bool parse_unbind_exec(const struct Command *cmd, struct ParseUnbind *args, struct Buffer *err)
547{
548 if (!cmd || !args || !err)
549 return false;
550
552 keycode_t key_bytes[KEY_SEQ_MAX_LEN] = { 0 };
553 int key_len = 0;
554 if (args->key)
555 {
556 key_len = parse_keys(args->key, key_bytes, KEY_SEQ_MAX_LEN);
557 if (key_len == 0)
558 return false;
559 }
560
561 bool success = false;
562 struct Buffer *keystr = buf_pool_get();
564 struct MenuDefinition **mdp = NULL;
565 ARRAY_FOREACH(mdp, &mod_data->menu_defs)
566 {
567 struct MenuDefinition *md = *mdp;
568
569 if (!args->all_menus)
570 {
571 bool found = false;
572 struct MenuDefinition **mdp2 = NULL;
573 ARRAY_FOREACH(mdp2, &args->mda)
574 {
575 if ((*mdp2)->id == md->id)
576 {
577 found = true;
578 break;
579 }
580 }
581 if (!found)
582 continue;
583 }
584
585 struct SubMenu **smp = ARRAY_GET(&md->submenus, 0);
586 if (!smp || !*smp)
587 continue;
588
589 struct SubMenu *sm = *smp;
590
591 struct Keymap *km = NULL;
592 struct Keymap *km_tmp = NULL;
593 STAILQ_FOREACH_SAFE(km, &sm->keymaps, entries, km_tmp)
594 {
595 if (args->all_keys ||
596 ((key_len == km->len) && (memcmp(km->keys, key_bytes, km->len) == 0)))
597 {
598 STAILQ_REMOVE(&sm->keymaps, km, Keymap, entries);
599 keymap_free(&km);
600 success = true;
601
602 if (!args->all_keys && !args->all_menus)
603 {
604 buf_reset(keystr);
605 keymap_expand_string(args->key, keystr);
606 mutt_debug(LL_NOTIFY, "%s: %s %s\n", notify_binding_name(nb),
607 md->name, buf_string(keystr));
608
609 struct EventBinding ev_b = { md, args->key, OP_NULL };
610 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
611 }
612 }
613 }
614
615 if (args->all_keys && !args->all_menus && success)
616 {
617 buf_reset(keystr);
618 keymap_expand_string(args->key, keystr);
619 mutt_debug(LL_NOTIFY, "%s: %s %s\n", notify_binding_name(nb), md->name,
620 buf_string(keystr));
621
622 struct EventBinding ev_b = { md, args->key, OP_NULL };
623 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
624
625 // restore some bindings for this menu
627 }
628 }
629
630 if (args->all_menus && success)
631 {
632 buf_reset(keystr);
633 keymap_expand_string(args->key, keystr);
634 mutt_debug(LL_NOTIFY, "%s: ALL %s\n", notify_binding_name(nb), buf_string(keystr));
635
636 struct EventBinding ev_b = { NULL, args->key, OP_NULL };
637 notify_send(NeoMutt->notify, NT_BINDING, nb, &ev_b);
638
639 // restore some bindings for all menus
641 }
642
643 buf_pool_release(&keystr);
644 return true;
645}
646
654enum CommandResult parse_unbind(const struct Command *cmd, struct Buffer *line,
655 const struct ParseContext *pc, struct ParseError *pe)
656{
657 struct Buffer *err = pe->message;
658
659 struct ParseUnbind args = { 0 };
661
662 if (!parse_unbind_args(cmd, line, err, &args))
663 goto done;
664
665 rc = MUTT_CMD_ERROR;
666 if (parse_unbind_exec(cmd, &args, err))
667 rc = MUTT_CMD_SUCCESS;
668
669done:
670 ARRAY_FREE(&args.mda);
671 FREE(&args.key);
672 return rc;
673}
674
681enum CommandResult parse_macro(const struct Command *cmd, struct Buffer *line,
682 const struct ParseContext *pc, struct ParseError *pe)
683{
684 struct Buffer *err = pe->message;
685
686 if (StartupComplete)
687 {
688 // Save and restore the offset in `line` because parse_dump() might change it
689 char *dptr = line->dptr;
690 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
691 {
692 return MUTT_CMD_SUCCESS;
693 }
694 if (!buf_is_empty(err))
695 {
696 return MUTT_CMD_ERROR;
697 }
698 line->dptr = dptr;
699 }
700
701 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
702 struct Buffer *token = buf_pool_get();
703 struct Buffer *keystr = NULL;
705
706 char *key = parse_keymap(cmd, &mda, line, err);
707 if (!key)
708 goto done;
709
711 /* make sure the macro sequence is not an empty string */
712 if (buf_at(token, 0) == '\0')
713 {
714 buf_strcpy(err, _("macro: empty key sequence"));
715 }
716 else
717 {
718 if (MoreArgs(line))
719 {
720 char *seq = mutt_str_dup(buf_string(token));
722
723 if (MoreArgs(line))
724 {
725 buf_printf(err, _("%s: too many arguments"), cmd->name);
726 }
727 else
728 {
729 keystr = buf_pool_get();
730 struct MenuDefinition **mdp = NULL;
731 ARRAY_FOREACH(mdp, &mda)
732 {
733 struct MenuDefinition *md = *mdp;
734
735 rc = km_bind(md, key, OP_MACRO, seq, token->data, NULL);
736 if (rc == MUTT_CMD_SUCCESS)
737 {
738 buf_reset(keystr);
739 keymap_expand_string(key, keystr);
740 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
741
742 struct EventBinding ev_b = { md, key, OP_MACRO };
744 continue;
745 }
746 }
747 }
748
749 FREE(&seq);
750 }
751 else
752 {
753 keystr = buf_pool_get();
754 struct MenuDefinition **mdp = NULL;
755 ARRAY_FOREACH(mdp, &mda)
756 {
757 struct MenuDefinition *md = *mdp;
758
759 rc = km_bind(md, key, OP_MACRO, token->data, NULL, NULL);
760 if (rc == MUTT_CMD_SUCCESS)
761 {
762 buf_reset(keystr);
763 keymap_expand_string(key, keystr);
764 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
765
766 struct EventBinding ev_b = { md, key, OP_MACRO };
768 continue;
769 }
770 }
771 }
772 }
773
774done:
775 FREE(&key);
776 ARRAY_FREE(&mda);
777 buf_pool_release(&keystr);
778 buf_pool_release(&token);
779 return rc;
780}
781
788enum CommandResult parse_exec(const struct Command *cmd, struct Buffer *line,
789 const struct ParseContext *pc, struct ParseError *pe)
790{
791 struct Buffer *err = pe->message;
792
793 if (!MoreArgs(line))
794 {
795 buf_printf(err, _("%s: too few arguments"), cmd->name);
796 return MUTT_CMD_WARNING;
797 }
798
799 struct Buffer *token = buf_pool_get();
801
802 int ops[128];
803 int nops = 0;
804 char *function = NULL;
805
806 do
807 {
808 parse_extract_token(token, line, TOKEN_NONE);
809 function = token->data;
810
811 const enum MenuType mtype = menu_get_current_type();
812 ops[nops] = km_get_op_menu(mtype, function);
813 if (ops[nops] == OP_NULL)
814 {
816 mutt_error(_("%s: no such function"), function);
817 goto done;
818 }
819 nops++;
820 } while (MoreArgs(line) && nops < countof(ops));
821
822 while (nops)
823 mutt_push_macro_event(0, ops[--nops]);
824
825 rc = MUTT_CMD_SUCCESS;
826
827done:
828 buf_pool_release(&token);
829 return rc;
830}
#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: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.
#define MdEditor
Definition functions.h:36
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:31
@ TOKEN_CONDENSE
^(char) to control chars (macros)
Definition extract.h:51
@ TOKEN_NONE
No flags are set.
Definition extract.h:49
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: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:788
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:681
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:654
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
#define MdGeneric
Definition functions.h:33
#define MdDialog
Definition functions.h:34
Convenience wrapper for the gui headers.
#define MdIndex
Definition functions.h:72
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:418
void set_default_bindings(const struct MenuDefinition *md)
Set some safe default keybindings.
Definition commands.c:360
bool parse_unbind_exec(const struct Command *cmd, struct ParseUnbind *args, struct Buffer *err)
Execute the 'unbind' or 'unmacro' command.
Definition commands.c:546
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:458
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: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:266
void keymap_free(struct Keymap **pptr)
Free a Keymap.
Definition keymap.c:146
size_t parse_keys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition keymap.c:337
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:82
Maniplate Menus and SubMenus.
@ MODULE_ID_KEY
ModuleKey, Key mappings
Definition module_api.h:73
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:677
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:665
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:663
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition notify_type.h:40
#define MdPager
Definition functions.h:73
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
Functions for a Dialog or Window.
Definition menu.h:77
const char * name
Menu name, e.g. "alias".
Definition menu.h:79
int id
Menu ID, e.g. MENU_ALIAS.
Definition menu.h:78
struct SubMenuPArray submenus
Parts making up the Menu.
Definition menu.h:80
Mapping between a function and an operation.
Definition menu.h:35
const char * name
Name of the function.
Definition menu.h:36
int op
Operation, e.g. OP_DELETE.
Definition menu.h:37
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:65
const struct MenuFuncOp * functions
All available functions.
Definition menu.h:67
struct KeymapList keymaps
All keybindings.
Definition menu.h:68
MenuType
Types of GUI selections.
Definition type.h:33