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

Function to parse a command. More...

+ Collaboration diagram for parse():

Functions

enum CommandResult parse_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 {
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:245
void grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition group.c:203
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:161
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
CommandResult
Error codes for command_t parse functions.
Definition command.h: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:31
#define TOKEN_NO_FLAGS
No flags are set.
Definition extract.h:45
#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:235
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:665
@ 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:159
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 {
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:665
+ 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 */
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:1469
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition address.c:649
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition address.c:1302
void grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition group.c:224
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:661
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
#define TOKEN_SPACE
Don't treat whitespace as a term.
Definition extract.h:48
#define TOKEN_QUOTE
Don't interpret quotes.
Definition extract.h:49
#define TOKEN_SEMICOLON
Don't treat ; as special.
Definition extract.h:52
@ 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:677
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_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition reverse.c:62
void alias_reverse_delete(struct Alias *alias)
Remove an email address lookup for an Alias.
Definition reverse.c:87
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
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 {
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:673
void aliaslist_clear(struct AliasArray *aa)
Empty a List of Aliases.
Definition alias.c:698
#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 {
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:337
void groups_remove_grouplist(struct HashTable *groups, struct GroupList *gl)
Clear a GroupList.
Definition group.c:312
int groups_remove_regex(struct HashTable *groups, struct GroupList *gl, const char *str)
Remove matching addresses from a GroupList.
Definition group.c:368
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:79
@ CMD_UNGROUP
:ungroup
Definition command.h:130
#define TAILQ_EMPTY(head)
Definition queue.h:778
enum CommandId id
ID of the Command.
Definition command.h:160
+ 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 {
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 {
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 {
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:459
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 {
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 472 of file commands.c.

474{
476 ASSERT(mod_data);
477
478 struct Buffer *err = pe->message;
479
480 if (!MoreArgs(line))
481 {
482 buf_printf(err, _("%s: too few arguments"), cmd->name);
483 return MUTT_CMD_WARNING;
484 }
485
486 struct Buffer *token = buf_pool_get();
488
490
491 char *category = token->data;
492 char op = *category++;
493
494 if (op == '?')
495 {
496 mutt_endwin();
497 fflush(stdout);
498 printf("\n%s\n\n", _("Current attachments settings:"));
499 print_attach_list(&mod_data->attach_allow, '+', "A");
500 print_attach_list(&mod_data->attach_exclude, '-', "A");
501 print_attach_list(&mod_data->inline_allow, '+', "I");
502 print_attach_list(&mod_data->inline_exclude, '-', "I");
504
505 rc = MUTT_CMD_SUCCESS;
506 goto done;
507 }
508
509 if ((op != '+') && (op != '-'))
510 {
511 op = '+';
512 category--;
513 }
514
515 struct ListHead *head = NULL;
516 if (mutt_istr_startswith("attachment", category))
517 {
518 if (op == '+')
519 head = &mod_data->attach_allow;
520 else
521 head = &mod_data->attach_exclude;
522 }
523 else if (mutt_istr_startswith("inline", category))
524 {
525 if (op == '+')
526 head = &mod_data->inline_allow;
527 else
528 head = &mod_data->inline_exclude;
529 }
530 else
531 {
532 buf_strcpy(err, _("attachments: invalid disposition"));
533 goto done;
534 }
535
536 rc = parse_attach_list(cmd, line, head, err);
537
538done:
539 buf_pool_release(&token);
540 return rc;
541}
static int print_attach_list(struct ListHead *h, const char op, const char *name)
Print a list of attachments.
Definition commands.c:452
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:291
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition curs_lib.c:175
void mutt_endwin(void)
Shutdown curses.
Definition curs_lib.c:153
@ 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 550 of file commands.c.

552{
553 struct Buffer *err = pe->message;
554
555 if (!MoreArgs(line))
556 {
557 buf_printf(err, _("%s: too few arguments"), cmd->name);
558 return MUTT_CMD_WARNING;
559 }
560
562 ASSERT(mod_data);
563
564 struct Buffer *token = buf_pool_get();
566
567 char op;
568 const char *p = NULL;
569 struct ListHead *head = NULL;
570
572
573 p = buf_string(token);
574 op = *p++;
575
576 if (op == '*')
577 {
582
583 mutt_debug(LL_NOTIFY, "NT_ATTACH_DELETE_ALL\n");
585
586 rc = MUTT_CMD_SUCCESS;
587 goto done;
588 }
589
590 if ((op != '+') && (op != '-'))
591 {
592 op = '+';
593 p--;
594 }
595 if (mutt_istr_startswith("attachment", p))
596 {
597 if (op == '+')
598 head = &mod_data->attach_allow;
599 else
600 head = &mod_data->attach_exclude;
601 }
602 else if (mutt_istr_startswith("inline", p))
603 {
604 if (op == '+')
605 head = &mod_data->inline_allow;
606 else
607 head = &mod_data->inline_exclude;
608 }
609 else
610 {
611 buf_strcpy(err, _("unattachments: invalid disposition"));
612 goto done;
613 }
614
615 rc = parse_unattach_list(cmd, line, head, err);
616
617done:
618 buf_pool_release(&token);
619 return rc;
620}
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:380
@ NT_ATTACH_DELETE_ALL
All Attachment regexes have been deleted.
Definition commands.h:46
void attachmatch_free(struct AttachMatch **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:144
void(* list_free_t)(void **ptr)
Definition list.h:50
@ 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 652 of file commands.c.

654{
656 ASSERT(mod_data);
657
658 return parse_stailq(cmd, line, &mod_data->mime_lookup, pc, pe);
659}
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 668 of file commands.c.

670{
672 ASSERT(mod_data);
673
674 return parse_unstailq(cmd, line, &mod_data->mime_lookup, pc, pe);
675}
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 {
219 if (mutt_str_equal(buf_string(token), "*"))
220 {
221 colors_reset();
222 rc = MUTT_CMD_SUCCESS;
223 goto done;
224 }
225 }
226
227 enum ColorId cid = MT_COLOR_NONE;
228 color_debug(LL_DEBUG5, "uncolor: %s\n", buf_string(token));
229 rc = parse_object(cmd, line, &cid, err);
230 if (rc != MUTT_CMD_SUCCESS)
231 goto done;
232
233 if ((cid == MT_COLOR_STATUS) && !MoreArgs(line))
234 {
235 color_debug(LL_DEBUG5, "simple\n");
236 simple_color_reset(cid); // default colour for the status bar
237 goto done;
238 }
239
240 if (!mutt_color_has_pattern(cid))
241 {
242 color_debug(LL_DEBUG5, "simple\n");
244 goto done;
245 }
246
247 if (!MoreArgs(line))
248 {
249 if (regex_colors_parse_uncolor(cid, NULL))
250 rc = MUTT_CMD_SUCCESS;
251 else
252 rc = MUTT_CMD_ERROR;
253 goto done;
254 }
255
256 do
257 {
259 if (mutt_str_equal("*", buf_string(token)))
260 {
261 if (regex_colors_parse_uncolor(cid, NULL))
262 rc = MUTT_CMD_SUCCESS;
263 else
264 rc = MUTT_CMD_ERROR;
265 goto done;
266 }
267
269
270 } while (MoreArgs(line));
271
272 rc = MUTT_CMD_SUCCESS;
273
274done:
275 buf_pool_release(&token);
276 return rc;
277}
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:414
void simple_color_reset(enum ColorId cid)
Clear the colour of a simple object.
Definition simple.c:154
bool mutt_color_has_pattern(enum ColorId cid)
Check if a color object supports a regex pattern.
Definition color.c:100
void colors_reset(void)
Reset all the simple, quoted and regex colours.
Definition color.c:69
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
+ 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 447 of file commands.c.

449{
450 struct Buffer *err = pe->message;
451
452 if (!MoreArgs(line))
453 {
454 buf_printf(err, _("%s: too few arguments"), cmd->name);
455 return MUTT_CMD_WARNING;
456 }
457
458 struct Buffer *token = buf_pool_get();
460
461 if (!OptGui) // No GUI, so quietly discard the command
462 {
463 while (MoreArgs(line))
464 {
466 }
467 goto done;
468 }
469
470 color_debug(LL_DEBUG5, "parse: %s\n", buf_string(token));
471 rc = parse_uncolor_command(cmd, line, pc, pe);
472 curses_colors_dump(token);
473
474done:
475 buf_pool_release(&token);
476 return rc;
477}
void curses_colors_dump(struct Buffer *buf)
Dump all the Curses colours.
Definition debug.c: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 485 of file commands.c.

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

◆ parse_color()

enum CommandResult parse_color ( const struct Command * cmd,
struct Buffer * line,
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 507 of file commands.c.

509{
510 struct Buffer *err = pe->message;
511
512 struct Buffer *token = buf_pool_get();
514
515 // No GUI, or no colours, so quietly discard the command
516 if (!OptGui || (COLORS == 0))
517 {
518 while (MoreArgs(line))
519 {
521 }
522 goto done;
523 }
524
525 color_debug(LL_DEBUG5, "parse: color\n");
526 rc = parse_color_command(cmd, line, err, parse_color_pair);
527 curses_colors_dump(token);
528
529done:
530 buf_pool_release(&token);
531 return rc;
532}
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:291
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 540 of file commands.c.

542{
543 struct Buffer *err = pe->message;
544
545 struct Buffer *token = buf_pool_get();
547
548 // No GUI, or colours available, so quietly discard the command
549 if (!OptGui || (COLORS != 0))
550 {
551 while (MoreArgs(line))
552 {
554 }
555 goto done;
556 }
557
558 color_debug(LL_DEBUG5, "parse: %s\n", buf_string(token));
559 rc = parse_color_command(cmd, line, err, parse_attr_spec);
560 curses_colors_dump(token);
561
562done:
563 buf_pool_release(&token);
564 return rc;
565}
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
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:84
@ CMD_IFDEF
:ifdef
Definition command.h:83
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:731
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:728
+ 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 {
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:1546
A group of associated Mailboxes.
Definition account.h:36
A mailbox.
Definition mailbox.h:78
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
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:291
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
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:787
+ 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;
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
When the config has been read.
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:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
#define MUTT_PAGER_NO_FLAGS
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:589
+ 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;
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));
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:143
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
#define TOKEN_EQUAL
Treat '=' as a special.
Definition extract.h:46
#define TOKEN_QUESTION
Treat '?' as a special.
Definition extract.h:55
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 227 of file source.c.

229{
230 struct Buffer *err = pe->message;
231
232 if (!MoreArgs(line))
233 {
234 buf_printf(err, _("%s: too few arguments"), cmd->name);
235 return MUTT_CMD_WARNING;
236 }
237
238 struct Buffer *token = buf_pool_get();
239 struct Buffer *path = buf_pool_get();
241
242 do
243 {
244 if (parse_extract_token(token, line, TOKEN_BACKTICK_VARS) != 0)
245 {
246 buf_printf(err, _("source: error at %s"), line->dptr);
247 goto done;
248 }
249 buf_copy(path, token);
250 expand_path(path, false);
251
252 // Cheat: Remove the `const` so we can recurse
253 if (source_rc(buf_string(path), (struct ParseContext *) pc, pe) < 0)
254 {
255 buf_printf(err, _("source: file %s could not be sourced"), buf_string(path));
256 goto done;
257 }
258
259 } while (MoreArgs(line));
260
261 rc = MUTT_CMD_SUCCESS;
262
263done:
264 buf_pool_release(&path);
265 buf_pool_release(&token);
266 return rc;
267}
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition buffer.c:601
#define TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition extract.h:53
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 {
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:316
+ 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 {
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:341
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:92
@ CMD_AUTO_VIEW
:auto-view
Definition command.h:66
@ CMD_ALTERNATIVE_ORDER
:alternative-order
Definition command.h:63
@ CMD_HEADER_ORDER
:header-order
Definition command.h:80
@ 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:125
@ CMD_UNAUTO_VIEW
:unauto-view
Definition command.h:127
@ CMD_UNHEADER_ORDER
:unheader-order
Definition command.h:131
@ CMD_UNMAILTO_ALLOW
:unmailto-allow
Definition command.h:137
+ 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:571
#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:337
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:364
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
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 {
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 {
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, *last = NULL;
89 char *pattern = NULL, *patchar = NULL;
90 struct Buffer *token = buf_pool_get();
92
94 if (!MoreArgs(line))
95 {
96 buf_printf(err, _("%s: too few arguments"), cmd->name);
97 goto done;
98 }
99 pattern = buf_strdup(token);
101 if (MoreArgs(line))
102 {
103 buf_printf(err, _("%s: too many arguments"), cmd->name);
104 goto done;
105 }
106
107 /* look for an existing entry and update the value, else add it to the end
108 * of the list */
109 for (ptr = mod_data->score_list, last = NULL; ptr; last = ptr, ptr = ptr->next)
110 if (mutt_str_equal(pattern, ptr->str))
111 break;
112
113 if (ptr)
114 {
115 /* 'token' arg was cleared and 'pattern' holds the only reference;
116 * as here 'ptr' != NULL -> update the value only in which case
117 * ptr->str already has the string, so pattern should be freed. */
118 FREE(&pattern);
119 }
120 else
121 {
122 struct MailboxView *mv_cur = get_current_mailbox_view();
123 struct PatternList *pat = mutt_pattern_comp(mv_cur, pattern, MUTT_PC_NO_FLAGS, err);
124 if (!pat)
125 {
126 goto done;
127 }
128 ptr = MUTT_MEM_CALLOC(1, struct Score);
129 if (last)
130 last->next = ptr;
131 else
132 mod_data->score_list = ptr;
133 ptr->pat = pat;
134 ptr->str = pattern;
135 pattern = NULL;
136 }
137
138 patchar = token->data;
139 if (*patchar == '=')
140 {
141 ptr->exact = true;
142 patchar++;
143 }
144
145 if (!mutt_str_atoi_full(patchar, &ptr->val))
146 {
147 buf_strcpy(err, _("Error: score: invalid number"));
148 goto done;
149 }
150 OptNeedRescore = true;
151
152 rc = MUTT_CMD_SUCCESS;
153
154done:
155 buf_pool_release(&token);
156 FREE(&pattern);
157 return rc;
158}
struct PatternList * mutt_pattern_comp(struct MailboxView *mv, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition compile.c:958
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:693
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:52
#define MUTT_PC_NO_FLAGS
No flags are set.
Definition lib.h:69
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 166 of file score.c.

168{
169 struct Buffer *err = pe->message;
171
172 if (!MoreArgs(line))
173 {
174 buf_printf(err, _("%s: too few arguments"), cmd->name);
175 return MUTT_CMD_WARNING;
176 }
177
178 struct Score *tmp = NULL, *last = NULL;
179 struct Buffer *token = buf_pool_get();
180
181 while (MoreArgs(line))
182 {
184 if (mutt_str_equal("*", buf_string(token)))
185 {
186 score_list_free(&mod_data->score_list);
187 }
188 else
189 {
190 for (tmp = mod_data->score_list; tmp; last = tmp, tmp = tmp->next)
191 {
192 if (mutt_str_equal(buf_string(token), tmp->str))
193 {
194 if (last)
195 last->next = tmp->next;
196 else
197 mod_data->score_list = tmp->next;
198 mutt_pattern_free(&tmp->pat);
199 FREE(&tmp);
200 /* there should only be one score per pattern, so we can stop here */
201 break;
202 }
203 }
204 }
205 }
206
207 OptNeedRescore = true;
208 buf_pool_release(&token);
209 return MUTT_CMD_SUCCESS;
210}
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition compile.c:830
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 "*"
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:566
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition regex.c:179
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition regex.c:450
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
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();
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:271
+ 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";
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:1574
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:70
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 56 of file parse.c.

58{
59 struct Buffer *err = pe->message;
60
61 if (!MoreArgs(line))
62 {
63 buf_printf(err, _("%s: too few arguments"), cmd->name);
64 return MUTT_CMD_WARNING;
65 }
66
67 struct Buffer *alias = buf_pool_get();
68 struct Buffer *charset = buf_pool_get();
70
71 if (parse_extract_token(alias, line, TOKEN_NO_FLAGS) < 0)
72 goto done;
73 if (parse_extract_token(charset, line, TOKEN_NO_FLAGS) < 0)
74 goto done;
75
76 const enum LookupType type = (cmd->id == CMD_ICONV_HOOK) ? MUTT_LOOKUP_ICONV :
78
79 if (buf_is_empty(alias) || buf_is_empty(charset))
80 {
81 buf_printf(err, _("%s: too few arguments"), cmd->name);
83 }
84 else if (MoreArgs(line))
85 {
86 buf_printf(err, _("%s: too many arguments"), cmd->name);
87 buf_reset(line); // clean up buffer to avoid a mess with further rcfile processing
89 }
90 else if (mutt_ch_lookup_add(type, buf_string(alias), buf_string(charset), err))
91 {
93 }
94
95done:
96 buf_pool_release(&alias);
97 buf_pool_release(&charset);
98
99 return rc;
100}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
@ CMD_ICONV_HOOK
:iconv-hook
Definition command.h:82
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:495
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 110 of file parse.c.

112{
113 struct Buffer *err = pe->message;
114
116 struct Hook *hook = NULL;
118
119 struct Buffer *command = buf_pool_get();
120
121 // TOKEN_SPACE allows the command to contain whitespace, without quoting
122 parse_extract_token(command, line, TOKEN_SPACE);
123
124 if (buf_is_empty(command))
125 {
126 buf_printf(err, _("%s: too few arguments"), cmd->name);
127 rc = MUTT_CMD_WARNING;
128 goto cleanup;
129 }
130
131 if (MoreArgs(line))
132 {
133 buf_printf(err, _("%s: too many arguments"), cmd->name);
134 rc = MUTT_CMD_WARNING;
135 goto cleanup;
136 }
137
138 /* check to make sure that a matching Hook doesn't already exist */
139 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
140 {
141 /* Ignore duplicate global Hooks */
142 if ((hook->id == cmd->id) && mutt_str_equal(hook->command, buf_string(command)))
143 {
144 rc = MUTT_CMD_SUCCESS;
145 goto cleanup;
146 }
147 }
148
149 hook = hook_new();
150 hook->id = cmd->id;
151 hook->command = buf_strdup(command);
153 hook->pattern = NULL;
154 hook->regex.pattern = NULL;
155 hook->regex.regex = NULL;
156 hook->regex.pat_not = false;
157 hook->expando = NULL;
158
159 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
160 rc = MUTT_CMD_SUCCESS;
161
162cleanup:
163 buf_pool_release(&command);
164 return rc;
165}
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:314
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 176 of file parse.c.

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

350{
351 struct Buffer *err = pe->message;
352
354 bool pat_not = false;
355
356 struct Buffer *pattern = buf_pool_get();
357 struct Buffer *mailbox = buf_pool_get();
358
359 if (*line->dptr == '!')
360 {
361 line->dptr++;
362 SKIPWS(line->dptr);
363 pat_not = true;
364 }
365
366 parse_extract_token(pattern, line, TOKEN_NO_FLAGS);
367
368 if (!MoreArgs(line))
369 {
370 buf_printf(err, _("%s: too few arguments"), cmd->name);
371 rc = MUTT_CMD_WARNING;
372 goto cleanup;
373 }
374
375 parse_extract_token(mailbox, line, TOKEN_NO_FLAGS);
376
377 if (buf_is_empty(mailbox))
378 {
379 buf_printf(err, _("%s: too few arguments"), cmd->name);
380 rc = MUTT_CMD_WARNING;
381 goto cleanup;
382 }
383
384 if (MoreArgs(line))
385 {
386 buf_printf(err, _("%s: too many arguments"), cmd->name);
387 rc = MUTT_CMD_WARNING;
388 goto cleanup;
389 }
390
391 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
392 if (c_default_hook)
393 {
394 mutt_check_simple(pattern, c_default_hook);
395 }
396
397 expand_path(mailbox, false);
398
399 if ((cmd->id == CMD_FCC_HOOK) || (cmd->id == CMD_FCC_SAVE_HOOK))
400 {
401 rc = add_mailbox_hook(CMD_FCC_HOOK, mailbox, pattern, pat_not, err);
402 if (rc != MUTT_CMD_SUCCESS)
403 goto cleanup;
404 }
405
406 if ((cmd->id == CMD_SAVE_HOOK) || (cmd->id == CMD_FCC_SAVE_HOOK))
407 {
408 rc = add_mailbox_hook(CMD_SAVE_HOOK, mailbox, pattern, pat_not, err);
409 if (rc != MUTT_CMD_SUCCESS)
410 goto cleanup;
411 }
412
413 rc = MUTT_CMD_SUCCESS;
414
415cleanup:
416 buf_pool_release(&pattern);
417 buf_pool_release(&mailbox);
418 return rc;
419}
@ CMD_FCC_SAVE_HOOK
:fcc-save-hook
Definition command.h:76
@ CMD_FCC_HOOK
:fcc-hook
Definition command.h:75
@ CMD_SAVE_HOOK
:save-hook
Definition command.h:104
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:287
+ 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 427 of file parse.c.

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

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

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

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

915{
916 struct Buffer *err = pe->message;
917
919 struct Hook *hook = NULL;
921 bool pat_not = false;
922 regex_t *rx = NULL;
923
924 struct Buffer *regex = buf_pool_get();
925 struct Buffer *command = buf_pool_get();
926
927 if (*line->dptr == '!')
928 {
929 line->dptr++;
930 SKIPWS(line->dptr);
931 pat_not = true;
932 }
933
935
936 if (!MoreArgs(line))
937 {
938 buf_printf(err, _("%s: too few arguments"), cmd->name);
939 rc = MUTT_CMD_WARNING;
940 goto cleanup;
941 }
942
943 // TOKEN_SPACE allows the command to contain whitespace, without quoting
944 parse_extract_token(command, line, TOKEN_SPACE);
945
946 if (buf_is_empty(command))
947 {
948 buf_printf(err, _("%s: too few arguments"), cmd->name);
949 rc = MUTT_CMD_WARNING;
950 goto cleanup;
951 }
952
953 if (MoreArgs(line))
954 {
955 buf_printf(err, _("%s: too many arguments"), cmd->name);
956 rc = MUTT_CMD_WARNING;
957 goto cleanup;
958 }
959
960 if (mutt_comp_valid_command(buf_string(command)) == 0)
961 {
962 buf_strcpy(err, _("badly formatted command string"));
963 goto cleanup;
964 }
965
966 /* check to make sure that a matching hook doesn't already exist */
967 TAILQ_FOREACH(hook, &mod_data->hooks, entries)
968 {
969 if ((hook->id == cmd->id) && (hook->regex.pat_not == pat_not) &&
970 mutt_str_equal(buf_string(regex), hook->regex.pattern))
971 {
972 // Update an existing hook
973 FREE(&hook->command);
974 hook->command = buf_strdup(command);
975 FREE(&hook->source_file);
977
978 rc = MUTT_CMD_SUCCESS;
979 goto cleanup;
980 }
981 }
982
983 /* Hooks not allowing full patterns: Check syntax of regex */
984 rx = MUTT_MEM_CALLOC(1, regex_t);
985 int rc2 = REG_COMP(rx, buf_string(regex), 0);
986 if (rc2 != 0)
987 {
988 regerror(rc2, rx, err->data, err->dsize);
989 buf_fix_dptr(err);
990 FREE(&rx);
991 goto cleanup;
992 }
993
994 hook = hook_new();
995 hook->id = cmd->id;
996 hook->command = buf_strdup(command);
998 hook->pattern = NULL;
999 hook->regex.pattern = buf_strdup(regex);
1000 hook->regex.regex = rx;
1001 hook->regex.pat_not = pat_not;
1002 hook->expando = NULL;
1003
1004 TAILQ_INSERT_TAIL(&mod_data->hooks, hook, entries);
1005 rc = MUTT_CMD_SUCCESS;
1006
1007cleanup:
1008 buf_pool_release(&regex);
1009 buf_pool_release(&command);
1010 return rc;
1011}
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition compress.c:387
+ 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 1068 of file parse.c.

1070{
1071 struct Buffer *err = pe->message;
1072
1073 if (!MoreArgs(line))
1074 {
1075 buf_printf(err, _("%s: too few arguments"), cmd->name);
1076 return MUTT_CMD_WARNING;
1077 }
1078
1080 enum CommandResult rc = MUTT_CMD_ERROR;
1081 bool pat_not = false;
1082
1083 struct Buffer *name = buf_pool_get();
1084 struct Buffer *pattern = buf_pool_get();
1085 struct Buffer *fmt = buf_pool_get();
1086 struct Expando *exp = NULL;
1087
1088 if (!mod_data->idx_fmt_hooks)
1089 {
1092 }
1093
1095 struct HookList *hl = mutt_hash_find(mod_data->idx_fmt_hooks, buf_string(name));
1096
1097 if (*line->dptr == '!')
1098 {
1099 line->dptr++;
1100 SKIPWS(line->dptr);
1101 pat_not = true;
1102 }
1103 parse_extract_token(pattern, line, TOKEN_NO_FLAGS);
1104
1105 if (!MoreArgs(line))
1106 {
1107 buf_printf(err, _("%s: too few arguments"), cmd->name);
1108 goto out;
1109 }
1111
1112 exp = expando_parse(buf_string(fmt), IndexFormatDef, err);
1113 if (!exp)
1114 goto out;
1115
1116 if (MoreArgs(line))
1117 {
1118 buf_printf(err, _("%s: too many arguments"), cmd->name);
1119 goto out;
1120 }
1121
1122 const char *const c_default_hook = cs_subset_string(NeoMutt->sub, "default_hook");
1123 if (c_default_hook)
1124 mutt_check_simple(pattern, c_default_hook);
1125
1126 /* check to make sure that a matching hook doesn't already exist */
1127 struct Hook *hook = NULL;
1128 if (hl)
1129 {
1130 TAILQ_FOREACH(hook, hl, entries)
1131 {
1132 // Update an existing hook
1133 if ((hook->regex.pat_not == pat_not) &&
1135 {
1136 expando_free(&hook->expando);
1137 hook->expando = exp;
1138 exp = NULL;
1139 rc = MUTT_CMD_SUCCESS;
1140 goto out;
1141 }
1142 }
1143 }
1144
1145 /* MUTT_PC_PATTERN_DYNAMIC sets so that date ranges are regenerated during
1146 * matching. This of course is slower, but index-format-hook is commonly
1147 * used for date ranges, and they need to be evaluated relative to "now", not
1148 * the hook compilation time. */
1149 struct MailboxView *mv_cur = get_current_mailbox_view();
1150 struct PatternList *pat = mutt_pattern_comp(mv_cur, buf_string(pattern),
1152 err);
1153 if (!pat)
1154 goto out;
1155
1156 hook = hook_new();
1157 hook->id = CMD_INDEX_FORMAT_HOOK;
1158 hook->command = NULL;
1160 hook->pattern = pat;
1161 hook->regex.pattern = buf_strdup(pattern);
1162 hook->regex.regex = NULL;
1163 hook->regex.pat_not = pat_not;
1164 hook->expando = exp;
1165 exp = NULL;
1166
1167 if (!hl)
1168 {
1169 hl = MUTT_MEM_CALLOC(1, struct HookList);
1170 TAILQ_INIT(hl);
1171 mutt_hash_insert(mod_data->idx_fmt_hooks, buf_string(name), hl);
1172 }
1173
1174 TAILQ_INSERT_TAIL(hl, hook, entries);
1175 rc = MUTT_CMD_SUCCESS;
1176
1177out:
1178 buf_pool_release(&name);
1179 buf_pool_release(&pattern);
1180 buf_pool_release(&fmt);
1181 expando_free(&exp);
1182
1183 return rc;
1184}
@ CMD_INDEX_FORMAT_HOOK
:index-format-hook
Definition command.h:86
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:1038
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition hash.c:261
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:303
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition hash.h:113
#define MUTT_PC_PATTERN_DYNAMIC
Enable runtime date range evaluation.
Definition lib.h:71
#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 1192 of file parse.c.

1194{
1195 struct Buffer *err = pe->message;
1196
1197 if (!MoreArgs(line))
1198 {
1199 buf_printf(err, _("%s: too few arguments"), cmd->name);
1200 return MUTT_CMD_WARNING;
1201 }
1202
1204 struct Buffer *token = buf_pool_get();
1206
1207 while (MoreArgs(line))
1208 {
1209 parse_extract_token(token, line, TOKEN_NO_FLAGS);
1210 if (mutt_str_equal("*", buf_string(token)))
1211 {
1212 if (mod_data->current_hook_id != CMD_NONE)
1213 {
1214 buf_addstr(err, _("unhook: Can't do unhook * from within a hook"));
1215 goto done;
1216 }
1220 }
1221 else
1222 {
1223 const struct Command *hook = command_find_by_name(&NeoMutt->commands,
1224 buf_string(token));
1225 if (!hook)
1226 {
1227 buf_printf(err, _("unhook: unknown hook type: %s"), buf_string(token));
1228 rc = MUTT_CMD_ERROR;
1229 goto done;
1230 }
1231
1232 if ((hook->id == CMD_CHARSET_HOOK) || (hook->id == CMD_ICONV_HOOK))
1233 {
1235 rc = MUTT_CMD_SUCCESS;
1236 goto done;
1237 }
1238 if (mod_data->current_hook_id == hook->id)
1239 {
1240 buf_printf(err, _("unhook: Can't delete a %s from within a %s"),
1241 buf_string(token), buf_string(token));
1242 rc = MUTT_CMD_WARNING;
1243 goto done;
1244 }
1245 if (hook->id == CMD_INDEX_FORMAT_HOOK)
1247 else
1248 mutt_delete_hooks(hook->id);
1249 }
1250 }
1251
1252 rc = MUTT_CMD_SUCCESS;
1253
1254done:
1255 buf_pool_release(&token);
1256 return rc;
1257}
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
@ CMD_CHARSET_HOOK
:charset-hook
Definition command.h:69
@ CMD_NONE
No Command.
Definition command.h:59
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(enum CommandId id)
Delete matching hooks.
Definition parse.c:1019
void delete_idxfmt_hooks(void)
Delete all the index-format-hooks.
Definition parse.c:1056
void mutt_ch_lookup_remove(void)
Remove all the character set lookups.
Definition charset.c:527
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
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
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:72
@ NT_SUBJECTRX
Subject Regex has changed, NotifySubjectRx.
Definition notify_type.h:55
Index private Module data.
Definition module_data.h:32
struct Notify * subject_rx_notify
Notifications: NotifySubjectRx.
Definition module_data.h:36
struct ReplaceList subject_rx_list
List of subject-regex rules for modifying the Subject:
Definition module_data.h:35
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 63 of file commands.c.

65{
66 struct Buffer *err = pe->message;
67
68 struct Buffer *token = buf_pool_get();
69 const struct MenuDefinition *md = NULL;
71
72 if (MoreArgs(line))
73 {
75
76 if (MoreArgs(line))
77 {
78 /* More arguments potentially means the user is using the
79 * ::command_t :bind command thus we delegate the task. */
80 goto done;
81 }
82
83 if (!mutt_str_equal(buf_string(token), "all"))
84 {
85 md = menu_find_by_name(buf_string(token));
86 if (!md)
87 {
88 // L10N: '%s' is the (misspelled) name of the menu, e.g. 'index' or 'pager'
89 buf_printf(err, _("%s: no such menu"), buf_string(token));
90 goto done;
91 }
92 }
93 }
94
95 dump_bind_macro(cmd, md, token, err);
97
98done:
99 buf_pool_release(&token);
100 return rc;
101}
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:267
Functions for a Dialog or Window.
Definition menu.h:80
+ 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 204 of file commands.c.

206{
207 struct Buffer *err = pe->message;
208
209 if (!MoreArgs(line))
210 {
211 buf_printf(err, _("%s: too few arguments"), cmd->name);
212 return MUTT_CMD_WARNING;
213 }
214
215 struct Buffer *token = buf_pool_get();
217
219 if (MoreArgs(line))
220 {
221 buf_printf(err, _("%s: too many arguments"), cmd->name);
222 goto done;
223 }
224
226 rc = MUTT_CMD_SUCCESS;
227
228done:
229 buf_pool_release(&token);
230 return rc;
231}
#define TOKEN_CONDENSE
^(char) to control chars (macros)
Definition extract.h:47
void generic_tokenize_push_string(char *s)
Parse and queue a 'push' command.
Definition get.c:311
+ 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 241 of file commands.c.

243{
244 struct Buffer *err = pe->message;
245
246 if (StartupComplete)
247 {
248 // Save and restore the offset in `line` because parse_dump() might change it
249 char *dptr = line->dptr;
250 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
251 {
252 return MUTT_CMD_SUCCESS;
253 }
254 if (!buf_is_empty(err))
255 {
256 return MUTT_CMD_ERROR;
257 }
258 line->dptr = dptr;
259 }
260
261 struct Buffer *token = buf_pool_get();
262 struct Buffer *keystr = NULL;
263
264 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
266
267 char *key = parse_keymap(cmd, &mda, line, err);
268 if (!key)
269 goto done;
270
271 /* function to execute */
273 if (MoreArgs(line))
274 {
275 buf_printf(err, _("%s: too many arguments"), cmd->name);
276 goto done;
277 }
278
279 rc = MUTT_CMD_SUCCESS;
280
281 if (mutt_istr_equal("noop", buf_string(token)))
282 {
283 keystr = buf_pool_get();
284 struct MenuDefinition **mdp = NULL;
285 ARRAY_FOREACH(mdp, &mda)
286 {
287 struct MenuDefinition *md = *mdp;
288
289 km_bind(md, key, OP_NULL, NULL, NULL, NULL); /* the 'unbind' command */
290
291 buf_reset(keystr);
292 keymap_expand_string(key, keystr);
293 mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", md->name, buf_string(keystr));
294
295 int op = km_get_op_menu(md->id, buf_string(token));
296
297 struct EventBinding ev_b = { md, key, op };
299 }
300 }
301 else
302 {
303 keystr = buf_pool_get();
304 struct MenuDefinition **mdp = NULL;
305 ARRAY_FOREACH(mdp, &mda)
306 {
307 struct MenuDefinition *md = *mdp;
308
309 int op = OP_NULL;
310 struct SubMenu **ptr = NULL;
311 ARRAY_FOREACH(ptr, &md->submenus)
312 {
313 struct SubMenu *sm = *ptr;
314 const struct MenuFuncOp *mfo = NULL;
315 for (int j = 0; sm->functions[j].name; j++)
316 {
317 mfo = &sm->functions[j];
318 if (mutt_str_equal(buf_string(token), mfo->name))
319 {
320 op = mfo->op;
321 break;
322 }
323 }
324 }
325
326 rc = km_bind(md, key, op, NULL, NULL, err);
327 if (rc == MUTT_CMD_SUCCESS)
328 {
329 buf_reset(keystr);
330 keymap_expand_string(key, keystr);
331 mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", md->name, buf_string(keystr));
332
333 struct EventBinding ev_b = { md, key, op };
335 }
336 }
337 }
338
339done:
340 FREE(&key);
341 ARRAY_FREE(&mda);
342 buf_pool_release(&keystr);
343 buf_pool_release(&token);
344 return rc;
345}
#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:63
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:115
enum CommandResult km_bind(struct MenuDefinition *md, const char *key_str, int op, char *macro, char *desc, struct Buffer *err)
Set up a key binding.
Definition menu.c:51
void keymap_expand_string(const char *str, struct Buffer *buf)
Get a human-readable key string.
Definition keymap.c:257
int km_get_op_menu(int mtype, const char *func)
Get the OpCode for a Function from a Menu.
Definition menu.c:214
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition notify.h:46
@ NT_BINDING_ADD
Key binding has been added.
Definition notify.h:45
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition notify_type.h:40
A key binding Event.
Definition notify.h:30
const char * key
Key string being bound (for new bind/macro)
Definition notify.h:32
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition notify.h:33
const char * name
Menu name, e.g. "alias".
Definition menu.h:82
int id
Menu ID, e.g. MENU_ALIAS.
Definition menu.h:81
struct SubMenuPArray submenus
Parts making up the Menu.
Definition menu.h:83
Mapping between a function and an operation.
Definition menu.h:38
const char * name
Name of the function.
Definition menu.h:39
int op
Operation, e.g. OP_DELETE.
Definition menu.h:40
Collection of related functions.
Definition menu.h:68
const struct MenuFuncOp * functions
All available functions.
Definition menu.h:70
+ 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 645 of file commands.c.

647{
648 struct Buffer *err = pe->message;
649
650 struct ParseUnbind args = { 0 };
652
653 if (!parse_unbind_args(cmd, line, err, &args))
654 goto done;
655
656 rc = MUTT_CMD_ERROR;
657 if (parse_unbind_exec(cmd, &args, err))
658 rc = MUTT_CMD_SUCCESS;
659
660done:
661 ARRAY_FREE(&args.mda);
662 FREE(&args.key);
663 return rc;
664}
bool parse_unbind_exec(const struct Command *cmd, struct ParseUnbind *args, struct Buffer *err)
Execute the 'unbind' or 'unmacro' command.
Definition commands.c:537
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:449
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:57
+ 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 672 of file commands.c.

674{
675 struct Buffer *err = pe->message;
676
677 if (StartupComplete)
678 {
679 // Save and restore the offset in `line` because parse_dump() might change it
680 char *dptr = line->dptr;
681 if (parse_dump(cmd, line, pc, pe) == MUTT_CMD_SUCCESS)
682 {
683 return MUTT_CMD_SUCCESS;
684 }
685 if (!buf_is_empty(err))
686 {
687 return MUTT_CMD_ERROR;
688 }
689 line->dptr = dptr;
690 }
691
692 struct MenuDefinitionArray mda = ARRAY_HEAD_INITIALIZER;
693 struct Buffer *token = buf_pool_get();
694 struct Buffer *keystr = NULL;
696
697 char *key = parse_keymap(cmd, &mda, line, err);
698 if (!key)
699 goto done;
700
702 /* make sure the macro sequence is not an empty string */
703 if (buf_at(token, 0) == '\0')
704 {
705 buf_strcpy(err, _("macro: empty key sequence"));
706 }
707 else
708 {
709 if (MoreArgs(line))
710 {
711 char *seq = mutt_str_dup(buf_string(token));
713
714 if (MoreArgs(line))
715 {
716 buf_printf(err, _("%s: too many arguments"), cmd->name);
717 }
718 else
719 {
720 keystr = buf_pool_get();
721 struct MenuDefinition **mdp = NULL;
722 ARRAY_FOREACH(mdp, &mda)
723 {
724 struct MenuDefinition *md = *mdp;
725
726 rc = km_bind(md, key, OP_MACRO, seq, token->data, NULL);
727 if (rc == MUTT_CMD_SUCCESS)
728 {
729 buf_reset(keystr);
730 keymap_expand_string(key, keystr);
731 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
732
733 struct EventBinding ev_b = { md, key, OP_MACRO };
735 continue;
736 }
737 }
738 }
739
740 FREE(&seq);
741 }
742 else
743 {
744 keystr = buf_pool_get();
745 struct MenuDefinition **mdp = NULL;
746 ARRAY_FOREACH(mdp, &mda)
747 {
748 struct MenuDefinition *md = *mdp;
749
750 rc = km_bind(md, key, OP_MACRO, token->data, NULL, NULL);
751 if (rc == MUTT_CMD_SUCCESS)
752 {
753 buf_reset(keystr);
754 keymap_expand_string(key, keystr);
755 mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", md->name, buf_string(keystr));
756
757 struct EventBinding ev_b = { md, key, OP_MACRO };
759 continue;
760 }
761 }
762 }
763 }
764
765done:
766 FREE(&key);
767 ARRAY_FREE(&mda);
768 buf_pool_release(&keystr);
769 buf_pool_release(&token);
770 return rc;
771}
@ NT_MACRO_ADD
Key macro has been added.
Definition notify.h:47
+ 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 779 of file commands.c.

781{
782 struct Buffer *err = pe->message;
783
784 if (!MoreArgs(line))
785 {
786 buf_printf(err, _("%s: too few arguments"), cmd->name);
787 return MUTT_CMD_WARNING;
788 }
789
790 struct Buffer *token = buf_pool_get();
792
793 int ops[128];
794 int nops = 0;
795 char *function = NULL;
796
797 do
798 {
800 function = token->data;
801
802 const enum MenuType mtype = menu_get_current_type();
803 ops[nops] = km_get_op_menu(mtype, function);
804 if (ops[nops] == OP_NULL)
805 {
807 mutt_error(_("%s: no such function"), function);
808 goto done;
809 }
810 nops++;
811 } while (MoreArgs(line) && nops < countof(ops));
812
813 while (nops)
814 mutt_push_macro_event(0, ops[--nops]);
815
816 rc = MUTT_CMD_SUCCESS;
817
818done:
819 buf_pool_release(&token);
820 return rc;
821}
void mutt_flushinp(void)
MacroEvents moved to KeyModuleData UngetKeyEvents moved to KeyModuleData.
Definition get.c:60
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition get.c:144
#define countof(x)
Definition memory.h:49
enum MenuType menu_get_current_type(void)
Get the type of the current Window.
Definition menu.c:92
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:74
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_NO_FLAGS) != 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();
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:103
@ CMD_TOGGLE
:toggle
Definition command.h:122
@ CMD_UNSET
:unset
Definition command.h:142
@ CMD_SET
:set
Definition command.h:108
#define TOKEN_PLUS
Treat '+' as a special.
Definition extract.h:56
#define TOKEN_MINUS
Treat '-' as a special.
Definition extract.h:57
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 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:90
@ 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, *tmp = NULL;
120 size_t l;
121
123 ASSERT(mod_data);
124
125 do
126 {
128 if (mutt_str_equal("*", buf_string(token)))
129 {
130 /* Clear all headers, send a notification for each header */
131 STAILQ_FOREACH(np, &mod_data->user_header, entries)
132 {
133 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
134 struct EventHeader ev_h = { np->data };
136 }
137 mutt_list_free(&mod_data->user_header);
138 continue;
139 }
140
141 l = mutt_str_len(buf_string(token));
142 if (buf_at(token, l - 1) == ':')
143 l--;
144
145 STAILQ_FOREACH_SAFE(np, &mod_data->user_header, entries, tmp)
146 {
147 if (mutt_istrn_equal(buf_string(token), np->data, l) && (np->data[l] == ':'))
148 {
149 mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
150 struct EventHeader ev_h = { np->data };
152
153 header_free(&mod_data->user_header, np);
154 }
155 }
156 } while (MoreArgs(line));
157 buf_pool_release(&token);
158 return MUTT_CMD_SUCCESS;
159}
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:91
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: