NeoMutt  2021-10-29-33-g41675a
Teaching an old dog new tricks
DOXYGEN

Function to parse a command. More...

+ Collaboration diagram for parse():

Functions

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

Detailed Description

Function to parse a command.

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

Function Documentation

◆ parse_alias()

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

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

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

Definition at line 1 of file commands.c.

50 {
51  struct Alias *tmp = NULL;
52  struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
53  enum NotifyAlias event;
54 
55  if (!MoreArgs(s))
56  {
57  mutt_buffer_strcpy(err, _("alias: no address"));
58  return MUTT_CMD_WARNING;
59  }
60 
61  /* name */
63  mutt_debug(LL_DEBUG5, "First token is '%s'\n", buf->data);
64  if (parse_grouplist(&gl, buf, s, err) == -1)
65  {
66  return MUTT_CMD_ERROR;
67  }
68  char *name = mutt_str_dup(buf->data);
69 
70  /* address list */
72  mutt_debug(LL_DEBUG5, "Second token is '%s'\n", buf->data);
73  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
74  int parsed = mutt_addrlist_parse2(&al, buf->data);
75  if (parsed == 0)
76  {
77  mutt_buffer_printf(err, _("Warning: Bad address '%s' in alias '%s'"), buf->data, name);
78  FREE(&name);
79  goto bail;
80  }
81 
82  /* IDN */
83  char *estr = NULL;
84  if (mutt_addrlist_to_intl(&al, &estr))
85  {
86  mutt_buffer_printf(err, _("Warning: Bad IDN '%s' in alias '%s'"), estr, name);
87  FREE(&name);
88  FREE(&estr);
89  goto bail;
90  }
91 
92  /* check to see if an alias with this name already exists */
93  TAILQ_FOREACH(tmp, &Aliases, entries)
94  {
95  if (mutt_istr_equal(tmp->name, name))
96  break;
97  }
98 
99  if (tmp)
100  {
101  FREE(&name);
103  /* override the previous value */
104  mutt_addrlist_clear(&tmp->addr);
105  FREE(&tmp->comment);
106  event = NT_ALIAS_CHANGE;
107  }
108  else
109  {
110  /* create a new alias */
111  tmp = alias_new();
112  tmp->name = name;
113  TAILQ_INSERT_TAIL(&Aliases, tmp, entries);
114  event = NT_ALIAS_ADD;
115  }
116  tmp->addr = al;
117 
118  mutt_grouplist_add_addrlist(&gl, &tmp->addr);
119 
120  const short c_debug_level = cs_subset_number(NeoMutt->sub, "debug_level");
121  if (c_debug_level > LL_DEBUG4)
122  {
123  /* A group is terminated with an empty address, so check a->mailbox */
124  struct Address *a = NULL;
125  TAILQ_FOREACH(a, &tmp->addr, entries)
126  {
127  if (!a->mailbox)
128  break;
129 
130  if (a->group)
131  mutt_debug(LL_DEBUG5, " Group %s\n", a->mailbox);
132  else
133  mutt_debug(LL_DEBUG5, " %s\n", a->mailbox);
134  }
135  }
137  if (!MoreArgs(s) && (s->dptr[0] == '#'))
138  {
139  char *comment = s->dptr + 1;
140  SKIPWS(comment);
141  tmp->comment = mutt_str_dup(comment);
142  }
143 
144  alias_reverse_add(tmp);
145 
146  mutt_debug(LL_NOTIFY, "%s: %s\n",
147  (event == NT_ALIAS_ADD) ? "NT_ALIAS_ADD" : "NT_ALIAS_CHANGE", tmp->name);
148  struct EventAlias ev_a = { tmp };
149  notify_send(NeoMutt->notify, NT_ALIAS, event, &ev_a);
150 
151  return MUTT_CMD_SUCCESS;
152 
153 bail:
155  return MUTT_CMD_ERROR;
156 }
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
int mutt_addrlist_parse2(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:616
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1305
struct AliasList Aliases
List of all the user's email aliases.
Definition: alias.c:57
struct Alias * alias_new(void)
Create a new Alias.
Definition: alias.c:617
NotifyAlias
Alias notification types.
Definition: alias.h:53
@ NT_ALIAS_ADD
Alias has been added.
Definition: alias.h:54
@ NT_ALIAS_CHANGE
Alias has been changed.
Definition: alias.h:57
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
#define MoreArgs(buf)
Definition: buffer.h:40
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:37
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:35
@ MUTT_CMD_WARNING
Warning: Help given to the user.
Definition: command.h:36
int parse_grouplist(struct GroupList *gl, struct Buffer *buf, struct Buffer *s, struct Buffer *err)
Parse a group context.
void mutt_grouplist_destroy(struct GroupList *gl)
Free a GroupList.
Definition: group.c:201
void mutt_grouplist_add_addrlist(struct GroupList *gl, struct AddressList *al)
Add Address list to a GroupList.
Definition: group.c:270
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition: helpers.c:169
int mutt_extract_token(struct Buffer *dest, struct Buffer *tok, TokenFlags flags)
Extract one token from a string.
Definition: init.c:398
@ LL_DEBUG4
Log at debug level 4.
Definition: logging.h:43
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
@ LL_NOTIFY
Log of notifications.
Definition: logging.h:45
#define FREE(x)
Definition: memory.h:40
#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:171
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:727
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:181
#define MUTT_TOKEN_QUOTE
Don't interpret quotes.
Definition: mutt.h:70
#define MUTT_TOKEN_SPACE
Don't treat whitespace as a term.
Definition: mutt.h:69
#define MUTT_TOKEN_SEMICOLON
Don't treat ; as special.
Definition: mutt.h:73
#define MUTT_TOKEN_NO_FLAGS
No flags are set.
Definition: mutt.h:66
@ NT_ALIAS
Alias has changed, NotifyAlias, EventAlias.
Definition: notify_type.h:35
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:809
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
void alias_reverse_add(struct Alias *alias)
Add an email address lookup for an Alias.
Definition: reverse.c:61
void alias_reverse_delete(struct Alias *alias)
Remove an email address lookup for an Alias.
Definition: reverse.c:83
#define SKIPWS(ch)
Definition: string2.h:46
An email address.
Definition: address.h:36
bool group
Group mailbox?
Definition: address.h:39
char * mailbox
Mailbox and host address.
Definition: address.h:38
A shortcut for an email address or addresses.
Definition: alias.h:34
char * comment
Free-form comment string.
Definition: alias.h:37
char * name
Short name.
Definition: alias.h:35
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
char * dptr
Current read/write position.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:35
An alias-change event.
Definition: alias.h:64
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:

◆ parse_unalias()

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

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

Definition at line 1 of file commands.c.

163 {
164  do
165  {
167 
168  struct Alias *np = NULL;
169  if (mutt_str_equal("*", buf->data))
170  {
171  TAILQ_FOREACH(np, &Aliases, entries)
172  {
174  }
175 
177  return MUTT_CMD_SUCCESS;
178  }
179 
180  TAILQ_FOREACH(np, &Aliases, entries)
181  {
182  if (!mutt_istr_equal(buf->data, np->name))
183  continue;
184 
185  TAILQ_REMOVE(&Aliases, np, entries);
187  alias_free(&np);
188  break;
189  }
190  } while (MoreArgs(s));
191  return MUTT_CMD_SUCCESS;
192 }
void alias_free(struct Alias **ptr)
Free an Alias.
Definition: alias.c:628
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:649
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:715
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:841

◆ parse_alternates()

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

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

Definition at line 72 of file alternates.c.

91 {
92  struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
93 
94  do
95  {
97 
98  if (parse_grouplist(&gl, buf, s, err) == -1)
99  goto bail;
100 
102 
103  if (mutt_regexlist_add(&Alternates, buf->data, REG_ICASE, err) != 0)
104  goto bail;
105 
106  if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
107  goto bail;
108  } while (MoreArgs(s));
109 
111 
112  mutt_debug(LL_NOTIFY, "NT_ALTERN_ADD: %s\n", buf->data);
114 
115  return MUTT_CMD_SUCCESS;
116 
117 bail:
119  return MUTT_CMD_ERROR;
120 }
struct RegexList Alternates
List of regexes to match the user's alternate email addresses.
Definition: alternates.c:42
static struct Notify * AlternatesNotify
Definition: alternates.c:44
struct RegexList UnAlternates
List of regexes to blacklist false matches in Alternates.
Definition: alternates.c:43
@ NT_ALTERN_ADD
Alternate address has been added.
Definition: alternates.h:39
int mutt_grouplist_add_regex(struct GroupList *gl, const char *s, uint16_t flags, struct Buffer *err)
Add matching Addresses to a GroupList.
Definition: group.c:320
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:134
int mutt_regexlist_remove(struct RegexList *rl, const char *str)
Remove a Regex from a list.
Definition: regex.c:229
@ NT_ALTERN
Alternates command changed, NotifyAlternates.
Definition: notify_type.h:36

◆ parse_unalternates()

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

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

Definition at line 72 of file alternates.c.

127 {
128  do
129  {
132 
133  if (!mutt_str_equal(buf->data, "*") &&
134  (mutt_regexlist_add(&UnAlternates, buf->data, REG_ICASE, err) != 0))
135  {
136  return MUTT_CMD_ERROR;
137  }
138 
139  } while (MoreArgs(s));
140 
141  mutt_debug(LL_NOTIFY, "NT_ALTERN_DELETE: %s\n", buf->data);
143 
144  return MUTT_CMD_SUCCESS;
145 }
@ NT_ALTERN_DELETE
Alternate address has been deleted.
Definition: alternates.h:40

◆ parse_attachments()

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

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

Definition at line 456 of file attachments.c.

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

◆ parse_unattachments()

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

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

Definition at line 456 of file attachments.c.

533 {
534  char op;
535  char *p = NULL;
536  struct ListHead *head = NULL;
537 
539  if (!buf->data || (*buf->data == '\0'))
540  {
541  mutt_buffer_strcpy(err, _("unattachments: no disposition"));
542  return MUTT_CMD_WARNING;
543  }
544 
545  p = buf->data;
546  op = *p++;
547 
548  if (op == '*')
549  {
554 
555  mutt_debug(LL_NOTIFY, "NT_ATTACH_DELETE_ALL\n");
557  return 0;
558  }
559 
560  if ((op != '+') && (op != '-'))
561  {
562  op = '+';
563  p--;
564  }
565  if (mutt_istr_startswith("attachment", p))
566  {
567  if (op == '+')
568  head = &AttachAllow;
569  else
570  head = &AttachExclude;
571  }
572  else if (mutt_istr_startswith("inline", p))
573  {
574  if (op == '+')
575  head = &InlineAllow;
576  else
577  head = &InlineExclude;
578  }
579  else
580  {
581  mutt_buffer_strcpy(err, _("unattachments: invalid disposition"));
582  return MUTT_CMD_ERROR;
583  }
584 
585  return parse_unattach_list(buf, s, head, err);
586 }
static struct Notify * AttachmentsNotify
Definition: attachments.c:60
static enum CommandResult parse_unattach_list(struct Buffer *buf, struct Buffer *s, struct ListHead *head, struct Buffer *err)
Parse the "unattachments" command.
Definition: attachments.c:390
@ NT_ATTACH_DELETE_ALL
All Attachment regexes have been deleted.
Definition: attachments.h:40
static void attachmatch_free(struct AttachMatch **ptr)
Free an AttachMatch - Implements list_free_t -.
Definition: attachments.c:69
void mutt_list_free_type(struct ListHead *h, list_free_t fn)
Free a List of type.
Definition: list.c:144
void(* list_free_t)(void **ptr)
Definition: list.h:48
@ NT_ATTACH
Attachment command changed, NotifyAttach.
Definition: notify_type.h:37

◆ mutt_parse_uncolor()

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

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

Definition at line 535 of file command.c.

681 {
682  if (OptNoCurses || !has_colors())
683  {
684  *s->dptr = '\0'; /* fake that we're done parsing */
685  return MUTT_CMD_SUCCESS;
686  }
687  return parse_uncolor(buf, s, err, true);
688 }
static enum CommandResult parse_uncolor(struct Buffer *buf, struct Buffer *s, struct Buffer *err, bool uncolor)
Parse an 'uncolor' command.
Definition: command.c:430
bool OptNoCurses
(pseudo) when sending in batch mode
Definition: options.h:53

◆ mutt_parse_unmono()

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

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

Definition at line 535 of file command.c.

695 {
696  if (OptNoCurses || !has_colors())
697  {
698  *s->dptr = '\0'; /* fake that we're done parsing */
699  return MUTT_CMD_SUCCESS;
700  }
701  return parse_uncolor(buf, s, err, false);
702 }

◆ mutt_parse_color()

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

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

Definition at line 535 of file command.c.

709 {
710  bool dry_run = false;
711 
712  if (OptNoCurses || !has_colors())
713  dry_run = true;
714 
715  return parse_color(buf, s, err, parse_color_pair, dry_run, true);
716 }
static enum CommandResult parse_color(struct Buffer *buf, struct Buffer *s, struct Buffer *err, parser_callback_t callback, bool dry_run, bool color)
Parse a 'color' command.
Definition: command.c:555
static enum CommandResult parse_color_pair(struct Buffer *buf, struct Buffer *s, uint32_t *fg, uint32_t *bg, int *attrs, struct Buffer *err)
Parse a pair of colours - Implements parser_callback_t -.
Definition: command.c:237

◆ mutt_parse_mono()

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

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

Definition at line 535 of file command.c.

723 {
724  bool dry_run = false;
725 
726  if (OptNoCurses || has_colors())
727  dry_run = true;
728 
729  return parse_color(buf, s, err, parse_attr_spec, dry_run, false);
730 }
static enum CommandResult parse_attr_spec(struct Buffer *buf, struct Buffer *s, uint32_t *fg, uint32_t *bg, int *attrs, struct Buffer *err)
Parse an attribute description - Implements parser_callback_t -.
Definition: command.c:196

◆ parse_cd()

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

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

Definition at line 142 of file command_parse.c.

289 {
292  if (mutt_buffer_len(buf) == 0)
293  {
294  if (HomeDir)
296  else
297  {
298  mutt_buffer_printf(err, _("%s: too few arguments"), "cd");
299  return MUTT_CMD_ERROR;
300  }
301  }
302 
303  if (chdir(mutt_buffer_string(buf)) != 0)
304  {
305  mutt_buffer_printf(err, "cd: %s", strerror(errno));
306  return MUTT_CMD_ERROR;
307  }
308 
309  return MUTT_CMD_SUCCESS;
310 }
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
char * HomeDir
User's home directory.
Definition: mutt_globals.h:51
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:322
+ Here is the call graph for this function:

◆ parse_echo()

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

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

Definition at line 142 of file command_parse.c.

317 {
318  if (!MoreArgs(s))
319  {
320  mutt_buffer_printf(err, _("%s: too few arguments"), "echo");
321  return MUTT_CMD_WARNING;
322  }
324  OptForceRefresh = true;
325  mutt_message("%s", buf->data);
326  OptForceRefresh = false;
327  mutt_sleep(0);
328 
329  return MUTT_CMD_SUCCESS;
330 }
#define mutt_message(...)
Definition: logging.h:86
void mutt_sleep(short s)
Sleep for a while.
Definition: muttlib.c:1461
bool OptForceRefresh
(pseudo) refresh even during macros
Definition: options.h:42

◆ parse_finish()

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

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

Return values
MUTT_CMD_FINISHStop processing the current file
MUTT_CMD_WARNINGFailed

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

Definition at line 142 of file command_parse.c.

341 {
342  if (MoreArgs(s))
343  {
344  mutt_buffer_printf(err, _("%s: too many arguments"), "finish");
345  return MUTT_CMD_WARNING;
346  }
347 
348  return MUTT_CMD_FINISH;
349 }
@ MUTT_CMD_FINISH
Finish: Stop processing this file.
Definition: command.h:38

◆ parse_group()

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

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

Definition at line 142 of file command_parse.c.

356 {
357  struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
358  enum GroupState state = GS_NONE;
359 
360  do
361  {
363  if (parse_grouplist(&gl, buf, s, err) == -1)
364  goto bail;
365 
366  if ((data == MUTT_UNGROUP) && mutt_istr_equal(buf->data, "*"))
367  {
369  goto out;
370  }
371 
372  if (mutt_istr_equal(buf->data, "-rx"))
373  state = GS_RX;
374  else if (mutt_istr_equal(buf->data, "-addr"))
375  state = GS_ADDR;
376  else
377  {
378  switch (state)
379  {
380  case GS_NONE:
381  mutt_buffer_printf(err, _("%sgroup: missing -rx or -addr"),
382  (data == MUTT_UNGROUP) ? "un" : "");
383  goto warn;
384 
385  case GS_RX:
386  if ((data == MUTT_GROUP) &&
387  (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0))
388  {
389  goto bail;
390  }
391  else if ((data == MUTT_UNGROUP) &&
392  (mutt_grouplist_remove_regex(&gl, buf->data) < 0))
393  {
394  goto bail;
395  }
396  break;
397 
398  case GS_ADDR:
399  {
400  char *estr = NULL;
401  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
402  mutt_addrlist_parse2(&al, buf->data);
403  if (TAILQ_EMPTY(&al))
404  goto bail;
405  if (mutt_addrlist_to_intl(&al, &estr))
406  {
407  mutt_buffer_printf(err, _("%sgroup: warning: bad IDN '%s'"),
408  (data == 1) ? "un" : "", estr);
409  mutt_addrlist_clear(&al);
410  FREE(&estr);
411  goto bail;
412  }
413  if (data == MUTT_GROUP)
414  mutt_grouplist_add_addrlist(&gl, &al);
415  else if (data == MUTT_UNGROUP)
417  mutt_addrlist_clear(&al);
418  break;
419  }
420  }
421  }
422  } while (MoreArgs(s));
423 
424 out:
426  return MUTT_CMD_SUCCESS;
427 
428 bail:
430  return MUTT_CMD_ERROR;
431 
432 warn:
434  return MUTT_CMD_WARNING;
435 }
GroupState
Type of email address group.
Definition: command_parse.c:73
@ GS_RX
Entry is a regular expression.
Definition: command_parse.c:75
@ GS_NONE
Group is missing an argument.
Definition: command_parse.c:74
@ GS_ADDR
Entry is an address.
Definition: command_parse.c:76
int mutt_grouplist_remove_addrlist(struct GroupList *gl, struct AddressList *al)
Remove an AddressList from a GroupList.
Definition: group.c:289
int mutt_grouplist_remove_regex(struct GroupList *gl, const char *s)
Remove matching addresses from a GroupList.
Definition: group.c:345
void mutt_grouplist_clear(struct GroupList *gl)
Clear a GroupList.
Definition: group.c:147
#define MUTT_GROUP
'group' config command
Definition: group.h:33
#define MUTT_UNGROUP
'ungroup' config command
Definition: group.h:34
#define TAILQ_EMPTY(head)
Definition: queue.h:721

◆ parse_ifdef()

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

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

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

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

Definition at line 142 of file command_parse.c.

452 {
454 
455  // is the item defined as:
456  bool res = cs_subset_lookup(NeoMutt->sub, buf->data) // a variable?
457  || feature_enabled(buf->data) // a compiled-in feature?
458  || is_function(buf->data) // a function?
459  || mutt_command_get(buf->data) // a command?
460  || myvar_get(buf->data) // a my_ variable?
461  || mutt_str_getenv(buf->data); // an environment variable?
462 
463  if (!MoreArgs(s))
464  {
465  mutt_buffer_printf(err, _("%s: too few arguments"), (data ? "ifndef" : "ifdef"));
466  return MUTT_CMD_WARNING;
467  }
469 
470  /* ifdef KNOWN_SYMBOL or ifndef UNKNOWN_SYMBOL */
471  if ((res && (data == 0)) || (!res && (data == 1)))
472  {
473  enum CommandResult rc = mutt_parse_rc_line(buf->data, err);
474  if (rc == MUTT_CMD_ERROR)
475  {
476  mutt_error(_("Error: %s"), err->data);
477  return MUTT_CMD_ERROR;
478  }
479  return rc;
480  }
481  return MUTT_CMD_SUCCESS;
482 }
CommandResult
Error codes for command_t parse functions.
Definition: command.h:34
static bool is_function(const char *name)
Is the argument a neomutt function?
Definition: command_parse.c:85
#define mutt_error(...)
Definition: logging.h:87
enum CommandResult mutt_parse_rc_line(const char *line, struct Buffer *err)
Parse a line of user config.
Definition: init.c:1043
const char * mutt_str_getenv(const char *name)
Get an environment variable.
Definition: string.c:835
struct Command * mutt_command_get(const char *s)
Get a Command by its name.
const char * myvar_get(const char *var)
Get the value of a "my_" variable.
Definition: myvar.c:92
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:179
bool feature_enabled(const char *name)
Test if a compile-time feature is enabled.
Definition: version.c:554

◆ parse_ignore()

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

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

Definition at line 142 of file command_parse.c.

489 {
490  do
491  {
494  add_to_stailq(&Ignore, buf->data);
495  } while (MoreArgs(s));
496 
497  return MUTT_CMD_SUCCESS;
498 }
struct ListHead Ignore
List of header patterns to ignore.
Definition: globals.c:35
struct ListHead UnIgnore
List of header patterns to unignore (see)
Definition: globals.c:36
void remove_from_stailq(struct ListHead *head, const char *str)
Remove an item, matching a string, from a List.
Definition: muttlib.c:1753
void add_to_stailq(struct ListHead *head, const char *str)
Add a string to a list.
Definition: muttlib.c:1728

◆ parse_lists()

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

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

Definition at line 142 of file command_parse.c.

505 {
506  struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
507 
508  do
509  {
511 
512  if (parse_grouplist(&gl, buf, s, err) == -1)
513  goto bail;
514 
516 
517  if (mutt_regexlist_add(&MailLists, buf->data, REG_ICASE, err) != 0)
518  goto bail;
519 
520  if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
521  goto bail;
522  } while (MoreArgs(s));
523 
525  return MUTT_CMD_SUCCESS;
526 
527 bail:
529  return MUTT_CMD_ERROR;
530 }
struct RegexList UnMailLists
List of regexes to blacklist false matches in MailLists.
Definition: globals.c:42
struct RegexList MailLists
List of regexes to match mailing lists.
Definition: globals.c:41

◆ parse_mailboxes()

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

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

This is also used by 'virtual-mailboxes'.

Definition at line 142 of file command_parse.c.

539 {
540  while (MoreArgs(s))
541  {
542  struct Mailbox *m = mailbox_new();
543 
544  if (data & MUTT_NAMED)
545  {
546  // This may be empty, e.g. `named-mailboxes "" +inbox`
548  m->name = mutt_buffer_strdup(buf);
549  }
550 
552  if (mutt_buffer_is_empty(buf))
553  {
554  /* Skip empty tokens. */
555  mailbox_free(&m);
556  continue;
557  }
558 
559  mutt_buffer_strcpy(&m->pathbuf, buf->data);
560  const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
561  /* int rc = */ mx_path_canon2(m, c_folder);
562 
563  if (m->type <= MUTT_UNKNOWN)
564  {
565  mutt_error("Unknown Mailbox: %s", m->realpath);
566  mailbox_free(&m);
567  return MUTT_CMD_ERROR;
568  }
569 
570  bool new_account = false;
571  struct Account *a = mx_ac_find(m);
572  if (!a)
573  {
574  a = account_new(NULL, NeoMutt->sub);
575  a->type = m->type;
576  new_account = true;
577  }
578 
579  if (!new_account)
580  {
581  struct Mailbox *m_old = mx_mbox_find(a, m->realpath);
582  if (m_old)
583  {
584  const bool show = (m_old->flags == MB_HIDDEN);
585  if (show)
586  {
587  m_old->flags = MB_NORMAL;
588  m_old->gen = mailbox_gen();
589  }
590 
591  const bool rename = (data & MUTT_NAMED) && !mutt_str_equal(m_old->name, m->name);
592  if (rename)
593  {
594  mutt_str_replace(&m_old->name, m->name);
595  }
596 
597  mailbox_free(&m);
598  continue;
599  }
600  }
601 
602  if (!mx_ac_add(a, m))
603  {
604  //error
605  mailbox_free(&m);
606  if (new_account)
607  {
608  cs_subset_free(&a->sub);
609  FREE(&a->name);
610  notify_free(&a->notify);
611  FREE(&a);
612  }
613  continue;
614  }
615  if (new_account)
616  {
618  }
619 
620 #ifdef USE_INOTIFY
621  mutt_monitor_add(m);
622 #endif
623  }
624  return MUTT_CMD_SUCCESS;
625 }
struct Account * account_new(const char *name, struct ConfigSubset *sub)
Create a new Account.
Definition: account.c:43
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:432
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
struct Mailbox * mailbox_new(void)
Create a new Mailbox.
Definition: mailbox.c:68
int mailbox_gen(void)
Get the next generation number.
Definition: mailbox.c:58
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
#define MB_HIDDEN
Definition: mailbox.h:38
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:47
#define MB_NORMAL
Definition: mailbox.h:37
int mutt_monitor_add(struct Mailbox *m)
Add a watch for a mailbox.
Definition: monitor.c:481
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:73
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:257
#define MUTT_NAMED
Definition: mutt_commands.h:44
bool mx_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Wrapper for MxOps::ac_add()
Definition: mx.c:1761
struct Mailbox * mx_mbox_find(struct Account *a, const char *path)
Find a Mailbox on an Account.
Definition: mx.c:1583
struct Account * mx_ac_find(struct Mailbox *m)
Find the Account owning a Mailbox.
Definition: mx.c:1559
int mx_path_canon2(struct Mailbox *m, const char *folder)
Canonicalise the path to realpath.
Definition: mx.c:1473
bool neomutt_account_add(struct NeoMutt *n, struct Account *a)
Add an Account to the global list.
Definition: neomutt.c:84
A group of associated Mailboxes.
Definition: account.h:37
enum MailboxType type
Type of Mailboxes this Account contains.
Definition: account.h:38
char * name
Name of Account.
Definition: account.h:39
struct Notify * notify
Notifications: NotifyAccount, EventAccount.
Definition: account.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: account.h:40
A mailbox.
Definition: mailbox.h:82
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:83
uint8_t flags
e.g. MB_NORMAL
Definition: mailbox.h:134
int gen
Generation number, for sorting.
Definition: mailbox.h:150
void cs_subset_free(struct ConfigSubset **ptr)
Free a Config Subset.
Definition: subset.c:104

◆ parse_my_hdr()

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

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

Definition at line 142 of file command_parse.c.

632 {
634  char *p = strpbrk(buf->data, ": \t");
635  if (!p || (*p != ':'))
636  {
637  mutt_buffer_strcpy(err, _("invalid header field"));
638  return MUTT_CMD_WARNING;
639  }
640 
641  struct EventHeader ev_h = { buf->data };
642  struct ListNode *n = header_find(&UserHeader, buf->data);
643 
644  if (n)
645  {
646  header_update(n, buf->data);
647  mutt_debug(LL_NOTIFY, "NT_HEADER_CHANGE: %s\n", buf->data);
649  }
650  else
651  {
652  header_add(&UserHeader, buf->data);
653  mutt_debug(LL_NOTIFY, "NT_HEADER_ADD: %s\n", buf->data);
655  }
656 
657  return MUTT_CMD_SUCCESS;
658 }
struct ListNode * header_add(struct ListHead *hdrlist, const char *header)
Add a header to a list.
Definition: email.c:203
struct ListNode * header_update(struct ListNode *hdr, const char *header)
Update an existing header.
Definition: email.c:217
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:180
@ NT_HEADER_CHANGE
An existing header has been changed.
Definition: email.h:171
@ NT_HEADER_ADD
Header has been added.
Definition: email.h:169
struct ListHead UserHeader
List of custom headers to add to outgoing emails.
Definition: mutt_globals.h:70
@ NT_HEADER
A header has changed, NotifyHeader EventHeader.
Definition: notify_type.h:46
An event that happened to a header.
Definition: email.h:178
A List node for strings.
Definition: list.h:35
+ Here is the caller graph for this function:

◆ parse_set()

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

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

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

Definition at line 142 of file command_parse.c.

667 {
668  /* The order must match `enum MuttSetCommand` */
669  static const char *set_commands[] = { "set", "toggle", "unset", "reset" };
670 
671  int rc = 0;
672 
673  while (MoreArgs(s))
674  {
675  bool prefix = false;
676  bool query = false;
677  bool inv = (data == MUTT_SET_INV);
678  bool reset = (data == MUTT_SET_RESET);
679  bool unset = (data == MUTT_SET_UNSET);
680 
681  if (*s->dptr == '?')
682  {
683  prefix = true;
684  query = true;
685  s->dptr++;
686  }
687  else if (mutt_str_startswith(s->dptr, "no"))
688  {
689  prefix = true;
690  unset = !unset;
691  s->dptr += 2;
692  }
693  else if (mutt_str_startswith(s->dptr, "inv"))
694  {
695  prefix = true;
696  inv = !inv;
697  s->dptr += 3;
698  }
699  else if (*s->dptr == '&')
700  {
701  prefix = true;
702  reset = true;
703  s->dptr++;
704  }
705 
706  if (prefix && (data != MUTT_SET_SET))
707  {
708  mutt_buffer_printf(err, _("Can't use 'inv', 'no', '&' or '?' with the '%s' command"),
709  set_commands[data]);
710  return MUTT_CMD_WARNING;
711  }
712 
713  /* get the variable name */
715 
716  bool bq = false;
717  bool equals = false;
718  bool increment = false;
719  bool decrement = false;
720 
721  struct HashElem *he = NULL;
722  bool my = mutt_str_startswith(buf->data, "my_");
723  if (!my)
724  {
725  he = cs_subset_lookup(NeoMutt->sub, buf->data);
726  if (!he)
727  {
728  if (reset && mutt_str_equal(buf->data, "all"))
729  {
730  struct HashElem **list = get_elem_list(NeoMutt->sub->cs);
731  if (!list)
732  return MUTT_CMD_ERROR;
733 
734  for (size_t i = 0; list[i]; i++)
735  cs_subset_he_reset(NeoMutt->sub, list[i], NULL);
736 
737  FREE(&list);
738  break;
739  }
740  else
741  {
742  mutt_buffer_printf(err, _("%s: unknown variable"), buf->data);
743  return MUTT_CMD_ERROR;
744  }
745  }
746 
747  // Use the correct name if a synonym is used
748  mutt_buffer_strcpy(buf, he->key.strkey);
749 
750  bq = ((DTYPE(he->type) == DT_BOOL) || (DTYPE(he->type) == DT_QUAD));
751  }
752 
753  if (*s->dptr == '?')
754  {
755  if (prefix)
756  {
757  mutt_buffer_printf(err,
758  _("Can't use a prefix when querying a variable"));
759  return MUTT_CMD_WARNING;
760  }
761 
762  if (reset || unset || inv)
763  {
764  mutt_buffer_printf(err, _("Can't query a variable with the '%s' command"),
765  set_commands[data]);
766  return MUTT_CMD_WARNING;
767  }
768 
769  query = true;
770  s->dptr++;
771  }
772  else if (*s->dptr == '+' || *s->dptr == '-')
773  {
774  if (prefix)
775  {
777  err,
778  _("Can't use prefix when incrementing or decrementing a variable"));
779  return MUTT_CMD_WARNING;
780  }
781 
782  if (reset || unset || inv)
783  {
784  mutt_buffer_printf(err, _("Can't set a variable with the '%s' command"),
785  set_commands[data]);
786  return MUTT_CMD_WARNING;
787  }
788  if (*s->dptr == '+')
789  increment = true;
790  else
791  decrement = true;
792 
793  if (my && decrement)
794  {
795  mutt_buffer_printf(err, _("Can't decrement a my_ variable"), set_commands[data]);
796  return MUTT_CMD_WARNING;
797  }
798  s->dptr++;
799  if (*s->dptr == '=')
800  {
801  equals = true;
802  s->dptr++;
803  }
804  }
805  else if (*s->dptr == '=')
806  {
807  if (prefix)
808  {
809  mutt_buffer_printf(err, _("Can't use prefix when setting a variable"));
810  return MUTT_CMD_WARNING;
811  }
812 
813  if (reset || unset || inv)
814  {
815  mutt_buffer_printf(err, _("Can't set a variable with the '%s' command"),
816  set_commands[data]);
817  return MUTT_CMD_WARNING;
818  }
819 
820  equals = true;
821  s->dptr++;
822  }
823 
824  if (!bq && (inv || (unset && prefix)))
825  {
826  if (data == MUTT_SET_SET)
827  {
828  mutt_buffer_printf(err, _("Prefixes 'no' and 'inv' may only be used "
829  "with bool/quad variables"));
830  }
831  else
832  {
833  mutt_buffer_printf(err, _("Command '%s' can only be used with bool/quad variables"),
834  set_commands[data]);
835  }
836  return MUTT_CMD_WARNING;
837  }
838 
839  if (reset)
840  {
841  // mutt_buffer_printf(err, "ACT24 reset variable %s", buf->data);
842  if (he)
843  {
844  rc = cs_subset_he_reset(NeoMutt->sub, he, err);
845  if (CSR_RESULT(rc) != CSR_SUCCESS)
846  return MUTT_CMD_ERROR;
847  }
848  else
849  {
850  myvar_del(buf->data);
851  }
852  continue;
853  }
854 
855  if ((data == MUTT_SET_SET) && !inv && !unset)
856  {
857  if (query)
858  {
859  // mutt_buffer_printf(err, "ACT08 query variable %s", buf->data);
860  if (he)
861  {
862  mutt_buffer_addstr(err, buf->data);
863  mutt_buffer_addch(err, '=');
864  mutt_buffer_reset(buf);
865  rc = cs_subset_he_string_get(NeoMutt->sub, he, buf);
866  if (CSR_RESULT(rc) != CSR_SUCCESS)
867  {
868  mutt_buffer_addstr(err, buf->data);
869  return MUTT_CMD_ERROR;
870  }
871  if (DTYPE(he->type) == DT_PATH)
872  mutt_pretty_mailbox(buf->data, buf->dsize);
873  pretty_var(buf->data, err);
874  }
875  else
876  {
877  const char *val = myvar_get(buf->data);
878  if (val)
879  {
880  mutt_buffer_addstr(err, buf->data);
881  mutt_buffer_addch(err, '=');
882  pretty_var(val, err);
883  }
884  else
885  {
886  mutt_buffer_printf(err, _("%s: unknown variable"), buf->data);
887  return MUTT_CMD_ERROR;
888  }
889  }
890  break;
891  }
892  else if (equals)
893  {
894  // mutt_buffer_printf(err, "ACT11 set variable %s to ", buf->data);
895  const char *name = NULL;
896  if (my)
897  {
898  name = mutt_str_dup(buf->data);
899  }
901  if (my)
902  {
903  assert(!decrement);
904  if (increment)
905  {
906  myvar_append(name, buf->data);
907  }
908  else
909  {
910  myvar_set(name, buf->data);
911  }
912  FREE(&name);
913  }
914  else
915  {
916  if (DTYPE(he->type) == DT_PATH)
917  {
918  if (he->type & (DT_PATH_DIR | DT_PATH_FILE))
920  else
921  mutt_path_tilde(buf->data, buf->dsize, HomeDir);
922  }
923  else if (IS_MAILBOX(he))
924  {
926  }
927  else if (IS_COMMAND(he))
928  {
929  struct Buffer scratch = mutt_buffer_make(1024);
930  mutt_buffer_copy(&scratch, buf);
931 
932  if (!mutt_str_equal(buf->data, "builtin"))
933  {
934  mutt_buffer_expand_path(&scratch);
935  }
936  mutt_buffer_reset(buf);
937  mutt_buffer_addstr(buf, mutt_buffer_string(&scratch));
938  mutt_buffer_dealloc(&scratch);
939  }
940  if (increment)
941  {
942  rc = cs_subset_he_string_plus_equals(NeoMutt->sub, he, buf->data, err);
943  }
944  else if (decrement)
945  {
946  rc = cs_subset_he_string_minus_equals(NeoMutt->sub, he, buf->data, err);
947  }
948  else
949  {
950  rc = cs_subset_he_string_set(NeoMutt->sub, he, buf->data, err);
951  }
952  if (CSR_RESULT(rc) != CSR_SUCCESS)
953  return MUTT_CMD_ERROR;
954  }
955  continue;
956  }
957  else
958  {
959  if (bq)
960  {
961  // mutt_buffer_printf(err, "ACT23 set variable %s to 'yes'", buf->data);
962  rc = cs_subset_he_native_set(NeoMutt->sub, he, true, err);
963  if (CSR_RESULT(rc) != CSR_SUCCESS)
964  return MUTT_CMD_ERROR;
965  continue;
966  }
967  else
968  {
969  // mutt_buffer_printf(err, "ACT10 query variable %s", buf->data);
970  if (he)
971  {
972  mutt_buffer_addstr(err, buf->data);
973  mutt_buffer_addch(err, '=');
974  mutt_buffer_reset(buf);
975  rc = cs_subset_he_string_get(NeoMutt->sub, he, buf);
976  if (CSR_RESULT(rc) != CSR_SUCCESS)
977  {
978  mutt_buffer_addstr(err, buf->data);
979  return MUTT_CMD_ERROR;
980  }
981  if (DTYPE(he->type) == DT_PATH)
982  mutt_pretty_mailbox(buf->data, buf->dsize);
983  pretty_var(buf->data, err);
984  }
985  else
986  {
987  const char *val = myvar_get(buf->data);
988  if (val)
989  {
990  mutt_buffer_addstr(err, buf->data);
991  mutt_buffer_addch(err, '=');
992  pretty_var(val, err);
993  }
994  else
995  {
996  mutt_buffer_printf(err, _("%s: unknown variable"), buf->data);
997  return MUTT_CMD_ERROR;
998  }
999  }
1000  break;
1001  }
1002  }
1003  }
1004 
1005  if (my)
1006  {
1007  myvar_del(buf->data);
1008  }
1009  else if (bq)
1010  {
1011  if (inv)
1012  {
1013  // mutt_buffer_printf(err, "ACT25 TOGGLE bool/quad variable %s", buf->data);
1014  if (DTYPE(he->type) == DT_BOOL)
1015  bool_he_toggle(NeoMutt->sub, he, err);
1016  else
1017  quad_he_toggle(NeoMutt->sub, he, err);
1018  }
1019  else
1020  {
1021  // mutt_buffer_printf(err, "ACT26 UNSET bool/quad variable %s", buf->data);
1022  rc = cs_subset_he_native_set(NeoMutt->sub, he, false, err);
1023  if (CSR_RESULT(rc) != CSR_SUCCESS)
1024  return MUTT_CMD_ERROR;
1025  }
1026  continue;
1027  }
1028  else
1029  {
1030  rc = cs_subset_he_string_set(NeoMutt->sub, he, NULL, err);
1031  if (CSR_RESULT(rc) != CSR_SUCCESS)
1032  return MUTT_CMD_ERROR;
1033  }
1034  }
1035 
1036  return MUTT_CMD_SUCCESS;
1037 }
int bool_he_toggle(struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:186
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:445
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:83
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:526
bool mutt_path_tilde(char *buf, size_t buflen, const char *homedir)
Expand '~' in a path.
Definition: path.c:223
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:158
#define MUTT_TOKEN_BACKTICK_VARS
Expand variables within backticks.
Definition: mutt.h:74
#define MUTT_TOKEN_MINUS
Treat '-' as a special.
Definition: mutt.h:78
#define MUTT_TOKEN_PLUS
Treat '+' as a special.
Definition: mutt.h:77
#define MUTT_TOKEN_EQUAL
Treat '=' as a special.
Definition: mutt.h:67
#define MUTT_TOKEN_QUESTION
Treat '?' as a special.
Definition: mutt.h:76
@ MUTT_SET_INV
default is to invert all vars
Definition: mutt_commands.h:38
@ MUTT_SET_SET
default is to set all vars
Definition: mutt_commands.h:37
@ MUTT_SET_RESET
default is to reset all vars to default
Definition: mutt_commands.h:40
@ MUTT_SET_UNSET
default is to unset all vars
Definition: mutt_commands.h:39
void myvar_del(const char *var)
Unset the value of a "my_" variable.
Definition: myvar.c:146
void myvar_set(const char *var, const char *val)
Set the value of a "my_" variable.
Definition: myvar.c:109
void myvar_append(const char *var, const char *val)
Append to the value of a "my_" variable.
Definition: myvar.c:128
int quad_he_toggle(struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Toggle the value of a quad.
Definition: quad.c:203
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
String manipulation buffer.
Definition: buffer.h:34
size_t dsize
Length of data.
Definition: buffer.h:37
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
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
void * data
User-supplied data.
Definition: hash.h:47
int cs_subset_he_string_minus_equals(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Remove from a config item by string.
Definition: subset.c:462
int cs_subset_he_string_get(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:354
int cs_subset_he_native_set(const struct ConfigSubset *sub, struct HashElem *he, intptr_t value, struct Buffer *err)
Natively set the value of a HashElem config item.
Definition: subset.c:283
int cs_subset_he_reset(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Reset a config item to its initial value.
Definition: subset.c:320
int cs_subset_he_string_set(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:386
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:75
int cs_subset_he_string_plus_equals(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Add to a config item by string.
Definition: subset.c:424
#define DTYPE(x)
Mask for the Data Type.
Definition: types.h:44
#define IS_MAILBOX(x)
Definition: types.h:57
#define DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:37
#define DT_BOOL
boolean option
Definition: types.h:30
#define DT_PATH_DIR
Path is a directory.
Definition: types.h:53
#define DT_PATH_FILE
Path is a file.
Definition: types.h:54
#define DT_PATH
a path to a file/directory
Definition: types.h:36
#define IS_COMMAND(x)
Definition: types.h:58
const char * strkey
String key.
Definition: hash.h:36

◆ parse_setenv()

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

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

Definition at line 142 of file command_parse.c.

1044 {
1045  char **envp = mutt_envlist_getlist();
1046 
1047  bool query = false;
1048  bool prefix = false;
1049  bool unset = (data == MUTT_SET_UNSET);
1050 
1051  if (!MoreArgs(s))
1052  {
1053  mutt_buffer_printf(err, _("%s: too few arguments"), "setenv");
1054  return MUTT_CMD_WARNING;
1055  }
1056 
1057  if (*s->dptr == '?')
1058  {
1059  query = true;
1060  prefix = true;
1061 
1062  if (unset)
1063  {
1064  mutt_buffer_printf(err, _("Can't query a variable with the '%s' command"), "unsetenv");
1065  return MUTT_CMD_WARNING;
1066  }
1067 
1068  s->dptr++;
1069  }
1070 
1071  /* get variable name */
1073 
1074  if (*s->dptr == '?')
1075  {
1076  if (unset)
1077  {
1078  mutt_buffer_printf(err, _("Can't query a variable with the '%s' command"), "unsetenv");
1079  return MUTT_CMD_WARNING;
1080  }
1081 
1082  if (prefix)
1083  {
1084  mutt_buffer_printf(err, _("Can't use a prefix when querying a variable"));
1085  return MUTT_CMD_WARNING;
1086  }
1087 
1088  query = true;
1089  s->dptr++;
1090  }
1091 
1092  if (query)
1093  {
1094  bool found = false;
1095  while (envp && *envp)
1096  {
1097  /* This will display all matches for "^QUERY" */
1098  if (mutt_str_startswith(*envp, buf->data))
1099  {
1100  if (!found)
1101  {
1102  mutt_endwin();
1103  found = true;
1104  }
1105  puts(*envp);
1106  }
1107  envp++;
1108  }
1109 
1110  if (found)
1111  {
1113  return MUTT_CMD_SUCCESS;
1114  }
1115 
1116  mutt_buffer_printf(err, _("%s is unset"), buf->data);
1117  return MUTT_CMD_WARNING;
1118  }
1119 
1120  if (unset)
1121  {
1122  if (!mutt_envlist_unset(buf->data))
1123  {
1124  mutt_buffer_printf(err, _("%s is unset"), buf->data);
1125  return MUTT_CMD_WARNING;
1126  }
1127  return MUTT_CMD_SUCCESS;
1128  }
1129 
1130  /* set variable */
1131 
1132  if (*s->dptr == '=')
1133  {
1134  s->dptr++;
1135  SKIPWS(s->dptr);
1136  }
1137 
1138  if (!MoreArgs(s))
1139  {
1140  mutt_buffer_printf(err, _("%s: too few arguments"), "setenv");
1141  return MUTT_CMD_WARNING;
1142  }
1143 
1144  char *name = mutt_str_dup(buf->data);
1146  mutt_envlist_set(name, buf->data, true);
1147  FREE(&name);
1148 
1149  return MUTT_CMD_SUCCESS;
1150 }
bool mutt_envlist_unset(const char *name)
Unset an environment variable.
Definition: envlist.c:132
bool mutt_envlist_set(const char *name, const char *value, bool overwrite)
Set an environment variable.
Definition: envlist.c:85
char ** mutt_envlist_getlist(void)
Get the private environment.
Definition: envlist.c:169

◆ parse_source()

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

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

Definition at line 142 of file command_parse.c.

1157 {
1158  char path[PATH_MAX];
1159 
1160  do
1161  {
1162  if (mutt_extract_token(buf, s, MUTT_TOKEN_NO_FLAGS) != 0)
1163  {
1164  mutt_buffer_printf(err, _("source: error at %s"), s->dptr);
1165  return MUTT_CMD_ERROR;
1166  }
1167  mutt_str_copy(path, buf->data, sizeof(path));
1168  mutt_expand_path(path, sizeof(path));
1169 
1170  if (source_rc(path, err) < 0)
1171  {
1172  mutt_buffer_printf(err, _("source: file %s could not be sourced"), path);
1173  return MUTT_CMD_ERROR;
1174  }
1175 
1176  } while (MoreArgs(s));
1177 
1178  return MUTT_CMD_SUCCESS;
1179 }
int source_rc(const char *rcfile_path, struct Buffer *err)
Read an initialization file.
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:560
#define PATH_MAX
Definition: mutt.h:40
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:122

◆ parse_spam_list()

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

Parse the 'spam' and 'nospam' commands - Implements Command::parse() -.

Definition at line 142 of file command_parse.c.

1186 {
1187  struct Buffer templ;
1188 
1189  mutt_buffer_init(&templ);
1190 
1191  /* Insist on at least one parameter */
1192  if (!MoreArgs(s))
1193  {
1194  if (data == MUTT_SPAM)
1195  mutt_buffer_strcpy(err, _("spam: no matching pattern"));
1196  else
1197  mutt_buffer_strcpy(err, _("nospam: no matching pattern"));
1198  return MUTT_CMD_ERROR;
1199  }
1200 
1201  /* Extract the first token, a regex */
1203 
1204  /* data should be either MUTT_SPAM or MUTT_NOSPAM. MUTT_SPAM is for spam commands. */
1205  if (data == MUTT_SPAM)
1206  {
1207  /* If there's a second parameter, it's a template for the spam tag. */
1208  if (MoreArgs(s))
1209  {
1211 
1212  /* Add to the spam list. */
1213  if (mutt_replacelist_add(&SpamList, buf->data, templ.data, err) != 0)
1214  {
1215  FREE(&templ.data);
1216  return MUTT_CMD_ERROR;
1217  }
1218  FREE(&templ.data);
1219  }
1220  /* If not, try to remove from the nospam list. */
1221  else
1222  {
1224  }
1225 
1226  return MUTT_CMD_SUCCESS;
1227  }
1228  /* MUTT_NOSPAM is for nospam commands. */
1229  else if (data == MUTT_NOSPAM)
1230  {
1231  /* nospam only ever has one parameter. */
1232 
1233  /* "*" is a special case. */
1234  if (mutt_str_equal(buf->data, "*"))
1235  {
1238  return MUTT_CMD_SUCCESS;
1239  }
1240 
1241  /* If it's on the spam list, just remove it. */
1242  if (mutt_replacelist_remove(&SpamList, buf->data) != 0)
1243  return MUTT_CMD_SUCCESS;
1244 
1245  /* Otherwise, add it to the nospam list. */
1246  if (mutt_regexlist_add(&NoSpamList, buf->data, REG_ICASE, err) != 0)
1247  return MUTT_CMD_ERROR;
1248 
1249  return MUTT_CMD_SUCCESS;
1250  }
1251 
1252  /* This should not happen. */
1253  mutt_buffer_strcpy(err, "This is no good at all.");
1254  return MUTT_CMD_ERROR;
1255 }
struct Buffer * mutt_buffer_init(struct Buffer *buf)
Initialise a new Buffer.
Definition: buffer.c:46
struct ReplaceList SpamList
List of regexes and patterns to match spam emails.
Definition: globals.c:34
struct RegexList NoSpamList
List of regexes to whitelist non-spam emails.
Definition: globals.c:33
int mutt_replacelist_remove(struct ReplaceList *rl, const char *pat)
Remove a pattern from a list.
Definition: regex.c:579
void mutt_regexlist_free(struct RegexList *rl)
Free a RegexList object.
Definition: regex.c:173
void mutt_replacelist_free(struct ReplaceList *rl)
Free a ReplaceList object.
Definition: regex.c:462
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:265
#define MUTT_NOSPAM
Definition: mutt.h:111
#define MUTT_SPAM
Definition: mutt.h:110

◆ parse_stailq()

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

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

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

Definition at line 142 of file command_parse.c.

1264 {
1265  do
1266  {
1268  add_to_stailq((struct ListHead *) data, buf->data);
1269  } while (MoreArgs(s));
1270 
1271  return MUTT_CMD_SUCCESS;
1272 }

◆ parse_subscribe()

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

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

Definition at line 142 of file command_parse.c.

1279 {
1280  struct GroupList gl = STAILQ_HEAD_INITIALIZER(gl);
1281 
1282  do
1283  {
1285 
1286  if (parse_grouplist(&gl, buf, s, err) == -1)
1287  goto bail;
1288 
1291 
1292  if (mutt_regexlist_add(&MailLists, buf->data, REG_ICASE, err) != 0)
1293  goto bail;
1294  if (mutt_regexlist_add(&SubscribedLists, buf->data, REG_ICASE, err) != 0)
1295  goto bail;
1296  if (mutt_grouplist_add_regex(&gl, buf->data, REG_ICASE, err) != 0)
1297  goto bail;
1298  } while (MoreArgs(s));
1299 
1301  return MUTT_CMD_SUCCESS;
1302 
1303 bail:
1305  return MUTT_CMD_ERROR;
1306 }
struct RegexList SubscribedLists
List of regexes to match subscribed mailing lists.
Definition: globals.c:43
struct RegexList UnSubscribedLists
List of regexes to blacklist false matches in SubscribedLists.
Definition: globals.c:40

◆ parse_subscribe_to()

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

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

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

Definition at line 142 of file command_parse.c.

1318 {
1319  if (!buf || !s || !err)
1320  return MUTT_CMD_ERROR;
1321 
1322  mutt_buffer_reset(err);
1323 
1324  if (MoreArgs(s))
1325  {
1327 
1328  if (MoreArgs(s))
1329  {
1330  mutt_buffer_printf(err, _("%s: too many arguments"), "subscribe-to");
1331  return MUTT_CMD_WARNING;
1332  }
1333 
1334  if (buf->data && (*buf->data != '\0'))
1335  {
1336  /* Expand and subscribe */
1337  if (imap_subscribe(mutt_expand_path(buf->data, buf->dsize), true) == 0)
1338  {
1339  mutt_message(_("Subscribed to %s"), buf->data);
1340  return MUTT_CMD_SUCCESS;
1341  }
1342 
1343  mutt_buffer_printf(err, _("Could not subscribe to %s"), buf->data);
1344  return MUTT_CMD_ERROR;
1345  }
1346 
1347  mutt_debug(LL_DEBUG1, "Corrupted buffer");
1348  return MUTT_CMD_ERROR;
1349  }
1350 
1351  mutt_buffer_addstr(err, _("No folder specified"));
1352  return MUTT_CMD_WARNING;
1353 }
int imap_subscribe(char *path, bool subscribe)
Subscribe to a mailbox.
Definition: imap.c:1286
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40

◆ parse_tag_formats()

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

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

Definition at line 142 of file command_parse.c.

1361 {
1362  if (!buf || !s)
1363  return MUTT_CMD_ERROR;
1364 
1365  char *tmp = NULL;
1366 
1367  while (MoreArgs(s))
1368  {
1369  char *tag = NULL, *format = NULL;
1370 
1372  if (buf->data && (*buf->data != '\0'))
1373  tag = mutt_str_dup(buf->data);
1374  else
1375  continue;
1376 
1378  format = mutt_str_dup(buf->data);
1379 
1380  /* avoid duplicates */
1381  tmp = mutt_hash_find(TagFormats, format);
1382  if (tmp)
1383  {
1384  mutt_debug(LL_DEBUG3, "tag format '%s' already registered as '%s'\n", format, tmp);
1385  FREE(&tag);
1386  FREE(&format);
1387  continue;
1388  }
1389 
1390  mutt_hash_insert(TagFormats, format, tag);
1391  }
1392  return MUTT_CMD_SUCCESS;
1393 }
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:335
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:362
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
struct HashTable * TagFormats
Hash Table of tag-formats (tag -> format string)
Definition: mutt_globals.h:61

◆ parse_tag_transforms()

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

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

Definition at line 142 of file command_parse.c.

1400 {
1401  if (!buf || !s)
1402  return MUTT_CMD_ERROR;
1403 
1404  char *tmp = NULL;
1405 
1406  while (MoreArgs(s))
1407  {
1408  char *tag = NULL, *transform = NULL;
1409 
1411  if (buf->data && (*buf->data != '\0'))
1412  tag = mutt_str_dup(buf->data);
1413  else
1414  continue;
1415 
1417  transform = mutt_str_dup(buf->data);
1418 
1419  /* avoid duplicates */
1420  tmp = mutt_hash_find(TagTransforms, tag);
1421  if (tmp)
1422  {
1423  mutt_debug(LL_DEBUG3, "tag transform '%s' already registered as '%s'\n", tag, tmp);
1424  FREE(&tag);
1425  FREE(&transform);
1426  continue;
1427  }
1428 
1429  mutt_hash_insert(TagTransforms, tag, transform);
1430  }
1431  return MUTT_CMD_SUCCESS;
1432 }
struct HashTable * TagTransforms
Lookup table of alternative tag names.
Definition: tags.c:37

◆ parse_unignore()

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

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

Definition at line 142 of file command_parse.c.

1439 {
1440  do
1441  {
1443 
1444  /* don't add "*" to the unignore list */
1445  if (strcmp(buf->data, "*") != 0)
1446  add_to_stailq(&UnIgnore, buf->data);
1447 
1448  remove_from_stailq(&Ignore, buf->data);
1449  } while (MoreArgs(s));
1450 
1451  return MUTT_CMD_SUCCESS;
1452 }

◆ parse_unlists()

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

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

Definition at line 142 of file command_parse.c.

1459 {
1461  do
1462  {
1466 
1467  if (!mutt_str_equal(buf->data, "*") &&
1468  (mutt_regexlist_add(&UnMailLists, buf->data, REG_ICASE, err) != 0))
1469  {
1470  return MUTT_CMD_ERROR;
1471  }
1472  } while (MoreArgs(s));
1473 
1474  return MUTT_CMD_SUCCESS;
1475 }
struct HashTable * AutoSubscribeCache
Hash Table of auto-subscribed mailing lists.
Definition: globals.c:38
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:457

◆ parse_unmailboxes()

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

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

This is also used by 'unvirtual-mailboxes'

Definition at line 1504 of file command_parse.c.

1524 {
1525  while (MoreArgs(s))
1526  {
1528 
1529  if (mutt_str_equal(buf->data, "*"))
1530  {
1532  return MUTT_CMD_SUCCESS;
1533  }
1534 
1536 
1537  struct Account *a = NULL;
1538  TAILQ_FOREACH(a, &NeoMutt->accounts, entries)
1539  {
1540  struct Mailbox *m = mx_mbox_find(a, mutt_buffer_string(buf));
1541  if (m)
1542  {
1543  do_unmailboxes(m);
1544  break;
1545  }
1546  }
1547  }
1548  return MUTT_CMD_SUCCESS;
1549 }
static void do_unmailboxes_star(void)
Remove all Mailboxes from the Sidebar/notifications.
static void do_unmailboxes(struct Mailbox *m)
Remove a Mailbox from the Sidebar/notifications.
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:40

◆ parse_unmy_hdr()

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

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

Definition at line 1504 of file command_parse.c.

1556 {
1557  struct ListNode *np = NULL, *tmp = NULL;
1558  size_t l;
1559 
1560  do
1561  {
1563  if (mutt_str_equal("*", buf->data))
1564  {
1565  /* Clear all headers, send a notification for each header */
1566  STAILQ_FOREACH(np, &UserHeader, entries)
1567  {
1568  mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1569  struct EventHeader ev_h = { np->data };
1571  }
1573  continue;
1574  }
1575 
1576  l = mutt_str_len(buf->data);
1577  if (buf->data[l - 1] == ':')
1578  l--;
1579 
1580  STAILQ_FOREACH_SAFE(np, &UserHeader, entries, tmp)
1581  {
1582  if (mutt_istrn_equal(buf->data, np->data, l) && (np->data[l] == ':'))
1583  {
1584  mutt_debug(LL_NOTIFY, "NT_HEADER_DELETE: %s\n", np->data);
1585  struct EventHeader ev_h = { np->data };
1587 
1588  header_free(&UserHeader, np);
1589  }
1590  }
1591  } while (MoreArgs(s));
1592  return MUTT_CMD_SUCCESS;
1593 }
void header_free(struct ListHead *hdrlist, struct ListNode *target)
Free and remove a header from a header list.
Definition: email.c:245
@ NT_HEADER_DELETE
Header has been removed.
Definition: email.h:170
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:475
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:432
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
char * data
String.
Definition: list.h:36

◆ parse_unstailq()

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

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

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

Definition at line 1504 of file command_parse.c.

1602 {
1603  do
1604  {
1606  /* Check for deletion of entire list */
1607  if (mutt_str_equal(buf->data, "*"))
1608  {
1609  mutt_list_free((struct ListHead *) data);
1610  break;
1611  }
1612  remove_from_stailq((struct ListHead *) data, buf->data);
1613  } while (MoreArgs(s));
1614 
1615  return MUTT_CMD_SUCCESS;
1616 }

◆ parse_unsubscribe()

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

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

Definition at line 1504 of file command_parse.c.

1623 {
1625  do
1626  {
1629 
1630  if (!mutt_str_equal(buf->data, "*") &&
1631  (mutt_regexlist_add(&UnSubscribedLists, buf->data, REG_ICASE, err) != 0))
1632  {
1633  return MUTT_CMD_ERROR;
1634  }
1635  } while (MoreArgs(s));
1636 
1637  return MUTT_CMD_SUCCESS;
1638 }

◆ parse_unsubscribe_from()

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

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

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

Definition at line 1504 of file command_parse.c.

1650 {
1651  if (!buf || !s || !err)
1652  return MUTT_CMD_ERROR;
1653 
1654  if (MoreArgs(s))
1655  {
1657 
1658  if (MoreArgs(s))
1659  {
1660  mutt_buffer_printf(err, _("%s: too many arguments"), "unsubscribe-from");
1661  return MUTT_CMD_WARNING;
1662  }
1663 
1664  if (buf->data && (*buf->data != '\0'))
1665  {
1666  /* Expand and subscribe */
1667  if (imap_subscribe(mutt_expand_path(buf->data, buf->dsize), false) == 0)
1668  {
1669  mutt_message(_("Unsubscribed from %s"), buf->data);
1670  return MUTT_CMD_SUCCESS;
1671  }
1672 
1673  mutt_buffer_printf(err, _("Could not unsubscribe from %s"), buf->data);
1674  return MUTT_CMD_ERROR;
1675  }
1676 
1677  mutt_debug(LL_DEBUG1, "Corrupted buffer");
1678  return MUTT_CMD_ERROR;
1679  }
1680 
1681  mutt_buffer_addstr(err, _("No folder specified"));
1682  return MUTT_CMD_WARNING;
1683 }

◆ mutt_parse_hook()

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

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

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

Definition at line 74 of file hook.c.

83 {
84  struct Hook *hook = NULL;
85  int rc = MUTT_CMD_ERROR;
86  bool pat_not = false;
87  bool use_regex = true;
88  regex_t *rx = NULL;
89  struct PatternList *pat = NULL;
90  const bool folder_or_mbox = (data & (MUTT_FOLDER_HOOK | MUTT_MBOX_HOOK));
91 
92  struct Buffer *cmd = mutt_buffer_pool_get();
93  struct Buffer *pattern = mutt_buffer_pool_get();
94 
95  if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
96  {
97  if (*s->dptr == '!')
98  {
99  s->dptr++;
100  SKIPWS(s->dptr);
101  pat_not = true;
102  }
103 
105  if (folder_or_mbox &&
106  mutt_str_equal(mutt_buffer_string(pattern), "-noregex"))
107  {
108  use_regex = false;
109  if (!MoreArgs(s))
110  {
111  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
112  rc = MUTT_CMD_WARNING;
113  goto cleanup;
114  }
116  }
117 
118  if (!MoreArgs(s))
119  {
120  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
121  rc = MUTT_CMD_WARNING;
122  goto cleanup;
123  }
124  }
125 
126  mutt_extract_token(cmd, s,
131 
132  if (mutt_buffer_is_empty(cmd))
133  {
134  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
135  rc = MUTT_CMD_WARNING;
136  goto cleanup;
137  }
138 
139  if (MoreArgs(s))
140  {
141  mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
142  rc = MUTT_CMD_WARNING;
143  goto cleanup;
144  }
145 
146  const char *const c_default_hook =
147  cs_subset_string(NeoMutt->sub, "default_hook");
148  if (folder_or_mbox)
149  {
150  /* Accidentally using the ^ mailbox shortcut in the .neomuttrc is a
151  * common mistake */
152  if ((pattern->data[0] == '^') && !CurrentFolder)
153  {
154  mutt_buffer_strcpy(err, _("current mailbox shortcut '^' is unset"));
155  goto cleanup;
156  }
157 
158  struct Buffer *tmp = mutt_buffer_pool_get();
159  mutt_buffer_copy(tmp, pattern);
160  mutt_buffer_expand_path_regex(tmp, use_regex);
161 
162  /* Check for other mailbox shortcuts that expand to the empty string.
163  * This is likely a mistake too */
164  if (mutt_buffer_is_empty(tmp) && !mutt_buffer_is_empty(pattern))
165  {
166  mutt_buffer_strcpy(err, _("mailbox shortcut expanded to empty regex"));
168  goto cleanup;
169  }
170 
171  if (use_regex)
172  {
173  mutt_buffer_copy(pattern, tmp);
174  }
175  else
176  {
178  }
180  }
181 #ifdef USE_COMP_MBOX
183  {
185  {
186  mutt_buffer_strcpy(err, _("badly formatted command string"));
187  goto cleanup;
188  }
189  }
190 #endif
191  else if (c_default_hook && (~data & MUTT_GLOBAL_HOOK) &&
193  (!WithCrypto || !(data & MUTT_CRYPT_HOOK)))
194  {
195  /* At this stage remain only message-hooks, reply-hooks, send-hooks,
196  * send2-hooks, save-hooks, and fcc-hooks: All those allowing full
197  * patterns. If given a simple regex, we expand $default_hook. */
198  mutt_check_simple(pattern, c_default_hook);
199  }
200 
202  {
204  }
205 
206  /* check to make sure that a matching hook doesn't already exist */
207  TAILQ_FOREACH(hook, &Hooks, entries)
208  {
209  if (data & MUTT_GLOBAL_HOOK)
210  {
211  /* Ignore duplicate global hooks */
212  if (mutt_str_equal(hook->command, mutt_buffer_string(cmd)))
213  {
214  rc = MUTT_CMD_SUCCESS;
215  goto cleanup;
216  }
217  }
218  else if ((hook->type == data) && (hook->regex.pat_not == pat_not) &&
220  {
224  {
225  /* these hooks allow multiple commands with the same
226  * pattern, so if we've already seen this pattern/command pair, just
227  * ignore it instead of creating a duplicate */
228  if (mutt_str_equal(hook->command, mutt_buffer_string(cmd)))
229  {
230  rc = MUTT_CMD_SUCCESS;
231  goto cleanup;
232  }
233  }
234  else
235  {
236  /* other hooks only allow one command per pattern, so update the
237  * entry with the new command. this currently does not change the
238  * order of execution of the hooks, which i think is desirable since
239  * a common action to perform is to change the default (.) entry
240  * based upon some other information. */
241  FREE(&hook->command);
242  hook->command = mutt_buffer_strdup(cmd);
243  rc = MUTT_CMD_SUCCESS;
244  goto cleanup;
245  }
246  }
247  }
248 
250  {
251  /* These are managed separately by the charset code */
253  if (mutt_ch_lookup_add(type, mutt_buffer_string(pattern), mutt_buffer_string(cmd), err))
254  rc = MUTT_CMD_SUCCESS;
255  goto cleanup;
256  }
259  {
260  PatternCompFlags comp_flags;
261 
262  if (data & (MUTT_SEND2_HOOK))
263  comp_flags = MUTT_PC_SEND_MODE_SEARCH;
264  else if (data & (MUTT_SEND_HOOK | MUTT_FCC_HOOK))
265  comp_flags = MUTT_PC_NO_FLAGS;
266  else
267  comp_flags = MUTT_PC_FULL_MSG;
268 
270  mutt_buffer_string(pattern), comp_flags, err);
271  if (!pat)
272  goto cleanup;
273  }
274  else if (~data & MUTT_GLOBAL_HOOK) /* NOT a global hook */
275  {
276  /* Hooks not allowing full patterns: Check syntax of regex */
277  rx = mutt_mem_malloc(sizeof(regex_t));
278  int rc2 = REG_COMP(rx, NONULL(mutt_buffer_string(pattern)),
279  ((data & MUTT_CRYPT_HOOK) ? REG_ICASE : 0));
280  if (rc2 != 0)
281  {
282  regerror(rc2, rx, err->data, err->dsize);
283  FREE(&rx);
284  goto cleanup;
285  }
286  }
287 
288  hook = mutt_mem_calloc(1, sizeof(struct Hook));
289  hook->type = data;
290  hook->command = mutt_buffer_strdup(cmd);
291  hook->pattern = pat;
292  hook->regex.pattern = mutt_buffer_strdup(pattern);
293  hook->regex.regex = rx;
294  hook->regex.pat_not = pat_not;
295  TAILQ_INSERT_TAIL(&Hooks, hook, entries);
296  rc = MUTT_CMD_SUCCESS;
297 
298 cleanup:
300  mutt_buffer_pool_release(&pattern);
301  return rc;
302 }
struct PatternList * mutt_pattern_comp(struct Mailbox *m, struct Menu *menu, const char *s, PatternCompFlags flags, struct Buffer *err)
Create a Pattern.
Definition: compile.c:1092
int mutt_comp_valid_command(const char *cmd)
Is this command string allowed?
Definition: compress.c:408
struct Mailbox * ctx_mailbox(struct Context *ctx)
Wrapper to get the mailbox in a Context, or NULL.
Definition: context.c:444
int mutt_file_sanitize_regex(struct Buffer *dest, const char *src)
Escape any regex-magic characters in a string.
Definition: file.c:641
static struct HookList Hooks
Definition: hook.c:71
#define MUTT_OPEN_HOOK
open-hook: to read a compressed mailbox
Definition: hook.h:51
#define MUTT_ICONV_HOOK
iconv-hook: create a system charset alias
Definition: hook.h:44
#define MUTT_FOLDER_HOOK
folder-hook: when entering a mailbox
Definition: hook.h:38
#define MUTT_SAVE_HOOK
save-hook: set a default folder when saving an email
Definition: hook.h:42
#define MUTT_SEND_HOOK
send-hook: when composing a new email
Definition: hook.h:40
#define MUTT_FCC_HOOK
fcc-hook: to save outgoing email
Definition: hook.h:41
#define MUTT_CLOSE_HOOK
close-hook: write to a compressed mailbox
Definition: hook.h:53
#define MUTT_ACCOUNT_HOOK
account-hook: when changing between accounts
Definition: hook.h:47
#define MUTT_APPEND_HOOK
append-hook: append to a compressed mailbox
Definition: hook.h:52
#define MUTT_GLOBAL_HOOK
Hooks which don't take a regex.
Definition: hook.h:59
#define MUTT_STARTUP_HOOK
startup-hook: run when starting NeoMutt
Definition: hook.h:57
#define MUTT_SEND2_HOOK
send2-hook: when changing fields in the compose menu
Definition: hook.h:49
#define MUTT_CRYPT_HOOK
crypt-hook: automatically select a PGP/SMIME key
Definition: hook.h:46
#define MUTT_MBOX_HOOK
mbox-hook: move messages after reading them
Definition: hook.h:39
#define MUTT_REPLY_HOOK
reply-hook: when replying to an email
Definition: hook.h:48
#define MUTT_TIMEOUT_HOOK
timeout-hook: run a command periodically
Definition: hook.h:56
#define MUTT_MESSAGE_HOOK
message-hook: run before displaying a message
Definition: hook.h:45
#define MUTT_SHUTDOWN_HOOK
shutdown-hook: run when leaving NeoMutt
Definition: hook.h:58
#define MUTT_CHARSET_HOOK
charset-hook: create a charset alias for malformed emails
Definition: hook.h:43
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
bool mutt_ch_lookup_add(enum LookupType type, const char *pat, const char *replace, struct Buffer *err)
Add a new character set lookup.
Definition: charset.c:496
LookupType
Types of character set lookups.
Definition: charset.h:66
@ MUTT_LOOKUP_ICONV
Character set conversion.
Definition: charset.h:68
@ MUTT_LOOKUP_CHARSET
Alias for another character set.
Definition: charset.h:67
char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:56
void mutt_buffer_expand_path_regex(struct Buffer *buf, bool regex)
Create the canonical path (with regex char escaping)
Definition: muttlib.c:134
#define WithCrypto
Definition: lib.h:113
#define MUTT_PC_SEND_MODE_SEARCH
Allow send-mode body searching.
Definition: lib.h:63
uint8_t PatternCompFlags
Flags for mutt_pattern_comp(), e.g. MUTT_PC_FULL_MSG.
Definition: lib.h:59
#define MUTT_PC_FULL_MSG
Enable body and header matching.
Definition: lib.h:61
void mutt_check_simple(struct Buffer *s, const char *simple)
Convert a simple search into a real request.
Definition: pattern.c:116
#define MUTT_PC_NO_FLAGS
No flags are set.
Definition: lib.h:60
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:54
#define NONULL(x)
Definition: string2.h:37
The "current" mailbox.
Definition: context.h:38
struct Menu * menu
Needed for pattern compilation.
Definition: context.h:45
A list of user hooks.
Definition: hook.c:62
HookFlags type
Hook type.
Definition: hook.c:63
struct PatternList * pattern
Used for fcc,save,send-hook.
Definition: hook.c:66
struct Regex regex
Regular expression.
Definition: hook.c:64
char * command
Filename, command or pattern to execute.
Definition: hook.c:65
char * pattern
printable version
Definition: regex3.h:91
bool pat_not
do not match
Definition: regex3.h:93
regex_t * regex
compiled expression
Definition: regex3.h:92
+ Here is the caller graph for this function:

◆ mutt_parse_idxfmt_hook()

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

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

Definition at line 363 of file hook.c.

373 {
374  enum CommandResult rc = MUTT_CMD_ERROR;
375  bool pat_not = false;
376 
377  struct Buffer *name = mutt_buffer_pool_get();
378  struct Buffer *pattern = mutt_buffer_pool_get();
379  struct Buffer *fmtstring = mutt_buffer_pool_get();
380 
381  if (!IdxFmtHooks)
382  {
385  }
386 
387  if (!MoreArgs(s))
388  {
389  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
390  goto out;
391  }
393  struct HookList *hl = mutt_hash_find(IdxFmtHooks, mutt_buffer_string(name));
394 
395  if (*s->dptr == '!')
396  {
397  s->dptr++;
398  SKIPWS(s->dptr);
399  pat_not = true;
400  }
402 
403  if (!MoreArgs(s))
404  {
405  mutt_buffer_printf(err, _("%s: too few arguments"), buf->data);
406  goto out;
407  }
409 
410  if (MoreArgs(s))
411  {
412  mutt_buffer_printf(err, _("%s: too many arguments"), buf->data);
413  goto out;
414  }
415 
416  const char *const c_default_hook =
417  cs_subset_string(NeoMutt->sub, "default_hook");
418  if (c_default_hook)
419  mutt_check_simple(pattern, c_default_hook);
420 
421  /* check to make sure that a matching hook doesn't already exist */
422  struct Hook *hook = NULL;
423  if (hl)
424  {
425  TAILQ_FOREACH(hook, hl, entries)
426  {
427  if ((hook->regex.pat_not == pat_not) &&
429  {
430  mutt_str_replace(&hook->command, mutt_buffer_string(fmtstring));
431  rc = MUTT_CMD_SUCCESS;
432  goto out;
433  }
434  }
435  }
436 
437  /* MUTT_PC_PATTERN_DYNAMIC sets so that date ranges are regenerated during
438  * matching. This of course is slower, but index-format-hook is commonly
439  * used for date ranges, and they need to be evaluated relative to "now", not
440  * the hook compilation time. */
441  struct PatternList *pat =
443  mutt_buffer_string(pattern),
445  if (!pat)
446  goto out;
447 
448  hook = mutt_mem_calloc(1, sizeof(struct Hook));
449  hook->type = MUTT_IDXFMTHOOK;
450  hook->command = mutt_buffer_strdup(fmtstring);
451  hook->pattern = pat;
452  hook->regex.pattern = mutt_buffer_strdup(pattern);
453  hook->regex.regex = NULL;
454  hook->regex.pat_not = pat_not;
455 
456  if (!hl)
457  {
458  hl = mutt_mem_calloc(1, sizeof(*hl));
459  TAILQ_INIT(hl);
461  }
462 
463  TAILQ_INSERT_TAIL(hl, hook, entries);
464  rc = MUTT_CMD_SUCCESS;
465 
466 out:
468  mutt_buffer_pool_release(&pattern);
469  mutt_buffer_pool_release(&fmtstring);
470 
471  return rc;
472 }
static void idxfmt_hashelem_free(int type, void *obj, intptr_t data)
Delete an index-format-hook from the Hash Table - Implements hash_hdata_free_t -.
Definition: hook.c:345
struct HashTable * mutt_hash_new(size_t num_elems, HashFlags flags)
Create a new Hash Table (with string keys)
Definition: hash.c:259
void mutt_hash_set_destructor(struct HashTable *table, hash_hdata_free_t fn, intptr_t fn_data)
Set the destructor for a Hash Table.
Definition: hash.c:301
#define MUTT_HASH_STRDUP_KEYS
make a copy of the keys
Definition: hash.h:111
static struct HashTable * IdxFmtHooks
Definition: hook.c:73
#define MUTT_IDXFMTHOOK
index-format-hook: customise the format of the index
Definition: hook.h:55
#define MUTT_PC_PATTERN_DYNAMIC
Enable runtime date range evaluation.
Definition: lib.h:62
#define TAILQ_INIT(head)
Definition: queue.h:765
+ Here is the caller graph for this function:

◆ mutt_parse_unhook()

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

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

Definition at line 363 of file hook.c.

479 {
480  while (MoreArgs(s))
481  {
483  if (mutt_str_equal("*", buf->data))
484  {
486  {
487  mutt_buffer_printf(err, "%s", _("unhook: Can't do unhook * from within a hook"));
488  return MUTT_CMD_WARNING;
489  }
493  }
494  else
495  {
496  HookFlags type = mutt_get_hook_type(buf->data);
497 
498  if (type == MUTT_HOOK_NO_FLAGS)
499  {
500  mutt_buffer_printf(err, _("unhook: unknown hook type: %s"), buf->data);
501  return MUTT_CMD_ERROR;
502  }
503  if (type & (MUTT_CHARSET_HOOK | MUTT_ICONV_HOOK))
504  {
506  return MUTT_CMD_SUCCESS;
507  }
508  if (current_hook_type == type)
509  {
510  mutt_buffer_printf(err, _("unhook: Can't delete a %s from within a %s"),
511  buf->data, buf->data);
512  return MUTT_CMD_WARNING;
513  }
514  if (type == MUTT_IDXFMTHOOK)
516  else
517  mutt_delete_hooks(type);
518  }
519  }
520  return MUTT_CMD_SUCCESS;
521 }
void mutt_delete_hooks(HookFlags type)
Delete matching hooks.
Definition: hook.c:327
static void delete_idxfmt_hooks(void)
Delete all the index-format-hooks.
Definition: hook.c:363
static HookFlags current_hook_type
Definition: hook.c:74
uint32_t HookFlags
Flags for mutt_parse_hook(), e.g. MUTT_FOLDER_HOOK.
Definition: hook.h:34
#define MUTT_HOOK_NO_FLAGS
No flags are set.
Definition: hook.h:37
HookFlags mutt_get_hook_type(const char *name)
Find a hook by name.
Definition: init.c:698
void mutt_ch_lookup_remove(void)
Remove all the character set lookups.
Definition: charset.c:528

◆ mutt_parse_push()

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

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

Definition at line 1132 of file keymap.c.

1190 {
1192  if (MoreArgs(s))
1193  {
1194  mutt_buffer_printf(err, _("%s: too many arguments"), "push");
1195  return MUTT_CMD_ERROR;
1196  }
1197 
1199  return MUTT_CMD_SUCCESS;
1200 }
void mutt_push_macro_event(int ch, int op)
Add the character/operation to the macro buffer.
Definition: curs_lib.c:625
static void generic_tokenize_push_string(char *s, void(*generic_push)(int, int))
Parse and queue a 'push' command.
Definition: keymap.c:528
#define MUTT_TOKEN_CONDENSE
^(char) to control chars (macros)
Definition: mutt.h:68

◆ mutt_parse_bind()

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

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

bind menu-name <key_sequence> function-name

Definition at line 1301 of file keymap.c.

1353 {
1354  const struct Binding *bindings = NULL;
1355  enum MenuType mtypes[MenuNamesLen];
1356  int num_menus = 0;
1357  enum CommandResult rc = MUTT_CMD_SUCCESS;
1358 
1359  char *key = parse_keymap(mtypes, s, mutt_array_size(mtypes), &num_menus, err, true);
1360  if (!key)
1361  return MUTT_CMD_ERROR;
1362 
1363  /* function to execute */
1365  if (MoreArgs(s))
1366  {
1367  mutt_buffer_printf(err, _("%s: too many arguments"), "bind");
1368  rc = MUTT_CMD_ERROR;
1369  }
1370  else if (mutt_istr_equal("noop", buf->data))
1371  {
1372  for (int i = 0; i < num_menus; i++)
1373  {
1374  km_bindkey(key, mtypes[i], OP_NULL); /* the 'unbind' command */
1375  bindings = km_get_table(mtypes[i]);
1376  if (bindings)
1377  {
1378  char keystr[32] = { 0 };
1379  km_expand_key_string(key, keystr, sizeof(keystr));
1380  const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1381  mutt_debug(LL_NOTIFY, "NT_BINDING_DELETE: %s %s\n", mname, keystr);
1382 
1383  int op = get_op(OpGeneric, buf->data, mutt_str_len(buf->data));
1384  struct EventBinding ev_b = { mtypes[i], key, op };
1386  }
1387  }
1388  }
1389  else
1390  {
1391  for (int i = 0; i < num_menus; i++)
1392  {
1393  /* The pager and editor menus don't use the generic map,
1394  * however for other menus try generic first. */
1395  if ((mtypes[i] != MENU_PAGER) && (mtypes[i] != MENU_EDITOR) && (mtypes[i] != MENU_GENERIC))
1396  {
1397  rc = try_bind(key, mtypes[i], buf->data, OpGeneric, err);
1398  if (rc == MUTT_CMD_SUCCESS)
1399  {
1400  char keystr[32] = { 0 };
1401  km_expand_key_string(key, keystr, sizeof(keystr));
1402  const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1403  mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, keystr);
1404 
1405  int op = get_op(OpGeneric, buf->data, mutt_str_len(buf->data));
1406  struct EventBinding ev_b = { mtypes[i], key, op };
1408  continue;
1409  }
1410  if (rc == MUTT_CMD_WARNING)
1411  break;
1412  }
1413 
1414  /* Clear any error message, we're going to try again */
1415  err->data[0] = '\0';
1416  bindings = km_get_table(mtypes[i]);
1417  if (bindings)
1418  {
1419  rc = try_bind(key, mtypes[i], buf->data, bindings, err);
1420  if (rc == MUTT_CMD_SUCCESS)
1421  {
1422  char keystr[32] = { 0 };
1423  km_expand_key_string(key, keystr, sizeof(keystr));
1424  const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1425  mutt_debug(LL_NOTIFY, "NT_BINDING_NEW: %s %s\n", mname, keystr);
1426 
1427  int op = get_op(bindings, buf->data, mutt_str_len(buf->data));
1428  struct EventBinding ev_b = { mtypes[i], key, op };
1430  continue;
1431  }
1432  }
1433  }
1434  }
1435  FREE(&key);
1436  return rc;
1437 }
const struct Binding OpGeneric[]
Key bindings for the generic menu.
Definition: functions.c:53
static int km_expand_key_string(char *str, char *buf, size_t buflen)
Get a human-readable key string.
Definition: keymap.c:885
static int get_op(const struct Binding *bindings, const char *start, size_t len)
Get the function by its name.
Definition: keymap.c:485
const struct Binding * km_get_table(enum MenuType mtype)
Lookup a menu's keybindings.
Definition: keymap.c:1301
static enum CommandResult km_bindkey(const char *s, enum MenuType mtype, int op)
Bind a key in a Menu to an operation.
Definition: keymap.c:473
static char * parse_keymap(enum MenuType *mtypes, struct Buffer *s, int max_menus, int *num_menus, struct Buffer *err, bool bind)
Parse a user-config key binding.
Definition: keymap.c:1216
static enum CommandResult try_bind(char *key, enum MenuType mtype, char *func, const struct Binding *bindings, struct Buffer *err)
Try to make a key binding.
Definition: keymap.c:1278
@ NT_BINDING_DELETE
Key binding has been deleted.
Definition: keymap.h:118
@ NT_BINDING_ADD
Key binding has been added.
Definition: keymap.h:117
const char * mutt_map_get_name(int val, const struct Mapping *map)
Lookup a string for a constant.
Definition: mapping.c:42
#define mutt_array_size(x)
Definition: memory.h:33
@ NT_BINDING
Key binding has changed, NotifyBinding, EventBinding.
Definition: notify_type.h:38
Mapping between a user key and a function.
Definition: keymap.h:92
int op
function id number
Definition: keymap.h:94
A key binding Event.
Definition: keymap.h:102
const char * key
Key string being bound (for new bind/macro)
Definition: keymap.h:104
int op
Operation the key's bound to (for bind), e.g. OP_DELETE.
Definition: keymap.h:105
const int MenuNamesLen
Definition: type.c:56
const struct Mapping MenuNames[]
Menu name lookup table.
Definition: type.c:31
MenuType
Types of GUI selections.
Definition: type.h:36
@ MENU_GENERIC
Generic selection list.
Definition: type.h:45
@ MENU_PAGER
Pager pager (email viewer)
Definition: type.h:54
@ MENU_EDITOR
Text entry area.
Definition: type.h:43

◆ mutt_parse_unbind()

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

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

Command unbinds:

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

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

Definition at line 1476 of file keymap.c.

1502 {
1503  bool menu_matches[MENU_MAX] = { 0 };
1504  bool all_keys = false;
1505  char *key = NULL;
1506 
1508  if (mutt_str_equal(buf->data, "*"))
1509  {
1510  for (enum MenuType i = 0; i < MENU_MAX; i++)
1511  menu_matches[i] = true;
1512  }
1513  else
1514  parse_menu(menu_matches, buf->data, err);
1515 
1516  if (MoreArgs(s))
1517  {
1519  key = buf->data;
1520  }
1521  else
1522  all_keys = true;
1523 
1524  if (MoreArgs(s))
1525  {
1526  const char *cmd = (data & MUTT_UNMACRO) ? "unmacro" : "unbind";
1527 
1528  mutt_buffer_printf(err, _("%s: too many arguments"), cmd);
1529  return MUTT_CMD_ERROR;
1530  }
1531 
1532  for (enum MenuType i = 0; i < MENU_MAX; i++)
1533  {
1534  if (!menu_matches[i])
1535  continue;
1536  if (all_keys)
1537  {
1538  km_unbind_all(&Keymaps[i], data);
1539  km_bindkey("<enter>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
1540  km_bindkey("<return>", MENU_GENERIC, OP_GENERIC_SELECT_ENTRY);
1541  km_bindkey("<enter>", MENU_MAIN, OP_DISPLAY_MESSAGE);
1542  km_bindkey("<return>", MENU_MAIN, OP_DISPLAY_MESSAGE);
1543  km_bindkey("<backspace>", MENU_EDITOR, OP_EDITOR_BACKSPACE);
1544  km_bindkey("\177", MENU_EDITOR, OP_EDITOR_BACKSPACE);
1545  km_bindkey(":", MENU_GENERIC, OP_ENTER_COMMAND);
1546  km_bindkey(":", MENU_PAGER, OP_ENTER_COMMAND);
1547  if (i != MENU_EDITOR)
1548  {
1549  km_bindkey("?", i, OP_HELP);
1550  km_bindkey("q", i, OP_EXIT);
1551  }
1552 
1553  const char *mname = mutt_map_get_name(i, MenuNames);
1554  mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE_ALL: %s\n", mname);
1555 
1556  struct EventBinding ev_b = { i, NULL, OP_NULL };
1559  &ev_b);
1560  }
1561  else
1562  {
1563  char keystr[32] = { 0 };
1564  km_expand_key_string(key, keystr, sizeof(keystr));
1565  const char *mname = mutt_map_get_name(i, MenuNames);
1566  mutt_debug(LL_NOTIFY, "NT_MACRO_DELETE: %s %s\n", mname, keystr);
1567 
1568  km_bindkey(key, i, OP_NULL);
1569  struct EventBinding ev_b = { i, key, OP_NULL };
1571  (data & MUTT_UNMACRO) ? NT_MACRO_DELETE : NT_BINDING_DELETE, &ev_b);
1572  }
1573  }
1574 
1575  return MUTT_CMD_SUCCESS;
1576 }
static void * parse_menu(bool *menus, char *s, struct Buffer *err)
Parse menu-names into an array.
Definition: keymap.c:1447
static void km_unbind_all(struct KeymapList *km_list, unsigned long mode)
Free all the keys in the supplied Keymap.
Definition: keymap.c:1476
struct KeymapList Keymaps[MENU_MAX]
Array of Keymap keybindings, one for each Menu.
Definition: keymap.c:120
@ NT_MACRO_DELETE
Key macro has been deleted.
Definition: keymap.h:122
@ NT_MACRO_DELETE_ALL
All key macros have been deleted.
Definition: keymap.h:123
@ NT_BINDING_DELETE_ALL
All key bindings have been deleted.
Definition: keymap.h:119
#define MUTT_UNMACRO
Definition: keymap.h:34
@ MENU_MAIN
Index panel (list of emails)
Definition: type.h:50
@ MENU_MAX
Definition: type.h:59

◆ mutt_parse_macro()

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

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

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

Definition at line 1476 of file keymap.c.

1585 {
1586  enum MenuType mtypes[MenuNamesLen];
1587  int num_menus = 0;
1588  enum CommandResult rc = MUTT_CMD_ERROR;
1589 
1590  char *key = parse_keymap(mtypes, s, mutt_array_size(mtypes), &num_menus, err, false);
1591  if (!key)
1592  return MUTT_CMD_ERROR;
1593 
1595  /* make sure the macro sequence is not an empty string */
1596  if (buf->data[0] == '\0')
1597  {
1598  mutt_buffer_strcpy(err, _("macro: empty key sequence"));
1599  }
1600  else
1601  {
1602  if (MoreArgs(s))
1603  {
1604  char *seq = mutt_str_dup(buf->data);
1606 
1607  if (MoreArgs(s))
1608  {
1609  mutt_buffer_printf(err, _("%s: too many arguments"), "macro");
1610  }
1611  else
1612  {
1613  for (int i = 0; i < num_menus; i++)
1614  {
1615  rc = km_bind(key, mtypes[i], OP_MACRO, seq, buf->data);
1616  if (rc == MUTT_CMD_SUCCESS)
1617  {
1618  char keystr[32] = { 0 };
1619  km_expand_key_string(key, keystr, sizeof(keystr));
1620  const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1621  mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, keystr);
1622 
1623  struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
1625  continue;
1626  }
1627  }
1628  }
1629 
1630  FREE(&seq);
1631  }
1632  else
1633  {
1634  for (int i = 0; i < num_menus; i++)
1635  {
1636  rc = km_bind(key, mtypes[i], OP_MACRO, buf->data, NULL);
1637  if (rc == MUTT_CMD_SUCCESS)
1638  {
1639  char keystr[32] = { 0 };
1640  km_expand_key_string(key, keystr, sizeof(keystr));
1641  const char *mname = mutt_map_get_name(mtypes[i], MenuNames);
1642  mutt_debug(LL_NOTIFY, "NT_MACRO_NEW: %s %s\n", mname, keystr);
1643 
1644  struct EventBinding ev_b = { mtypes[i], key, OP_MACRO };
1646  continue;
1647  }
1648  }
1649  }
1650  }
1651  FREE(&key);
1652  return rc;
1653 }
enum CommandResult km_bind(char *s, enum MenuType mtype, int op, char *macro, char *desc)
Bind a key to a macro.
Definition: keymap.c:447
@ NT_MACRO_ADD
Key macro has been added.
Definition: keymap.h:121

◆ mutt_parse_exec()

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

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

Definition at line 1476 of file keymap.c.

1660 {
1661  int ops[128];
1662  int nops = 0;
1663  const struct Binding *bindings = NULL;
1664  char *function = NULL;
1665 
1666  if (!MoreArgs(s))
1667  {
1668  mutt_buffer_strcpy(err, _("exec: no arguments"));
1669  return MUTT_CMD_ERROR;
1670  }
1671 
1672  do
1673  {
1675  function = buf->data;
1676 
1677  const enum MenuType mtype = menu_get_current_type();
1678  bindings = km_get_table(mtype);
1679  if (!bindings && (mtype != MENU_PAGER))
1680  bindings = OpGeneric;
1681 
1682  ops[nops] = get_op(bindings, function, mutt_str_len(function));
1683  if ((ops[nops] == OP_NULL) && (mtype != MENU_PAGER))
1684  ops[nops] = get_op(OpGeneric, function, mutt_str_len(function));
1685 
1686  if (ops[nops] == OP_NULL)
1687  {
1688  mutt_flushinp();
1689  mutt_error(_("%s: no such function"), function);
1690  return MUTT_CMD_ERROR;
1691  }
1692  nops++;
1693  } while (MoreArgs(s) && nops < mutt_array_size(ops));
1694 
1695  while (nops)
1696  mutt_push_macro_event(0, ops[--nops]);
1697 
1698  return MUTT_CMD_SUCCESS;
1699 }
void mutt_flushinp(void)
Empty all the keyboard buffers.
Definition: curs_lib.c:673
enum MenuType menu_get_current_type(void)
Get the type of the current Window.
Definition: menu.c:531

◆ mutt_lua_parse()

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

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

Definition at line 469 of file mutt_lua.c.

479 {
480  lua_init(&LuaState);
481  mutt_debug(LL_DEBUG2, " * mutt_lua_parse(%s)\n", buf->data);
482 
483  if (luaL_dostring(LuaState, s->dptr))
484  {
485  mutt_debug(LL_DEBUG2, " * %s -> failure\n", s->dptr);
486  mutt_buffer_printf(err, "%s: %s", s->dptr, lua_tostring(LuaState, -1));
487  /* pop error message from the stack */
488  lua_pop(LuaState, 1);
489  return MUTT_CMD_ERROR;
490  }
491  mutt_debug(LL_DEBUG2, " * %s -> success\n", s->dptr);
492  mutt_buffer_reset(s); // Clear the rest of the line
493  return MUTT_CMD_SUCCESS;
494 }
@ LL_DEBUG2
Log at debug level 2.
Definition: logging.h:41
static bool lua_init(lua_State **l)
Initialise a Lua State.
Definition: mutt_lua.c:441
lua_State * LuaState
Global Lua State.
Definition: mutt_lua.c:56

◆ mutt_lua_source_file()

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

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

Definition at line 469 of file mutt_lua.c.

501 {
502  mutt_debug(LL_DEBUG2, " * mutt_lua_source()\n");
503 
504  lua_init(&LuaState);
505 
506  char path[PATH_MAX];
507 
508  if (mutt_extract_token(buf, s, MUTT_TOKEN_NO_FLAGS) != 0)
509  {
510  mutt_buffer_printf(err, _("source: error at %s"), s->dptr);
511  return MUTT_CMD_ERROR;
512  }
513  if (MoreArgs(s))
514  {
515  mutt_buffer_printf(err, _("%s: too many arguments"), "source");
516  return MUTT_CMD_WARNING;
517  }
518  mutt_str_copy(path, buf->data, sizeof(path));
519  mutt_expand_path(path, sizeof(path));
520 
521  if (luaL_dofile(LuaState, path))
522  {
523  mutt_error(_("Couldn't source lua source: %s"), lua_tostring(LuaState, -1));
524  lua_pop(LuaState, 1);
525  return MUTT_CMD_ERROR;
526  }
527  return MUTT_CMD_SUCCESS;
528 }

◆ mutt_parse_score()

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

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

Definition at line 64 of file score.c.

89 {
90  struct Score *ptr = NULL, *last = NULL;
91  char *pattern = NULL, *pc = NULL;
92 
94  if (!MoreArgs(s))
95  {
96  mutt_buffer_printf(err, _("%s: too few arguments"), "score");
97  return MUTT_CMD_WARNING;
98  }
99  pattern = mutt_buffer_strdup(buf);
101  if (MoreArgs(s))
102  {
103  FREE(&pattern);
104  mutt_buffer_printf(err, _("%s: too many arguments"), "score");
105  return MUTT_CMD_WARNING;
106  }
107 
108  /* look for an existing entry and update the value, else add it to the end
109  * of the list */
110  for (ptr = ScoreList, last = NULL; ptr; last = ptr, ptr = ptr->next)
111  if (mutt_str_equal(pattern, ptr->str))
112  break;
113  if (!ptr)
114  {
115  struct PatternList *pat =
117  pattern, MUTT_PC_NO_FLAGS, err);
118  if (!pat)
119  {
120  FREE(&pattern);
121  return MUTT_CMD_ERROR;
122  }
123  ptr = mutt_mem_calloc(1, sizeof(struct Score));
124  if (last)
125  last->next = ptr;
126  else
127  ScoreList = ptr;
128  ptr->pat = pat;
129  ptr->str = pattern;
130  }
131  else
132  {
133  /* 'buf' arg was cleared and 'pattern' holds the only reference;
134  * as here 'ptr' != NULL -> update the value only in which case
135  * ptr->str already has the string, so pattern should be freed. */
136  FREE(&pattern);
137  }
138  pc = buf->data;
139  if (*pc == '=')
140  {
141  ptr->exact = true;
142  pc++;
143  }
144  if (!mutt_str_atoi_full(pc, &ptr->val))
145  {
146  FREE(&pattern);
147  mutt_buffer_strcpy(err, _("Error: score: invalid number"));
148  return MUTT_CMD_ERROR;
149  }
150  OptNeedRescore = true;
151  return MUTT_CMD_SUCCESS;
152 }
bool OptNeedRescore
(pseudo) set when the 'score' command is used
Definition: options.h:47
static struct Score * ScoreList
Definition: score.c:58
Scoring rule for email.
Definition: score.c:50
struct PatternList * pat
Definition: score.c:52
struct Score * next
Definition: score.c:55

◆ mutt_parse_unscore()

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

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

Definition at line 160 of file score.c.

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

◆ sb_parse_whitelist()

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

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

Definition at line 1 of file commands.c.

44 {
45  struct Buffer *path = mutt_buffer_pool_get();
46 
47  do
48  {
52  } while (MoreArgs(s));
54 
55  return MUTT_CMD_SUCCESS;
56 }
struct ListHead SidebarWhitelist
List of mailboxes to always display in the sidebar.
Definition: sidebar.c:44
+ Here is the caller graph for this function:

◆ sb_parse_unwhitelist()

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

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

Definition at line 1 of file commands.c.

63 {
64  struct Buffer *path = mutt_buffer_pool_get();
65 
66  do
67  {
69  /* Check for deletion of entire list */
70  if (mutt_str_equal(mutt_buffer_string(path), "*"))
71  {
73  break;
74  }
77  } while (MoreArgs(s));
79 
80  return MUTT_CMD_SUCCESS;
81 }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_unreplace_list()

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

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

Definition at line 54 of file subjectrx.c.

68 {
69  /* First token is a regex. */
70  if (!MoreArgs(s))
71  {
72  mutt_buffer_printf(err, _("%s: too few arguments"), "unsubjectrx");
73  return MUTT_CMD_WARNING;
74  }
75 
77 
78  /* "*" is a special case. */
79  if (mutt_str_equal(buf->data, "*"))
80  {
82  return MUTT_CMD_SUCCESS;
83  }
84 
85  mutt_replacelist_remove(list, buf->data);
86  return MUTT_CMD_SUCCESS;
87 }

◆ parse_replace_list()

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

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

Definition at line 54 of file subjectrx.c.

94 {
95  struct Buffer templ = mutt_buffer_make(0);
96 
97  /* First token is a regex. */
98  if (!MoreArgs(s))
99  {
100  mutt_buffer_printf(err, _("%s: too few arguments"), "subjectrx");
101  return MUTT_CMD_WARNING;
102  }
104 
105  /* Second token is a replacement template */
106  if (!MoreArgs(s))
107  {
108  mutt_buffer_printf(err, _("%s: too few arguments"), "subjectrx");
109  return MUTT_CMD_WARNING;
110  }
112 
113  if (mutt_replacelist_add(list, buf->data, templ.data, err) != 0)
114  {
115  FREE(&templ.data);
116  return MUTT_CMD_ERROR;
117  }
118  FREE(&templ.data);
119 
120  return MUTT_CMD_SUCCESS;
121 }
+ Here is the call graph for this function:

◆ parse_subjectrx_list()

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

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

Definition at line 146 of file subjectrx.c.

165 {
166  enum CommandResult rc;
167 
168  rc = parse_replace_list(buf, s, &SubjectRegexList, err);
169  if (rc == MUTT_CMD_SUCCESS)
170  {
171  mutt_debug(LL_NOTIFY, "NT_SUBJRX_ADD: %s\n", buf->data);
173  }
174  return rc;
175 }
static enum CommandResult parse_replace_list(struct Buffer *buf, struct Buffer *s, struct ReplaceList *list, struct Buffer *err)
Parse a string replacement rule - Implements Command::parse() -.
Definition: subjectrx.c:92
@ NT_SUBJRX
Subject Regex has changed, NotifySubjRx.
Definition: notify_type.h:52
static struct Notify * SubjRxNotify
Definition: subjectrx.c:40
static struct ReplaceList SubjectRegexList
Definition: subjectrx.c:39
@ NT_SUBJRX_ADD
Subject Regex has been added.
Definition: subjectrx.h:40

◆ parse_unsubjectrx_list()

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

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

Definition at line 146 of file subjectrx.c.

182 {
183  enum CommandResult rc;
184 
185  rc = parse_unreplace_list(buf, s, &SubjectRegexList, err);
186  if (rc == MUTT_CMD_SUCCESS)
187  {
188  mutt_debug(LL_NOTIFY, "NT_SUBJRX_DELETE: %s\n", buf->data);
190  }
191  return rc;
192 }
static enum CommandResult parse_unreplace_list(struct Buffer *buf, struct Buffer *s, struct ReplaceList *list, struct Buffer *err)
Remove a string replacement rule - Implements Command::parse() -.
Definition: subjectrx.c:66
@ NT_SUBJRX_DELETE
Subject Regex has been deleted.
Definition: subjectrx.h:41