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

Detailed Description

Function to parse a command.

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

Function Documentation

◆ parse_alias()

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

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

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

Definition at line 135 of file commands.c.

137{
138 struct Alias *tmp = NULL;
139 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
140 enum NotifyAlias event;
141
142 if (!MoreArgs(s))
143 {
144 buf_strcpy(err, _("alias: no address"));
145 return MUTT_CMD_WARNING;
146 }
147
148 /* name */
150 mutt_debug(LL_DEBUG5, "First token is '%s'\n", buf->data);
151 if (parse_grouplist(&gl, buf, s, err) == -1)
152 {
153 return MUTT_CMD_ERROR;
154 }
155 char *name = mutt_str_dup(buf->data);
156
157 /* address list */
159 mutt_debug(LL_DEBUG5, "Second token is '%s'\n", buf->data);
160 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
161 int parsed = mutt_addrlist_parse2(&al, buf->data);
162 if (parsed == 0)
163 {
164 buf_printf(err, _("Warning: Bad address '%s' in alias '%s'"), buf->data, name);
165 FREE(&name);
166 goto bail;
167 }
168
169 /* IDN */
170 char *estr = NULL;
171 if (mutt_addrlist_to_intl(&al, &estr))
172 {
173 buf_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, name);
174 FREE(&name);
175 FREE(&estr);
176 goto bail;
177 }
178
179 /* check to see if an alias with this name already exists */
180 TAILQ_FOREACH(tmp, &Aliases, entries)
181 {
182 if (mutt_istr_equal(tmp->name, name))
183 break;
184 }
185
186 if (tmp)
187 {
188 FREE(&name);
190 /* override the previous value */
192 FREE(&tmp->comment);
193 event = NT_ALIAS_CHANGE;
194 }
195 else
196 {
197 /* create a new alias */
198 tmp = alias_new();
199 tmp->name = name;
200 TAILQ_INSERT_TAIL(&Aliases, tmp, entries);
201 event = NT_ALIAS_ADD;
202 }
203 tmp->addr = al;
204
206
207 const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
208 if (c_debug_level > LL_DEBUG4)
209 {
210 /* A group is terminated with an empty address, so check a->mailbox */
211 struct Address *a = NULL;
212 TAILQ_FOREACH(a, &tmp->addr, entries)
213 {
214 if (!a->mailbox)
215 break;
216
217 if (a->group)
218 mutt_debug(LL_DEBUG5, " Group %s\n", buf_string(a->mailbox));
219 else
220 mutt_debug(LL_DEBUG5, " %s\n", buf_string(a->mailbox));
221 }
222 }
224 if (!MoreArgs(s) && (s->dptr[0] == '#'))
225 {
226 s->dptr++; // skip over the "# "
227 if (*s->dptr == ' ')
228 s->dptr++;
229
230 parse_alias_comments(tmp, s->dptr);
231 *s->dptr = '\0'; // We're done parsing
232 }
233
235
236 mutt_debug(LL_NOTIFY, "%s: %s\n",
237 (event == NT_ALIAS_ADD) ? "NT_ALIAS_ADD" : "NT_ALIAS_CHANGE", tmp->name);
238 struct EventAlias ev_a = { tmp };
239 notify_send(NeoMutt->notify, NT_ALIAS, event, &ev_a);
240
241 return MUTT_CMD_SUCCESS;
242
243bail:
245 return MUTT_CMD_ERROR;
246}
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:95
struct AliasList Aliases
List of all the user's email aliases.
Definition: alias.c:62
struct Alias * alias_new(void)
Create a new Alias.
Definition: alias.c:660
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
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:39
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:37
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:38
int parse_grouplist(struct GroupList *gl, struct Buffer *buf, struct Buffer *s, struct Buffer *err)
Parse a group context.
Definition: commands.c:131
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 *tok, TokenFlags flags)
Extract one token from a string.
Definition: extract.c:50
#define TOKEN_SPACE
Don't treat whitespace as a term.
Definition: extract.h:49
#define TOKEN_QUOTE
Don't interpret quotes.
Definition: extract.h:50
#define MoreArgs(buf)
Definition: extract.h:32
#define TOKEN_SEMICOLON
Don't treat ; as special.
Definition: extract.h:53
#define TOKEN_NO_FLAGS
No flags are set.
Definition: extract.h:46
void mutt_grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition: group.c:202
void mutt_grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition: group.c:271
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
@ LL_DEBUG4
Log at debug level 4.
Definition: logging2.h:46
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
@ LL_NOTIFY
Log of notifications.
Definition: logging2.h:48
#define FREE(x)
Definition: memory.h:45
#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:253
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition: notify_type.h:37
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:809
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
void alias_reverse_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition: reverse.c:61
void alias_reverse_delete(struct Alias *alias)
Remove an email address lookup for an Alias.
Definition: reverse.c:83
An email address.
Definition: address.h:36
bool group
Group mailbox?
Definition: address.h:39
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
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
char * dptr
Current read/write position.
Definition: buffer.h:38
char * data
Pointer to data.
Definition: buffer.h:37
An alias-change event.
Definition: alias.h:66
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct Notify * notify
Notifications handler.
Definition: neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
+ Here is the call graph for this function:

◆ parse_unalias()

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

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

Definition at line 251 of file commands.c.

253{
254 do
255 {
257
258 struct Alias *np = NULL;
259 if (mutt_str_equal("*", buf->data))
260 {
261 TAILQ_FOREACH(np, &Aliases, entries)
262 {
264 }
265
267 return MUTT_CMD_SUCCESS;
268 }
269
270 TAILQ_FOREACH(np, &Aliases, entries)
271 {
272 if (!mutt_istr_equal(buf->data, np->name))
273 continue;
274
275 TAILQ_REMOVE(&Aliases, np, entries);
277 alias_free(&np);
278 break;
279 }
280 } while (MoreArgs(s));
281 return MUTT_CMD_SUCCESS;
282}
void alias_free(struct Alias **ptr)
Free an Alias.
Definition: alias.c:672
void aliaslist_clear(struct AliasList *al)
Empty a List of Aliases.
Definition: alias.c:697
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:841
+ Here is the call graph for this function:

◆ parse_alternates()

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

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

Definition at line 92 of file alternates.c.

94{
95 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
96
97 do
98 {
100
101 if (parse_grouplist(&gl, buf, s, err) == -1)
102 goto bail;
103
105
106 if (mutt_regexlist_add(&Alternates, buf->data, REG_ICASE, err) != 0)
107 goto bail;
108
109 if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
110 goto bail;
111 } while (MoreArgs(s));
112
114
115 mutt_debug(LL_NOTIFY, "NT_ALTERN_ADD: %s\n", buf->data);
117
118 return MUTT_CMD_SUCCESS;
119
120bail:
122 return MUTT_CMD_ERROR;
123}
static struct RegexList Alternates
List of regexes to match the user's alternate email addresses.
Definition: alternates.c:42
static struct Notify * AlternatesNotify
Notifications: NotifyAlternates.
Definition: alternates.c:44
static struct RegexList UnAlternates
List of regexes to exclude false matches in Alternates.
Definition: alternates.c:43
@ NT_ALTERN_ADD
Alternate address has been added.
Definition: alternates.h:42
int mutt_grouplist_add_regex(struct GroupList *gl, const char *s, uint16_t flags, struct Buffer *err)
Add matching Addresses to a GroupList.
Definition: group.c:321
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:140
int mutt_regexlist_remove(struct RegexList *rl, const char *str)
Remove a Regex from a list.
Definition: regex.c:235
@ NT_ALTERN
Alternates command changed, NotifyAlternates.
Definition: notify_type.h:38
+ Here is the call graph for this function:

◆ parse_unalternates()

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

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

Definition at line 128 of file alternates.c.

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

◆ parse_attachments()

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

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

Definition at line 476 of file attachments.c.

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

◆ parse_unattachments()

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

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

Definition at line 535 of file attachments.c.

537{
538 char op;
539 char *p = NULL;
540 struct ListHead *head = NULL;
541
543 if (!buf->data || (*buf->data == '\0'))
544 {
545 buf_strcpy(err, _("unattachments: no disposition"));
546 return MUTT_CMD_WARNING;
547 }
548
549 p = buf->data;
550 op = *p++;
551
552 if (op == '*')
553 {
558
559 mutt_debug(LL_NOTIFY, "NT_ATTACH_DELETE_ALL\n");
561 return 0;
562 }
563
564 if ((op != '+') && (op != '-'))
565 {
566 op = '+';
567 p--;
568 }
569 if (mutt_istr_startswith("attachment", p))
570 {
571 if (op == '+')
572 head = &AttachAllow;
573 else
574 head = &AttachExclude;
575 }
576 else if (mutt_istr_startswith("inline", p))
577 {
578 if (op == '+')
579 head = &InlineAllow;
580 else
581 head = &InlineExclude;
582 }
583 else
584 {
585 buf_strcpy(err, _("unattachments: invalid disposition"));
586 return MUTT_CMD_ERROR;
587 }
588
589 return parse_unattach_list(buf, s, head, err);
590}
static struct Notify * AttachmentsNotify
Notifications: NotifyAttach.
Definition: attachments.c:60
static enum CommandResult parse_unattach_list(struct Buffer *buf, struct Buffer *s, struct ListHead *head, struct Buffer *err)
Parse the "unattachments" command.
Definition: attachments.c:394
@ NT_ATTACH_DELETE_ALL
All Attachment regexes have been deleted.
Definition: attachments.h:43
static void attachmatch_free(struct AttachMatch **ptr)
Free an AttachMatch - Implements list_free_t -.
Definition: attachments.c:69
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:49
@ NT_ATTACH
Attachment command changed, NotifyAttach.
Definition: notify_type.h:39
+ Here is the call graph for this function:

◆ mutt_parse_uncolor()

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

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

Definition at line 477 of file command.c.

479{
480 if (OptNoCurses) // No GUI, so quietly discard the command
481 {
482 while (MoreArgs(s))
483 {
485 }
486 return MUTT_CMD_SUCCESS;
487 }
488
489 color_debug(LL_DEBUG5, "parse: %s\n", buf_string(buf));
490 enum CommandResult rc = parse_uncolor(buf, s, err, true);
492 return rc;
493}
static enum CommandResult parse_uncolor(struct Buffer *buf, struct Buffer *s, struct Buffer *err, bool uncolor)
Parse an 'uncolor' command.
Definition: command.c:229
CommandResult
Error codes for command_t parse functions.
Definition: command.h:36
void curses_colors_dump(struct Buffer *buf)
Dump all the Curses colours.
Definition: debug.c:144
static int color_debug(enum LogLevel level, const char *format,...)
Definition: debug.h:53
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: globals.c:72
+ Here is the call graph for this function:

◆ mutt_parse_unmono()

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

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

Definition at line 498 of file command.c.

500{
501 *s->dptr = '\0'; /* fake that we're done parsing */
502 return MUTT_CMD_SUCCESS;
503}

◆ mutt_parse_color()

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

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

Definition at line 508 of file command.c.

510{
511 // No GUI, or no colours, so quietly discard the command
512 if (OptNoCurses || (COLORS == 0))
513 {
514 while (MoreArgs(s))
515 {
517 }
518 return MUTT_CMD_SUCCESS;
519 }
520
521 color_debug(LL_DEBUG5, "parse: %s\n", buf_string(buf));
522 enum CommandResult rc = parse_color(buf, s, err, parse_color_pair, true);
524 return rc;
525}
static enum CommandResult parse_color(struct Buffer *buf, struct Buffer *s, struct Buffer *err, parser_callback_t callback, bool color)
Parse a 'color' command.
Definition: command.c:321
enum CommandResult parse_color_pair(struct Buffer *buf, struct Buffer *s, struct AttrColor *ac, struct Buffer *err)
Parse a pair of colours - Implements parser_callback_t -.
Definition: parse_color.c:281
+ Here is the call graph for this function:

◆ mutt_parse_mono()

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

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

Definition at line 530 of file command.c.

532{
533 // No GUI, or colours available, so quietly discard the command
534 if (OptNoCurses || (COLORS != 0))
535 {
536 while (MoreArgs(s))
537 {
539 }
540 return MUTT_CMD_SUCCESS;
541 }
542
543 color_debug(LL_DEBUG5, "parse: %s\n", buf_string(buf));
544 enum CommandResult rc = parse_color(buf, s, err, parse_attr_spec, false);
546 return rc;
547}
enum CommandResult parse_attr_spec(struct Buffer *buf, struct Buffer *s, struct AttrColor *ac, struct Buffer *err)
Parse an attribute description - Implements parser_callback_t -.
Definition: parse_color.c:325
+ Here is the call graph for this function:

◆ parse_cd()

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

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

Definition at line 354 of file commands.c.

356{
358 buf_expand_path(buf);
359 if (buf_is_empty(buf))
360 {
361 if (HomeDir)
362 {
363 buf_strcpy(buf, HomeDir);
364 }
365 else
366 {
367 buf_printf(err, _("%s: too few arguments"), "cd");
368 return MUTT_CMD_ERROR;
369 }
370 }
371
372 if (chdir(buf_string(buf)) != 0)
373 {
374 buf_printf(err, "cd: %s", strerror(errno));
375 return MUTT_CMD_ERROR;
376 }
377
378 return MUTT_CMD_SUCCESS;
379}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
char * HomeDir
User's home directory.
Definition: globals.c:38
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:328
+ Here is the call graph for this function:

◆ parse_echo()

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

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

Definition at line 384 of file commands.c.

386{
387 if (!MoreArgs(s))
388 {
389 buf_printf(err, _("%s: too few arguments"), "echo");
390 return MUTT_CMD_WARNING;
391 }
393 OptForceRefresh = true;
394 mutt_message("%s", buf->data);
395 OptForceRefresh = false;
396 mutt_sleep(0);
397
398 return MUTT_CMD_SUCCESS;
399}
bool OptForceRefresh
(pseudo) refresh even during macros
Definition: globals.c:65
#define mutt_message(...)
Definition: logging2.h:91
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:878
+ Here is the call graph for this function:

◆ parse_finish()

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

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

Return values
MUTT_CMD_FINISHStop processing the current file
MUTT_CMD_WARNINGFailed

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

Definition at line 408 of file commands.c.

410{
411 if (MoreArgs(s))
412 {
413 buf_printf(err, _("%s: too many arguments"), "finish");
414 return MUTT_CMD_WARNING;
415 }
416
417 return MUTT_CMD_FINISH;
418}
@ MUTT_CMD_FINISH
Finish: Stop processing this file.
Definition: command.h:40
+ Here is the call graph for this function:

◆ parse_group()

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

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

Definition at line 423 of file commands.c.

425{
426 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
427 enum GroupState gstate = GS_NONE;
428
429 do
430 {
432 if (parse_grouplist(&gl, buf, s, err) == -1)
433 goto bail;
434
435 if ((data == MUTT_UNGROUP) && mutt_istr_equal(buf->data, "*"))
436 {
438 goto out;
439 }
440
441 if (mutt_istr_equal(buf->data, "-rx"))
442 {
443 gstate = GS_RX;
444 }
445 else if (mutt_istr_equal(buf->data, "-addr"))
446 {
447 gstate = GS_ADDR;
448 }
449 else
450 {
451 switch (gstate)
452 {
453 case GS_NONE:
454 buf_printf(err, _("%sgroup: missing -rx or -addr"),
455 (data == MUTT_UNGROUP) ? "un" : "");
456 goto warn;
457
458 case GS_RX:
459 if ((data == MUTT_GROUP) &&
460 (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0))
461 {
462 goto bail;
463 }
464 else if ((data == MUTT_UNGROUP) &&
465 (mutt_grouplist_remove_regex(&gl, buf->data) < 0))
466 {
467 goto bail;
468 }
469 break;
470
471 case GS_ADDR:
472 {
473 char *estr = NULL;
474 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
475 mutt_addrlist_parse2(&al, buf->data);
476 if (TAILQ_EMPTY(&al))
477 goto bail;
478 if (mutt_addrlist_to_intl(&al, &estr))
479 {
480 buf_printf(err, _("%sgroup: warning: bad IDN '%s'"),
481 (data == 1) ? "un" : "", estr);
483 FREE(&estr);
484 goto bail;
485 }
486 if (data == MUTT_GROUP)
488 else if (data == MUTT_UNGROUP)
491 break;
492 }
493 }
494 }
495 } while (MoreArgs(s));
496
497out:
499 return MUTT_CMD_SUCCESS;
500
501bail:
503 return MUTT_CMD_ERROR;
504
505warn:
507 return MUTT_CMD_WARNING;
508}
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 mutt_grouplist_remove_addrlist(struct GroupList *gl, struct AddressList *al)
Remove an AddressList from a GroupList.
Definition: group.c:290
int mutt_grouplist_remove_regex(struct GroupList *gl, const char *s)
Remove matching addresses from a GroupList.
Definition: group.c:346
void mutt_grouplist_clear(struct GroupList *gl)
Clear a GroupList.
Definition: group.c:148
#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:721
+ Here is the call graph for this function:

◆ parse_ifdef()

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

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

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

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

Definition at line 523 of file commands.c.

525{
527
528 if (buf_is_empty(buf))
529 {
530 buf_printf(err, _("%s: too few arguments"), (data ? "ifndef" : "ifdef"));
531 return MUTT_CMD_WARNING;
532 }
533
534 // is the item defined as:
535 bool res = cs_subset_lookup(NeoMutt->sub, buf->data) // a variable?
536 || feature_enabled(buf->data) // a compiled-in feature?
537 || is_function(buf->data) // a function?
538 || command_get(buf->data) // a command?
539#ifdef USE_HCACHE
540 || store_is_valid_backend(buf->data) // a store? (database)
541#endif
542 || mutt_str_getenv(buf->data); // an environment variable?
543
544 if (!MoreArgs(s))
545 {
546 buf_printf(err, _("%s: too few arguments"), (data ? "ifndef" : "ifdef"));
547 return MUTT_CMD_WARNING;
548 }
550
551 /* ifdef KNOWN_SYMBOL or ifndef UNKNOWN_SYMBOL */
552 if ((res && (data == 0)) || (!res && (data == 1)))
553 {
554 enum CommandResult rc = parse_rc_line(buf->data, err);
555 if (rc == MUTT_CMD_ERROR)
556 {
557 mutt_error(_("Error: %s"), buf_string(err));
558 return MUTT_CMD_ERROR;
559 }
560 return rc;
561 }
562 return MUTT_CMD_SUCCESS;
563}
static bool is_function(const char *name)
Is the argument a neomutt function?
Definition: commands.c:107
struct Command * command_get(const char *s)
Get a Command by its name.
Definition: command.c:87
#define mutt_error(...)
Definition: logging2.h:92
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:726
enum CommandResult parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: rc.c:104
bool store_is_valid_backend(const char *str)
Is the string a valid Store backend.
Definition: store.c:129
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:187
bool feature_enabled(const char *name)
Test if a compile-time feature is enabled.
Definition: version.c:552
+ Here is the call graph for this function:

◆ parse_ignore()

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

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

Definition at line 568 of file commands.c.

570{
571 do
572 {
575 add_to_stailq(&Ignore, buf->data);
576 } while (MoreArgs(s));
577
578 return MUTT_CMD_SUCCESS;
579}
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:1172
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1147
+ Here is the call graph for this function:

◆ parse_lists()

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

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

Definition at line 584 of file commands.c.

586{
587 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
588
589 do
590 {
592
593 if (parse_grouplist(&gl, buf, s, err) == -1)
594 goto bail;
595
597
598 if (mutt_regexlist_add(&MailLists, buf->data, REG_ICASE, err) != 0)
599 goto bail;
600
601 if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
602 goto bail;
603 } while (MoreArgs(s));
604
606 return MUTT_CMD_SUCCESS;
607
608bail:
610 return MUTT_CMD_ERROR;
611}
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 ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

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

This is also used by 'virtual-mailboxes'.

Definition at line 739 of file commands.c.

741{
743
744 struct Buffer *label = buf_pool_get();
745 struct Buffer *mailbox = buf_pool_get();
746
747 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
748 while (MoreArgs(s))
749 {
750 bool label_set = false;
751 enum TriBool notify = TB_UNSET;
752 enum TriBool poll = TB_UNSET;
753
754 do
755 {
756 // Start by handling the options
758
759 if (mutt_str_equal(buf_string(buf), "-label"))
760 {
761 if (!MoreArgs(s))
762 {
763 buf_printf(err, _("%s: too few arguments"), "mailboxes -label");
764 goto done;
765 }
766
768 label_set = true;
769 }
770 else if (mutt_str_equal(buf_string(buf), "-nolabel"))
771 {
772 buf_reset(label);
773 label_set = true;
774 }
775 else if (mutt_str_equal(buf_string(buf), "-notify"))
776 {
777 notify = TB_TRUE;
778 }
779 else if (mutt_str_equal(buf_string(buf), "-nonotify"))
780 {
781 notify = TB_FALSE;
782 }
783 else if (mutt_str_equal(buf_string(buf), "-poll"))
784 {
785 poll = TB_TRUE;
786 }
787 else if (mutt_str_equal(buf_string(buf), "-nopoll"))
788 {
789 poll = TB_FALSE;
790 }
791 else if ((data & MUTT_NAMED) && !label_set)
792 {
793 if (!MoreArgs(s))
794 {
795 buf_printf(err, _("%s: too few arguments"), "named-mailboxes");
796 goto done;
797 }
798
799 buf_copy(label, buf);
800 label_set = true;
801 }
802 else
803 {
804 buf_copy(mailbox, buf);
805 break;
806 }
807 } while (MoreArgs(s));
808
809 if (buf_is_empty(mailbox))
810 {
811 buf_printf(err, _("%s: too few arguments"), "mailboxes");
812 goto done;
813 }
814
815 rc = mailbox_add(c_folder, buf_string(mailbox),
816 label_set ? buf_string(label) : NULL, poll, notify, err);
817 if (rc != MUTT_CMD_SUCCESS)
818 goto done;
819
820 buf_reset(label);
821 buf_reset(mailbox);
822 }
823
824 rc = MUTT_CMD_SUCCESS;
825
826done:
827 buf_pool_release(&label);
828 buf_pool_release(&mailbox);
829 return rc;
830}
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:623
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
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
String manipulation buffer.
Definition: buffer.h:36
+ Here is the call graph for this function:

◆ parse_my_hdr()

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

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

Definition at line 835 of file commands.c.

837{
839 char *p = strpbrk(buf->data, ": \t");
840 if (!p || (*p != ':'))
841 {
842 buf_strcpy(err, _("invalid header field"));
843 return MUTT_CMD_WARNING;
844 }
845
846 struct EventHeader ev_h = { buf->data };
847 struct ListNode *n = header_find(&UserHeader, buf->data);
848
849 if (n)
850 {
851 header_update(n, buf->data);
852 mutt_debug(LL_NOTIFY, "NT_HEADER_CHANGE: %s\n", buf->data);
854 }
855 else
856 {
857 header_add(&UserHeader, buf->data);
858 mutt_debug(LL_NOTIFY, "NT_HEADER_ADD: %s\n", buf->data);
860 }
861
862 return MUTT_CMD_SUCCESS;
863}
struct ListNode * header_add(struct ListHead *hdrlist, const char *header)
Add a header to a list.
Definition: email.c:166
struct ListNode * header_update(struct ListNode *hdr, const char *header)
Update an existing header.
Definition: email.c:180
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:143
@ NT_HEADER_CHANGE
An existing header has been changed.
Definition: email.h:213
@ NT_HEADER_ADD
Header has been added.
Definition: email.h:211
struct ListHead UserHeader
List of custom headers to add to outgoing emails.
Definition: globals.c:54
@ NT_HEADER
A header has changed, NotifyHeader EventHeader.
Definition: notify_type.h:47
An event that happened to a header.
Definition: email.h:220
A List node for strings.
Definition: list.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_setenv()

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

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

Definition at line 918 of file commands.c.

920{
921 char **envp = EnvList;
922
923 bool query = false;
924 bool prefix = false;
925 bool unset = (data == MUTT_SET_UNSET);
926
927 if (!MoreArgs(s))
928 {
929 if (!StartupComplete)
930 {
931 buf_printf(err, _("%s: too few arguments"), "setenv");
932 return MUTT_CMD_WARNING;
933 }
934
935 struct Buffer *tempfile = buf_pool_get();
936 buf_mktemp(tempfile);
937
938 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
939 if (!fp_out)
940 {
941 // L10N: '%s' is the file name of the temporary file
942 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
943 buf_pool_release(&tempfile);
944 return MUTT_CMD_ERROR;
945 }
946
947 int count = 0;
948 for (char **env = EnvList; *env; env++)
949 count++;
950
951 mutt_qsort_r(EnvList, count, sizeof(char *), envlist_sort, NULL);
952
953 for (char **env = EnvList; *env; env++)
954 fprintf(fp_out, "%s\n", *env);
955
956 mutt_file_fclose(&fp_out);
957
958 struct PagerData pdata = { 0 };
959 struct PagerView pview = { &pdata };
960
961 pdata.fname = buf_string(tempfile);
962
963 pview.banner = "setenv";
965 pview.mode = PAGER_MODE_OTHER;
966
967 mutt_do_pager(&pview, NULL);
968 buf_pool_release(&tempfile);
969
970 return MUTT_CMD_SUCCESS;
971 }
972
973 if (*s->dptr == '?')
974 {
975 query = true;
976 prefix = true;
977
978 if (unset)
979 {
980 buf_printf(err, _("Can't query option with the '%s' command"), "unsetenv");
981 return MUTT_CMD_WARNING;
982 }
983
984 s->dptr++;
985 }
986
987 /* get variable name */
989
990 if (*s->dptr == '?')
991 {
992 if (unset)
993 {
994 buf_printf(err, _("Can't query option with the '%s' command"), "unsetenv");
995 return MUTT_CMD_WARNING;
996 }
997
998 if (prefix)
999 {
1000 buf_printf(err, _("Can't use a prefix when querying a variable"));
1001 return MUTT_CMD_WARNING;
1002 }
1003
1004 query = true;
1005 s->dptr++;
1006 }
1007
1008 if (query)
1009 {
1010 bool found = false;
1011 while (envp && *envp)
1012 {
1013 /* This will display all matches for "^QUERY" */
1014 if (mutt_str_startswith(*envp, buf->data))
1015 {
1016 if (!found)
1017 {
1018 mutt_endwin();
1019 found = true;
1020 }
1021 puts(*envp);
1022 }
1023 envp++;
1024 }
1025
1026 if (found)
1027 {
1029 return MUTT_CMD_SUCCESS;
1030 }
1031
1032 buf_printf(err, _("%s is unset"), buf->data);
1033 return MUTT_CMD_WARNING;
1034 }
1035
1036 if (unset)
1037 {
1038 if (!envlist_unset(&EnvList, buf->data))
1039 {
1040 buf_printf(err, _("%s is unset"), buf->data);
1041 return MUTT_CMD_WARNING;
1042 }
1043 return MUTT_CMD_SUCCESS;
1044 }
1045
1046 /* set variable */
1047
1048 if (*s->dptr == '=')
1049 {
1050 s->dptr++;
1051 SKIPWS(s->dptr);
1052 }
1053
1054 if (!MoreArgs(s))
1055 {
1056 buf_printf(err, _("%s: too few arguments"), "setenv");
1057 return MUTT_CMD_WARNING;
1058 }
1059
1060 char *name = mutt_str_dup(buf->data);
1062 envlist_set(&EnvList, name, buf->data, true);
1063 FREE(&name);
1064
1065 return MUTT_CMD_SUCCESS;
1066}
bool StartupComplete
When the config has been read.
Definition: main.c:192
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:47
#define TOKEN_QUESTION
Treat '?' as a special.
Definition: extract.h:56
#define mutt_file_fclose(FP)
Definition: file.h:149
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:148
char ** EnvList
Private copy of the environment variables.
Definition: globals.c:78
static int envlist_sort(const void *a, const void *b, void *sdata)
Compare two environment strings - Implements sort_t -.
Definition: commands.c:910
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
#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:142
@ MUTT_SET_UNSET
default is to unset all vars
Definition: set.h:38
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:45
Data to be displayed by PagerView.
Definition: lib.h:161
const char * fname
Name of the file to read.
Definition: lib.h:165
Paged view into some data.
Definition: lib.h:172
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:173
enum PagerMode mode
Pager mode.
Definition: lib.h:174
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:175
const char * banner
Title to display in status bar.
Definition: lib.h:176
#define buf_mktemp(buf)
Definition: tmp.h:33
+ Here is the call graph for this function:

◆ parse_source()

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

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

Definition at line 1071 of file commands.c.

1073{
1074 char path[PATH_MAX] = { 0 };
1075
1076 do
1077 {
1078 if (parse_extract_token(buf, s, TOKEN_NO_FLAGS) != 0)
1079 {
1080 buf_printf(err, _("source: error at %s"), s->dptr);
1081 return MUTT_CMD_ERROR;
1082 }
1083 mutt_str_copy(path, buf->data, sizeof(path));
1084 mutt_expand_path(path, sizeof(path));
1085
1086 if (source_rc(path, err) < 0)
1087 {
1088 buf_printf(err, _("source: file %s could not be sourced"), path);
1089 return MUTT_CMD_ERROR;
1090 }
1091
1092 } while (MoreArgs(s));
1093
1094 return MUTT_CMD_SUCCESS;
1095}
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
Definition: commands.c:206
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:581
#define PATH_MAX
Definition: mutt.h:42
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:123
+ Here is the call graph for this function:

◆ parse_nospam()

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

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

Definition at line 1100 of file commands.c.

1102{
1103 if (!MoreArgs(s))
1104 {
1105 buf_printf(err, _("%s: too few arguments"), "nospam");
1106 return MUTT_CMD_ERROR;
1107 }
1108
1109 // Extract the first token, a regex or "*"
1111
1112 if (MoreArgs(s))
1113 {
1114 buf_printf(err, _("%s: too many arguments"), "finish");
1115 return MUTT_CMD_ERROR;
1116 }
1117
1118 // "*" is special - clear both spam and nospam lists
1119 if (mutt_str_equal(buf_string(buf), "*"))
1120 {
1123 return MUTT_CMD_SUCCESS;
1124 }
1125
1126 // If it's on the spam list, just remove it
1128 return MUTT_CMD_SUCCESS;
1129
1130 // Otherwise, add it to the nospam list
1131 if (mutt_regexlist_add(&NoSpamList, buf_string(buf), REG_ICASE, err) != 0)
1132 return MUTT_CMD_ERROR;
1133
1134 return MUTT_CMD_SUCCESS;
1135}
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:566
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:179
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:450
+ Here is the call graph for this function:

◆ parse_spam()

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

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

Definition at line 1140 of file commands.c.

1142{
1143 if (!MoreArgs(s))
1144 {
1145 buf_printf(err, _("%s: too few arguments"), "spam");
1146 return MUTT_CMD_ERROR;
1147 }
1148
1149 // Extract the first token, a regex
1151
1152 // If there's a second parameter, it's a template for the spam tag
1153 if (MoreArgs(s))
1154 {
1155 struct Buffer *templ = buf_pool_get();
1157
1158 // Add to the spam list
1159 int rc = mutt_replacelist_add(&SpamList, buf_string(buf), buf_string(templ), err);
1160 buf_pool_release(&templ);
1161 if (rc != 0)
1162 return MUTT_CMD_ERROR;
1163 }
1164 else
1165 {
1166 // If not, try to remove from the nospam list
1168 }
1169
1170 return MUTT_CMD_SUCCESS;
1171}
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:271
+ Here is the call graph for this function:

◆ parse_stailq()

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

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

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

Definition at line 1178 of file commands.c.

1180{
1181 do
1182 {
1184 add_to_stailq((struct ListHead *) data, buf->data);
1185 } while (MoreArgs(s));
1186
1187 return MUTT_CMD_SUCCESS;
1188}
+ Here is the call graph for this function:

◆ parse_subscribe()

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

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

Definition at line 1193 of file commands.c.

1195{
1196 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
1197
1198 do
1199 {
1201
1202 if (parse_grouplist(&gl, buf, s, err) == -1)
1203 goto bail;
1204
1207
1208 if (mutt_regexlist_add(&MailLists, buf->data, REG_ICASE, err) != 0)
1209 goto bail;
1210 if (mutt_regexlist_add(&SubscribedLists, buf->data, REG_ICASE, err) != 0)
1211 goto bail;
1212 if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
1213 goto bail;
1214 } while (MoreArgs(s));
1215
1217 return MUTT_CMD_SUCCESS;
1218
1219bail:
1221 return MUTT_CMD_ERROR;
1222}
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 ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

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

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

Definition at line 1231 of file commands.c.

1233{
1234 if (!buf || !s || !err)
1235 return MUTT_CMD_ERROR;
1236
1237 buf_reset(err);
1238
1239 if (MoreArgs(s))
1240 {
1242
1243 if (MoreArgs(s))
1244 {
1245 buf_printf(err, _("%s: too many arguments"), "subscribe-to");
1246 return MUTT_CMD_WARNING;
1247 }
1248
1249 if (!buf_is_empty(buf))
1250 {
1251 /* Expand and subscribe */
1252 if (imap_subscribe(mutt_expand_path(buf->data, buf->dsize), true) == 0)
1253 {
1254 mutt_message(_("Subscribed to %s"), buf->data);
1255 return MUTT_CMD_SUCCESS;
1256 }
1257
1258 buf_printf(err, _("Could not subscribe to %s"), buf->data);
1259 return MUTT_CMD_ERROR;
1260 }
1261
1262 mutt_debug(LL_DEBUG1, "Corrupted buffer");
1263 return MUTT_CMD_ERROR;
1264 }
1265
1266 buf_addstr(err, _("No folder specified"));
1267 return MUTT_CMD_WARNING;
1268}
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
int imap_subscribe(char *path, bool subscribe)
Subscribe to a mailbox.
Definition: imap.c:1223
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
size_t dsize
Length of data.
Definition: buffer.h:39
+ Here is the call graph for this function:

◆ parse_tag_formats()

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

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

Parse config like: tag-formats pgp GP

Note
This maps format -> tag

Definition at line 1277 of file commands.c.

1279{
1280 if (!s)
1281 return MUTT_CMD_ERROR;
1282
1283 struct Buffer *tagbuf = buf_pool_get();
1284 struct Buffer *fmtbuf = buf_pool_get();
1285
1286 while (MoreArgs(s))
1287 {
1289 const char *tag = buf_string(tagbuf);
1290 if (*tag == '\0')
1291 continue;
1292
1294 const char *fmt = buf_string(fmtbuf);
1295
1296 /* avoid duplicates */
1297 const char *tmp = mutt_hash_find(TagFormats, fmt);
1298 if (tmp)
1299 {
1300 mutt_warning(_("tag format '%s' already registered as '%s'"), fmt, tmp);
1301 continue;
1302 }
1303
1305 }
1306
1307 buf_pool_release(&tagbuf);
1308 buf_pool_release(&fmtbuf);
1309 return MUTT_CMD_SUCCESS;
1310}
#define mutt_warning(...)
Definition: logging2.h:90
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()

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

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

Parse config like: tag-transforms pgp P

Note
This maps tag -> transform

Definition at line 1319 of file commands.c.

1321{
1322 if (!s)
1323 return MUTT_CMD_ERROR;
1324
1325 struct Buffer *tagbuf = buf_pool_get();
1326 struct Buffer *trnbuf = buf_pool_get();
1327
1328 while (MoreArgs(s))
1329 {
1331 const char *tag = buf_string(tagbuf);
1332 if (*tag == '\0')
1333 continue;
1334
1336 const char *trn = buf_string(trnbuf);
1337
1338 /* avoid duplicates */
1339 const char *tmp = mutt_hash_find(TagTransforms, tag);
1340 if (tmp)
1341 {
1342 mutt_warning(_("tag transform '%s' already registered as '%s'"), tag, tmp);
1343 continue;
1344 }
1345
1347 }
1348
1349 buf_pool_release(&tagbuf);
1350 buf_pool_release(&trnbuf);
1351 return MUTT_CMD_SUCCESS;
1352}
struct HashTable * TagTransforms
Hash Table: "inbox" -> "i" - Alternative tag names.
Definition: tags.c:41
+ Here is the call graph for this function:

◆ parse_unignore()

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

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

Definition at line 1357 of file commands.c.

1359{
1360 do
1361 {
1363
1364 /* don't add "*" to the unignore list */
1365 if (!mutt_str_equal(buf->data, "*"))
1366 add_to_stailq(&UnIgnore, buf->data);
1367
1369 } while (MoreArgs(s));
1370
1371 return MUTT_CMD_SUCCESS;
1372}
+ Here is the call graph for this function:

◆ parse_unlists()

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

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

Definition at line 1377 of file commands.c.

1379{
1381 do
1382 {
1386
1387 if (!mutt_str_equal(buf->data, "*") &&
1388 (mutt_regexlist_add(&UnMailLists, buf->data, REG_ICASE, err) != 0))
1389 {
1390 return MUTT_CMD_ERROR;
1391 }
1392 } while (MoreArgs(s));
1393
1394 return MUTT_CMD_SUCCESS;
1395}
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 ( struct Buffer buf,
struct Buffer s,
intptr_t  data,
struct Buffer err 
)

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

This is also used by 'unvirtual-mailboxes'

Definition at line 1443 of file commands.c.

1445{
1446 while (MoreArgs(s))
1447 {
1449
1450 if (mutt_str_equal(buf->data, "*"))
1451 {
1453 return MUTT_CMD_SUCCESS;
1454 }
1455
1456 buf_expand_path(buf);
1457
1458 struct Account *a = NULL;
1459 TAILQ_FOREACH(a, &NeoMutt->accounts, entries)
1460 {
1461 struct Mailbox *m = mx_mbox_find(a, buf_string(buf));
1462 if (m)
1463 {
1464 do_unmailboxes(m);
1465 break;
1466 }
1467 }
1468 }
1469 return MUTT_CMD_SUCCESS;
1470}
static void do_unmailboxes_star(void)
Remove all Mailboxes from the Sidebar/notifications.
Definition: commands.c:1425
static void do_unmailboxes(struct Mailbox *m)
Remove a Mailbox from the Sidebar/notifications.
Definition: commands.c:1401
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1543
A group of associated Mailboxes.
Definition: account.h:36
A mailbox.
Definition: mailbox.h:79
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:47
+ Here is the call graph for this function:

◆ parse_unmy_hdr()

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

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

Definition at line 1475 of file commands.c.

1477{
1478 struct ListNode *np = NULL, *tmp = NULL;
1479 size_t l;
1480
1481 do
1482 {
1484 if (mutt_str_equal("*", buf->data))
1485 {
1486 /* Clear all headers, send a notification for each header */
1487 STAILQ_FOREACH(np, &UserHeader, entries)
1488 {
1489 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1490 struct EventHeader ev_h = { np->data };
1492 }
1494 continue;
1495 }
1496
1497 l = mutt_str_len(buf->data);
1498 if (buf->data[l - 1] == ':')
1499 l--;
1500
1501 STAILQ_FOREACH_SAFE(np, &UserHeader, entries, tmp)
1502 {
1503 if (mutt_istrn_equal(buf->data, np->data, l) && (np->data[l] == ':'))
1504 {
1505 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1506 struct EventHeader ev_h = { np->data };
1508
1509 header_free(&UserHeader, np);
1510 }
1511 }
1512 } while (MoreArgs(s));
1513 return MUTT_CMD_SUCCESS;
1514}
void header_free(struct ListHead *hdrlist, struct ListNode *target)
Free and remove a header from a header list.
Definition: email.c:208
@ NT_HEADER_DELETE
Header has been removed.
Definition: email.h:212
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:496
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:453
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
char * data
String.
Definition: list.h:37
+ Here is the call graph for this function:

◆ parse_unstailq()

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

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

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

Definition at line 1521 of file commands.c.

1523{
1524 do
1525 {
1527 /* Check for deletion of entire list */
1528 if (mutt_str_equal(buf->data, "*"))
1529 {
1530 mutt_list_free((struct ListHead *) data);
1531 break;
1532 }
1533 remove_from_stailq((struct ListHead *) data, buf->data);
1534 } while (MoreArgs(s));
1535
1536 return MUTT_CMD_SUCCESS;
1537}
+ Here is the call graph for this function:

◆ parse_unsubscribe()

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

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

Definition at line 1542 of file commands.c.

1544{
1546 do
1547 {
1550
1551 if (!mutt_str_equal(buf->data, "*") &&
1552 (mutt_regexlist_add(&UnSubscribedLists, buf->data, REG_ICASE, err) != 0))
1553 {
1554 return MUTT_CMD_ERROR;
1555 }
1556 } while (MoreArgs(s));
1557
1558 return MUTT_CMD_SUCCESS;
1559}
+ Here is the call graph for this function:

◆ parse_unsubscribe_from()

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

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

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

Definition at line 1568 of file commands.c.

1570{
1571 if (!buf || !s || !err)
1572 return MUTT_CMD_ERROR;
1573
1574 if (MoreArgs(s))
1575 {
1577
1578 if (MoreArgs(s))
1579 {
1580 buf_printf(err, _("%s: too many arguments"), "unsubscribe-from");
1581 return MUTT_CMD_WARNING;
1582 }
1583
1584 if (buf->data && (*buf->data != '\0'))
1585 {
1586 /* Expand and subscribe */
1587 if (imap_subscribe(mutt_expand_path(buf->data, buf->dsize), false) == 0)
1588 {
1589 mutt_message(_("Unsubscribed from %s"), buf->data);
1590 return MUTT_CMD_SUCCESS;
1591 }
1592
1593 buf_printf(err, _("Could not unsubscribe from %s"), buf->data);
1594 return MUTT_CMD_ERROR;
1595 }
1596
1597 mutt_debug(LL_DEBUG1, "Corrupted buffer");
1598 return MUTT_CMD_ERROR;
1599 }
1600
1601 buf_addstr(err, _("No folder specified"));
1602 return MUTT_CMD_WARNING;
1603}
+ Here is the call graph for this function:

◆ parse_version()

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

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

Definition at line 1608 of file commands.c.

1610{
1611 // silently ignore 'version' if it's in a config file
1612 if (!StartupComplete)
1613 return MUTT_CMD_SUCCESS;
1614
1615 struct Buffer *tempfile = buf_pool_get();
1616 buf_mktemp(tempfile);
1617
1618 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
1619 if (!fp_out)
1620 {
1621 // L10N: '%s' is the file name of the temporary file
1622 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
1623 buf_pool_release(&tempfile);
1624 return MUTT_CMD_ERROR;
1625 }
1626
1627 print_version(fp_out);
1628 mutt_file_fclose(&fp_out);
1629
1630 struct PagerData pdata = { 0 };
1631 struct PagerView pview = { &pdata };
1632
1633 pdata.fname = buf_string(tempfile);
1634
1635 pview.banner = "version";
1636 pview.flags = MUTT_PAGER_NO_FLAGS;
1637 pview.mode = PAGER_MODE_OTHER;
1638
1639 mutt_do_pager(&pview, NULL);
1640 buf_pool_release(&tempfile);
1641
1642 return MUTT_CMD_SUCCESS;
1643}
bool print_version(FILE *fp)
Print system and compile info to a file.
Definition: version.c:393
+ Here is the call graph for this function:

◆ mutt_parse_charset_iconv_hook()

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

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

Definition at line 124 of file hook.c.

126{
127 struct Buffer *alias = buf_pool_get();
128 struct Buffer *charset = buf_pool_get();
129
130 int rc = MUTT_CMD_ERROR;
131
132 if (parse_extract_token(alias, s, TOKEN_NO_FLAGS) < 0)
133 goto done;
134 if (parse_extract_token(charset, s, TOKEN_NO_FLAGS) < 0)
135 goto done;
136
138
139 if (buf_is_empty(alias) || buf_is_empty(charset))
140 {
141 buf_printf(err, _("%s: too few arguments"), buf->data);
142 rc = MUTT_CMD_WARNING;
143 }
144 else if (MoreArgs(s))
145 {
146 buf_printf(err, _("%s: too many arguments"), buf->data);
147 buf_reset(s); // clean up buffer to avoid a mess with further rcfile processing
148 rc = MUTT_CMD_WARNING;
149 }
150 else if (mutt_ch_lookup_add(type, buf_string(alias), buf_string(charset), err))
151 {
152 rc = MUTT_CMD_SUCCESS;
153 }
154
155done:
156 buf_pool_release(&alias);
157 buf_pool_release(&charset);
158
159 return rc;
160}
#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:68
@ MUTT_LOOKUP_ICONV
Character set conversion.
Definition: charset.h:70
@ MUTT_LOOKUP_CHARSET
Alias for another character set.
Definition: charset.h:69
+ Here is the call graph for this function:

◆ mutt_parse_hook()

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

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

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

Definition at line 167 of file hook.c.

169{
170 struct Hook *hook = NULL;
171 int rc = MUTT_CMD_ERROR;
172 bool pat_not = false;
173 bool use_regex = true;
174 regex_t *rx = NULL;
175 struct PatternList *pat = NULL;
176 const bool folder_or_mbox = (data & (MUTT_FOLDER_HOOK | MUTT_MBOX_HOOK));
177
178 struct Buffer *cmd = buf_pool_get();
179 struct Buffer *pattern = buf_pool_get();
180
181 if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
182 {
183 if (*s->dptr == '!')
184 {
185 s->dptr++;
186 SKIPWS(s->dptr);
187 pat_not = true;
188 }
189
191 if (folder_or_mbox && mutt_str_equal(buf_string(pattern), "-noregex"))
192 {
193 use_regex = false;
194 if (!MoreArgs(s))
195 {
196 buf_printf(err, _("%s: too few arguments"), buf->data);
197 rc = MUTT_CMD_WARNING;
198 goto cleanup;
199 }
201 }
202
203 if (!MoreArgs(s))
204 {
205 buf_printf(err, _("%s: too few arguments"), buf->data);
206 rc = MUTT_CMD_WARNING;
207 goto cleanup;
208 }
209 }
210
211 parse_extract_token(cmd, s,
216
217 if (buf_is_empty(cmd))
218 {
219 buf_printf(err, _("%s: too few arguments"), buf->data);
220 rc = MUTT_CMD_WARNING;
221 goto cleanup;
222 }
223
224 if (MoreArgs(s))
225 {
226 buf_printf(err, _("%s: too many arguments"), buf->data);
227 rc = MUTT_CMD_WARNING;
228 goto cleanup;
229 }
230
231 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
232 if (folder_or_mbox)
233 {
234 /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
235 * common mistake */
236 if ((pattern->data[0] == '^') && !CurrentFolder)
237 {
238 buf_strcpy(err, _("current mailbox shortcut '^' is unset"));
239 goto cleanup;
240 }
241
242 struct Buffer *tmp = buf_pool_get();
243 buf_copy(tmp, pattern);
244 buf_expand_path_regex(tmp, use_regex);
245
246 /* Check for other mailbox shortcuts that expand to the empty string.
247 * This is likely a mistake too */
248 if (buf_is_empty(tmp) && !buf_is_empty(pattern))
249 {
250 buf_strcpy(err, _("mailbox shortcut expanded to empty regex"));
251 buf_pool_release(&tmp);
252 goto cleanup;
253 }
254
255 if (use_regex)
256 {
257 buf_copy(pattern, tmp);
258 }
259 else
260 {
262 }
263 buf_pool_release(&tmp);
264 }
266 {
267 if (mutt_comp_valid_command(buf_string(cmd)) == 0)
268 {
269 buf_strcpy(err, _("badly formatted command string"));
270 goto cleanup;
271 }
272 }
273 else if (c_default_hook && (~data & MUTT_GLOBAL_HOOK) &&
275 {
276 /* At this stage only these hooks remain:
277 * fcc-, fcc-save-, index-format-, message-, reply-, save-, send- and send2-hook
278 * If given a plain string, or regex, we expand it using $default_hook. */
279 mutt_check_simple(pattern, c_default_hook);
280 }
281
283 {
284 buf_expand_path(cmd);
285 }
286
287 /* check to make sure that a matching hook doesn't already exist */
288 TAILQ_FOREACH(hook, &Hooks, entries)
289 {
291 {
292 /* Ignore duplicate global hooks */
293 if (mutt_str_equal(hook->command, buf_string(cmd)))
294 {
295 rc = MUTT_CMD_SUCCESS;
296 goto cleanup;
297 }
298 }
299 else if ((hook->type == data) && (hook->regex.pat_not == pat_not) &&
300 mutt_str_equal(buf_string(pattern), hook->regex.pattern))
301 {
305 {
306 /* these hooks allow multiple commands with the same
307 * pattern, so if we've already seen this pattern/command pair, just
308 * ignore it instead of creating a duplicate */
309 if (mutt_str_equal(hook->command, buf_string(cmd)))
310 {
311 rc = MUTT_CMD_SUCCESS;
312 goto cleanup;
313 }
314 }
315 else
316 {
317 /* other hooks only allow one command per pattern, so update the
318 * entry with the new command. this currently does not change the
319 * order of execution of the hooks, which i think is desirable since
320 * a common action to perform is to change the default (.) entry
321 * based upon some other information. */
322 FREE(&hook->command);
323 hook->command = buf_strdup(cmd);
325 rc = MUTT_CMD_SUCCESS;
326 goto cleanup;
327 }
328 }
329 }
330
333 {
334 PatternCompFlags comp_flags;
335
336 if (data & (MUTT_SEND2_HOOK))
337 comp_flags = MUTT_PC_SEND_MODE_SEARCH;
338 else if (data & (MUTT_SEND_HOOK | MUTT_FCC_HOOK))
339 comp_flags = MUTT_PC_NO_FLAGS;
340 else
341 comp_flags = MUTT_PC_FULL_MSG;
342
343 struct MailboxView *mv_cur = get_current_mailbox_view();
344 struct Menu *menu = get_current_menu();
345 pat = mutt_pattern_comp(mv_cur, menu, buf_string(pattern), comp_flags, err);
346 if (!pat)
347 goto cleanup;
348 }
349 else if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
350 {
351 /* Hooks not allowing full patterns: Check syntax of regex */
352 rx = mutt_mem_calloc(1, sizeof(regex_t));
353 int rc2 = REG_COMP(rx, buf_string(pattern), ((data & MUTT_CRYPT_HOOK) ? REG_ICASE : 0));
354 if (rc2 != 0)
355 {
356 regerror(rc2, rx, err->data, err->dsize);
357 FREE(&rx);
358 goto cleanup;
359 }
360 }
361
362 struct Expando *exp = NULL;
364 exp = expando_parse(buf_string(cmd), IndexFormatDef, err);
365
366 hook = hook_new();
367 hook->type = data;
368 hook->command = buf_strdup(cmd);
370 hook->pattern = pat;
371 hook->regex.pattern = buf_strdup(pattern);
372 hook->regex.regex = rx;
373 hook->regex.pat_not = pat_not;
374 hook->expando = exp;
375
376 TAILQ_INSERT_TAIL(&Hooks, hook, entries);
377 rc = MUTT_CMD_SUCCESS;
378
379cleanup:
380 buf_pool_release(&cmd);
381 buf_pool_release(&pattern);
382 return rc;
383}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:571
char * mutt_get_sourced_cwd(void)
Get the current file path that is being parsed.
Definition: commands.c:185
struct PatternList * mutt_pattern_comp(struct MailboxView *mv, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:906
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition: compress.c:414
struct Expando * expando_parse(const char *str, const struct ExpandoDefinition *defs, struct Buffer *err)
Parse an Expando string.
Definition: expando.c:74
int mutt_file_sanitize_regex(struct Buffer *dest, const char *src)
Escape any regex-magic characters in a string.
Definition: file.c:754
char * CurrentFolder
Currently selected mailbox.
Definition: globals.c:43
const struct ExpandoDefinition IndexFormatDef[]
Expando definitions.
Definition: mutt_config.c:296
static struct HookList Hooks
All simple hooks, e.g. MUTT_FOLDER_HOOK.
Definition: hook.c:80
static struct Hook * hook_new(void)
Create a Hook.
Definition: hook.c:116
#define MUTT_OPEN_HOOK
open-hook: to read a compressed mailbox
Definition: hook.h:49
#define MUTT_FOLDER_HOOK
folder-hook: when entering a mailbox
Definition: hook.h:37
#define MUTT_SAVE_HOOK
save-hook: set a default folder when saving an email
Definition: hook.h:41
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:39
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition: hook.h:40
#define MUTT_CLOSE_HOOK
close-hook: write to a compressed mailbox
Definition: hook.h:51
#define MUTT_ACCOUNT_HOOK
account-hook: when changing between accounts
Definition: hook.h:46
#define MUTT_APPEND_HOOK
append-hook: append to a compressed mailbox
Definition: hook.h:50
#define MUTT_GLOBAL_HOOK
Hooks which don't take a regex.
Definition: hook.h:56
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:54
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:48
#define MUTT_CRYPT_HOOK
crypt-hook: automatically select a PGP/SMIME key
Definition: hook.h:45
#define MUTT_MBOX_HOOK
mbox-hook: move messages after reading them
Definition: hook.h:38
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:47
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:53
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:44
#define MUTT_SHUTDOWN_HOOK
shutdown-hook: run when leaving NeoMutt
Definition: hook.h:55
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:52
struct MailboxView * get_current_mailbox_view(void)
Get the current Mailbox view.
Definition: index.c:683
struct Menu * get_current_menu(void)
Get the current Menu.
Definition: index.c:731
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
void buf_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:135
#define WithCrypto
Definition: lib.h:116
#define MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition: lib.h: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:112
#define MUTT_PC_NO_FLAGS
No flags are set.
Definition: lib.h:68
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:49
Parsed Expando trees.
Definition: expando.h:41
A list of user hooks.
Definition: hook.c:68
HookFlags type
Hook type.
Definition: hook.c:69
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:73
struct Regex regex
Regular expression.
Definition: hook.c:70
char * command
Filename, command or pattern to execute.
Definition: hook.c:71
struct Expando * expando
Used for format hooks.
Definition: hook.c:74
char * source_file
Used for relative-directory source.
Definition: hook.c:72
View of a Mailbox.
Definition: mview.h:40
Definition: lib.h:79
char * pattern
printable version
Definition: regex3.h:86
bool pat_not
do not match
Definition: regex3.h:88
regex_t * regex
compiled expression
Definition: regex3.h:87
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_idxfmt_hook()

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

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

Definition at line 435 of file hook.c.

437{
439 bool pat_not = false;
440
441 struct Buffer *name = buf_pool_get();
442 struct Buffer *pattern = buf_pool_get();
443 struct Buffer *fmtstring = buf_pool_get();
444 struct Expando *exp = NULL;
445
446 if (!IdxFmtHooks)
447 {
450 }
451
452 if (!MoreArgs(s))
453 {
454 buf_printf(err, _("%s: too few arguments"), buf->data);
455 goto out;
456 }
458 struct HookList *hl = mutt_hash_find(IdxFmtHooks, buf_string(name));
459
460 if (*s->dptr == '!')
461 {
462 s->dptr++;
463 SKIPWS(s->dptr);
464 pat_not = true;
465 }
467
468 if (!MoreArgs(s))
469 {
470 buf_printf(err, _("%s: too few arguments"), buf->data);
471 goto out;
472 }
473 parse_extract_token(fmtstring, s, TOKEN_NO_FLAGS);
474
475 exp = expando_parse(buf_string(fmtstring), IndexFormatDef, err);
476 if (!exp)
477 goto out;
478
479 if (MoreArgs(s))
480 {
481 buf_printf(err, _("%s: too many arguments"), buf->data);
482 goto out;
483 }
484
485 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
486 if (c_default_hook)
487 mutt_check_simple(pattern, c_default_hook);
488
489 /* check to make sure that a matching hook doesn't already exist */
490 struct Hook *hook = NULL;
491 if (hl)
492 {
493 TAILQ_FOREACH(hook, hl, entries)
494 {
495 if ((hook->regex.pat_not == pat_not) &&
497 {
498 expando_free(&hook->expando);
499 hook->expando = exp;
500 exp = NULL;
501 rc = MUTT_CMD_SUCCESS;
502 goto out;
503 }
504 }
505 }
506
507 /* MUTT_PC_PATTERN_DYNAMIC sets so that date ranges are regenerated during
508 * matching. This of course is slower, but index-format-hook is commonly
509 * used for date ranges, and they need to be evaluated relative to "now", not
510 * the hook compilation time. */
511 struct MailboxView *mv_cur = get_current_mailbox_view();
512 struct Menu *menu = get_current_menu();
513 struct PatternList *pat = mutt_pattern_comp(mv_cur, menu, buf_string(pattern),
515 err);
516 if (!pat)
517 goto out;
518
519 hook = hook_new();
520 hook->type = MUTT_IDXFMTHOOK;
521 hook->command = NULL;
523 hook->pattern = pat;
524 hook->regex.pattern = buf_strdup(pattern);
525 hook->regex.regex = NULL;
526 hook->regex.pat_not = pat_not;
527 hook->expando = exp;
528 exp = NULL;
529
530 if (!hl)
531 {
532 hl = mutt_mem_calloc(1, sizeof(*hl));
533 TAILQ_INIT(hl);
535 }
536
537 TAILQ_INSERT_TAIL(hl, hook, entries);
538 rc = MUTT_CMD_SUCCESS;
539
540out:
541 buf_pool_release(&name);
542 buf_pool_release(&pattern);
543 buf_pool_release(&fmtstring);
544 expando_free(&exp);
545
546 return rc;
547}
void expando_free(struct Expando **ptr)
Free an Expando object.
Definition: expando.c:54
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:409
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:259
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition: hash.c:301
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:111
static struct HashTable * IdxFmtHooks
All Index Format hooks.
Definition: hook.c:83
#define MUTT_PC_PATTERN_DYNAMIC
Enable runtime date range evaluation.
Definition: lib.h:70
#define TAILQ_INIT(head)
Definition: queue.h:765
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_unhook()

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

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

Definition at line 572 of file hook.c.

574{
575 while (MoreArgs(s))
576 {
578 if (mutt_str_equal("*", buf->data))
579 {
581 {
582 buf_addstr(err, _("unhook: Can't do unhook * from within a hook"));
583 return MUTT_CMD_WARNING;
584 }
588 }
589 else
590 {
591 HookFlags type = mutt_get_hook_type(buf->data);
592
593 if (type == MUTT_HOOK_NO_FLAGS)
594 {
595 buf_printf(err, _("unhook: unknown hook type: %s"), buf->data);
596 return MUTT_CMD_ERROR;
597 }
598 if (type & (MUTT_CHARSET_HOOK | MUTT_ICONV_HOOK))
599 {
601 return MUTT_CMD_SUCCESS;
602 }
603 if (CurrentHookType == type)
604 {
605 buf_printf(err, _("unhook: Can't delete a %s from within a %s"),
606 buf->data, buf->data);
607 return MUTT_CMD_WARNING;
608 }
609 if (type == MUTT_IDXFMTHOOK)
611 else
612 mutt_delete_hooks(type);
613 }
614 }
615 return MUTT_CMD_SUCCESS;
616}
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:391
static void delete_idxfmt_hooks(void)
Delete all the index-format-hooks.
Definition: hook.c:427
static HookFlags mutt_get_hook_type(const char *name)
Find a hook by name.
Definition: hook.c:555
static HookFlags CurrentHookType
The type of the hook currently being executed, e.g. MUTT_SAVE_HOOK.
Definition: hook.c:86
uint32_t HookFlags
Flags for mutt_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:

◆ dump_bind_macro()

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

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

Definition at line 172 of file dump.c.

174{
175 FILE *fp_out = NULL;
176 bool dump_all = false, bind = (data == 0);
177
178 if (!MoreArgs(s))
179 dump_all = true;
180 else
182
183 if (MoreArgs(s))
184 {
185 /* More arguments potentially means the user is using the
186 * ::command_t :bind command thus we delegate the task. */
187 return MUTT_CMD_ERROR;
188 }
189
190 struct Buffer *filebuf = buf_pool_get();
191 if (dump_all || mutt_istr_equal(buf_string(buf), "all"))
192 {
193 if (bind)
194 dump_all_binds(filebuf);
195 else
196 dump_all_macros(filebuf);
197 }
198 else
199 {
200 const int menu_index = mutt_map_get_value(buf_string(buf), MenuNames);
201 if (menu_index == -1)
202 {
203 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
204 buf_printf(err, _("%s: no such menu"), buf_string(buf));
205 buf_pool_release(&filebuf);
206 return MUTT_CMD_ERROR;
207 }
208
209 if (bind)
210 dump_bind(filebuf, menu_index, buf_string(buf));
211 else
212 dump_macro(filebuf, menu_index, buf_string(buf));
213 }
214
215 if (buf_is_empty(filebuf))
216 {
217 // L10N: '%s' is the name of the menu, e.g. 'index' or 'pager',
218 // it might also be 'all' when all menus are affected.
219 buf_printf(err, bind ? _("%s: no binds for this menu") : _("%s: no macros for this menu"),
220 dump_all ? "all" : buf_string(buf));
221 buf_pool_release(&filebuf);
222 return MUTT_CMD_ERROR;
223 }
224
225 struct Buffer *tempfile = buf_pool_get();
226 buf_mktemp(tempfile);
227 fp_out = mutt_file_fopen(buf_string(tempfile), "w");
228 if (!fp_out)
229 {
230 // L10N: '%s' is the file name of the temporary file
231 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
232 buf_pool_release(&filebuf);
233 buf_pool_release(&tempfile);
234 return MUTT_CMD_ERROR;
235 }
236 fputs(buf_string(filebuf), fp_out);
237
238 mutt_file_fclose(&fp_out);
239 buf_pool_release(&filebuf);
240
241 struct PagerData pdata = { 0 };
242 struct PagerView pview = { &pdata };
243
244 pdata.fname = buf_string(tempfile);
245
246 pview.banner = (bind) ? "bind" : "macro";
248 pview.mode = PAGER_MODE_OTHER;
249
250 mutt_do_pager(&pview, NULL);
251 buf_pool_release(&tempfile);
252
253 return MUTT_CMD_SUCCESS;
254}
static void dump_all_macros(struct Buffer *buf)
Dumps all the macros inside every menu.
Definition: dump.c:157
static void dump_all_binds(struct Buffer *buf)
Dumps all the binds inside every menu.
Definition: dump.c:100
static bool dump_bind(struct Buffer *buf, enum MenuType menu, const char *name)
Dumps all the binds maps of a menu into a buffer.
Definition: dump.c:51
static bool dump_macro(struct Buffer *buf, enum MenuType menu, const char *name)
Dumps all the macros maps of a menu into a buffer.
Definition: dump.c:120
int mutt_map_get_value(const char *name, const struct Mapping *map)
Lookup the constant for a string.
Definition: mapping.c:85
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_parse_push()

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

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

Definition at line 344 of file parse.c.

346{
348 if (MoreArgs(s))
349 {
350 buf_printf(err, _("%s: too many arguments"), "push");
351 return MUTT_CMD_ERROR;
352 }
353
355 return MUTT_CMD_SUCCESS;
356}
#define TOKEN_CONDENSE
^(char) to control chars (macros)
Definition: extract.h:48
void generic_tokenize_push_string(char *s)
Parse and queue a 'push' command.
Definition: lib.c:341
+ Here is the call graph for this function:

◆ mutt_parse_bind()

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

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

bind menu-name <key_sequence> function-name

Definition at line 363 of file parse.c.

365{
366 if (StartupComplete)
367 {
368 // Save and restore the offset in `s` because dump_bind_macro() might change it
369 char *dptr = s->dptr;
370 if (dump_bind_macro(buf, s, data, err) == MUTT_CMD_SUCCESS)
371 return MUTT_CMD_SUCCESS;
372 if (!buf_is_empty(err))
373 return MUTT_CMD_ERROR;
374 s->dptr = dptr;
375 }
376
377 const struct MenuFuncOp *funcs = NULL;
378 enum MenuType mtypes[MenuNamesLen];
379 int num_menus = 0;
381
382 char *key = parse_keymap(mtypes, s, mutt_array_size(mtypes), &num_menus, err, true);
383 if (!key)
384 return MUTT_CMD_ERROR;
385
386 /* function to execute */
388 if (MoreArgs(s))
389 {
390 buf_printf(err, _("%s: too many arguments"), "bind");
391 rc = MUTT_CMD_ERROR;
392 }
393 else if (mutt_istr_equal("noop", buf->data))
394 {
395 for (int i = 0; i < num_menus; i++)
396 {
397 km_bindkey(key, mtypes[i], OP_NULL); /* the 'unbind' command */
398 funcs = km_get_table(mtypes[i]);
399 if (funcs)
400 {
401 char keystr[32] = { 0 };
402 km_expand_key_string(key, keystr, sizeof(keystr));
403 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
404 mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", mname, keystr);
405
406 int op = get_op(OpGeneric, buf->data, mutt_str_len(buf->data));
407 struct EventBinding ev_b = { mtypes[i], key, op };
409 }
410 }
411 }
412 else
413 {
414 for (int i = 0; i < num_menus; i++)
415 {
416 /* The pager and editor menus don't use the generic map,
417 * however for other menus try generic first. */
418 if ((mtypes[i] != MENU_PAGER) && (mtypes[i] != MENU_EDITOR) && (mtypes[i] != MENU_GENERIC))
419 {
420 rc = try_bind(key, mtypes[i], buf->data, OpGeneric, err);
421 if (rc == MUTT_CMD_SUCCESS)
422 {
423 char keystr[32] = { 0 };
424 km_expand_key_string(key, keystr, sizeof(keystr));
425 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
426 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, keystr);
427
428 int op = get_op(OpGeneric, buf->data, mutt_str_len(buf->data));
429 struct EventBinding ev_b = { mtypes[i], key, op };
431 continue;
432 }
433 if (rc == MUTT_CMD_WARNING)
434 break;
435 }
436
437 /* Clear any error message, we're going to try again */
438 err->data[0] = '\0';
439 funcs = km_get_table(mtypes[i]);
440 if (funcs)
441 {
442 rc = try_bind(key, mtypes[i], buf->data, funcs, err);
443 if (rc == MUTT_CMD_SUCCESS)
444 {
445 char keystr[32] = { 0 };
446 km_expand_key_string(key, keystr, sizeof(keystr));
447 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
448 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, keystr);
449
450 int op = get_op(funcs, buf->data, mutt_str_len(buf->data));
451 struct EventBinding ev_b = { mtypes[i], key, op };
453 continue;
454 }
455 }
456 }
457 }
458 FREE(&key);
459 return rc;
460}
enum CommandResult dump_bind_macro(struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
Parse 'bind' and 'macro' commands - Implements Command::parse() -.
Definition: dump.c:172
const struct MenuFuncOp OpGeneric[]
Functions for the Generic Menu.
Definition: functions.c:68
const struct MenuFuncOp * km_get_table(enum MenuType mtype)
Lookup a Menu's functions.
Definition: lib.c:528
int get_op(const struct MenuFuncOp *funcs, const char *start, size_t len)
Get the function by its name.
Definition: lib.c:302
int km_expand_key_string(char *str, char *buf, size_t buflen)
Get a human-readable key string.
Definition: lib.c:489
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition: lib.h:135
@ NT_BINDING_ADD
Key binding has been added.
Definition: lib.h:134
enum CommandResult km_bindkey(const char *s, enum MenuType mtype, int op)
Bind a key in a Menu to an operation.
Definition: parse.c:186
static char * parse_keymap(enum MenuType *mtypes, struct Buffer *s, int max_menus, int *num_menus, struct Buffer *err, bool bind)
Parse a user-config key binding.
Definition: parse.c:226
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: parse.c:323
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
#define mutt_array_size(x)
Definition: memory.h:38
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition: notify_type.h:40
A key binding Event.
Definition: lib.h:119
const char * key
Key string being bound (for new bind/macro)
Definition: lib.h:121
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition: lib.h:122
Mapping between a function and an operation.
Definition: lib.h:101
int op
Operation, e.g. OP_DELETE.
Definition: lib.h:103
const int MenuNamesLen
Number of entries in the MenuNames array.
Definition: type.c:67
MenuType
Types of GUI selections.
Definition: type.h:36
@ MENU_GENERIC
Generic selection list.
Definition: type.h:46
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:55
@ MENU_EDITOR
Text entry area.
Definition: type.h:44
+ Here is the call graph for this function:

◆ mutt_parse_unbind()

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

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

Command unbinds:

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

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

Definition at line 472 of file parse.c.

474{
475 bool menu_matches[MENU_MAX] = { 0 };
476 bool all_keys = false;
477 char *key = NULL;
478
480 if (mutt_str_equal(buf->data, "*"))
481 {
482 for (enum MenuType i = 1; i < MENU_MAX; i++)
483 menu_matches[i] = true;
484 }
485 else
486 {
487 parse_menu(menu_matches, buf->data, err);
488 }
489
490 if (MoreArgs(s))
491 {
493 key = buf->data;
494 }
495 else
496 {
497 all_keys = true;
498 }
499
500 if (MoreArgs(s))
501 {
502 const char *cmd = (data & MUTT_UNMACRO) ? "unmacro" : "unbind";
503
504 buf_printf(err, _("%s: too many arguments"), cmd);
505 return MUTT_CMD_ERROR;
506 }
507
508 for (enum MenuType i = 1; i < MENU_MAX; i++)
509 {
510 if (!menu_matches[i])
511 continue;
512 if (all_keys)
513 {
514 km_unbind_all(&Keymaps[i], data);
515 km_bindkey("<enter>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
516 km_bindkey("<return>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
517 km_bindkey("<enter>", MENU_INDEX, OP_DISPLAY_MESSAGE);
518 km_bindkey("<return>", MENU_INDEX, OP_DISPLAY_MESSAGE);
519 km_bindkey("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE);
520 km_bindkey("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE);
521 km_bindkey(":", MENU_GENERIC, OP_ENTER_COMMAND);
522 km_bindkey(":", MENU_PAGER, OP_ENTER_COMMAND);
523 if (i != MENU_EDITOR)
524 {
525 km_bindkey("?", i, OP_HELP);
526 km_bindkey("q", i, OP_EXIT);
527 }
528
529 const char *mname = mutt_map_get_name(i, MenuNames);
530 mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE_ALL: %s\n", mname);
531
532 struct EventBinding ev_b = { i, NULL, OP_NULL };
535 &ev_b);
536 }
537 else
538 {
539 char keystr[32] = { 0 };
540 km_expand_key_string(key, keystr, sizeof(keystr));
541 const char *mname = mutt_map_get_name(i, MenuNames);
542 mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE: %s %s\n", mname, keystr);
543
544 km_bindkey(key, i, OP_NULL);
545 struct EventBinding ev_b = { i, key, OP_NULL };
548 }
549 }
550
551 return MUTT_CMD_SUCCESS;
552}
struct KeymapList Keymaps[MENU_MAX]
Array of key mappings, one for each MenuType.
Definition: lib.c:128
@ NT_MACRO_DELETE
Key macro has been deleted.
Definition: lib.h:139
@ NT_MACRO_DELETE_ALL
All key macros have been deleted.
Definition: lib.h:140
@ NT_BINDING_DELETE_ALL
All key bindings have been deleted.
Definition: lib.h:136
#define MUTT_UNMACRO
Parse 'unmacro' command.
Definition: lib.h:48
static void * parse_menu(bool *menus, char *s, struct Buffer *err)
Parse menu-names into an array.
Definition: parse.c:290
static void km_unbind_all(struct KeymapList *km_list, unsigned long mode)
Free all the keys in the supplied Keymap.
Definition: parse.c:198
@ MENU_INDEX
Index panel (list of emails)
Definition: type.h:51
@ MENU_MAX
Definition: type.h:60
+ Here is the call graph for this function:

◆ mutt_parse_macro()

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

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

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

Definition at line 559 of file parse.c.

561{
562 if (StartupComplete)
563 {
564 // Save and restore the offset in `s` because dump_bind_macro() might change it
565 char *dptr = s->dptr;
566 if (dump_bind_macro(buf, s, data, err) == MUTT_CMD_SUCCESS)
567 return MUTT_CMD_SUCCESS;
568 if (!buf_is_empty(err))
569 return MUTT_CMD_ERROR;
570 s->dptr = dptr;
571 }
572
573 enum MenuType mtypes[MenuNamesLen];
574 int num_menus = 0;
576
577 char *key = parse_keymap(mtypes, s, mutt_array_size(mtypes), &num_menus, err, false);
578 if (!key)
579 return MUTT_CMD_ERROR;
580
582 /* make sure the macro sequence is not an empty string */
583 if (buf->data[0] == '\0')
584 {
585 buf_strcpy(err, _("macro: empty key sequence"));
586 }
587 else
588 {
589 if (MoreArgs(s))
590 {
591 char *seq = mutt_str_dup(buf->data);
593
594 if (MoreArgs(s))
595 {
596 buf_printf(err, _("%s: too many arguments"), "macro");
597 }
598 else
599 {
600 for (int i = 0; i < num_menus; i++)
601 {
602 rc = km_bind(key, mtypes[i], OP_MACRO, seq, buf->data);
603 if (rc == MUTT_CMD_SUCCESS)
604 {
605 char keystr[32] = { 0 };
606 km_expand_key_string(key, keystr, sizeof(keystr));
607 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
608 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, keystr);
609
610 struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
612 continue;
613 }
614 }
615 }
616
617 FREE(&seq);
618 }
619 else
620 {
621 for (int i = 0; i < num_menus; i++)
622 {
623 rc = km_bind(key, mtypes[i], OP_MACRO, buf->data, NULL);
624 if (rc == MUTT_CMD_SUCCESS)
625 {
626 char keystr[32] = { 0 };
627 km_expand_key_string(key, keystr, sizeof(keystr));
628 const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
629 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, keystr);
630
631 struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
633 continue;
634 }
635 }
636 }
637 }
638 FREE(&key);
639 return rc;
640}
@ NT_MACRO_ADD
Key macro has been added.
Definition: lib.h:138
enum CommandResult km_bind(char *s, enum MenuType mtype, int op, char *macro, char *desc)
Bind a key to a macro.
Definition: parse.c:160
+ Here is the call graph for this function:

◆ mutt_parse_exec()

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

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

Definition at line 645 of file parse.c.

647{
648 int ops[128];
649 int nops = 0;
650 const struct MenuFuncOp *funcs = NULL;
651 char *function = NULL;
652
653 if (!MoreArgs(s))
654 {
655 buf_strcpy(err, _("exec: no arguments"));
656 return MUTT_CMD_ERROR;
657 }
658
659 do
660 {
662 function = buf->data;
663
664 const enum MenuType mtype = menu_get_current_type();
665 funcs = km_get_table(mtype);
666 if (!funcs && (mtype != MENU_PAGER))
667 funcs = OpGeneric;
668
669 ops[nops] = get_op(funcs, function, mutt_str_len(function));
670 if ((ops[nops] == OP_NULL) && (mtype != MENU_PAGER) && (mtype != MENU_GENERIC))
671 {
672 ops[nops] = get_op(OpGeneric, function, mutt_str_len(function));
673 }
674
675 if (ops[nops] == OP_NULL)
676 {
678 mutt_error(_("%s: no such function"), function);
679 return MUTT_CMD_ERROR;
680 }
681 nops++;
682 } while (MoreArgs(s) && nops < mutt_array_size(ops));
683
684 while (nops)
685 mutt_push_macro_event(0, ops[--nops]);
686
687 return MUTT_CMD_SUCCESS;
688}
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:

◆ mutt_lua_parse()

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

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

Definition at line 472 of file mutt_lua.c.

474{
476 mutt_debug(LL_DEBUG2, " * mutt_lua_parse(%s)\n", buf->data);
477
478 if (luaL_dostring(LuaState, s->dptr))
479 {
480 mutt_debug(LL_DEBUG2, " * %s -> failure\n", s->dptr);
481 buf_printf(err, "%s: %s", s->dptr, lua_tostring(LuaState, -1));
482 /* pop error message from the stack */
483 lua_pop(LuaState, 1);
484 return MUTT_CMD_ERROR;
485 }
486 mutt_debug(LL_DEBUG2, " * %s -> success\n", s->dptr);
487 buf_reset(s); // Clear the rest of the line
488 return MUTT_CMD_SUCCESS;
489}
@ LL_DEBUG2
Log at debug level 2.
Definition: logging2.h:44
static bool lua_init(lua_State **l)
Initialise a Lua State.
Definition: mutt_lua.c:436
static lua_State * LuaState
Global Lua State.
Definition: mutt_lua.c:57
+ Here is the call graph for this function:

◆ mutt_lua_source_file()

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

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

Definition at line 494 of file mutt_lua.c.

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

◆ parse_set()

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

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

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

Definition at line 424 of file set.c.

426{
427 /* The order must match `enum MuttSetCommand` */
428 static const char *set_commands[] = { "set", "toggle", "unset", "reset" };
429
430 if (!buf || !s)
431 return MUTT_CMD_ERROR;
432
433 do
434 {
435 bool prefix = false;
436 bool query = false;
437 bool inv = (data == MUTT_SET_INV);
438 bool reset = (data == MUTT_SET_RESET);
439 bool unset = (data == MUTT_SET_UNSET);
440
441 if (*s->dptr == '?')
442 {
443 prefix = true;
444 query = true;
445 s->dptr++;
446 }
447 else if (mutt_str_startswith(s->dptr, "no"))
448 {
449 prefix = true;
450 unset = !unset;
451 s->dptr += 2;
452 }
453 else if (mutt_str_startswith(s->dptr, "inv"))
454 {
455 prefix = true;
456 inv = !inv;
457 s->dptr += 3;
458 }
459 else if (*s->dptr == '&')
460 {
461 prefix = true;
462 reset = true;
463 s->dptr++;
464 }
465
466 if (prefix && (data != MUTT_SET_SET))
467 {
468 buf_printf(err, _("Can't use 'inv', 'no', '&' or '?' with the '%s' command"),
469 set_commands[data]);
470 return MUTT_CMD_WARNING;
471 }
472
473 // get the variable name. Note that buf might be empty if no additional
474 // argument was given.
476 if (ret == -1)
477 return MUTT_CMD_ERROR;
478
479 bool bool_or_quad = false;
480 bool equals = false;
481 bool increment = false;
482 bool decrement = false;
483
484 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, buf->data);
485 if (he)
486 {
487 // Use the correct name if a synonym is used
488 buf_strcpy(buf, he->key.strkey);
489 bool_or_quad = ((DTYPE(he->type) == DT_BOOL) || (DTYPE(he->type) == DT_QUAD));
490 }
491
492 if (*s->dptr == '?')
493 {
494 if (prefix)
495 {
496 buf_printf(err, _("Can't use a prefix when querying a variable"));
497 return MUTT_CMD_WARNING;
498 }
499
500 if (reset || unset || inv)
501 {
502 buf_printf(err, _("Can't query option with the '%s' command"), set_commands[data]);
503 return MUTT_CMD_WARNING;
504 }
505
506 query = true;
507 s->dptr++;
508 }
509 else if ((*s->dptr == '+') || (*s->dptr == '-'))
510 {
511 if (prefix)
512 {
513 buf_printf(err, _("Can't use prefix when incrementing or decrementing a variable"));
514 return MUTT_CMD_WARNING;
515 }
516
517 if (reset || unset || inv)
518 {
519 buf_printf(err, _("Can't set option with the '%s' command"), set_commands[data]);
520 return MUTT_CMD_WARNING;
521 }
522 if (*s->dptr == '+')
523 increment = true;
524 else
525 decrement = true;
526
527 s->dptr++;
528 if (*s->dptr == '=')
529 {
530 equals = true;
531 s->dptr++;
532 }
533 else
534 {
535 buf_printf(err, _("'+' and '-' must be followed by '='"));
536 return MUTT_CMD_WARNING;
537 }
538 }
539 else if (*s->dptr == '=')
540 {
541 if (prefix)
542 {
543 buf_printf(err, _("Can't use prefix when setting a variable"));
544 return MUTT_CMD_WARNING;
545 }
546
547 if (reset || unset || inv)
548 {
549 buf_printf(err, _("Can't set option with the '%s' command"), set_commands[data]);
550 return MUTT_CMD_WARNING;
551 }
552
553 equals = true;
554 s->dptr++;
555 }
556
557 if (!bool_or_quad && (inv || (unset && prefix)))
558 {
559 if (data == MUTT_SET_SET)
560 {
561 buf_printf(err, _("Prefixes 'no' and 'inv' may only be used with bool/quad variables"));
562 }
563 else
564 {
565 buf_printf(err, _("Command '%s' can only be used with bool/quad variables"),
566 set_commands[data]);
567 }
568 return MUTT_CMD_WARNING;
569 }
570
571 // sanity checks for the above
572 // Each of inv, unset reset, query, equals implies that the others are not set.
573 // If none of them are set, then we are dealing with a "set foo" command.
574 // clang-format off
575 ASSERT(!inv || !( unset || reset || query || equals ));
576 ASSERT(!unset || !(inv || reset || query || equals ));
577 ASSERT(!reset || !(inv || unset || query || equals ));
578 ASSERT(!query || !(inv || unset || reset || equals ));
579 ASSERT(!equals || !(inv || unset || reset || query || prefix));
580 // clang-format on
581 ASSERT(!(increment && decrement)); // only one of increment or decrement is set
582 ASSERT(!(increment || decrement) || equals); // increment/decrement implies equals
583 ASSERT(!inv || bool_or_quad); // inv (aka toggle) implies bool or quad
584
586 if (query)
587 {
588 rc = command_set_query(buf, err);
589 return rc; // We can only do one query even if multiple config names are given
590 }
591 else if (reset)
592 {
593 rc = command_set_reset(buf, err);
594 }
595 else if (unset)
596 {
597 rc = command_set_unset(buf, err);
598 }
599 else if (inv)
600 {
601 rc = command_set_toggle(buf, err);
602 }
603 else if (equals)
604 {
605 // These three cases all need a value, since 'increment'/'decrement'
606 // implies 'equals', we can group them in this single case guarded by
607 // 'equals'.
608 struct Buffer *value = buf_pool_get();
610 if (increment)
611 rc = command_set_increment(buf, value, err);
612 else if (decrement)
613 rc = command_set_decrement(buf, value, err);
614 else
615 rc = command_set_set(buf, value, err);
616 buf_pool_release(&value);
617 }
618 else
619 {
620 // This is the "set foo" case which has different meanings depending on
621 // the type of the config variable
622 if (bool_or_quad)
623 {
624 struct Buffer *yes = buf_pool_get();
625 buf_addstr(yes, "yes");
626 rc = command_set_set(buf, yes, err);
627 buf_pool_release(&yes);
628 }
629 else
630 {
631 rc = command_set_query(buf, err);
632 return rc; // We can only do one query even if multiple config names are given
633 }
634 }
635 // Short circuit (i.e. skipping further config variable names) if the action on
636 // the current variable failed.
637 if (rc != MUTT_CMD_SUCCESS)
638 return rc;
639 } while (MoreArgs(s));
640
641 return MUTT_CMD_SUCCESS;
642}
#define TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition: extract.h:54
#define TOKEN_PLUS
Treat '+' as a special.
Definition: extract.h:57
#define TOKEN_MINUS
Treat '-' as a special.
Definition: extract.h:58
static enum CommandResult command_set_toggle(struct Buffer *name, struct Buffer *err)
Toggle a boolean or quad variable.
Definition: set.c:333
static enum CommandResult command_set_set(struct Buffer *name, struct Buffer *value, struct Buffer *err)
Set a variable to the given value.
Definition: set.c:100
static enum CommandResult command_set_reset(struct Buffer *name, struct Buffer *err)
Reset a variable.
Definition: set.c:279
static enum CommandResult command_set_unset(struct Buffer *name, struct Buffer *err)
Unset a variable.
Definition: set.c:240
static enum CommandResult command_set_query(struct Buffer *name, struct Buffer *err)
Query a variable.
Definition: set.c:369
static enum CommandResult command_set_increment(struct Buffer *name, struct Buffer *value, struct Buffer *err)
Increment a variable by a value.
Definition: set.c:155
static enum CommandResult command_set_decrement(struct Buffer *name, struct Buffer *value, struct Buffer *err)
Decrement a variable by a value.
Definition: set.c:210
@ MUTT_SET_INV
default is to invert all vars
Definition: set.h:37
@ MUTT_SET_SET
default is to set all vars
Definition: set.h:36
@ MUTT_SET_RESET
default is to reset all vars to default
Definition: set.h:39
#define ASSERT(COND)
Definition: signal2.h:58
The item stored in a Hash Table.
Definition: hash.h:43
union HashKey key
Key representing the data.
Definition: hash.h:45
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:44
void * data
User-supplied data.
Definition: hash.h:46
#define DTYPE(t)
Definition: types.h:50
@ DT_BOOL
boolean option
Definition: types.h:32
@ DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:41
const char * strkey
String key.
Definition: hash.h:35
+ Here is the call graph for this function:

◆ mutt_parse_score()

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

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

Definition at line 90 of file score.c.

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

◆ mutt_parse_unscore()

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

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

Definition at line 200 of file score.c.

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

◆ sb_parse_sidebar_pin()

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

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

Definition at line 41 of file commands.c.

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

◆ sb_parse_sidebar_unpin()

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

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

Definition at line 60 of file commands.c.

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

◆ parse_unreplace_list()

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

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

Definition at line 67 of file subjectrx.c.

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

◆ parse_replace_list()

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

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

Definition at line 93 of file subjectrx.c.

95{
96 struct Buffer *templ = buf_pool_get();
97 int rc = MUTT_CMD_WARNING;
98
99 /* First token is a regex. */
100 if (!MoreArgs(s))
101 {
102 buf_printf(err, _("%s: too few arguments"), "subjectrx");
103 goto done;
104 }
106
107 /* Second token is a replacement template */
108 if (!MoreArgs(s))
109 {
110 buf_printf(err, _("%s: too few arguments"), "subjectrx");
111 goto done;
112 }
114
115 if (mutt_replacelist_add(list, buf->data, buf_string(templ), err) != 0)
116 {
117 rc = MUTT_CMD_ERROR;
118 goto done;
119 }
120
121 rc = MUTT_CMD_SUCCESS;
122
123done:
124 buf_pool_release(&templ);
125 return rc;
126}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_subjectrx_list()

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

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

Definition at line 171 of file subjectrx.c.

173{
174 enum CommandResult rc;
175
176 rc = parse_replace_list(buf, s, &SubjectRegexList, err);
177 if (rc == MUTT_CMD_SUCCESS)
178 {
179 mutt_debug(LL_NOTIFY, "NT_SUBJRX_ADD: %s\n", buf->data);
181 }
182 return rc;
183}
static enum CommandResult parse_replace_list(struct Buffer *buf, struct Buffer *s, struct ReplaceList *list, struct Buffer *err)
Parse a string replacement rule - Implements Command::parse() -.
Definition: subjectrx.c:93
@ NT_SUBJRX
Subject Regex has changed, NotifySubjRx.
Definition: notify_type.h:55
static struct Notify * SubjRxNotify
Notifications: NotifySubjRx.
Definition: subjectrx.c:41
static struct ReplaceList SubjectRegexList
List of subjectrx rules for modifying the Subject:
Definition: subjectrx.c:40
@ NT_SUBJRX_ADD
Subject Regex has been added.
Definition: subjectrx.h:43
+ Here is the call graph for this function:

◆ parse_unsubjectrx_list()

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

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

Definition at line 188 of file subjectrx.c.

190{
191 enum CommandResult rc;
192
193 rc = parse_unreplace_list(buf, s, &SubjectRegexList, err);
194 if (rc == MUTT_CMD_SUCCESS)
195 {
196 mutt_debug(LL_NOTIFY, "NT_SUBJRX_DELETE: %s\n", buf->data);
198 }
199 return rc;
200}
static enum CommandResult parse_unreplace_list(struct Buffer *buf, struct Buffer *s, struct ReplaceList *list, struct Buffer *err)
Remove a string replacement rule - Implements Command::parse() -.
Definition: subjectrx.c:67
@ NT_SUBJRX_DELETE
Subject Regex has been deleted.
Definition: subjectrx.h:44
+ Here is the call graph for this function: