NeoMutt  2022-04-29-215-gc12b98
Teaching an old dog new tricks
DOXYGEN

Function to parse a command. More...

+ Collaboration diagram for parse():

Functions

enum CommandResult parse_alias (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'alias' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unalias (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unalias' command - Implements Command::parse() -. More...
 
enum CommandResult parse_alternates (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'alternates' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unalternates (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unalternates' command - Implements Command::parse() -. More...
 
enum CommandResult parse_attachments (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'attachments' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unattachments (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unattachments' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_uncolor (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'uncolor' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_unmono (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unmono' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_color (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'color' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_mono (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'mono' command - Implements Command::parse() -. More...
 
enum CommandResult parse_cd (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'cd' command - Implements Command::parse() -. More...
 
enum CommandResult parse_echo (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'echo' command - Implements Command::parse() -. More...
 
enum CommandResult parse_finish (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'finish' command - Implements Command::parse() -. More...
 
enum CommandResult parse_group (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'group' and 'ungroup' commands - Implements Command::parse() -. More...
 
enum CommandResult parse_ifdef (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'ifdef' and 'ifndef' commands - Implements Command::parse() -. More...
 
enum CommandResult parse_ignore (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'ignore' command - Implements Command::parse() -. More...
 
enum CommandResult parse_lists (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'lists' command - Implements Command::parse() -. More...
 
enum CommandResult parse_mailboxes (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'mailboxes' command - Implements Command::parse() -. More...
 
enum CommandResult parse_my_hdr (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'my_hdr' command - Implements Command::parse() -. More...
 
enum CommandResult parse_set (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'set' family of commands - Implements Command::parse() -. More...
 
enum CommandResult parse_setenv (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'setenv' and 'unsetenv' commands - Implements Command::parse() -. More...
 
enum CommandResult parse_source (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'source' command - Implements Command::parse() -. More...
 
enum CommandResult parse_spam_list (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'spam' and 'nospam' commands - Implements Command::parse() -. More...
 
enum CommandResult parse_stailq (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse a list command - Implements Command::parse() -. More...
 
enum CommandResult parse_subscribe (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'subscribe' command - Implements Command::parse() -. More...
 
enum CommandResult parse_subscribe_to (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'subscribe-to' command - Implements Command::parse() -. More...
 
enum CommandResult parse_tag_formats (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'tag-formats' command - Implements Command::parse() -. More...
 
enum CommandResult parse_tag_transforms (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'tag-transforms' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unignore (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unignore' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unlists (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unlists' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unmailboxes (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unmailboxes' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unmy_hdr (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unmy_hdr' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unstailq (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse an unlist command - Implements Command::parse() -. More...
 
enum CommandResult parse_unsubscribe (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unsubscribe' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unsubscribe_from (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unsubscribe-from' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_charset_iconv_hook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse 'charset-hook' and 'iconv-hook' commands - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_hook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'hook' family of commands - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_idxfmt_hook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'index-format-hook' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_unhook (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unhook' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_push (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'push' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_bind (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'bind' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_unbind (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unbind' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_macro (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'macro' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_exec (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'exec' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_lua_parse (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'lua' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_lua_source_file (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'lua-source' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_score (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'score' command - Implements Command::parse() -. More...
 
enum CommandResult mutt_parse_unscore (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unscore' command - Implements Command::parse() -. More...
 
enum CommandResult sb_parse_whitelist (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'sidebar_whitelist' command - Implements Command::parse() -. More...
 
enum CommandResult sb_parse_unwhitelist (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unsidebar_whitelist' command - Implements Command::parse() -. More...
 
static enum CommandResult parse_unreplace_list (struct Buffer *buf, struct Buffer *s, struct ReplaceList *list, struct Buffer *err)
 Remove a string replacement rule - Implements Command::parse() -. More...
 
static enum CommandResult parse_replace_list (struct Buffer *buf, struct Buffer *s, struct ReplaceList *list, struct Buffer *err)
 Parse a string replacement rule - Implements Command::parse() -. More...
 
enum CommandResult parse_subjectrx_list (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'subjectrx' command - Implements Command::parse() -. More...
 
enum CommandResult parse_unsubjectrx_list (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'unsubjectrx' command - Implements Command::parse() -. More...
 

Detailed Description

Function to parse a command.

Parameters
bufTemporary Buffer space
sBuffer containing string to be parsed
dataFlags associated with the command
errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Function Documentation

◆ parse_alias()

enum CommandResult parse_alias ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'alias' command - Implements Command::parse() -.

e.g. "alias jim James Smith <js@example.com> # Pointy-haired boss"

Definition at line 48 of file commands.c.

50{
51 struct Alias *tmp = NULL;
52 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
53 enum NotifyAlias event;
54
55 if (!MoreArgs(s))
56 {
57 mutt_buffer_strcpy(err, _("alias: no address"));
58 return MUTT_CMD_WARNING;
59 }
60
61 /* name */
63 mutt_debug(LL_DEBUG5, "First token is '%s'\n", buf->data);
64 if (parse_grouplist(&gl, buf, s, err) == -1)
65 {
66 return MUTT_CMD_ERROR;
67 }
68 char *name = mutt_str_dup(buf->data);
69
70 /* address list */
72 mutt_debug(LL_DEBUG5, "Second token is '%s'\n", buf->data);
73 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
74 int parsed = mutt_addrlist_parse2(&al, buf->data);
75 if (parsed == 0)
76 {
77 mutt_buffer_printf(err, _("Warning: Bad address '%s' in alias '%s'"), buf->data, name);
78 FREE(&name);
79 goto bail;
80 }
81
82 /* IDN */
83 char *estr = NULL;
84 if (mutt_addrlist_to_intl(&al, &estr))
85 {
86 mutt_buffer_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, name);
87 FREE(&name);
88 FREE(&estr);
89 goto bail;
90 }
91
92 /* check to see if an alias with this name already exists */
93 TAILQ_FOREACH(tmp, &Aliases, entries)
94 {
95 if (mutt_istr_equal(tmp->name, name))
96 break;
97 }
98
99 if (tmp)
100 {
101 FREE(&name);
103 /* override the previous value */
105 FREE(&tmp->comment);
106 event = NT_ALIAS_CHANGE;
107 }
108 else
109 {
110 /* create a new alias */
111 tmp = alias_new();
112 tmp->name = name;
113 TAILQ_INSERT_TAIL(&Aliases, tmp, entries);
114 event = NT_ALIAS_ADD;
115 }
116 tmp->addr = al;
117
119
120 const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
121 if (c_debug_level > LL_DEBUG4)
122 {
123 /* A group is terminated with an empty address, so check a->mailbox */
124 struct Address *a = NULL;
125 TAILQ_FOREACH(a, &tmp->addr, entries)
126 {
127 if (!a->mailbox)
128 break;
129
130 if (a->group)
131 mutt_debug(LL_DEBUG5, " Group %s\n", a->mailbox);
132 else
133 mutt_debug(LL_DEBUG5, " %s\n", a->mailbox);
134 }
135 }
137 if (!MoreArgs(s) && (s->dptr[0] == '#'))
138 {
139 char *comment = s->dptr + 1;
140 SKIPWS(comment);
141 tmp->comment = mutt_str_dup(comment);
142 }
143
145
146 mutt_debug(LL_NOTIFY, "%s: %s\n",
147 (event == NT_ALIAS_ADD) ? "NT_ALIAS_ADD" : "NT_ALIAS_CHANGE", tmp->name);
148 struct EventAlias ev_a = { tmp };
149 notify_send(NeoMutt->notify, NT_ALIAS, event, &ev_a);
150
151 return MUTT_CMD_SUCCESS;
152
153bail:
155 return MUTT_CMD_ERROR;
156}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:616
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1305
struct AliasList Aliases
List of all the user's email aliases.
Definition: alias.c:58
struct Alias * alias_new(void)
Create a new Alias.
Definition: alias.c:630
NotifyAlias
Alias notification types.
Definition: alias.h:53
@ NT_ALIAS_ADD
Alias has been added.
Definition: alias.h:54
@ NT_ALIAS_CHANGE
Alias has been changed.
Definition: alias.h:57
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:168
#define MoreArgs(buf)
Definition: buffer.h:40
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:37
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:35
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:36
int parse_grouplist(struct GroupList *gl, struct Buffer *buf, struct Buffer *s, struct Buffer *err)
Parse a group context.
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
void mutt_grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition: group.c:201
void mutt_grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition: group.c:270
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:273
@ LL_DEBUG4
Log at debug level 4.
Definition: logging.h:43
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
@ LL_NOTIFY
Log of notifications.
Definition: logging.h:45
#define FREE(x)
Definition: memory.h:43
#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:171
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:819
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
#define MUTT_TOKEN_QUOTE
Don't interpret quotes.
Definition: mutt.h:71
#define MUTT_TOKEN_SPACE
Don't treat whitespace as a term.
Definition: mutt.h:70
#define MUTT_TOKEN_SEMICOLON
Don't treat ; as special.
Definition: mutt.h:74
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:67
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition: notify_type.h:37
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:809
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
void alias_reverse_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition: reverse.c:61
void alias_reverse_delete(struct Alias *alias)
Remove an email address lookup for an Alias.
Definition: reverse.c:83
#define SKIPWS(ch)
Definition: string2.h:46
An email address.
Definition: address.h:36
bool group
Group mailbox?
Definition: address.h:39
char * mailbox
Mailbox and host address.
Definition: address.h:38
A shortcut for an email address or addresses.
Definition: alias.h:34
char * comment
Free-form comment string.
Definition: alias.h:37
char * name
Short name.
Definition: alias.h:35
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
An alias-change event.
Definition: alias.h:64
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:

◆ parse_unalias()

enum CommandResult parse_unalias ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unalias' command - Implements Command::parse() -.

Definition at line 161 of file commands.c.

163{
164 do
165 {
167
168 struct Alias *np = NULL;
169 if (mutt_str_equal("*", buf->data))
170 {
171 TAILQ_FOREACH(np, &Aliases, entries)
172 {
174 }
175
177 return MUTT_CMD_SUCCESS;
178 }
179
180 TAILQ_FOREACH(np, &Aliases, entries)
181 {
182 if (!mutt_istr_equal(buf->data, np->name))
183 continue;
184
185 TAILQ_REMOVE(&Aliases, np, entries);
187 alias_free(&np);
188 break;
189 }
190 } while (MoreArgs(s));
191 return MUTT_CMD_SUCCESS;
192}
void alias_free(struct Alias **ptr)
Free an Alias.
Definition: alias.c:641
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:662
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:807
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841
+ Here is the call graph for this function:

◆ parse_alternates()

enum CommandResult parse_alternates ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'alternates' command - Implements Command::parse() -.

Definition at line 89 of file alternates.c.

91{
92 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
93
94 do
95 {
97
98 if (parse_grouplist(&gl, buf, s, err) == -1)
99 goto bail;
100
102
103 if (mutt_regexlist_add(&Alternates, buf->data, REG_ICASE, err) != 0)
104 goto bail;
105
106 if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
107 goto bail;
108 } while (MoreArgs(s));
109
111
112 mutt_debug(LL_NOTIFY, "NT_ALTERN_ADD: %s\n", buf->data);
114
115 return MUTT_CMD_SUCCESS;
116
117bail:
119 return MUTT_CMD_ERROR;
120}
struct RegexList Alternates
List of regexes to match the user's alternate email addresses.
Definition: alternates.c:42
static struct Notify * AlternatesNotify
Definition: alternates.c:44
struct RegexList UnAlternates
List of regexes to blacklist false matches in Alternates.
Definition: alternates.c:43
@ NT_ALTERN_ADD
Alternate address has been added.
Definition: alternates.h:41
int mutt_grouplist_add_regex(struct GroupList *gl, const char *s, uint16_t flags, struct Buffer *err)
Add matching Addresses to a GroupList.
Definition: group.c:320
int mutt_regexlist_add(struct RegexList *rl, const char *str, uint16_t flags, struct Buffer *err)
Compile a regex string and add it to a list.
Definition: regex.c:135
int mutt_regexlist_remove(struct RegexList *rl, const char *str)
Remove a Regex from a list.
Definition: regex.c:230
@ NT_ALTERN
Alternates command changed, NotifyAlternates.
Definition: notify_type.h:38
+ Here is the call graph for this function:

◆ parse_unalternates()

enum CommandResult parse_unalternates ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unalternates' command - Implements Command::parse() -.

Definition at line 125 of file alternates.c.

127{
128 do
129 {
132
133 if (!mutt_str_equal(buf->data, "*") &&
134 (mutt_regexlist_add(&UnAlternates, buf->data, REG_ICASE, err) != 0))
135 {
136 return MUTT_CMD_ERROR;
137 }
138
139 } while (MoreArgs(s));
140
141 mutt_debug(LL_NOTIFY, "NT_ALTERN_DELETE: %s\n", buf->data);
143
144 return MUTT_CMD_SUCCESS;
145}
@ NT_ALTERN_DELETE
Alternate address has been deleted.
Definition: alternates.h:42
+ Here is the call graph for this function:

◆ parse_attachments()

enum CommandResult parse_attachments ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'attachments' command - Implements Command::parse() -.

Definition at line 470 of file attachments.c.

472{
474 if (!buf->data || (*buf->data == '\0'))
475 {
476 mutt_buffer_strcpy(err, _("attachments: no disposition"));
477 return MUTT_CMD_WARNING;
478 }
479
480 char *category = buf->data;
481 char op = *category++;
482
483 if (op == '?')
484 {
485 mutt_endwin();
486 fflush(stdout);
487 printf("\n%s\n\n", _("Current attachments settings:"));
488 print_attach_list(&AttachAllow, '+', "A");
490 print_attach_list(&InlineAllow, '+', "I");
493 return MUTT_CMD_SUCCESS;
494 }
495
496 if ((op != '+') && (op != '-'))
497 {
498 op = '+';
499 category--;
500 }
501
502 struct ListHead *head = NULL;
503 if (mutt_istr_startswith("attachment", category))
504 {
505 if (op == '+')
506 head = &AttachAllow;
507 else
508 head = &AttachExclude;
509 }
510 else if (mutt_istr_startswith("inline", category))
511 {
512 if (op == '+')
513 head = &InlineAllow;
514 else
515 head = &InlineExclude;
516 }
517 else
518 {
519 mutt_buffer_strcpy(err, _("attachments: invalid disposition"));
520 return MUTT_CMD_ERROR;
521 }
522
523 return parse_attach_list(buf, s, head, err);
524}
struct ListHead AttachAllow
List of attachment types to be counted.
Definition: attachments.c:55
static int print_attach_list(struct ListHead *h, const char op, const char *name)
Print a list of attachments.
Definition: attachments.c:454
struct ListHead InlineExclude
List of inline types to ignore.
Definition: attachments.c:58
struct ListHead AttachExclude
List of attachment types to be ignored.
Definition: attachments.c:56
static enum CommandResult parse_attach_list(struct Buffer *buf, struct Buffer *s, struct ListHead *head, struct Buffer *err)
Parse the "attachments" command.
Definition: attachments.c:308
struct ListHead InlineAllow
List of inline types to counted.
Definition: attachments.c:57
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:387
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:354
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:239
+ Here is the call graph for this function:

◆ parse_unattachments()

enum CommandResult parse_unattachments ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unattachments' command - Implements Command::parse() -.

Definition at line 529 of file attachments.c.

531{
532 char op;
533 char *p = NULL;
534 struct ListHead *head = NULL;
535
537 if (!buf->data || (*buf->data == '\0'))
538 {
539 mutt_buffer_strcpy(err, _("unattachments: no disposition"));
540 return MUTT_CMD_WARNING;
541 }
542
543 p = buf->data;
544 op = *p++;
545
546 if (op == '*')
547 {
552
553 mutt_debug(LL_NOTIFY, "NT_ATTACH_DELETE_ALL\n");
555 return 0;
556 }
557
558 if ((op != '+') && (op != '-'))
559 {
560 op = '+';
561 p--;
562 }
563 if (mutt_istr_startswith("attachment", p))
564 {
565 if (op == '+')
566 head = &AttachAllow;
567 else
568 head = &AttachExclude;
569 }
570 else if (mutt_istr_startswith("inline", p))
571 {
572 if (op == '+')
573 head = &InlineAllow;
574 else
575 head = &InlineExclude;
576 }
577 else
578 {
579 mutt_buffer_strcpy(err, _("unattachments: invalid disposition"));
580 return MUTT_CMD_ERROR;
581 }
582
583 return parse_unattach_list(buf, s, head, err);
584}
static struct Notify * AttachmentsNotify
Definition: attachments.c:59
static enum CommandResult parse_unattach_list(struct Buffer *buf, struct Buffer *s, struct ListHead *head, struct Buffer *err)
Parse the "unattachments" command.
Definition: attachments.c:388
@ NT_ATTACH_DELETE_ALL
All Attachment regexes have been deleted.
Definition: attachments.h:42
static void attachmatch_free(struct AttachMatch **ptr)
Free an AttachMatch - Implements list_free_t -.
Definition: attachments.c:68
void mutt_list_free_type(struct ListHead *h, list_free_t fn)
Free a List of type.
Definition: list.c:144
void(* list_free_t)(void **ptr)
Definition: list.h:48
@ NT_ATTACH
Attachment command changed, NotifyAttach.
Definition: notify_type.h:39
+ Here is the call graph for this function:

◆ mutt_parse_uncolor()

enum CommandResult mutt_parse_uncolor ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'uncolor' command - Implements Command::parse() -.

Definition at line 666 of file command.c.

668{
669 if (OptNoCurses)
670 {
671 *s->dptr = '\0'; /* fake that we're done parsing */
672 return MUTT_CMD_SUCCESS;
673 }
674 color_debug(LL_DEBUG5, "parse: %s\n", mutt_buffer_string(buf));
675 enum CommandResult rc = parse_uncolor(buf, s, err, true);
676 // simple_colors_dump(false);
678 return rc;
679}
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
static enum CommandResult parse_uncolor(struct Buffer *buf, struct Buffer *s, struct Buffer *err, bool uncolor)
Parse an 'uncolor' command.
Definition: command.c:431
CommandResult
Error codes for command_t parse functions.
Definition: command.h:34
int color_debug(enum LogLevel level, const char *format,...)
Write to the log file.
Definition: debug.c:44
void curses_colors_dump(void)
Log all the Curses colours.
Definition: debug.c:267
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:53
+ Here is the call graph for this function:

◆ mutt_parse_unmono()

enum CommandResult mutt_parse_unmono ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unmono' command - Implements Command::parse() -.

Definition at line 684 of file command.c.

686{
687 *s->dptr = '\0'; /* fake that we're done parsing */
688 return MUTT_CMD_SUCCESS;
689}

◆ mutt_parse_color()

enum CommandResult mutt_parse_color ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'color' command - Implements Command::parse() -.

Definition at line 694 of file command.c.

696{
697 bool dry_run = OptNoCurses;
698
699 color_debug(LL_DEBUG5, "parse: %s\n", mutt_buffer_string(buf));
700 enum CommandResult rc = parse_color(buf, s, err, parse_color_pair, dry_run, true);
701 // simple_colors_dump(false);
703 return rc;
704}
static enum CommandResult parse_color(struct Buffer *buf, struct Buffer *s, struct Buffer *err, parser_callback_t callback, bool dry_run, bool color)
Parse a 'color' command.
Definition: command.c:532
static enum CommandResult parse_color_pair(struct Buffer *buf, struct Buffer *s, uint32_t *fg, uint32_t *bg, int *attrs, struct Buffer *err)
Parse a pair of colours - Implements parser_callback_t -.
Definition: command.c:255
+ Here is the call graph for this function:

◆ mutt_parse_mono()

enum CommandResult mutt_parse_mono ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'mono' command - Implements Command::parse() -.

Definition at line 709 of file command.c.

711{
712 return parse_color(buf, s, err, parse_attr_spec, true, false);
713}
static enum CommandResult parse_attr_spec(struct Buffer *buf, struct Buffer *s, uint32_t *fg, uint32_t *bg, int *attrs, struct Buffer *err)
Parse an attribute description - Implements parser_callback_t -.
Definition: command.c:210
+ Here is the call graph for this function:

◆ parse_cd()

enum CommandResult parse_cd ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'cd' command - Implements Command::parse() -.

Definition at line 335 of file command_parse.c.

337{
340 if (mutt_buffer_len(buf) == 0)
341 {
342 if (HomeDir)
344 else
345 {
346 mutt_buffer_printf(err, _("%s: too few arguments"), "cd");
347 return MUTT_CMD_ERROR;
348 }
349 }
350
351 if (chdir(mutt_buffer_string(buf)) != 0)
352 {
353 mutt_buffer_printf(err, "cd: %s", strerror(errno));
354 return MUTT_CMD_ERROR;
355 }
356
357 return MUTT_CMD_SUCCESS;
358}
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:371
char * HomeDir
User's home directory.
Definition: mutt_globals.h:49
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
+ Here is the call graph for this function:

◆ parse_echo()

enum CommandResult parse_echo ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'echo' command - Implements Command::parse() -.

Definition at line 363 of file command_parse.c.

365{
366 if (!MoreArgs(s))
367 {
368 mutt_buffer_printf(err, _("%s: too few arguments"), "echo");
369 return MUTT_CMD_WARNING;
370 }
372 OptForceRefresh = true;
373 mutt_message("%s", buf->data);
374 OptForceRefresh = false;
375 mutt_sleep(0);
376
377 return MUTT_CMD_SUCCESS;
378}
#define mutt_message(...)
Definition: logging.h:86
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1455
bool OptForceRefresh
(pseudo) refresh even during macros
Definition: options.h:42
+ Here is the call graph for this function:

◆ parse_finish()

enum CommandResult parse_finish ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'finish' command - Implements Command::parse() -.

Return values
MUTT_CMD_FINISHStop processing the current file
MUTT_CMD_WARNINGFailed

If the 'finish' command is found, we should stop reading the current file.

Definition at line 387 of file command_parse.c.

389{
390 if (MoreArgs(s))
391 {
392 mutt_buffer_printf(err, _("%s: too many arguments"), "finish");
393 return MUTT_CMD_WARNING;
394 }
395
396 return MUTT_CMD_FINISH;
397}
@ MUTT_CMD_FINISH
Finish: Stop processing this file.
Definition: command.h:38
+ Here is the call graph for this function:

◆ parse_group()

enum CommandResult parse_group ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'group' and 'ungroup' commands - Implements Command::parse() -.

Definition at line 402 of file command_parse.c.

404{
405 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
406 enum GroupState state = GS_NONE;
407
408 do
409 {
411 if (parse_grouplist(&gl, buf, s, err) == -1)
412 goto bail;
413
414 if ((data == MUTT_UNGROUP) && mutt_istr_equal(buf->data, "*"))
415 {
417 goto out;
418 }
419
420 if (mutt_istr_equal(buf->data, "-rx"))
421 state = GS_RX;
422 else if (mutt_istr_equal(buf->data, "-addr"))
423 state = GS_ADDR;
424 else
425 {
426 switch (state)
427 {
428 case GS_NONE:
429 mutt_buffer_printf(err, _("%sgroup: missing -rx or -addr"),
430 (data == MUTT_UNGROUP) ? "un" : "");
431 goto warn;
432
433 case GS_RX:
434 if ((data == MUTT_GROUP) &&
435 (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0))
436 {
437 goto bail;
438 }
439 else if ((data == MUTT_UNGROUP) &&
440 (mutt_grouplist_remove_regex(&gl, buf->data) < 0))
441 {
442 goto bail;
443 }
444 break;
445
446 case GS_ADDR:
447 {
448 char *estr = NULL;
449 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
450 mutt_addrlist_parse2(&al, buf->data);
451 if (TAILQ_EMPTY(&al))
452 goto bail;
453 if (mutt_addrlist_to_intl(&al, &estr))
454 {
455 mutt_buffer_printf(err, _("%sgroup: warning: bad IDN '%s'"),
456 (data == 1) ? "un" : "", estr);
458 FREE(&estr);
459 goto bail;
460 }
461 if (data == MUTT_GROUP)
463 else if (data == MUTT_UNGROUP)
466 break;
467 }
468 }
469 }
470 } while (MoreArgs(s));
471
472out:
474 return MUTT_CMD_SUCCESS;
475
476bail:
478 return MUTT_CMD_ERROR;
479
480warn:
482 return MUTT_CMD_WARNING;
483}
GroupState
Type of email address group.
Definition: command_parse.c:75
@ GS_RX
Entry is a regular expression.
Definition: command_parse.c:77
@ GS_NONE
Group is missing an argument.
Definition: command_parse.c:76
@ GS_ADDR
Entry is an address.
Definition: command_parse.c:78
int mutt_grouplist_remove_addrlist(struct GroupList *gl, struct AddressList *al)
Remove an AddressList from a GroupList.
Definition: group.c:289
int mutt_grouplist_remove_regex(struct GroupList *gl, const char *s)
Remove matching addresses from a GroupList.
Definition: group.c:345
void mutt_grouplist_clear(struct GroupList *gl)
Clear a GroupList.
Definition: group.c:147
#define MUTT_GROUP
'group' config command
Definition: group.h:33
#define MUTT_UNGROUP
'ungroup' config command
Definition: group.h:34
#define TAILQ_EMPTY(head)
Definition: queue.h:721
+ Here is the call graph for this function:

◆ parse_ifdef()

enum CommandResult parse_ifdef ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'ifdef' and 'ifndef' commands - Implements Command::parse() -.

The 'ifdef' command allows conditional elements in the config file. If a given variable, function, command or compile-time symbol exists, then read the rest of the line of config commands. e.g. ifdef sidebar source ~/.neomutt/sidebar.rc

If (data == 1) then it means use the 'ifndef' (if-not-defined) command. e.g. ifndef imap finish

Definition at line 498 of file command_parse.c.

500{
502
503 // is the item defined as:
504 bool res = cs_subset_lookup(NeoMutt->sub, buf->data) // a variable?
505 || feature_enabled(buf->data) // a compiled-in feature?
506 || is_function(buf->data) // a function?
507 || mutt_command_get(buf->data) // a command?
508 || myvar_get(buf->data) // a my_ variable?
509 || mutt_str_getenv(buf->data); // an environment variable?
510
511 if (!MoreArgs(s))
512 {
513 mutt_buffer_printf(err, _("%s: too few arguments"), (data ? "ifndef" : "ifdef"));
514 return MUTT_CMD_WARNING;
515 }
517
518 /* ifdef KNOWN_SYMBOL or ifndef UNKNOWN_SYMBOL */
519 if ((res && (data == 0)) || (!res && (data == 1)))
520 {
521 enum CommandResult rc = mutt_parse_rc_line(buf->data, err);
522 if (rc == MUTT_CMD_ERROR)
523 {
524 mutt_error(_("Error: %s"), err->data);
525 return MUTT_CMD_ERROR;
526 }
527 return rc;
528 }
529 return MUTT_CMD_SUCCESS;
530}
static bool is_function(const char *name)
Is the argument a neomutt function?
Definition: command_parse.c:87
#define mutt_error(...)
Definition: logging.h:87
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:894
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:927
struct Command * mutt_command_get(const char *s)
Get a Command by its name.
const char * myvar_get(const char *var)
Get the value of a "my_" variable.
Definition: myvar.c:92
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:179
bool feature_enabled(const char *name)
Test if a compile-time feature is enabled.
Definition: version.c:563
+ Here is the call graph for this function:

◆ parse_ignore()

enum CommandResult parse_ignore ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'ignore' command - Implements Command::parse() -.

Definition at line 535 of file command_parse.c.

537{
538 do
539 {
542 add_to_stailq(&Ignore, buf->data);
543 } while (MoreArgs(s));
544
545 return MUTT_CMD_SUCCESS;
546}
struct ListHead Ignore
List of header patterns to ignore.
Definition: globals.c:35
struct ListHead UnIgnore
List of header patterns to unignore (see)
Definition: globals.c:36
void remove_from_stailq(struct ListHead *head, const char *str)
Remove an item, matching a string, from a List.
Definition: muttlib.c:1744
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1719
+ Here is the call graph for this function:

◆ parse_lists()

enum CommandResult parse_lists ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'lists' command - Implements Command::parse() -.

Definition at line 551 of file command_parse.c.

553{
554 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
555
556 do
557 {
559
560 if (parse_grouplist(&gl, buf, s, err) == -1)
561 goto bail;
562
564
565 if (mutt_regexlist_add(&MailLists, buf->data, REG_ICASE, err) != 0)
566 goto bail;
567
568 if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
569 goto bail;
570 } while (MoreArgs(s));
571
573 return MUTT_CMD_SUCCESS;
574
575bail:
577 return MUTT_CMD_ERROR;
578}
struct RegexList UnMailLists
List of regexes to blacklist false matches in MailLists.
Definition: globals.c:42
struct RegexList MailLists
List of regexes to match mailing lists.
Definition: globals.c:41
+ Here is the call graph for this function:

◆ parse_mailboxes()

enum CommandResult parse_mailboxes ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'mailboxes' command - Implements Command::parse() -.

This is also used by 'virtual-mailboxes'.

Definition at line 585 of file command_parse.c.

587{
588 while (MoreArgs(s))
589 {
590 struct Mailbox *m = mailbox_new();
591
592 if (data & MUTT_NAMED)
593 {
594 // This may be empty, e.g. `named-mailboxes "" +inbox`
596 m->name = mutt_buffer_strdup(buf);
597 }
598
600 if (mutt_buffer_is_empty(buf))
601 {
602 /* Skip empty tokens. */
603 mailbox_free(&m);
604 continue;
605 }
606
608 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
609 /* int rc = */ mx_path_canon2(m, c_folder);
610
611 if (m->type <= MUTT_UNKNOWN)
612 {
613 mutt_error("Unknown Mailbox: %s", m->realpath);
614 mailbox_free(&m);
615 return MUTT_CMD_ERROR;
616 }
617
618 bool new_account = false;
619 struct Account *a = mx_ac_find(m);
620 if (!a)
621 {
622 a = account_new(NULL, NeoMutt->sub);
623 a->type = m->type;
624 new_account = true;
625 }
626
627 if (!new_account)
628 {
629 struct Mailbox *m_old = mx_mbox_find(a, m->realpath);
630 if (m_old)
631 {
632 if (!m_old->visible)
633 {
634 m_old->visible = true;
635 m_old->gen = mailbox_gen();
636 }
637
638 const bool rename = (data & MUTT_NAMED) && !mutt_str_equal(m_old->name, m->name);
639 if (rename)
640 {
641 mutt_str_replace(&m_old->name, m->name);
642 }
643
644 mailbox_free(&m);
645 continue;
646 }
647 }
648
649 if (!mx_ac_add(a, m))
650 {
651 mailbox_free(&m);
652 if (new_account)
653 {
654 cs_subset_free(&a->sub);
655 FREE(&a->name);
656 notify_free(&a->notify);
657 FREE(&a);
658 }
659 continue;
660 }
661 if (new_account)
662 {
664 }
665
666 // this is finally a visible mailbox in the sidebar and mailboxes list
667 m->visible = true;
668
669#ifdef USE_INOTIFY
671#endif
672 }
673 return MUTT_CMD_SUCCESS;
674}
struct Account * account_new(const char *name, struct ConfigSubset *sub)
Create a new Account.
Definition: account.c:43
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:260
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:447
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
int mailbox_gen(void)
Get the next generation number.
Definition: mailbox.c:58
struct Mailbox * mailbox_new(void)
Create a new Mailbox.
Definition: mailbox.c:68
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:44
int mutt_monitor_add(struct Mailbox *m)
Add a watch for a mailbox.
Definition: monitor.c:481
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:73
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:326
#define MUTT_NAMED
Definition: mutt_commands.h:44
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1587
bool mx_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Wrapper for MxOps::ac_add()
Definition: mx.c:1764
struct Account * mx_ac_find(struct Mailbox *m)
Find the Account owning a Mailbox.
Definition: mx.c:1563
int mx_path_canon2(struct Mailbox *m, const char *folder)
Canonicalise the path to realpath.
Definition: mx.c:1477
bool neomutt_account_add(struct NeoMutt *n, struct Account *a)
Add an Account to the global list.
Definition: neomutt.c:84
A group of associated Mailboxes.
Definition: account.h:37
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
char * name
Name of Account.
Definition: account.h:39
struct Notify * notify
Notifications: NotifyAccount, EventAccount.
Definition: account.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: account.h:40
A mailbox.
Definition: mailbox.h:79
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
char * name
A short name for the Mailbox.
Definition: mailbox.h:82
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:80
bool visible
True if a result of "mailboxes".
Definition: mailbox.h:130
int gen
Generation number, for sorting.
Definition: mailbox.h:146
void cs_subset_free(struct ConfigSubset **ptr)
Free a Config Subset.
Definition: subset.c:104
+ Here is the call graph for this function:

◆ parse_my_hdr()

enum CommandResult parse_my_hdr ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'my_hdr' command - Implements Command::parse() -.

Definition at line 679 of file command_parse.c.

681{
683 char *p = strpbrk(buf->data, ": \t");
684 if (!p || (*p != ':'))
685 {
686 mutt_buffer_strcpy(err, _("invalid header field"));
687 return MUTT_CMD_WARNING;
688 }
689
690 struct EventHeader ev_h = { buf->data };
691 struct ListNode *n = header_find(&UserHeader, buf->data);
692
693 if (n)
694 {
695 header_update(n, buf->data);
696 mutt_debug(LL_NOTIFY, "NT_HEADER_CHANGE: %s\n", buf->data);
698 }
699 else
700 {
701 header_add(&UserHeader, buf->data);
702 mutt_debug(LL_NOTIFY, "NT_HEADER_ADD: %s\n", buf->data);
704 }
705
706 return MUTT_CMD_SUCCESS;
707}
struct ListNode * header_add(struct ListHead *hdrlist, const char *header)
Add a header to a list.
Definition: email.c:203
struct ListNode * header_update(struct ListNode *hdr, const char *header)
Update an existing header.
Definition: email.c:217
struct ListNode * header_find(const struct ListHead *hdrlist, const char *header)
Find a header, matching on its field, in a list of headers.
Definition: email.c:180
@ NT_HEADER_CHANGE
An existing header has been changed.
Definition: email.h:174
@ NT_HEADER_ADD
Header has been added.
Definition: email.h:172
struct ListHead UserHeader
List of custom headers to add to outgoing emails.
Definition: mutt_globals.h:66
@ NT_HEADER
A header has changed, NotifyHeader EventHeader.
Definition: notify_type.h:47
An event that happened to a header.
Definition: email.h:181
A List node for strings.
Definition: list.h:35
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_set()

enum CommandResult parse_set ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'set' family of commands - Implements Command::parse() -.

This is used by 'reset', 'set', 'toggle' and 'unset'.

Definition at line 714 of file command_parse.c.

716{
717 /* The order must match `enum MuttSetCommand` */
718 static const char *set_commands[] = { "set", "toggle", "unset", "reset" };
719
720 int rc = 0;
721
722 while (MoreArgs(s))
723 {
724 bool prefix = false;
725 bool query = false;
726 bool inv = (data == MUTT_SET_INV);
727 bool reset = (data == MUTT_SET_RESET);
728 bool unset = (data == MUTT_SET_UNSET);
729
730 if (*s->dptr == '?')
731 {
732 prefix = true;
733 query = true;
734 s->dptr++;
735 }
736 else if (mutt_str_startswith(s->dptr, "no"))
737 {
738 prefix = true;
739 unset = !unset;
740 s->dptr += 2;
741 }
742 else if (mutt_str_startswith(s->dptr, "inv"))
743 {
744 prefix = true;
745 inv = !inv;
746 s->dptr += 3;
747 }
748 else if (*s->dptr == '&')
749 {
750 prefix = true;
751 reset = true;
752 s->dptr++;
753 }
754
755 if (prefix && (data != MUTT_SET_SET))
756 {
757 mutt_buffer_printf(err, _("Can't use 'inv', 'no', '&' or '?' with the '%s' command"),
758 set_commands[data]);
759 return MUTT_CMD_WARNING;
760 }
761
762 /* get the variable name */
764
765 bool bq = false;
766 bool equals = false;
767 bool increment = false;
768 bool decrement = false;
769
770 struct HashElem *he = NULL;
771 bool my = mutt_str_startswith(buf->data, "my_");
772 if (!my)
773 {
774 he = cs_subset_lookup(NeoMutt->sub, buf->data);
775 if (!he)
776 {
777 if (reset && mutt_str_equal(buf->data, "all"))
778 {
779 struct HashElem **list = get_elem_list(NeoMutt->sub->cs);
780 if (!list)
781 return MUTT_CMD_ERROR;
782
783 for (size_t i = 0; list[i]; i++)
784 cs_subset_he_reset(NeoMutt->sub, list[i], NULL);
785
786 FREE(&list);
787 break;
788 }
789 else
790 {
791 mutt_buffer_printf(err, _("%s: unknown variable"), buf->data);
792 return MUTT_CMD_ERROR;
793 }
794 }
795
796 // Use the correct name if a synonym is used
797 mutt_buffer_strcpy(buf, he->key.strkey);
798
799 bq = ((DTYPE(he->type) == DT_BOOL) || (DTYPE(he->type) == DT_QUAD));
800 }
801
802 if (*s->dptr == '?')
803 {
804 if (prefix)
805 {
806 mutt_buffer_printf(err, _("Can't use a prefix when querying a variable"));
807 return MUTT_CMD_WARNING;
808 }
809
810 if (reset || unset || inv)
811 {
812 mutt_buffer_printf(err, _("Can't query a variable with the '%s' command"),
813 set_commands[data]);
814 return MUTT_CMD_WARNING;
815 }
816
817 query = true;
818 s->dptr++;
819 }
820 else if (*s->dptr == '+' || *s->dptr == '-')
821 {
822 if (prefix)
823 {
824 mutt_buffer_printf(err, _("Can't use prefix when incrementing or decrementing a variable"));
825 return MUTT_CMD_WARNING;
826 }
827
828 if (reset || unset || inv)
829 {
830 mutt_buffer_printf(err, _("Can't set a variable with the '%s' command"),
831 set_commands[data]);
832 return MUTT_CMD_WARNING;
833 }
834 if (*s->dptr == '+')
835 increment = true;
836 else
837 decrement = true;
838
839 if (my && decrement)
840 {
841 mutt_buffer_printf(err, _("Can't decrement a my_ variable"), set_commands[data]);
842 return MUTT_CMD_WARNING;
843 }
844 s->dptr++;
845 if (*s->dptr == '=')
846 {
847 equals = true;
848 s->dptr++;
849 }
850 }
851 else if (*s->dptr == '=')
852 {
853 if (prefix)
854 {
855 mutt_buffer_printf(err, _("Can't use prefix when setting a variable"));
856 return MUTT_CMD_WARNING;
857 }
858
859 if (reset || unset || inv)
860 {
861 mutt_buffer_printf(err, _("Can't set a variable with the '%s' command"),
862 set_commands[data]);
863 return MUTT_CMD_WARNING;
864 }
865
866 equals = true;
867 s->dptr++;
868 }
869
870 if (!bq && (inv || (unset && prefix)))
871 {
872 if (data == MUTT_SET_SET)
873 {
874 mutt_buffer_printf(err, _("Prefixes 'no' and 'inv' may only be used with bool/quad variables"));
875 }
876 else
877 {
878 mutt_buffer_printf(err, _("Command '%s' can only be used with bool/quad variables"),
879 set_commands[data]);
880 }
881 return MUTT_CMD_WARNING;
882 }
883
884 if (reset)
885 {
886 // mutt_buffer_printf(err, "ACT24 reset variable %s", buf->data);
887 if (he)
888 {
889 rc = cs_subset_he_reset(NeoMutt->sub, he, err);
890 if (CSR_RESULT(rc) != CSR_SUCCESS)
891 return MUTT_CMD_ERROR;
892 }
893 else
894 {
895 myvar_del(buf->data);
896 }
897 continue;
898 }
899
900 if ((data == MUTT_SET_SET) && !inv && !unset)
901 {
902 if (query)
903 {
904 // mutt_buffer_printf(err, "ACT08 query variable %s", buf->data);
905 if (he)
906 {
907 mutt_buffer_addstr(err, buf->data);
908 mutt_buffer_addch(err, '=');
910 rc = cs_subset_he_string_get(NeoMutt->sub, he, buf);
911 if (CSR_RESULT(rc) != CSR_SUCCESS)
912 {
913 mutt_buffer_addstr(err, buf->data);
914 return MUTT_CMD_ERROR;
915 }
916 if (DTYPE(he->type) == DT_PATH)
917 mutt_pretty_mailbox(buf->data, buf->dsize);
918 pretty_var(buf->data, err);
919 }
920 else
921 {
922 const char *val = myvar_get(buf->data);
923 if (val)
924 {
925 mutt_buffer_addstr(err, buf->data);
926 mutt_buffer_addch(err, '=');
927 pretty_var(val, err);
928 }
929 else
930 {
931 mutt_buffer_printf(err, _("%s: unknown variable"), buf->data);
932 return MUTT_CMD_ERROR;
933 }
934 }
935 break;
936 }
937 else if (equals)
938 {
939 // mutt_buffer_printf(err, "ACT11 set variable %s to ", buf->data);
940 const char *name = NULL;
941 if (my)
942 {
943 name = mutt_str_dup(buf->data);
944 }
946 if (my)
947 {
948 assert(!decrement);
949 if (increment)
950 {
951 myvar_append(name, buf->data);
952 }
953 else
954 {
955 myvar_set(name, buf->data);
956 }
957 FREE(&name);
958 }
959 else
960 {
961 if (DTYPE(he->type) == DT_PATH)
962 {
963 if (he->type & (DT_PATH_DIR | DT_PATH_FILE))
965 else
966 mutt_path_tilde(buf->data, buf->dsize, HomeDir);
967 }
968 else if (IS_MAILBOX(he))
969 {
971 }
972 else if (IS_COMMAND(he))
973 {
974 struct Buffer scratch = mutt_buffer_make(1024);
975 mutt_buffer_copy(&scratch, buf);
976
977 if (!mutt_str_equal(buf->data, "builtin"))
978 {
979 mutt_buffer_expand_path(&scratch);
980 }
983 mutt_buffer_dealloc(&scratch);
984 }
985 if (increment)
986 {
987 rc = cs_subset_he_string_plus_equals(NeoMutt->sub, he, buf->data, err);
988 }
989 else if (decrement)
990 {
991 rc = cs_subset_he_string_minus_equals(NeoMutt->sub, he, buf->data, err);
992 }
993 else
994 {
995 rc = cs_subset_he_string_set(NeoMutt->sub, he, buf->data, err);
996 }
997 if (CSR_RESULT(rc) != CSR_SUCCESS)
998 return MUTT_CMD_ERROR;
999 }
1000 continue;
1001 }
1002 else
1003 {
1004 if (bq)
1005 {
1006 // mutt_buffer_printf(err, "ACT23 set variable %s to 'yes'", buf->data);
1007 rc = cs_subset_he_native_set(NeoMutt->sub, he, true, err);
1008 if (CSR_RESULT(rc) != CSR_SUCCESS)
1009 return MUTT_CMD_ERROR;
1010 continue;
1011 }
1012 else
1013 {
1014 // mutt_buffer_printf(err, "ACT10 query variable %s", buf->data);
1015 if (he)
1016 {
1017 mutt_buffer_addstr(err, buf->data);
1018 mutt_buffer_addch(err, '=');
1019 mutt_buffer_reset(buf);
1020 rc = cs_subset_he_string_get(NeoMutt->sub, he, buf);
1021 if (CSR_RESULT(rc) != CSR_SUCCESS)
1022 {
1023 mutt_buffer_addstr(err, buf->data);
1024 return MUTT_CMD_ERROR;
1025 }
1026 if (DTYPE(he->type) == DT_PATH)
1027 mutt_pretty_mailbox(buf->data, buf->dsize);
1028 pretty_var(buf->data, err);
1029 }
1030 else
1031 {
1032 const char *val = myvar_get(buf->data);
1033 if (val)
1034 {
1035 mutt_buffer_addstr(err, buf->data);
1036 mutt_buffer_addch(err, '=');
1037 pretty_var(val, err);
1038 }
1039 else
1040 {
1041 mutt_buffer_printf(err, _("%s: unknown variable"), buf->data);
1042 return MUTT_CMD_ERROR;
1043 }
1044 }
1045 break;
1046 }
1047 }
1048 }
1049
1050 if (my)
1051 {
1052 myvar_del(buf->data);
1053 }
1054 else if (bq)
1055 {
1056 if (inv)
1057 {
1058 // mutt_buffer_printf(err, "ACT25 TOGGLE bool/quad variable %s", buf->data);
1059 if (DTYPE(he->type) == DT_BOOL)
1060 bool_he_toggle(NeoMutt->sub, he, err);
1061 else
1062 quad_he_toggle(NeoMutt->sub, he, err);
1063 }
1064 else
1065 {
1066 // mutt_buffer_printf(err, "ACT26 UNSET bool/quad variable %s", buf->data);
1067 rc = cs_subset_he_native_set(NeoMutt->sub, he, false, err);
1068 if (CSR_RESULT(rc) != CSR_SUCCESS)
1069 return MUTT_CMD_ERROR;
1070 }
1071 continue;
1072 }
1073 else
1074 {
1075 rc = cs_subset_he_string_set(NeoMutt->sub, he, NULL, err);
1076 if (CSR_RESULT(rc) != CSR_SUCCESS)
1077 return MUTT_CMD_ERROR;
1078 }
1079 }
1080
1081 return MUTT_CMD_SUCCESS;
1082}
int bool_he_toggle(struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:186
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:67
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:309
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:248
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:233
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:462
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:85
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:522
bool mutt_path_tilde(char *buf, size_t buflen, const char *homedir)
Expand '~' in a path.
Definition: path.c:223
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:227
#define MUTT_TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition: mutt.h:75
#define MUTT_TOKEN_MINUS
Treat '-' as a special.
Definition: mutt.h:79
#define MUTT_TOKEN_PLUS
Treat '+' as a special.
Definition: mutt.h:78
#define MUTT_TOKEN_EQUAL
Treat '=' as a special.
Definition: mutt.h:68
#define MUTT_TOKEN_QUESTION
Treat '?' as a special.
Definition: mutt.h:77
@ MUTT_SET_INV
default is to invert all vars
Definition: mutt_commands.h:38
@ MUTT_SET_SET
default is to set all vars
Definition: mutt_commands.h:37
@ MUTT_SET_RESET
default is to reset all vars to default
Definition: mutt_commands.h:40
@ MUTT_SET_UNSET
default is to unset all vars
Definition: mutt_commands.h:39
void myvar_del(const char *var)
Unset the value of a "my_" variable.
Definition: myvar.c:146
void myvar_set(const char *var, const char *val)
Set the value of a "my_" variable.
Definition: myvar.c:109
void myvar_append(const char *var, const char *val)
Append to the value of a "my_" variable.
Definition: myvar.c:128
int quad_he_toggle(struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Toggle the value of a quad.
Definition: quad.c:204
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
String manipulation buffer.
Definition: buffer.h:34
size_t dsize
Length of data.
Definition: buffer.h:37
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
The item stored in a Hash Table.
Definition: hash.h:44
union HashKey key
Key representing the data.
Definition: hash.h:46
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:45
void * data
User-supplied data.
Definition: hash.h:47
int cs_subset_he_string_minus_equals(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Remove from a config item by string.
Definition: subset.c:462
int cs_subset_he_string_get(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:354
int cs_subset_he_native_set(const struct ConfigSubset *sub, struct HashElem *he, intptr_t value, struct Buffer *err)
Natively set the value of a HashElem config item.
Definition: subset.c:283
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:75
int cs_subset_he_reset(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Reset a config item to its initial value.
Definition: subset.c:320
int cs_subset_he_string_set(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:386
int cs_subset_he_string_plus_equals(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Add to a config item by string.
Definition: subset.c:424
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:44
#define IS_MAILBOX(x)
Definition: types.h:57
#define DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:37
#define DT_BOOL
boolean option
Definition: types.h:30
#define DT_PATH_DIR
Path is a directory.
Definition: types.h:53
#define DT_PATH_FILE
Path is a file.
Definition: types.h:54
#define DT_PATH
a path to a file/directory
Definition: types.h:36
#define IS_COMMAND(x)
Definition: types.h:58
const char * strkey
String key.
Definition: hash.h:36
+ Here is the call graph for this function:

◆ parse_setenv()

enum CommandResult parse_setenv ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'setenv' and 'unsetenv' commands - Implements Command::parse() -.

Definition at line 1087 of file command_parse.c.

1089{
1090 char **envp = mutt_envlist_getlist();
1091
1092 bool query = false;
1093 bool prefix = false;
1094 bool unset = (data == MUTT_SET_UNSET);
1095
1096 if (!MoreArgs(s))
1097 {
1098 mutt_buffer_printf(err, _("%s: too few arguments"), "setenv");
1099 return MUTT_CMD_WARNING;
1100 }
1101
1102 if (*s->dptr == '?')
1103 {
1104 query = true;
1105 prefix = true;
1106
1107 if (unset)
1108 {
1109 mutt_buffer_printf(err, _("Can't query a variable with the '%s' command"), "unsetenv");
1110 return MUTT_CMD_WARNING;
1111 }
1112
1113 s->dptr++;
1114 }
1115
1116 /* get variable name */
1118
1119 if (*s->dptr == '?')
1120 {
1121 if (unset)
1122 {
1123 mutt_buffer_printf(err, _("Can't query a variable with the '%s' command"), "unsetenv");
1124 return MUTT_CMD_WARNING;
1125 }
1126
1127 if (prefix)
1128 {
1129 mutt_buffer_printf(err, _("Can't use a prefix when querying a variable"));
1130 return MUTT_CMD_WARNING;
1131 }
1132
1133 query = true;
1134 s->dptr++;
1135 }
1136
1137 if (query)
1138 {
1139 bool found = false;
1140 while (envp && *envp)
1141 {
1142 /* This will display all matches for "^QUERY" */
1143 if (mutt_str_startswith(*envp, buf->data))
1144 {
1145 if (!found)
1146 {
1147 mutt_endwin();
1148 found = true;
1149 }
1150 puts(*envp);
1151 }
1152 envp++;
1153 }
1154
1155 if (found)
1156 {
1158 return MUTT_CMD_SUCCESS;
1159 }
1160
1161 mutt_buffer_printf(err, _("%s is unset"), buf->data);
1162 return MUTT_CMD_WARNING;
1163 }
1164
1165 if (unset)
1166 {
1167 if (!mutt_envlist_unset(buf->data))
1168 {
1169 mutt_buffer_printf(err, _("%s is unset"), buf->data);
1170 return MUTT_CMD_WARNING;
1171 }
1172 return MUTT_CMD_SUCCESS;
1173 }
1174
1175 /* set variable */
1176
1177 if (*s->dptr == '=')
1178 {
1179 s->dptr++;
1180 SKIPWS(s->dptr);
1181 }
1182
1183 if (!MoreArgs(s))
1184 {
1185 mutt_buffer_printf(err, _("%s: too few arguments"), "setenv");
1186 return MUTT_CMD_WARNING;
1187 }
1188
1189 char *name = mutt_str_dup(buf->data);
1191 mutt_envlist_set(name, buf->data, true);
1192 FREE(&name);
1193
1194 return MUTT_CMD_SUCCESS;
1195}
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:169
bool mutt_envlist_unset(const char *name)
Unset an environment variable.
Definition: envlist.c:132
bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:85
+ Here is the call graph for this function:

◆ parse_source()

enum CommandResult parse_source ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'source' command - Implements Command::parse() -.

Definition at line 1200 of file command_parse.c.

1202{
1203 char path[PATH_MAX] = { 0 };
1204
1205 do
1206 {
1207 if (mutt_extract_token(buf, s, MUTT_TOKEN_NO_FLAGS) != 0)
1208 {
1209 mutt_buffer_printf(err, _("source: error at %s"), s->dptr);
1210 return MUTT_CMD_ERROR;
1211 }
1212 mutt_str_copy(path, buf->data, sizeof(path));
1213 mutt_expand_path(path, sizeof(path));
1214
1215 if (source_rc(path, err) < 0)
1216 {
1217 mutt_buffer_printf(err, _("source: file %s could not be sourced"), path);
1218 return MUTT_CMD_ERROR;
1219 }
1220
1221 } while (MoreArgs(s));
1222
1223 return MUTT_CMD_SUCCESS;
1224}
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:652
#define PATH_MAX
Definition: mutt.h:40
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:123
+ Here is the call graph for this function:

◆ parse_spam_list()

enum CommandResult parse_spam_list ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'spam' and 'nospam' commands - Implements Command::parse() -.

Definition at line 1229 of file command_parse.c.

1231{
1232 struct Buffer templ;
1233
1234 mutt_buffer_init(&templ);
1235
1236 /* Insist on at least one parameter */
1237 if (!MoreArgs(s))
1238 {
1239 if (data == MUTT_SPAM)
1240 mutt_buffer_strcpy(err, _("spam: no matching pattern"));
1241 else
1242 mutt_buffer_strcpy(err, _("nospam: no matching pattern"));
1243 return MUTT_CMD_ERROR;
1244 }
1245
1246 /* Extract the first token, a regex */
1248
1249 /* data should be either MUTT_SPAM or MUTT_NOSPAM. MUTT_SPAM is for spam commands. */
1250 if (data == MUTT_SPAM)
1251 {
1252 /* If there's a second parameter, it's a template for the spam tag. */
1253 if (MoreArgs(s))
1254 {
1256
1257 /* Add to the spam list. */
1258 if (mutt_replacelist_add(&SpamList, buf->data, templ.data, err) != 0)
1259 {
1260 FREE(&templ.data);
1261 return MUTT_CMD_ERROR;
1262 }
1263 FREE(&templ.data);
1264 }
1265 /* If not, try to remove from the nospam list. */
1266 else
1267 {
1269 }
1270
1271 return MUTT_CMD_SUCCESS;
1272 }
1273 /* MUTT_NOSPAM is for nospam commands. */
1274 else if (data == MUTT_NOSPAM)
1275 {
1276 /* nospam only ever has one parameter. */
1277
1278 /* "*" is a special case. */
1279 if (mutt_str_equal(buf->data, "*"))
1280 {
1283 return MUTT_CMD_SUCCESS;
1284 }
1285
1286 /* If it's on the spam list, just remove it. */
1287 if (mutt_replacelist_remove(&SpamList, buf->data) != 0)
1288 return MUTT_CMD_SUCCESS;
1289
1290 /* Otherwise, add it to the nospam list. */
1291 if (mutt_regexlist_add(&NoSpamList, buf->data, REG_ICASE, err) != 0)
1292 return MUTT_CMD_ERROR;
1293
1294 return MUTT_CMD_SUCCESS;
1295 }
1296
1297 /* This should not happen. */
1298 mutt_buffer_strcpy(err, "This is no good at all.");
1299 return MUTT_CMD_ERROR;
1300}
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:52
struct ReplaceList SpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:34
struct RegexList NoSpamList
List of regexes to whitelist non-spam emails.
Definition: globals.c:33
int mutt_replacelist_remove(struct ReplaceList *rl, const char *pat)
Remove a pattern from a list.
Definition: regex.c:583
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:174
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:467
int mutt_replacelist_add(struct ReplaceList *rl, const char *pat, const char *templ, struct Buffer *err)
Add a pattern and a template to a list.
Definition: regex.c:266
#define MUTT_NOSPAM
Definition: mutt.h:112
#define MUTT_SPAM
Definition: mutt.h:111
+ Here is the call graph for this function:

◆ parse_stailq()

enum CommandResult parse_stailq ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse a list command - Implements Command::parse() -.

This is used by 'alternative_order', 'auto_view' and several others.

Definition at line 1307 of file command_parse.c.

1309{
1310 do
1311 {
1313 add_to_stailq((struct ListHead *) data, buf->data);
1314 } while (MoreArgs(s));
1315
1316 return MUTT_CMD_SUCCESS;
1317}
+ Here is the call graph for this function:

◆ parse_subscribe()

enum CommandResult parse_subscribe ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'subscribe' command - Implements Command::parse() -.

Definition at line 1322 of file command_parse.c.

1324{
1325 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
1326
1327 do
1328 {
1330
1331 if (parse_grouplist(&gl, buf, s, err) == -1)
1332 goto bail;
1333
1336
1337 if (mutt_regexlist_add(&MailLists, buf->data, REG_ICASE, err) != 0)
1338 goto bail;
1339 if (mutt_regexlist_add(&SubscribedLists, buf->data, REG_ICASE, err) != 0)
1340 goto bail;
1341 if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
1342 goto bail;
1343 } while (MoreArgs(s));
1344
1346 return MUTT_CMD_SUCCESS;
1347
1348bail:
1350 return MUTT_CMD_ERROR;
1351}
struct RegexList SubscribedLists
List of regexes to match subscribed mailing lists.
Definition: globals.c:43
struct RegexList UnSubscribedLists
List of regexes to blacklist false matches in SubscribedLists.
Definition: globals.c:40
+ Here is the call graph for this function:

◆ parse_subscribe_to()

enum CommandResult parse_subscribe_to ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'subscribe-to' command - Implements Command::parse() -.

The 'subscribe-to' command allows to subscribe to an IMAP-Mailbox. Patterns are not supported. Use it as follows: subscribe-to =folder

Definition at line 1361 of file command_parse.c.

1363{
1364 if (!buf || !s || !err)
1365 return MUTT_CMD_ERROR;
1366
1367 mutt_buffer_reset(err);
1368
1369 if (MoreArgs(s))
1370 {
1372
1373 if (MoreArgs(s))
1374 {
1375 mutt_buffer_printf(err, _("%s: too many arguments"), "subscribe-to");
1376 return MUTT_CMD_WARNING;
1377 }
1378
1379 if (buf->data && (*buf->data != '\0'))
1380 {
1381 /* Expand and subscribe */
1382 if (imap_subscribe(mutt_expand_path(buf->data, buf->dsize), true) == 0)
1383 {
1384 mutt_message(_("Subscribed to %s"), buf->data);
1385 return MUTT_CMD_SUCCESS;
1386 }
1387
1388 mutt_buffer_printf(err, _("Could not subscribe to %s"), buf->data);
1389 return MUTT_CMD_ERROR;
1390 }
1391
1392 mutt_debug(LL_DEBUG1, "Corrupted buffer");
1393 return MUTT_CMD_ERROR;
1394 }
1395
1396 mutt_buffer_addstr(err, _("No folder specified"));
1397 return MUTT_CMD_WARNING;
1398}
int imap_subscribe(char *path, bool subscribe)
Subscribe to a mailbox.
Definition: imap.c:1289
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
+ Here is the call graph for this function:

◆ parse_tag_formats()

enum CommandResult parse_tag_formats ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'tag-formats' command - Implements Command::parse() -.

Parse config like: tag-formats pgp GP

Note
This maps format -> tag

Definition at line 1408 of file command_parse.c.

1410{
1411 if (!s)
1412 return MUTT_CMD_ERROR;
1413
1414 struct Buffer *tagbuf = mutt_buffer_pool_get();
1415 struct Buffer *fmtbuf = mutt_buffer_pool_get();
1416
1417 while (MoreArgs(s))
1418 {
1420 const char *tag = mutt_buffer_string(tagbuf);
1421 if (*tag == '\0')
1422 continue;
1423
1425 const char *fmt = mutt_buffer_string(fmtbuf);
1426
1427 /* avoid duplicates */
1428 const char *tmp = mutt_hash_find(TagFormats, fmt);
1429 if (tmp)
1430 {
1431 mutt_warning(_("tag format '%s' already registered as '%s'"), fmt, tmp);
1432 continue;
1433 }
1434
1436 }
1437
1438 mutt_buffer_pool_release(&tagbuf);
1439 mutt_buffer_pool_release(&fmtbuf);
1440 return MUTT_CMD_SUCCESS;
1441}
#define mutt_warning(...)
Definition: logging.h:85
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:335
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:362
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
struct HashTable * TagFormats
Hash Table of tag-formats (tag -> format string)
Definition: tags.c:39
+ Here is the call graph for this function:

◆ parse_tag_transforms()

enum CommandResult parse_tag_transforms ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'tag-transforms' command - Implements Command::parse() -.

Parse config like: tag-transforms pgp P

Note
This maps tag -> transform

Definition at line 1450 of file command_parse.c.

1452{
1453 if (!s)
1454 return MUTT_CMD_ERROR;
1455
1456 struct Buffer *tagbuf = mutt_buffer_pool_get();
1457 struct Buffer *trnbuf = mutt_buffer_pool_get();
1458
1459 while (MoreArgs(s))
1460 {
1462 const char *tag = mutt_buffer_string(tagbuf);
1463 if (*tag == '\0')
1464 continue;
1465
1467 const char *trn = mutt_buffer_string(trnbuf);
1468
1469 /* avoid duplicates */
1470 const char *tmp = mutt_hash_find(TagTransforms, tag);
1471 if (tmp)
1472 {
1473 mutt_warning(_("tag transform '%s' already registered as '%s'"), tag, tmp);
1474 continue;
1475 }
1476
1478 }
1479
1480 mutt_buffer_pool_release(&tagbuf);
1481 mutt_buffer_pool_release(&trnbuf);
1482 return MUTT_CMD_SUCCESS;
1483}
struct HashTable * TagTransforms
Lookup table of alternative tag names.
Definition: tags.c:38
+ Here is the call graph for this function:

◆ parse_unignore()

enum CommandResult parse_unignore ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unignore' command - Implements Command::parse() -.

Definition at line 1488 of file command_parse.c.

1490{
1491 do
1492 {
1494
1495 /* don't add "*" to the unignore list */
1496 if (strcmp(buf->data, "*") != 0)
1497 add_to_stailq(&UnIgnore, buf->data);
1498
1500 } while (MoreArgs(s));
1501
1502 return MUTT_CMD_SUCCESS;
1503}
+ Here is the call graph for this function:

◆ parse_unlists()

enum CommandResult parse_unlists ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unlists' command - Implements Command::parse() -.

Definition at line 1508 of file command_parse.c.

1510{
1512 do
1513 {
1517
1518 if (!mutt_str_equal(buf->data, "*") &&
1519 (mutt_regexlist_add(&UnMailLists, buf->data, REG_ICASE, err) != 0))
1520 {
1521 return MUTT_CMD_ERROR;
1522 }
1523 } while (MoreArgs(s));
1524
1525 return MUTT_CMD_SUCCESS;
1526}
struct HashTable * AutoSubscribeCache
Hash Table of auto-subscribed mailing lists.
Definition: globals.c:38
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457
+ Here is the call graph for this function:

◆ parse_unmailboxes()

enum CommandResult parse_unmailboxes ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unmailboxes' command - Implements Command::parse() -.

This is also used by 'unvirtual-mailboxes'

Definition at line 1573 of file command_parse.c.

1575{
1576 while (MoreArgs(s))
1577 {
1579
1580 if (mutt_str_equal(buf->data, "*"))
1581 {
1583 return MUTT_CMD_SUCCESS;
1584 }
1585
1587
1588 struct Account *a = NULL;
1589 TAILQ_FOREACH(a, &NeoMutt->accounts, entries)
1590 {
1591 struct Mailbox *m = mx_mbox_find(a, mutt_buffer_string(buf));
1592 if (m)
1593 {
1594 do_unmailboxes(m);
1595 break;
1596 }
1597 }
1598 }
1599 return MUTT_CMD_SUCCESS;
1600}
static void do_unmailboxes_star(void)
Remove all Mailboxes from the Sidebar/notifications.
static void do_unmailboxes(struct Mailbox *m)
Remove a Mailbox from the Sidebar/notifications.
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40
+ Here is the call graph for this function:

◆ parse_unmy_hdr()

enum CommandResult parse_unmy_hdr ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unmy_hdr' command - Implements Command::parse() -.

Definition at line 1605 of file command_parse.c.

1607{
1608 struct ListNode *np = NULL, *tmp = NULL;
1609 size_t l;
1610
1611 do
1612 {
1614 if (mutt_str_equal("*", buf->data))
1615 {
1616 /* Clear all headers, send a notification for each header */
1617 STAILQ_FOREACH(np, &UserHeader, entries)
1618 {
1619 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1620 struct EventHeader ev_h = { np->data };
1622 }
1624 continue;
1625 }
1626
1627 l = mutt_str_len(buf->data);
1628 if (buf->data[l - 1] == ':')
1629 l--;
1630
1631 STAILQ_FOREACH_SAFE(np, &UserHeader, entries, tmp)
1632 {
1633 if (mutt_istrn_equal(buf->data, np->data, l) && (np->data[l] == ':'))
1634 {
1635 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1636 struct EventHeader ev_h = { np->data };
1638
1639 header_free(&UserHeader, np);
1640 }
1641 }
1642 } while (MoreArgs(s));
1643 return MUTT_CMD_SUCCESS;
1644}
void header_free(struct ListHead *hdrlist, struct ListNode *target)
Free and remove a header from a header list.
Definition: email.c:245
@ NT_HEADER_DELETE
Header has been removed.
Definition: email.h:173
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:567
bool mutt_istrn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings ignoring case (to a maximum), safely.
Definition: string.c:524
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
char * data
String.
Definition: list.h:36
+ Here is the call graph for this function:

◆ parse_unstailq()

enum CommandResult parse_unstailq ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse an unlist command - Implements Command::parse() -.

This is used by 'unalternative_order', 'unauto_view' and several others.

Definition at line 1651 of file command_parse.c.

1653{
1654 do
1655 {
1657 /* Check for deletion of entire list */
1658 if (mutt_str_equal(buf->data, "*"))
1659 {
1660 mutt_list_free((struct ListHead *) data);
1661 break;
1662 }
1663 remove_from_stailq((struct ListHead *) data, buf->data);
1664 } while (MoreArgs(s));
1665
1666 return MUTT_CMD_SUCCESS;
1667}
+ Here is the call graph for this function:

◆ parse_unsubscribe()

enum CommandResult parse_unsubscribe ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unsubscribe' command - Implements Command::parse() -.

Definition at line 1672 of file command_parse.c.

1674{
1676 do
1677 {
1680
1681 if (!mutt_str_equal(buf->data, "*") &&
1682 (mutt_regexlist_add(&UnSubscribedLists, buf->data, REG_ICASE, err) != 0))
1683 {
1684 return MUTT_CMD_ERROR;
1685 }
1686 } while (MoreArgs(s));
1687
1688 return MUTT_CMD_SUCCESS;
1689}
+ Here is the call graph for this function:

◆ parse_unsubscribe_from()

enum CommandResult parse_unsubscribe_from ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unsubscribe-from' command - Implements Command::parse() -.

The 'unsubscribe-from' command allows to unsubscribe from an IMAP-Mailbox. Patterns are not supported. Use it as follows: unsubscribe-from =folder

Definition at line 1699 of file command_parse.c.

1701{
1702 if (!buf || !s || !err)
1703 return MUTT_CMD_ERROR;
1704
1705 if (MoreArgs(s))
1706 {
1708
1709 if (MoreArgs(s))
1710 {
1711 mutt_buffer_printf(err, _("%s: too many arguments"), "unsubscribe-from");
1712 return MUTT_CMD_WARNING;
1713 }
1714
1715 if (buf->data && (*buf->data != '\0'))
1716 {
1717 /* Expand and subscribe */
1718 if (imap_subscribe(mutt_expand_path(buf->data, buf->dsize), false) == 0)
1719 {
1720 mutt_message(_("Unsubscribed from %s"), buf->data);
1721 return MUTT_CMD_SUCCESS;
1722 }
1723
1724 mutt_buffer_printf(err, _("Could not unsubscribe from %s"), buf->data);
1725 return MUTT_CMD_ERROR;
1726 }
1727
1728 mutt_debug(LL_DEBUG1, "Corrupted buffer");
1729 return MUTT_CMD_ERROR;
1730 }
1731
1732 mutt_buffer_addstr(err, _("No folder specified"));
1733 return MUTT_CMD_WARNING;
1734}
+ Here is the call graph for this function:

◆ mutt_parse_charset_iconv_hook()

enum CommandResult mutt_parse_charset_iconv_hook ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse 'charset-hook' and 'iconv-hook' commands - Implements Command::parse() -.

Definition at line 83 of file hook.c.

85{
86 struct Buffer *alias = mutt_buffer_pool_get();
87 struct Buffer *charset = mutt_buffer_pool_get();
88
89 int rc = MUTT_CMD_ERROR;
90 int retval = 0;
91
92 retval += mutt_extract_token(alias, s, MUTT_TOKEN_NO_FLAGS);
93 retval += mutt_extract_token(charset, s, MUTT_TOKEN_NO_FLAGS);
94 if (retval != 0)
95 goto done;
96
98
99 if (mutt_buffer_is_empty(alias) || mutt_buffer_is_empty(charset))
100 {
101 mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
102 rc = MUTT_CMD_WARNING;
103 }
104 else if (MoreArgs(s))
105 {
106 mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
107 mutt_buffer_reset(s); // clean up buffer to avoid a mess with further rcfile processing
108 rc = MUTT_CMD_WARNING;
109 }
110 else if (mutt_ch_lookup_add(type, mutt_buffer_string(alias),
111 mutt_buffer_string(charset), err))
112 {
113 rc = MUTT_CMD_SUCCESS;
114 }
115
116done:
118 mutt_buffer_pool_release(&charset);
119
120 return rc;
121}
#define MUTT_ICONV_HOOK
iconv-hook: create a system charset alias
Definition: hook.h:44
bool mutt_ch_lookup_add(enum LookupType type, const char *pat, const char *replace, struct Buffer *err)
Add a new character set lookup.
Definition: charset.c:484
LookupType
Types of character set lookups.
Definition: charset.h:66
@ MUTT_LOOKUP_ICONV
Character set conversion.
Definition: charset.h:68
@ MUTT_LOOKUP_CHARSET
Alias for another character set.
Definition: charset.h:67
+ Here is the call graph for this function:

◆ mutt_parse_hook()

enum CommandResult mutt_parse_hook ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'hook' family of commands - Implements Command::parse() -.

This is used by 'account-hook', 'append-hook' and many more.

Definition at line 128 of file hook.c.

130{
131 struct Hook *hook = NULL;
132 int rc = MUTT_CMD_ERROR;
133 bool pat_not = false;
134 bool use_regex = true;
135 regex_t *rx = NULL;
136 struct PatternList *pat = NULL;
137 const bool folder_or_mbox = (data & (MUTT_FOLDER_HOOK | MUTT_MBOX_HOOK));
138
139 struct Buffer *cmd = mutt_buffer_pool_get();
140 struct Buffer *pattern = mutt_buffer_pool_get();
141
142 if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
143 {
144 if (*s->dptr == '!')
145 {
146 s->dptr++;
147 SKIPWS(s->dptr);
148 pat_not = true;
149 }
150
152 if (folder_or_mbox && mutt_str_equal(mutt_buffer_string(pattern), "-noregex"))
153 {
154 use_regex = false;
155 if (!MoreArgs(s))
156 {
157 mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
158 rc = MUTT_CMD_WARNING;
159 goto cleanup;
160 }
162 }
163
164 if (!MoreArgs(s))
165 {
166 mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
167 rc = MUTT_CMD_WARNING;
168 goto cleanup;
169 }
170 }
171
172 mutt_extract_token(cmd, s,
177
178 if (mutt_buffer_is_empty(cmd))
179 {
180 mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
181 rc = MUTT_CMD_WARNING;
182 goto cleanup;
183 }
184
185 if (MoreArgs(s))
186 {
187 mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
188 rc = MUTT_CMD_WARNING;
189 goto cleanup;
190 }
191
192 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
193 if (folder_or_mbox)
194 {
195 /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
196 * common mistake */
197 if ((pattern->data[0] == '^') && !CurrentFolder)
198 {
199 mutt_buffer_strcpy(err, _("current mailbox shortcut '^' is unset"));
200 goto cleanup;
201 }
202
203 struct Buffer *tmp = mutt_buffer_pool_get();
204 mutt_buffer_copy(tmp, pattern);
205 mutt_buffer_expand_path_regex(tmp, use_regex);
206
207 /* Check for other mailbox shortcuts that expand to the empty string.
208 * This is likely a mistake too */
209 if (mutt_buffer_is_empty(tmp) && !mutt_buffer_is_empty(pattern))
210 {
211 mutt_buffer_strcpy(err, _("mailbox shortcut expanded to empty regex"));
213 goto cleanup;
214 }
215
216 if (use_regex)
217 {
218 mutt_buffer_copy(pattern, tmp);
219 }
220 else
221 {
223 }
225 }
226#ifdef USE_COMP_MBOX
228 {
230 {
231 mutt_buffer_strcpy(err, _("badly formatted command string"));
232 goto cleanup;
233 }
234 }
235#endif
236 else if (c_default_hook && (~data & MUTT_GLOBAL_HOOK) &&
238 {
239 /* At this stage remain only message-hooks, reply-hooks, send-hooks,
240 * send2-hooks, save-hooks, and fcc-hooks: All those allowing full
241 * patterns. If given a simple regex, we expand $default_hook. */
242 mutt_check_simple(pattern, c_default_hook);
243 }
244
246 {
248 }
249
250 /* check to make sure that a matching hook doesn't already exist */
251 TAILQ_FOREACH(hook, &Hooks, entries)
252 {
254 {
255 /* Ignore duplicate global hooks */
257 {
258 rc = MUTT_CMD_SUCCESS;
259 goto cleanup;
260 }
261 }
262 else if ((hook->type == data) && (hook->regex.pat_not == pat_not) &&
264 {
268 {
269 /* these hooks allow multiple commands with the same
270 * pattern, so if we've already seen this pattern/command pair, just
271 * ignore it instead of creating a duplicate */
273 {
274 rc = MUTT_CMD_SUCCESS;
275 goto cleanup;
276 }
277 }
278 else
279 {
280 /* other hooks only allow one command per pattern, so update the
281 * entry with the new command. this currently does not change the
282 * order of execution of the hooks, which i think is desirable since
283 * a common action to perform is to change the default (.) entry
284 * based upon some other information. */
285 FREE(&hook->command);
286 hook->command = mutt_buffer_strdup(cmd);
288 rc = MUTT_CMD_SUCCESS;
289 goto cleanup;
290 }
291 }
292 }
293
296 {
297 PatternCompFlags comp_flags;
298
299 if (data & (MUTT_SEND2_HOOK))
300 comp_flags = MUTT_PC_SEND_MODE_SEARCH;
301 else if (data & (MUTT_SEND_HOOK | MUTT_FCC_HOOK))
302 comp_flags = MUTT_PC_NO_FLAGS;
303 else
304 comp_flags = MUTT_PC_FULL_MSG;
305
306 struct Mailbox *m_cur = get_current_mailbox();
307 struct Menu *menu = get_current_menu();
308 pat = mutt_pattern_comp(m_cur, menu, mutt_buffer_string(pattern), comp_flags, err);
309 if (!pat)
310 goto cleanup;
311 }
312 else if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
313 {
314 /* Hooks not allowing full patterns: Check syntax of regex */
315 rx = mutt_mem_calloc(1, sizeof(regex_t));
316 int rc2 = REG_COMP(rx, NONULL(mutt_buffer_string(pattern)),
317 ((data & MUTT_CRYPT_HOOK) ? REG_ICASE : 0));
318 if (rc2 != 0)
319 {
320 regerror(rc2, rx, err->data, err->dsize);
321 FREE(&rx);
322 goto cleanup;
323 }
324 }
325
326 hook = mutt_mem_calloc(1, sizeof(struct Hook));
327 hook->type = data;
328 hook->command = mutt_buffer_strdup(cmd);
330 hook->pattern = pat;
331 hook->regex.pattern = mutt_buffer_strdup(pattern);
332 hook->regex.regex = rx;
333 hook->regex.pat_not = pat_not;
334 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
335 rc = MUTT_CMD_SUCCESS;
336
337cleanup:
339 mutt_buffer_pool_release(&pattern);
340 return rc;
341}
char * mutt_get_sourced_cwd(void)
Get the current file path that is being parsed.
struct PatternList * mutt_pattern_comp(struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1160
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition: compress.c:411
int mutt_file_sanitize_regex(struct Buffer *dest, const char *src)
Escape any regex-magic characters in a string.
Definition: file.c:666
static struct HookList Hooks
Definition: hook.c:75
#define MUTT_OPEN_HOOK
open-hook: to read a compressed mailbox
Definition: hook.h:51
#define MUTT_FOLDER_HOOK
folder-hook: when entering a mailbox
Definition: hook.h:38
#define MUTT_SAVE_HOOK
save-hook: set a default folder when saving an email
Definition: hook.h:42
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:40
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition: hook.h:41
#define MUTT_CLOSE_HOOK
close-hook: write to a compressed mailbox
Definition: hook.h:53
#define MUTT_ACCOUNT_HOOK
account-hook: when changing between accounts
Definition: hook.h:47
#define MUTT_APPEND_HOOK
append-hook: append to a compressed mailbox
Definition: hook.h:52
#define MUTT_GLOBAL_HOOK
Hooks which don't take a regex.
Definition: hook.h:59
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:57
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:49
#define MUTT_CRYPT_HOOK
crypt-hook: automatically select a PGP/SMIME key
Definition: hook.h:46
#define MUTT_MBOX_HOOK
mbox-hook: move messages after reading them
Definition: hook.h:39
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:48
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:56
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:45
#define MUTT_SHUTDOWN_HOOK
shutdown-hook: run when leaving NeoMutt
Definition: hook.h:58
struct Mailbox * get_current_mailbox(void)
Get the current Mailbox.
Definition: index.c:624
struct Menu * get_current_menu(void)
Get the current Menu.
Definition: index.c:650
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:54
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:135
#define WithCrypto
Definition: lib.h:116
#define MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition: lib.h:64
uint8_t PatternCompFlags
Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG.
Definition: lib.h:60
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:62
void mutt_check_simple(struct Buffer *s, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:116
#define MUTT_PC_NO_FLAGS
No flags are set.
Definition: lib.h:61
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:53
#define NONULL(x)
Definition: string2.h:37
A list of user hooks.
Definition: hook.c:65
HookFlags type
Hook type.
Definition: hook.c:66
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:70
struct Regex regex
Regular expression.
Definition: hook.c:67
char * command
Filename, command or pattern to execute.
Definition: hook.c:68
char * source_file
Used for relative-directory source.
Definition: hook.c:69
Definition: lib.h:69
char * pattern
printable version
Definition: regex3.h:90
bool pat_not
do not match
Definition: regex3.h:92
regex_t * regex
compiled expression
Definition: regex3.h:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_idxfmt_hook()

enum CommandResult mutt_parse_idxfmt_hook ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'index-format-hook' command - Implements Command::parse() -.

Definition at line 411 of file hook.c.

413{
415 bool pat_not = false;
416
417 struct Buffer *name = mutt_buffer_pool_get();
418 struct Buffer *pattern = mutt_buffer_pool_get();
419 struct Buffer *fmtstring = mutt_buffer_pool_get();
420
421 if (!IdxFmtHooks)
422 {
425 }
426
427 if (!MoreArgs(s))
428 {
429 mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
430 goto out;
431 }
433 struct HookList *hl = mutt_hash_find(IdxFmtHooks, mutt_buffer_string(name));
434
435 if (*s->dptr == '!')
436 {
437 s->dptr++;
438 SKIPWS(s->dptr);
439 pat_not = true;
440 }
442
443 if (!MoreArgs(s))
444 {
445 mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
446 goto out;
447 }
449
450 if (MoreArgs(s))
451 {
452 mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
453 goto out;
454 }
455
456 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
457 if (c_default_hook)
458 mutt_check_simple(pattern, c_default_hook);
459
460 /* check to make sure that a matching hook doesn't already exist */
461 struct Hook *hook = NULL;
462 if (hl)
463 {
464 TAILQ_FOREACH(hook, hl, entries)
465 {
466 if ((hook->regex.pat_not == pat_not) &&
468 {
469 mutt_str_replace(&hook->command, mutt_buffer_string(fmtstring));
470 rc = MUTT_CMD_SUCCESS;
471 goto out;
472 }
473 }
474 }
475
476 /* MUTT_PC_PATTERN_DYNAMIC sets so that date ranges are regenerated during
477 * matching. This of course is slower, but index-format-hook is commonly
478 * used for date ranges, and they need to be evaluated relative to "now", not
479 * the hook compilation time. */
480 struct Mailbox *m_cur = get_current_mailbox();
481 struct Menu *menu = get_current_menu();
482 struct PatternList *pat = mutt_pattern_comp(m_cur, menu, mutt_buffer_string(pattern),
484 err);
485 if (!pat)
486 goto out;
487
488 hook = mutt_mem_calloc(1, sizeof(struct Hook));
489 hook->type = MUTT_IDXFMTHOOK;
490 hook->command = mutt_buffer_strdup(fmtstring);
492 hook->pattern = pat;
493 hook->regex.pattern = mutt_buffer_strdup(pattern);
494 hook->regex.regex = NULL;
495 hook->regex.pat_not = pat_not;
496
497 if (!hl)
498 {
499 hl = mutt_mem_calloc(1, sizeof(*hl));
500 TAILQ_INIT(hl);
502 }
503
504 TAILQ_INSERT_TAIL(hl, hook, entries);
505 rc = MUTT_CMD_SUCCESS;
506
507out:
509 mutt_buffer_pool_release(&pattern);
510 mutt_buffer_pool_release(&fmtstring);
511
512 return rc;
513}
static void idxfmt_hashelem_free(int type, void *obj, intptr_t data)
Delete an index-format-hook from the Hash Table - Implements hash_hdata_free_t -.
Definition: hook.c:385
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:259
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition: hash.c:301
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:111
static struct HashTable * IdxFmtHooks
Definition: hook.c:77
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:55
#define MUTT_PC_PATTERN_DYNAMIC
Enable runtime date range evaluation.
Definition: lib.h:63
#define TAILQ_INIT(head)
Definition: queue.h:765
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_unhook()

enum CommandResult mutt_parse_unhook ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unhook' command - Implements Command::parse() -.

Definition at line 538 of file hook.c.

540{
541 while (MoreArgs(s))
542 {
544 if (mutt_str_equal("*", buf->data))
545 {
547 {
548 mutt_buffer_printf(err, "%s", _("unhook: Can't do unhook * from within a hook"));
549 return MUTT_CMD_WARNING;
550 }
554 }
555 else
556 {
557 HookFlags type = mutt_get_hook_type(buf->data);
558
559 if (type == MUTT_HOOK_NO_FLAGS)
560 {
561 mutt_buffer_printf(err, _("unhook: unknown hook type: %s"), buf->data);
562 return MUTT_CMD_ERROR;
563 }
564 if (type & (MUTT_CHARSET_HOOK | MUTT_ICONV_HOOK))
565 {
567 return MUTT_CMD_SUCCESS;
568 }
569 if (current_hook_type == type)
570 {
571 mutt_buffer_printf(err, _("unhook: Can't delete a %s from within a %s"),
572 buf->data, buf->data);
573 return MUTT_CMD_WARNING;
574 }
575 if (type == MUTT_IDXFMTHOOK)
577 else
578 mutt_delete_hooks(type);
579 }
580 }
581 return MUTT_CMD_SUCCESS;
582}
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:367
static void delete_idxfmt_hooks(void)
Delete all the index-format-hooks.
Definition: hook.c:403
static HookFlags mutt_get_hook_type(const char *name)
Find a hook by name.
Definition: hook.c:521
static HookFlags current_hook_type
Definition: hook.c:78
uint32_t HookFlags
Flags for mutt_parse_hook(), e.g. MUTT_FOLDER_HOOK.
Definition: hook.h:36
#define MUTT_CHARSET_HOOK
charset-hook: create a charset alias for malformed emails
Definition: hook.h:43
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:37
void mutt_ch_lookup_remove(void)
Remove all the character set lookups.
Definition: charset.c:516
+ Here is the call graph for this function:

◆ mutt_parse_push()

enum CommandResult mutt_parse_push ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'push' command - Implements Command::parse() -.

Definition at line 1117 of file keymap.c.

1119{
1121 if (MoreArgs(s))
1122 {
1123 mutt_buffer_printf(err, _("%s: too many arguments"), "push");
1124 return MUTT_CMD_ERROR;
1125 }
1126
1128 return MUTT_CMD_SUCCESS;
1129}
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition: curs_lib.c:561
static void generic_tokenize_push_string(char *s, void(*generic_push)(int, int))
Parse and queue a 'push' command.
Definition: keymap.c:538
#define MUTT_TOKEN_CONDENSE
^(char) to control chars (macros)
Definition: mutt.h:69
+ Here is the call graph for this function:

◆ mutt_parse_bind()

enum CommandResult mutt_parse_bind ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'bind' command - Implements Command::parse() -.

bind menu-name <key_sequence> function-name

Definition at line 1280 of file keymap.c.

1282{
1283 const struct MenuFuncOp *funcs = NULL;
1284 enum MenuType mtypes[MenuNamesLen];
1285 int num_menus = 0;
1287
1288 char *key = parse_keymap(mtypes, s, mutt_array_size(mtypes), &num_menus, err, true);
1289 if (!key)
1290 return MUTT_CMD_ERROR;
1291
1292 /* function to execute */
1294 if (MoreArgs(s))
1295 {
1296 mutt_buffer_printf(err, _("%s: too many arguments"), "bind");
1297 rc = MUTT_CMD_ERROR;
1298 }
1299 else if (mutt_istr_equal("noop", buf->data))
1300 {
1301 for (int i = 0; i < num_menus; i++)
1302 {
1303 km_bindkey(key, mtypes[i], OP_NULL); /* the 'unbind' command */
1304 funcs = km_get_table(mtypes[i]);
1305 if (funcs)
1306 {
1307 char keystr[32] = { 0 };
1308 km_expand_key_string(key, keystr, sizeof(keystr));
1309 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1310 mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", mname, keystr);
1311
1312 int op = get_op(OpGeneric, buf->data, mutt_str_len(buf->data));
1313 struct EventBinding ev_b = { mtypes[i], key, op };
1315 }
1316 }
1317 }
1318 else
1319 {
1320 for (int i = 0; i < num_menus; i++)
1321 {
1322 /* The pager and editor menus don't use the generic map,
1323 * however for other menus try generic first. */
1324 if ((mtypes[i] != MENU_PAGER) && (mtypes[i] != MENU_EDITOR) && (mtypes[i] != MENU_GENERIC))
1325 {
1326 rc = try_bind(key, mtypes[i], buf->data, OpGeneric, err);
1327 if (rc == MUTT_CMD_SUCCESS)
1328 {
1329 char keystr[32] = { 0 };
1330 km_expand_key_string(key, keystr, sizeof(keystr));
1331 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1332 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, keystr);
1333
1334 int op = get_op(OpGeneric, buf->data, mutt_str_len(buf->data));
1335 struct EventBinding ev_b = { mtypes[i], key, op };
1337 continue;
1338 }
1339 if (rc == MUTT_CMD_WARNING)
1340 break;
1341 }
1342
1343 /* Clear any error message, we're going to try again */
1344 err->data[0] = '\0';
1345 funcs = km_get_table(mtypes[i]);
1346 if (funcs)
1347 {
1348 rc = try_bind(key, mtypes[i], buf->data, funcs, err);
1349 if (rc == MUTT_CMD_SUCCESS)
1350 {
1351 char keystr[32] = { 0 };
1352 km_expand_key_string(key, keystr, sizeof(keystr));
1353 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1354 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, keystr);
1355
1356 int op = get_op(funcs, buf->data, mutt_str_len(buf->data));
1357 struct EventBinding ev_b = { mtypes[i], key, op };
1359 continue;
1360 }
1361 }
1362 }
1363 }
1364 FREE(&key);
1365 return rc;
1366}
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition: functions.c:288
static int km_expand_key_string(char *str, char *buf, size_t buflen)
Get a human-readable key string.
Definition: keymap.c:903
static enum CommandResult km_bindkey(const char *s, enum MenuType mtype, int op)
Bind a key in a Menu to an operation.
Definition: keymap.c:484
static char * parse_keymap(enum MenuType *mtypes, struct Buffer *s, int max_menus, int *num_menus, struct Buffer *err, bool bind)
Parse a user-config key binding.
Definition: keymap.c:1145
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: keymap.c:1230
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: keymap.c:1207
static int get_op(const struct MenuFuncOp *funcs, const char *start, size_t len)
Get the function by its name.
Definition: keymap.c:496
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition: keymap.h:126
@ NT_BINDING_ADD
Key binding has been added.
Definition: keymap.h:125
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
#define mutt_array_size(x)
Definition: memory.h:36
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition: notify_type.h:40
A key binding Event.
Definition: keymap.h:110
const char * key
Key string being bound (for new bind/macro)
Definition: keymap.h:112
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition: keymap.h:113
Mapping between a function and an operation.
Definition: keymap.h:92
int op
Operation, e.g. OP_DELETE.
Definition: keymap.h:94
const int MenuNamesLen
Definition: type.c:59
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:31
MenuType
Types of GUI selections.
Definition: type.h:36
@ MENU_GENERIC
Generic selection list.
Definition: type.h:45
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54
@ MENU_EDITOR
Text entry area.
Definition: type.h:43
+ Here is the call graph for this function:

◆ mutt_parse_unbind()

enum CommandResult mutt_parse_unbind ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unbind' command - Implements Command::parse() -.

Command unbinds:

  • one binding in one menu-name
  • one binding in all menu-names
  • all bindings in all menu-names

unbind <menu-name[,...]|*> [<key_sequence>]

Definition at line 1430 of file keymap.c.

1432{
1433 bool menu_matches[MENU_MAX] = { 0 };
1434 bool all_keys = false;
1435 char *key = NULL;
1436
1438 if (mutt_str_equal(buf->data, "*"))
1439 {
1440 for (enum MenuType i = 0; i < MENU_MAX; i++)
1441 menu_matches[i] = true;
1442 }
1443 else
1444 parse_menu(menu_matches, buf->data, err);
1445
1446 if (MoreArgs(s))
1447 {
1449 key = buf->data;
1450 }
1451 else
1452 all_keys = true;
1453
1454 if (MoreArgs(s))
1455 {
1456 const char *cmd = (data & MUTT_UNMACRO) ? "unmacro" : "unbind";
1457
1458 mutt_buffer_printf(err, _("%s: too many arguments"), cmd);
1459 return MUTT_CMD_ERROR;
1460 }
1461
1462 for (enum MenuType i = 0; i < MENU_MAX; i++)
1463 {
1464 if (!menu_matches[i])
1465 continue;
1466 if (all_keys)
1467 {
1468 km_unbind_all(&Keymaps[i], data);
1469 km_bindkey("<enter>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
1470 km_bindkey("<return>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
1471 km_bindkey("<enter>", MENU_INDEX, OP_DISPLAY_MESSAGE);
1472 km_bindkey("<return>", MENU_INDEX, OP_DISPLAY_MESSAGE);
1473 km_bindkey("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE);
1474 km_bindkey("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE);
1475 km_bindkey(":", MENU_GENERIC, OP_ENTER_COMMAND);
1476 km_bindkey(":", MENU_PAGER, OP_ENTER_COMMAND);
1477 if (i != MENU_EDITOR)
1478 {
1479 km_bindkey("?", i, OP_HELP);
1480 km_bindkey("q", i, OP_EXIT);
1481 }
1482
1483 const char *mname = mutt_map_get_name(i, MenuNames);
1484 mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE_ALL: %s\n", mname);
1485
1486 struct EventBinding ev_b = { i, NULL, OP_NULL };
1489 &ev_b);
1490 }
1491 else
1492 {
1493 char keystr[32] = { 0 };
1494 km_expand_key_string(key, keystr, sizeof(keystr));
1495 const char *mname = mutt_map_get_name(i, MenuNames);
1496 mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE: %s %s\n", mname, keystr);
1497
1498 km_bindkey(key, i, OP_NULL);
1499 struct EventBinding ev_b = { i, key, OP_NULL };
1501 (data & MUTT_UNMACRO) ? NT_MACRO_DELETE : NT_BINDING_DELETE, &ev_b);
1502 }
1503 }
1504
1505 return MUTT_CMD_SUCCESS;
1506}
static void * parse_menu(bool *menus, char *s, struct Buffer *err)
Parse menu-names into an array.
Definition: keymap.c:1377
static void km_unbind_all(struct KeymapList *km_list, unsigned long mode)
Free all the keys in the supplied Keymap.
Definition: keymap.c:1406
struct KeymapList Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:126
@ NT_MACRO_DELETE
Key macro has been deleted.
Definition: keymap.h:130
@ NT_MACRO_DELETE_ALL
All key macros have been deleted.
Definition: keymap.h:131
@ NT_BINDING_DELETE_ALL
All key bindings have been deleted.
Definition: keymap.h:127
#define MUTT_UNMACRO
Definition: keymap.h:34
@ MENU_INDEX
Index panel (list of emails)
Definition: type.h:50
@ MENU_MAX
Definition: type.h:59
+ Here is the call graph for this function:

◆ mutt_parse_macro()

enum CommandResult mutt_parse_macro ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'macro' command - Implements Command::parse() -.

macro <menu> <key> <macro> <description>

Definition at line 1513 of file keymap.c.

1515{
1516 enum MenuType mtypes[MenuNamesLen];
1517 int num_menus = 0;
1518 enum CommandResult rc = MUTT_CMD_ERROR;
1519
1520 char *key = parse_keymap(mtypes, s, mutt_array_size(mtypes), &num_menus, err, false);
1521 if (!key)
1522 return MUTT_CMD_ERROR;
1523
1525 /* make sure the macro sequence is not an empty string */
1526 if (buf->data[0] == '\0')
1527 {
1528 mutt_buffer_strcpy(err, _("macro: empty key sequence"));
1529 }
1530 else
1531 {
1532 if (MoreArgs(s))
1533 {
1534 char *seq = mutt_str_dup(buf->data);
1536
1537 if (MoreArgs(s))
1538 {
1539 mutt_buffer_printf(err, _("%s: too many arguments"), "macro");
1540 }
1541 else
1542 {
1543 for (int i = 0; i < num_menus; i++)
1544 {
1545 rc = km_bind(key, mtypes[i], OP_MACRO, seq, buf->data);
1546 if (rc == MUTT_CMD_SUCCESS)
1547 {
1548 char keystr[32] = { 0 };
1549 km_expand_key_string(key, keystr, sizeof(keystr));
1550 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1551 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, keystr);
1552
1553 struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
1555 continue;
1556 }
1557 }
1558 }
1559
1560 FREE(&seq);
1561 }
1562 else
1563 {
1564 for (int i = 0; i < num_menus; i++)
1565 {
1566 rc = km_bind(key, mtypes[i], OP_MACRO, buf->data, NULL);
1567 if (rc == MUTT_CMD_SUCCESS)
1568 {
1569 char keystr[32] = { 0 };
1570 km_expand_key_string(key, keystr, sizeof(keystr));
1571 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1572 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, keystr);
1573
1574 struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
1576 continue;
1577 }
1578 }
1579 }
1580 }
1581 FREE(&key);
1582 return rc;
1583}
enum CommandResult km_bind(char *s, enum MenuType mtype, int op, char *macro, char *desc)
Bind a key to a macro.
Definition: keymap.c:458
@ NT_MACRO_ADD
Key macro has been added.
Definition: keymap.h:129
+ Here is the call graph for this function:

◆ mutt_parse_exec()

enum CommandResult mutt_parse_exec ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'exec' command - Implements Command::parse() -.

Definition at line 1588 of file keymap.c.

1590{
1591 int ops[128];
1592 int nops = 0;
1593 const struct MenuFuncOp *funcs = NULL;
1594 char *function = NULL;
1595
1596 if (!MoreArgs(s))
1597 {
1598 mutt_buffer_strcpy(err, _("exec: no arguments"));
1599 return MUTT_CMD_ERROR;
1600 }
1601
1602 do
1603 {
1605 function = buf->data;
1606
1607 const enum MenuType mtype = menu_get_current_type();
1608 funcs = km_get_table(mtype);
1609 if (!funcs && (mtype != MENU_PAGER))
1610 funcs = OpGeneric;
1611
1612 ops[nops] = get_op(funcs, function, mutt_str_len(function));
1613 if ((ops[nops] == OP_NULL) && (mtype != MENU_PAGER) && (mtype != MENU_GENERIC))
1614 {
1615 ops[nops] = get_op(OpGeneric, function, mutt_str_len(function));
1616 }
1617
1618 if (ops[nops] == OP_NULL)
1619 {
1620 mutt_flushinp();
1621 mutt_error(_("%s: no such function"), function);
1622 return MUTT_CMD_ERROR;
1623 }
1624 nops++;
1625 } while (MoreArgs(s) && nops < mutt_array_size(ops));
1626
1627 while (nops)
1628 mutt_push_macro_event(0, ops[--nops]);
1629
1630 return MUTT_CMD_SUCCESS;
1631}
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:592
enum MenuType menu_get_current_type(void)
Get the type of the current Window.
Definition: menu.c:84
+ Here is the call graph for this function:

◆ mutt_lua_parse()

enum CommandResult mutt_lua_parse ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'lua' command - Implements Command::parse() -.

Definition at line 477 of file mutt_lua.c.

479{
481 mutt_debug(LL_DEBUG2, " * mutt_lua_parse(%s)\n", buf->data);
482
483 if (luaL_dostring(LuaState, s->dptr))
484 {
485 mutt_debug(LL_DEBUG2, " * %s -> failure\n", s->dptr);
486 mutt_buffer_printf(err, "%s: %s", s->dptr, lua_tostring(LuaState, -1));
487 /* pop error message from the stack */
488 lua_pop(LuaState, 1);
489 return MUTT_CMD_ERROR;
490 }
491 mutt_debug(LL_DEBUG2, " * %s -> success\n", s->dptr);
492 mutt_buffer_reset(s); // Clear the rest of the line
493 return MUTT_CMD_SUCCESS;
494}
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
static bool lua_init(lua_State **l)
Initialise a Lua State.
Definition: mutt_lua.c:441
lua_State * LuaState
Global Lua State.
Definition: mutt_lua.c:56
+ Here is the call graph for this function:

◆ mutt_lua_source_file()

enum CommandResult mutt_lua_source_file ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'lua-source' command - Implements Command::parse() -.

Definition at line 499 of file mutt_lua.c.

501{
502 mutt_debug(LL_DEBUG2, " * mutt_lua_source()\n");
503
505
506 char path[PATH_MAX] = { 0 };
507
508 if (mutt_extract_token(buf, s, MUTT_TOKEN_NO_FLAGS) != 0)
509 {
510 mutt_buffer_printf(err, _("source: error at %s"), s->dptr);
511 return MUTT_CMD_ERROR;
512 }
513 if (MoreArgs(s))
514 {
515 mutt_buffer_printf(err, _("%s: too many arguments"), "source");
516 return MUTT_CMD_WARNING;
517 }
518 mutt_str_copy(path, buf->data, sizeof(path));
519 mutt_expand_path(path, sizeof(path));
520
521 if (luaL_dofile(LuaState, path))
522 {
523 mutt_error(_("Couldn't source lua source: %s"), lua_tostring(LuaState, -1));
524 lua_pop(LuaState, 1);
525 return MUTT_CMD_ERROR;
526 }
527 return MUTT_CMD_SUCCESS;
528}
+ Here is the call graph for this function:

◆ mutt_parse_score()

enum CommandResult mutt_parse_score ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'score' command - Implements Command::parse() -.

Definition at line 86 of file score.c.

88{
89 struct Score *ptr = NULL, *last = NULL;
90 char *pattern = NULL, *pc = NULL;
91
93 if (!MoreArgs(s))
94 {
95 mutt_buffer_printf(err, _("%s: too few arguments"), "score");
96 return MUTT_CMD_WARNING;
97 }
98 pattern = mutt_buffer_strdup(buf);
100 if (MoreArgs(s))
101 {
102 FREE(&pattern);
103 mutt_buffer_printf(err, _("%s: too many arguments"), "score");
104 return MUTT_CMD_WARNING;
105 }
106
107 /* look for an existing entry and update the value, else add it to the end
108 * of the list */
109 for (ptr = ScoreList, last = NULL; ptr; last = ptr, ptr = ptr->next)
110 if (mutt_str_equal(pattern, ptr->str))
111 break;
112 if (!ptr)
113 {
114 struct Mailbox *m_cur = get_current_mailbox();
115 struct Menu *menu = get_current_menu();
116 struct PatternList *pat = mutt_pattern_comp(m_cur, menu, pattern, MUTT_PC_NO_FLAGS, err);
117 if (!pat)
118 {
119 FREE(&pattern);
120 return MUTT_CMD_ERROR;
121 }
122 ptr = mutt_mem_calloc(1, sizeof(struct Score));
123 if (last)
124 last->next = ptr;
125 else
126 ScoreList = ptr;
127 ptr->pat = pat;
128 ptr->str = pattern;
129 }
130 else
131 {
132 /* 'buf' arg was cleared and 'pattern' holds the only reference;
133 * as here 'ptr' != NULL -> update the value only in which case
134 * ptr->str already has the string, so pattern should be freed. */
135 FREE(&pattern);
136 }
137 pc = buf->data;
138 if (*pc == '=')
139 {
140 ptr->exact = true;
141 pc++;
142 }
143 if (!mutt_str_atoi_full(pc, &ptr->val))
144 {
145 FREE(&pattern);
146 mutt_buffer_strcpy(err, _("Error: score: invalid number"));
147 return MUTT_CMD_ERROR;
148 }
149 OptNeedRescore = true;
150 return MUTT_CMD_SUCCESS;
151}
bool OptNeedRescore
(pseudo) set when the 'score' command is used
Definition: options.h:47
static struct Score * ScoreList
Definition: score.c:57
Scoring rule for email.
Definition: score.c:49
struct PatternList * pat
Definition: score.c:51
struct Score * next
Definition: score.c:54
+ Here is the call graph for this function:

◆ mutt_parse_unscore()

enum CommandResult mutt_parse_unscore ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unscore' command - Implements Command::parse() -.

Definition at line 195 of file score.c.

197{
198 struct Score *tmp = NULL, *last = NULL;
199
200 while (MoreArgs(s))
201 {
203 if (mutt_str_equal("*", buf->data))
204 {
205 for (tmp = ScoreList; tmp;)
206 {
207 last = tmp;
208 tmp = tmp->next;
209 mutt_pattern_free(&last->pat);
210 FREE(&last);
211 }
212 ScoreList = NULL;
213 }
214 else
215 {
216 for (tmp = ScoreList; tmp; last = tmp, tmp = tmp->next)
217 {
218 if (mutt_str_equal(buf->data, tmp->str))
219 {
220 if (last)
221 last->next = tmp->next;
222 else
223 ScoreList = tmp->next;
224 mutt_pattern_free(&tmp->pat);
225 FREE(&tmp);
226 /* there should only be one score per pattern, so we can stop here */
227 break;
228 }
229 }
230 }
231 }
232 OptNeedRescore = true;
233 return MUTT_CMD_SUCCESS;
234}
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
+ Here is the call graph for this function:

◆ sb_parse_whitelist()

enum CommandResult sb_parse_whitelist ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'sidebar_whitelist' command - Implements Command::parse() -.

Definition at line 41 of file commands.c.

43{
44 struct Buffer *path = mutt_buffer_pool_get();
45
46 do
47 {
51 } while (MoreArgs(s));
53
54 return MUTT_CMD_SUCCESS;
55}
struct ListHead SidebarWhitelist
List of mailboxes to always display in the sidebar.
Definition: sidebar.c:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sb_parse_unwhitelist()

enum CommandResult sb_parse_unwhitelist ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unsidebar_whitelist' command - Implements Command::parse() -.

Definition at line 60 of file commands.c.

62{
63 struct Buffer *path = mutt_buffer_pool_get();
64
65 do
66 {
68 /* Check for deletion of entire list */
69 if (mutt_str_equal(mutt_buffer_string(path), "*"))
70 {
72 break;
73 }
76 } while (MoreArgs(s));
78
79 return MUTT_CMD_SUCCESS;
80}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_unreplace_list()

static enum CommandResult parse_unreplace_list ( struct Buffer buf,
struct Buffer s,
struct ReplaceList *  list,
struct Buffer err 
)
static

Remove a string replacement rule - Implements Command::parse() -.

Definition at line 66 of file subjectrx.c.

68{
69 /* First token is a regex. */
70 if (!MoreArgs(s))
71 {
72 mutt_buffer_printf(err, _("%s: too few arguments"), "unsubjectrx");
73 return MUTT_CMD_WARNING;
74 }
75
77
78 /* "*" is a special case. */
79 if (mutt_str_equal(buf->data, "*"))
80 {
82 return MUTT_CMD_SUCCESS;
83 }
84
85 mutt_replacelist_remove(list, buf->data);
86 return MUTT_CMD_SUCCESS;
87}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_replace_list()

static enum CommandResult parse_replace_list ( struct Buffer buf,
struct Buffer s,
struct ReplaceList *  list,
struct Buffer err 
)
static

Parse a string replacement rule - Implements Command::parse() -.

Definition at line 92 of file subjectrx.c.

94{
95 struct Buffer templ = mutt_buffer_make(0);
96
97 /* First token is a regex. */
98 if (!MoreArgs(s))
99 {
100 mutt_buffer_printf(err, _("%s: too few arguments"), "subjectrx");
101 return MUTT_CMD_WARNING;
102 }
104
105 /* Second token is a replacement template */
106 if (!MoreArgs(s))
107 {
108 mutt_buffer_printf(err, _("%s: too few arguments"), "subjectrx");
109 return MUTT_CMD_WARNING;
110 }
112
113 if (mutt_replacelist_add(list, buf->data, templ.data, err) != 0)
114 {
115 FREE(&templ.data);
116 return MUTT_CMD_ERROR;
117 }
118 FREE(&templ.data);
119
120 return MUTT_CMD_SUCCESS;
121}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_subjectrx_list()

enum CommandResult parse_subjectrx_list ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'subjectrx' command - Implements Command::parse() -.

Definition at line 163 of file subjectrx.c.

165{
166 enum CommandResult rc;
167
168 rc = parse_replace_list(buf, s, &SubjectRegexList, err);
169 if (rc == MUTT_CMD_SUCCESS)
170 {
171 mutt_debug(LL_NOTIFY, "NT_SUBJRX_ADD: %s\n", buf->data);
173 }
174 return rc;
175}
static enum CommandResult parse_replace_list(struct Buffer *buf, struct Buffer *s, struct ReplaceList *list, struct Buffer *err)
Parse a string replacement rule - Implements Command::parse() -.
Definition: subjectrx.c:92
@ NT_SUBJRX
Subject Regex has changed, NotifySubjRx.
Definition: notify_type.h:54
static struct Notify * SubjRxNotify
Definition: subjectrx.c:40
static struct ReplaceList SubjectRegexList
Definition: subjectrx.c:39
@ NT_SUBJRX_ADD
Subject Regex has been added.
Definition: subjectrx.h:42
+ Here is the call graph for this function:

◆ parse_unsubjectrx_list()

enum CommandResult parse_unsubjectrx_list ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

Parse the 'unsubjectrx' command - Implements Command::parse() -.

Definition at line 180 of file subjectrx.c.

182{
183 enum CommandResult rc;
184
185 rc = parse_unreplace_list(buf, s, &SubjectRegexList, err);
186 if (rc == MUTT_CMD_SUCCESS)
187 {
188 mutt_debug(LL_NOTIFY, "NT_SUBJRX_DELETE: %s\n", buf->data);
190 }
191 return rc;
192}
static enum CommandResult parse_unreplace_list(struct Buffer *buf, struct Buffer *s, struct ReplaceList *list, struct Buffer *err)
Remove a string replacement rule - Implements Command::parse() -.
Definition: subjectrx.c:66
@ NT_SUBJRX_DELETE
Subject Regex has been deleted.
Definition: subjectrx.h:43
+ Here is the call graph for this function: