NeoMutt  2025-12-11-58-g09398d
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches

Function to parse a command. More...

+ Collaboration diagram for parse():

Functions

enum CommandResult parse_alias (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'alias' command - Implements Command::parse() -.
 
enum CommandResult parse_unalias (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unalias' command - Implements Command::parse() -.
 
enum CommandResult parse_alternates (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'alternates' command - Implements Command::parse() -.
 
enum CommandResult parse_unalternates (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unalternates' command - Implements Command::parse() -.
 
enum CommandResult parse_attachments (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'attachments' command - Implements Command::parse() -.
 
enum CommandResult parse_unattachments (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unattachments' command - Implements Command::parse() -.
 
enum CommandResult parse_uncolor_command (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse an 'uncolor' command - Implements Command::parse() -.
 
enum CommandResult parse_uncolor (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'uncolor' command - Implements Command::parse() -.
 
enum CommandResult parse_unmono (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unmono' command - Implements Command::parse() -.
 
enum CommandResult parse_color (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'color' command - Implements Command::parse() -.
 
enum CommandResult parse_mono (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'mono' command - Implements Command::parse() -.
 
enum CommandResult parse_cd (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'cd' command - Implements Command::parse() -.
 
enum CommandResult parse_echo (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'echo' command - Implements Command::parse() -.
 
enum CommandResult parse_finish (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'finish' command - Implements Command::parse() -.
 
enum CommandResult parse_group (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'group' and 'ungroup' commands - Implements Command::parse() -.
 
enum CommandResult parse_ifdef (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'ifdef' and 'ifndef' commands - Implements Command::parse() -.
 
enum CommandResult parse_ignore (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'ignore' command - Implements Command::parse() -.
 
enum CommandResult parse_lists (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'lists' command - Implements Command::parse() -.
 
enum CommandResult parse_mailboxes (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'mailboxes' command - Implements Command::parse() -.
 
enum CommandResult parse_my_hdr (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'my_hdr' command - Implements Command::parse() -.
 
enum CommandResult parse_setenv (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'setenv' and 'unsetenv' commands - Implements Command::parse() -.
 
enum CommandResult parse_source (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'source' command - Implements Command::parse() -.
 
enum CommandResult parse_nospam (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'nospam' command - Implements Command::parse() -.
 
enum CommandResult parse_spam (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'spam' command - Implements Command::parse() -.
 
enum CommandResult parse_stailq (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse a list command - Implements Command::parse() -.
 
enum CommandResult parse_subscribe (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'subscribe' command - Implements Command::parse() -.
 
enum CommandResult parse_subscribe_to (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'subscribe-to' command - Implements Command::parse() -.
 
enum CommandResult parse_tag_formats (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'tag-formats' command - Implements Command::parse() -.
 
enum CommandResult parse_tag_transforms (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'tag-transforms' command - Implements Command::parse() -.
 
enum CommandResult parse_unignore (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unignore' command - Implements Command::parse() -.
 
enum CommandResult parse_unlists (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unlists' command - Implements Command::parse() -.
 
enum CommandResult parse_unmailboxes (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unmailboxes' command - Implements Command::parse() -.
 
enum CommandResult parse_unmy_hdr (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unmy_hdr' command - Implements Command::parse() -.
 
enum CommandResult parse_unstailq (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse an unlist command - Implements Command::parse() -.
 
enum CommandResult parse_unsubscribe (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unsubscribe' command - Implements Command::parse() -.
 
enum CommandResult parse_unsubscribe_from (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unsubscribe-from' command - Implements Command::parse() -.
 
enum CommandResult parse_version (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'version' command - Implements Command::parse() -.
 
enum CommandResult parse_hook_charset (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse charset hook commands - Implements Command::parse() -.
 
enum CommandResult parse_hook_global (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse global hook commands - Implements Command::parse() -.
 
enum CommandResult parse_hook_pattern (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse pattern-based hook commands - Implements Command::parse() -.
 
enum CommandResult parse_hook_mailbox (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse mailbox pattern hook commands - Implements Command::parse() -.
 
enum CommandResult parse_hook_regex (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse regex-based hook command - Implements Command::parse() -.
 
enum CommandResult parse_hook_folder (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse folder hook command - Implements Command::parse() -.
 
enum CommandResult parse_hook_crypt (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse crypt hook commands - Implements Command::parse() -.
 
enum CommandResult parse_hook_mbox (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse mbox hook command - Implements Command::parse() -.
 
enum CommandResult parse_hook_compress (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse compress hook commands - Implements Command::parse() -.
 
enum CommandResult parse_hook_index (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the index format hook command - Implements Command::parse() -.
 
enum CommandResult parse_unhook (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the unhook command - Implements Command::parse() -.
 
enum CommandResult parse_push (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'push' command - Implements Command::parse() -.
 
enum CommandResult parse_bind (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'bind' command - Implements Command::parse() -.
 
enum CommandResult parse_unbind (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unbind' command - Implements Command::parse() -.
 
enum CommandResult parse_macro (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'macro' command - Implements Command::parse() -.
 
enum CommandResult parse_exec (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'exec' command - Implements Command::parse() -.
 
enum CommandResult parse_bind_macro (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse 'bind' and 'macro' commands - Implements Command::parse() -.
 
enum CommandResult parse_lua (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'lua' command - Implements Command::parse() -.
 
enum CommandResult parse_lua_source (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'lua-source' command - Implements Command::parse() -.
 
enum CommandResult parse_set (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'set' family of commands - Implements Command::parse() -.
 
enum CommandResult parse_score (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'score' command - Implements Command::parse() -.
 
enum CommandResult parse_unscore (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unscore' command - Implements Command::parse() -.
 
enum CommandResult parse_sidebar_pin (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'sidebar_pin' command - Implements Command::parse() -.
 
enum CommandResult parse_sidebar_unpin (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'sidebar_unpin' command - Implements Command::parse() -.
 
enum CommandResult parse_subjectrx_list (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'subjectrx' command - Implements Command::parse() -.
 
enum CommandResult parse_unsubjectrx_list (const struct Command *cmd, struct Buffer *line, struct Buffer *err)
 Parse the 'unsubjectrx' command - Implements Command::parse() -.
 

Detailed Description

Function to parse a command.

Parameters
cmdCommand being parsed
lineBuffer containing string to be parsed
errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
cmd is not NULL
line is not NULL
err is not NULL

Function Documentation

◆ parse_alias()

enum CommandResult parse_alias ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

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

Parse:

  • alias [ -group <name> ... ] <key> <address> [, <address> ... ]

Definition at line 137 of file commands.c.

139{
140 if (!MoreArgs(line))
141 {
142 buf_printf(err, _("%s: too few arguments"), cmd->name);
143 return MUTT_CMD_WARNING;
144 }
145
146 struct Alias *tmp = NULL;
147 enum NotifyAlias event;
148 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
149 struct Buffer *token = buf_pool_get();
151
152 /* name */
154 mutt_debug(LL_DEBUG5, "First token is '%s'\n", buf_string(token));
155 if (parse_grouplist(&gl, token, line, err, NeoMutt->groups) == -1)
156 goto done;
157
158 char *name = mutt_str_dup(buf_string(token));
159
160 /* address list */
162 mutt_debug(LL_DEBUG5, "Second token is '%s'\n", buf_string(token));
163 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
164 int parsed = mutt_addrlist_parse2(&al, buf_string(token));
165 if (parsed == 0)
166 {
167 buf_printf(err, _("Warning: Bad address '%s' in alias '%s'"), buf_string(token), name);
168 FREE(&name);
169 goto done;
170 }
171
172 /* IDN */
173 char *estr = NULL;
174 if (mutt_addrlist_to_intl(&al, &estr))
175 {
176 buf_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, name);
177 FREE(&name);
178 FREE(&estr);
179 goto done;
180 }
181
182 /* check to see if an alias with this name already exists */
183 TAILQ_FOREACH(tmp, &Aliases, entries)
184 {
185 if (mutt_istr_equal(tmp->name, name))
186 break;
187 }
188
189 if (tmp)
190 {
191 FREE(&name);
193 /* override the previous value */
195 FREE(&tmp->comment);
196 event = NT_ALIAS_CHANGE;
197 }
198 else
199 {
200 /* create a new alias */
201 tmp = alias_new();
202 tmp->name = name;
203 TAILQ_INSERT_TAIL(&Aliases, tmp, entries);
204 event = NT_ALIAS_ADD;
205 }
206 tmp->addr = al;
207
208 grouplist_add_addrlist(&gl, &tmp->addr);
209
210 const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
211 if (c_debug_level > LL_DEBUG4)
212 {
213 /* A group is terminated with an empty address, so check a->mailbox */
214 struct Address *a = NULL;
215 TAILQ_FOREACH(a, &tmp->addr, entries)
216 {
217 if (!a->mailbox)
218 break;
219
220 if (a->group)
221 mutt_debug(LL_DEBUG5, " Group %s\n", buf_string(a->mailbox));
222 else
223 mutt_debug(LL_DEBUG5, " %s\n", buf_string(a->mailbox));
224 }
225 }
226
227 if (!MoreArgs(line) && (line->dptr[0] == '#'))
228 {
229 line->dptr++; // skip over the "# "
230 if (*line->dptr == ' ')
231 line->dptr++;
232
233 parse_alias_comments(tmp, line->dptr);
234 *line->dptr = '\0'; // We're done parsing
235 }
236
238
239 mutt_debug(LL_NOTIFY, "%s: %s\n",
240 (event == NT_ALIAS_ADD) ? "NT_ALIAS_ADD" : "NT_ALIAS_CHANGE", tmp->name);
241 struct EventAlias ev_a = { tmp };
242 notify_send(NeoMutt->notify, NT_ALIAS, event, &ev_a);
243
244 rc = MUTT_CMD_SUCCESS;
245
246done:
247 buf_pool_release(&token);
249 return rc;
250}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1460
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition address.c:644
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition address.c:1293
void parse_alias_comments(struct Alias *alias, const char *com)
Parse the alias/query comment field.
Definition commands.c:94
struct AliasList Aliases
List of all the user's email aliases.
Definition alias.c:61
struct Alias * alias_new(void)
Create a new Alias.
Definition alias.c:656
NotifyAlias
Alias notification types.
Definition alias.h:55
@ NT_ALIAS_ADD
Alias has been added.
Definition alias.h:56
@ NT_ALIAS_CHANGE
Alias has been changed.
Definition alias.h:59
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
CommandResult
Error codes for command_t parse functions.
Definition command.h:35
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition command.h:38
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition command.h:36
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition command.h:37
int parse_grouplist(struct GroupList *gl, struct Buffer *token, struct Buffer *line, struct Buffer *err, struct HashTable *groups)
Parse a group context.
Definition commands.c:145
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
int parse_extract_token(struct Buffer *dest, struct Buffer *line, TokenFlags flags)
Extract one token from a string.
Definition extract.c:48
#define TOKEN_SPACE
Don't treat whitespace as a term.
Definition extract.h:47
#define TOKEN_QUOTE
Don't interpret quotes.
Definition extract.h:48
#define MoreArgs(buf)
Definition extract.h:30
#define TOKEN_SEMICOLON
Don't treat ; as special.
Definition extract.h:51
#define TOKEN_NO_FLAGS
No flags are set.
Definition extract.h:44
void grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition group.c:224
void grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition group.c:203
#define mutt_debug(LEVEL,...)
Definition logging2.h:90
@ LL_DEBUG4
Log at debug level 4.
Definition logging2.h:47
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:48
@ LL_NOTIFY
Log of notifications.
Definition logging2.h:49
#define FREE(x)
Definition memory.h:62
#define _(a)
Definition message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition notify.c:173
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:672
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:255
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition notify_type.h:37
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:96
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define STAILQ_HEAD_INITIALIZER(head)
Definition queue.h:324
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:866
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:694
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
An email address.
Definition address.h:35
bool group
Group mailbox?
Definition address.h:38
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:37
A shortcut for an email address or addresses.
Definition alias.h:35
char * comment
Free-form comment string.
Definition alias.h:38
char * name
Short name.
Definition alias.h:36
struct AddressList addr
List of Addresses the Alias expands to.
Definition alias.h:37
String manipulation buffer.
Definition buffer.h:36
char * dptr
Current read/write position.
Definition buffer.h:38
const char * name
Name of the command.
Definition command.h:59
An alias-change event.
Definition alias.h:66
Container for Accounts, Notifications.
Definition neomutt.h:43
struct Notify * notify
Notifications handler.
Definition neomutt.h:44
struct HashTable * groups
Hash Table: "group-name" -> Group.
Definition neomutt.h:52
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:47
+ Here is the call graph for this function:

◆ parse_unalias()

enum CommandResult parse_unalias ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unalias [ -group <name> ... ] { * | <key> ... }

Definition at line 258 of file commands.c.

260{
261 if (!MoreArgs(line))
262 {
263 buf_printf(err, _("%s: too few arguments"), cmd->name);
264 return MUTT_CMD_WARNING;
265 }
266
267 struct Buffer *token = buf_pool_get();
268
269 do
270 {
272
273 struct Alias *np = NULL;
274 if (mutt_str_equal("*", buf_string(token)))
275 {
276 TAILQ_FOREACH(np, &Aliases, entries)
277 {
279 }
280
282 goto done;
283 }
284
285 TAILQ_FOREACH(np, &Aliases, entries)
286 {
287 if (!mutt_istr_equal(buf_string(token), np->name))
288 continue;
289
290 TAILQ_REMOVE(&Aliases, np, entries);
292 alias_free(&np);
293 break;
294 }
295 } while (MoreArgs(line));
296
297done:
298 buf_pool_release(&token);
299 return MUTT_CMD_SUCCESS;
300}
void alias_free(struct Alias **ptr)
Free an Alias.
Definition alias.c:668
void aliaslist_clear(struct AliasList *al)
Empty a List of Aliases.
Definition alias.c:693
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:660
#define TAILQ_REMOVE(head, elm, field)
Definition queue.h:901
+ Here is the call graph for this function:

◆ parse_alternates()

enum CommandResult parse_alternates ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • alternates [ -group <name> ... ] <regex> [ <regex> ... ]

Definition at line 94 of file alternates.c.

96{
97 if (!MoreArgs(line))
98 {
99 buf_printf(err, _("%s: too few arguments"), cmd->name);
100 return MUTT_CMD_WARNING;
101 }
102
103 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
104 struct Buffer *token = buf_pool_get();
106
107 do
108 {
110
111 if (parse_grouplist(&gl, token, line, err, NeoMutt->groups) == -1)
112 goto done;
113
115
116 if (mutt_regexlist_add(&Alternates, buf_string(token), REG_ICASE, err) != 0)
117 goto done;
118
119 if (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0)
120 goto done;
121 } while (MoreArgs(line));
122
123 mutt_debug(LL_NOTIFY, "NT_ALTERN_ADD: %s\n", buf_string(token));
125
126 rc = MUTT_CMD_SUCCESS;
127
128done:
129 buf_pool_release(&token);
131 return rc;
132}
static struct RegexList Alternates
List of regexes to match the user's alternate email addresses.
Definition alternates.c:41
static struct Notify * AlternatesNotify
Notifications: NotifyAlternates.
Definition alternates.c:43
static struct RegexList UnAlternates
List of regexes to exclude false matches in Alternates.
Definition alternates.c:42
@ NT_ALTERN_ADD
Alternate address has been added.
Definition alternates.h:41
int grouplist_add_regex(struct GroupList *gl, const char *str, uint16_t flags, struct Buffer *err)
Add matching Addresses to a GroupList.
Definition group.c:245
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:139
int mutt_regexlist_remove(struct RegexList *rl, const char *str)
Remove a Regex from a list.
Definition regex.c:234
@ 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 ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unalternates [ -group <name> ... ] { * | <regex> ... }

Definition at line 140 of file alternates.c.

142{
143 if (!MoreArgs(line))
144 {
145 buf_printf(err, _("%s: too few arguments"), cmd->name);
146 return MUTT_CMD_WARNING;
147 }
148
149 struct Buffer *token = buf_pool_get();
151
152 do
153 {
156
157 if (!mutt_str_equal(buf_string(token), "*") &&
158 (mutt_regexlist_add(&UnAlternates, buf_string(token), REG_ICASE, err) != 0))
159 {
160 goto done;
161 }
162
163 } while (MoreArgs(line));
164
165 mutt_debug(LL_NOTIFY, "NT_ALTERN_DELETE: %s\n", buf_string(token));
167
168 rc = MUTT_CMD_SUCCESS;
169
170done:
171 buf_pool_release(&token);
172 return rc;
173}
@ 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 ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • attachments { + | - }<disposition> <mime-type> [ <mime-type> ... ] | ?

Definition at line 485 of file commands.c.

487{
488 if (!MoreArgs(line))
489 {
490 buf_printf(err, _("%s: too few arguments"), cmd->name);
491 return MUTT_CMD_WARNING;
492 }
493
494 struct Buffer *token = buf_pool_get();
496
498
499 char *category = token->data;
500 char op = *category++;
501
502 if (op == '?')
503 {
504 mutt_endwin();
505 fflush(stdout);
506 printf("\n%s\n\n", _("Current attachments settings:"));
507 print_attach_list(&AttachAllow, '+', "A");
509 print_attach_list(&InlineAllow, '+', "I");
512
513 rc = MUTT_CMD_SUCCESS;
514 goto done;
515 }
516
517 if ((op != '+') && (op != '-'))
518 {
519 op = '+';
520 category--;
521 }
522
523 struct ListHead *head = NULL;
524 if (mutt_istr_startswith("attachment", category))
525 {
526 if (op == '+')
527 head = &AttachAllow;
528 else
529 head = &AttachExclude;
530 }
531 else if (mutt_istr_startswith("inline", category))
532 {
533 if (op == '+')
534 head = &InlineAllow;
535 else
536 head = &InlineExclude;
537 }
538 else
539 {
540 buf_strcpy(err, _("attachments: invalid disposition"));
541 goto done;
542 }
543
544 rc = parse_attach_list(cmd, line, head, err);
545
546done:
547 buf_pool_release(&token);
548 return rc;
549}
static struct ListHead AttachAllow
List of attachment types to be counted.
Definition commands.c:55
static int print_attach_list(struct ListHead *h, const char op, const char *name)
Print a list of attachments.
Definition commands.c:466
static struct ListHead InlineExclude
List of inline types to ignore.
Definition commands.c:58
static struct ListHead AttachExclude
List of attachment types to be ignored.
Definition commands.c:56
static enum CommandResult parse_attach_list(const struct Command *cmd, struct Buffer *line, struct ListHead *head, struct Buffer *err)
Parse the "attachments" command.
Definition commands.c:312
static struct ListHead InlineAllow
List of inline types to counted.
Definition commands.c:57
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition curs_lib.c:174
void mutt_endwin(void)
Shutdown curses.
Definition curs_lib.c:152
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition string.c:244
char * data
Pointer to data.
Definition buffer.h:37
+ Here is the call graph for this function:

◆ parse_unattachments()

enum CommandResult parse_unattachments ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unattachments { * | { + | - }<disposition> <mime-type> [ <mime-type> ... ] }

Definition at line 557 of file commands.c.

559{
560 if (!MoreArgs(line))
561 {
562 buf_printf(err, _("%s: too few arguments"), cmd->name);
563 return MUTT_CMD_WARNING;
564 }
565
566 struct Buffer *token = buf_pool_get();
568
569 char op;
570 const char *p = NULL;
571 struct ListHead *head = NULL;
572
574
575 p = buf_string(token);
576 op = *p++;
577
578 if (op == '*')
579 {
584
585 mutt_debug(LL_NOTIFY, "NT_ATTACH_DELETE_ALL\n");
587
588 rc = MUTT_CMD_SUCCESS;
589 goto done;
590 }
591
592 if ((op != '+') && (op != '-'))
593 {
594 op = '+';
595 p--;
596 }
597 if (mutt_istr_startswith("attachment", p))
598 {
599 if (op == '+')
600 head = &AttachAllow;
601 else
602 head = &AttachExclude;
603 }
604 else if (mutt_istr_startswith("inline", p))
605 {
606 if (op == '+')
607 head = &InlineAllow;
608 else
609 head = &InlineExclude;
610 }
611 else
612 {
613 buf_strcpy(err, _("unattachments: invalid disposition"));
614 goto done;
615 }
616
617 rc = parse_unattach_list(cmd, line, head, err);
618
619done:
620 buf_pool_release(&token);
621 return rc;
622}
static enum CommandResult parse_unattach_list(const struct Command *cmd, struct Buffer *line, struct ListHead *head, struct Buffer *err)
Parse the "unattachments" command.
Definition commands.c:397
static struct Notify * AttachmentsNotify
Notifications: NotifyAttach.
Definition commands.c:59
@ NT_ATTACH_DELETE_ALL
All Attachment regexes have been deleted.
Definition commands.h:42
static void attachmatch_free(struct AttachMatch **ptr)
Free an AttachMatch - Implements list_free_t -.
Definition commands.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:50
@ NT_ATTACH
Attachment command changed, NotifyAttach.
Definition notify_type.h:39
+ Here is the call graph for this function:

◆ parse_uncolor_command()

enum CommandResult parse_uncolor_command ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Usage:

  • uncolor OBJECT [ PATTERN | REGEX | * ]

Definition at line 199 of file commands.c.

201{
202 if (!MoreArgs(line))
203 {
204 buf_printf(err, _("%s: too few arguments"), cmd->name);
205 return MUTT_CMD_WARNING;
206 }
207
208 struct Buffer *token = buf_pool_get();
210
211 // Peek at the next token ('*' won't match a colour name)
212 if (line->dptr[0] == '*')
213 {
215 if (mutt_str_equal(buf_string(token), "*"))
216 {
217 colors_reset();
218 rc = MUTT_CMD_SUCCESS;
219 goto done;
220 }
221 }
222
223 unsigned int cid = MT_COLOR_NONE;
224 color_debug(LL_DEBUG5, "uncolor: %s\n", buf_string(token));
225 rc = parse_object(cmd, line, &cid, err);
226 if (rc != MUTT_CMD_SUCCESS)
227 goto done;
228
229 if (cid == -1)
230 {
231 buf_printf(err, _("%s: no such object"), buf_string(token));
232 rc = MUTT_CMD_ERROR;
233 goto done;
234 }
235
236 if ((cid == MT_COLOR_STATUS) && !MoreArgs(line))
237 {
238 color_debug(LL_DEBUG5, "simple\n");
239 simple_color_reset(cid); // default colour for the status bar
240 goto done;
241 }
242
243 if (!mutt_color_has_pattern(cid))
244 {
245 color_debug(LL_DEBUG5, "simple\n");
247 goto done;
248 }
249
250 if (!MoreArgs(line))
251 {
252 if (regex_colors_parse_uncolor(cid, NULL))
253 rc = MUTT_CMD_SUCCESS;
254 else
255 rc = MUTT_CMD_ERROR;
256 goto done;
257 }
258
259 do
260 {
262 if (mutt_str_equal("*", buf_string(token)))
263 {
264 if (regex_colors_parse_uncolor(cid, NULL))
265 rc = MUTT_CMD_SUCCESS;
266 else
267 rc = MUTT_CMD_ERROR;
268 goto done;
269 }
270
272
273 } while (MoreArgs(line));
274
275 rc = MUTT_CMD_SUCCESS;
276
277done:
278 buf_pool_release(&token);
279 return rc;
280}
static enum CommandResult parse_object(const struct Command *cmd, struct Buffer *line, enum ColorId *cid, struct Buffer *err)
Identify a colour object.
Definition commands.c:146
bool regex_colors_parse_uncolor(enum ColorId cid, const char *pat)
Parse a Regex 'uncolor' command.
Definition regex.c:424
void simple_color_reset(enum ColorId cid)
Clear the colour of a simple object.
Definition simple.c:150
bool mutt_color_has_pattern(enum ColorId cid)
Check if a color object supports a regex pattern.
Definition color.c:98
void colors_reset(void)
Reset all the simple, quoted and regex colours.
Definition color.c:68
@ MT_COLOR_STATUS
Status bar (takes a pattern)
Definition color.h:79
@ MT_COLOR_NONE
No colour.
Definition color.h:37
static int color_debug(enum LogLevel level, const char *format,...)
Definition debug.h:52
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_uncolor()

enum CommandResult parse_uncolor ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • uncolor <object> { * | <pattern> ... }

Definition at line 449 of file commands.c.

451{
452 if (!MoreArgs(line))
453 {
454 buf_printf(err, _("%s: too few arguments"), cmd->name);
455 return MUTT_CMD_WARNING;
456 }
457
458 struct Buffer *token = buf_pool_get();
460
461 if (!OptGui) // No GUI, so quietly discard the command
462 {
463 while (MoreArgs(line))
464 {
466 }
467 goto done;
468 }
469
470 color_debug(LL_DEBUG5, "parse: %s\n", buf_string(token));
471 rc = parse_uncolor_command(cmd, line, err);
472 curses_colors_dump(token);
473
474done:
475 buf_pool_release(&token);
476 return rc;
477}
void curses_colors_dump(struct Buffer *buf)
Dump all the Curses colours.
Definition debug.c:143
bool OptGui
(pseudo) when the gui (and curses) are started
Definition globals.c:59
enum CommandResult parse_uncolor_command(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse an 'uncolor' command - Implements Command::parse() -.
Definition commands.c:199
+ Here is the call graph for this function:

◆ parse_unmono()

enum CommandResult parse_unmono ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unmono <object> { * | <pattern> ... }

Definition at line 485 of file commands.c.

487{
488 // Quietly discard the command
489 struct Buffer *token = buf_pool_get();
490 while (MoreArgs(line))
491 {
493 }
494 buf_pool_release(&token);
495
496 return MUTT_CMD_SUCCESS;
497}
+ Here is the call graph for this function:

◆ parse_color()

enum CommandResult parse_color ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • color <object> [ <attribute> ... ] <foreground> <background> [ <regex> [ <num> ]]

Definition at line 505 of file commands.c.

507{
508 struct Buffer *token = buf_pool_get();
510
511 // No GUI, or no colours, so quietly discard the command
512 if (!OptGui || (COLORS == 0))
513 {
514 while (MoreArgs(line))
515 {
517 }
518 goto done;
519 }
520
521 color_debug(LL_DEBUG5, "parse: color\n");
522 rc = parse_color_command(cmd, line, err, parse_color_pair);
523 curses_colors_dump(token);
524
525done:
526 buf_pool_release(&token);
527 return rc;
528}
static enum CommandResult parse_color_command(const struct Command *cmd, struct Buffer *line, struct Buffer *err, parser_callback_t callback)
Parse a 'color' command.
Definition commands.c:294
enum CommandResult parse_color_pair(const struct Command *cmd, struct Buffer *line, struct AttrColor *ac, struct Buffer *err)
Parse a pair of colours - Implements parser_callback_t -.
+ Here is the call graph for this function:

◆ parse_mono()

enum CommandResult parse_mono ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • mono <object> <attribute> [ <pattern> | <regex> ]

Definition at line 536 of file commands.c.

538{
539 struct Buffer *token = buf_pool_get();
541
542 // No GUI, or colours available, so quietly discard the command
543 if (!OptGui || (COLORS != 0))
544 {
545 while (MoreArgs(line))
546 {
548 }
549 goto done;
550 }
551
552 color_debug(LL_DEBUG5, "parse: %s\n", buf_string(token));
553 rc = parse_color_command(cmd, line, err, parse_attr_spec);
554 curses_colors_dump(token);
555
556done:
557 buf_pool_release(&token);
558 return rc;
559}
enum CommandResult parse_attr_spec(const struct Command *cmd, struct Buffer *line, struct AttrColor *ac, struct Buffer *err)
Parse an attribute description - Implements parser_callback_t -.
+ Here is the call graph for this function:

◆ parse_cd()

enum CommandResult parse_cd ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • cd [ <directory> ]

Definition at line 372 of file commands.c.

373{
374 struct Buffer *token = buf_pool_get();
376
378 if (buf_is_empty(token))
379 {
380 buf_strcpy(token, NeoMutt->home_dir);
381 }
382 else
383 {
384 buf_expand_path(token);
385 }
386
387 if (chdir(buf_string(token)) != 0)
388 {
389 buf_printf(err, "%s: %s", cmd->name, strerror(errno));
390 goto done;
391 }
392
393 rc = MUTT_CMD_SUCCESS;
394
395done:
396 buf_pool_release(&token);
397 return rc;
398}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:291
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition muttlib.c:314
char * home_dir
User's home directory.
Definition neomutt.h:54
+ Here is the call graph for this function:

◆ parse_echo()

enum CommandResult parse_echo ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • echo <message>

Definition at line 406 of file commands.c.

408{
409 if (!MoreArgs(line))
410 {
411 buf_printf(err, _("%s: too few arguments"), cmd->name);
412 return MUTT_CMD_WARNING;
413 }
414
415 struct Buffer *token = buf_pool_get();
416
418 OptForceRefresh = true;
419 mutt_message("%s", buf_string(token));
420 OptForceRefresh = false;
421 mutt_sleep(0);
422
423 buf_pool_release(&token);
424 return MUTT_CMD_SUCCESS;
425}
bool OptForceRefresh
(pseudo) refresh even during macros
Definition globals.c:58
#define mutt_message(...)
Definition logging2.h:92
void mutt_sleep(short s)
Sleep for a while.
Definition muttlib.c:841
+ Here is the call graph for this function:

◆ parse_finish()

enum CommandResult parse_finish ( const struct Command * cmd,
struct Buffer * line,
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.

Parse:

  • finish

Definition at line 437 of file commands.c.

439{
440 if (MoreArgs(line))
441 {
442 buf_printf(err, _("%s: too many arguments"), cmd->name);
443 return MUTT_CMD_WARNING;
444 }
445
446 return MUTT_CMD_FINISH;
447}
@ MUTT_CMD_FINISH
Finish: Stop processing this file.
Definition command.h:39
+ Here is the call graph for this function:

◆ parse_group()

enum CommandResult parse_group ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • group [ -group <name> ... ] { -rx <regex> ... | -addr <address> ... }
  • ungroup [ -group <name> ... ] { * | -rx <regex> ... | -addr <address> ... }

Definition at line 456 of file commands.c.

458{
459 if (!MoreArgs(line))
460 {
461 buf_printf(err, _("%s: too few arguments"), cmd->name);
462 return MUTT_CMD_WARNING;
463 }
464
465 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
466 enum GroupState gstate = GS_NONE;
467 struct Buffer *token = buf_pool_get();
469
470 do
471 {
473 if (parse_grouplist(&gl, token, line, err, NeoMutt->groups) == -1)
474 goto done;
475
476 if ((cmd->data == MUTT_UNGROUP) && mutt_istr_equal(buf_string(token), "*"))
477 {
479 rc = MUTT_CMD_SUCCESS;
480 goto done;
481 }
482
483 if (mutt_istr_equal(buf_string(token), "-rx"))
484 {
485 gstate = GS_RX;
486 }
487 else if (mutt_istr_equal(buf_string(token), "-addr"))
488 {
489 gstate = GS_ADDR;
490 }
491 else
492 {
493 switch (gstate)
494 {
495 case GS_NONE:
496 buf_printf(err, _("%s: missing -rx or -addr"), cmd->name);
497 rc = MUTT_CMD_WARNING;
498 goto done;
499
500 case GS_RX:
501 if ((cmd->data == MUTT_GROUP) &&
502 (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0))
503 {
504 goto done;
505 }
506 else if ((cmd->data == MUTT_UNGROUP) &&
507 (groups_remove_regex(NeoMutt->groups, &gl, buf_string(token)) < 0))
508 {
509 goto done;
510 }
511 break;
512
513 case GS_ADDR:
514 {
515 char *estr = NULL;
516 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
517 mutt_addrlist_parse2(&al, buf_string(token));
518 if (TAILQ_EMPTY(&al))
519 goto done;
520 if (mutt_addrlist_to_intl(&al, &estr))
521 {
522 buf_printf(err, _("%s: warning: bad IDN '%s'"), cmd->name, estr);
524 FREE(&estr);
525 goto done;
526 }
527 if (cmd->data == MUTT_GROUP)
528 grouplist_add_addrlist(&gl, &al);
529 else if (cmd->data == MUTT_UNGROUP)
532 break;
533 }
534 }
535 }
536 } while (MoreArgs(line));
537
538 rc = MUTT_CMD_SUCCESS;
539
540done:
541 buf_pool_release(&token);
543 return rc;
544}
GroupState
Type of email address group.
Definition commands.c:95
@ GS_RX
Entry is a regular expression.
Definition commands.c:97
@ GS_NONE
Group is missing an argument.
Definition commands.c:96
@ GS_ADDR
Entry is an address.
Definition commands.c:98
int groups_remove_addrlist(struct HashTable *groups, struct GroupList *gl, struct AddressList *al)
Remove an AddressList from a GroupList.
Definition group.c:337
void groups_remove_grouplist(struct HashTable *groups, struct GroupList *gl)
Clear a GroupList.
Definition group.c:312
int groups_remove_regex(struct HashTable *groups, struct GroupList *gl, const char *str)
Remove matching addresses from a GroupList.
Definition group.c:368
#define MUTT_GROUP
'group' config command
Definition group.h:32
#define MUTT_UNGROUP
'ungroup' config command
Definition group.h:33
#define TAILQ_EMPTY(head)
Definition queue.h:778
intptr_t data
Data or flags to pass to the command.
Definition command.h:77
+ Here is the call graph for this function:

◆ parse_ifdef()

enum CommandResult parse_ifdef ( const struct Command * cmd,
struct Buffer * line,
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 (cmd->data == 1) then it means use the 'ifndef' (if-not-defined) command. e.g. ifndef imap finish

Parse:

  • ifdef <symbol> "<config-command> [ <args> ... ]"
  • ifndef <symbol> "<config-command> [ <args> ... ]"

Definition at line 563 of file commands.c.

565{
566 if (!MoreArgs(line))
567 {
568 buf_printf(err, _("%s: too few arguments"), cmd->name);
569 return MUTT_CMD_WARNING;
570 }
571
572 struct Buffer *token = buf_pool_get();
574
576
577 // is the item defined as:
578 bool res = cs_subset_lookup(NeoMutt->sub, buf_string(token)) // a variable?
579 || feature_enabled(buf_string(token)) // a compiled-in feature?
580 || is_function(buf_string(token)) // a function?
581 || commands_get(&NeoMutt->commands, buf_string(token)) // a command?
582 || is_color_object(buf_string(token)) // a color?
583#ifdef USE_HCACHE
584 || store_is_valid_backend(buf_string(token)) // a store? (database)
585#endif
586 || mutt_str_getenv(buf_string(token)); // an environment variable?
587
588 if (!MoreArgs(line))
589 {
590 buf_printf(err, _("%s: too few arguments"), cmd->name);
591 rc = MUTT_CMD_WARNING;
592 goto done;
593 }
594 parse_extract_token(token, line, TOKEN_SPACE);
595
596 /* ifdef KNOWN_SYMBOL or ifndef UNKNOWN_SYMBOL */
597 if ((res && (cmd->data == 0)) || (!res && (cmd->data == 1)))
598 {
599 rc = parse_rc_line(token, err);
600 if (rc == MUTT_CMD_ERROR)
601 mutt_error(_("Error: %s"), buf_string(err));
602
603 goto done;
604 }
605
606done:
607 buf_pool_release(&token);
608 return rc;
609}
static bool is_color_object(const char *name)
Is the argument a neomutt colour?
Definition commands.c:128
static bool is_function(const char *name)
Is the argument a neomutt function?
Definition commands.c:107
const struct Command * commands_get(struct CommandArray *ca, const char *name)
Get a Command by its name.
Definition command.c:82
#define mutt_error(...)
Definition logging2.h:93
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition string.c:726
enum CommandResult parse_rc_line(struct Buffer *line, struct Buffer *err)
Parse a line of user config.
Definition rc.c:45
bool store_is_valid_backend(const char *str)
Is the string a valid Store backend.
Definition store.c:126
struct CommandArray commands
NeoMutt commands.
Definition neomutt.h:51
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition subset.c:193
bool feature_enabled(const char *name)
Test if a compile-time feature is enabled.
Definition version.c:729
+ Here is the call graph for this function:

◆ parse_ignore()

enum CommandResult parse_ignore ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • ignore { * | <string> ... }

Definition at line 617 of file commands.c.

619{
620 if (!MoreArgs(line))
621 {
622 buf_printf(err, _("%s: too few arguments"), cmd->name);
623 return MUTT_CMD_WARNING;
624 }
625
626 struct Buffer *token = buf_pool_get();
627
628 do
629 {
633 } while (MoreArgs(line));
634
635 buf_pool_release(&token);
636 return MUTT_CMD_SUCCESS;
637}
struct ListHead Ignore
List of regexes to match mailing lists.
Definition globals.c:38
struct ListHead UnIgnore
List of regexes to exclude false matches in MailLists.
Definition globals.c:50
void remove_from_stailq(struct ListHead *head, const char *str)
Remove an item, matching a string, from a List.
Definition muttlib.c:1063
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition muttlib.c:1038
+ Here is the call graph for this function:

◆ parse_lists()

enum CommandResult parse_lists ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • lists [ -group <name> ... ] <regex> [ <regex> ... ]

Definition at line 645 of file commands.c.

647{
648 if (!MoreArgs(line))
649 {
650 buf_printf(err, _("%s: too few arguments"), cmd->name);
651 return MUTT_CMD_WARNING;
652 }
653
654 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
655 struct Buffer *token = buf_pool_get();
657
658 do
659 {
661
662 if (parse_grouplist(&gl, token, line, err, NeoMutt->groups) == -1)
663 goto done;
664
666
667 if (mutt_regexlist_add(&MailLists, buf_string(token), REG_ICASE, err) != 0)
668 goto done;
669
670 if (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0)
671 goto done;
672 } while (MoreArgs(line));
673
674 rc = MUTT_CMD_SUCCESS;
675
676done:
677 buf_pool_release(&token);
679 return rc;
680}
struct RegexList UnMailLists
List of regexes to exclude false matches in SubscribedLists.
Definition globals.c:52
struct RegexList MailLists
List of permitted fields in a mailto: url.
Definition globals.c:40
+ Here is the call graph for this function:

◆ parse_mailboxes()

enum CommandResult parse_mailboxes ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • mailboxes [[ -label <label> ] | -nolabel ] [[ -notify | -nonotify ] [ -poll | -nopoll ] <mailbox> ] [ ... ]
  • named-mailboxes <description> <mailbox> [ <description> <mailbox> ... ]

Definition at line 810 of file commands.c.

812{
813 if (!MoreArgs(line))
814 {
815 buf_printf(err, _("%s: too few arguments"), cmd->name);
816 return MUTT_CMD_WARNING;
817 }
818
819 struct Buffer *label = buf_pool_get();
820 struct Buffer *mailbox = buf_pool_get();
821 struct Buffer *token = buf_pool_get();
823
824 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
825 while (MoreArgs(line))
826 {
827 bool label_set = false;
828 enum TriBool notify = TB_UNSET;
829 enum TriBool poll = TB_UNSET;
830
831 do
832 {
833 // Start by handling the options
835
836 if (mutt_str_equal(buf_string(token), "-label"))
837 {
838 if (!MoreArgs(line))
839 {
840 buf_printf(err, _("%s: too few arguments"), "mailboxes -label");
841 goto done;
842 }
843
845 label_set = true;
846 }
847 else if (mutt_str_equal(buf_string(token), "-nolabel"))
848 {
849 buf_reset(label);
850 label_set = true;
851 }
852 else if (mutt_str_equal(buf_string(token), "-notify"))
853 {
854 notify = TB_TRUE;
855 }
856 else if (mutt_str_equal(buf_string(token), "-nonotify"))
857 {
858 notify = TB_FALSE;
859 }
860 else if (mutt_str_equal(buf_string(token), "-poll"))
861 {
862 poll = TB_TRUE;
863 }
864 else if (mutt_str_equal(buf_string(token), "-nopoll"))
865 {
866 poll = TB_FALSE;
867 }
868 else if ((cmd->data & MUTT_NAMED) && !label_set)
869 {
870 if (!MoreArgs(line))
871 {
872 buf_printf(err, _("%s: too few arguments"), cmd->name);
873 goto done;
874 }
875
876 buf_copy(label, token);
877 label_set = true;
878 }
879 else
880 {
881 buf_copy(mailbox, token);
882 break;
883 }
884 } while (MoreArgs(line));
885
886 if (buf_is_empty(mailbox))
887 {
888 buf_printf(err, _("%s: too few arguments"), cmd->name);
889 goto done;
890 }
891
892 rc = mailbox_add(c_folder, buf_string(mailbox),
893 label_set ? buf_string(label) : NULL, poll, notify, err);
894 if (rc != MUTT_CMD_SUCCESS)
895 goto done;
896
897 buf_reset(label);
898 buf_reset(mailbox);
899 }
900
901 rc = MUTT_CMD_SUCCESS;
902
903done:
904 buf_pool_release(&label);
905 buf_pool_release(&mailbox);
906 buf_pool_release(&token);
907 return rc;
908}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition buffer.c:601
static enum CommandResult mailbox_add(const char *folder, const char *mailbox, const char *label, enum TriBool poll, enum TriBool notify, struct Buffer *err)
Add a new Mailbox.
Definition commands.c:692
TriBool
Tri-state boolean.
Definition commands.c:85
@ TB_FALSE
Value is false.
Definition commands.c:87
@ TB_TRUE
Value is true.
Definition commands.c:88
@ TB_UNSET
Value hasn't been set.
Definition commands.c:86
#define MUTT_NAMED
Definition commands.h:36
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
+ Here is the call graph for this function:

◆ parse_my_hdr()

enum CommandResult parse_my_hdr ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • my_hdr <string>

Definition at line 916 of file commands.c.

918{
919 if (!MoreArgs(line))
920 {
921 buf_printf(err, _("%s: too few arguments"), cmd->name);
922 return MUTT_CMD_WARNING;
923 }
924
925 struct Buffer *token = buf_pool_get();
927
929 char *p = strpbrk(buf_string(token), ": \t");
930 if (!p || (*p != ':'))
931 {
932 buf_strcpy(err, _("invalid header field"));
933 goto done;
934 }
935
936 struct EventHeader ev_h = { token->data };
937 struct ListNode *node = header_find(&UserHeader, buf_string(token));
938
939 if (node)
940 {
941 header_update(node, buf_string(token));
942 mutt_debug(LL_NOTIFY, "NT_HEADER_CHANGE: %s\n", buf_string(token));
944 }
945 else
946 {
948 mutt_debug(LL_NOTIFY, "NT_HEADER_ADD: %s\n", buf_string(token));
950 }
951
952 rc = MUTT_CMD_SUCCESS;
953
954done:
955 buf_pool_release(&token);
956 return rc;
957}
struct ListNode * header_add(struct ListHead *hdrlist, const char *header)
Add a header to a list.
Definition email.c:160
struct ListNode * header_update(struct ListNode *hdr, const char *header)
Update an existing header.
Definition email.c:174
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:137
@ NT_HEADER_CHANGE
An existing header has been changed.
Definition email.h:210
@ NT_HEADER_ADD
Header has been added.
Definition email.h:208
struct ListHead UserHeader
List of custom headers to add to outgoing emails.
Definition globals.c:49
@ NT_HEADER
A header has changed, NotifyHeader EventHeader.
Definition notify_type.h:47
An event that happened to a header.
Definition email.h:217
A List node for strings.
Definition list.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_setenv()

enum CommandResult parse_setenv ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • setenv { <variable>? | <variable> <value> }
  • unsetenv <variable>

Definition at line 1019 of file commands.c.

1021{
1022 struct Buffer *token = buf_pool_get();
1023 struct Buffer *tempfile = NULL;
1025
1026 char **envp = NeoMutt->env;
1027
1028 bool query = false;
1029 bool prefix = false;
1030 bool unset = (cmd->data == MUTT_SET_UNSET);
1031
1032 if (!MoreArgs(line))
1033 {
1034 if (!StartupComplete)
1035 {
1036 buf_printf(err, _("%s: too few arguments"), cmd->name);
1037 goto done;
1038 }
1039
1040 tempfile = buf_pool_get();
1041 buf_mktemp(tempfile);
1042
1043 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
1044 if (!fp_out)
1045 {
1046 // L10N: '%s' is the file name of the temporary file
1047 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
1048 rc = MUTT_CMD_ERROR;
1049 goto done;
1050 }
1051
1052 int count = 0;
1053 for (char **env = NeoMutt->env; *env; env++)
1054 count++;
1055
1056 mutt_qsort_r(NeoMutt->env, count, sizeof(char *), envlist_sort, NULL);
1057
1058 for (char **env = NeoMutt->env; *env; env++)
1059 fprintf(fp_out, "%s\n", *env);
1060
1061 mutt_file_fclose(&fp_out);
1062
1063 struct PagerData pdata = { 0 };
1064 struct PagerView pview = { &pdata };
1065
1066 pdata.fname = buf_string(tempfile);
1067
1068 pview.banner = cmd->name;
1069 pview.flags = MUTT_PAGER_NO_FLAGS;
1070 pview.mode = PAGER_MODE_OTHER;
1071
1072 mutt_do_pager(&pview, NULL);
1073
1074 rc = MUTT_CMD_SUCCESS;
1075 goto done;
1076 }
1077
1078 if (*line->dptr == '?')
1079 {
1080 query = true;
1081 prefix = true;
1082
1083 if (unset)
1084 {
1085 buf_printf(err, _("Can't query option with the '%s' command"), cmd->name);
1086 goto done;
1087 }
1088
1089 line->dptr++;
1090 }
1091
1092 /* get variable name */
1094
1095 if (*line->dptr == '?')
1096 {
1097 if (unset)
1098 {
1099 buf_printf(err, _("Can't query option with the '%s' command"), cmd->name);
1100 goto done;
1101 }
1102
1103 if (prefix)
1104 {
1105 buf_printf(err, _("Can't use a prefix when querying a variable"));
1106 goto done;
1107 }
1108
1109 query = true;
1110 line->dptr++;
1111 }
1112
1113 if (query)
1114 {
1115 bool found = false;
1116 while (envp && *envp)
1117 {
1118 /* This will display all matches for "^QUERY" */
1119 if (mutt_str_startswith(*envp, buf_string(token)))
1120 {
1121 if (!found)
1122 {
1123 mutt_endwin();
1124 found = true;
1125 }
1126 puts(*envp);
1127 }
1128 envp++;
1129 }
1130
1131 if (found)
1132 {
1134 rc = MUTT_CMD_SUCCESS;
1135 goto done;
1136 }
1137
1138 buf_printf(err, _("%s is unset"), buf_string(token));
1139 goto done;
1140 }
1141
1142 if (unset)
1143 {
1144 if (envlist_unset(&NeoMutt->env, buf_string(token)))
1145 rc = MUTT_CMD_SUCCESS;
1146 else
1147 buf_printf(err, _("%s is unset"), buf_string(token));
1148
1149 goto done;
1150 }
1151
1152 /* set variable */
1153
1154 if (*line->dptr == '=')
1155 {
1156 line->dptr++;
1157 SKIPWS(line->dptr);
1158 }
1159
1160 if (!MoreArgs(line))
1161 {
1162 buf_printf(err, _("%s: too few arguments"), cmd->name);
1163 goto done;
1164 }
1165
1166 char *varname = mutt_str_dup(buf_string(token));
1167 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1168 envlist_set(&NeoMutt->env, varname, buf_string(token), true);
1169 FREE(&varname);
1170
1171 rc = MUTT_CMD_SUCCESS;
1172
1173done:
1174 buf_pool_release(&token);
1175 buf_pool_release(&tempfile);
1176 return rc;
1177}
bool StartupComplete
When the config has been read.
Definition address.c:13
int mutt_do_pager(struct PagerView *pview, struct Email *e)
Display some page-able text to the user (help or attachment)
Definition do_pager.c:122
bool envlist_set(char ***envp, const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition envlist.c:88
bool envlist_unset(char ***envp, const char *name)
Unset an environment variable.
Definition envlist.c:136
#define TOKEN_EQUAL
Treat '=' as a special.
Definition extract.h:45
#define TOKEN_QUESTION
Treat '?' as a special.
Definition extract.h:54
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
static int envlist_sort(const void *a, const void *b, void *sdata)
Compare two environment strings - Implements sort_t -.
Definition commands.c:1007
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition string.c:232
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition lib.h:60
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition lib.h:140
@ MUTT_SET_UNSET
default is to unset all vars
Definition set.h:37
void mutt_qsort_r(void *base, size_t nmemb, size_t size, sort_t compar, void *sdata)
Sort an array, where the comparator has access to opaque data rather than requiring global variables.
Definition qsort_r.c:67
#define SKIPWS(ch)
Definition string2.h:51
char ** env
Private copy of the environment variables.
Definition neomutt.h:56
Data to be displayed by PagerView.
Definition lib.h:159
const char * fname
Name of the file to read.
Definition lib.h:163
Paged view into some data.
Definition lib.h:170
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition lib.h:171
enum PagerMode mode
Pager mode.
Definition lib.h:172
PagerFlags flags
Additional settings to tweak pager's function.
Definition lib.h:173
const char * banner
Title to display in status bar.
Definition lib.h:174
#define buf_mktemp(buf)
Definition tmp.h:33
+ Here is the call graph for this function:

◆ parse_source()

enum CommandResult parse_source ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • source <filename>

Definition at line 1185 of file commands.c.

1187{
1188 if (!MoreArgs(line))
1189 {
1190 buf_printf(err, _("%s: too few arguments"), cmd->name);
1191 return MUTT_CMD_WARNING;
1192 }
1193
1194 struct Buffer *token = buf_pool_get();
1195 struct Buffer *path = buf_pool_get();
1196 enum CommandResult rc = MUTT_CMD_ERROR;
1197
1198 do
1199 {
1200 if (parse_extract_token(token, line, TOKEN_BACKTICK_VARS) != 0)
1201 {
1202 buf_printf(err, _("source: error at %s"), line->dptr);
1203 goto done;
1204 }
1205 buf_copy(path, token);
1206 buf_expand_path(path);
1207
1208 if (source_rc(buf_string(path), err) < 0)
1209 {
1210 buf_printf(err, _("source: file %s could not be sourced"), buf_string(path));
1211 goto done;
1212 }
1213
1214 } while (MoreArgs(line));
1215
1216 rc = MUTT_CMD_SUCCESS;
1217
1218done:
1219 buf_pool_release(&path);
1220 buf_pool_release(&token);
1221 return rc;
1222}
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
Definition commands.c:223
#define TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition extract.h:52
+ Here is the call graph for this function:

◆ parse_nospam()

enum CommandResult parse_nospam ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • nospam { * | <regex> }

Definition at line 1230 of file commands.c.

1232{
1233 if (!MoreArgs(line))
1234 {
1235 buf_printf(err, _("%s: too few arguments"), cmd->name);
1236 return MUTT_CMD_WARNING;
1237 }
1238
1239 struct Buffer *token = buf_pool_get();
1241
1242 // Extract the first token, a regex or "*"
1243 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1244
1245 if (MoreArgs(line))
1246 {
1247 buf_printf(err, _("%s: too many arguments"), cmd->name);
1248 goto done;
1249 }
1250
1251 // "*" is special - clear both spam and nospam lists
1252 if (mutt_str_equal(buf_string(token), "*"))
1253 {
1256 rc = MUTT_CMD_SUCCESS;
1257 goto done;
1258 }
1259
1260 // If it's on the spam list, just remove it
1261 if (mutt_replacelist_remove(&SpamList, buf_string(token)) != 0)
1262 {
1263 rc = MUTT_CMD_SUCCESS;
1264 goto done;
1265 }
1266
1267 // Otherwise, add it to the nospam list
1268 if (mutt_regexlist_add(&NoSpamList, buf_string(token), REG_ICASE, err) != 0)
1269 {
1270 rc = MUTT_CMD_ERROR;
1271 goto done;
1272 }
1273
1274 rc = MUTT_CMD_SUCCESS;
1275
1276done:
1277 buf_pool_release(&token);
1278 return rc;
1279}
struct ReplaceList SpamList
List of regexes to match subscribed mailing lists.
Definition globals.c:46
struct RegexList NoSpamList
List of regexes and patterns to match spam emails.
Definition globals.c:44
int mutt_replacelist_remove(struct ReplaceList *rl, const char *pat)
Remove a pattern from a list.
Definition regex.c:565
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition regex.c:178
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition regex.c:449
+ Here is the call graph for this function:

◆ parse_spam()

enum CommandResult parse_spam ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • spam <regex> <format>

Definition at line 1287 of file commands.c.

1289{
1290 if (!MoreArgs(line))
1291 {
1292 buf_printf(err, _("%s: too few arguments"), cmd->name);
1293 return MUTT_CMD_WARNING;
1294 }
1295
1296 struct Buffer *token = buf_pool_get();
1297 struct Buffer *templ = NULL;
1298 enum CommandResult rc = MUTT_CMD_ERROR;
1299
1300 // Extract the first token, a regex
1301 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1302
1303 // If there's a second parameter, it's a template for the spam tag
1304 if (MoreArgs(line))
1305 {
1306 templ = buf_pool_get();
1307 parse_extract_token(templ, line, TOKEN_NO_FLAGS);
1308
1309 // Add to the spam list
1310 if (mutt_replacelist_add(&SpamList, buf_string(token), buf_string(templ), err) != 0)
1311 goto done;
1312 }
1313 else
1314 {
1315 // If not, try to remove from the nospam list
1317 }
1318
1319 rc = MUTT_CMD_SUCCESS;
1320
1321done:
1322 buf_pool_release(&templ);
1323 buf_pool_release(&token);
1324 return rc;
1325}
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:270
+ Here is the call graph for this function:

◆ parse_stailq()

enum CommandResult parse_stailq ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • alternative_order <mime-type>[/<mime-subtype> ] [ <mime-type>[/<mime-subtype> ] ... ]
  • auto_view <mime-type>[/<mime-subtype> ] [ <mime-type>[/<mime-subtype> ] ... ]
  • hdr_order <header> [ <header> ... ]
  • mailto_allow { * | <header-field> ... }
  • mime_lookup <mime-type>[/<mime-subtype> ] [ <mime-type>[/<mime-subtype> ] ... ]

Definition at line 1337 of file commands.c.

1339{
1340 if (!MoreArgs(line))
1341 {
1342 buf_printf(err, _("%s: too few arguments"), cmd->name);
1343 return MUTT_CMD_WARNING;
1344 }
1345
1346 struct Buffer *token = buf_pool_get();
1347
1348 do
1349 {
1350 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1351 add_to_stailq((struct ListHead *) cmd->data, buf_string(token));
1352 } while (MoreArgs(line));
1353
1354 buf_pool_release(&token);
1355 return MUTT_CMD_SUCCESS;
1356}
+ Here is the call graph for this function:

◆ parse_subscribe()

enum CommandResult parse_subscribe ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • subscribe [ -group <name> ... ] <regex> [ <regex> ... ]

Definition at line 1364 of file commands.c.

1366{
1367 if (!MoreArgs(line))
1368 {
1369 buf_printf(err, _("%s: too few arguments"), cmd->name);
1370 return MUTT_CMD_WARNING;
1371 }
1372
1373 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
1374 struct Buffer *token = buf_pool_get();
1375 enum CommandResult rc = MUTT_CMD_ERROR;
1376
1377 do
1378 {
1379 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1380
1381 if (parse_grouplist(&gl, token, line, err, NeoMutt->groups) == -1)
1382 goto done;
1383
1386
1387 if (mutt_regexlist_add(&MailLists, buf_string(token), REG_ICASE, err) != 0)
1388 goto done;
1389
1390 if (mutt_regexlist_add(&SubscribedLists, buf_string(token), REG_ICASE, err) != 0)
1391 goto done;
1392
1393 if (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0)
1394 goto done;
1395 } while (MoreArgs(line));
1396
1397 rc = MUTT_CMD_SUCCESS;
1398
1399done:
1400 buf_pool_release(&token);
1401 grouplist_destroy(&gl);
1402 return rc;
1403}
struct RegexList SubscribedLists
List of header patterns to unignore (see)
Definition globals.c:48
struct RegexList UnSubscribedLists
Definition globals.c:54
+ Here is the call graph for this function:

◆ parse_subscribe_to()

enum CommandResult parse_subscribe_to ( const struct Command * cmd,
struct Buffer * line,
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.

Parse:

  • subscribe-to <imap-folder-uri>

Definition at line 1414 of file commands.c.

1416{
1417 if (!MoreArgs(line))
1418 {
1419 buf_printf(err, _("%s: too few arguments"), cmd->name);
1420 return MUTT_CMD_WARNING;
1421 }
1422
1423 struct Buffer *token = buf_pool_get();
1425
1426 buf_reset(err);
1427
1428 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1429
1430 if (MoreArgs(line))
1431 {
1432 buf_printf(err, _("%s: too many arguments"), cmd->name);
1433 goto done;
1434 }
1435
1436 // Expand and subscribe
1437 buf_expand_path(token);
1438 if (imap_subscribe(buf_string(token), true) != 0)
1439 {
1440 buf_printf(err, _("Could not subscribe to %s"), buf_string(token));
1441 rc = MUTT_CMD_ERROR;
1442 goto done;
1443 }
1444
1445 mutt_message(_("Subscribed to %s"), buf_string(token));
1446 rc = MUTT_CMD_SUCCESS;
1447
1448done:
1449 buf_pool_release(&token);
1450 return rc;
1451}
int imap_subscribe(const char *path, bool subscribe)
Subscribe to a mailbox.
Definition imap.c:1245
+ Here is the call graph for this function:

◆ parse_tag_formats()

enum CommandResult parse_tag_formats ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse config like: tag-formats pgp GP

Note
This maps format -> tag

Parse:

  • tag-formats <tag> <format-string> { tag format-string ... }

Definition at line 1463 of file commands.c.

1465{
1466 if (!MoreArgs(line))
1467 {
1468 buf_printf(err, _("%s: too few arguments"), cmd->name);
1469 return MUTT_CMD_WARNING;
1470 }
1471
1472 struct Buffer *tag = buf_pool_get();
1473 struct Buffer *fmt = buf_pool_get();
1474
1475 while (MoreArgs(line))
1476 {
1478 if (buf_is_empty(tag))
1479 continue;
1480
1482
1483 /* avoid duplicates */
1484 const char *tmp = mutt_hash_find(TagFormats, buf_string(fmt));
1485 if (tmp)
1486 {
1487 mutt_warning(_("tag format '%s' already registered as '%s'"), buf_string(fmt), tmp);
1488 continue;
1489 }
1490
1492 }
1493
1494 buf_pool_release(&tag);
1495 buf_pool_release(&fmt);
1496 return MUTT_CMD_SUCCESS;
1497}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
#define mutt_warning(...)
Definition logging2.h:91
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
struct HashTable * TagFormats
Hash Table: "inbox" -> "GI" - Tag format strings.
Definition tags.c:42
+ Here is the call graph for this function:

◆ parse_tag_transforms()

enum CommandResult parse_tag_transforms ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse config like: tag-transforms pgp P

Note
This maps tag -> transform

Parse:

  • tag-transforms <tag> <transformed-string> { tag transformed-string ... }

Definition at line 1509 of file commands.c.

1511{
1512 if (!MoreArgs(line))
1513 {
1514 buf_printf(err, _("%s: too few arguments"), cmd->name);
1515 return MUTT_CMD_WARNING;
1516 }
1517
1518 struct Buffer *tag = buf_pool_get();
1519 struct Buffer *trnbuf = buf_pool_get();
1520
1521 while (MoreArgs(line))
1522 {
1524 if (buf_is_empty(tag))
1525 continue;
1526
1527 parse_extract_token(trnbuf, line, TOKEN_NO_FLAGS);
1528 const char *trn = buf_string(trnbuf);
1529
1530 /* avoid duplicates */
1531 const char *tmp = mutt_hash_find(TagTransforms, buf_string(tag));
1532 if (tmp)
1533 {
1534 mutt_warning(_("tag transform '%s' already registered as '%s'"),
1535 buf_string(tag), tmp);
1536 continue;
1537 }
1538
1540 }
1541
1542 buf_pool_release(&tag);
1543 buf_pool_release(&trnbuf);
1544 return MUTT_CMD_SUCCESS;
1545}
struct HashTable * TagTransforms
Hash Table: "inbox" -> "i" - Alternative tag names.
Definition tags.c:41
+ Here is the call graph for this function:

◆ parse_unignore()

enum CommandResult parse_unignore ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unignore { * | <string> ... }

Definition at line 1553 of file commands.c.

1555{
1556 if (!MoreArgs(line))
1557 {
1558 buf_printf(err, _("%s: too few arguments"), cmd->name);
1559 return MUTT_CMD_WARNING;
1560 }
1561
1562 struct Buffer *token = buf_pool_get();
1563
1564 do
1565 {
1566 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1567
1568 /* don't add "*" to the unignore list */
1569 if (!mutt_str_equal(buf_string(token), "*"))
1571
1573 } while (MoreArgs(line));
1574
1575 buf_pool_release(&token);
1576 return MUTT_CMD_SUCCESS;
1577}
+ Here is the call graph for this function:

◆ parse_unlists()

enum CommandResult parse_unlists ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unlists [ -group <name> ... ] { * | <regex> ... }

Definition at line 1585 of file commands.c.

1587{
1588 if (!MoreArgs(line))
1589 {
1590 buf_printf(err, _("%s: too few arguments"), cmd->name);
1591 return MUTT_CMD_WARNING;
1592 }
1593
1594 struct Buffer *token = buf_pool_get();
1595 enum CommandResult rc = MUTT_CMD_ERROR;
1596
1598 do
1599 {
1600 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1603
1604 if (!mutt_str_equal(buf_string(token), "*") &&
1605 (mutt_regexlist_add(&UnMailLists, buf_string(token), REG_ICASE, err) != 0))
1606 {
1607 goto done;
1608 }
1609 } while (MoreArgs(line));
1610
1611 rc = MUTT_CMD_SUCCESS;
1612
1613done:
1614 buf_pool_release(&token);
1615 return rc;
1616}
struct HashTable * AutoSubscribeCache
< Hash Table: "mailto:" -> AutoSubscribeCache
Definition globals.c:36
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 ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unmailboxes { * | <mailbox> ... }

Definition at line 1664 of file commands.c.

1666{
1667 if (!MoreArgs(line))
1668 {
1669 buf_printf(err, _("%s: too few arguments"), cmd->name);
1670 return MUTT_CMD_WARNING;
1671 }
1672
1673 struct Buffer *token = buf_pool_get();
1674
1675 while (MoreArgs(line))
1676 {
1677 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1678
1679 if (mutt_str_equal(buf_string(token), "*"))
1680 {
1682 goto done;
1683 }
1684
1685 buf_expand_path(token);
1686
1687 struct Account **ap = NULL;
1689 {
1690 struct Mailbox *m = mx_mbox_find(*ap, buf_string(token));
1691 if (m)
1692 {
1693 do_unmailboxes(m);
1694 break;
1695 }
1696 }
1697 }
1698
1699done:
1700 buf_pool_release(&token);
1701 return MUTT_CMD_SUCCESS;
1702}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:214
static void do_unmailboxes_star(void)
Remove all Mailboxes from the Sidebar/notifications.
Definition commands.c:1646
static void do_unmailboxes(struct Mailbox *m)
Remove a Mailbox from the Sidebar/notifications.
Definition commands.c:1622
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition mx.c:1549
A group of associated Mailboxes.
Definition account.h:36
A mailbox.
Definition mailbox.h:79
struct AccountArray accounts
All Accounts.
Definition neomutt.h:48
+ Here is the call graph for this function:

◆ parse_unmy_hdr()

enum CommandResult parse_unmy_hdr ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unmy_hdr { * | <field> ... }

Definition at line 1710 of file commands.c.

1712{
1713 if (!MoreArgs(line))
1714 {
1715 buf_printf(err, _("%s: too few arguments"), cmd->name);
1716 return MUTT_CMD_WARNING;
1717 }
1718
1719 struct Buffer *token = buf_pool_get();
1720
1721 struct ListNode *np = NULL, *tmp = NULL;
1722 size_t l;
1723
1724 do
1725 {
1726 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1727 if (mutt_str_equal("*", buf_string(token)))
1728 {
1729 /* Clear all headers, send a notification for each header */
1730 STAILQ_FOREACH(np, &UserHeader, entries)
1731 {
1732 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1733 struct EventHeader ev_h = { np->data };
1735 }
1737 continue;
1738 }
1739
1740 l = mutt_str_len(buf_string(token));
1741 if (buf_at(token, l - 1) == ':')
1742 l--;
1743
1744 STAILQ_FOREACH_SAFE(np, &UserHeader, entries, tmp)
1745 {
1746 if (mutt_istrn_equal(buf_string(token), np->data, l) && (np->data[l] == ':'))
1747 {
1748 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1749 struct EventHeader ev_h = { np->data };
1751
1752 header_free(&UserHeader, np);
1753 }
1754 }
1755 } while (MoreArgs(line));
1756 buf_pool_release(&token);
1757 return MUTT_CMD_SUCCESS;
1758}
char buf_at(const struct Buffer *buf, size_t offset)
Return the character at the given offset.
Definition buffer.c:668
void header_free(struct ListHead *hdrlist, struct ListNode *target)
Free and remove a header from a header list.
Definition email.c:202
@ NT_HEADER_DELETE
Header has been removed.
Definition email.h:209
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition list.c:123
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:498
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:455
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
char * data
String.
Definition list.h:38
+ Here is the call graph for this function:

◆ parse_unstailq()

enum CommandResult parse_unstailq ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unalternative_order { * | [ <mime-type>[/<mime-subtype> ] ... ] }
  • unauto_view { * | [ <mime-type>[/<mime-subtype> ] ... ] }
  • unhdr_order { * | <header> ... }
  • unmailto_allow { * | <header-field> ... }
  • unmime_lookup { * | [ <mime-type>[/<mime-subtype> ] ... ] }

Definition at line 1770 of file commands.c.

1772{
1773 if (!MoreArgs(line))
1774 {
1775 buf_printf(err, _("%s: too few arguments"), cmd->name);
1776 return MUTT_CMD_WARNING;
1777 }
1778
1779 struct Buffer *token = buf_pool_get();
1780
1781 do
1782 {
1783 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1784 /* Check for deletion of entire list */
1785 if (mutt_str_equal(buf_string(token), "*"))
1786 {
1787 mutt_list_free((struct ListHead *) cmd->data);
1788 break;
1789 }
1790 remove_from_stailq((struct ListHead *) cmd->data, buf_string(token));
1791 } while (MoreArgs(line));
1792
1793 buf_pool_release(&token);
1794 return MUTT_CMD_SUCCESS;
1795}
+ Here is the call graph for this function:

◆ parse_unsubscribe()

enum CommandResult parse_unsubscribe ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unsubscribe [ -group <name> ... ] { * | <regex> ... }

Definition at line 1803 of file commands.c.

1805{
1806 if (!MoreArgs(line))
1807 {
1808 buf_printf(err, _("%s: too few arguments"), cmd->name);
1809 return MUTT_CMD_WARNING;
1810 }
1811
1812 struct Buffer *token = buf_pool_get();
1813 enum CommandResult rc = MUTT_CMD_ERROR;
1814
1816 do
1817 {
1818 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1820
1821 if (!mutt_str_equal(buf_string(token), "*") &&
1822 (mutt_regexlist_add(&UnSubscribedLists, buf_string(token), REG_ICASE, err) != 0))
1823 {
1824 goto done;
1825 }
1826 } while (MoreArgs(line));
1827
1828 rc = MUTT_CMD_SUCCESS;
1829
1830done:
1831 buf_pool_release(&token);
1832 return rc;
1833}
+ Here is the call graph for this function:

◆ parse_unsubscribe_from()

enum CommandResult parse_unsubscribe_from ( const struct Command * cmd,
struct Buffer * line,
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.

Parse:

  • unsubscribe-from <imap-folder-uri>

Definition at line 1844 of file commands.c.

1846{
1847 if (!MoreArgs(line))
1848 {
1849 buf_printf(err, _("%s: too few arguments"), cmd->name);
1850 return MUTT_CMD_WARNING;
1851 }
1852
1853 struct Buffer *token = buf_pool_get();
1855
1856 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1857
1858 if (MoreArgs(line))
1859 {
1860 buf_printf(err, _("%s: too many arguments"), cmd->name);
1861 goto done;
1862 }
1863
1864 // Expand and unsubscribe
1865 buf_expand_path(token);
1866 if (imap_subscribe(buf_string(token), false) != 0)
1867 {
1868 buf_printf(err, _("Could not unsubscribe from %s"), buf_string(token));
1869 rc = MUTT_CMD_ERROR;
1870 goto done;
1871 }
1872
1873 mutt_message(_("Unsubscribed from %s"), buf_string(token));
1874 rc = MUTT_CMD_SUCCESS;
1875
1876done:
1877 buf_pool_release(&token);
1878 return rc;
1879}
+ Here is the call graph for this function:

◆ parse_version()

enum CommandResult parse_version ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • version

Definition at line 1887 of file commands.c.

1889{
1890 // silently ignore 'version' if it's in a config file
1891 if (!StartupComplete)
1892 return MUTT_CMD_SUCCESS;
1893
1894 if (MoreArgs(line))
1895 {
1896 buf_printf(err, _("%s: too many arguments"), cmd->name);
1897 return MUTT_CMD_WARNING;
1898 }
1899
1900 struct Buffer *tempfile = buf_pool_get();
1901 enum CommandResult rc = MUTT_CMD_ERROR;
1902
1903 buf_mktemp(tempfile);
1904
1905 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
1906 if (!fp_out)
1907 {
1908 // L10N: '%s' is the file name of the temporary file
1909 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
1910 goto done;
1911 }
1912
1913 print_version(fp_out, false);
1914 mutt_file_fclose(&fp_out);
1915
1916 struct PagerData pdata = { 0 };
1917 struct PagerView pview = { &pdata };
1918
1919 pdata.fname = buf_string(tempfile);
1920
1921 pview.banner = cmd->name;
1922 pview.flags = MUTT_PAGER_NO_FLAGS;
1923 pview.mode = PAGER_MODE_OTHER;
1924
1925 mutt_do_pager(&pview, NULL);
1926 rc = MUTT_CMD_SUCCESS;
1927
1928done:
1929 buf_pool_release(&tempfile);
1930 return rc;
1931}
bool print_version(FILE *fp, bool use_ansi)
Print system and compile info to a file.
Definition version.c:591
+ Here is the call graph for this function:

◆ parse_hook_charset()

enum CommandResult parse_hook_charset ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • charset-hook <alias> <charset>
  • iconv-hook <charset> <local-charset>

Definition at line 126 of file hook.c.

128{
129 if (!MoreArgs(line))
130 {
131 buf_printf(err, _("%s: too few arguments"), cmd->name);
132 return MUTT_CMD_WARNING;
133 }
134
135 struct Buffer *alias = buf_pool_get();
136 struct Buffer *charset = buf_pool_get();
138
139 if (parse_extract_token(alias, line, TOKEN_NO_FLAGS) < 0)
140 goto done;
141 if (parse_extract_token(charset, line, TOKEN_NO_FLAGS) < 0)
142 goto done;
143
144 const enum LookupType type = (cmd->data & MUTT_ICONV_HOOK) ? MUTT_LOOKUP_ICONV :
146
147 if (buf_is_empty(alias) || buf_is_empty(charset))
148 {
149 buf_printf(err, _("%s: too few arguments"), cmd->name);
150 rc = MUTT_CMD_WARNING;
151 }
152 else if (MoreArgs(line))
153 {
154 buf_printf(err, _("%s: too many arguments"), cmd->name);
155 buf_reset(line); // clean up buffer to avoid a mess with further rcfile processing
156 rc = MUTT_CMD_WARNING;
157 }
158 else if (mutt_ch_lookup_add(type, buf_string(alias), buf_string(charset), err))
159 {
160 rc = MUTT_CMD_SUCCESS;
161 }
162
163done:
164 buf_pool_release(&alias);
165 buf_pool_release(&charset);
166
167 return rc;
168}
#define MUTT_ICONV_HOOK
iconv-hook: create a system charset alias
Definition hook.h:43
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:509
LookupType
Types of character set lookups.
Definition charset.h:59
@ MUTT_LOOKUP_ICONV
Character set conversion.
Definition charset.h:61
@ MUTT_LOOKUP_CHARSET
Alias for another character set.
Definition charset.h:60
+ Here is the call graph for this function:

◆ parse_hook_global()

enum CommandResult parse_hook_global ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse global hook commands - Implements Command::parse() -.

Parse:

  • shutdown-hook <command>
  • startup-hook <command>
  • timeout-hook <command>

Definition at line 178 of file hook.c.

180{
181 struct Hook *hook = NULL;
183
184 struct Buffer *command = buf_pool_get();
185
186 // TOKEN_SPACE allows the command to contain whitespace, without quoting
187 parse_extract_token(command, line, TOKEN_SPACE);
188
189 if (buf_is_empty(command))
190 {
191 buf_printf(err, _("%s: too few arguments"), cmd->name);
192 rc = MUTT_CMD_WARNING;
193 goto cleanup;
194 }
195
196 if (MoreArgs(line))
197 {
198 buf_printf(err, _("%s: too many arguments"), cmd->name);
199 rc = MUTT_CMD_WARNING;
200 goto cleanup;
201 }
202
203 /* check to make sure that a matching hook doesn't already exist */
204 TAILQ_FOREACH(hook, &Hooks, entries)
205 {
206 /* Ignore duplicate global hooks */
207 if ((hook->type == cmd->data) && mutt_str_equal(hook->command, buf_string(command)))
208 {
209 rc = MUTT_CMD_SUCCESS;
210 goto cleanup;
211 }
212 }
213
214 hook = hook_new();
215 hook->type = cmd->data;
216 hook->command = buf_strdup(command);
218 hook->pattern = NULL;
219 hook->regex.pattern = NULL;
220 hook->regex.regex = NULL;
221 hook->regex.pat_not = false;
222 hook->expando = NULL;
223
224 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
225 rc = MUTT_CMD_SUCCESS;
226
227cleanup:
228 buf_pool_release(&command);
229 return rc;
230}
char * mutt_get_sourced_cwd(void)
Get the current file path that is being parsed.
Definition commands.c:202
static struct HookList Hooks
All simple hooks, e.g. MUTT_FOLDER_HOOK.
Definition hook.c:78
static struct Hook * hook_new(void)
Create a Hook.
Definition hook.c:114
A list of user hooks.
Definition hook.c:66
HookFlags type
Hook type.
Definition hook.c:67
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition hook.c:71
struct Regex regex
Regular expression.
Definition hook.c:68
char * command
Filename, command or pattern to execute.
Definition hook.c:69
struct Expando * expando
Used for format hooks.
Definition hook.c:72
char * source_file
Used for relative-directory source.
Definition hook.c:70
char * pattern
printable version
Definition regex3.h:87
bool pat_not
do not match
Definition regex3.h:89
regex_t * regex
compiled expression
Definition regex3.h:88
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_hook_pattern()

enum CommandResult parse_hook_pattern ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse pattern-based hook commands - Implements Command::parse() -.

Parse:

  • message-hook <pattern> <command>
  • reply-hook <pattern> <command>
  • send-hook <pattern> <command>
  • send2-hook <pattern> <command>

Definition at line 241 of file hook.c.

243{
244 struct Hook *hook = NULL;
246 bool pat_not = false;
247 struct PatternList *pat = NULL;
248
249 struct Buffer *command = buf_pool_get();
250 struct Buffer *pattern = buf_pool_get();
251
252 if (*line->dptr == '!')
253 {
254 line->dptr++;
255 SKIPWS(line->dptr);
256 pat_not = true;
257 }
258
259 parse_extract_token(pattern, line, TOKEN_NO_FLAGS);
260
261 if (!MoreArgs(line))
262 {
263 buf_printf(err, _("%s: too few arguments"), cmd->name);
264 rc = MUTT_CMD_WARNING;
265 goto cleanup;
266 }
267
268 // TOKEN_SPACE allows the command to contain whitespace, without quoting
269 parse_extract_token(command, line, TOKEN_SPACE);
270
271 if (buf_is_empty(command))
272 {
273 buf_printf(err, _("%s: too few arguments"), cmd->name);
274 rc = MUTT_CMD_WARNING;
275 goto cleanup;
276 }
277
278 if (MoreArgs(line))
279 {
280 buf_printf(err, _("%s: too many arguments"), cmd->name);
281 rc = MUTT_CMD_WARNING;
282 goto cleanup;
283 }
284
285 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
286 if (c_default_hook)
287 {
288 mutt_check_simple(pattern, c_default_hook);
289 }
290
291 /* check to make sure that a matching hook doesn't already exist */
292 TAILQ_FOREACH(hook, &Hooks, entries)
293 {
294 if ((hook->type == cmd->data) && (hook->regex.pat_not == pat_not) &&
295 mutt_str_equal(buf_string(pattern), hook->regex.pattern))
296 {
297 /* these hooks allow multiple commands with the same pattern,
298 * so if we've already seen this pattern/command pair,
299 * just ignore it instead of creating a duplicate */
300 if (mutt_str_equal(hook->command, buf_string(command)))
301 {
302 rc = MUTT_CMD_SUCCESS;
303 goto cleanup;
304 }
305 }
306 }
307
308 PatternCompFlags comp_flags;
309 if (cmd->data & MUTT_SEND2_HOOK)
310 comp_flags = MUTT_PC_SEND_MODE_SEARCH;
311 else if (cmd->data & (MUTT_SEND_HOOK))
312 comp_flags = MUTT_PC_NO_FLAGS;
313 else
314 comp_flags = MUTT_PC_FULL_MSG;
315
316 struct MailboxView *mv_cur = get_current_mailbox_view();
317 pat = mutt_pattern_comp(mv_cur, buf_string(pattern), comp_flags, err);
318 if (!pat)
319 goto cleanup;
320
321 hook = hook_new();
322 hook->type = cmd->data;
323 hook->command = buf_strdup(command);
325 hook->pattern = pat;
327 hook->regex.regex = NULL;
328 hook->regex.pat_not = pat_not;
329 hook->expando = NULL;
330
331 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
332 rc = MUTT_CMD_SUCCESS;
333
334cleanup:
335 buf_pool_release(&command);
337 return rc;
338}
struct PatternList * mutt_pattern_comp(struct MailboxView *mv, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition compile.c:902
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition hook.h:39
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition hook.h:48
struct MailboxView * get_current_mailbox_view(void)
Get the current Mailbox view.
Definition index.c:689
#define MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition lib.h:71
uint8_t PatternCompFlags
Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG.
Definition lib.h:67
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition lib.h:69
void mutt_check_simple(struct Buffer *s, const char *simple)
Convert a simple search into a real request.
Definition pattern.c:109
#define MUTT_PC_NO_FLAGS
No flags are set.
Definition lib.h:68
View of a Mailbox.
Definition mview.h:40
char * pattern
Limit pattern string.
Definition mview.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_hook_mailbox()

enum CommandResult parse_hook_mailbox ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse mailbox pattern hook commands - Implements Command::parse() -.

Parse:

  • fcc-hook <pattern> <mailbox>
  • fcc-save-hook <pattern> <mailbox>
  • save-hook <pattern> <mailbox>

Definition at line 348 of file hook.c.

350{
351 struct Hook *hook = NULL;
353 bool pat_not = false;
354 struct PatternList *pat = NULL;
355
356 struct Buffer *pattern = buf_pool_get();
357 struct Buffer *mailbox = buf_pool_get();
358
359 if (*line->dptr == '!')
360 {
361 line->dptr++;
362 SKIPWS(line->dptr);
363 pat_not = true;
364 }
365
366 parse_extract_token(pattern, line, TOKEN_NO_FLAGS);
367
368 if (!MoreArgs(line))
369 {
370 buf_printf(err, _("%s: too few arguments"), cmd->name);
371 rc = MUTT_CMD_WARNING;
372 goto cleanup;
373 }
374
375 parse_extract_token(mailbox, line, TOKEN_NO_FLAGS);
376
377 if (buf_is_empty(mailbox))
378 {
379 buf_printf(err, _("%s: too few arguments"), cmd->name);
380 rc = MUTT_CMD_WARNING;
381 goto cleanup;
382 }
383
384 if (MoreArgs(line))
385 {
386 buf_printf(err, _("%s: too many arguments"), cmd->name);
387 rc = MUTT_CMD_WARNING;
388 goto cleanup;
389 }
390
391 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
392 if (c_default_hook)
393 {
394 mutt_check_simple(pattern, c_default_hook);
395 }
396
397 buf_expand_path(mailbox);
398
399 /* check to make sure that a matching hook doesn't already exist */
400 TAILQ_FOREACH(hook, &Hooks, entries)
401 {
402 if ((hook->type == cmd->data) && (hook->regex.pat_not == pat_not) &&
403 mutt_str_equal(buf_string(pattern), hook->regex.pattern))
404 {
405 // Update an existing hook
406 FREE(&hook->command);
407 hook->command = buf_strdup(mailbox);
408 FREE(&hook->source_file);
410
411 expando_free(&hook->expando);
412 hook->expando = expando_parse(buf_string(mailbox), IndexFormatDef, err);
413
414 rc = MUTT_CMD_SUCCESS;
415 goto cleanup;
416 }
417 }
418
419 PatternCompFlags comp_flags;
420 if (cmd->data & MUTT_FCC_HOOK)
421 comp_flags = MUTT_PC_NO_FLAGS;
422 else
423 comp_flags = MUTT_PC_FULL_MSG;
424
425 struct MailboxView *mv_cur = get_current_mailbox_view();
426 pat = mutt_pattern_comp(mv_cur, buf_string(pattern), comp_flags, err);
427 if (!pat)
428 goto cleanup;
429
430 struct Expando *exp = expando_parse(buf_string(mailbox), IndexFormatDef, err);
431
432 hook = hook_new();
433 hook->type = cmd->data;
434 hook->command = buf_strdup(mailbox);
436 hook->pattern = pat;
437 hook->regex.pattern = buf_strdup(pattern);
438 hook->regex.regex = NULL;
439 hook->regex.pat_not = pat_not;
440 hook->expando = exp;
441
442 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
443 rc = MUTT_CMD_SUCCESS;
444
445cleanup:
446 buf_pool_release(&pattern);
447 buf_pool_release(&mailbox);
448 return rc;
449}
struct Expando * expando_parse(const char *str, const struct ExpandoDefinition *defs, struct Buffer *err)
Parse an Expando string.
Definition expando.c:81
void expando_free(struct Expando **ptr)
Free an Expando object.
Definition expando.c:61
const struct ExpandoDefinition IndexFormatDef[]
Expando definitions.
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition hook.h:40
Parsed Expando trees.
Definition expando.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_hook_regex()

enum CommandResult parse_hook_regex ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse regex-based hook command - Implements Command::parse() -.

Parse:

  • account-hook <regex> <command>

Definition at line 457 of file hook.c.

459{
460 struct Hook *hook = NULL;
462 bool pat_not = false;
463 regex_t *rx = NULL;
464
465 struct Buffer *regex = buf_pool_get();
466 struct Buffer *command = buf_pool_get();
467
468 if (*line->dptr == '!')
469 {
470 line->dptr++;
471 SKIPWS(line->dptr);
472 pat_not = true;
473 }
474
476
477 if (!MoreArgs(line))
478 {
479 buf_printf(err, _("%s: too few arguments"), cmd->name);
480 rc = MUTT_CMD_WARNING;
481 goto cleanup;
482 }
483
484 parse_extract_token(command, line, TOKEN_SPACE);
485
486 if (buf_is_empty(command))
487 {
488 buf_printf(err, _("%s: too few arguments"), cmd->name);
489 rc = MUTT_CMD_WARNING;
490 goto cleanup;
491 }
492
493 if (MoreArgs(line))
494 {
495 buf_printf(err, _("%s: too many arguments"), cmd->name);
496 rc = MUTT_CMD_WARNING;
497 goto cleanup;
498 }
499
500 /* check to make sure that a matching hook doesn't already exist */
501 TAILQ_FOREACH(hook, &Hooks, entries)
502 {
503 if ((hook->type == cmd->data) && (hook->regex.pat_not == pat_not) &&
504 mutt_str_equal(buf_string(regex), hook->regex.pattern))
505 {
506 // Ignore duplicate hooks
507 if (mutt_str_equal(hook->command, buf_string(command)))
508 {
509 rc = MUTT_CMD_SUCCESS;
510 goto cleanup;
511 }
512 }
513 }
514
515 /* Hooks not allowing full patterns: Check syntax of regex */
516 rx = MUTT_MEM_CALLOC(1, regex_t);
517 int rc2 = REG_COMP(rx, buf_string(regex), 0);
518 if (rc2 != 0)
519 {
520 regerror(rc2, rx, err->data, err->dsize);
521 FREE(&rx);
522 goto cleanup;
523 }
524
525 hook = hook_new();
526 hook->type = cmd->data;
527 hook->command = buf_strdup(command);
529 hook->pattern = NULL;
530 hook->regex.pattern = buf_strdup(regex);
531 hook->regex.regex = rx;
532 hook->regex.pat_not = pat_not;
533 hook->expando = NULL;
534
535 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
536 rc = MUTT_CMD_SUCCESS;
537
538cleanup:
539 buf_pool_release(&regex);
540 buf_pool_release(&command);
541 return rc;
542}
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:47
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition regex3.h:50
size_t dsize
Length of data.
Definition buffer.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_hook_folder()

enum CommandResult parse_hook_folder ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse folder hook command - Implements Command::parse() -.

Parse:

  • folder-hook [ -noregex ] <regex> <command>

Definition at line 550 of file hook.c.

552{
553 struct Hook *hook = NULL;
555 bool pat_not = false;
556 bool use_regex = true;
557 regex_t *rx = NULL;
558
559 struct Buffer *regex = buf_pool_get();
560 struct Buffer *command = buf_pool_get();
561
562 if (*line->dptr == '!')
563 {
564 line->dptr++;
565 SKIPWS(line->dptr);
566 pat_not = true;
567 }
568
570 if (mutt_str_equal(buf_string(regex), "-noregex"))
571 {
572 use_regex = false;
573 if (!MoreArgs(line))
574 {
575 buf_printf(err, _("%s: too few arguments"), cmd->name);
576 rc = MUTT_CMD_WARNING;
577 goto cleanup;
578 }
580 }
581
582 if (!MoreArgs(line))
583 {
584 buf_printf(err, _("%s: too few arguments"), cmd->name);
585 rc = MUTT_CMD_WARNING;
586 goto cleanup;
587 }
588
589 parse_extract_token(command, line, TOKEN_SPACE);
590
591 if (buf_is_empty(command))
592 {
593 buf_printf(err, _("%s: too few arguments"), cmd->name);
594 rc = MUTT_CMD_WARNING;
595 goto cleanup;
596 }
597
598 if (MoreArgs(line))
599 {
600 buf_printf(err, _("%s: too many arguments"), cmd->name);
601 rc = MUTT_CMD_WARNING;
602 goto cleanup;
603 }
604
605 /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
606 * common mistake */
607 if ((buf_at(regex, 0) == '^') && !CurrentFolder)
608 {
609 buf_strcpy(err, _("current mailbox shortcut '^' is unset"));
610 goto cleanup;
611 }
612
613 struct Buffer *tmp = buf_pool_get();
614 buf_copy(tmp, regex);
615 buf_expand_path_regex(tmp, use_regex);
616
617 /* Check for other mailbox shortcuts that expand to the empty string.
618 * This is likely a mistake too */
619 if (buf_is_empty(tmp) && !buf_is_empty(regex))
620 {
621 buf_strcpy(err, _("mailbox shortcut expanded to empty regex"));
622 buf_pool_release(&tmp);
623 goto cleanup;
624 }
625
626 if (use_regex)
627 {
628 buf_copy(regex, tmp);
629 }
630 else
631 {
633 }
634 buf_pool_release(&tmp);
635
636 /* check to make sure that a matching hook doesn't already exist */
637 TAILQ_FOREACH(hook, &Hooks, entries)
638 {
639 if ((hook->type == cmd->data) && (hook->regex.pat_not == pat_not) &&
640 mutt_str_equal(buf_string(regex), hook->regex.pattern))
641 {
642 // Ignore duplicate hooks
643 if (mutt_str_equal(hook->command, buf_string(command)))
644 {
645 rc = MUTT_CMD_SUCCESS;
646 goto cleanup;
647 }
648 }
649 }
650
651 /* Hooks not allowing full patterns: Check syntax of regex */
652 rx = MUTT_MEM_CALLOC(1, regex_t);
653 int rc2 = REG_COMP(rx, buf_string(regex), 0);
654 if (rc2 != 0)
655 {
656 regerror(rc2, rx, err->data, err->dsize);
657 FREE(&rx);
658 goto cleanup;
659 }
660
661 hook = hook_new();
662 hook->type = cmd->data;
663 hook->command = buf_strdup(command);
665 hook->pattern = NULL;
666 hook->regex.pattern = buf_strdup(regex);
667 hook->regex.regex = rx;
668 hook->regex.pat_not = pat_not;
669 hook->expando = NULL;
670
671 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
672 rc = MUTT_CMD_SUCCESS;
673
674cleanup:
675 buf_pool_release(&regex);
676 buf_pool_release(&command);
677 return rc;
678}
int mutt_file_sanitize_regex(struct Buffer *dest, const char *src)
Escape any regex-magic characters in a string.
Definition file.c:631
char * CurrentFolder
Currently selected mailbox.
Definition globals.c:39
void buf_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition muttlib.c:121
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_hook_crypt()

enum CommandResult parse_hook_crypt ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse crypt hook commands - Implements Command::parse() -.

Parse:

  • crypt-hook <regex> <keyid>
  • pgp-hook is a deprecated synonym for crypt-hook

Definition at line 687 of file hook.c.

689{
690 struct Hook *hook = NULL;
692 bool pat_not = false;
693 regex_t *rx = NULL;
694
695 struct Buffer *regex = buf_pool_get();
696 struct Buffer *keyid = buf_pool_get();
697
698 if (*line->dptr == '!')
699 {
700 line->dptr++;
701 SKIPWS(line->dptr);
702 pat_not = true;
703 }
704
706
707 if (!MoreArgs(line))
708 {
709 buf_printf(err, _("%s: too few arguments"), cmd->name);
710 rc = MUTT_CMD_WARNING;
711 goto cleanup;
712 }
713
715
716 if (buf_is_empty(keyid))
717 {
718 buf_printf(err, _("%s: too few arguments"), cmd->name);
719 rc = MUTT_CMD_WARNING;
720 goto cleanup;
721 }
722
723 if (MoreArgs(line))
724 {
725 buf_printf(err, _("%s: too many arguments"), cmd->name);
726 rc = MUTT_CMD_WARNING;
727 goto cleanup;
728 }
729
730 /* check to make sure that a matching hook doesn't already exist */
731 TAILQ_FOREACH(hook, &Hooks, entries)
732 {
733 if ((hook->type == cmd->data) && (hook->regex.pat_not == pat_not) &&
734 mutt_str_equal(buf_string(regex), hook->regex.pattern))
735 {
736 // Ignore duplicate hooks
737 if (mutt_str_equal(hook->command, buf_string(keyid)))
738 {
739 rc = MUTT_CMD_SUCCESS;
740 goto cleanup;
741 }
742 }
743 }
744
745 /* Hooks not allowing full patterns: Check syntax of regex */
746 rx = MUTT_MEM_CALLOC(1, regex_t);
747 int rc2 = REG_COMP(rx, buf_string(regex), REG_ICASE);
748 if (rc2 != 0)
749 {
750 regerror(rc2, rx, err->data, err->dsize);
751 FREE(&rx);
752 goto cleanup;
753 }
754
755 hook = hook_new();
756 hook->type = cmd->data;
757 hook->command = buf_strdup(keyid);
759 hook->pattern = NULL;
760 hook->regex.pattern = buf_strdup(regex);
761 hook->regex.regex = rx;
762 hook->regex.pat_not = pat_not;
763 hook->expando = NULL;
764
765 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
766 rc = MUTT_CMD_SUCCESS;
767
768cleanup:
769 buf_pool_release(&regex);
770 buf_pool_release(&keyid);
771 return rc;
772}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_hook_mbox()

enum CommandResult parse_hook_mbox ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse mbox hook command - Implements Command::parse() -.

Parse:

  • mbox-hook [ -noregex ] <regex> <mailbox>

Definition at line 780 of file hook.c.

782{
783 struct Hook *hook = NULL;
785 bool pat_not = false;
786 bool use_regex = true;
787 regex_t *rx = NULL;
788
789 struct Buffer *regex = buf_pool_get();
790 struct Buffer *command = buf_pool_get();
791
792 if (*line->dptr == '!')
793 {
794 line->dptr++;
795 SKIPWS(line->dptr);
796 pat_not = true;
797 }
798
800 if (mutt_str_equal(buf_string(regex), "-noregex"))
801 {
802 use_regex = false;
803 if (!MoreArgs(line))
804 {
805 buf_printf(err, _("%s: too few arguments"), cmd->name);
806 rc = MUTT_CMD_WARNING;
807 goto cleanup;
808 }
810 }
811
812 if (!MoreArgs(line))
813 {
814 buf_printf(err, _("%s: too few arguments"), cmd->name);
815 rc = MUTT_CMD_WARNING;
816 goto cleanup;
817 }
818
819 parse_extract_token(command, line, TOKEN_NO_FLAGS);
820
821 if (buf_is_empty(command))
822 {
823 buf_printf(err, _("%s: too few arguments"), cmd->name);
824 rc = MUTT_CMD_WARNING;
825 goto cleanup;
826 }
827
828 if (MoreArgs(line))
829 {
830 buf_printf(err, _("%s: too many arguments"), cmd->name);
831 rc = MUTT_CMD_WARNING;
832 goto cleanup;
833 }
834
835 /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
836 * common mistake */
837 if ((buf_at(regex, 0) == '^') && !CurrentFolder)
838 {
839 buf_strcpy(err, _("current mailbox shortcut '^' is unset"));
840 goto cleanup;
841 }
842
843 struct Buffer *tmp = buf_pool_get();
844 buf_copy(tmp, regex);
845 buf_expand_path_regex(tmp, use_regex);
846
847 /* Check for other mailbox shortcuts that expand to the empty string.
848 * This is likely a mistake too */
849 if (buf_is_empty(tmp) && !buf_is_empty(regex))
850 {
851 buf_strcpy(err, _("mailbox shortcut expanded to empty regex"));
852 buf_pool_release(&tmp);
853 goto cleanup;
854 }
855
856 if (use_regex)
857 {
858 buf_copy(regex, tmp);
859 }
860 else
861 {
863 }
864 buf_pool_release(&tmp);
865
866 buf_expand_path(command);
867
868 /* check to make sure that a matching hook doesn't already exist */
869 TAILQ_FOREACH(hook, &Hooks, entries)
870 {
871 if ((hook->type == cmd->data) && (hook->regex.pat_not == pat_not) &&
872 mutt_str_equal(buf_string(regex), hook->regex.pattern))
873 {
874 // Update an existing hook
875 FREE(&hook->command);
876 hook->command = buf_strdup(command);
877 FREE(&hook->source_file);
879
880 expando_free(&hook->expando);
881 hook->expando = expando_parse(buf_string(command), IndexFormatDef, err);
882
883 rc = MUTT_CMD_SUCCESS;
884 goto cleanup;
885 }
886 }
887
888 /* Hooks not allowing full patterns: Check syntax of regex */
889 rx = MUTT_MEM_CALLOC(1, regex_t);
890 int rc2 = REG_COMP(rx, buf_string(regex), 0);
891 if (rc2 != 0)
892 {
893 regerror(rc2, rx, err->data, err->dsize);
894 FREE(&rx);
895 goto cleanup;
896 }
897
898 struct Expando *exp = expando_parse(buf_string(command), IndexFormatDef, err);
899
900 hook = hook_new();
901 hook->type = cmd->data;
902 hook->command = buf_strdup(command);
904 hook->pattern = NULL;
905 hook->regex.pattern = buf_strdup(regex);
906 hook->regex.regex = rx;
907 hook->regex.pat_not = pat_not;
908 hook->expando = exp;
909
910 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
911 rc = MUTT_CMD_SUCCESS;
912
913cleanup:
914 buf_pool_release(&regex);
915 buf_pool_release(&command);
916 return rc;
917}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_hook_compress()

enum CommandResult parse_hook_compress ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse compress hook commands - Implements Command::parse() -.

Parse:

  • append-hook <regex> <shell-command>
  • close-hook <regex> <shell-command>
  • open-hook <regex> <shell-command>

Definition at line 927 of file hook.c.

929{
930 struct Hook *hook = NULL;
932 bool pat_not = false;
933 regex_t *rx = NULL;
934
935 struct Buffer *regex = buf_pool_get();
936 struct Buffer *command = buf_pool_get();
937
938 if (*line->dptr == '!')
939 {
940 line->dptr++;
941 SKIPWS(line->dptr);
942 pat_not = true;
943 }
944
946
947 if (!MoreArgs(line))
948 {
949 buf_printf(err, _("%s: too few arguments"), cmd->name);
950 rc = MUTT_CMD_WARNING;
951 goto cleanup;
952 }
953
954 // TOKEN_SPACE allows the command to contain whitespace, without quoting
955 parse_extract_token(command, line, TOKEN_SPACE);
956
957 if (buf_is_empty(command))
958 {
959 buf_printf(err, _("%s: too few arguments"), cmd->name);
960 rc = MUTT_CMD_WARNING;
961 goto cleanup;
962 }
963
964 if (MoreArgs(line))
965 {
966 buf_printf(err, _("%s: too many arguments"), cmd->name);
967 rc = MUTT_CMD_WARNING;
968 goto cleanup;
969 }
970
971 if (mutt_comp_valid_command(buf_string(command)) == 0)
972 {
973 buf_strcpy(err, _("badly formatted command string"));
974 goto cleanup;
975 }
976
977 /* check to make sure that a matching hook doesn't already exist */
978 TAILQ_FOREACH(hook, &Hooks, entries)
979 {
980 if ((hook->type == cmd->data) && (hook->regex.pat_not == pat_not) &&
981 mutt_str_equal(buf_string(regex), hook->regex.pattern))
982 {
983 // Update an existing hook
984 FREE(&hook->command);
985 hook->command = buf_strdup(command);
986 FREE(&hook->source_file);
988
989 rc = MUTT_CMD_SUCCESS;
990 goto cleanup;
991 }
992 }
993
994 /* Hooks not allowing full patterns: Check syntax of regex */
995 rx = MUTT_MEM_CALLOC(1, regex_t);
996 int rc2 = REG_COMP(rx, buf_string(regex), 0);
997 if (rc2 != 0)
998 {
999 regerror(rc2, rx, err->data, err->dsize);
1000 FREE(&rx);
1001 goto cleanup;
1002 }
1003
1004 hook = hook_new();
1005 hook->type = cmd->data;
1006 hook->command = buf_strdup(command);
1008 hook->pattern = NULL;
1009 hook->regex.pattern = buf_strdup(regex);
1010 hook->regex.regex = rx;
1011 hook->regex.pat_not = pat_not;
1012 hook->expando = NULL;
1013
1014 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
1015 rc = MUTT_CMD_SUCCESS;
1016
1017cleanup:
1018 buf_pool_release(&regex);
1019 buf_pool_release(&command);
1020 return rc;
1021}
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition compress.c:391
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_hook_index()

enum CommandResult parse_hook_index ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • index-format-hook <name> [ ! ]<pattern> <format-string>

Definition at line 1076 of file hook.c.

1078{
1079 if (!MoreArgs(line))
1080 {
1081 buf_printf(err, _("%s: too few arguments"), cmd->name);
1082 return MUTT_CMD_WARNING;
1083 }
1084
1085 enum CommandResult rc = MUTT_CMD_ERROR;
1086 bool pat_not = false;
1087
1088 struct Buffer *name = buf_pool_get();
1089 struct Buffer *pattern = buf_pool_get();
1090 struct Buffer *fmt = buf_pool_get();
1091 struct Expando *exp = NULL;
1092
1093 if (!IdxFmtHooks)
1094 {
1097 }
1098
1100 struct HookList *hl = mutt_hash_find(IdxFmtHooks, buf_string(name));
1101
1102 if (*line->dptr == '!')
1103 {
1104 line->dptr++;
1105 SKIPWS(line->dptr);
1106 pat_not = true;
1107 }
1108 parse_extract_token(pattern, line, TOKEN_NO_FLAGS);
1109
1110 if (!MoreArgs(line))
1111 {
1112 buf_printf(err, _("%s: too few arguments"), cmd->name);
1113 goto out;
1114 }
1116
1117 exp = expando_parse(buf_string(fmt), IndexFormatDef, err);
1118 if (!exp)
1119 goto out;
1120
1121 if (MoreArgs(line))
1122 {
1123 buf_printf(err, _("%s: too many arguments"), cmd->name);
1124 goto out;
1125 }
1126
1127 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
1128 if (c_default_hook)
1129 mutt_check_simple(pattern, c_default_hook);
1130
1131 /* check to make sure that a matching hook doesn't already exist */
1132 struct Hook *hook = NULL;
1133 if (hl)
1134 {
1135 TAILQ_FOREACH(hook, hl, entries)
1136 {
1137 // Update an existing hook
1138 if ((hook->regex.pat_not == pat_not) &&
1140 {
1141 expando_free(&hook->expando);
1142 hook->expando = exp;
1143 exp = NULL;
1144 rc = MUTT_CMD_SUCCESS;
1145 goto out;
1146 }
1147 }
1148 }
1149
1150 /* MUTT_PC_PATTERN_DYNAMIC sets so that date ranges are regenerated during
1151 * matching. This of course is slower, but index-format-hook is commonly
1152 * used for date ranges, and they need to be evaluated relative to "now", not
1153 * the hook compilation time. */
1154 struct MailboxView *mv_cur = get_current_mailbox_view();
1155 struct PatternList *pat = mutt_pattern_comp(mv_cur, buf_string(pattern),
1157 err);
1158 if (!pat)
1159 goto out;
1160
1161 hook = hook_new();
1162 hook->type = MUTT_IDXFMTHOOK;
1163 hook->command = NULL;
1165 hook->pattern = pat;
1166 hook->regex.pattern = buf_strdup(pattern);
1167 hook->regex.regex = NULL;
1168 hook->regex.pat_not = pat_not;
1169 hook->expando = exp;
1170 exp = NULL;
1171
1172 if (!hl)
1173 {
1174 hl = MUTT_MEM_CALLOC(1, struct HookList);
1175 TAILQ_INIT(hl);
1177 }
1178
1179 TAILQ_INSERT_TAIL(hl, hook, entries);
1180 rc = MUTT_CMD_SUCCESS;
1181
1182out:
1183 buf_pool_release(&name);
1184 buf_pool_release(&pattern);
1185 buf_pool_release(&fmt);
1186 expando_free(&exp);
1187
1188 return rc;
1189}
static void idxfmt_hashelem_free(int type, void *obj, intptr_t data)
Free our hash table data - Implements hash_hdata_free_t -.
Definition hook.c:1047
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:113
static struct HashTable * IdxFmtHooks
All Index Format hooks.
Definition hook.c:81
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition hook.h:52
#define MUTT_PC_PATTERN_DYNAMIC
Enable runtime date range evaluation.
Definition lib.h:70
#define TAILQ_INIT(head)
Definition queue.h:822
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_unhook()

enum CommandResult parse_unhook ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unhook { * | <hook-type> }

Definition at line 1223 of file hook.c.

1225{
1226 if (!MoreArgs(line))
1227 {
1228 buf_printf(err, _("%s: too few arguments"), cmd->name);
1229 return MUTT_CMD_WARNING;
1230 }
1231
1232 struct Buffer *token = buf_pool_get();
1234
1235 while (MoreArgs(line))
1236 {
1237 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1238 if (mutt_str_equal("*", buf_string(token)))
1239 {
1241 {
1242 buf_addstr(err, _("unhook: Can't do unhook * from within a hook"));
1243 goto done;
1244 }
1248 }
1249 else
1250 {
1252
1253 if (type == MUTT_HOOK_NO_FLAGS)
1254 {
1255 buf_printf(err, _("unhook: unknown hook type: %s"), buf_string(token));
1256 rc = MUTT_CMD_ERROR;
1257 goto done;
1258 }
1259 if (type & (MUTT_CHARSET_HOOK | MUTT_ICONV_HOOK))
1260 {
1262 rc = MUTT_CMD_SUCCESS;
1263 goto done;
1264 }
1265 if (CurrentHookType == type)
1266 {
1267 buf_printf(err, _("unhook: Can't delete a %s from within a %s"),
1268 buf_string(token), buf_string(token));
1269 rc = MUTT_CMD_WARNING;
1270 goto done;
1271 }
1272 if (type == MUTT_IDXFMTHOOK)
1274 else
1275 mutt_delete_hooks(type);
1276 }
1277 }
1278
1279 rc = MUTT_CMD_SUCCESS;
1280
1281done:
1282 buf_pool_release(&token);
1283 return rc;
1284}
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition hook.c:1029
static void delete_idxfmt_hooks(void)
Delete all the index-format-hooks.
Definition hook.c:1065
static HookFlags mutt_get_hook_type(const char *name)
Find a hook by name.
Definition hook.c:1197
static HookFlags CurrentHookType
The type of the hook currently being executed, e.g. MUTT_SAVE_HOOK.
Definition hook.c:84
uint32_t HookFlags
Flags for parse_hook(), e.g. MUTT_FOLDER_HOOK.
Definition hook.h:35
#define MUTT_CHARSET_HOOK
charset-hook: create a charset alias for malformed emails
Definition hook.h:42
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition hook.h:36
void mutt_ch_lookup_remove(void)
Remove all the character set lookups.
Definition charset.c:541
+ Here is the call graph for this function:

◆ parse_push()

enum CommandResult parse_push ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • push <string>

Definition at line 310 of file commands.c.

312{
313 if (!MoreArgs(line))
314 {
315 buf_printf(err, _("%s: too few arguments"), cmd->name);
316 return MUTT_CMD_WARNING;
317 }
318
319 struct Buffer *token = buf_pool_get();
321
323 if (MoreArgs(line))
324 {
325 buf_printf(err, _("%s: too many arguments"), cmd->name);
326 goto done;
327 }
328
330 rc = MUTT_CMD_SUCCESS;
331
332done:
333 buf_pool_release(&token);
334 return rc;
335}
#define TOKEN_CONDENSE
^(char) to control chars (macros)
Definition extract.h:46
void generic_tokenize_push_string(char *s)
Parse and queue a 'push' command.
Definition get.c:348
+ Here is the call graph for this function:

◆ parse_bind()

enum CommandResult parse_bind ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

bind menu-name <key_sequence> function-name

Parse:

  • bind <map>[,<map> ... ] <key> <function>

Definition at line 345 of file commands.c.

347{
348 if (StartupComplete)
349 {
350 // Save and restore the offset in `line` because parse_bind_macro() might change it
351 char *dptr = line->dptr;
352 if (parse_bind_macro(cmd, line, err) == MUTT_CMD_SUCCESS)
353 {
354 return MUTT_CMD_SUCCESS;
355 }
356 if (!buf_is_empty(err))
357 {
358 return MUTT_CMD_ERROR;
359 }
360 line->dptr = dptr;
361 }
362
363 struct Buffer *token = buf_pool_get();
364 struct Buffer *keystr = NULL;
365
366 const struct MenuFuncOp *funcs = NULL;
367 enum MenuType mtypes[MENU_MAX];
368 int num_menus = 0;
370
371 char *key = parse_keymap(mtypes, line, countof(mtypes), &num_menus, err, true);
372 if (!key)
373 goto done;
374
375 /* function to execute */
377 if (MoreArgs(line))
378 {
379 buf_printf(err, _("%s: too many arguments"), cmd->name);
380 goto done;
381 }
382
383 rc = MUTT_CMD_SUCCESS;
384
385 if (mutt_istr_equal("noop", buf_string(token)))
386 {
387 keystr = buf_pool_get();
388 for (int i = 0; i < num_menus; i++)
389 {
390 km_bind(key, mtypes[i], OP_NULL, NULL, NULL, NULL); /* the 'unbind' command */
391 funcs = km_get_table(mtypes[i]);
392 if (funcs)
393 {
394 buf_reset(keystr);
395 km_expand_key_string(key, keystr);
396 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
397 mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", mname, buf_string(keystr));
398
399 int op = get_op(OpGeneric, buf_string(token), mutt_str_len(buf_string(token)));
400 struct EventBinding ev_b = { mtypes[i], key, op };
402 }
403 }
404 }
405 else
406 {
407 keystr = buf_pool_get();
408 for (int i = 0; i < num_menus; i++)
409 {
410 /* The pager and editor menus don't use the generic map,
411 * however for other menus try generic first. */
412 if ((mtypes[i] != MENU_PAGER) && (mtypes[i] != MENU_EDITOR) && (mtypes[i] != MENU_GENERIC))
413 {
414 rc = try_bind(key, mtypes[i], token->data, OpGeneric, err);
415 if (rc == MUTT_CMD_SUCCESS)
416 {
417 buf_reset(keystr);
418 km_expand_key_string(key, keystr);
419 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
420 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, buf_string(keystr));
421
422 int op = get_op(OpGeneric, buf_string(token), mutt_str_len(buf_string(token)));
423 struct EventBinding ev_b = { mtypes[i], key, op };
425 continue;
426 }
427 if (rc == MUTT_CMD_WARNING)
428 break;
429 }
430
431 /* Clear any error message, we're going to try again */
432 err->data[0] = '\0';
433 funcs = km_get_table(mtypes[i]);
434 if (funcs)
435 {
436 rc = try_bind(key, mtypes[i], token->data, funcs, err);
437 if (rc == MUTT_CMD_SUCCESS)
438 {
439 buf_reset(keystr);
440 km_expand_key_string(key, keystr);
441 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
442 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, buf_string(keystr));
443
444 int op = get_op(funcs, buf_string(token), mutt_str_len(buf_string(token)));
445 struct EventBinding ev_b = { mtypes[i], key, op };
447 continue;
448 }
449 }
450 }
451 }
452
453done:
454 FREE(&key);
455 buf_pool_release(&keystr);
456 buf_pool_release(&token);
457 return rc;
458}
enum CommandResult parse_bind_macro(const struct Command *cmd, struct Buffer *line, struct Buffer *err)
Parse 'bind' and 'macro' commands - Implements Command::parse() -.
Definition dump.c:175
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition functions.c:69
enum CommandResult km_bind(const char *s, enum MenuType mtype, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition commands.c:56
static char * parse_keymap(enum MenuType *mtypes, struct Buffer *line, int max_menus, int *num_menus, struct Buffer *err, bool bind)
Parse a user-config key binding.
Definition commands.c:189
static enum CommandResult try_bind(char *key, enum MenuType mtype, char *func, const struct MenuFuncOp *funcs, struct Buffer *err)
Try to make a key binding.
Definition commands.c:286
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition lib.c:485
int get_op(const struct MenuFuncOp *funcs, const char *start, size_t len)
Get the function by its name.
Definition lib.c:299
void km_expand_key_string(char *str, struct Buffer *buf)
Get a human-readable key string.
Definition lib.c:455
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition lib.h:152
@ NT_BINDING_ADD
Key binding has been added.
Definition lib.h:151
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition mapping.c:42
#define countof(x)
Definition memory.h:44
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition notify_type.h:40
A key binding Event.
Definition lib.h:136
const char * key
Key string being bound (for new bind/macro)
Definition lib.h:138
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition lib.h:139
Mapping between a function and an operation.
Definition lib.h:117
int op
Operation, e.g. OP_DELETE.
Definition lib.h:119
const struct Mapping MenuNames[]
Menu name lookup table.
Definition type.c:37
MenuType
Types of GUI selections.
Definition type.h:35
@ MENU_GENERIC
Generic selection list.
Definition type.h:45
@ MENU_PAGER
Pager pager (email viewer)
Definition type.h:47
@ MENU_MAX
Definition type.h:52
@ MENU_EDITOR
Text entry area.
Definition type.h:44
+ Here is the call graph for this function:

◆ parse_unbind()

enum CommandResult parse_unbind ( const struct Command * cmd,
struct Buffer * line,
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

Parse:

  • unbind { * | <menu>[,<menu> ... ] } [ <key> ]
  • unmacro { * | <menu>[,<menu> ... ] } [ <key> ]

Definition at line 472 of file commands.c.

474{
475 if (!MoreArgs(line))
476 {
477 buf_printf(err, _("%s: too few arguments"), cmd->name);
478 return MUTT_CMD_WARNING;
479 }
480
481 struct Buffer *token = buf_pool_get();
483
484 bool menu_matches[MENU_MAX] = { 0 };
485 bool all_keys = false;
486 char *key = NULL;
487
489 if (mutt_str_equal(buf_string(token), "*"))
490 {
491 for (enum MenuType i = 1; i < MENU_MAX; i++)
492 menu_matches[i] = true;
493 }
494 else
495 {
496 parse_menu(menu_matches, token->data, err);
497 }
498
499 if (MoreArgs(line))
500 {
502 key = token->data;
503 }
504 else
505 {
506 all_keys = true;
507 }
508
509 if (MoreArgs(line))
510 {
511 buf_printf(err, _("%s: too many arguments"), cmd->name);
512 goto done;
513 }
514
515 for (enum MenuType i = 1; i < MENU_MAX; i++)
516 {
517 if (!menu_matches[i])
518 continue;
519 if (all_keys)
520 {
521 km_unbind_all(&Keymaps[i], cmd->data);
522 km_bind("<enter>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
523 km_bind("<return>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY, NULL, NULL, NULL);
524 km_bind("<enter>", MENU_INDEX, OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
525 km_bind("<return>", MENU_INDEX, OP_DISPLAY_MESSAGE, NULL, NULL, NULL);
526 km_bind("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
527 km_bind("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE, NULL, NULL, NULL);
528 km_bind(":", MENU_GENERIC, OP_ENTER_COMMAND, NULL, NULL, NULL);
529 km_bind(":", MENU_PAGER, OP_ENTER_COMMAND, NULL, NULL, NULL);
530 if (i != MENU_EDITOR)
531 {
532 km_bind("?", i, OP_HELP, NULL, NULL, NULL);
533 km_bind("q", i, OP_EXIT, NULL, NULL, NULL);
534 }
535
536 const char *mname = mutt_map_get_name(i, MenuNames);
537 mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE_ALL: %s\n", mname);
538
539 struct EventBinding ev_b = { i, NULL, OP_NULL };
542 &ev_b);
543 }
544 else
545 {
546 struct Buffer *keystr = buf_pool_get();
547 km_expand_key_string(key, keystr);
548 const char *mname = mutt_map_get_name(i, MenuNames);
549 mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE: %s %s\n", mname, buf_string(keystr));
550 buf_pool_release(&keystr);
551
552 km_bind(key, i, OP_NULL, NULL, NULL, NULL);
553 struct EventBinding ev_b = { i, key, OP_NULL };
556 }
557 }
558
559 rc = MUTT_CMD_SUCCESS;
560
561done:
562 buf_pool_release(&token);
563 return rc;
564}
static void * parse_menu(bool *menus, char *s, struct Buffer *err)
Parse menu-names into an array.
Definition commands.c:253
static void km_unbind_all(struct KeymapList *km_list, unsigned long mode)
Free all the keys in the supplied Keymap.
Definition commands.c:161
struct KeymapList Keymaps[MENU_MAX]
Array of key mappings, one for each MenuType.
Definition lib.c:125
@ NT_MACRO_DELETE
Key macro has been deleted.
Definition lib.h:156
@ NT_MACRO_DELETE_ALL
All key macros have been deleted.
Definition lib.h:157
@ NT_BINDING_DELETE_ALL
All key bindings have been deleted.
Definition lib.h:153
#define MUTT_UNMACRO
Parse 'unmacro' command.
Definition lib.h:50
@ MENU_INDEX
Index panel (list of emails)
Definition type.h:46
+ Here is the call graph for this function:

◆ parse_macro()

enum CommandResult parse_macro ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • macro <menu>[,<menu> ... ] <key> <sequence> [ <description> ]

Definition at line 572 of file commands.c.

574{
575 if (StartupComplete)
576 {
577 // Save and restore the offset in `line` because parse_bind_macro() might change it
578 char *dptr = line->dptr;
579 if (parse_bind_macro(cmd, line, err) == MUTT_CMD_SUCCESS)
580 {
581 return MUTT_CMD_SUCCESS;
582 }
583 if (!buf_is_empty(err))
584 {
585 return MUTT_CMD_ERROR;
586 }
587 line->dptr = dptr;
588 }
589
590 enum MenuType mtypes[MENU_MAX];
591 int num_menus = 0;
592 struct Buffer *token = buf_pool_get();
593 struct Buffer *keystr = NULL;
595
596 char *key = parse_keymap(mtypes, line, countof(mtypes), &num_menus, err, false);
597 if (!key)
598 goto done;
599
601 /* make sure the macro sequence is not an empty string */
602 if (buf_at(token, 0) == '\0')
603 {
604 buf_strcpy(err, _("macro: empty key sequence"));
605 }
606 else
607 {
608 if (MoreArgs(line))
609 {
610 char *seq = mutt_str_dup(buf_string(token));
612
613 if (MoreArgs(line))
614 {
615 buf_printf(err, _("%s: too many arguments"), cmd->name);
616 }
617 else
618 {
619 keystr = buf_pool_get();
620 for (int i = 0; i < num_menus; i++)
621 {
622 rc = km_bind(key, mtypes[i], OP_MACRO, seq, token->data, NULL);
623 if (rc == MUTT_CMD_SUCCESS)
624 {
625 buf_reset(keystr);
626 km_expand_key_string(key, keystr);
627 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
628 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, buf_string(keystr));
629
630 struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
632 continue;
633 }
634 }
635 }
636
637 FREE(&seq);
638 }
639 else
640 {
641 keystr = buf_pool_get();
642 for (int i = 0; i < num_menus; i++)
643 {
644 rc = km_bind(key, mtypes[i], OP_MACRO, token->data, NULL, NULL);
645 if (rc == MUTT_CMD_SUCCESS)
646 {
647 buf_reset(keystr);
648 km_expand_key_string(key, keystr);
649 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
650 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, buf_string(keystr));
651
652 struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
654 continue;
655 }
656 }
657 }
658 }
659
660done:
661 FREE(&key);
662 buf_pool_release(&keystr);
663 buf_pool_release(&token);
664 return rc;
665}
@ NT_MACRO_ADD
Key macro has been added.
Definition lib.h:155
+ Here is the call graph for this function:

◆ parse_exec()

enum CommandResult parse_exec ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • exec <function> [ <function> ... ]

Definition at line 673 of file commands.c.

675{
676 if (!MoreArgs(line))
677 {
678 buf_printf(err, _("%s: too few arguments"), cmd->name);
679 return MUTT_CMD_WARNING;
680 }
681
682 struct Buffer *token = buf_pool_get();
684
685 int ops[128];
686 int nops = 0;
687 const struct MenuFuncOp *funcs = NULL;
688 char *function = NULL;
689
690 do
691 {
693 function = token->data;
694
695 const enum MenuType mtype = menu_get_current_type();
696 funcs = km_get_table(mtype);
697 if (!funcs && (mtype != MENU_PAGER))
698 funcs = OpGeneric;
699
700 ops[nops] = get_op(funcs, function, mutt_str_len(function));
701 if ((ops[nops] == OP_NULL) && (mtype != MENU_PAGER) && (mtype != MENU_GENERIC))
702 {
703 ops[nops] = get_op(OpGeneric, function, mutt_str_len(function));
704 }
705
706 if (ops[nops] == OP_NULL)
707 {
709 mutt_error(_("%s: no such function"), function);
710 goto done;
711 }
712 nops++;
713 } while (MoreArgs(line) && nops < countof(ops));
714
715 while (nops)
716 mutt_push_macro_event(0, ops[--nops]);
717
718 rc = MUTT_CMD_SUCCESS;
719
720done:
721 buf_pool_release(&token);
722 return rc;
723}
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition get.c:58
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition get.c:155
enum MenuType menu_get_current_type(void)
Get the type of the current Window.
Definition menu.c:89
+ Here is the call graph for this function:

◆ parse_bind_macro()

enum CommandResult parse_bind_macro ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

Parse 'bind' and 'macro' commands - Implements Command::parse() -.

Definition at line 175 of file dump.c.

177{
178 FILE *fp = NULL;
179 bool dump_all = false;
180 bool bind = (cmd->data == 0);
181 struct Buffer *token = buf_pool_get();
182 struct Buffer *tempfile = NULL;
184
185 if (!MoreArgs(line))
186 dump_all = true;
187 else
189
190 if (MoreArgs(line))
191 {
192 /* More arguments potentially means the user is using the
193 * ::command_t :bind command thus we delegate the task. */
194 goto done;
195 }
196
197 tempfile = buf_pool_get();
198 buf_mktemp(tempfile);
199 fp = mutt_file_fopen(buf_string(tempfile), "w");
200 if (!fp)
201 {
202 // L10N: '%s' is the file name of the temporary file
203 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
204 goto done;
205 }
206
207 if (dump_all || mutt_istr_equal(buf_string(token), "all"))
208 {
209 if (bind)
210 colon_bind(MENU_MAX, fp);
211 else
213 }
214 else
215 {
216 const int menu = mutt_map_get_value(buf_string(token), MenuNames);
217 if (menu == -1)
218 {
219 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
220 buf_printf(err, _("%s: no such menu"), buf_string(token));
221 goto done;
222 }
223
224 if (bind)
225 colon_bind(menu, fp);
226 else
227 colon_macro(menu, fp);
228 }
229
230 if (ftello(fp) == 0)
231 {
232 // L10N: '%s' is the name of the menu, e.g. 'index' or 'pager',
233 // it might also be 'all' when all menus are affected.
234 buf_printf(err, bind ? _("%s: no binds for this menu") : _("%s: no macros for this menu"),
235 dump_all ? "all" : buf_string(token));
236 goto done;
237 }
238 mutt_file_fclose(&fp);
239
240 struct PagerData pdata = { 0 };
241 struct PagerView pview = { &pdata };
242
243 pdata.fname = buf_string(tempfile);
244
245 pview.banner = cmd->name;
247 pview.mode = PAGER_MODE_OTHER;
248
249 mutt_do_pager(&pview, NULL);
250 rc = MUTT_CMD_SUCCESS;
251
252done:
253 mutt_file_fclose(&fp);
254 buf_pool_release(&token);
255 buf_pool_release(&tempfile);
256
257 return rc;
258}
static void colon_macro(enum MenuType menu, FILE *fp)
Dump the macros.
Definition dump.c:153
static void colon_bind(enum MenuType menu, FILE *fp)
Dump the key bindings.
Definition dump.c:87
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition mapping.c:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_lua()

enum CommandResult parse_lua ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • lua "<lua-commands>"

Definition at line 57 of file commands.c.

58{
59 if (!MoreArgs(line))
60 {
61 buf_printf(err, _("%s: too few arguments"), cmd->name);
62 return MUTT_CMD_WARNING;
63 }
64
65 struct Buffer *token = buf_pool_get();
67
69
71 mutt_debug(LL_DEBUG2, "%s\n", buf_string(token));
72
73 if (luaL_dostring(LuaState, buf_string(token)) != LUA_OK)
74 {
75 mutt_debug(LL_DEBUG2, "%s -> failure\n", buf_string(token));
76 buf_printf(err, "%s: %s", buf_string(token), lua_tostring(LuaState, -1));
77 /* pop error message from the stack */
78 lua_pop(LuaState, 1);
79 goto done;
80 }
81 mutt_debug(LL_DEBUG2, "%s -> success\n", buf_string(token));
82 buf_reset(line); // Clear the rest of the line
83
85
86done:
87 buf_pool_release(&token);
88 return rc;
89}
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:45
bool lua_init_state(lua_State **l)
Initialise a Lua State.
Definition lua.c:436
lua_State * LuaState
Global Lua State.
Definition lua.c:56
+ Here is the call graph for this function:

◆ parse_lua_source()

enum CommandResult parse_lua_source ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • lua-source <file>

Definition at line 97 of file commands.c.

99{
100 if (!MoreArgs(line))
101 {
102 buf_printf(err, _("%s: too few arguments"), cmd->name);
103 return MUTT_CMD_WARNING;
104 }
105
106 struct Buffer *token = buf_pool_get();
108
109 mutt_debug(LL_DEBUG2, "enter\n");
110
112
113 if (parse_extract_token(token, line, TOKEN_NO_FLAGS) != 0)
114 {
115 buf_printf(err, _("source: error at %s"), line->dptr);
116 goto done;
117 }
118 if (MoreArgs(line))
119 {
120 buf_printf(err, _("%s: too many arguments"), cmd->name);
121 rc = MUTT_CMD_WARNING;
122 goto done;
123 }
124
125 buf_expand_path(token);
126
127 if (luaL_dofile(LuaState, buf_string(token)) != LUA_OK)
128 {
129 mutt_error(_("Couldn't source lua source: %s"), lua_tostring(LuaState, -1));
130 lua_pop(LuaState, 1);
131 goto done;
132 }
133
134 rc = MUTT_CMD_SUCCESS;
135
136done:
137 buf_pool_release(&token);
138 return rc;
139}
+ Here is the call graph for this function:

◆ parse_set()

enum CommandResult parse_set ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • reset <variable> [ <variable> ... ]
  • set { [ no | inv | & ] <variable> [?] | <variable> [=|+=|-=] value } [... ]
  • toggle <variable> [ <variable> ... ]
  • unset <variable> [ <variable> ... ]

Definition at line 473 of file set.c.

474{
475 /* The order must match `enum MuttSetCommand` */
476 static const char *set_commands[] = { "set", "toggle", "unset", "reset" };
477
478 struct Buffer *token = buf_pool_get();
480
481 do
482 {
483 bool prefix = false;
484 bool query = false;
485 bool inv = (cmd->data == MUTT_SET_INV);
486 bool reset = (cmd->data == MUTT_SET_RESET);
487 bool unset = (cmd->data == MUTT_SET_UNSET);
488
489 if (*line->dptr == '?')
490 {
491 prefix = true;
492 query = true;
493 line->dptr++;
494 }
495 else if (mutt_str_startswith(line->dptr, "no"))
496 {
497 prefix = true;
498 unset = !unset;
499 line->dptr += 2;
500 }
501 else if (mutt_str_startswith(line->dptr, "inv"))
502 {
503 prefix = true;
504 inv = !inv;
505 line->dptr += 3;
506 }
507 else if (*line->dptr == '&')
508 {
509 prefix = true;
510 reset = true;
511 line->dptr++;
512 }
513
514 if (prefix && (cmd->data != MUTT_SET_SET))
515 {
516 buf_printf(err, _("Can't use 'inv', 'no', '&' or '?' with the '%s' command"),
517 set_commands[cmd->data]);
518 goto done;
519 }
520
521 // get the variable name. Note that token might be empty if no additional
522 // argument was given.
523 int ret = parse_extract_token(token, line,
525 if (ret == -1)
526 {
527 buf_pool_release(&token);
528 return MUTT_CMD_ERROR;
529 }
530
531 bool bool_or_quad = false;
532 bool invertible = false;
533 bool equals = false;
534 bool increment = false;
535 bool decrement = false;
536
537 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, buf_string(token));
538 if (he)
539 {
540 // Use the correct name if a synonym is used
541 buf_strcpy(token, he->key.strkey);
542 bool_or_quad = ((CONFIG_TYPE(he->type) == DT_BOOL) ||
543 (CONFIG_TYPE(he->type) == DT_QUAD));
544 invertible = (bool_or_quad || (CONFIG_TYPE(he->type) == DT_NUMBER));
545 }
546
547 if (*line->dptr == '?')
548 {
549 if (prefix)
550 {
551 buf_printf(err, _("Can't use a prefix when querying a variable"));
552 goto done;
553 }
554
555 if (reset || unset || inv)
556 {
557 buf_printf(err, _("Can't query option with the '%s' command"),
558 set_commands[cmd->data]);
559 goto done;
560 }
561
562 query = true;
563 line->dptr++;
564 }
565 else if ((*line->dptr == '+') || (*line->dptr == '-'))
566 {
567 if (prefix)
568 {
569 buf_printf(err, _("Can't use prefix when incrementing or decrementing a variable"));
570 goto done;
571 }
572
573 if (reset || unset || inv)
574 {
575 buf_printf(err, _("Can't set option with the '%s' command"),
576 set_commands[cmd->data]);
577 goto done;
578 }
579 if (*line->dptr == '+')
580 increment = true;
581 else
582 decrement = true;
583
584 line->dptr++;
585 if (*line->dptr == '=')
586 {
587 equals = true;
588 line->dptr++;
589 }
590 else
591 {
592 buf_printf(err, _("'+' and '-' must be followed by '='"));
593 goto done;
594 }
595 }
596 else if (*line->dptr == '=')
597 {
598 if (prefix)
599 {
600 buf_printf(err, _("Can't use prefix when setting a variable"));
601 goto done;
602 }
603
604 if (reset || unset || inv)
605 {
606 buf_printf(err, _("Can't set option with the '%s' command"),
607 set_commands[cmd->data]);
608 goto done;
609 }
610
611 equals = true;
612 line->dptr++;
613 }
614
615 if (!invertible && (inv || (unset && prefix)))
616 {
617 if (cmd->data == MUTT_SET_SET)
618 {
619 buf_printf(err, _("Prefixes 'no' and 'inv' may only be used with bool/quad/number variables"));
620 }
621 else
622 {
623 buf_printf(err, _("Command '%s' can only be used with bool/quad/number variables"),
624 set_commands[cmd->data]);
625 }
626 goto done;
627 }
628
629 // sanity checks for the above
630 // Each of inv, unset reset, query, equals implies that the others are not set.
631 // If none of them are set, then we are dealing with a "set foo" command.
632 // clang-format off
633 ASSERT(!inv || !( unset || reset || query || equals ));
634 ASSERT(!unset || !(inv || reset || query || equals ));
635 ASSERT(!reset || !(inv || unset || query || equals ));
636 ASSERT(!query || !(inv || unset || reset || equals ));
637 ASSERT(!equals || !(inv || unset || reset || query || prefix));
638 // clang-format on
639 ASSERT(!(increment && decrement)); // only one of increment or decrement is set
640 ASSERT(!(increment || decrement) || equals); // increment/decrement implies equals
641 ASSERT(!inv || invertible); // inv (aka toggle) implies bool or quad
642
643 rc = MUTT_CMD_ERROR;
644 if (query)
645 {
646 rc = command_set_query(token, err);
647 goto done; // We can only do one query even if multiple config names are given
648 }
649 else if (reset)
650 {
651 rc = command_set_reset(token, err);
652 }
653 else if (unset)
654 {
655 rc = command_set_unset(token, err);
656 }
657 else if (inv)
658 {
659 rc = command_set_toggle(token, err);
660 }
661 else if (equals)
662 {
663 // These three cases all need a value, since 'increment'/'decrement'
664 // implies 'equals', we can group them in this single case guarded by
665 // 'equals'.
666 struct Buffer *value = buf_pool_get();
668 if (increment)
669 rc = command_set_increment(token, value, err);
670 else if (decrement)
671 rc = command_set_decrement(token, value, err);
672 else
673 rc = command_set_set(token, value, err);
674 buf_pool_release(&value);
675 }
676 else
677 {
678 // This is the "set foo" case which has different meanings depending on
679 // the type of the config variable
680 if (bool_or_quad)
681 {
682 struct Buffer *yes = buf_pool_get();
683 buf_addstr(yes, "yes");
684 rc = command_set_set(token, yes, err);
685 buf_pool_release(&yes);
686 }
687 else
688 {
689 rc = command_set_query(token, err);
690 goto done; // We can only do one query even if multiple config names are given
691 }
692 }
693 // Short circuit (i.e. skipping further config variable names) if the action on
694 // the current variable failed.
695 if (rc != MUTT_CMD_SUCCESS)
696 goto done;
697 } while (MoreArgs(line));
698
699 rc = MUTT_CMD_SUCCESS;
700
701done:
702 buf_pool_release(&token);
703 return rc;
704}
#define TOKEN_PLUS
Treat '+' as a special.
Definition extract.h:55
#define TOKEN_MINUS
Treat '-' as a special.
Definition extract.h:56
enum CommandResult command_set_increment(struct Buffer *name, struct Buffer *value, struct Buffer *err)
Increment a variable by a value.
Definition set.c:159
enum CommandResult command_set_decrement(struct Buffer *name, struct Buffer *value, struct Buffer *err)
Decrement a variable by a value.
Definition set.c:220
enum CommandResult command_set_toggle(struct Buffer *name, struct Buffer *err)
Toggle a boolean, quad, or number variable.
Definition set.c:360
enum CommandResult command_set_reset(struct Buffer *name, struct Buffer *err)
Reset a variable.
Definition set.c:301
enum CommandResult command_set_query(struct Buffer *name, struct Buffer *err)
Query a variable.
Definition set.c:406
enum CommandResult command_set_unset(struct Buffer *name, struct Buffer *err)
Unset a variable.
Definition set.c:256
enum CommandResult command_set_set(struct Buffer *name, struct Buffer *value, struct Buffer *err)
Set a variable to the given value.
Definition set.c:99
@ MUTT_SET_INV
default is to invert all vars
Definition set.h:36
@ MUTT_SET_SET
default is to set all vars
Definition set.h:35
@ MUTT_SET_RESET
default is to reset all vars to default
Definition set.h:38
#define ASSERT(COND)
Definition signal2.h:60
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
#define CONFIG_TYPE(t)
Definition types.h:49
@ DT_NUMBER
a number
Definition types.h:38
@ DT_BOOL
boolean option
Definition types.h:32
@ DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition types.h:40
const char * strkey
String key.
Definition hash.h:36
+ Here is the call graph for this function:

◆ parse_score()

enum CommandResult parse_score ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • score <pattern> <value>

Definition at line 94 of file score.c.

96{
97 if (!MoreArgs(line))
98 {
99 buf_printf(err, _("%s: too few arguments"), cmd->name);
100 return MUTT_CMD_WARNING;
101 }
102
103 struct Score *ptr = NULL, *last = NULL;
104 char *pattern = NULL, *pc = NULL;
105 struct Buffer *token = buf_pool_get();
107
109 if (!MoreArgs(line))
110 {
111 buf_printf(err, _("%s: too few arguments"), cmd->name);
112 goto done;
113 }
114 pattern = buf_strdup(token);
116 if (MoreArgs(line))
117 {
118 buf_printf(err, _("%s: too many arguments"), cmd->name);
119 goto done;
120 }
121
122 /* look for an existing entry and update the value, else add it to the end
123 * of the list */
124 for (ptr = ScoreList, last = NULL; ptr; last = ptr, ptr = ptr->next)
125 if (mutt_str_equal(pattern, ptr->str))
126 break;
127
128 if (ptr)
129 {
130 /* 'token' arg was cleared and 'pattern' holds the only reference;
131 * as here 'ptr' != NULL -> update the value only in which case
132 * ptr->str already has the string, so pattern should be freed. */
133 FREE(&pattern);
134 }
135 else
136 {
137 struct MailboxView *mv_cur = get_current_mailbox_view();
138 struct PatternList *pat = mutt_pattern_comp(mv_cur, pattern, MUTT_PC_NO_FLAGS, err);
139 if (!pat)
140 {
141 goto done;
142 }
143 ptr = MUTT_MEM_CALLOC(1, struct Score);
144 if (last)
145 last->next = ptr;
146 else
147 ScoreList = ptr;
148 ptr->pat = pat;
149 ptr->str = pattern;
150 pattern = NULL;
151 }
152
153 pc = token->data;
154 if (*pc == '=')
155 {
156 ptr->exact = true;
157 pc++;
158 }
159
160 if (!mutt_str_atoi_full(pc, &ptr->val))
161 {
162 buf_strcpy(err, _("Error: score: invalid number"));
163 goto done;
164 }
165 OptNeedRescore = true;
166
167 rc = MUTT_CMD_SUCCESS;
168
169done:
170 buf_pool_release(&token);
171 FREE(&pattern);
172 return rc;
173}
bool OptNeedRescore
(pseudo) set when the 'score' command is used
Definition globals.c:62
static struct Score * ScoreList
Linked list of email scoring rules.
Definition score.c:61
Scoring rule for email.
Definition score.c:52
struct Score * next
Linked list.
Definition score.c:57
+ Here is the call graph for this function:

◆ parse_unscore()

enum CommandResult parse_unscore ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unscore { * | <pattern> ... }

Definition at line 220 of file score.c.

222{
223 if (!MoreArgs(line))
224 {
225 buf_printf(err, _("%s: too few arguments"), cmd->name);
226 return MUTT_CMD_WARNING;
227 }
228
229 struct Score *tmp = NULL, *last = NULL;
230 struct Buffer *token = buf_pool_get();
231
232 while (MoreArgs(line))
233 {
235 if (mutt_str_equal("*", buf_string(token)))
236 {
237 for (tmp = ScoreList; tmp;)
238 {
239 last = tmp;
240 tmp = tmp->next;
241 mutt_pattern_free(&last->pat);
242 FREE(&last);
243 }
244 ScoreList = NULL;
245 }
246 else
247 {
248 for (tmp = ScoreList; tmp; last = tmp, tmp = tmp->next)
249 {
250 if (mutt_str_equal(buf_string(token), tmp->str))
251 {
252 if (last)
253 last->next = tmp->next;
254 else
255 ScoreList = tmp->next;
256 mutt_pattern_free(&tmp->pat);
257 FREE(&tmp);
258 /* there should only be one score per pattern, so we can stop here */
259 break;
260 }
261 }
262 }
263 }
264
265 OptNeedRescore = true;
266 buf_pool_release(&token);
267 return MUTT_CMD_SUCCESS;
268}
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition compile.c:774
+ Here is the call graph for this function:

◆ parse_sidebar_pin()

enum CommandResult parse_sidebar_pin ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • sidebar_pin <mailbox> [ <mailbox> ... ]

Definition at line 43 of file commands.c.

45{
46 if (!MoreArgs(line))
47 {
48 buf_printf(err, _("%s: too few arguments"), cmd->name);
49 return MUTT_CMD_WARNING;
50 }
51
52 struct Buffer *path = buf_pool_get();
53
54 do
55 {
57 buf_expand_path(path);
59 } while (MoreArgs(line));
60 buf_pool_release(&path);
61
62 return MUTT_CMD_SUCCESS;
63}
struct ListHead SidebarPinned
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:

◆ parse_sidebar_unpin()

enum CommandResult parse_sidebar_unpin ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • sidebar_unpin { * | <mailbox> ... }

Definition at line 71 of file commands.c.

73{
74 if (!MoreArgs(line))
75 {
76 buf_printf(err, _("%s: too few arguments"), cmd->name);
77 return MUTT_CMD_WARNING;
78 }
79
80 struct Buffer *path = buf_pool_get();
81
82 do
83 {
85 /* Check for deletion of entire list */
86 if (mutt_str_equal(buf_string(path), "*"))
87 {
89 break;
90 }
91 buf_expand_path(path);
93 } while (MoreArgs(line));
94 buf_pool_release(&path);
95
96 return MUTT_CMD_SUCCESS;
97}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_subjectrx_list()

enum CommandResult parse_subjectrx_list ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • subjectrx <regex> <replacement>

Definition at line 192 of file subjectrx.c.

194{
195 if (!MoreArgs(line))
196 {
197 buf_printf(err, _("%s: too few arguments"), cmd->name);
198 return MUTT_CMD_WARNING;
199 }
200
201 enum CommandResult rc;
202
203 rc = parse_replace_list(cmd, line, &SubjectRegexList, err);
204 if (rc == MUTT_CMD_SUCCESS)
205 {
206 mutt_debug(LL_NOTIFY, "NT_SUBJRX_ADD: %s\n", cmd->name);
208 }
209 return rc;
210}
@ NT_SUBJRX
Subject Regex has changed, NotifySubjRx.
Definition notify_type.h:55
static enum CommandResult parse_replace_list(const struct Command *cmd, struct Buffer *line, struct ReplaceList *list, struct Buffer *err)
Parse a string replacement rule.
Definition subjectrx.c:107
static struct Notify * SubjRxNotify
Notifications: NotifySubjRx.
Definition subjectrx.c:40
static struct ReplaceList SubjectRegexList
List of subjectrx rules for modifying the Subject:
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 ( const struct Command * cmd,
struct Buffer * line,
struct Buffer * err )

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

Parse:

  • unsubjectrx { * | <regex> }

Definition at line 218 of file subjectrx.c.

220{
221 if (!MoreArgs(line))
222 {
223 buf_printf(err, _("%s: too few arguments"), cmd->name);
224 return MUTT_CMD_WARNING;
225 }
226
227 enum CommandResult rc;
228
229 rc = parse_unreplace_list(cmd, line, &SubjectRegexList, err);
230 if (rc == MUTT_CMD_SUCCESS)
231 {
232 mutt_debug(LL_NOTIFY, "NT_SUBJRX_DELETE: %s\n", cmd->name);
234 }
235 return rc;
236}
static enum CommandResult parse_unreplace_list(const struct Command *cmd, struct Buffer *line, struct ReplaceList *list, struct Buffer *err)
Remove a string replacement rule.
Definition subjectrx.c:71
@ NT_SUBJRX_DELETE
Subject Regex has been deleted.
Definition subjectrx.h:43
+ Here is the call graph for this function: