NeoMutt  2025-12-11-58-g09398d
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 "core/lib.h"
34#include "gui/lib.h"
35#include "mutt.h"
36#include "lib.h"
37#include "menu/lib.h"
38#include "parse/lib.h"
39
41#define MAX_SEQ 8
42
56enum CommandResult km_bind(const char *s, enum MenuType mtype, int op,
57 char *macro, char *desc, struct Buffer *err)
58{
60 struct Keymap *last = NULL, *np = NULL, *compare = NULL;
61 keycode_t buf[MAX_SEQ];
62 size_t pos = 0, lastpos = 0;
63
64 size_t len = parsekeys(s, buf, MAX_SEQ);
65
66 struct Keymap *map = alloc_keys(len, buf);
67 map->op = op;
68 map->macro = mutt_str_dup(macro);
69 map->desc = mutt_str_dup(desc);
70
71 /* find position to place new keymap */
72 STAILQ_FOREACH(np, &Keymaps[mtype], entries)
73 {
74 compare = km_compare_keys(map, np, &pos);
75
76 if (compare == map) /* map's keycode is bigger */
77 {
78 last = np;
79 lastpos = pos;
80 if (pos > np->eq)
81 pos = np->eq;
82 }
83 else if (compare == np) /* np's keycode is bigger, found insert location */
84 {
85 map->eq = pos;
86 break;
87 }
88 else /* equal keycodes */
89 {
90 /* Don't warn on overwriting a 'noop' binding */
91 if ((np->len != len) && (np->op != OP_NULL))
92 {
93 static const char *guide_link = "https://neomutt.org/guide/configuration.html#bind-warnings";
94 /* Overwrite with the different lengths, warn */
95 struct Buffer *old_binding = buf_pool_get();
96 struct Buffer *new_binding = buf_pool_get();
97
98 km_expand_key(map, old_binding);
99 km_expand_key(np, new_binding);
100
101 char *err_msg = _("Binding '%s' will alias '%s' Before, try: 'bind %s %s noop'");
102 if (err)
103 {
104 /* err was passed, put the string there */
105 buf_printf(err, err_msg, buf_string(old_binding), buf_string(new_binding),
106 mutt_map_get_name(mtype, MenuNames), buf_string(new_binding));
107 buf_add_printf(err, " %s", guide_link);
108 }
109 else
110 {
111 struct Buffer *tmp = buf_pool_get();
112 buf_printf(tmp, err_msg, buf_string(old_binding), buf_string(new_binding),
113 mutt_map_get_name(mtype, MenuNames), buf_string(new_binding));
114 buf_add_printf(tmp, " %s", guide_link);
115 mutt_error("%s", buf_string(tmp));
116 buf_pool_release(&tmp);
117 }
118 rc = MUTT_CMD_WARNING;
119
120 buf_pool_release(&old_binding);
121 buf_pool_release(&new_binding);
122 }
123
124 map->eq = np->eq;
125 STAILQ_REMOVE(&Keymaps[mtype], np, Keymap, entries);
126 mutt_keymap_free(&np);
127 break;
128 }
129 }
130
131 if (map->op == OP_NULL)
132 {
133 mutt_keymap_free(&map);
134 }
135 else
136 {
137 if (last) /* if queue has at least one entry */
138 {
139 if (STAILQ_NEXT(last, entries))
140 STAILQ_INSERT_AFTER(&Keymaps[mtype], last, map, entries);
141 else /* last entry in the queue */
142 STAILQ_INSERT_TAIL(&Keymaps[mtype], map, entries);
143 last->eq = lastpos;
144 }
145 else /* queue is empty, so insert from head */
146 {
147 STAILQ_INSERT_HEAD(&Keymaps[mtype], map, entries);
148 }
149 }
150
151 return rc;
152}
153
161static void km_unbind_all(struct KeymapList *km_list, unsigned long mode)
162{
163 struct Keymap *np = NULL, *tmp = NULL;
164
165 STAILQ_FOREACH_SAFE(np, km_list, entries, tmp)
166 {
167 if (((mode & MUTT_UNBIND) && !np->macro) || ((mode & MUTT_UNMACRO) && np->macro))
168 {
169 STAILQ_REMOVE(km_list, np, Keymap, entries);
170 mutt_keymap_free(&np);
171 }
172 }
173}
174
189static char *parse_keymap(enum MenuType *mtypes, struct Buffer *line, int max_menus,
190 int *num_menus, struct Buffer *err, bool bind)
191{
192 struct Buffer *token = buf_pool_get();
193 int i = 0;
194 char *q = NULL;
195 char *result = NULL;
196
197 /* menu name */
199 char *p = token->data;
200 if (MoreArgs(line))
201 {
202 while (i < max_menus)
203 {
204 q = strchr(p, ',');
205 if (q)
206 *q = '\0';
207
208 int val = mutt_map_get_value(p, MenuNames);
209 if (val == -1)
210 {
211 buf_printf(err, _("%s: no such menu"), p);
212 goto done;
213 }
214 mtypes[i] = val;
215 i++;
216 if (q)
217 p = q + 1;
218 else
219 break;
220 }
221 *num_menus = i;
222 /* key sequence */
224
225 if (buf_at(token, 0) == '\0')
226 {
227 buf_printf(err, _("%s: null key sequence"), bind ? "bind" : "macro");
228 }
229 else if (MoreArgs(line))
230 {
231 result = buf_strdup(token);
232 goto done;
233 }
234 }
235 else
236 {
237 buf_printf(err, _("%s: too few arguments"), bind ? "bind" : "macro");
238 }
239done:
240 buf_pool_release(&token);
241 return result;
242}
243
253static void *parse_menu(bool *menus, char *s, struct Buffer *err)
254{
255 char *menu_names_dup = mutt_str_dup(s);
256 char *marker = menu_names_dup;
257 char *menu_name = NULL;
258
259 while ((menu_name = mutt_str_sep(&marker, ",")))
260 {
261 int value = mutt_map_get_value(menu_name, MenuNames);
262 if (value == -1)
263 {
264 buf_printf(err, _("%s: no such menu"), menu_name);
265 break;
266 }
267 else
268 {
269 menus[value] = true;
270 }
271 }
272
273 FREE(&menu_names_dup);
274 return NULL;
275}
276
286static enum CommandResult try_bind(char *key, enum MenuType mtype, char *func,
287 const struct MenuFuncOp *funcs, struct Buffer *err)
288{
289 for (int i = 0; funcs[i].name; i++)
290 {
291 if (mutt_str_equal(func, funcs[i].name))
292 {
293 return km_bind(key, mtype, funcs[i].op, NULL, NULL, err);
294 }
295 }
296 if (err)
297 {
298 buf_printf(err, _("Function '%s' not available for menu '%s'"), func,
300 }
301 return MUTT_CMD_ERROR; /* Couldn't find an existing function with this name */
302}
303
310enum CommandResult parse_push(const struct Command *cmd, struct Buffer *line,
311 struct Buffer *err)
312{
313 if (!MoreArgs(line))
314 {
315 buf_printf(err, _("%s: too few arguments"), cmd->name);
316 return MUTT_CMD_WARNING;
317 }
318
319 struct Buffer *token = buf_pool_get();
321
323 if (MoreArgs(line))
324 {
325 buf_printf(err, _("%s: too many arguments"), cmd->name);
326 goto done;
327 }
328
330 rc = MUTT_CMD_SUCCESS;
331
332done:
333 buf_pool_release(&token);
334 return rc;
335}
336
345enum CommandResult parse_bind(const struct Command *cmd, struct Buffer *line,
346 struct Buffer *err)
347{
348 if (StartupComplete)
349 {
350 // Save and restore the offset in `line` because parse_bind_macro() might change it
351 char *dptr = line->dptr;
352 if (parse_bind_macro(cmd, line, err) == MUTT_CMD_SUCCESS)
353 {
354 return MUTT_CMD_SUCCESS;
355 }
356 if (!buf_is_empty(err))
357 {
358 return MUTT_CMD_ERROR;
359 }
360 line->dptr = dptr;
361 }
362
363 struct Buffer *token = buf_pool_get();
364 struct Buffer *keystr = NULL;
365
366 const struct MenuFuncOp *funcs = NULL;
367 enum MenuType mtypes[MENU_MAX];
368 int num_menus = 0;
370
371 char *key = parse_keymap(mtypes, line, countof(mtypes), &num_menus, err, true);
372 if (!key)
373 goto done;
374
375 /* function to execute */
377 if (MoreArgs(line))
378 {
379 buf_printf(err, _("%s: too many arguments"), cmd->name);
380 goto done;
381 }
382
383 rc = MUTT_CMD_SUCCESS;
384
385 if (mutt_istr_equal("noop", buf_string(token)))
386 {
387 keystr = buf_pool_get();
388 for (int i = 0; i < num_menus; i++)
389 {
390 km_bind(key, mtypes[i], OP_NULL, NULL, NULL, NULL); /* the 'unbind' command */
391 funcs = km_get_table(mtypes[i]);
392 if (funcs)
393 {
394 buf_reset(keystr);
395 km_expand_key_string(key, keystr);
396 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
397 mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", mname, buf_string(keystr));
398
399 int op = get_op(OpGeneric, buf_string(token), mutt_str_len(buf_string(token)));
400 struct EventBinding ev_b = { mtypes[i], key, op };
402 }
403 }
404 }
405 else
406 {
407 keystr = buf_pool_get();
408 for (int i = 0; i < num_menus; i++)
409 {
410 /* The pager and editor menus don't use the generic map,
411 * however for other menus try generic first. */
412 if ((mtypes[i] != MENU_PAGER) && (mtypes[i] != MENU_EDITOR) && (mtypes[i] != MENU_GENERIC))
413 {
414 rc = try_bind(key, mtypes[i], token->data, OpGeneric, err);
415 if (rc == MUTT_CMD_SUCCESS)
416 {
417 buf_reset(keystr);
418 km_expand_key_string(key, keystr);
419 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
420 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, buf_string(keystr));
421
422 int op = get_op(OpGeneric, buf_string(token), mutt_str_len(buf_string(token)));
423 struct EventBinding ev_b = { mtypes[i], key, op };
425 continue;
426 }
427 if (rc == MUTT_CMD_WARNING)
428 break;
429 }
430
431 /* Clear any error message, we're going to try again */
432 err->data[0] = '\0';
433 funcs = km_get_table(mtypes[i]);
434 if (funcs)
435 {
436 rc = try_bind(key, mtypes[i], token->data, funcs, err);
437 if (rc == MUTT_CMD_SUCCESS)
438 {
439 buf_reset(keystr);
440 km_expand_key_string(key, keystr);
441 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
442 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, buf_string(keystr));
443
444 int op = get_op(funcs, buf_string(token), mutt_str_len(buf_string(token)));
445 struct EventBinding ev_b = { mtypes[i], key, op };
447 continue;
448 }
449 }
450 }
451 }
452
453done:
454 FREE(&key);
455 buf_pool_release(&keystr);
456 buf_pool_release(&token);
457 return rc;
458}
459
472enum CommandResult parse_unbind(const struct Command *cmd, struct Buffer *line,
473 struct Buffer *err)
474{
475 if (!MoreArgs(line))
476 {
477 buf_printf(err, _("%s: too few arguments"), cmd->name);
478 return MUTT_CMD_WARNING;
479 }
480
481 struct Buffer *token = buf_pool_get();
483
484 bool menu_matches[MENU_MAX] = { 0 };
485 bool all_keys = false;
486 char *key = NULL;
487
489 if (mutt_str_equal(buf_string(token), "*"))
490 {
491 for (enum MenuType i = 1; i < MENU_MAX; i++)
492 menu_matches[i] = true;
493 }
494 else
495 {
496 parse_menu(menu_matches, token->data, err);
497 }
498
499 if (MoreArgs(line))
500 {
502 key = token->data;
503 }
504 else
505 {
506 all_keys = true;
507 }
508
509 if (MoreArgs(line))
510 {
511 buf_printf(err, _("%s: too many arguments"), cmd->name);
512 goto done;
513 }
514
515 for (enum MenuType i = 1; i < MENU_MAX; i++)
516 {
517 if (!menu_matches[i])
518 continue;
519 if (all_keys)
520 {
521 km_unbind_all(&Keymaps[i], cmd->data);
522 km_bind("<enter>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
523 km_bind("<return>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
524 km_bind("<enter>", MENU_INDEX, OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
525 km_bind("<return>", MENU_INDEX, OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
526 km_bind("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
527 km_bind("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
528 km_bind(":", MENU_GENERIC, OP_ENTER_COMMAND, NULL, NULL, NULL);
529 km_bind(":", MENU_PAGER, OP_ENTER_COMMAND, NULL, NULL, NULL);
530 if (i != MENU_EDITOR)
531 {
532 km_bind("?", i, OP_HELP, NULL, NULL, NULL);
533 km_bind("q", i, OP_EXIT, NULL, NULL, NULL);
534 }
535
536 const char *mname = mutt_map_get_name(i, MenuNames);
537 mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE_ALL: %s\n", mname);
538
539 struct EventBinding ev_b = { i, NULL, OP_NULL };
542 &ev_b);
543 }
544 else
545 {
546 struct Buffer *keystr = buf_pool_get();
547 km_expand_key_string(key, keystr);
548 const char *mname = mutt_map_get_name(i, MenuNames);
549 mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE: %s %s\n", mname, buf_string(keystr));
550 buf_pool_release(&keystr);
551
552 km_bind(key, i, OP_NULL, NULL, NULL, NULL);
553 struct EventBinding ev_b = { i, key, OP_NULL };
556 }
557 }
558
559 rc = MUTT_CMD_SUCCESS;
560
561done:
562 buf_pool_release(&token);
563 return rc;
564}
565
572enum CommandResult parse_macro(const struct Command *cmd, struct Buffer *line,
573 struct Buffer *err)
574{
575 if (StartupComplete)
576 {
577 // Save and restore the offset in `line` because parse_bind_macro() might change it
578 char *dptr = line->dptr;
579 if (parse_bind_macro(cmd, line, err) == MUTT_CMD_SUCCESS)
580 {
581 return MUTT_CMD_SUCCESS;
582 }
583 if (!buf_is_empty(err))
584 {
585 return MUTT_CMD_ERROR;
586 }
587 line->dptr = dptr;
588 }
589
590 enum MenuType mtypes[MENU_MAX];
591 int num_menus = 0;
592 struct Buffer *token = buf_pool_get();
593 struct Buffer *keystr = NULL;
595
596 char *key = parse_keymap(mtypes, line, countof(mtypes), &num_menus, err, false);
597 if (!key)
598 goto done;
599
601 /* make sure the macro sequence is not an empty string */
602 if (buf_at(token, 0) == '\0')
603 {
604 buf_strcpy(err, _("macro: empty key sequence"));
605 }
606 else
607 {
608 if (MoreArgs(line))
609 {
610 char *seq = mutt_str_dup(buf_string(token));
612
613 if (MoreArgs(line))
614 {
615 buf_printf(err, _("%s: too many arguments"), cmd->name);
616 }
617 else
618 {
619 keystr = buf_pool_get();
620 for (int i = 0; i < num_menus; i++)
621 {
622 rc = km_bind(key, mtypes[i], OP_MACRO, seq, token->data, NULL);
623 if (rc == MUTT_CMD_SUCCESS)
624 {
625 buf_reset(keystr);
626 km_expand_key_string(key, keystr);
627 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
628 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, buf_string(keystr));
629
630 struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
632 continue;
633 }
634 }
635 }
636
637 FREE(&seq);
638 }
639 else
640 {
641 keystr = buf_pool_get();
642 for (int i = 0; i < num_menus; i++)
643 {
644 rc = km_bind(key, mtypes[i], OP_MACRO, token->data, NULL, NULL);
645 if (rc == MUTT_CMD_SUCCESS)
646 {
647 buf_reset(keystr);
648 km_expand_key_string(key, keystr);
649 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
650 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, buf_string(keystr));
651
652 struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
654 continue;
655 }
656 }
657 }
658 }
659
660done:
661 FREE(&key);
662 buf_pool_release(&keystr);
663 buf_pool_release(&token);
664 return rc;
665}
666
673enum CommandResult parse_exec(const struct Command *cmd, struct Buffer *line,
674 struct Buffer *err)
675{
676 if (!MoreArgs(line))
677 {
678 buf_printf(err, _("%s: too few arguments"), cmd->name);
679 return MUTT_CMD_WARNING;
680 }
681
682 struct Buffer *token = buf_pool_get();
684
685 int ops[128];
686 int nops = 0;
687 const struct MenuFuncOp *funcs = NULL;
688 char *function = NULL;
689
690 do
691 {
693 function = token->data;
694
695 const enum MenuType mtype = menu_get_current_type();
696 funcs = km_get_table(mtype);
697 if (!funcs && (mtype != MENU_PAGER))
698 funcs = OpGeneric;
699
700 ops[nops] = get_op(funcs, function, mutt_str_len(function));
701 if ((ops[nops] == OP_NULL) && (mtype != MENU_PAGER) && (mtype != MENU_GENERIC))
702 {
703 ops[nops] = get_op(OpGeneric, function, mutt_str_len(function));
704 }
705
706 if (ops[nops] == OP_NULL)
707 {
709 mutt_error(_("%s: no such function"), function);
710 goto done;
711 }
712 nops++;
713 } while (MoreArgs(line) && nops < countof(ops));
714
715 while (nops)
716 mutt_push_macro_event(0, ops[--nops]);
717
718 rc = MUTT_CMD_SUCCESS;
719
720done:
721 buf_pool_release(&token);
722 return rc;
723}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:204
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
CommandResult
Error codes for command_t parse functions.
Definition command.h:35
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition command.h:38
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition command.h:36
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition command.h:37
bool StartupComplete
When the config has been read.
Definition address.c:13
Convenience wrapper for the core headers.
int parse_extract_token(struct Buffer *dest, struct Buffer *line, TokenFlags flags)
Extract one token from a string.
Definition extract.c:48
#define TOKEN_CONDENSE
^(char) to control chars (macros)
Definition extract.h:46
#define MoreArgs(buf)
Definition extract.h:30
#define TOKEN_NO_FLAGS
No flags are set.
Definition extract.h:44
void generic_tokenize_push_string(char *s)
Parse and queue a 'push' command.
Definition get.c:348
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition get.c:58
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition get.c:155
enum CommandResult parse_push(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse the 'push' command - Implements Command::parse() -.
Definition commands.c:310
enum CommandResult parse_bind_macro(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse 'bind' and 'macro' commands - Implements Command::parse() -.
Definition dump.c:175
enum CommandResult parse_macro(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse the 'macro' command - Implements Command::parse() -.
Definition commands.c:572
enum CommandResult parse_exec(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse the 'exec' command - Implements Command::parse() -.
Definition commands.c:673
enum CommandResult parse_bind(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse the 'bind' command - Implements Command::parse() -.
Definition commands.c:345
enum CommandResult parse_unbind(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse the 'unbind' command - Implements Command::parse() -.
Definition commands.c:472
#define mutt_error(...)
Definition logging2.h:93
#define mutt_debug(LEVEL,...)
Definition logging2.h:90
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition functions.c:69
Convenience wrapper for the gui headers.
static void * parse_menu(bool *menus, char *s, struct Buffer *err)
Parse menu-names into an array.
Definition commands.c:253
enum CommandResult km_bind(const char *s, enum MenuType mtype, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition commands.c:56
static char * parse_keymap(enum MenuType *mtypes, struct Buffer *line, int max_menus, int *num_menus, struct Buffer *err, bool bind)
Parse a user-config key binding.
Definition commands.c:189
static void km_unbind_all(struct KeymapList *km_list, unsigned long mode)
Free all the keys in the supplied Keymap.
Definition commands.c:161
static enum CommandResult try_bind(char *key, enum MenuType mtype, char *func, const struct MenuFuncOp *funcs, struct Buffer *err)
Try to make a key binding.
Definition commands.c:286
#define MAX_SEQ
Maximum length of a key binding sequence used for buffer in km_bind.
Definition commands.c:41
struct Keymap * km_compare_keys(struct Keymap *k1, struct Keymap *k2, size_t *pos)
Compare two keymaps' keyscodes and return the bigger one.
Definition lib.c:275
struct Keymap * alloc_keys(size_t len, keycode_t *keys)
Allocate space for a sequence of keys.
Definition lib.c:150
void mutt_keymap_free(struct Keymap **ptr)
Free a Keymap.
Definition lib.c:131
struct KeymapList Keymaps[MENU_MAX]
Array of key mappings, one for each MenuType.
Definition lib.c:125
size_t parsekeys(const char *str, keycode_t *d, size_t max)
Parse a key string into key codes.
Definition lib.c:216
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition lib.c:485
int get_op(const struct MenuFuncOp *funcs, const char *start, size_t len)
Get the function by its name.
Definition lib.c:299
bool km_expand_key(struct Keymap *map, struct Buffer *buf)
Get the key string bound to a Keymap.
Definition lib.c:437
void km_expand_key_string(char *str, struct Buffer *buf)
Get a human-readable key string.
Definition lib.c:455
Manage keymappings.
@ NT_MACRO_ADD
Key macro has been added.
Definition lib.h:155
@ NT_MACRO_DELETE
Key macro has been deleted.
Definition lib.h:156
@ NT_MACRO_DELETE_ALL
All key macros have been deleted.
Definition lib.h:157
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition lib.h:152
@ NT_BINDING_ADD
Key binding has been added.
Definition lib.h:151
@ NT_BINDING_DELETE_ALL
All key bindings have been deleted.
Definition lib.h:153
#define MUTT_UNBIND
Parse 'unbind' command.
Definition lib.h:49
#define MUTT_UNMACRO
Parse 'unmacro' command.
Definition lib.h:50
short keycode_t
Type for key storage, the rest of neomutt works fine with int type.
Definition lib.h:57
@ LL_NOTIFY
Log of notifications.
Definition logging2.h:49
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition mapping.c:85
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition mapping.c:42
#define countof(x)
Definition memory.h:44
#define FREE(x)
Definition memory.h:62
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:89
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:672
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:255
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:660
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:498
char * mutt_str_sep(char **stringp, const char *delim)
Find first occurrence of any of delim characters in *stringp.
Definition string.c:188
Many unsorted constants and some structs.
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition notify_type.h:40
Text parsing functions.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:96
#define STAILQ_REMOVE(head, elm, type, field)
Definition queue.h:441
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:427
#define STAILQ_INSERT_HEAD(head, elm, field)
Definition queue.h:421
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
#define STAILQ_NEXT(elm, field)
Definition queue.h:439
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field)
Definition queue.h:415
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
intptr_t data
Data or flags to pass to the command.
Definition command.h:77
const char * name
Name of the command.
Definition command.h:59
A key binding Event.
Definition lib.h:136
const char * key
Key string being bound (for new bind/macro)
Definition lib.h:138
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition lib.h:139
A keyboard mapping.
Definition lib.h:67
char * macro
Macro expansion (op == OP_MACRO)
Definition lib.h:68
short eq
Number of leading keys equal to next entry.
Definition lib.h:71
char * desc
Description of a macro for the help menu.
Definition lib.h:69
short len
Length of key sequence (unit: sizeof (keycode_t))
Definition lib.h:72
short op
Operation to perform.
Definition lib.h:70
Mapping between a function and an operation.
Definition lib.h:117
const char * name
Name of the function.
Definition lib.h:118
int op
Operation, e.g. OP_DELETE.
Definition lib.h:119
Container for Accounts, Notifications.
Definition neomutt.h:43
struct Notify * notify
Notifications handler.
Definition neomutt.h:44
const struct Mapping MenuNames[]
Menu name lookup table.
Definition type.c:37
MenuType
Types of GUI selections.
Definition type.h:35
@ MENU_INDEX
Index panel (list of emails)
Definition type.h:46
@ MENU_GENERIC
Generic selection list.
Definition type.h:45
@ MENU_PAGER
Pager pager (email viewer)
Definition type.h:47
@ MENU_MAX
Definition type.h:52
@ MENU_EDITOR
Text entry area.
Definition type.h:44