NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
dlgquery.c
Go to the documentation of this file.
1 
31 #include "config.h"
32 #include <stdbool.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <sys/types.h>
36 #include "mutt/lib.h"
37 #include "address/lib.h"
38 #include "email/lib.h"
39 #include "core/lib.h"
40 #include "gui/lib.h"
41 #include "mutt.h"
42 #include "lib.h"
43 #include "pattern/lib.h"
44 #include "send/lib.h"
45 #include "alias.h"
46 #include "format_flags.h"
47 #include "gui.h"
48 #include "keymap.h"
49 #include "mutt_globals.h"
50 #include "mutt_logging.h"
51 #include "mutt_menu.h"
52 #include "muttlib.h"
53 #include "opcodes.h"
54 
56 static const struct Mapping QueryHelp[] = {
57  // clang-format off
58  { N_("Exit"), OP_EXIT },
59  { N_("Mail"), OP_MAIL },
60  { N_("New Query"), OP_QUERY },
61  { N_("Make Alias"), OP_CREATE_ALIAS },
62  { N_("Sort"), OP_SORT },
63  { N_("Rev-Sort"), OP_SORT_REVERSE },
64  { N_("Search"), OP_SEARCH },
65  { N_("Help"), OP_HELP },
66  { NULL, 0 },
67  // clang-format on
68 };
69 
76 static bool alias_to_addrlist(struct AddressList *al, struct Alias *alias)
77 {
78  if (!al || !TAILQ_EMPTY(al) || !alias)
79  return false;
80 
81  mutt_addrlist_copy(al, &alias->addr, false);
82  if (!TAILQ_EMPTY(al))
83  {
84  struct Address *first = TAILQ_FIRST(al);
85  struct Address *second = TAILQ_NEXT(first, entries);
86  if (!second && !first->personal)
87  first->personal = mutt_str_dup(alias->name);
88 
89  mutt_addrlist_to_intl(al, NULL);
90  }
91 
92  return true;
93 }
94 
100 static int query_search(struct Menu *menu, regex_t *rx, int line)
101 {
102  const struct AliasViewArray *ava = &((struct AliasMenuData *) menu->mdata)->ava;
103  struct AliasView *av = ARRAY_GET(ava, line);
104  struct Alias *alias = av->alias;
105 
106  if (alias->name && (regexec(rx, alias->name, 0, NULL, 0) == 0))
107  return 0;
108  if (alias->comment && (regexec(rx, alias->comment, 0, NULL, 0) == 0))
109  return 0;
110  if (!TAILQ_EMPTY(&alias->addr))
111  {
112  struct Address *addr = TAILQ_FIRST(&alias->addr);
113  if (addr->personal && (regexec(rx, addr->personal, 0, NULL, 0) == 0))
114  {
115  return 0;
116  }
117  if (addr->mailbox && (regexec(rx, addr->mailbox, 0, NULL, 0) == 0))
118  {
119  return 0;
120  }
121  }
122 
123  return REG_NOMATCH;
124 }
125 
137 static const char *query_format_str(char *buf, size_t buflen, size_t col, int cols,
138  char op, const char *src, const char *prec,
139  const char *if_str, const char *else_str,
140  intptr_t data, MuttFormatFlags flags)
141 {
142  struct AliasView *av = (struct AliasView *) data;
143  struct Alias *alias = av->alias;
144  char fmt[128];
145  char tmp[256] = { 0 };
146  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
147 
148  switch (op)
149  {
150  case 'a':
151  tmp[0] = '<';
152  mutt_addrlist_write(&alias->addr, tmp + 1, sizeof(tmp) - 1, true);
153  const size_t len = strlen(tmp);
154  if (len < (sizeof(tmp) - 1))
155  {
156  tmp[len] = '>';
157  tmp[len + 1] = '\0';
158  }
159  mutt_format_s(buf, buflen, prec, tmp);
160  break;
161  case 'c':
162  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
163  snprintf(buf, buflen, fmt, av->num + 1);
164  break;
165  case 'e':
166  if (!optional)
167  mutt_format_s(buf, buflen, prec, NONULL(alias->comment));
168  else if (!alias->comment || (*alias->comment == '\0'))
169  optional = false;
170  break;
171  case 'n':
172  mutt_format_s(buf, buflen, prec, NONULL(alias->name));
173  break;
174  case 't':
175  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
176  snprintf(buf, buflen, fmt, av->is_tagged ? '*' : ' ');
177  break;
178  default:
179  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
180  snprintf(buf, buflen, fmt, op);
181  break;
182  }
183 
184  if (optional)
185  {
186  mutt_expando_format(buf, buflen, col, cols, if_str, query_format_str, data,
188  }
189  else if (flags & MUTT_FORMAT_OPTIONAL)
190  {
191  mutt_expando_format(buf, buflen, col, cols, else_str, query_format_str,
192  data, MUTT_FORMAT_NO_FLAGS);
193  }
194 
195  return src;
196 }
197 
201 static void query_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
202 {
203  const struct AliasMenuData *mdata = (struct AliasMenuData *) menu->mdata;
204  const struct AliasViewArray *ava = &((struct AliasMenuData *) menu->mdata)->ava;
205  struct AliasView *av = ARRAY_GET(ava, line);
206 
207  const char *query_format = cs_subset_string(mdata->sub, "query_format");
208 
209  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols, NONULL(query_format),
211 }
212 
216 static int query_tag(struct Menu *menu, int sel, int act)
217 {
218  const struct AliasViewArray *ava = &((struct AliasMenuData *) menu->mdata)->ava;
219  struct AliasView *av = ARRAY_GET(ava, sel);
220 
221  bool ot = av->is_tagged;
222 
223  av->is_tagged = ((act >= 0) ? act : !av->is_tagged);
224  return av->is_tagged - ot;
225 }
226 
236 static int query_run(char *s, bool verbose, struct AliasList *al,
237  const struct ConfigSubset *sub)
238 {
239  FILE *fp = NULL;
240  char *buf = NULL;
241  size_t buflen;
242  char *msg = NULL;
243  size_t msglen = 0;
244  char *p = NULL;
245  struct Buffer *cmd = mutt_buffer_pool_get();
246 
247  const char *query_command = cs_subset_string(sub, "query_command");
248  mutt_buffer_file_expand_fmt_quote(cmd, query_command, s);
249 
250  pid_t pid = filter_create(mutt_buffer_string(cmd), NULL, &fp, NULL);
251  if (pid < 0)
252  {
253  mutt_debug(LL_DEBUG1, "unable to fork command: %s\n", mutt_buffer_string(cmd));
255  return -1;
256  }
258 
259  if (verbose)
260  mutt_message(_("Waiting for response..."));
261 
262  /* The query protocol first reads one NL-terminated line. If an error
263  * occurs, this is assumed to be an error message. Otherwise it's ignored. */
264  msg = mutt_file_read_line(msg, &msglen, fp, NULL, MUTT_RL_NO_FLAGS);
265  while ((buf = mutt_file_read_line(buf, &buflen, fp, NULL, MUTT_RL_NO_FLAGS)))
266  {
267  p = strtok(buf, "\t\n");
268  if (p)
269  {
270  struct Alias *alias = alias_new();
271 
272  mutt_addrlist_parse(&alias->addr, p);
273  p = strtok(NULL, "\t\n");
274  if (p)
275  {
276  alias->name = mutt_str_dup(p);
277  p = strtok(NULL, "\t\n");
278  if (p)
279  alias->comment = mutt_str_dup(p);
280  }
281  TAILQ_INSERT_TAIL(al, alias, entries);
282  }
283  }
284  FREE(&buf);
285  mutt_file_fclose(&fp);
286  if (filter_wait(pid))
287  {
288  mutt_debug(LL_DEBUG1, "Error: %s\n", msg);
289  if (verbose)
290  mutt_error("%s", msg);
291  }
292  else
293  {
294  if (verbose)
295  mutt_message("%s", msg);
296  }
297  FREE(&msg);
298 
299  return 0;
300 }
301 
310 static void dlg_select_query(char *buf, size_t buflen, struct AliasList *all,
311  bool retbuf, struct ConfigSubset *sub)
312 {
313  struct AliasMenuData mdata = { NULL, NULL, ARRAY_HEAD_INITIALIZER, sub };
314 
315  struct Alias *np = NULL;
316  TAILQ_FOREACH(np, all, entries)
317  {
318  alias_array_alias_add(&mdata.ava, np);
319  }
320  alias_array_sort(&mdata.ava, mdata.sub);
321 
322  struct Menu *menu = NULL;
323  char title[256];
324 
325  snprintf(title, sizeof(title), "%s%s", _("Query: "), buf);
326 
327  menu = mutt_menu_new(MENU_QUERY);
329  dlg->help_data = QueryHelp;
330  dlg->help_menu = MENU_QUERY;
331 
333  menu->search = query_search;
334  menu->custom_search = true;
335  menu->tag = query_tag;
336  menu->title = strdup(title);
337  menu->max = ARRAY_SIZE(&mdata.ava);
338  menu->mdata = &mdata;
340 
343 
344  short sort_alias = cs_subset_sort(sub, "sort_alias");
345 
346  int done = 0;
347  while (done == 0)
348  {
349  const int op = mutt_menu_loop(menu);
350  switch (op)
351  {
352  case OP_QUERY_APPEND:
353  case OP_QUERY:
354  {
355  if ((mutt_get_field(_("Query: "), buf, buflen, MUTT_COMP_NO_FLAGS,
356  false, NULL, NULL) != 0) ||
357  (buf[0] == '\0'))
358  {
359  break;
360  }
361 
362  if (op == OP_QUERY)
363  {
364  ARRAY_FREE(&mdata.ava);
365  aliaslist_free(all);
366  }
367 
368  struct AliasList al = TAILQ_HEAD_INITIALIZER(al);
369  query_run(buf, true, &al, sub);
370  menu->redraw = REDRAW_FULL;
371  if (TAILQ_EMPTY(&al))
372  break;
373 
374  snprintf(title, sizeof(title), "%s%s", _("Query: "), buf);
375 
376  struct Alias *tmp = NULL;
377  TAILQ_FOREACH_SAFE(np, &al, entries, tmp)
378  {
379  alias_array_alias_add(&mdata.ava, np);
380  TAILQ_REMOVE(&al, np, entries);
381  TAILQ_INSERT_TAIL(all, np, entries); // Transfer
382  }
383  alias_array_sort(&mdata.ava, mdata.sub);
384  menu->max = ARRAY_SIZE(&mdata.ava);
385  break;
386  }
387 
388  case OP_CREATE_ALIAS:
389  if (menu->tagprefix)
390  {
391  struct AddressList naddr = TAILQ_HEAD_INITIALIZER(naddr);
392 
393  struct AliasView *avp = NULL;
394  ARRAY_FOREACH(avp, &mdata.ava)
395  {
396  if (avp->is_tagged)
397  {
398  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
399  if (alias_to_addrlist(&al, avp->alias))
400  {
401  mutt_addrlist_copy(&naddr, &al, false);
402  mutt_addrlist_clear(&al);
403  }
404  }
405  }
406 
407  alias_create(&naddr, sub);
408  mutt_addrlist_clear(&naddr);
409  }
410  else
411  {
412  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
413  if (alias_to_addrlist(&al, ARRAY_GET(&mdata.ava, menu->current)->alias))
414  {
415  alias_create(&al, sub);
416  mutt_addrlist_clear(&al);
417  }
418  }
419  break;
420 
421  case OP_GENERIC_SELECT_ENTRY:
422  if (retbuf)
423  {
424  done = 2;
425  break;
426  }
427  /* fallthrough */
428  case OP_MAIL:
429  {
430  struct Email *e = email_new();
431  e->env = mutt_env_new();
432  if (menu->tagprefix)
433  {
434  struct AliasView *avp = NULL;
435  ARRAY_FOREACH(avp, &mdata.ava)
436  {
437  if (avp->is_tagged)
438  {
439  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
440  if (alias_to_addrlist(&al, avp->alias))
441  {
442  mutt_addrlist_copy(&e->env->to, &al, false);
443  mutt_addrlist_clear(&al);
444  }
445  }
446  }
447  }
448  else
449  {
450  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
451  if (alias_to_addrlist(&al, ARRAY_GET(&mdata.ava, menu->current)->alias))
452  {
453  mutt_addrlist_copy(&e->env->to, &al, false);
454  mutt_addrlist_clear(&al);
455  }
456  }
458  menu->redraw = REDRAW_FULL;
459  break;
460  }
461 
462  case OP_SORT:
463  case OP_SORT_REVERSE:
464  {
465  int sort = sort_alias;
466  bool resort = true;
467  bool reverse = (op == OP_SORT_REVERSE);
468 
469  switch (mutt_multi_choice(
470  reverse ?
471  /* L10N: The highlighted letters must match the "Sort" options */
472  _("Rev-Sort (a)lias, a(d)dress or (u)nsorted?") :
473  /* L10N: The highlighted letters must match the "Rev-Sort" options */
474  _("Sort (a)lias, a(d)dress or (u)nsorted?"),
475  /* L10N: These must match the highlighted letters from "Sort" and "Rev-Sort" */
476  _("adu")))
477  {
478  case -1: /* abort */
479  resort = false;
480  break;
481 
482  case 1: /* (a)lias */
483  sort = SORT_ALIAS;
484  break;
485 
486  case 2: /* a(d)dress */
487  sort = SORT_ADDRESS;
488  break;
489 
490  case 3: /* (u)nsorted */
491  sort = SORT_ORDER;
492  break;
493  }
494 
495  if (resort)
496  {
497  sort |= reverse ? SORT_REVERSE : 0;
498 
499  cs_subset_str_native_set(sub, "sort_alias", sort, NULL);
500  menu->redraw = REDRAW_FULL;
501  }
502 
503  break;
504  }
505 
506  case OP_SEARCH_REVERSE:
507  case OP_SEARCH_NEXT:
508  case OP_SEARCH_OPPOSITE:
509  case OP_SEARCH:
510  menu->current = mutt_search_alias_command(Context, menu, menu->current, op);
511  if (menu->current == -1)
512  menu->current = menu->oldcurrent;
513  else
514  menu->redraw |= REDRAW_MOTION;
515  break;
516 
517  case OP_MAIN_LIMIT:
518  {
519  int result = mutt_pattern_alias_func(MUTT_LIMIT, _("Limit to messages matching: "),
520  _("Query"), &mdata, Context, menu);
521 
522  if (result == 0)
523  {
524  alias_array_sort(&mdata.ava, mdata.sub);
525  menu->redraw = REDRAW_FULL;
526  }
527 
528  break;
529  }
530 
531  case OP_EXIT:
532  done = 1;
533  break;
534  }
535  }
536 
537  /* if we need to return the selected entries */
538  if (retbuf && (done == 2))
539  {
540  bool tagged = false;
541  size_t curpos = 0;
542 
543  memset(buf, 0, buflen);
544 
545  /* check for tagged entries */
546  struct AliasView *avp = NULL;
547  ARRAY_FOREACH(avp, &mdata.ava)
548  {
549  if (!avp->is_tagged)
550  continue;
551 
552  if (curpos == 0)
553  {
554  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
555  if (alias_to_addrlist(&al, avp->alias))
556  {
558  tagged = true;
559  mutt_addrlist_write(&al, buf, buflen, false);
560  curpos = mutt_str_len(buf);
561  mutt_addrlist_clear(&al);
562  }
563  }
564  else if (curpos + 2 < buflen)
565  {
566  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
567  if (alias_to_addrlist(&al, avp->alias))
568  {
570  strcat(buf, ", ");
571  mutt_addrlist_write(&al, buf + curpos + 2, buflen - curpos - 2, false);
572  curpos = mutt_str_len(buf);
573  mutt_addrlist_clear(&al);
574  }
575  }
576  }
577  /* then enter current message */
578  if (!tagged)
579  {
580  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
581  if (alias_to_addrlist(&al, ARRAY_GET(&mdata.ava, menu->current)->alias))
582  {
584  mutt_addrlist_write(&al, buf, buflen, false);
585  mutt_addrlist_clear(&al);
586  }
587  }
588  }
589 
592 
593  mutt_menu_pop_current(menu);
594  mutt_menu_free(&menu);
596  ARRAY_FREE(&mdata.ava);
597 }
598 
606 int query_complete(char *buf, size_t buflen, struct ConfigSubset *sub)
607 {
608  const char *query_command = cs_subset_string(sub, "query_command");
609  if (!query_command)
610  {
611  mutt_warning(_("Query command not defined"));
612  return 0;
613  }
614 
615  struct AliasList al = TAILQ_HEAD_INITIALIZER(al);
616  query_run(buf, true, &al, sub);
617  if (TAILQ_EMPTY(&al))
618  return 0;
619 
620  struct Alias *a_first = TAILQ_FIRST(&al);
621  if (!TAILQ_NEXT(a_first, entries)) // only one response?
622  {
623  struct AddressList addr = TAILQ_HEAD_INITIALIZER(addr);
624  if (alias_to_addrlist(&addr, a_first))
625  {
626  mutt_addrlist_to_local(&addr);
627  buf[0] = '\0';
628  mutt_addrlist_write(&addr, buf, buflen, false);
629  mutt_addrlist_clear(&addr);
630  aliaslist_free(&al);
632  }
633  return 0;
634  }
635 
636  /* multiple results, choose from query menu */
637  dlg_select_query(buf, buflen, &al, true, sub);
638  aliaslist_free(&al);
639  return 0;
640 }
641 
646 void query_index(struct ConfigSubset *sub)
647 {
648  const char *query_command = cs_subset_string(sub, "query_command");
649  if (!query_command)
650  {
651  mutt_warning(_("Query command not defined"));
652  return;
653  }
654 
655  char buf[256] = { 0 };
656  if ((mutt_get_field(_("Query: "), buf, sizeof(buf), MUTT_COMP_NO_FLAGS, false,
657  NULL, NULL) != 0) ||
658  (buf[0] == '\0'))
659  {
660  return;
661  }
662 
663  struct AliasList al = TAILQ_HEAD_INITIALIZER(al);
664  query_run(buf, false, &al, sub);
665  if (TAILQ_EMPTY(&al))
666  return;
667 
668  dlg_select_query(buf, sizeof(buf), &al, false, sub);
669  aliaslist_free(&al);
670 }
Menu::oldcurrent
int oldcurrent
For driver use only.
Definition: mutt_menu.h:76
IP
#define IP
Definition: set.h:54
dlg_select_query
static void dlg_select_query(char *buf, size_t buflen, struct AliasList *all, bool retbuf, struct ConfigSubset *sub)
Get the user to enter an Address Query.
Definition: dlgquery.c:310
dialog_create_simple_index
struct MuttWindow * dialog_create_simple_index(struct Menu *menu, enum WindowType type)
Create a simple index Dialog.
Definition: dialog.c:165
Menu::search
int(* search)(struct Menu *menu, regex_t *rx, int line)
Search a menu for a item matching a regex.
Definition: mutt_menu.h:98
MENU_QUERY
@ MENU_QUERY
Select from results of external query.
Definition: keymap.h:83
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
aliaslist_free
void aliaslist_free(struct AliasList *al)
Free a List of Aliases.
Definition: alias.c:648
Alias::addr
struct AddressList addr
List of Addresses the Alias expands to.
Definition: alias.h:36
alias_array_sort
void alias_array_sort(struct AliasViewArray *ava, const struct ConfigSubset *sub)
Sort and reindex an AliasViewArray.
Definition: sort.c:158
Address::personal
char * personal
Real name of address.
Definition: address.h:36
NT_CONFIG
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:37
Buffer
String manipulation buffer.
Definition: buffer.h:33
mutt_addrlist_to_intl
int mutt_addrlist_to_intl(struct AddressList *al, char **err)
Convert an Address list to Punycode.
Definition: address.c:1304
sort_alias
static short sort_alias
Definition: sort.c:42
alias_new
struct Alias * alias_new(void)
Create a new Alias.
Definition: alias.c:617
SORT_ALIAS
@ SORT_ALIAS
Sort by email alias.
Definition: sort2.h:55
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
alias_array_alias_add
int alias_array_alias_add(struct AliasViewArray *ava, struct Alias *alias)
Add an Alias to the AliasViewArray.
Definition: array.c:45
format_flags.h
MUTT_FORMAT_ARROWCURSOR
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
mutt_addrlist_write
size_t mutt_addrlist_write(const struct AddressList *al, char *buf, size_t buflen, bool display)
Write an Address to a buffer.
Definition: address.c:1150
NeoMutt::notify
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
MuttWindow
A division of the screen.
Definition: mutt_window.h:115
mutt_multi_choice
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:937
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
QueryHelp
static const struct Mapping QueryHelp[]
Help Bar for the Address Query dialog.
Definition: dlgquery.c:56
Context
The "current" mailbox.
Definition: context.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
mutt_globals.h
LL_DEBUG1
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
AliasView::alias
struct Alias * alias
Alias.
Definition: gui.h:45
FREE
#define FREE(x)
Definition: memory.h:40
AliasView::num
int num
Index number in list.
Definition: gui.h:38
SORT_REVERSE
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:81
mutt_addrlist_parse
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
TAILQ_INSERT_TAIL
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
mutt_menu_new
struct Menu * mutt_menu_new(enum MenuType type)
Create a new Menu.
Definition: menu.c:956
MuttWindow::help_menu
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:134
ARRAY_SIZE
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
Menu::make_entry
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Format a item for a menu.
Definition: mutt_menu.h:88
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
MUTT_LIMIT
@ MUTT_LIMIT
Messages in limited view.
Definition: mutt.h:105
MUTT_FORMAT_NO_FLAGS
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
email_new
struct Email * email_new(void)
Create a new Email.
Definition: email.c:72
query_complete
int query_complete(char *buf, size_t buflen, struct ConfigSubset *sub)
Perform auto-complete using an Address Query.
Definition: dlgquery.c:606
ARRAY_GET
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:105
cs_subset_str_native_set
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:292
AliasView
GUI data wrapping an Alias.
Definition: gui.h:36
alias.h
query_search
static int query_search(struct Menu *menu, regex_t *rx, int line)
Search a Address menu item - Implements Menu::search()
Definition: dlgquery.c:100
Mapping
Mapping between user-readable string and a constant.
Definition: mapping.h:31
alias_create
void alias_create(struct AddressList *al, const struct ConfigSubset *sub)
Create a new Alias from an Address.
Definition: alias.c:366
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
MUTT_RL_NO_FLAGS
#define MUTT_RL_NO_FLAGS
No flags are set.
Definition: file.h:39
TAILQ_REMOVE
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
mutt_buffer_file_expand_fmt_quote
void mutt_buffer_file_expand_fmt_quote(struct Buffer *dest, const char *fmt, const char *src)
Replace s in a string with a filename.
Definition: file.c:1432
filter_create
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err)
Set up filter program.
Definition: filter.c:206
mutt_menu_push_current
void mutt_menu_push_current(struct Menu *menu)
Add a new Menu to the stack.
Definition: menu.c:1015
AliasMenuData::ava
struct AliasViewArray ava
Array of AliasView.
Definition: gui.h:57
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
ARRAY_FOREACH
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
keymap.h
lib.h
muttlib.h
ARRAY_HEAD_INITIALIZER
#define ARRAY_HEAD_INITIALIZER
Static initializer for arrays.
Definition: array.h:54
WT_DLG_QUERY
@ WT_DLG_QUERY
Query Dialog, dlg_select_query()
Definition: mutt_window.h:87
notify_observer_remove
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:207
NT_COLOR
@ NT_COLOR
Colour has changed, ColorId, EventColor.
Definition: notify_type.h:35
AliasView::is_tagged
bool is_tagged
Is it tagged?
Definition: gui.h:42
mutt_menu.h
REDRAW_FULL
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:45
lib.h
lib.h
mutt_clear_error
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
mutt_send_message
int mutt_send_message(SendFlags flags, struct Email *e_templ, const char *tempfile, struct Context *ctx, struct EmailList *el, struct ConfigSubset *sub)
Send an email.
Definition: send.c:2012
mutt_addrlist_clear
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
Menu::tagprefix
bool tagprefix
Definition: mutt_menu.h:61
ARRAY_FREE
#define ARRAY_FREE(head)
Release all memory.
Definition: array.h:198
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
mutt_debug
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
query_format_str
static const char * query_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the query menu - Implements format_t.
Definition: dlgquery.c:137
Menu::tag
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:107
Menu::title
const char * title
Title of this menu.
Definition: mutt_menu.h:54
notify_observer_add
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:169
SEND_NO_FLAGS
#define SEND_NO_FLAGS
No flags are set.
Definition: send.h:40
AliasMenuData::sub
struct ConfigSubset * sub
Config items.
Definition: gui.h:58
query_tag
static int query_tag(struct Menu *menu, int sel, int act)
Tag an entry in the Query Menu - Implements Menu::tag()
Definition: dlgquery.c:216
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
TAILQ_FOREACH_SAFE
#define TAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:728
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
mutt_env_new
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
SORT_ORDER
@ SORT_ORDER
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:50
MuttWindow::help_data
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:135
mutt_format_s
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1248
mutt_search_alias_command
int mutt_search_alias_command(struct Context *ctx, struct Menu *menu, int cur, int op)
Perform a search.
Definition: pattern.c:642
Menu::custom_search
bool custom_search
The menu implements its own non-Menusearch()-compatible search, trickle OP_SEARCH*.
Definition: mutt_menu.h:79
query_run
static int query_run(char *s, bool verbose, struct AliasList *al, const struct ConfigSubset *sub)
Run an external program to find Addresses.
Definition: dlgquery.c:236
alias_config_observer
int alias_config_observer(struct NotifyCallback *nc)
Listen for sort_alias configuration changes and reorders menu items accordingly.
Definition: gui.c:44
SORT_ADDRESS
@ SORT_ADDRESS
Sort by email address.
Definition: sort2.h:56
filter_wait
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
lib.h
MUTT_FORMAT_OPTIONAL
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
cs_subset_sort
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:219
mutt_logging.h
mutt_menu_loop
int mutt_menu_loop(struct Menu *menu)
Menu event loop.
Definition: menu.c:1309
MuttWindow::state
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:120
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
Alias::name
char * name
Short name.
Definition: alias.h:35
lib.h
mutt_menu_pop_current
void mutt_menu_pop_current(struct Menu *menu)
Remove a Menu from the stack.
Definition: menu.c:1027
cs_subset_string
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:241
lib.h
Menu::mdata
void * mdata
Extra data for the current menu.
Definition: mutt_menu.h:55
TAILQ_NEXT
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
query_make_entry
static void query_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
Format a menu item for the query list - Implements Menu::make_entry()
Definition: dlgquery.c:201
mutt_expando_format
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:774
Menu::max
int max
Number of entries in the menu.
Definition: mutt_menu.h:57
Alias::comment
char * comment
Free-form comment string.
Definition: alias.h:37
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
mutt.h
AliasMenuData
AliasMenuData - AliasView array wrapper with Pattern information.
Definition: gui.h:53
mutt_pattern_alias_func
int mutt_pattern_alias_func(int op, char *prompt, char *title, struct AliasMenuData *mdata, struct Context *ctx, struct Menu *menu)
Perform some Pattern matching for Alias.
Definition: pattern.c:241
Menu::redraw
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:58
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Alias
A shortcut for an email address or addresses.
Definition: alias.h:33
mutt_addrlist_to_local
int mutt_addrlist_to_local(struct AddressList *al)
Convert an Address list from Punycode.
Definition: address.c:1386
mutt_get_field
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:311
gui.h
WindowState::cols
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
dialog_destroy_simple_index
void dialog_destroy_simple_index(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: dialog.c:209
alias_to_addrlist
static bool alias_to_addrlist(struct AddressList *al, struct Alias *alias)
Turn an Alias into an AddressList.
Definition: dlgquery.c:76
Menu::current
int current
Current entry.
Definition: mutt_menu.h:56
opcodes.h
ConfigSubset
A set of inherited config items.
Definition: subset.h:46
Email
The envelope/body of an email.
Definition: email.h:37
lib.h
REDRAW_MOTION
#define REDRAW_MOTION
Redraw after moving the menu list.
Definition: mutt_menu.h:41
mutt_message
#define mutt_message(...)
Definition: logging.h:83
Menu::win_index
struct MuttWindow * win_index
Definition: mutt_menu.h:63
mutt_addrlist_copy
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
mutt_warning
#define mutt_warning(...)
Definition: logging.h:82
Menu
GUI selectable list of items.
Definition: mutt_menu.h:52
N_
#define N_(a)
Definition: message.h:32
query_index
void query_index(struct ConfigSubset *sub)
Perform an Alias Query and display the results.
Definition: dlgquery.c:646
Address
An email address.
Definition: address.h:34
alias_color_observer
int alias_color_observer(struct NotifyCallback *nc)
Listen for color configuration changes and refreshes the menu.
Definition: gui.c:66
MuttFormatFlags
uint8_t MuttFormatFlags
Flags for mutt_expando_format(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: format_flags.h:29
mutt_menu_free
void mutt_menu_free(struct Menu **ptr)
Destroy a menu.
Definition: menu.c:972
mutt_error
#define mutt_error(...)
Definition: logging.h:84
mutt_file_read_line
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
Definition: file.c:667
MUTT_COMP_NO_FLAGS
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56