NeoMutt  2025-12-11-769-g906513
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
commands.c
Go to the documentation of this file.
1
23
29
30#include "config.h"
31#include <stdio.h>
32#include "mutt/lib.h"
33#include "address/lib.h"
34#include "config/lib.h"
35#include "email/lib.h"
36#include "core/lib.h"
37#include "lib.h"
38#include "parse/lib.h"
39#include "alias.h"
40#include "alternates.h"
41#include "group.h"
42#include "module_data.h"
43#include "reverse.h"
44
49void mutt_auto_subscribe(const char *mailto)
50{
51 if (!mailto)
52 return;
53
55 ASSERT(mod_data);
56
57 if (!mod_data->auto_subscribe_cache)
59
60 if (mutt_hash_find(mod_data->auto_subscribe_cache, mailto))
61 return;
62
64
65 struct Envelope *lpenv = mutt_env_new(); /* parsed envelope from the List-Post mailto: URL */
66
67 if (mutt_parse_mailto(lpenv, NULL, mailto) && !TAILQ_EMPTY(&lpenv->to))
68 {
69 const char *mailbox = buf_string(TAILQ_FIRST(&lpenv->to)->mailbox);
70 if (mailbox && !mutt_regexlist_match(&mod_data->subscribed, mailbox) &&
71 !mutt_regexlist_match(&mod_data->unmail, mailbox) &&
72 !mutt_regexlist_match(&mod_data->unsubscribed, mailbox))
73 {
74 /* mutt_regexlist_add() detects duplicates, so it is safe to
75 * try to add here without any checks. */
76 mutt_regexlist_add(&mod_data->mail, mailbox, REG_ICASE, NULL);
77 mutt_regexlist_add(&mod_data->subscribed, mailbox, REG_ICASE, NULL);
78 }
79 }
80
81 mutt_env_free(&lpenv);
82}
83
89void alias_tags_to_buffer(struct TagList *tl, struct Buffer *buf)
90{
91 struct Tag *tag = NULL;
92 STAILQ_FOREACH(tag, tl, entries)
93 {
94 buf_addstr(buf, tag->name);
95 if (STAILQ_NEXT(tag, entries))
96 buf_addch(buf, ',');
97 }
98}
99
105void parse_alias_tags(const char *tags, struct TagList *tl)
106{
107 if (!tags || !tl)
108 return;
109
110 struct Slist *sl = slist_parse(tags, D_SLIST_SEP_COMMA);
111 if (slist_is_empty(sl))
112 {
113 slist_free(&sl);
114 return;
115 }
116
117 struct ListNode *np = NULL;
118 STAILQ_FOREACH(np, &sl->head, entries)
119 {
120 struct Tag *tag = tag_new();
121 tag->name = np->data; // Transfer string
122 np->data = NULL;
123 STAILQ_INSERT_TAIL(tl, tag, entries);
124 }
125 slist_free(&sl);
126}
127
135void parse_alias_comments(struct Alias *alias, const char *com)
136{
137 if (!com || (com[0] == '\0'))
138 return;
139
140 const regmatch_t *match = mutt_prex_capture(PREX_ALIAS_TAGS, com);
141 if (match)
142 {
143 const regmatch_t *pre = &match[PREX_ALIAS_TAGS_MATCH_PRE];
144 const regmatch_t *tags = &match[PREX_ALIAS_TAGS_MATCH_TAGS];
145 const regmatch_t *post = &match[PREX_ALIAS_TAGS_MATCH_POST];
146
147 struct Buffer *tmp = buf_pool_get();
148
149 // Extract the tags
150 buf_addstr_n(tmp, com + mutt_regmatch_start(tags),
152 parse_alias_tags(buf_string(tmp), &alias->tags);
153 buf_reset(tmp);
154
155 // Collect all the other text as "comments"
156 buf_addstr_n(tmp, com + mutt_regmatch_start(pre),
158 buf_addstr_n(tmp, com + mutt_regmatch_start(post),
160 alias->comment = buf_strdup(tmp);
161
162 buf_pool_release(&tmp);
163 }
164 else
165 {
166 alias->comment = mutt_str_dup(com);
167 }
168}
169
178enum CommandResult parse_alias(const struct Command *cmd, struct Buffer *line,
179 const struct ParseContext *pc, struct ParseError *pe)
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}
301
308enum CommandResult parse_unalias(const struct Command *cmd, struct Buffer *line,
309 const struct ParseContext *pc, struct ParseError *pe)
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}
357
361const struct Command AliasCommands[] = {
362 // clang-format off
363 { "alias", CMD_ALIAS, parse_alias,
364 N_("Define an alias (name to email address)"),
365 N_("alias [ -group <name> ... ] <key> <address> [,...] [ # <comments> ]"),
366 "configuration.html#alias" },
367 { "alternates", CMD_ALTERNATES, parse_alternates,
368 N_("Define a list of alternate email addresses for the user"),
369 N_("alternates [ -group <name> ... ] <regex> [ <regex> ... ]"),
370 "configuration.html#alternates" },
371 { "group", CMD_GROUP, parse_group,
372 N_("Add addresses to an address group"),
373 N_("group [ -group <name> ... ] { -rx <regex> ... | -addr <address> ... }"),
374 "configuration.html#addrgroup" },
375 { "lists", CMD_LISTS, parse_lists,
376 N_("Add address to the list of mailing lists"),
377 N_("lists [ -group <name> ... ] <regex> [ ... ]"),
378 "configuration.html#lists" },
379 { "subscribe", CMD_SUBSCRIBE, parse_subscribe,
380 N_("Add address to the list of subscribed mailing lists"),
381 N_("subscribe [ -group <name> ... ] <regex> [ ... ]"),
382 "configuration.html#lists" },
383 { "unalias", CMD_UNALIAS, parse_unalias,
384 N_("Remove an alias definition"),
385 N_("unalias { * | <key> ... }"),
386 "configuration.html#alias" },
387 { "unalternates", CMD_UNALTERNATES, parse_unalternates,
388 N_("Remove addresses from `alternates` list"),
389 N_("unalternates { * | <regex> ... }"),
390 "configuration.html#alternates" },
391 { "ungroup", CMD_UNGROUP, parse_group,
392 N_("Remove addresses from an address `group`"),
393 N_("ungroup [ -group <name> ... ] { * | -rx <regex> ... | -addr <address> ... }"),
394 "configuration.html#addrgroup" },
395 { "unlists", CMD_UNLISTS, parse_unlists,
396 N_("Remove address from the list of mailing lists"),
397 N_("unlists { * | <regex> ... }"),
398 "configuration.html#lists" },
399 { "unsubscribe", CMD_UNSUBSCRIBE, parse_unsubscribe,
400 N_("Remove address from the list of subscribed mailing lists"),
401 N_("unsubscribe { * | <regex> ... }"),
402 "configuration.html#lists" },
403
404 { NULL, CMD_NONE, NULL, NULL, NULL, NULL, CF_NO_FLAGS },
405 // clang-format on
406};
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 grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition group.c:203
Email Address Handling.
void mutt_auto_subscribe(const char *mailto)
Check if user is subscribed to mailing list.
Definition commands.c:49
void parse_alias_comments(struct Alias *alias, const char *com)
Parse the alias/query comment field.
Definition commands.c:135
void parse_alias_tags(const char *tags, struct TagList *tl)
Parse a comma-separated list of tags.
Definition commands.c:105
const struct Command AliasCommands[]
Alias Commands.
Definition commands.c:361
void alias_tags_to_buffer(struct TagList *tl, struct Buffer *buf)
Write a comma-separated list of tags to a Buffer.
Definition commands.c:89
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
Parse Group/Lists Commands.
Email Aliases.
Alias private Module data.
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
struct Alias * alias_new(void)
Create a new Alias.
Definition alias.c:661
Representation of a single alias to an email address.
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
Parse Alternate Commands.
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_REMOVE(head, elem)
Remove an entry from the array, shifting down the subsequent entries.
Definition array.h:355
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:161
size_t buf_addstr_n(struct Buffer *buf, const char *s, size_t len)
Add a string to a Buffer, expanding it if necessary.
Definition buffer.c:96
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:241
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
#define CF_NO_FLAGS
No flags are set.
Definition command.h:48
@ CMD_SUBSCRIBE
:subscribe
Definition command.h:117
@ CMD_UNSUBSCRIBE
:unsubscribe
Definition command.h:145
@ CMD_UNALIAS
:unalias
Definition command.h:123
@ CMD_GROUP
:group
Definition command.h:79
@ CMD_ALIAS
:alias
Definition command.h:61
@ CMD_LISTS
:lists
Definition command.h:87
@ CMD_UNGROUP
:ungroup
Definition command.h:130
@ CMD_NONE
No Command.
Definition command.h:59
@ CMD_ALTERNATES
:alternates
Definition command.h:62
@ CMD_UNLISTS
:unlists
Definition command.h:134
@ CMD_UNALTERNATES
:unalternates
Definition command.h:124
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
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
Structs that make up an email.
bool mutt_parse_mailto(struct Envelope *env, char **body, const char *src)
Parse a mailto:// url.
Definition parse.c:1723
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition envelope.c:125
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition envelope.c:45
int parse_extract_token(struct Buffer *dest, struct Buffer *line, TokenFlags flags)
Extract one token from a string.
Definition extract.c:49
#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 MoreArgs(buf)
Definition extract.h:31
#define TOKEN_SEMICOLON
Don't treat ; as special.
Definition extract.h:52
#define TOKEN_NO_FLAGS
No flags are set.
Definition extract.h:45
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() -.
Definition commands.c:308
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() -.
Definition group.c:239
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() -.
Definition group.c:291
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() -.
Definition alternates.c:68
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() -.
Definition group.c:191
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() -.
Definition group.c:90
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() -.
Definition alternates.c:119
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() -.
Definition group.c:335
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() -.
Definition commands.c:178
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition hash.c: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 * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition hash.c:261
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition hash.h:113
#define MUTT_HASH_STRCASECMP
use strcasecmp() to compare keys
Definition hash.h:112
@ LL_DEBUG4
Log at debug level 4.
Definition logging2.h:48
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
@ LL_NOTIFY
Log of notifications.
Definition logging2.h:50
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
@ MODULE_ID_ALIAS
ModuleAlias, Alias
Definition module_api.h:48
Convenience wrapper for the library headers.
#define N_(a)
Definition message.h:32
#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
bool mutt_regexlist_match(struct RegexList *rl, const char *str)
Does a string match any Regex in the list?
Definition regex.c:200
struct Slist * slist_parse(const char *str, uint32_t flags)
Parse a list of strings into a list.
Definition slist.c:177
bool slist_is_empty(const struct Slist *list)
Is the slist empty?
Definition slist.c:140
void slist_free(struct Slist **ptr)
Free an Slist object.
Definition slist.c:124
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
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:665
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition notify_type.h:37
Text parsing functions.
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
regmatch_t * mutt_prex_capture(enum Prex which, const char *str)
Match a precompiled regex against a string.
Definition prex.c:301
@ PREX_ALIAS_TAGS
tags:a,b,c
Definition prex.h:43
@ PREX_ALIAS_TAGS_MATCH_POST
... tags:a,b,c[ ...]
Definition prex.h:240
@ PREX_ALIAS_TAGS_MATCH_PRE
[... ]tags:a,b,c ...
Definition prex.h:237
@ PREX_ALIAS_TAGS_MATCH_TAGS
... tags:[a,b,c] ...
Definition prex.h:239
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define STAILQ_HEAD_INITIALIZER(head)
Definition queue.h:324
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:427
#define TAILQ_FIRST(head)
Definition queue.h:780
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:694
#define TAILQ_EMPTY(head)
Definition queue.h:778
#define STAILQ_NEXT(elm, field)
Definition queue.h:439
static regoff_t mutt_regmatch_end(const regmatch_t *match)
Return the end of a match.
Definition regex3.h:66
static regoff_t mutt_regmatch_start(const regmatch_t *match)
Return the start of a match.
Definition regex3.h:56
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
Manage alias reverse lookups.
#define ASSERT(COND)
Definition signal2.h:59
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
Alias private Module data.
Definition module_data.h:33
struct AliasArray aliases
User's email aliases.
Definition module_data.h:35
struct RegexList subscribed
Regexes to match subscribed mailing lists.
Definition module_data.h:49
struct RegexList mail
Regexes to match mailing lists.
Definition module_data.h:48
struct HashTable * auto_subscribe_cache
Hash Table: "mailto:" (no value)
Definition module_data.h:47
struct HashTable * groups
Hash Table: "group-name" -> Group.
Definition module_data.h:45
struct RegexList unmail
Regexes to exclude false matches in mail.
Definition module_data.h:50
struct RegexList unsubscribed
Regexes to exclude false matches in subscribed.
Definition module_data.h:51
A shortcut for an email address or addresses.
Definition alias.h:35
struct TagList tags
Tags.
Definition alias.h:39
char * comment
Free-form comment string.
Definition alias.h:38
char * name
Short name.
Definition alias.h:36
struct AddressList addr
List of Addresses the Alias expands to.
Definition alias.h:37
String manipulation buffer.
Definition buffer.h:36
char * dptr
Current read/write position.
Definition buffer.h:38
const char * name
Name of the Command.
Definition command.h:159
The header of an Email.
Definition envelope.h:57
struct AddressList to
Email's 'To' list.
Definition envelope.h:60
An alias-change event.
Definition alias.h:65
A List node for strings.
Definition list.h:37
char * data
String.
Definition list.h:38
Container for Accounts, Notifications.
Definition neomutt.h:41
struct Notify * notify
Notifications handler.
Definition neomutt.h:45
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
Context for config parsing (history/backtrace)
Definition pcontext.h:34
Detailed error information from config parsing.
Definition perror.h:34
struct Buffer * message
Error message.
Definition perror.h:35
String list.
Definition slist.h:37
struct ListHead head
List containing values.
Definition slist.h:38
LinkedList Tag Element.
Definition tags.h:41
char * name
Tag name.
Definition tags.h:42
struct Tag * tag_new(void)
Create a new Tag.
Definition tags.c:62
#define D_SLIST_SEP_COMMA
Slist items are comma-separated.
Definition types.h:111