NeoMutt  2025-12-11-1039-g550ac6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
parse()

Function to parse a command. More...

Collaboration diagram for parse():

Functions

enum CommandResult parse_alternates (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'alternates' command - Implements Command::parse() -.
enum CommandResult parse_unalternates (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unalternates' command - Implements Command::parse() -.
enum CommandResult parse_alias (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'alias' command - Implements Command::parse() -.
enum CommandResult parse_unalias (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unalias' command - Implements Command::parse() -.
enum CommandResult parse_group (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'group' and 'ungroup' commands - Implements Command::parse() -.
enum CommandResult parse_lists (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'lists' command - Implements Command::parse() -.
enum CommandResult parse_subscribe (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'subscribe' command - Implements Command::parse() -.
enum CommandResult parse_unlists (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unlists' command - Implements Command::parse() -.
enum CommandResult parse_unsubscribe (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unsubscribe' command - Implements Command::parse() -.
enum CommandResult parse_attachments (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'attachments' command - Implements Command::parse() -.
enum CommandResult parse_unattachments (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unattachments' command - Implements Command::parse() -.
enum CommandResult parse_mime_lookup (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'mime-lookup' command - Implements Command::parse() -.
enum CommandResult parse_unmime_lookup (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unmime-lookup' command - Implements Command::parse() -.
enum CommandResult parse_uncolor_command (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse an 'uncolor' command - Implements Command::parse() -.
enum CommandResult parse_uncolor (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'uncolor' command - Implements Command::parse() -.
enum CommandResult parse_unmono (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unmono' command - Implements Command::parse() -.
enum CommandResult parse_color (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'color' command - Implements Command::parse() -.
enum CommandResult parse_mono (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'mono' command - Implements Command::parse() -.
enum CommandResult parse_ifdef (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'ifdef' and 'ifndef' commands - Implements Command::parse() -.
enum CommandResult parse_finish (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'finish' command - Implements Command::parse() -.
enum CommandResult parse_mailboxes (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'mailboxes' command - Implements Command::parse() -.
enum CommandResult parse_unmailboxes (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unmailboxes' command - Implements Command::parse() -.
enum CommandResult parse_cd (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'cd' command - Implements Command::parse() -.
enum CommandResult parse_echo (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'echo' command - Implements Command::parse() -.
enum CommandResult parse_version (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'version' command - Implements Command::parse() -.
enum CommandResult parse_setenv (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'setenv' and 'unsetenv' commands - Implements Command::parse() -.
enum CommandResult parse_source (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'source' command - Implements Command::parse() -.
enum CommandResult parse_stailq (const struct Command *cmd, struct Buffer *line, struct ListHead *list, const struct ParseContext *pc, struct ParseError *pe)
 Parse a list command - Implements Command::parse() -.
enum CommandResult parse_unstailq (const struct Command *cmd, struct Buffer *line, struct ListHead *list, const struct ParseContext *pc, struct ParseError *pe)
 Parse an unlist command - Implements Command::parse() -.
enum CommandResult parse_list (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse a list command - Implements Command::parse() -.
enum CommandResult parse_unlist (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse an unlist command - Implements Command::parse() -.
enum CommandResult parse_tag_formats (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'tag-formats' command - Implements Command::parse() -.
enum CommandResult parse_tag_transforms (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'tag-transforms' command - Implements Command::parse() -.
enum CommandResult parse_ignore (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'ignore' command - Implements Command::parse() -.
enum CommandResult parse_unignore (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unignore' command - Implements Command::parse() -.
enum CommandResult parse_score (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'score' command - Implements Command::parse() -.
enum CommandResult parse_unscore (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unscore' command - Implements Command::parse() -.
enum CommandResult parse_nospam (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'nospam' command - Implements Command::parse() -.
enum CommandResult parse_spam (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'spam' command - Implements Command::parse() -.
enum CommandResult parse_hooks (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'hooks' command - Implements Command::parse() -.
enum CommandResult parse_charset_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse charset Hook commands - Implements Command::parse() -.
enum CommandResult parse_global_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse global Hook commands - Implements Command::parse() -.
enum CommandResult parse_pattern_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse pattern-based Hook commands - Implements Command::parse() -.
enum CommandResult parse_mailbox_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse mailbox pattern hook commands - Implements Command::parse() -.
enum CommandResult parse_regex_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse regex-based hook command - Implements Command::parse() -.
enum CommandResult parse_folder_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse folder hook command - Implements Command::parse() -.
enum CommandResult parse_crypt_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse crypt hook commands - Implements Command::parse() -.
enum CommandResult parse_mbox_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse mbox hook command - Implements Command::parse() -.
enum CommandResult parse_compress_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse compress hook commands - Implements Command::parse() -.
enum CommandResult parse_index_hook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the index format hook command - Implements Command::parse() -.
enum CommandResult parse_unhook (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the unhook command - Implements Command::parse() -.
enum CommandResult parse_subscribe_to (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'subscribe-to' command - Implements Command::parse() -.
enum CommandResult parse_unsubscribe_from (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unsubscribe-from' command - Implements Command::parse() -.
enum CommandResult parse_subjectrx_list (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'subject-regex' command - Implements Command::parse() -.
enum CommandResult parse_unsubjectrx_list (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unsubject-regex' command - Implements Command::parse() -.
enum CommandResult parse_dump (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse 'bind' and 'macro' commands - Implements Command::parse() -.
enum CommandResult parse_push (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'push' command - Implements Command::parse() -.
enum CommandResult parse_bind (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'bind' command - Implements Command::parse() -.
enum CommandResult parse_unbind (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unbind' and 'unmacro' commands - Implements Command::parse() -.
enum CommandResult parse_macro (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'macro' command - Implements Command::parse() -.
enum CommandResult parse_exec (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'exec' command - Implements Command::parse() -.
enum CommandResult parse_lua (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'lua' command - Implements Command::parse() -.
enum CommandResult parse_lua_source (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'lua-source' command - Implements Command::parse() -.
enum CommandResult parse_set (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'set' family of commands - Implements Command::parse() -.
enum CommandResult parse_my_header (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'my-header' command - Implements Command::parse() -.
enum CommandResult parse_unmy_header (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'unmy-header' command - Implements Command::parse() -.
enum CommandResult parse_sidebar_pin (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'sidebar-pin' command - Implements Command::parse() -.
enum CommandResult parse_sidebar_unpin (const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
 Parse the 'sidebar-unpin' command - Implements Command::parse() -.

Detailed Description

Function to parse a command.

Parameters
cmdCommand being parsed
lineBuffer containing string to be parsed
pcParse Context
peParse Errors
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
cmd is not NULL
line is not NULL
pc is not NULL
pe is not NULL

Function Documentation

◆ parse_alternates()

enum CommandResult parse_alternates ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 68 of file alternates.c.

70{
71 struct Buffer *err = pe->message;
72
73 if (!MoreArgs(line))
74 {
75 buf_printf(err, _("%s: too few arguments"), cmd->name);
76 return MUTT_CMD_WARNING;
77 }
78
79 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
80 struct Buffer *token = buf_pool_get();
82
84 ASSERT(mod_data);
85
86 do
87 {
88 parse_extract_token(token, line, TOKEN_NONE);
89
90 if (parse_grouplist(&gl, token, line, err, mod_data->groups) == -1)
91 goto done;
92
94
95 if (mutt_regexlist_add(&mod_data->alternates, buf_string(token), REG_ICASE, err) != 0)
96 goto done;
97
98 if (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0)
99 goto done;
100 } while (MoreArgs(line));
101
102 mutt_debug(LL_NOTIFY, "NT_ALTERN_ADD: %s\n", buf_string(token));
104
105 rc = MUTT_CMD_SUCCESS;
106
107done:
108 buf_pool_release(&token);
110 return rc;
111}
int grouplist_add_regex(struct GroupList *gl, const char *str, uint16_t flags, struct Buffer *err)
Add matching Addresses to a GroupList.
Definition group.c:246
void grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition group.c:204
int parse_grouplist(struct GroupList *gl, struct Buffer *token, struct Buffer *line, struct Buffer *err, struct HashTable *groups)
Parse a group context.
Definition group.c:56
@ NT_ALTERN_ADD
Alternate address has been added.
Definition alternates.h:43
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:168
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
CommandResult
Error codes for command_t parse functions.
Definition command.h:37
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition command.h:40
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition command.h:38
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition command.h:39
int parse_extract_token(struct Buffer *dest, struct Buffer *line, TokenFlags flags)
Extract one token from a string.
Definition extract.c:49
#define MoreArgs(buf)
Definition extract.h:32
@ TOKEN_NONE
No flags are set.
Definition extract.h:50
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
@ LL_NOTIFY
Log of notifications.
Definition logging2.h:50
@ MODULE_ID_ALIAS
ModuleAlias, Alias
Definition module_api.h:48
#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
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:236
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
@ NT_ALTERN
Alternates command changed, NotifyAlternates.
Definition notify_type.h:38
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define STAILQ_HEAD_INITIALIZER(head)
Definition queue.h:324
#define ASSERT(COND)
Definition signal2.h:59
Alias private Module data.
Definition module_data.h:33
struct RegexList unalternates
Regexes to exclude false matches in alternates.
Definition module_data.h:39
struct Notify * alternates_notify
Notifications: NotifyAlternates.
Definition module_data.h:40
struct HashTable * groups
Hash Table: "group-name" -> Group.
Definition module_data.h:45
struct RegexList alternates
Regexes to match the user's alternate email addresses.
Definition module_data.h:38
String manipulation buffer.
Definition buffer.h:36
const char * name
Name of the Command.
Definition command.h:162
Container for Accounts, Notifications.
Definition neomutt.h:41
struct Buffer * message
Error message.
Definition perror.h:35
Here is the call graph for this function:

◆ parse_unalternates()

enum CommandResult parse_unalternates ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unalternates { * | <regex> ... }

Definition at line 119 of file alternates.c.

121{
122 struct Buffer *err = pe->message;
123
124 if (!MoreArgs(line))
125 {
126 buf_printf(err, _("%s: too few arguments"), cmd->name);
127 return MUTT_CMD_WARNING;
128 }
129
130 struct Buffer *token = buf_pool_get();
132
134 ASSERT(mod_data);
135
136 do
137 {
138 parse_extract_token(token, line, TOKEN_NONE);
139 mutt_regexlist_remove(&mod_data->alternates, buf_string(token));
140
141 if (!mutt_str_equal(buf_string(token), "*") &&
142 (mutt_regexlist_add(&mod_data->unalternates, buf_string(token), REG_ICASE, err) != 0))
143 {
144 goto done;
145 }
146
147 } while (MoreArgs(line));
148
149 mutt_debug(LL_NOTIFY, "NT_ALTERN_DELETE: %s\n", buf_string(token));
151
152 rc = MUTT_CMD_SUCCESS;
153
154done:
155 buf_pool_release(&token);
156 return rc;
157}
@ NT_ALTERN_DELETE
Alternate address has been deleted.
Definition alternates.h:44
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:666
Here is the call graph for this function:

◆ parse_alias()

enum CommandResult parse_alias ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

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

Parse:

  • alias [ -group <name> ... ] <key> <address> [, <address> ...] [ # [ <comments> ] [ tags:... ]]

Definition at line 178 of file commands.c.

180{
181 struct Buffer *err = pe->message;
182
183 if (!MoreArgs(line))
184 {
185 buf_printf(err, _("%s: too few arguments"), cmd->name);
186 return MUTT_CMD_WARNING;
187 }
188
190 ASSERT(mod_data);
191
192 struct Alias *a = NULL;
193 enum NotifyAlias event;
194 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
195 struct Buffer *token = buf_pool_get();
197
198 /* name */
199 parse_extract_token(token, line, TOKEN_NONE);
200 mutt_debug(LL_DEBUG5, "First token is '%s'\n", buf_string(token));
201 if (parse_grouplist(&gl, token, line, err, mod_data->groups) == -1)
202 goto done;
203
204 char *name = mutt_str_dup(buf_string(token));
205
206 /* address list */
208 mutt_debug(LL_DEBUG5, "Second token is '%s'\n", buf_string(token));
209 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
210 int parsed = mutt_addrlist_parse2(&al, buf_string(token));
211 if (parsed == 0)
212 {
213 buf_printf(err, _("Warning: Bad address '%s' in alias '%s'"), buf_string(token), name);
214 FREE(&name);
215 goto done;
216 }
217
218 /* IDN */
219 char *estr = NULL;
220 if (mutt_addrlist_to_intl(&al, &estr))
221 {
222 buf_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, name);
223 FREE(&name);
224 FREE(&estr);
225 goto done;
226 }
227
228 /* check to see if an alias with this name already exists */
229 struct Alias **ap = NULL;
230 ARRAY_FOREACH(ap, &mod_data->aliases)
231 {
232 if (mutt_istr_equal((*ap)->name, name))
233 {
234 a = *ap;
235 break;
236 }
237 }
238
239 if (a)
240 {
241 FREE(&name);
243 /* override the previous value */
245 FREE(&a->comment);
246 event = NT_ALIAS_CHANGE;
247 }
248 else
249 {
250 /* create a new alias */
251 a = alias_new();
252 a->name = name;
253 ARRAY_ADD(&mod_data->aliases, a);
254 event = NT_ALIAS_ADD;
255 }
256 a->addr = al;
257
259
260 const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
261 if (c_debug_level > LL_DEBUG4)
262 {
263 /* A group is terminated with an empty address, so check addr->mailbox */
264 struct Address *addr = NULL;
265 TAILQ_FOREACH(addr, &a->addr, entries)
266 {
267 if (!addr->mailbox)
268 break;
269
270 if (addr->group)
271 mutt_debug(LL_DEBUG5, " Group %s\n", buf_string(addr->mailbox));
272 else
273 mutt_debug(LL_DEBUG5, " %s\n", buf_string(addr->mailbox));
274 }
275 }
276
277 if (!MoreArgs(line) && (line->dptr[0] == '#'))
278 {
279 line->dptr++; // skip over the "# "
280 if (*line->dptr == ' ')
281 line->dptr++;
282
283 parse_alias_comments(a, line->dptr);
284 *line->dptr = '\0'; // We're done parsing
285 }
286
288
289 mutt_debug(LL_NOTIFY, "%s: %s\n",
290 (event == NT_ALIAS_ADD) ? "NT_ALIAS_ADD" : "NT_ALIAS_CHANGE", a->name);
291 struct EventAlias ev_a = { a };
292 notify_send(NeoMutt->notify, NT_ALIAS, event, &ev_a);
293
294 rc = MUTT_CMD_SUCCESS;
295
296done:
297 buf_pool_release(&token);
299 return rc;
300}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1473
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition address.c:651
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition address.c:1304
void grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition group.c:225
void parse_alias_comments(struct Alias *alias, const char *com)
Parse the alias/query comment field.
Definition commands.c:135
struct Alias * alias_new(void)
Create a new Alias.
Definition alias.c:662
NotifyAlias
Alias notification types.
Definition alias.h:54
@ NT_ALIAS_ADD
Alias has been added.
Definition alias.h:55
@ NT_ALIAS_CHANGE
Alias has been changed.
Definition alias.h:58
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
@ TOKEN_SPACE
Don't treat whitespace as a term.
Definition extract.h:53
@ TOKEN_QUOTE
Don't interpret quotes.
Definition extract.h:54
@ TOKEN_SEMICOLON
Don't treat ; as special.
Definition extract.h:57
@ LL_DEBUG4
Log at debug level 4.
Definition logging2.h:48
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:678
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition notify_type.h:37
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:694
void alias_reverse_delete(struct HashTable *reverse_aliases, struct Alias *alias)
Remove an email address lookup for an Alias.
Definition reverse.c:88
void alias_reverse_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition reverse.c:62
An email address.
Definition address.h:35
bool group
Group mailbox?
Definition address.h:38
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:37
struct AliasArray aliases
User's email aliases.
Definition module_data.h:35
struct HashTable * reverse_aliases
Hash Table of aliases (email address -> alias).
Definition module_data.h:36
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
An alias-change event.
Definition alias.h:65
struct Notify * notify
Notifications handler.
Definition neomutt.h:45
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
Here is the call graph for this function:

◆ parse_unalias()

enum CommandResult parse_unalias ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unalias { * | <key> ... }

Definition at line 308 of file commands.c.

310{
311 struct Buffer *err = pe->message;
312
313 if (!MoreArgs(line))
314 {
315 buf_printf(err, _("%s: too few arguments"), cmd->name);
316 return MUTT_CMD_WARNING;
317 }
318
319 struct Buffer *token = buf_pool_get();
320
322 ASSERT(mod_data);
323
324 do
325 {
326 parse_extract_token(token, line, TOKEN_NONE);
327
328 struct Alias **ap = NULL;
329 if (mutt_str_equal("*", buf_string(token)))
330 {
331 ARRAY_FOREACH(ap, &mod_data->aliases)
332 {
334 }
335
336 aliaslist_clear(&mod_data->aliases);
337 goto done;
338 }
339
340 ARRAY_FOREACH(ap, &mod_data->aliases)
341 {
342 if (!mutt_istr_equal(buf_string(token), (*ap)->name))
343 continue;
344
345 struct Alias *a = *ap;
346 ARRAY_REMOVE(&mod_data->aliases, ap);
348 alias_free(&a);
349 break;
350 }
351 } while (MoreArgs(line));
352
353done:
354 buf_pool_release(&token);
355 return MUTT_CMD_SUCCESS;
356}
void alias_free(struct Alias **ptr)
Free an Alias.
Definition alias.c:674
void aliaslist_clear(struct AliasArray *aa)
Empty a List of Aliases.
Definition alias.c:699
#define ARRAY_REMOVE(head, elem)
Remove an entry from the array, shifting down the subsequent entries.
Definition array.h:355
Here is the call graph for this function:

◆ parse_group()

enum CommandResult parse_group ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 90 of file group.c.

92{
93 struct Buffer *err = pe->message;
94
95 if (!MoreArgs(line))
96 {
97 buf_printf(err, _("%s: too few arguments"), cmd->name);
98 return MUTT_CMD_WARNING;
99 }
100
102 ASSERT(mod_data);
103
104 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
105 enum GroupState gstate = GS_NONE;
106 struct Buffer *token = buf_pool_get();
108
109 do
110 {
111 parse_extract_token(token, line, TOKEN_NONE);
112 if (parse_grouplist(&gl, token, line, err, mod_data->groups) == -1)
113 goto done;
114
115 if ((cmd->id == CMD_UNGROUP) && mutt_istr_equal(buf_string(token), "*"))
116 {
117 groups_remove_grouplist(mod_data->groups, &gl);
118 rc = MUTT_CMD_SUCCESS;
119 goto done;
120 }
121
122 if (mutt_istr_equal(buf_string(token), "-rx"))
123 {
124 gstate = GS_RX;
125 }
126 else if (mutt_istr_equal(buf_string(token), "-addr"))
127 {
128 gstate = GS_ADDR;
129 }
130 else
131 {
132 switch (gstate)
133 {
134 case GS_NONE:
135 buf_printf(err, _("%s: missing -rx or -addr"), cmd->name);
136 rc = MUTT_CMD_WARNING;
137 goto done;
138
139 case GS_RX:
140 if ((cmd->id == CMD_GROUP) &&
141 (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0))
142 {
143 goto done;
144 }
145 else if ((cmd->id == CMD_UNGROUP) &&
146 (groups_remove_regex(mod_data->groups, &gl, buf_string(token)) < 0))
147 {
148 goto done;
149 }
150 break;
151
152 case GS_ADDR:
153 {
154 char *estr = NULL;
155 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
156 mutt_addrlist_parse2(&al, buf_string(token));
157 if (TAILQ_EMPTY(&al))
158 goto done;
159 if (mutt_addrlist_to_intl(&al, &estr))
160 {
161 buf_printf(err, _("%s: warning: bad IDN '%s'"), cmd->name, estr);
163 FREE(&estr);
164 goto done;
165 }
166 if (cmd->id == CMD_GROUP)
167 grouplist_add_addrlist(&gl, &al);
168 else if (cmd->id == CMD_UNGROUP)
169 groups_remove_addrlist(mod_data->groups, &gl, &al);
171 break;
172 }
173 }
174 }
175 } while (MoreArgs(line));
176
177 rc = MUTT_CMD_SUCCESS;
178
179done:
180 buf_pool_release(&token);
182 return rc;
183}
int groups_remove_addrlist(struct HashTable *groups, struct GroupList *gl, struct AddressList *al)
Remove an AddressList from a GroupList.
Definition group.c:338
void groups_remove_grouplist(struct HashTable *groups, struct GroupList *gl)
Clear a GroupList.
Definition group.c:313
int groups_remove_regex(struct HashTable *groups, struct GroupList *gl, const char *str)
Remove matching addresses from a GroupList.
Definition group.c:369
GroupState
Type of email address group.
Definition group.h:38
@ GS_RX
Entry is a regular expression.
Definition group.h:40
@ GS_NONE
Group is missing an argument.
Definition group.h:39
@ GS_ADDR
Entry is an address.
Definition group.h:41
@ CMD_GROUP
:group
Definition command.h:82
@ CMD_UNGROUP
:ungroup
Definition command.h:133
#define TAILQ_EMPTY(head)
Definition queue.h:778
enum CommandId id
ID of the Command.
Definition command.h:163
Here is the call graph for this function:

◆ parse_lists()

enum CommandResult parse_lists ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 191 of file group.c.

193{
194 struct Buffer *err = pe->message;
195
196 if (!MoreArgs(line))
197 {
198 buf_printf(err, _("%s: too few arguments"), cmd->name);
199 return MUTT_CMD_WARNING;
200 }
201
202 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
203 struct Buffer *token = buf_pool_get();
205
207 ASSERT(mod_data);
208
209 do
210 {
211 parse_extract_token(token, line, TOKEN_NONE);
212
213 if (parse_grouplist(&gl, token, line, err, mod_data->groups) == -1)
214 goto done;
215
216 mutt_regexlist_remove(&mod_data->unmail, buf_string(token));
217
218 if (mutt_regexlist_add(&mod_data->mail, buf_string(token), REG_ICASE, err) != 0)
219 goto done;
220
221 if (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0)
222 goto done;
223 } while (MoreArgs(line));
224
225 rc = MUTT_CMD_SUCCESS;
226
227done:
228 buf_pool_release(&token);
230 return rc;
231}
struct RegexList mail
Regexes to match mailing lists.
Definition module_data.h:48
struct RegexList unmail
Regexes to exclude false matches in mail.
Definition module_data.h:50
Here is the call graph for this function:

◆ parse_subscribe()

enum CommandResult parse_subscribe ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 239 of file group.c.

241{
242 struct Buffer *err = pe->message;
243
244 if (!MoreArgs(line))
245 {
246 buf_printf(err, _("%s: too few arguments"), cmd->name);
247 return MUTT_CMD_WARNING;
248 }
249
250 struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
251 struct Buffer *token = buf_pool_get();
253
255 ASSERT(mod_data);
256
257 do
258 {
259 parse_extract_token(token, line, TOKEN_NONE);
260
261 if (parse_grouplist(&gl, token, line, err, mod_data->groups) == -1)
262 goto done;
263
264 mutt_regexlist_remove(&mod_data->unmail, buf_string(token));
266
267 if (mutt_regexlist_add(&mod_data->mail, buf_string(token), REG_ICASE, err) != 0)
268 goto done;
269
270 if (mutt_regexlist_add(&mod_data->subscribed, buf_string(token), REG_ICASE, err) != 0)
271 goto done;
272
273 if (grouplist_add_regex(&gl, buf_string(token), REG_ICASE, err) != 0)
274 goto done;
275 } while (MoreArgs(line));
276
277 rc = MUTT_CMD_SUCCESS;
278
279done:
280 buf_pool_release(&token);
282 return rc;
283}
struct RegexList subscribed
Regexes to match subscribed mailing lists.
Definition module_data.h:49
struct RegexList unsubscribed
Regexes to exclude false matches in subscribed.
Definition module_data.h:51
Here is the call graph for this function:

◆ parse_unlists()

enum CommandResult parse_unlists ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unlists { * | <regex> ... }

Definition at line 291 of file group.c.

293{
294 struct Buffer *err = pe->message;
295
296 if (!MoreArgs(line))
297 {
298 buf_printf(err, _("%s: too few arguments"), cmd->name);
299 return MUTT_CMD_WARNING;
300 }
301
302 struct Buffer *token = buf_pool_get();
304
306 ASSERT(mod_data);
307
309 do
310 {
311 parse_extract_token(token, line, TOKEN_NONE);
312 mutt_regexlist_remove(&mod_data->subscribed, buf_string(token));
313 mutt_regexlist_remove(&mod_data->mail, buf_string(token));
314
315 if (!mutt_str_equal(buf_string(token), "*") &&
316 (mutt_regexlist_add(&mod_data->unmail, buf_string(token), REG_ICASE, err) != 0))
317 {
318 goto done;
319 }
320 } while (MoreArgs(line));
321
322 rc = MUTT_CMD_SUCCESS;
323
324done:
325 buf_pool_release(&token);
326 return rc;
327}
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition hash.c:460
struct HashTable * auto_subscribe_cache
Hash Table: "mailto:" (no value).
Definition module_data.h:47
Here is the call graph for this function:

◆ parse_unsubscribe()

enum CommandResult parse_unsubscribe ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unsubscribe { * | <regex> ... }

Definition at line 335 of file group.c.

337{
338 struct Buffer *err = pe->message;
339
340 if (!MoreArgs(line))
341 {
342 buf_printf(err, _("%s: too few arguments"), cmd->name);
343 return MUTT_CMD_WARNING;
344 }
345
347 ASSERT(mod_data);
348
349 struct Buffer *token = buf_pool_get();
351
353 do
354 {
355 parse_extract_token(token, line, TOKEN_NONE);
356 mutt_regexlist_remove(&mod_data->subscribed, buf_string(token));
357
358 if (!mutt_str_equal(buf_string(token), "*") &&
359 (mutt_regexlist_add(&mod_data->unsubscribed, buf_string(token), REG_ICASE, err) != 0))
360 {
361 goto done;
362 }
363 } while (MoreArgs(line));
364
365 rc = MUTT_CMD_SUCCESS;
366
367done:
368 buf_pool_release(&token);
369 return rc;
370}
Here is the call graph for this function:

◆ parse_attachments()

enum CommandResult parse_attachments ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 474 of file commands.c.

476{
478 ASSERT(mod_data);
479
480 struct Buffer *err = pe->message;
481
482 if (!MoreArgs(line))
483 {
484 buf_printf(err, _("%s: too few arguments"), cmd->name);
485 return MUTT_CMD_WARNING;
486 }
487
488 struct Buffer *token = buf_pool_get();
490
491 parse_extract_token(token, line, TOKEN_NONE);
492
493 char *category = token->data;
494 char op = *category++;
495
496 if (op == '?')
497 {
498 mutt_endwin();
499 fflush(stdout);
500 printf("\n%s\n\n", _("Current attachments settings:"));
501 print_attach_list(&mod_data->attach_allow, '+', "A");
502 print_attach_list(&mod_data->attach_exclude, '-', "A");
503 print_attach_list(&mod_data->inline_allow, '+', "I");
504 print_attach_list(&mod_data->inline_exclude, '-', "I");
506
507 rc = MUTT_CMD_SUCCESS;
508 goto done;
509 }
510
511 if ((op != '+') && (op != '-'))
512 {
513 op = '+';
514 category--;
515 }
516
517 struct ListHead *head = NULL;
518 if (mutt_istr_startswith("attachment", category))
519 {
520 if (op == '+')
521 head = &mod_data->attach_allow;
522 else
523 head = &mod_data->attach_exclude;
524 }
525 else if (mutt_istr_startswith("inline", category))
526 {
527 if (op == '+')
528 head = &mod_data->inline_allow;
529 else
530 head = &mod_data->inline_exclude;
531 }
532 else
533 {
534 buf_strcpy(err, _("attachments: invalid disposition"));
535 goto done;
536 }
537
538 rc = parse_attach_list(cmd, line, head, err);
539
540done:
541 buf_pool_release(&token);
542 return rc;
543}
static int print_attach_list(struct ListHead *h, const char op, const char *name)
Print a list of attachments.
Definition commands.c:454
static enum CommandResult parse_attach_list(const struct Command *cmd, struct Buffer *line, struct ListHead *head, struct Buffer *err)
Parse the "attachments" command.
Definition commands.c:292
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition curs_lib.c:174
void mutt_endwin(void)
Shutdown curses.
Definition curs_lib.c:152
@ MODULE_ID_ATTACH
ModuleAttach, Attachments
Definition module_api.h:49
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition string.c:246
Attach private Module data.
Definition module_data.h:32
struct ListHead attach_allow
List of attachment types to be counted.
Definition module_data.h:34
struct ListHead attach_exclude
List of attachment types to be ignored.
Definition module_data.h:35
struct ListHead inline_allow
List of inline types to counted.
Definition module_data.h:36
struct ListHead inline_exclude
List of inline types to ignore.
Definition module_data.h:37
char * data
Pointer to data.
Definition buffer.h:37
Here is the call graph for this function:

◆ parse_unattachments()

enum CommandResult parse_unattachments ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 552 of file commands.c.

554{
555 struct Buffer *err = pe->message;
556
557 if (!MoreArgs(line))
558 {
559 buf_printf(err, _("%s: too few arguments"), cmd->name);
560 return MUTT_CMD_WARNING;
561 }
562
564 ASSERT(mod_data);
565
566 struct Buffer *token = buf_pool_get();
568
569 char op;
570 const char *p = NULL;
571 struct ListHead *head = NULL;
572
573 parse_extract_token(token, line, TOKEN_NONE);
574
575 p = buf_string(token);
576 op = *p++;
577
578 if (op == '*')
579 {
584
585 mutt_debug(LL_NOTIFY, "NT_ATTACH_DELETE_ALL\n");
587
588 rc = MUTT_CMD_SUCCESS;
589 goto done;
590 }
591
592 if ((op != '+') && (op != '-'))
593 {
594 op = '+';
595 p--;
596 }
597 if (mutt_istr_startswith("attachment", p))
598 {
599 if (op == '+')
600 head = &mod_data->attach_allow;
601 else
602 head = &mod_data->attach_exclude;
603 }
604 else if (mutt_istr_startswith("inline", p))
605 {
606 if (op == '+')
607 head = &mod_data->inline_allow;
608 else
609 head = &mod_data->inline_exclude;
610 }
611 else
612 {
613 buf_strcpy(err, _("unattachments: invalid disposition"));
614 goto done;
615 }
616
617 rc = parse_unattach_list(cmd, line, head, err);
618
619done:
620 buf_pool_release(&token);
621 return rc;
622}
static enum CommandResult parse_unattach_list(const struct Command *cmd, struct Buffer *line, struct ListHead *head, struct Buffer *err)
Parse the "unattachments" command.
Definition commands.c:381
@ NT_ATTACH_DELETE_ALL
All Attachment regexes have been deleted.
Definition commands.h:46
void attachmatch_free(void **ptr)
Free an AttachMatch - Implements list_free_t -.
Definition commands.c:63
void mutt_list_free_type(struct ListHead *h, list_free_t fn)
Free a List of type.
Definition list.c:145
@ NT_ATTACH
Attachment command changed, NotifyAttach.
Definition notify_type.h:39
struct Notify * attachments_notify
Notifications: NotifyAttach.
Definition module_data.h:38
Here is the call graph for this function:

◆ parse_mime_lookup()

enum CommandResult parse_mime_lookup ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 654 of file commands.c.

656{
658 ASSERT(mod_data);
659
660 return parse_stailq(cmd, line, &mod_data->mime_lookup, pc, pe);
661}
enum CommandResult parse_stailq(const struct Command *cmd, struct Buffer *line, struct ListHead *list, const struct ParseContext *pc, struct ParseError *pe)
Parse a list command - Implements Command::parse() -.
Definition stailq.c:52
struct ListHead mime_lookup
List of mime types that that shouldn't use the mailcap entry.
Definition module_data.h:42
Here is the call graph for this function:

◆ parse_unmime_lookup()

enum CommandResult parse_unmime_lookup ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unmime-lookup { + | - } disposition mime-type [ mime-type ...]
  • unmime-lookup *

Definition at line 670 of file commands.c.

672{
674 ASSERT(mod_data);
675
676 return parse_unstailq(cmd, line, &mod_data->mime_lookup, pc, pe);
677}
enum CommandResult parse_unstailq(const struct Command *cmd, struct Buffer *line, struct ListHead *list, const struct ParseContext *pc, struct ParseError *pe)
Parse an unlist command - Implements Command::parse() -.
Definition stailq.c:85
Here is the call graph for this function:

◆ parse_uncolor_command()

enum CommandResult parse_uncolor_command ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Usage:

  • uncolor OBJECT [ PATTERN | REGEX | * ]

Definition at line 200 of file commands.c.

203{
204 struct Buffer *err = pe->message;
205
206 if (!MoreArgs(line))
207 {
208 buf_printf(err, _("%s: too few arguments"), cmd->name);
209 return MUTT_CMD_WARNING;
210 }
211
212 struct Buffer *token = buf_pool_get();
214
215 // Peek at the next token ('*' won't match a colour name)
216 if (line->dptr[0] == '*')
217 {
218 parse_extract_token(token, line, TOKEN_NONE);
219 if (mutt_str_equal(buf_string(token), "*"))
220 {
222 colors_reset(mod_data);
223 rc = MUTT_CMD_SUCCESS;
224 goto done;
225 }
226 }
227
228 enum ColorId cid = MT_COLOR_NONE;
229 color_debug(LL_DEBUG5, "uncolor: %s\n", buf_string(token));
230 rc = parse_object(cmd, line, &cid, err);
231 if (rc != MUTT_CMD_SUCCESS)
232 goto done;
233
234 if ((cid == MT_COLOR_STATUS) && !MoreArgs(line))
235 {
236 color_debug(LL_DEBUG5, "simple\n");
237 simple_color_reset(cid); // default colour for the status bar
238 goto done;
239 }
240
241 if (!mutt_color_has_pattern(cid))
242 {
243 color_debug(LL_DEBUG5, "simple\n");
245 goto done;
246 }
247
248 if (!MoreArgs(line))
249 {
250 if (regex_colors_parse_uncolor(cid, NULL))
251 rc = MUTT_CMD_SUCCESS;
252 else
253 rc = MUTT_CMD_ERROR;
254 goto done;
255 }
256
257 do
258 {
259 parse_extract_token(token, line, TOKEN_NONE);
260 if (mutt_str_equal("*", buf_string(token)))
261 {
262 if (regex_colors_parse_uncolor(cid, NULL))
263 rc = MUTT_CMD_SUCCESS;
264 else
265 rc = MUTT_CMD_ERROR;
266 goto done;
267 }
268
270
271 } while (MoreArgs(line));
272
273 rc = MUTT_CMD_SUCCESS;
274
275done:
276 buf_pool_release(&token);
277 return rc;
278}
static enum CommandResult parse_object(const struct Command *cmd, struct Buffer *line, enum ColorId *cid, struct Buffer *err)
Identify a colour object.
Definition commands.c:147
bool regex_colors_parse_uncolor(enum ColorId cid, const char *pat)
Parse a Regex 'uncolor' command.
Definition regex.c:416
void simple_color_reset(enum ColorId cid)
Clear the colour of a simple object.
Definition simple.c:155
bool mutt_color_has_pattern(enum ColorId cid)
Check if a color object supports a regex pattern.
Definition color.c:102
void colors_reset(struct ColorModuleData *mod_data)
Reset all the simple, quoted and regex colours.
Definition color.c:71
ColorId
List of all coloured objects.
Definition color.h:35
@ MT_COLOR_STATUS
Status bar (takes a pattern).
Definition color.h:78
@ MT_COLOR_NONE
No colour.
Definition color.h:36
static int color_debug(enum LogLevel level, const char *format,...)
Definition debug.h:51
@ MODULE_ID_COLOR
ModuleColor, Color
Definition module_api.h:53
Color private Module data.
Definition module_data.h:35
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_uncolor()

enum CommandResult parse_uncolor ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 448 of file commands.c.

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

◆ parse_unmono()

enum CommandResult parse_unmono ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 486 of file commands.c.

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

◆ parse_color()

enum CommandResult parse_color ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • color object [ attribute ...] foreground background
  • color index [ attribute ...] foreground background [ pattern ]
  • color { header | body } [ attribute ...] foreground background regex

Definition at line 508 of file commands.c.

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

◆ parse_mono()

enum CommandResult parse_mono ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 541 of file commands.c.

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

◆ parse_ifdef()

enum CommandResult parse_ifdef ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 89 of file ifdef.c.

91{
92 struct Buffer *err = pe->message;
93
94 if (!MoreArgs(line))
95 {
96 buf_printf(err, _("%s: too few arguments"), cmd->name);
97 return MUTT_CMD_WARNING;
98 }
99
100 struct Buffer *token = buf_pool_get();
102
103 parse_extract_token(token, line, TOKEN_NONE);
104
105 // is the item defined as:
106 bool res = cs_subset_lookup(NeoMutt->sub, buf_string(token)) // a variable?
107 || feature_enabled(buf_string(token)) // a compiled-in feature?
108 || is_function(buf_string(token)) // a function?
109 || commands_get(&NeoMutt->commands, buf_string(token)) // a command?
110 || is_color_object(buf_string(token)) // a color?
111#ifdef USE_HCACHE
112 || store_is_valid_backend(buf_string(token)) // a store? (database)
113#endif
114 || mutt_str_getenv(buf_string(token)); // an environment variable?
115
116 if (!MoreArgs(line))
117 {
118 buf_printf(err, _("%s: too few arguments"), cmd->name);
119 rc = MUTT_CMD_WARNING;
120 goto done;
121 }
122 parse_extract_token(token, line, TOKEN_SPACE);
123
124 /* ifdef KNOWN_SYMBOL or ifndef UNKNOWN_SYMBOL */
125 if ((res && (cmd->id == CMD_IFDEF)) || (!res && (cmd->id == CMD_IFNDEF)))
126 {
127 // Cheat: Remove the `const` so we can recurse
128 rc = parse_rc_line(token, (struct ParseContext *) pc, pe);
129 if (rc == MUTT_CMD_ERROR)
130 mutt_error(_("Error: %s"), buf_string(err));
131
132 goto done;
133 }
134
135done:
136 buf_pool_release(&token);
137 return rc;
138}
@ CMD_IFNDEF
:ifndef
Definition command.h:87
@ CMD_IFDEF
:ifdef
Definition command.h:86
const struct Command * commands_get(struct CommandArray *ca, const char *name)
Get a Command by its name.
Definition command.c:82
#define mutt_error(...)
Definition logging2.h:94
static bool is_color_object(const char *name)
Is the argument a neomutt colour?
Definition ifdef.c:69
static bool is_function(const char *name)
Is the argument a neomutt function?
Definition ifdef.c:56
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition string.c:732
enum CommandResult parse_rc_line(struct Buffer *line, struct ParseContext *pc, struct ParseError *pe)
Parse a line of user config.
Definition rc.c:45
bool store_is_valid_backend(const char *str)
Is the string a valid Store backend.
Definition store.c:110
struct CommandArray commands
NeoMutt commands.
Definition neomutt.h:53
Context for config parsing (history/backtrace).
Definition pcontext.h:34
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition subset.c:193
bool feature_enabled(const char *name)
Test if a compile-time feature is enabled.
Definition version.c:730
Here is the call graph for this function:

◆ parse_finish()

enum CommandResult parse_finish ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Return values
MUTT_CMD_FINISHStop processing the current file
MUTT_CMD_WARNINGFailed

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

Parse:

  • finish

Definition at line 150 of file ifdef.c.

152{
153 struct Buffer *err = pe->message;
154
155 if (MoreArgs(line))
156 {
157 buf_printf(err, _("%s: too many arguments"), cmd->name);
158 return MUTT_CMD_WARNING;
159 }
160
161 return MUTT_CMD_FINISH;
162}
@ MUTT_CMD_FINISH
Finish: Stop processing this file.
Definition command.h:41
Here is the call graph for this function:

◆ parse_mailboxes()

enum CommandResult parse_mailboxes ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 349 of file mailboxes.c.

351{
352 struct Buffer *err = pe->message;
353
354 struct ParseMailboxArray args = ARRAY_HEAD_INITIALIZER;
356
357 if (!parse_mailboxes_args(cmd, line, err, &args))
358 goto done;
359
360 rc = parse_mailboxes_exec(cmd, &args, err);
361
362done:
364 return rc;
365}
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition array.h:58
void parse_mailbox_array_free(struct ParseMailboxArray *pma)
Free a ParseMailboxArray.
Definition mailboxes.c:181
bool parse_mailboxes_args(const struct Command *cmd, struct Buffer *line, struct Buffer *err, struct ParseMailboxArray *args)
Parse the 'mailboxes' and 'named-mailboxes' commands.
Definition mailboxes.c:206
enum CommandResult parse_mailboxes_exec(const struct Command *cmd, struct ParseMailboxArray *args, struct Buffer *err)
Execute the 'mailboxes' or 'named-mailboxes' command.
Definition mailboxes.c:322
Here is the call graph for this function:

◆ parse_unmailboxes()

enum CommandResult parse_unmailboxes ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 440 of file mailboxes.c.

442{
443 struct Buffer *err = pe->message;
444
445 if (!MoreArgs(line))
446 {
447 buf_printf(err, _("%s: too few arguments"), cmd->name);
448 return MUTT_CMD_WARNING;
449 }
450
451 struct Buffer *token = buf_pool_get();
452
453 while (MoreArgs(line))
454 {
455 parse_extract_token(token, line, TOKEN_NONE);
456
457 if (mutt_str_equal(buf_string(token), "*"))
458 {
460 goto done;
461 }
462
463 expand_path(token, false);
464
465 struct Account **ap = NULL;
467 {
468 struct Mailbox *m = mx_mbox_find(*ap, buf_string(token));
469 if (m)
470 {
472 break;
473 }
474 }
475 }
476
477done:
478 buf_pool_release(&token);
479 return MUTT_CMD_SUCCESS;
480}
static void do_unmailboxes_star(void)
Remove all Mailboxes from the Sidebar/notifications.
Definition mailboxes.c:422
static void do_unmailboxes(struct Mailbox *m)
Remove a Mailbox from the Sidebar/notifications.
Definition mailboxes.c:371
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:122
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition mx.c:1549
A group of associated Mailboxes.
Definition account.h:36
A mailbox.
Definition mailbox.h:81
struct AccountArray accounts
All Accounts.
Definition neomutt.h:50
Here is the call graph for this function:

◆ parse_cd()

enum CommandResult parse_cd ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • cd [ <directory> ]

Definition at line 59 of file parse.c.

61{
62 struct Buffer *err = pe->message;
63
64 struct Buffer *token = buf_pool_get();
66
67 parse_extract_token(token, line, TOKEN_NONE);
68 if (buf_is_empty(token))
69 {
71 }
72 else
73 {
74 expand_path(token, false);
75 }
76
77 if (chdir(buf_string(token)) != 0)
78 {
79 buf_printf(err, "%s: %s", cmd->name, strerror(errno));
80 goto done;
81 }
82
84
85done:
86 buf_pool_release(&token);
87 return rc;
88}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:298
char * home_dir
User's home directory.
Definition neomutt.h:55
Here is the call graph for this function:

◆ parse_echo()

enum CommandResult parse_echo ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • echo <message>

Definition at line 96 of file parse.c.

98{
99 struct Buffer *err = pe->message;
100
101 if (!MoreArgs(line))
102 {
103 buf_printf(err, _("%s: too few arguments"), cmd->name);
104 return MUTT_CMD_WARNING;
105 }
106
107 struct Buffer *token = buf_pool_get();
108
109 parse_extract_token(token, line, TOKEN_NONE);
110 OptForceRefresh = true;
111 mutt_message("%s", buf_string(token));
112 OptForceRefresh = false;
113 mutt_sleep(0);
114
115 buf_pool_release(&token);
116 return MUTT_CMD_SUCCESS;
117}
bool OptForceRefresh
(pseudo) refresh even during macros
Definition globals.c:47
#define mutt_message(...)
Definition logging2.h:93
void mutt_sleep(short s)
Sleep for a while.
Definition muttlib.c:795
Here is the call graph for this function:

◆ parse_version()

enum CommandResult parse_version ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • version

Definition at line 125 of file parse.c.

127{
128 struct Buffer *err = pe->message;
129
130 // silently ignore 'version' if it's in a config file
131 if (!StartupComplete)
132 return MUTT_CMD_SUCCESS;
133
134 if (MoreArgs(line))
135 {
136 buf_printf(err, _("%s: too many arguments"), cmd->name);
137 return MUTT_CMD_WARNING;
138 }
139
140 struct Buffer *tempfile = buf_pool_get();
142
143 buf_mktemp(tempfile);
144
145 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
146 if (!fp_out)
147 {
148 // L10N: '%s' is the file name of the temporary file
149 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
150 goto done;
151 }
152
153 print_version(fp_out, false);
154 mutt_file_fclose(&fp_out);
155
156 struct PagerData pdata = { 0 };
157 struct PagerView pview = { &pdata };
158
159 pdata.fname = buf_string(tempfile);
160
161 pview.banner = cmd->name;
162 pview.flags = MUTT_PAGER_NONE;
163 pview.mode = PAGER_MODE_OTHER;
164
165 mutt_do_pager(&pview, NULL);
166 rc = MUTT_CMD_SUCCESS;
167
168done:
169 buf_pool_release(&tempfile);
170 return rc;
171}
bool StartupComplete
Definition address.c:11
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
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
#define MUTT_PAGER_NONE
No flags are set.
Definition lib.h:63
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition lib.h:143
Data to be displayed by PagerView.
Definition lib.h:162
const char * fname
Name of the file to read.
Definition lib.h:166
Paged view into some data.
Definition lib.h:173
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition lib.h:174
enum PagerMode mode
Pager mode.
Definition lib.h:175
PagerFlags flags
Additional settings to tweak pager's function.
Definition lib.h:176
const char * banner
Title to display in status bar.
Definition lib.h:177
#define buf_mktemp(buf)
Definition tmp.h:33
bool print_version(FILE *fp, bool use_ansi)
Print system and compile info to a file.
Definition version.c:591
Here is the call graph for this function:

◆ parse_setenv()

enum CommandResult parse_setenv ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Note: Also accepts the old syntax: setenv <variable> <value>

Definition at line 67 of file setenv.c.

69{
70 struct Buffer *err = pe->message;
71
72 struct Buffer *token = buf_pool_get();
73 struct Buffer *tempfile = NULL;
75
76 char **envp = NeoMutt->env;
77
78 bool query = false;
79 bool prefix = false;
80 bool unset = (cmd->id == CMD_UNSETENV);
81
82 if (!MoreArgs(line))
83 {
84 if (!StartupComplete)
85 {
86 buf_printf(err, _("%s: too few arguments"), cmd->name);
87 goto done;
88 }
89
90 tempfile = buf_pool_get();
91 buf_mktemp(tempfile);
92
93 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
94 if (!fp_out)
95 {
96 // L10N: '%s' is the file name of the temporary file
97 buf_printf(err, _("Could not create temporary file %s"), buf_string(tempfile));
98 rc = MUTT_CMD_ERROR;
99 goto done;
100 }
101
102 int count = 0;
103 for (char **env = NeoMutt->env; *env; env++)
104 count++;
105
106 mutt_qsort_r(NeoMutt->env, count, sizeof(char *), envlist_sort, NULL);
107
108 for (char **env = NeoMutt->env; *env; env++)
109 fprintf(fp_out, "%s\n", *env);
110
111 mutt_file_fclose(&fp_out);
112
113 struct PagerData pdata = { 0 };
114 struct PagerView pview = { &pdata };
115
116 pdata.fname = buf_string(tempfile);
117
118 pview.banner = cmd->name;
119 pview.flags = MUTT_PAGER_NONE;
120 pview.mode = PAGER_MODE_OTHER;
121
122 mutt_do_pager(&pview, NULL);
123
124 rc = MUTT_CMD_SUCCESS;
125 goto done;
126 }
127
128 if (*line->dptr == '?')
129 {
130 query = true;
131 prefix = true;
132
133 if (unset)
134 {
135 buf_printf(err, _("Can't query option with the '%s' command"), cmd->name);
136 goto done;
137 }
138
139 line->dptr++;
140 }
141
142 /* get variable name */
144
145 /* Validate variable name: must match [_a-zA-Z][_a-zA-Z0-9]* */
146 const char *name = buf_string(token);
147 if (!buf_is_empty(token))
148 {
149 /* First character must be a letter or underscore */
150 if (!isalpha(name[0]) && (name[0] != '_'))
151 {
152 buf_printf(err, _("%s: invalid variable name '%s'"), cmd->name, name);
153 goto done;
154 }
155 /* Subsequent characters must be letter, digit, or underscore */
156 for (size_t i = 1; name[i] != '\0'; i++)
157 {
158 if (!isalpha(name[i]) && !mutt_isdigit(name[i]) && (name[i] != '_'))
159 {
160 buf_printf(err, _("%s: invalid variable name '%s'"), cmd->name, name);
161 goto done;
162 }
163 }
164 }
165
166 if (*line->dptr == '?')
167 {
168 if (unset)
169 {
170 buf_printf(err, _("Can't query option with the '%s' command"), cmd->name);
171 goto done;
172 }
173
174 if (prefix)
175 {
176 buf_printf(err, _("Can't use a prefix when querying a variable"));
177 goto done;
178 }
179
180 query = true;
181 line->dptr++;
182 }
183
184 if (query)
185 {
186 bool found = false;
187 while (envp && *envp)
188 {
189 /* This will display all matches for "^QUERY" */
190 if (mutt_str_startswith(*envp, buf_string(token)))
191 {
192 if (!found)
193 {
194 mutt_endwin();
195 found = true;
196 }
197 puts(*envp);
198 }
199 envp++;
200 }
201
202 if (found)
203 {
205 rc = MUTT_CMD_SUCCESS;
206 goto done;
207 }
208
209 buf_printf(err, _("%s is unset"), buf_string(token));
210 goto done;
211 }
212
213 if (unset)
214 {
216 rc = MUTT_CMD_SUCCESS;
217 goto done;
218 }
219
220 /* set variable */
221
222 if (*line->dptr == '=')
223 {
224 line->dptr++;
225 SKIPWS(line->dptr);
226 }
227
228 if (!MoreArgs(line))
229 {
230 buf_printf(err, _("%s: too few arguments"), cmd->name);
231 goto done;
232 }
233
234 char *varname = mutt_str_dup(buf_string(token));
235 parse_extract_token(token, line, TOKEN_NONE);
236 envlist_set(&NeoMutt->env, varname, buf_string(token), true);
237 FREE(&varname);
238
239 rc = MUTT_CMD_SUCCESS;
240
241done:
242 buf_pool_release(&token);
243 buf_pool_release(&tempfile);
244 return rc;
245}
@ CMD_UNSETENV
:unsetenv
Definition command.h:146
bool mutt_isdigit(int arg)
Wrapper for isdigit(3).
Definition ctype.c:66
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:140
@ TOKEN_EQUAL
Treat '=' as a special.
Definition extract.h:51
@ TOKEN_QUESTION
Treat '?' as a special.
Definition extract.h:59
static int envlist_sort(const void *a, const void *b, void *sdata)
Compare two environment strings - Implements sort_t -.
Definition setenv.c:53
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition string.c:234
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:72
#define SKIPWS(ch)
Definition string2.h:52
char ** env
Private copy of the environment variables.
Definition neomutt.h:57
Here is the call graph for this function:

◆ parse_source()

enum CommandResult parse_source ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • source <filename> [ <filename> ... ]

Definition at line 229 of file source.c.

231{
232 struct Buffer *err = pe->message;
233
234 if (!MoreArgs(line))
235 {
236 buf_printf(err, _("%s: too few arguments"), cmd->name);
237 return MUTT_CMD_WARNING;
238 }
239
240 struct Buffer *token = buf_pool_get();
241 struct Buffer *path = buf_pool_get();
243
244 do
245 {
246 if (parse_extract_token(token, line, TOKEN_NONE) != 0)
247 {
248 buf_printf(err, _("source: error at %s"), line->dptr);
249 goto done;
250 }
251 buf_copy(path, token);
252 expand_path(path, false);
253
254 // Cheat: Remove the `const` so we can recurse
255 if (source_rc(buf_string(path), (struct ParseContext *) pc, pe) < 0)
256 {
257 buf_printf(err, _("source: file %s could not be sourced"), buf_string(path));
258 goto done;
259 }
260
261 } while (MoreArgs(line));
262
263 rc = MUTT_CMD_SUCCESS;
264
265done:
266 buf_pool_release(&path);
267 buf_pool_release(&token);
268 return rc;
269}
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition buffer.c:607
int source_rc(const char *rcfile_path, struct ParseContext *pc, struct ParseError *pe)
Read an initialization file.
Definition source.c:64
Here is the call graph for this function:

◆ parse_stailq()

enum CommandResult parse_stailq ( const struct Command * cmd,
struct Buffer * line,
struct ListHead * list,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parameters
cmdCommand being parsed
lineBuffer containing string to be parsed
listList for the results
pcParse Context
peParse Errors
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 52 of file stailq.c.

55{
56 struct Buffer *err = pe->message;
57
58 if (!MoreArgs(line))
59 {
60 buf_printf(err, _("%s: too few arguments"), cmd->name);
61 return MUTT_CMD_WARNING;
62 }
63
64 struct Buffer *token = buf_pool_get();
65
66 do
67 {
68 parse_extract_token(token, line, TOKEN_NONE);
69 add_to_stailq(list, buf_string(token));
70 } while (MoreArgs(line));
71
72 buf_pool_release(&token);
73 return MUTT_CMD_SUCCESS;
74}
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition list.c:319
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_unstailq()

enum CommandResult parse_unstailq ( const struct Command * cmd,
struct Buffer * line,
struct ListHead * list,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parameters
cmdCommand being parsed
lineBuffer containing string to be parsed
listList for the results
pcParse Context
peParse Errors
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS

Definition at line 85 of file stailq.c.

88{
89 struct Buffer *err = pe->message;
90
91 if (!MoreArgs(line))
92 {
93 buf_printf(err, _("%s: too few arguments"), cmd->name);
94 return MUTT_CMD_WARNING;
95 }
96
97 struct Buffer *token = buf_pool_get();
98
99 do
100 {
101 parse_extract_token(token, line, TOKEN_NONE);
102 /* Check for deletion of entire list */
103 if (mutt_str_equal(buf_string(token), "*"))
104 {
105 mutt_list_free(list);
106 break;
107 }
108 remove_from_stailq(list, buf_string(token));
109 } while (MoreArgs(line));
110
111 buf_pool_release(&token);
112 return MUTT_CMD_SUCCESS;
113}
void remove_from_stailq(struct ListHead *head, const char *str)
Remove an item, matching a string, from a List.
Definition list.c:344
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition list.c:123
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_list()

enum CommandResult parse_list ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • alternative-order <mime-type>[/<mime-subtype> ] [ <mime-type>[/<mime-subtype> ] ... ]
  • auto-view <mime-type>[/<mime-subtype> ] [ <mime-type>[/<mime-subtype> ] ... ]
  • header-order <header> [ <header> ... ]
  • mailto-allow { * | <header-field> ... }

Definition at line 50 of file commands.c.

52{
54 ASSERT(mod_data);
55
56 switch (cmd->id)
57 {
59 return parse_stailq(cmd, line, &mod_data->alternative_order, pc, pe);
60
61 case CMD_AUTO_VIEW:
62 return parse_stailq(cmd, line, &mod_data->auto_view, pc, pe);
63
65 return parse_stailq(cmd, line, &mod_data->header_order, pc, pe);
66
68 return parse_stailq(cmd, line, &mod_data->mail_to_allow, pc, pe);
69
70 default:
71 ASSERT(false);
72 }
73
74 return MUTT_CMD_ERROR;
75}
@ CMD_MAILTO_ALLOW
:mailto-allow
Definition command.h:95
@ CMD_AUTO_VIEW
:auto-view
Definition command.h:69
@ CMD_ALTERNATIVE_ORDER
:alternative-order
Definition command.h:66
@ CMD_HEADER_ORDER
:header-order
Definition command.h:83
@ MODULE_ID_EMAIL
ModuleEmail, Email code
Definition module_api.h:64
Email private Module data.
Definition module_data.h:32
struct ListHead auto_view
List of mime types to auto view.
Definition module_data.h:35
struct ListHead mail_to_allow
Permitted fields in a mailto: url.
Definition module_data.h:38
struct ListHead alternative_order
List of preferred mime types to display.
Definition module_data.h:34
struct ListHead header_order
List of header fields in the order they should be displayed.
Definition module_data.h:36
Here is the call graph for this function:

◆ parse_unlist()

enum CommandResult parse_unlist ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unalternative-order { * | [ <mime-type>[/<mime-subtype> ] ... ] }
  • unauto-view { * | [ <mime-type>[/<mime-subtype> ] ... ] }
  • unheader-order { * | <header> ... }
  • unmailto-allow { * | <header-field> ... }

Definition at line 86 of file commands.c.

88{
90 ASSERT(mod_data);
91
92 switch (cmd->id)
93 {
95 return parse_unstailq(cmd, line, &mod_data->alternative_order, pc, pe);
96
97 case CMD_UNAUTO_VIEW:
98 return parse_unstailq(cmd, line, &mod_data->auto_view, pc, pe);
99
101 return parse_unstailq(cmd, line, &mod_data->header_order, pc, pe);
102
104 return parse_unstailq(cmd, line, &mod_data->mail_to_allow, pc, pe);
105
106 default:
107 ASSERT(false);
108 }
109
110 return MUTT_CMD_ERROR;
111}
@ CMD_UNALTERNATIVE_ORDER
:unalternative-order
Definition command.h:128
@ CMD_UNAUTO_VIEW
:unauto-view
Definition command.h:130
@ CMD_UNHEADER_ORDER
:unheader-order
Definition command.h:134
@ CMD_UNMAILTO_ALLOW
:unmailto-allow
Definition command.h:140
Here is the call graph for this function:

◆ parse_tag_formats()

enum CommandResult parse_tag_formats ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse config like: tag-formats pgp GP

Note
This maps format -> tag

Parse:

  • tag-formats <tag> <format-string> [ <tag> <format-string> ... ] }

Definition at line 123 of file commands.c.

125{
126 struct Buffer *err = pe->message;
127
128 if (!MoreArgs(line))
129 {
130 buf_printf(err, _("%s: too few arguments"), cmd->name);
131 return MUTT_CMD_WARNING;
132 }
133
134 struct Buffer *tag = buf_pool_get();
135 struct Buffer *fmt = buf_pool_get();
136
138 ASSERT(mod_data);
139
140 while (MoreArgs(line))
141 {
143 if (buf_is_empty(tag))
144 continue;
145
147
148 /* avoid duplicates */
149 const char *tmp = mutt_hash_find(mod_data->tag_formats, buf_string(fmt));
150 if (tmp)
151 {
152 mutt_warning(_("tag format '%s' already registered as '%s'"), buf_string(fmt), tmp);
153 continue;
154 }
155
156 mutt_hash_insert(mod_data->tag_formats, buf_string(fmt), buf_strdup(tag));
157 }
158
159 buf_pool_release(&tag);
160 buf_pool_release(&fmt);
161 return MUTT_CMD_SUCCESS;
162}
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:577
#define mutt_warning(...)
Definition logging2.h:92
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:338
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:365
struct HashTable * tag_formats
Hash Table: "inbox" -> "GI" - Tag format strings.
Definition module_data.h:41
Here is the call graph for this function:

◆ parse_tag_transforms()

enum CommandResult parse_tag_transforms ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse config like: tag-transforms pgp P

Note
This maps tag -> transform

Parse:

  • tag-transforms <tag> <transformed-string> [ <tag> <transformed-string> ... ]}

Definition at line 174 of file commands.c.

177{
178 struct Buffer *err = pe->message;
179
180 if (!MoreArgs(line))
181 {
182 buf_printf(err, _("%s: too few arguments"), cmd->name);
183 return MUTT_CMD_WARNING;
184 }
185
186 struct Buffer *tag = buf_pool_get();
187 struct Buffer *trans = buf_pool_get();
188
190 ASSERT(mod_data);
191
192 while (MoreArgs(line))
193 {
195 if (buf_is_empty(tag))
196 continue;
197
198 parse_extract_token(trans, line, TOKEN_NONE);
199 const char *trn = buf_string(trans);
200
201 /* avoid duplicates */
202 const char *tmp = mutt_hash_find(mod_data->tag_transforms, buf_string(tag));
203 if (tmp)
204 {
205 mutt_warning(_("tag transform '%s' already registered as '%s'"),
206 buf_string(tag), tmp);
207 continue;
208 }
209
211 }
212
213 buf_pool_release(&tag);
214 buf_pool_release(&trans);
215 return MUTT_CMD_SUCCESS;
216}
struct HashTable * tag_transforms
Hash Table: "inbox" -> "i" - Alternative tag names.
Definition module_data.h:42
Here is the call graph for this function:

◆ parse_ignore()

enum CommandResult parse_ignore ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • ignore <string> [ <string> ...]

Definition at line 50 of file ignore.c.

52{
53 struct Buffer *err = pe->message;
54
55 if (!MoreArgs(line))
56 {
57 buf_printf(err, _("%s: too few arguments"), cmd->name);
58 return MUTT_CMD_WARNING;
59 }
60
61 struct Buffer *token = buf_pool_get();
62
64 ASSERT(mod_data);
65
66 do
67 {
68 parse_extract_token(token, line, TOKEN_NONE);
69 remove_from_stailq(&mod_data->unignore, buf_string(token));
70 add_to_stailq(&mod_data->ignore, buf_string(token));
71 } while (MoreArgs(line));
72
73 buf_pool_release(&token);
74 return MUTT_CMD_SUCCESS;
75}
struct ListHead unignore
Header patterns to unignore.
Definition module_data.h:43
struct ListHead ignore
Header patterns to ignore.
Definition module_data.h:37
Here is the call graph for this function:

◆ parse_unignore()

enum CommandResult parse_unignore ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 83 of file ignore.c.

85{
86 struct Buffer *err = pe->message;
87
88 if (!MoreArgs(line))
89 {
90 buf_printf(err, _("%s: too few arguments"), cmd->name);
91 return MUTT_CMD_WARNING;
92 }
93
94 struct Buffer *token = buf_pool_get();
95
97 ASSERT(mod_data);
98
99 do
100 {
101 parse_extract_token(token, line, TOKEN_NONE);
102
103 /* don't add "*" to the unignore list */
104 if (!mutt_str_equal(buf_string(token), "*"))
105 add_to_stailq(&mod_data->unignore, buf_string(token));
106
107 remove_from_stailq(&mod_data->ignore, buf_string(token));
108 } while (MoreArgs(line));
109
110 buf_pool_release(&token);
111 return MUTT_CMD_SUCCESS;
112}
Here is the call graph for this function:

◆ parse_score()

enum CommandResult parse_score ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • score <pattern> <value>

Definition at line 76 of file score.c.

78{
79 struct Buffer *err = pe->message;
81
82 if (!MoreArgs(line))
83 {
84 buf_printf(err, _("%s: too few arguments"), cmd->name);
85 return MUTT_CMD_WARNING;
86 }
87
88 struct Score *ptr = NULL;
89 struct Score *last = NULL;
90 char *pattern = NULL;
91 char *patchar = NULL;
92 struct Buffer *token = buf_pool_get();
94
95 parse_extract_token(token, line, TOKEN_NONE);
96 if (!MoreArgs(line))
97 {
98 buf_printf(err, _("%s: too few arguments"), cmd->name);
99 goto done;
100 }
101 pattern = buf_strdup(token);
102 parse_extract_token(token, line, TOKEN_NONE);
103 if (MoreArgs(line))
104 {
105 buf_printf(err, _("%s: too many arguments"), cmd->name);
106 goto done;
107 }
108
109 /* look for an existing entry and update the value, else add it to the end
110 * of the list */
111 for (ptr = mod_data->score_list, last = NULL; ptr; last = ptr, ptr = ptr->next)
112 if (mutt_str_equal(pattern, ptr->str))
113 break;
114
115 if (ptr)
116 {
117 /* 'token' arg was cleared and 'pattern' holds the only reference;
118 * as here 'ptr' != NULL -> update the value only in which case
119 * ptr->str already has the string, so pattern should be freed. */
120 FREE(&pattern);
121 }
122 else
123 {
124 struct MailboxView *mv_cur = get_current_mailbox_view();
125 struct PatternList *pat = mutt_pattern_comp(mv_cur, pattern, MUTT_PC_NONE, err);
126 if (!pat)
127 {
128 goto done;
129 }
130 ptr = MUTT_MEM_CALLOC(1, struct Score);
131 if (last)
132 last->next = ptr;
133 else
134 mod_data->score_list = ptr;
135 ptr->pat = pat;
136 ptr->str = pattern;
137 pattern = NULL;
138 }
139
140 patchar = token->data;
141 if (*patchar == '=')
142 {
143 ptr->exact = true;
144 patchar++;
145 }
146
147 if (!mutt_str_atoi_full(patchar, &ptr->val))
148 {
149 buf_strcpy(err, _("Error: score: invalid number"));
150 goto done;
151 }
152 OptNeedRescore = true;
153
154 rc = MUTT_CMD_SUCCESS;
155
156done:
157 buf_pool_release(&token);
158 FREE(&pattern);
159 return rc;
160}
struct PatternList * mutt_pattern_comp(struct MailboxView *mv, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition compile.c:964
bool OptNeedRescore
(pseudo) set when the 'score' command is used
Definition globals.c:51
struct MailboxView * get_current_mailbox_view(void)
Get the current Mailbox view.
Definition index.c:692
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
@ MUTT_PC_NONE
No flags are set.
Definition lib.h:73
struct Score * score_list
Linked list of email scoring rules.
Definition module_data.h:44
View of a Mailbox.
Definition mview.h:40
Scoring rule for email.
Definition score.h:38
bool exact
If this rule matches, don't evaluate any more.
Definition score.h:42
char * str
String to match.
Definition score.h:39
struct PatternList * pat
Pattern to match.
Definition score.h:40
int val
Score to add.
Definition score.h:41
struct Score * next
Linked list.
Definition score.h:43
Here is the call graph for this function:

◆ parse_unscore()

enum CommandResult parse_unscore ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 168 of file score.c.

170{
171 struct Buffer *err = pe->message;
173
174 if (!MoreArgs(line))
175 {
176 buf_printf(err, _("%s: too few arguments"), cmd->name);
177 return MUTT_CMD_WARNING;
178 }
179
180 struct Score *tmp = NULL;
181 struct Score *last = NULL;
182 struct Buffer *token = buf_pool_get();
183
184 while (MoreArgs(line))
185 {
186 parse_extract_token(token, line, TOKEN_NONE);
187 if (mutt_str_equal("*", buf_string(token)))
188 {
189 score_list_free(&mod_data->score_list);
190 }
191 else
192 {
193 for (tmp = mod_data->score_list; tmp; last = tmp, tmp = tmp->next)
194 {
195 if (mutt_str_equal(buf_string(token), tmp->str))
196 {
197 if (last)
198 last->next = tmp->next;
199 else
200 mod_data->score_list = tmp->next;
201 mutt_pattern_free(&tmp->pat);
202 FREE(&tmp);
203 /* there should only be one score per pattern, so we can stop here */
204 break;
205 }
206 }
207 }
208 }
209
210 OptNeedRescore = true;
211 buf_pool_release(&token);
212 return MUTT_CMD_SUCCESS;
213}
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition compile.c:836
void score_list_free(struct Score **sp)
Free a list of scoring rules.
Definition score.c:53
Here is the call graph for this function:

◆ parse_nospam()

enum CommandResult parse_nospam ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • nospam { * | <regex> }

Definition at line 51 of file spam.c.

53{
54 struct Buffer *err = pe->message;
55
56 if (!MoreArgs(line))
57 {
58 buf_printf(err, _("%s: too few arguments"), cmd->name);
59 return MUTT_CMD_WARNING;
60 }
61
62 struct Buffer *token = buf_pool_get();
64
65 // Extract the first token, a regex or "*"
66 parse_extract_token(token, line, TOKEN_NONE);
67
68 if (MoreArgs(line))
69 {
70 buf_printf(err, _("%s: too many arguments"), cmd->name);
71 goto done;
72 }
73
75 ASSERT(mod_data);
76
77 // "*" is special - clear both spam and nospam lists
78 if (mutt_str_equal(buf_string(token), "*"))
79 {
80 mutt_replacelist_free(&mod_data->spam);
81 mutt_regexlist_free(&mod_data->no_spam);
83 goto done;
84 }
85
86 // If it's on the spam list, just remove it
87 if (mutt_replacelist_remove(&mod_data->spam, buf_string(token)) != 0)
88 {
90 goto done;
91 }
92
93 // Otherwise, add it to the nospam list
94 if (mutt_regexlist_add(&mod_data->no_spam, buf_string(token), REG_ICASE, err) != 0)
95 {
96 rc = MUTT_CMD_ERROR;
97 goto done;
98 }
99
100 rc = MUTT_CMD_SUCCESS;
101
102done:
103 buf_pool_release(&token);
104 return rc;
105}
int mutt_replacelist_remove(struct ReplaceList *rl, const char *pat)
Remove a pattern from a list.
Definition regex.c:572
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:452
struct ReplaceList spam
Regexes and patterns to match spam emails.
Definition module_data.h:40
struct RegexList no_spam
Regexes to identify non-spam emails.
Definition module_data.h:39
Here is the call graph for this function:

◆ parse_spam()

enum CommandResult parse_spam ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • spam <regex> [ <format> ]

Definition at line 113 of file spam.c.

115{
116 struct Buffer *err = pe->message;
117
118 if (!MoreArgs(line))
119 {
120 buf_printf(err, _("%s: too few arguments"), cmd->name);
121 return MUTT_CMD_WARNING;
122 }
123
124 struct Buffer *token = buf_pool_get();
125 struct Buffer *templ = NULL;
127
128 // Extract the first token, a regex
129 parse_extract_token(token, line, TOKEN_NONE);
130
132 ASSERT(mod_data);
133
134 // If there's a second parameter, it's a template for the spam tag
135 if (MoreArgs(line))
136 {
137 templ = buf_pool_get();
138 parse_extract_token(templ, line, TOKEN_NONE);
139
140 // Add to the spam list
141 if (mutt_replacelist_add(&mod_data->spam, buf_string(token), buf_string(templ), err) != 0)
142 goto done;
143 }
144 else
145 {
146 // If not, try to remove from the nospam list
147 mutt_regexlist_remove(&mod_data->no_spam, buf_string(token));
148 }
149
150 rc = MUTT_CMD_SUCCESS;
151
152done:
153 buf_pool_release(&templ);
154 buf_pool_release(&token);
155 return rc;
156}
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:273
Here is the call graph for this function:

◆ parse_hooks()

enum CommandResult parse_hooks ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • hooks

Definition at line 227 of file dump.c.

229{
230 struct Buffer *err = pe->message;
231
232 if (MoreArgs(line))
233 {
234 buf_printf(err, _("%s: too many arguments"), cmd->name);
235 return MUTT_CMD_WARNING;
236 }
237
238 if (!StartupComplete)
239 return MUTT_CMD_SUCCESS;
240
242 if (TAILQ_EMPTY(&mod_data->hooks))
243 {
244 buf_printf(err, _("%s: No Hooks are configured"), cmd->name);
245 return MUTT_CMD_WARNING;
246 }
247
248 struct Buffer *tempfile = buf_pool_get();
249 buf_mktemp(tempfile);
250
251 FILE *fp = mutt_file_fopen(buf_string(tempfile), "w");
252 if (!fp)
253 {
254 mutt_error(_("Could not create temporary file %s"), buf_string(tempfile));
255 buf_pool_release(&tempfile);
256 return MUTT_CMD_ERROR;
257 }
258
259 struct Buffer *buf = buf_pool_get();
260
262 hooks_dump_index(buf);
264
266 mutt_file_fclose(&fp);
267 buf_pool_release(&buf);
268
269 struct PagerData pdata = { 0 };
270 struct PagerView pview = { &pdata };
271
272 pdata.fname = buf_string(tempfile);
273
274 pview.banner = "hooks";
275 pview.flags = MUTT_PAGER_NONE;
276 pview.mode = PAGER_MODE_OTHER;
277
278 mutt_do_pager(&pview, NULL);
279 buf_pool_release(&tempfile);
280 return MUTT_CMD_SUCCESS;
281}
size_t mutt_file_save_str(FILE *fp, const char *str)
Save a string to a file.
Definition file.c:1575
static void hooks_dump_charset(struct Buffer *buf)
Dump the Charset Hooks.
Definition dump.c:176
static void hooks_dump_index(struct Buffer *buf)
Dump the Index Format Hooks.
Definition dump.c:135
static void hooks_dump_simple(struct Buffer *buf)
Dump the simple Hooks.
Definition dump.c:94
@ MODULE_ID_HOOKS
ModuleHooks, Hook Commands
Definition module_api.h:71
Hooks private Module data.
Definition module_data.h:33
struct HookList hooks
All simple hooks, e.g. CMD_FOLDER_HOOK.
Definition module_data.h:35
Here is the call graph for this function:

◆ parse_charset_hook()

enum CommandResult parse_charset_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 57 of file parse.c.

59{
60 struct Buffer *err = pe->message;
61
62 if (!MoreArgs(line))
63 {
64 buf_printf(err, _("%s: too few arguments"), cmd->name);
65 return MUTT_CMD_WARNING;
66 }
67
68 struct Buffer *alias = buf_pool_get();
69 struct Buffer *charset = buf_pool_get();
71
72 if (parse_extract_token(alias, line, TOKEN_NONE) < 0)
73 goto done;
74 if (parse_extract_token(charset, line, TOKEN_NONE) < 0)
75 goto done;
76
77 const enum LookupType type = (cmd->id == CMD_ICONV_HOOK) ? MUTT_LOOKUP_ICONV :
79
80 if (buf_is_empty(alias) || buf_is_empty(charset))
81 {
82 buf_printf(err, _("%s: too few arguments"), cmd->name);
84 }
85 else if (MoreArgs(line))
86 {
87 buf_printf(err, _("%s: too many arguments"), cmd->name);
88 buf_reset(line); // clean up buffer to avoid a mess with further rcfile processing
90 }
91 else if (mutt_ch_lookup_add(type, buf_string(alias), buf_string(charset), err))
92 {
94 }
95
96done:
97 buf_pool_release(&alias);
98 buf_pool_release(&charset);
99
100 return rc;
101}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:89
@ CMD_ICONV_HOOK
:iconv-hook
Definition command.h:85
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:496
LookupType
Types of character set lookups.
Definition charset.h:61
@ MUTT_LOOKUP_ICONV
Character set conversion.
Definition charset.h:63
@ MUTT_LOOKUP_CHARSET
Alias for another character set.
Definition charset.h:62
Here is the call graph for this function:

◆ parse_global_hook()

enum CommandResult parse_global_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 111 of file parse.c.

113{
114 struct Buffer *err = pe->message;
115
117 struct Hook *hook = NULL;
119
120 struct Buffer *command = buf_pool_get();
121
122 // TOKEN_SPACE allows the command to contain whitespace, without quoting
123 parse_extract_token(command, line, TOKEN_SPACE);
124
125 if (buf_is_empty(command))
126 {
127 buf_printf(err, _("%s: too few arguments"), cmd->name);
128 rc = MUTT_CMD_WARNING;
129 goto cleanup;
130 }
131
132 if (MoreArgs(line))
133 {
134 buf_printf(err, _("%s: too many arguments"), cmd->name);
135 rc = MUTT_CMD_WARNING;
136 goto cleanup;
137 }
138
139 /* check to make sure that a matching Hook doesn't already exist */
140 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
141 {
142 /* Ignore duplicate global Hooks */
143 if ((hook->id == cmd->id) && mutt_str_equal(hook->command, buf_string(command)))
144 {
145 rc = MUTT_CMD_SUCCESS;
146 goto cleanup;
147 }
148 }
149
150 hook = hook_new();
151 hook->id = cmd->id;
152 hook->command = buf_strdup(command);
154 hook->pattern = NULL;
155 hook->regex.pattern = NULL;
156 hook->regex.regex = NULL;
157 hook->regex.pat_not = false;
158 hook->expando = NULL;
159
160 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
161 rc = MUTT_CMD_SUCCESS;
162
163cleanup:
164 buf_pool_release(&command);
165 return rc;
166}
struct Hook * hook_new(void)
Create a Hook.
Definition hook.c:71
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:866
char * mutt_get_sourced_cwd(void)
Get the current file path that is being parsed.
Definition source.c:317
A list of user hooks.
Definition hook.h:33
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition hook.h:38
struct Regex regex
Regular expression.
Definition hook.h:35
char * command
Filename, command or pattern to execute.
Definition hook.h:36
struct Expando * expando
Used for format hooks.
Definition hook.h:39
enum CommandId id
Hook CommandId, e.g. CMD_FOLDER_HOOK.
Definition hook.h:34
char * source_file
Used for relative-directory source.
Definition hook.h:37
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:

◆ parse_pattern_hook()

enum CommandResult parse_pattern_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 177 of file parse.c.

179{
180 struct Buffer *err = pe->message;
181
183 struct Hook *hook = NULL;
185 bool pat_not = false;
186 struct PatternList *pat = NULL;
187
188 struct Buffer *command = buf_pool_get();
189 struct Buffer *pattern = buf_pool_get();
190
191 if (*line->dptr == '!')
192 {
193 line->dptr++;
194 SKIPWS(line->dptr);
195 pat_not = true;
196 }
197
198 parse_extract_token(pattern, line, TOKEN_NONE);
199
200 if (!MoreArgs(line))
201 {
202 buf_printf(err, _("%s: too few arguments"), cmd->name);
203 rc = MUTT_CMD_WARNING;
204 goto cleanup;
205 }
206
207 // TOKEN_SPACE allows the command to contain whitespace, without quoting
208 parse_extract_token(command, line, TOKEN_SPACE);
209
210 if (buf_is_empty(command))
211 {
212 buf_printf(err, _("%s: too few arguments"), cmd->name);
213 rc = MUTT_CMD_WARNING;
214 goto cleanup;
215 }
216
217 if (MoreArgs(line))
218 {
219 buf_printf(err, _("%s: too many arguments"), cmd->name);
220 rc = MUTT_CMD_WARNING;
221 goto cleanup;
222 }
223
224 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
225 if (c_default_hook)
226 {
227 mutt_check_simple(pattern, c_default_hook);
228 }
229
230 /* check to make sure that a matching hook doesn't already exist */
231 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
232 {
233 if ((hook->id == cmd->id) && (hook->regex.pat_not == pat_not) &&
234 mutt_str_equal(buf_string(pattern), hook->regex.pattern))
235 {
236 /* these hooks allow multiple commands with the same pattern,
237 * so if we've already seen this pattern/command pair,
238 * just ignore it instead of creating a duplicate */
239 if (mutt_str_equal(hook->command, buf_string(command)))
240 {
241 rc = MUTT_CMD_SUCCESS;
242 goto cleanup;
243 }
244 }
245 }
246
247 PatternCompFlags comp_flags;
248 if (cmd->id == CMD_SEND2_HOOK)
249 comp_flags = MUTT_PC_SEND_MODE_SEARCH;
250 else if (cmd->id == CMD_SEND_HOOK)
251 comp_flags = MUTT_PC_NONE;
252 else
253 comp_flags = MUTT_PC_FULL_MSG;
254
255 struct MailboxView *mv_cur = get_current_mailbox_view();
256 pat = mutt_pattern_comp(mv_cur, buf_string(pattern), comp_flags, err);
257 if (!pat)
258 goto cleanup;
259
260 hook = hook_new();
261 hook->id = cmd->id;
262 hook->command = buf_strdup(command);
264 hook->pattern = pat;
266 hook->regex.regex = NULL;
267 hook->regex.pat_not = pat_not;
268 hook->expando = NULL;
269
270 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
271 rc = MUTT_CMD_SUCCESS;
272
273cleanup:
274 buf_pool_release(&command);
276 return rc;
277}
@ CMD_SEND_HOOK
:send-hook
Definition command.h:110
@ CMD_SEND2_HOOK
:send2-hook
Definition command.h:109
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
uint8_t PatternCompFlags
Definition lib.h:78
void mutt_check_simple(struct Buffer *s, const char *simple)
Convert a simple search into a real request.
Definition pattern.c:91
@ MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition lib.h:76
@ MUTT_PC_FULL_MSG
Enable body and header matching.
Definition lib.h:74
char * pattern
Limit pattern string.
Definition mview.h:42
Here is the call graph for this function:

◆ parse_mailbox_hook()

enum CommandResult parse_mailbox_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 349 of file parse.c.

351{
352 struct Buffer *err = pe->message;
353
355 bool pat_not = false;
356
357 struct Buffer *pattern = buf_pool_get();
358 struct Buffer *mailbox = buf_pool_get();
359
360 if (*line->dptr == '!')
361 {
362 line->dptr++;
363 SKIPWS(line->dptr);
364 pat_not = true;
365 }
366
367 parse_extract_token(pattern, line, TOKEN_NONE);
368
369 if (!MoreArgs(line))
370 {
371 buf_printf(err, _("%s: too few arguments"), cmd->name);
372 rc = MUTT_CMD_WARNING;
373 goto cleanup;
374 }
375
376 parse_extract_token(mailbox, line, TOKEN_NONE);
377
378 if (buf_is_empty(mailbox))
379 {
380 buf_printf(err, _("%s: too few arguments"), cmd->name);
381 rc = MUTT_CMD_WARNING;
382 goto cleanup;
383 }
384
385 if (MoreArgs(line))
386 {
387 buf_printf(err, _("%s: too many arguments"), cmd->name);
388 rc = MUTT_CMD_WARNING;
389 goto cleanup;
390 }
391
392 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
393 if (c_default_hook)
394 {
395 mutt_check_simple(pattern, c_default_hook);
396 }
397
398 expand_path(mailbox, false);
399
400 if ((cmd->id == CMD_FCC_HOOK) || (cmd->id == CMD_FCC_SAVE_HOOK))
401 {
402 rc = add_mailbox_hook(CMD_FCC_HOOK, mailbox, pattern, pat_not, err);
403 if (rc != MUTT_CMD_SUCCESS)
404 goto cleanup;
405 }
406
407 if ((cmd->id == CMD_SAVE_HOOK) || (cmd->id == CMD_FCC_SAVE_HOOK))
408 {
409 rc = add_mailbox_hook(CMD_SAVE_HOOK, mailbox, pattern, pat_not, err);
410 if (rc != MUTT_CMD_SUCCESS)
411 goto cleanup;
412 }
413
414 rc = MUTT_CMD_SUCCESS;
415
416cleanup:
417 buf_pool_release(&pattern);
418 buf_pool_release(&mailbox);
419 return rc;
420}
@ CMD_FCC_SAVE_HOOK
:fcc-save-hook
Definition command.h:79
@ CMD_FCC_HOOK
:fcc-hook
Definition command.h:78
@ CMD_SAVE_HOOK
:save-hook
Definition command.h:107
enum CommandResult add_mailbox_hook(enum CommandId id, struct Buffer *mailbox, struct Buffer *pattern, bool pat_not, struct Buffer *err)
Add a Mailbox Hook.
Definition parse.c:288
Here is the call graph for this function:

◆ parse_regex_hook()

enum CommandResult parse_regex_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • account-hook <regex> <command>

Definition at line 428 of file parse.c.

430{
431 struct Buffer *err = pe->message;
432
434 struct Hook *hook = NULL;
436 bool pat_not = false;
437 regex_t *rx = NULL;
438
439 struct Buffer *regex = buf_pool_get();
440 struct Buffer *command = buf_pool_get();
441
442 if (*line->dptr == '!')
443 {
444 line->dptr++;
445 SKIPWS(line->dptr);
446 pat_not = true;
447 }
448
449 parse_extract_token(regex, line, TOKEN_NONE);
450
451 if (!MoreArgs(line))
452 {
453 buf_printf(err, _("%s: too few arguments"), cmd->name);
454 rc = MUTT_CMD_WARNING;
455 goto cleanup;
456 }
457
458 parse_extract_token(command, line, TOKEN_SPACE);
459
460 if (buf_is_empty(command))
461 {
462 buf_printf(err, _("%s: too few arguments"), cmd->name);
463 rc = MUTT_CMD_WARNING;
464 goto cleanup;
465 }
466
467 if (MoreArgs(line))
468 {
469 buf_printf(err, _("%s: too many arguments"), cmd->name);
470 rc = MUTT_CMD_WARNING;
471 goto cleanup;
472 }
473
474 /* check to make sure that a matching hook doesn't already exist */
475 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
476 {
477 if ((hook->id == cmd->id) && (hook->regex.pat_not == pat_not) &&
478 mutt_str_equal(buf_string(regex), hook->regex.pattern))
479 {
480 // Ignore duplicate hooks
481 if (mutt_str_equal(hook->command, buf_string(command)))
482 {
483 rc = MUTT_CMD_SUCCESS;
484 goto cleanup;
485 }
486 }
487 }
488
489 /* Hooks not allowing full patterns: Check syntax of regex */
490 rx = MUTT_MEM_CALLOC(1, regex_t);
491 int rc2 = REG_COMP(rx, buf_string(regex), 0);
492 if (rc2 != 0)
493 {
494 regerror(rc2, rx, err->data, err->dsize);
495 buf_fix_dptr(err);
496 FREE(&rx);
497 goto cleanup;
498 }
499
500 hook = hook_new();
501 hook->id = cmd->id;
502 hook->command = buf_strdup(command);
504 hook->pattern = NULL;
505 hook->regex.pattern = buf_strdup(regex);
506 hook->regex.regex = rx;
507 hook->regex.pat_not = pat_not;
508 hook->expando = NULL;
509
510 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
511 rc = MUTT_CMD_SUCCESS;
512
513cleanup:
514 buf_pool_release(&regex);
515 buf_pool_release(&command);
516 return rc;
517}
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition buffer.c:189
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition regex3.h:49
size_t dsize
Length of data.
Definition buffer.h:39
Here is the call graph for this function:

◆ parse_folder_hook()

enum CommandResult parse_folder_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 525 of file parse.c.

527{
528 struct Buffer *err = pe->message;
529
531 struct Hook *hook = NULL;
533 bool pat_not = false;
534 bool use_regex = true;
535 regex_t *rx = NULL;
536
537 struct Buffer *regex = buf_pool_get();
538 struct Buffer *command = buf_pool_get();
539
540 if (*line->dptr == '!')
541 {
542 line->dptr++;
543 SKIPWS(line->dptr);
544 pat_not = true;
545 }
546
547 parse_extract_token(regex, line, TOKEN_NONE);
548 if (mutt_str_equal(buf_string(regex), "-noregex"))
549 {
550 use_regex = false;
551 if (!MoreArgs(line))
552 {
553 buf_printf(err, _("%s: too few arguments"), cmd->name);
554 rc = MUTT_CMD_WARNING;
555 goto cleanup;
556 }
557 parse_extract_token(regex, line, TOKEN_NONE);
558 }
559
560 if (!MoreArgs(line))
561 {
562 buf_printf(err, _("%s: too few arguments"), cmd->name);
563 rc = MUTT_CMD_WARNING;
564 goto cleanup;
565 }
566
567 parse_extract_token(command, line, TOKEN_SPACE);
568
569 if (buf_is_empty(command))
570 {
571 buf_printf(err, _("%s: too few arguments"), cmd->name);
572 rc = MUTT_CMD_WARNING;
573 goto cleanup;
574 }
575
576 if (MoreArgs(line))
577 {
578 buf_printf(err, _("%s: too many arguments"), cmd->name);
579 rc = MUTT_CMD_WARNING;
580 goto cleanup;
581 }
582
583 /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
584 * common mistake */
585 if ((buf_at(regex, 0) == '^') && !CurrentFolder)
586 {
587 buf_strcpy(err, _("current mailbox shortcut '^' is unset"));
588 goto cleanup;
589 }
590
591 struct Buffer *tmp = buf_pool_get();
592 buf_copy(tmp, regex);
593 expand_path(tmp, use_regex);
594
595 /* Check for other mailbox shortcuts that expand to the empty string.
596 * This is likely a mistake too */
597 if (buf_is_empty(tmp) && !buf_is_empty(regex))
598 {
599 buf_strcpy(err, _("mailbox shortcut expanded to empty regex"));
600 buf_pool_release(&tmp);
601 goto cleanup;
602 }
603
604 if (use_regex)
605 {
606 buf_copy(regex, tmp);
607 }
608 else
609 {
611 }
612 buf_pool_release(&tmp);
613
614 /* check to make sure that a matching hook doesn't already exist */
615 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
616 {
617 if ((hook->id == cmd->id) && (hook->regex.pat_not == pat_not) &&
618 mutt_str_equal(buf_string(regex), hook->regex.pattern))
619 {
620 // Ignore duplicate hooks
621 if (mutt_str_equal(hook->command, buf_string(command)))
622 {
623 rc = MUTT_CMD_SUCCESS;
624 goto cleanup;
625 }
626 }
627 }
628
629 /* Hooks not allowing full patterns: Check syntax of regex */
630 rx = MUTT_MEM_CALLOC(1, regex_t);
631 int rc2 = REG_COMP(rx, buf_string(regex), 0);
632 if (rc2 != 0)
633 {
634 regerror(rc2, rx, err->data, err->dsize);
635 buf_fix_dptr(err);
636 FREE(&rx);
637 goto cleanup;
638 }
639
640 hook = hook_new();
641 hook->id = cmd->id;
642 hook->command = buf_strdup(command);
644 hook->pattern = NULL;
645 hook->regex.pattern = buf_strdup(regex);
646 hook->regex.regex = rx;
647 hook->regex.pat_not = pat_not;
648 hook->expando = NULL;
649
650 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
651 rc = MUTT_CMD_SUCCESS;
652
653cleanup:
654 buf_pool_release(&regex);
655 buf_pool_release(&command);
656 return rc;
657}
char buf_at(const struct Buffer *buf, size_t offset)
Return the character at the given offset.
Definition buffer.c:674
int mutt_file_sanitize_regex(struct Buffer *dest, const char *src)
Escape any regex-magic characters in a string.
Definition file.c:624
char * CurrentFolder
Currently selected mailbox.
Definition globals.c:38
Here is the call graph for this function:

◆ parse_crypt_hook()

enum CommandResult parse_crypt_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 666 of file parse.c.

668{
669 struct Buffer *err = pe->message;
670
672 struct Hook *hook = NULL;
674 bool pat_not = false;
675 regex_t *rx = NULL;
676
677 struct Buffer *regex = buf_pool_get();
678 struct Buffer *keyid = buf_pool_get();
679
680 if (*line->dptr == '!')
681 {
682 line->dptr++;
683 SKIPWS(line->dptr);
684 pat_not = true;
685 }
686
687 parse_extract_token(regex, line, TOKEN_NONE);
688
689 if (!MoreArgs(line))
690 {
691 buf_printf(err, _("%s: too few arguments"), cmd->name);
692 rc = MUTT_CMD_WARNING;
693 goto cleanup;
694 }
695
696 parse_extract_token(keyid, line, TOKEN_NONE);
697
698 if (buf_is_empty(keyid))
699 {
700 buf_printf(err, _("%s: too few arguments"), cmd->name);
701 rc = MUTT_CMD_WARNING;
702 goto cleanup;
703 }
704
705 if (MoreArgs(line))
706 {
707 buf_printf(err, _("%s: too many arguments"), cmd->name);
708 rc = MUTT_CMD_WARNING;
709 goto cleanup;
710 }
711
712 /* check to make sure that a matching hook doesn't already exist */
713 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
714 {
715 if ((hook->id == cmd->id) && (hook->regex.pat_not == pat_not) &&
716 mutt_str_equal(buf_string(regex), hook->regex.pattern))
717 {
718 // Ignore duplicate hooks
719 if (mutt_str_equal(hook->command, buf_string(keyid)))
720 {
721 rc = MUTT_CMD_SUCCESS;
722 goto cleanup;
723 }
724 }
725 }
726
727 /* Hooks not allowing full patterns: Check syntax of regex */
728 rx = MUTT_MEM_CALLOC(1, regex_t);
729 int rc2 = REG_COMP(rx, buf_string(regex), REG_ICASE);
730 if (rc2 != 0)
731 {
732 regerror(rc2, rx, err->data, err->dsize);
733 buf_fix_dptr(err);
734 FREE(&rx);
735 goto cleanup;
736 }
737
738 hook = hook_new();
739 hook->id = cmd->id;
740 hook->command = buf_strdup(keyid);
742 hook->pattern = NULL;
743 hook->regex.pattern = buf_strdup(regex);
744 hook->regex.regex = rx;
745 hook->regex.pat_not = pat_not;
746 hook->expando = NULL;
747
748 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
749 rc = MUTT_CMD_SUCCESS;
750
751cleanup:
752 buf_pool_release(&regex);
753 buf_pool_release(&keyid);
754 return rc;
755}
Here is the call graph for this function:

◆ parse_mbox_hook()

enum CommandResult parse_mbox_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 763 of file parse.c.

765{
766 struct Buffer *err = pe->message;
767
769 struct Hook *hook = NULL;
771 bool pat_not = false;
772 bool use_regex = true;
773 regex_t *rx = NULL;
774
775 struct Buffer *regex = buf_pool_get();
776 struct Buffer *command = buf_pool_get();
777
778 if (*line->dptr == '!')
779 {
780 line->dptr++;
781 SKIPWS(line->dptr);
782 pat_not = true;
783 }
784
785 parse_extract_token(regex, line, TOKEN_NONE);
786 if (mutt_str_equal(buf_string(regex), "-noregex"))
787 {
788 use_regex = false;
789 if (!MoreArgs(line))
790 {
791 buf_printf(err, _("%s: too few arguments"), cmd->name);
792 rc = MUTT_CMD_WARNING;
793 goto cleanup;
794 }
795 parse_extract_token(regex, line, TOKEN_NONE);
796 }
797
798 if (!MoreArgs(line))
799 {
800 buf_printf(err, _("%s: too few arguments"), cmd->name);
801 rc = MUTT_CMD_WARNING;
802 goto cleanup;
803 }
804
805 parse_extract_token(command, line, TOKEN_NONE);
806
807 if (buf_is_empty(command))
808 {
809 buf_printf(err, _("%s: too few arguments"), cmd->name);
810 rc = MUTT_CMD_WARNING;
811 goto cleanup;
812 }
813
814 if (MoreArgs(line))
815 {
816 buf_printf(err, _("%s: too many arguments"), cmd->name);
817 rc = MUTT_CMD_WARNING;
818 goto cleanup;
819 }
820
821 /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
822 * common mistake */
823 if ((buf_at(regex, 0) == '^') && !CurrentFolder)
824 {
825 buf_strcpy(err, _("current mailbox shortcut '^' is unset"));
826 goto cleanup;
827 }
828
829 struct Buffer *tmp = buf_pool_get();
830 buf_copy(tmp, regex);
831 expand_path(tmp, use_regex);
832
833 /* Check for other mailbox shortcuts that expand to the empty string.
834 * This is likely a mistake too */
835 if (buf_is_empty(tmp) && !buf_is_empty(regex))
836 {
837 buf_strcpy(err, _("mailbox shortcut expanded to empty regex"));
838 buf_pool_release(&tmp);
839 goto cleanup;
840 }
841
842 if (use_regex)
843 {
844 buf_copy(regex, tmp);
845 }
846 else
847 {
849 }
850 buf_pool_release(&tmp);
851
852 expand_path(command, false);
853
854 /* check to make sure that a matching hook doesn't already exist */
855 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
856 {
857 if ((hook->id == cmd->id) && (hook->regex.pat_not == pat_not) &&
858 mutt_str_equal(buf_string(regex), hook->regex.pattern))
859 {
860 // Update an existing hook
861 FREE(&hook->command);
862 hook->command = buf_strdup(command);
863 FREE(&hook->source_file);
865
866 expando_free(&hook->expando);
867 hook->expando = expando_parse(buf_string(command), IndexFormatDef, err);
868
869 rc = MUTT_CMD_SUCCESS;
870 goto cleanup;
871 }
872 }
873
874 /* Hooks not allowing full patterns: Check syntax of regex */
875 rx = MUTT_MEM_CALLOC(1, regex_t);
876 int rc2 = REG_COMP(rx, buf_string(regex), 0);
877 if (rc2 != 0)
878 {
879 regerror(rc2, rx, err->data, err->dsize);
880 buf_fix_dptr(err);
881 FREE(&rx);
882 goto cleanup;
883 }
884
885 struct Expando *exp = expando_parse(buf_string(command), IndexFormatDef, err);
886
887 hook = hook_new();
888 hook->id = cmd->id;
889 hook->command = buf_strdup(command);
891 hook->pattern = NULL;
892 hook->regex.pattern = buf_strdup(regex);
893 hook->regex.regex = rx;
894 hook->regex.pat_not = pat_not;
895 hook->expando = exp;
896
897 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
898 rc = MUTT_CMD_SUCCESS;
899
900cleanup:
901 buf_pool_release(&regex);
902 buf_pool_release(&command);
903 return rc;
904}
const struct ExpandoDefinition IndexFormatDef[]
Expando definitions.
struct Expando * expando_parse(const char *str, const struct ExpandoDefinition *defs, struct Buffer *err)
Parse an Expando string.
Definition expando.c:124
void expando_free(struct Expando **ptr)
Free an Expando object.
Definition expando.c:61
Parsed Expando trees.
Definition expando.h:41
Here is the call graph for this function:

◆ parse_compress_hook()

enum CommandResult parse_compress_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 914 of file parse.c.

916{
917 struct Buffer *err = pe->message;
918
920 struct Hook *hook = NULL;
921 struct Expando *exp = NULL;
923 bool pat_not = false;
924 regex_t *rx = NULL;
925
926 struct Buffer *regex = buf_pool_get();
927 struct Buffer *command = buf_pool_get();
928
929 if (*line->dptr == '!')
930 {
931 line->dptr++;
932 SKIPWS(line->dptr);
933 pat_not = true;
934 }
935
936 parse_extract_token(regex, line, TOKEN_NONE);
937
938 if (!MoreArgs(line))
939 {
940 buf_printf(err, _("%s: too few arguments"), cmd->name);
941 rc = MUTT_CMD_WARNING;
942 goto cleanup;
943 }
944
945 // TOKEN_SPACE allows the command to contain whitespace, without quoting
946 parse_extract_token(command, line, TOKEN_SPACE);
947
948 if (buf_is_empty(command))
949 {
950 buf_printf(err, _("%s: too few arguments"), cmd->name);
951 rc = MUTT_CMD_WARNING;
952 goto cleanup;
953 }
954
955 if (MoreArgs(line))
956 {
957 buf_printf(err, _("%s: too many arguments"), cmd->name);
958 rc = MUTT_CMD_WARNING;
959 goto cleanup;
960 }
961
962 exp = expando_parse(buf_string(command), CompressFormatDef, err);
963 if (!exp)
964 goto cleanup;
965
968 {
969 buf_strcpy(err, _("badly formatted command string"));
970 goto cleanup;
971 }
972
973 /* check to make sure that a matching hook doesn't already exist */
974 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
975 {
976 if ((hook->id == cmd->id) && (hook->regex.pat_not == pat_not) &&
977 mutt_str_equal(buf_string(regex), hook->regex.pattern))
978 {
979 // Update an existing hook
980 FREE(&hook->command);
981 hook->command = buf_strdup(command);
982 FREE(&hook->source_file);
984 expando_free(&hook->expando);
985 hook->expando = exp;
986 exp = NULL;
987
988 rc = MUTT_CMD_SUCCESS;
989 goto cleanup;
990 }
991 }
992
993 /* Hooks not allowing full patterns: Check syntax of regex */
994 rx = MUTT_MEM_CALLOC(1, regex_t);
995 int rc2 = REG_COMP(rx, buf_string(regex), 0);
996 if (rc2 != 0)
997 {
998 regerror(rc2, rx, err->data, err->dsize);
999 buf_fix_dptr(err);
1000 FREE(&rx);
1001 goto cleanup;
1002 }
1003
1004 hook = hook_new();
1005 hook->id = cmd->id;
1006 hook->command = buf_strdup(command);
1008 hook->pattern = NULL;
1009 hook->regex.pattern = buf_strdup(regex);
1010 hook->regex.regex = rx;
1011 hook->regex.pat_not = pat_not;
1012 hook->expando = exp;
1013 exp = NULL;
1014
1015 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
1016 rc = MUTT_CMD_SUCCESS;
1017
1018cleanup:
1019 expando_free(&exp);
1020 buf_pool_release(&regex);
1021 buf_pool_release(&command);
1022 return rc;
1023}
const struct ExpandoDefinition CompressFormatDef[]
Expando definitions.
Definition compress.c:89
@ ED_CMP_FROM
'from' path
Definition lib.h:51
@ ED_CMP_TO
'to' path
Definition lib.h:52
@ ED_COMPRESS
Compress ED_CMP_ ExpandoDataCompress.
Definition domain.h:40
const struct ExpandoNode * expando_find_node(const struct Expando *exp, int did, int uid)
Find a Node in an Expando tree.
Definition expando.c:109
Here is the call graph for this function:

◆ parse_index_hook()

enum CommandResult parse_index_hook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 1080 of file parse.c.

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

◆ parse_unhook()

enum CommandResult parse_unhook ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unhook { * | <hook-type> }

Definition at line 1204 of file parse.c.

1206{
1207 struct Buffer *err = pe->message;
1208
1209 if (!MoreArgs(line))
1210 {
1211 buf_printf(err, _("%s: too few arguments"), cmd->name);
1212 return MUTT_CMD_WARNING;
1213 }
1214
1216 struct Buffer *token = buf_pool_get();
1218
1219 while (MoreArgs(line))
1220 {
1221 parse_extract_token(token, line, TOKEN_NONE);
1222 if (mutt_str_equal("*", buf_string(token)))
1223 {
1224 if (mod_data->current_hook_id != CMD_NONE)
1225 {
1226 buf_addstr(err, _("unhook: Can't do unhook * from within a hook"));
1227 goto done;
1228 }
1229 mutt_delete_hooks(&mod_data->hooks, CMD_NONE);
1232 break;
1233 }
1234 else
1235 {
1236 const struct Command *hook = command_find_by_name(&NeoMutt->commands,
1237 buf_string(token));
1238 if (!hook)
1239 {
1240 buf_printf(err, _("unhook: unknown hook type: %s"), buf_string(token));
1241 rc = MUTT_CMD_ERROR;
1242 goto done;
1243 }
1244
1245 if ((hook->id == CMD_CHARSET_HOOK) || (hook->id == CMD_ICONV_HOOK))
1246 {
1248 }
1249 else if ((mod_data->current_hook_id == hook->id) ||
1250 ((hook->id == CMD_FCC_SAVE_HOOK) &&
1251 ((mod_data->current_hook_id == CMD_FCC_HOOK) ||
1252 (mod_data->current_hook_id == CMD_SAVE_HOOK))))
1253 {
1254 buf_printf(err, _("unhook: Can't delete a %s from within a %s"),
1255 buf_string(token), buf_string(token));
1256 rc = MUTT_CMD_WARNING;
1257 goto done;
1258 }
1259 else if (hook->id == CMD_INDEX_FORMAT_HOOK)
1260 {
1262 }
1263 else if (hook->id == CMD_FCC_SAVE_HOOK)
1264 {
1267 }
1268 else
1269 {
1270 mutt_delete_hooks(&mod_data->hooks, hook->id);
1271 }
1272 }
1273 }
1274
1275 rc = MUTT_CMD_SUCCESS;
1276
1277done:
1278 buf_pool_release(&token);
1279 return rc;
1280}
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:233
@ CMD_CHARSET_HOOK
:charset-hook
Definition command.h:72
@ CMD_NONE
No Command.
Definition command.h:62
const struct Command * command_find_by_name(const struct CommandArray *ca, const char *name)
Find a NeoMutt Command by its name.
Definition commands.c:145
void mutt_delete_hooks(struct HookList *hooks, enum CommandId id)
Delete matching hooks.
Definition parse.c:1032
void delete_idxfmt_hooks(struct HashTable **idx_fmt_hooks)
Delete all the index-format-hooks.
Definition parse.c:1069
void mutt_ch_lookup_remove(void)
Remove all the character set lookups.
Definition charset.c:528
int current_hook_id
The ID of the Hook currently being executed.
Definition module_data.h:37
Here is the call graph for this function:

◆ parse_subscribe_to()

enum CommandResult parse_subscribe_to ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

The 'subscribe-to' command allows to subscribe to an IMAP-Mailbox. Patterns are not supported.

Parse:

  • subscribe-to <imap-folder-uri>

Definition at line 93 of file imap.c.

95{
96 struct Buffer *err = pe->message;
97
98 if (!MoreArgs(line))
99 {
100 buf_printf(err, _("%s: too few arguments"), cmd->name);
101 return MUTT_CMD_WARNING;
102 }
103
104 struct Buffer *token = buf_pool_get();
106
107 buf_reset(err);
108
109 parse_extract_token(token, line, TOKEN_NONE);
110
111 if (MoreArgs(line))
112 {
113 buf_printf(err, _("%s: too many arguments"), cmd->name);
114 goto done;
115 }
116
117 // Expand and subscribe
118 expand_path(token, false);
119 if (imap_subscribe(buf_string(token), true) != 0)
120 {
121 buf_printf(err, _("Could not subscribe to %s"), buf_string(token));
122 rc = MUTT_CMD_ERROR;
123 goto done;
124 }
125
126 mutt_message(_("Subscribed to %s"), buf_string(token));
127 rc = MUTT_CMD_SUCCESS;
128
129done:
130 buf_pool_release(&token);
131 return rc;
132}
int imap_subscribe(const char *path, bool subscribe)
Subscribe to a mailbox.
Definition imap.c:1413
Here is the call graph for this function:

◆ parse_unsubscribe_from()

enum CommandResult parse_unsubscribe_from ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

The 'unsubscribe-from' command allows to unsubscribe from an IMAP-Mailbox. Patterns are not supported.

Parse:

  • unsubscribe-from <imap-folder-uri>

Definition at line 143 of file imap.c.

146{
147 struct Buffer *err = pe->message;
148
149 if (!MoreArgs(line))
150 {
151 buf_printf(err, _("%s: too few arguments"), cmd->name);
152 return MUTT_CMD_WARNING;
153 }
154
155 struct Buffer *token = buf_pool_get();
157
158 parse_extract_token(token, line, TOKEN_NONE);
159
160 if (MoreArgs(line))
161 {
162 buf_printf(err, _("%s: too many arguments"), cmd->name);
163 goto done;
164 }
165
166 // Expand and unsubscribe
167 expand_path(token, false);
168 if (imap_subscribe(buf_string(token), false) != 0)
169 {
170 buf_printf(err, _("Could not unsubscribe from %s"), buf_string(token));
171 rc = MUTT_CMD_ERROR;
172 goto done;
173 }
174
175 mutt_message(_("Unsubscribed from %s"), buf_string(token));
176 rc = MUTT_CMD_SUCCESS;
177
178done:
179 buf_pool_release(&token);
180 return rc;
181}
Here is the call graph for this function:

◆ parse_subjectrx_list()

enum CommandResult parse_subjectrx_list ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • subject-regex <regex> <replacement>

Definition at line 192 of file subjectrx.c.

195{
196 struct Buffer *err = pe->message;
197
198 if (!MoreArgs(line))
199 {
200 buf_printf(err, _("%s: too few arguments"), cmd->name);
201 return MUTT_CMD_WARNING;
202 }
203
205 ASSERT(mod_data);
206
207 enum CommandResult rc;
208
209 rc = parse_replace_list(cmd, line, &mod_data->subject_rx_list, err);
210 if (rc == MUTT_CMD_SUCCESS)
211 {
212 mutt_debug(LL_NOTIFY, "NT_SUBJECTRX_ADD: %s\n", cmd->name);
214 }
215 return rc;
216}
@ MODULE_ID_INDEX
ModuleIndex, Index
Definition module_api.h:73
@ NT_SUBJECTRX
Subject Regex has changed, NotifySubjectRx.
Definition notify_type.h:56
Index private Module data.
Definition module_data.h:32
struct Notify * subject_rx_notify
Notifications: NotifySubjectRx.
Definition module_data.h:37
struct ReplaceList subject_rx_list
List of subject-regex rules for modifying the Subject:
Definition module_data.h:36
static enum CommandResult parse_replace_list(const struct Command *cmd, struct Buffer *line, struct ReplaceList *list, struct Buffer *err)
Parse a string replacement rule.
Definition subjectrx.c:104
@ NT_SUBJECTRX_ADD
Subject Regex has been added.
Definition subjectrx.h:45
Here is the call graph for this function:

◆ parse_unsubjectrx_list()

enum CommandResult parse_unsubjectrx_list ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unsubject-regex { * | <regex> }

Definition at line 224 of file subjectrx.c.

227{
228 struct Buffer *err = pe->message;
229
230 if (!MoreArgs(line))
231 {
232 buf_printf(err, _("%s: too few arguments"), cmd->name);
233 return MUTT_CMD_WARNING;
234 }
235
237 ASSERT(mod_data);
238
239 enum CommandResult rc;
240
241 rc = parse_unreplace_list(cmd, line, &mod_data->subject_rx_list, err);
242 if (rc == MUTT_CMD_SUCCESS)
243 {
244 mutt_debug(LL_NOTIFY, "NT_SUBJECTRX_DELETE: %s\n", cmd->name);
246 }
247 return rc;
248}
static enum CommandResult parse_unreplace_list(const struct Command *cmd, struct Buffer *line, struct ReplaceList *list, struct Buffer *err)
Remove a string replacement rule.
Definition subjectrx.c:68
@ NT_SUBJECTRX_DELETE
Subject Regex has been deleted.
Definition subjectrx.h:46
Here is the call graph for this function:

◆ parse_dump()

enum CommandResult parse_dump ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Definition at line 64 of file commands.c.

66{
67 struct Buffer *err = pe->message;
68
69 struct Buffer *token = buf_pool_get();
70 const struct MenuDefinition *md = NULL;
72
73 if (MoreArgs(line))
74 {
75 parse_extract_token(token, line, TOKEN_NONE);
76
77 if (MoreArgs(line))
78 {
79 /* More arguments potentially means the user is using the
80 * ::command_t :bind command thus we delegate the task. */
81 goto done;
82 }
83
84 if (!mutt_str_equal(buf_string(token), "all"))
85 {
86 md = menu_find_by_name(buf_string(token));
87 if (!md)
88 {
89 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
90 buf_printf(err, _("%s: no such menu"), buf_string(token));
91 goto done;
92 }
93 }
94 }
95
96 dump_bind_macro(cmd, md, token, err);
98
99done:
100 buf_pool_release(&token);
101 return rc;
102}
void dump_bind_macro(const struct Command *cmd, const struct MenuDefinition *md, struct Buffer *buf, struct Buffer *err)
Dump a Menu's binds or macros to the Pager.
Definition dump.c:389
struct MenuDefinition * menu_find_by_name(const char *name)
Find a Menu Definition by its name.
Definition menu.c:251
Functions for a Dialog or Window.
Definition menudef.h:44
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_push()

enum CommandResult parse_push ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • push <string>

Definition at line 205 of file commands.c.

207{
208 struct Buffer *err = pe->message;
209
210 if (!MoreArgs(line))
211 {
212 buf_printf(err, _("%s: too few arguments"), cmd->name);
213 return MUTT_CMD_WARNING;
214 }
215
216 struct Buffer *token = buf_pool_get();
218
220 if (MoreArgs(line))
221 {
222 buf_printf(err, _("%s: too many arguments"), cmd->name);
223 goto done;
224 }
225
227 rc = MUTT_CMD_SUCCESS;
228
229done:
230 buf_pool_release(&token);
231 return rc;
232}
@ TOKEN_CONDENSE
^(char) to control chars (macros)
Definition extract.h:52
void generic_tokenize_push_string(char *s)
Parse and queue a 'push' command.
Definition get.c:352
Here is the call graph for this function:

◆ parse_bind()

enum CommandResult parse_bind ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

bind menu-name <key_sequence> function-name

Parse:

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

Definition at line 242 of file commands.c.

244{
245 struct Buffer *err = pe->message;
246
247 if (StartupComplete)
248 {
249 // Save and restore the offset in `line` because parse_dump() might change it
250 char *dptr = line->dptr;
251 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
252 {
253 return MUTT_CMD_SUCCESS;
254 }
255 if (!buf_is_empty(err))
256 {
257 return MUTT_CMD_ERROR;
258 }
259 line->dptr = dptr;
260 }
261
262 struct Buffer *token = buf_pool_get();
263 struct Buffer *keystr = NULL;
264
265 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
267
268 char *key = parse_keymap(cmd, &mda, line, err);
269 if (!key)
270 goto done;
271
272 /* function to execute */
273 parse_extract_token(token, line, TOKEN_NONE);
274 if (MoreArgs(line))
275 {
276 buf_printf(err, _("%s: too many arguments"), cmd->name);
277 goto done;
278 }
279
280 rc = MUTT_CMD_SUCCESS;
281
282 if (mutt_istr_equal("noop", buf_string(token)))
283 {
284 keystr = buf_pool_get();
285 struct MenuDefinition **mdp = NULL;
286 ARRAY_FOREACH(mdp, &mda)
287 {
288 struct MenuDefinition *md = *mdp;
289
290 km_bind(md, key, OP_NULL, NULL, NULL, NULL); /* the 'unbind' command */
291
292 buf_reset(keystr);
293 keymap_expand_string(key, keystr);
294 mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", md->name, buf_string(keystr));
295
296 int op = km_get_op_menu(md->id, buf_string(token));
297
298 struct EventBinding ev_b = { md, key, op };
300 }
301 }
302 else
303 {
304 keystr = buf_pool_get();
305 struct MenuDefinition **mdp = NULL;
306 ARRAY_FOREACH(mdp, &mda)
307 {
308 struct MenuDefinition *md = *mdp;
309
310 int op = OP_NULL;
311 struct SubMenu **ptr = NULL;
312 ARRAY_FOREACH(ptr, &md->submenus)
313 {
314 struct SubMenu *sm = *ptr;
315 const struct MenuFuncOp *mfo = NULL;
316 for (int j = 0; sm->functions[j].name; j++)
317 {
318 mfo = &sm->functions[j];
319 if (mutt_str_equal(buf_string(token), mfo->name))
320 {
321 op = mfo->op;
322 break;
323 }
324 }
325 if (op != OP_NULL)
326 break;
327 }
328
329 if (op == OP_NULL)
330 {
331 buf_printf(err, _("%s: no such function: %s"), cmd->name, buf_string(token));
332 rc = MUTT_CMD_ERROR;
333 goto done;
334 }
335
336 rc = km_bind(md, key, op, NULL, NULL, err);
337 if (rc == MUTT_CMD_SUCCESS)
338 {
339 buf_reset(keystr);
340 keymap_expand_string(key, keystr);
341 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", md->name, buf_string(keystr));
342
343 struct EventBinding ev_b = { md, key, op };
345 }
346 }
347 }
348
349done:
350 FREE(&key);
351 ARRAY_FREE(&mda);
352 buf_pool_release(&keystr);
353 buf_pool_release(&token);
354 return rc;
355}
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
enum CommandResult parse_dump(const struct Command *cmd, struct Buffer *line, const struct ParseContext *pc, struct ParseError *pe)
Parse 'bind' and 'macro' commands - Implements Command::parse() -.
Definition commands.c:64
char * parse_keymap(const struct Command *cmd, struct MenuDefinitionArray *mda, struct Buffer *line, struct Buffer *err)
Parse a user-config key binding.
Definition commands.c:116
enum CommandResult km_bind(const struct MenuDefinition *md, const char *key_str, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition menu.c:52
void keymap_expand_string(const char *str, struct Buffer *buf)
Get a human-readable key string.
Definition keymap.c:265
int km_get_op_menu(int mtype, const char *func)
Get the OpCode for a Function from a Menu.
Definition menu.c:198
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition notify.h:49
@ NT_BINDING_ADD
Key binding has been added.
Definition notify.h:48
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition notify_type.h:40
A key binding Event.
Definition notify.h:33
const char * key
Key string being bound (for new bind/macro).
Definition notify.h:35
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition notify.h:36
struct SubMenuArray submenus
Parts making up the Menu.
Definition menudef.h:47
const char * name
Menu name, e.g. "alias".
Definition menudef.h:46
int id
Menu ID, e.g. MENU_ALIAS.
Definition menudef.h:45
Mapping between a function and an operation.
Definition menu.h:37
const char * name
Name of the function.
Definition menu.h:38
int op
Operation, e.g. OP_DELETE.
Definition menu.h:39
Collection of related functions.
Definition menudef.h:33
const struct MenuFuncOp * functions
All available functions.
Definition menudef.h:35
Here is the call graph for this function:

◆ parse_unbind()

enum CommandResult parse_unbind ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

Parse the 'unbind' and 'unmacro' commands - Implements Command::parse() -.

Parse:

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

Definition at line 676 of file commands.c.

678{
679 struct Buffer *err = pe->message;
680
681 struct ParseUnbind args = { 0 };
683
684 if (!parse_unbind_args(cmd, line, err, &args))
685 goto done;
686
687 rc = MUTT_CMD_ERROR;
688 if (parse_unbind_exec(cmd, &args, err))
689 rc = MUTT_CMD_SUCCESS;
690
691done:
692 ARRAY_FREE(&args.mda);
693 FREE(&args.key);
694 return rc;
695}
bool parse_unbind_exec(const struct Command *cmd, struct ParseUnbind *args, struct Buffer *err)
Execute the 'unbind' or 'unmacro' command.
Definition commands.c:554
bool parse_unbind_args(const struct Command *cmd, struct Buffer *line, struct Buffer *err, struct ParseUnbind *args)
Parse the 'unbind' and 'unmacro' commands.
Definition commands.c:455
Parsed 'unbind' or 'unmacro' command.
Definition commands.c:53
struct MenuDefinitionArray mda
Menus to work on.
Definition commands.c:54
const char * key
Key string to be removed.
Definition commands.c:58
Here is the call graph for this function:

◆ parse_macro()

enum CommandResult parse_macro ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 703 of file commands.c.

705{
706 struct Buffer *err = pe->message;
707
708 if (StartupComplete)
709 {
710 // Save and restore the offset in `line` because parse_dump() might change it
711 char *dptr = line->dptr;
712 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
713 {
714 return MUTT_CMD_SUCCESS;
715 }
716 if (!buf_is_empty(err))
717 {
718 return MUTT_CMD_ERROR;
719 }
720 line->dptr = dptr;
721 }
722
723 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
724 struct Buffer *token = buf_pool_get();
725 struct Buffer *keystr = NULL;
727
728 char *key = parse_keymap(cmd, &mda, line, err);
729 if (!key)
730 goto done;
731
733 /* make sure the macro sequence is not an empty string */
734 if (buf_at(token, 0) == '\0')
735 {
736 buf_strcpy(err, _("macro: empty key sequence"));
737 }
738 else
739 {
740 if (MoreArgs(line))
741 {
742 char *seq = mutt_str_dup(buf_string(token));
744
745 if (MoreArgs(line))
746 {
747 buf_printf(err, _("%s: too many arguments"), cmd->name);
748 }
749 else
750 {
751 keystr = buf_pool_get();
752 struct MenuDefinition **mdp = NULL;
753 ARRAY_FOREACH(mdp, &mda)
754 {
755 struct MenuDefinition *md = *mdp;
756
757 rc = km_bind(md, key, OP_MACRO, seq, token->data, NULL);
758 if (rc == MUTT_CMD_SUCCESS)
759 {
760 buf_reset(keystr);
761 keymap_expand_string(key, keystr);
762 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
763
764 struct EventBinding ev_b = { md, key, OP_MACRO };
766 continue;
767 }
768 }
769 }
770
771 FREE(&seq);
772 }
773 else
774 {
775 keystr = buf_pool_get();
776 struct MenuDefinition **mdp = NULL;
777 ARRAY_FOREACH(mdp, &mda)
778 {
779 struct MenuDefinition *md = *mdp;
780
781 rc = km_bind(md, key, OP_MACRO, token->data, NULL, NULL);
782 if (rc == MUTT_CMD_SUCCESS)
783 {
784 buf_reset(keystr);
785 keymap_expand_string(key, keystr);
786 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
787
788 struct EventBinding ev_b = { md, key, OP_MACRO };
790 continue;
791 }
792 }
793 }
794 }
795
796done:
797 FREE(&key);
798 ARRAY_FREE(&mda);
799 buf_pool_release(&keystr);
800 buf_pool_release(&token);
801 return rc;
802}
@ NT_MACRO_ADD
Key macro has been added.
Definition notify.h:50
Here is the call graph for this function:

◆ parse_exec()

enum CommandResult parse_exec ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 810 of file commands.c.

812{
813 struct Buffer *err = pe->message;
814
815 if (!MoreArgs(line))
816 {
817 buf_printf(err, _("%s: too few arguments"), cmd->name);
818 return MUTT_CMD_WARNING;
819 }
820
821 struct Buffer *token = buf_pool_get();
823
824 int ops[128] = { 0 };
825 int nops = 0;
826 char *function = NULL;
827
828 do
829 {
830 parse_extract_token(token, line, TOKEN_NONE);
831 function = token->data;
832
833 const enum MenuType mtype = menu_get_current_type();
834 ops[nops] = km_get_op_menu(mtype, function);
835 if (ops[nops] == OP_NULL)
836 {
838 mutt_error(_("%s: no such function"), function);
839 goto done;
840 }
841 nops++;
842 } while (MoreArgs(line) && nops < countof(ops));
843
844 while (nops)
845 mutt_push_macro_event(0, ops[--nops]);
846
847 rc = MUTT_CMD_SUCCESS;
848
849done:
850 buf_pool_release(&token);
851 return rc;
852}
void mutt_flushinp(void)
MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.
Definition get.c:81
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition get.c:173
#define countof(x)
Definition memory.h:49
enum MenuType menu_get_current_type(void)
Get the type of the current Window.
Definition menu.c:80
MenuType
Types of GUI selections.
Definition type.h:33
Here is the call graph for this function:

◆ parse_lua()

enum CommandResult parse_lua ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • lua <lua-command>

Definition at line 56 of file commands.c.

58{
60 struct Buffer *err = pe->message;
61
62 if (!MoreArgs(line))
63 {
64 buf_printf(err, _("%s: too few arguments"), cmd->name);
65 return MUTT_CMD_WARNING;
66 }
67
68 // From here on, use the remainder of `line`, raw
70
71 lua_State *lua_state = mod_data->lua_state;
72 lua_init_state(&lua_state);
73 mod_data->lua_state = lua_state;
74 mutt_debug(LL_DEBUG2, "%s\n", line->dptr);
75
76 if (luaL_dostring(lua_state, line->dptr) != LUA_OK)
77 {
78 mutt_debug(LL_DEBUG2, "%s -> failure\n", line->dptr);
79 buf_printf(err, "%s: %s", line->dptr, lua_tostring(lua_state, -1));
80 /* pop error message from the stack */
81 lua_pop(lua_state, 1);
82 goto done;
83 }
84 mutt_debug(LL_DEBUG2, "%s -> success\n", line->dptr);
85 buf_reset(line); // Clear the rest of the line
86
88
89done:
90 return rc;
91}
@ LL_DEBUG2
Log at debug level 2.
Definition logging2.h:46
bool lua_init_state(lua_State **l)
Initialise a Lua State.
Definition lua.c:443
@ MODULE_ID_LUA
ModuleLua, Integrated Lua scripting
Definition module_api.h:75
Lua private Module data.
Definition module_data.h:35
lua_State * lua_state
Lua State.
Definition module_data.h:37
Here is the call graph for this function:

◆ parse_lua_source()

enum CommandResult parse_lua_source ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • lua-source <filename>

Definition at line 99 of file commands.c.

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

◆ parse_set()

enum CommandResult parse_set ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

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

Definition at line 488 of file set.c.

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

◆ parse_my_header()

enum CommandResult parse_my_header ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • my-header <string>

Definition at line 52 of file my_header.c.

54{
55 struct Buffer *err = pe->message;
56
57 if (!MoreArgs(line))
58 {
59 buf_printf(err, _("%s: too few arguments"), cmd->name);
60 return MUTT_CMD_WARNING;
61 }
62
63 struct Buffer *token = buf_pool_get();
65
67 const char *p = strpbrk(buf_string(token), ": \t");
68 if (!p || (*p != ':'))
69 {
70 buf_strcpy(err, _("invalid header field"));
71 goto done;
72 }
73
75 ASSERT(mod_data);
76
77 struct EventHeader ev_h = { token->data };
78 struct ListNode *node = header_find(&mod_data->user_header, buf_string(token));
79
80 if (node)
81 {
82 header_update(node, buf_string(token));
83 mutt_debug(LL_NOTIFY, "NT_HEADER_CHANGE: %s\n", buf_string(token));
85 }
86 else
87 {
88 header_add(&mod_data->user_header, buf_string(token));
89 mutt_debug(LL_NOTIFY, "NT_HEADER_ADD: %s\n", buf_string(token));
91 }
92
94
95done:
96 buf_pool_release(&token);
97 return rc;
98}
struct ListNode * header_add(struct ListHead *hdrlist, const char *header)
Add a header to a list.
Definition email.c:160
struct ListNode * header_update(struct ListNode *hdr, const char *header)
Update an existing header.
Definition email.c:174
struct ListNode * header_find(const struct ListHead *hdrlist, const char *header)
Find a header, matching on its field, in a list of headers.
Definition email.c:137
@ NT_HEADER_CHANGE
An existing header has been changed.
Definition email.h:210
@ NT_HEADER_ADD
Header has been added.
Definition email.h:208
@ MODULE_ID_SEND
ModuleSend, Send
Definition module_api.h:92
@ NT_HEADER
A header has changed, NotifyHeader EventHeader.
Definition notify_type.h:47
An event that happened to a header.
Definition email.h:217
A List node for strings.
Definition list.h:37
Send private Module data.
Definition module_data.h:33
struct ListHead user_header
Custom headers to add to outgoing emails.
Definition module_data.h:35
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_unmy_header()

enum CommandResult parse_unmy_header ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • unmy-header { * | <field> ... }

Definition at line 106 of file my_header.c.

108{
109 struct Buffer *err = pe->message;
110
111 if (!MoreArgs(line))
112 {
113 buf_printf(err, _("%s: too few arguments"), cmd->name);
114 return MUTT_CMD_WARNING;
115 }
116
117 struct Buffer *token = buf_pool_get();
118
119 struct ListNode *np = NULL;
120 struct ListNode *tmp = NULL;
121 size_t l;
122
124 ASSERT(mod_data);
125
126 do
127 {
128 parse_extract_token(token, line, TOKEN_NONE);
129 if (mutt_str_equal("*", buf_string(token)))
130 {
131 /* Clear all headers, send a notification for each header */
132 STAILQ_FOREACH(np, &mod_data->user_header, entries)
133 {
134 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
135 struct EventHeader ev_h = { np->data };
137 }
138 mutt_list_free(&mod_data->user_header);
139 continue;
140 }
141
142 l = mutt_str_len(buf_string(token));
143 if (buf_at(token, l - 1) == ':')
144 l--;
145
146 STAILQ_FOREACH_SAFE(np, &mod_data->user_header, entries, tmp)
147 {
148 if (mutt_istrn_equal(buf_string(token), np->data, l) && (np->data[l] == ':'))
149 {
150 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
151 struct EventHeader ev_h = { np->data };
153
154 header_free(&mod_data->user_header, np);
155 }
156 }
157 } while (MoreArgs(line));
158 buf_pool_release(&token);
159 return MUTT_CMD_SUCCESS;
160}
void header_free(struct ListHead *hdrlist, struct ListNode *target)
Free and remove a header from a header list.
Definition email.c:202
@ NT_HEADER_DELETE
Header has been removed.
Definition email.h:209
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
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:457
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
char * data
String.
Definition list.h:38
Here is the call graph for this function:

◆ parse_sidebar_pin()

enum CommandResult parse_sidebar_pin ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • sidebar-pin <mailbox> [ <mailbox> ... ]

Definition at line 45 of file commands.c.

47{
49 struct Buffer *err = pe->message;
50
51 if (!MoreArgs(line))
52 {
53 buf_printf(err, _("%s: too few arguments"), cmd->name);
54 return MUTT_CMD_WARNING;
55 }
56
57 struct Buffer *path = buf_pool_get();
58
59 do
60 {
62 expand_path(path, false);
63 add_to_stailq(&mod_data->sidebar_pinned, buf_string(path));
64 } while (MoreArgs(line));
65 buf_pool_release(&path);
66
67 return MUTT_CMD_SUCCESS;
68}
@ MODULE_ID_SIDEBAR
ModuleSidebar, Sidebar
Definition module_api.h:93
Sidebar private Module data.
Definition module_data.h:32
struct ListHead sidebar_pinned
List of mailboxes to always display in the sidebar.
Definition module_data.h:36
Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_sidebar_unpin()

enum CommandResult parse_sidebar_unpin ( const struct Command * cmd,
struct Buffer * line,
const struct ParseContext * pc,
struct ParseError * pe )

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

Parse:

  • sidebar-unpin { * | <mailbox> ... }

Definition at line 76 of file commands.c.

78{
80 struct Buffer *err = pe->message;
81
82 if (!MoreArgs(line))
83 {
84 buf_printf(err, _("%s: too few arguments"), cmd->name);
85 return MUTT_CMD_WARNING;
86 }
87
88 struct Buffer *path = buf_pool_get();
89
90 do
91 {
93 /* Check for deletion of entire list */
94 if (mutt_str_equal(buf_string(path), "*"))
95 {
97 break;
98 }
99 expand_path(path, false);
101 } while (MoreArgs(line));
102 buf_pool_release(&path);
103
104 return MUTT_CMD_SUCCESS;
105}
Here is the call graph for this function:
Here is the caller graph for this function: