NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
hdrline.c
Go to the documentation of this file.
1 
32 #include "config.h"
33 #include <locale.h>
34 #include <stdbool.h>
35 #include <stdint.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <time.h>
40 #include "mutt/lib.h"
41 #include "address/lib.h"
42 #include "config/lib.h"
43 #include "email/lib.h"
44 #include "core/lib.h"
45 #include "alias/lib.h"
46 #include "gui/lib.h"
47 #include "hdrline.h"
48 #include "ncrypt/lib.h"
49 #include "context.h"
50 #include "format_flags.h"
51 #include "hook.h"
52 #include "maillist.h"
53 #include "mutt_globals.h"
54 #include "mutt_menu.h"
55 #include "mutt_parse.h"
56 #include "mutt_thread.h"
57 #include "muttlib.h"
58 #include "sort.h"
59 #ifdef USE_NOTMUCH
60 #include "notmuch/lib.h"
61 #endif
62 
63 /* These Config Variables are only used in hdrline.c */
67 struct MbTable *C_ToChars;
68 
73 {
74  struct Mailbox *mailbox;
76  struct Email *email;
77  const char *pager_progress;
78 };
79 
84 {
96 };
97 
102 {
108 };
109 
116 {
123 };
124 
135 static size_t add_index_color(char *buf, size_t buflen, MuttFormatFlags flags, char color)
136 {
137  /* only add color markers if we are operating on main index entries. */
138  if (!(flags & MUTT_FORMAT_INDEX))
139  return 0;
140 
141  /* this item is going to be passed to an external filter */
142  if (flags & MUTT_FORMAT_NOFILTER)
143  return 0;
144 
145  if (color == MT_COLOR_INDEX)
146  { /* buf might be uninitialized other cases */
147  const size_t len = mutt_str_len(buf);
148  buf += len;
149  buflen -= len;
150  }
151 
152  if (buflen <= 2)
153  return 0;
154 
155  buf[0] = MUTT_SPECIAL_INDEX;
156  buf[1] = color;
157  buf[2] = '\0';
158 
159  return 2;
160 }
161 
172 static const char *get_nth_wchar(struct MbTable *table, int index)
173 {
174  if (!table || !table->chars || (index < 0) || (index >= table->len))
175  return " ";
176 
177  if (table->chars[index][0] == '\r')
178  return "";
179 
180  return table->chars[index];
181 }
182 
191 static const char *make_from_prefix(enum FieldType disp)
192 {
193  /* need 2 bytes at the end, one for the space, another for NUL */
194  static char padded[8];
195  static const char *long_prefixes[DISP_MAX] = {
196  [DISP_TO] = "To ", [DISP_CC] = "Cc ", [DISP_BCC] = "Bcc ",
197  [DISP_FROM] = "", [DISP_PLAIN] = "",
198  };
199 
200  if (!C_FromChars || !C_FromChars->chars || (C_FromChars->len == 0))
201  return long_prefixes[disp];
202 
203  const char *pchar = get_nth_wchar(C_FromChars, disp);
204  if (mutt_str_len(pchar) == 0)
205  return "";
206 
207  snprintf(padded, sizeof(padded), "%s ", pchar);
208  return padded;
209 }
210 
225 static void make_from(struct Envelope *env, char *buf, size_t buflen,
226  bool do_lists, MuttFormatFlags flags)
227 {
228  if (!env || !buf)
229  return;
230 
231  bool me;
232  enum FieldType disp;
233  struct AddressList *name = NULL;
234 
235  me = mutt_addr_is_user(TAILQ_FIRST(&env->from));
236 
237  if (do_lists || me)
238  {
239  if (check_for_mailing_list(&env->to, make_from_prefix(DISP_TO), buf, buflen))
240  return;
241  if (check_for_mailing_list(&env->cc, make_from_prefix(DISP_CC), buf, buflen))
242  return;
243  }
244 
245  if (me && !TAILQ_EMPTY(&env->to))
246  {
247  disp = (flags & MUTT_FORMAT_PLAIN) ? DISP_PLAIN : DISP_TO;
248  name = &env->to;
249  }
250  else if (me && !TAILQ_EMPTY(&env->cc))
251  {
252  disp = DISP_CC;
253  name = &env->cc;
254  }
255  else if (me && !TAILQ_EMPTY(&env->bcc))
256  {
257  disp = DISP_BCC;
258  name = &env->bcc;
259  }
260  else if (!TAILQ_EMPTY(&env->from))
261  {
262  disp = DISP_FROM;
263  name = &env->from;
264  }
265  else
266  {
267  *buf = '\0';
268  return;
269  }
270 
271  snprintf(buf, buflen, "%s%s", make_from_prefix(disp), mutt_get_name(TAILQ_FIRST(name)));
272 }
273 
281 static void make_from_addr(struct Envelope *env, char *buf, size_t buflen, bool do_lists)
282 {
283  if (!env || !buf)
284  return;
285 
286  bool me = mutt_addr_is_user(TAILQ_FIRST(&env->from));
287 
288  if (do_lists || me)
289  {
290  if (check_for_mailing_list_addr(&env->to, buf, buflen))
291  return;
292  if (check_for_mailing_list_addr(&env->cc, buf, buflen))
293  return;
294  }
295 
296  if (me && !TAILQ_EMPTY(&env->to))
297  snprintf(buf, buflen, "%s", TAILQ_FIRST(&env->to)->mailbox);
298  else if (me && !TAILQ_EMPTY(&env->cc))
299  snprintf(buf, buflen, "%s", TAILQ_FIRST(&env->cc)->mailbox);
300  else if (!TAILQ_EMPTY(&env->from))
301  mutt_str_copy(buf, TAILQ_FIRST(&env->from)->mailbox, buflen);
302  else
303  *buf = '\0';
304 }
305 
311 static bool user_in_addr(struct AddressList *al)
312 {
313  struct Address *a = NULL;
314  TAILQ_FOREACH(a, al, entries)
315  if (mutt_addr_is_user(a))
316  return true;
317  return false;
318 }
319 
331 static int user_is_recipient(struct Email *e)
332 {
333  if (!e || !e->env)
334  return 0;
335 
336  struct Envelope *env = e->env;
337 
338  if (!e->recip_valid)
339  {
340  e->recip_valid = true;
341 
342  if (mutt_addr_is_user(TAILQ_FIRST(&env->from)))
343  e->recipient = 4;
344  else if (user_in_addr(&env->to))
345  {
346  if (TAILQ_NEXT(TAILQ_FIRST(&env->to), entries) || !TAILQ_EMPTY(&env->cc))
347  e->recipient = 2; /* non-unique recipient */
348  else
349  e->recipient = 1; /* unique recipient */
350  }
351  else if (user_in_addr(&env->cc))
352  e->recipient = 3;
353  else if (check_for_mailing_list(&env->to, NULL, NULL, 0))
354  e->recipient = 5;
355  else if (check_for_mailing_list(&env->cc, NULL, NULL, 0))
356  e->recipient = 5;
357  else if (user_in_addr(&env->reply_to))
358  e->recipient = 6;
359  else
360  e->recipient = 0;
361  }
362 
363  return e->recipient;
364 }
365 
372 static char *apply_subject_mods(struct Envelope *env)
373 {
374  if (!env)
375  return NULL;
376 
378  return env->subject;
379 
380  if (!env->subject || (*env->subject == '\0'))
381  {
382  env->disp_subj = NULL;
383  return NULL;
384  }
385 
387  return env->disp_subj;
388 }
389 
395 static bool thread_is_new(struct Email *e)
396 {
397  return e->collapsed && (e->num_hidden > 1) && (mutt_thread_contains_unread(e) == 1);
398 }
399 
405 static bool thread_is_old(struct Email *e)
406 {
407  return e->collapsed && (e->num_hidden > 1) && (mutt_thread_contains_unread(e) == 2);
408 }
409 
466 static const char *index_format_str(char *buf, size_t buflen, size_t col, int cols,
467  char op, const char *src, const char *prec,
468  const char *if_str, const char *else_str,
469  intptr_t data, MuttFormatFlags flags)
470 {
471  struct HdrFormatInfo *hfi = (struct HdrFormatInfo *) data;
472  char fmt[128], tmp[1024];
473  char *p = NULL, *tags = NULL;
474  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
475  int threads = ((C_Sort & SORT_MASK) == SORT_THREADS);
476  int is_index = (flags & MUTT_FORMAT_INDEX);
477  size_t colorlen;
478 
479  struct Email *e = hfi->email;
480  size_t msg_in_pager = hfi->msg_in_pager;
481  struct Mailbox *m = hfi->mailbox;
482 
483  if (!e || !e->env)
484  return src;
485 
486  const struct Address *reply_to = TAILQ_FIRST(&e->env->reply_to);
487  const struct Address *from = TAILQ_FIRST(&e->env->from);
488  const struct Address *to = TAILQ_FIRST(&e->env->to);
489  const struct Address *cc = TAILQ_FIRST(&e->env->cc);
490 
491  buf[0] = '\0';
492  switch (op)
493  {
494  case 'A':
495  case 'I':
496  if (op == 'A')
497  {
498  if (reply_to && reply_to->mailbox)
499  {
500  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
501  mutt_format_s(buf + colorlen, buflen - colorlen, prec,
502  mutt_addr_for_display(reply_to));
503  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
504  break;
505  }
506  }
507  else
508  {
509  if (mutt_mb_get_initials(mutt_get_name(from), tmp, sizeof(tmp)))
510  {
511  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
512  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
513  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
514  break;
515  }
516  }
517  /* fallthrough */
518 
519  case 'a':
520  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
521  if (from && from->mailbox)
522  {
523  mutt_format_s(buf + colorlen, buflen - colorlen, prec, mutt_addr_for_display(from));
524  }
525  else
526  mutt_format_s(buf + colorlen, buflen - colorlen, prec, "");
527  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
528  break;
529 
530  case 'B':
531  case 'K':
532  if (!first_mailing_list(buf, buflen, &e->env->to) &&
533  !first_mailing_list(buf, buflen, &e->env->cc))
534  {
535  buf[0] = '\0';
536  }
537  if (buf[0] != '\0')
538  {
539  mutt_str_copy(tmp, buf, sizeof(tmp));
540  mutt_format_s(buf, buflen, prec, tmp);
541  break;
542  }
543  if (op == 'K')
544  {
545  if (optional)
546  optional = false;
547  /* break if 'K' returns nothing */
548  break;
549  }
550  /* if 'B' returns nothing */
551  /* fallthrough */
552 
553  case 'b':
554  if (m)
555  {
556  p = strrchr(mailbox_path(m), '/');
557 #ifdef USE_NOTMUCH
558  if (m->type == MUTT_NOTMUCH)
559  {
560  char *rel_path = nm_email_get_folder_rel_db(m, e);
561  if (rel_path)
562  p = rel_path;
563  }
564 #endif
565 
566  if (p)
567  mutt_str_copy(buf, p + 1, buflen);
568  else
569  mutt_str_copy(buf, mailbox_path(m), buflen);
570  }
571  else
572  mutt_str_copy(buf, "(null)", buflen);
573  mutt_str_copy(tmp, buf, sizeof(tmp));
574  mutt_format_s(buf, buflen, prec, tmp);
575  break;
576 
577  case 'c':
578  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_SIZE);
579  if (src[0] == 'r')
580  {
581  mutt_str_pretty_size(tmp, sizeof(tmp), email_size(e));
582  src++;
583  }
584  else
585  {
586  mutt_str_pretty_size(tmp, sizeof(tmp), e->body->length);
587  }
588  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
589  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
590  break;
591 
592  case 'C':
593  colorlen = add_index_color(fmt, sizeof(fmt), flags, MT_COLOR_INDEX_NUMBER);
594  snprintf(fmt + colorlen, sizeof(fmt) - colorlen, "%%%sd", prec);
595  add_index_color(fmt + colorlen, sizeof(fmt) - colorlen, flags, MT_COLOR_INDEX);
596  snprintf(buf, buflen, fmt, e->msgno + 1);
597  break;
598 
599  case 'd':
600  case 'D':
601  case '{':
602  case '[':
603  case '(':
604  case '<':
605  /* preprocess $date_format to handle %Z */
606  {
607  const char *cp = NULL;
608  time_t now;
609  int j = 0;
610 
611  if (optional && ((op == '[') || (op == '(')))
612  {
613  now = mutt_date_epoch();
614  struct tm tm = mutt_date_localtime(now);
615  now -= (op == '(') ? e->received : e->date_sent;
616 
617  char *is = (char *) prec;
618  bool invert = false;
619  if (*is == '>')
620  {
621  invert = true;
622  is++;
623  }
624 
625  while (*is && (*is != '?'))
626  {
627  int t = strtol(is, &is, 10);
628  /* semi-broken (assuming 30 days in all months) */
629  switch (*(is++))
630  {
631  case 'y':
632  if (t > 1)
633  {
634  t--;
635  t *= (60 * 60 * 24 * 365);
636  }
637  t += ((tm.tm_mon * 60 * 60 * 24 * 30) + (tm.tm_mday * 60 * 60 * 24) +
638  (tm.tm_hour * 60 * 60) + (tm.tm_min * 60) + tm.tm_sec);
639  break;
640 
641  case 'm':
642  if (t > 1)
643  {
644  t--;
645  t *= (60 * 60 * 24 * 30);
646  }
647  t += ((tm.tm_mday * 60 * 60 * 24) + (tm.tm_hour * 60 * 60) +
648  (tm.tm_min * 60) + tm.tm_sec);
649  break;
650 
651  case 'w':
652  if (t > 1)
653  {
654  t--;
655  t *= (60 * 60 * 24 * 7);
656  }
657  t += ((tm.tm_wday * 60 * 60 * 24) + (tm.tm_hour * 60 * 60) +
658  (tm.tm_min * 60) + tm.tm_sec);
659  break;
660 
661  case 'd':
662  if (t > 1)
663  {
664  t--;
665  t *= (60 * 60 * 24);
666  }
667  t += ((tm.tm_hour * 60 * 60) + (tm.tm_min * 60) + tm.tm_sec);
668  break;
669 
670  case 'H':
671  if (t > 1)
672  {
673  t--;
674  t *= (60 * 60);
675  }
676  t += ((tm.tm_min * 60) + tm.tm_sec);
677  break;
678 
679  case 'M':
680  if (t > 1)
681  {
682  t--;
683  t *= (60);
684  }
685  t += (tm.tm_sec);
686  break;
687 
688  default:
689  break;
690  }
691  j += t;
692  }
693 
694  if (j < 0)
695  j *= -1;
696 
697  if (((now > j) || (now < (-1 * j))) ^ invert)
698  optional = false;
699  break;
700  }
701 
702  p = buf;
703 
704  cp = ((op == 'd') || (op == 'D')) ? (NONULL(C_DateFormat)) : src;
705  bool do_locales;
706  if (*cp == '!')
707  {
708  do_locales = false;
709  cp++;
710  }
711  else
712  do_locales = true;
713 
714  size_t len = buflen - 1;
715  while ((len > 0) &&
716  ((((op == 'd') || (op == 'D')) && *cp) ||
717  ((op == '{') && (*cp != '}')) || ((op == '[') && (*cp != ']')) ||
718  ((op == '(') && (*cp != ')')) || ((op == '<') && (*cp != '>'))))
719  {
720  if (*cp == '%')
721  {
722  cp++;
723  if (((*cp == 'Z') || (*cp == 'z')) && ((op == 'd') || (op == '{')))
724  {
725  if (len >= 5)
726  {
727  sprintf(p, "%c%02u%02u", e->zoccident ? '-' : '+', e->zhours, e->zminutes);
728  p += 5;
729  len -= 5;
730  }
731  else
732  break; /* not enough space left */
733  }
734  else
735  {
736  if (len >= 2)
737  {
738  *p++ = '%';
739  *p++ = *cp;
740  len -= 2;
741  }
742  else
743  break; /* not enough space */
744  }
745  cp++;
746  }
747  else
748  {
749  *p++ = *cp++;
750  len--;
751  }
752  }
753  *p = '\0';
754 
755  struct tm tm;
756  if ((op == '[') || (op == 'D'))
758  else if (op == '(')
759  tm = mutt_date_localtime(e->received);
760  else if (op == '<')
761  {
763  }
764  else
765  {
766  /* restore sender's time zone */
767  now = e->date_sent;
768  if (e->zoccident)
769  now -= (e->zhours * 3600 + e->zminutes * 60);
770  else
771  now += (e->zhours * 3600 + e->zminutes * 60);
772  tm = mutt_date_gmtime(now);
773  }
774 
775  if (!do_locales)
776  setlocale(LC_TIME, "C");
777  strftime(tmp, sizeof(tmp), buf, &tm);
778  if (!do_locales)
779  setlocale(LC_TIME, "");
780 
781  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_DATE);
782  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
783  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
784 
785  if ((len > 0) && (op != 'd') && (op != 'D')) /* Skip ending op */
786  src = cp + 1;
787  break;
788  }
789 
790  case 'e':
791  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
792  snprintf(buf, buflen, fmt, mutt_messages_in_thread(m, e, MIT_POSITION));
793  break;
794 
795  case 'E':
796  if (!optional)
797  {
798  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
799  snprintf(buf, buflen, fmt, mutt_messages_in_thread(m, e, MIT_NUM_MESSAGES));
800  }
801  else if (mutt_messages_in_thread(m, e, MIT_NUM_MESSAGES) <= 1)
802  optional = false;
803  break;
804 
805  case 'f':
806  tmp[0] = '\0';
807  mutt_addrlist_write(&e->env->from, tmp, sizeof(tmp), true);
808  mutt_format_s(buf, buflen, prec, tmp);
809  break;
810 
811  case 'F':
812  if (!optional)
813  {
814  const bool is_plain = (src[0] == 'p');
815  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
816  make_from(e->env, tmp, sizeof(tmp), false,
817  (is_plain ? MUTT_FORMAT_PLAIN : MUTT_FORMAT_NO_FLAGS));
818  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
819  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
820 
821  if (is_plain)
822  src++;
823  }
824  else if (mutt_addr_is_user(from))
825  {
826  optional = false;
827  }
828  break;
829 
830  case 'g':
831  tags = driver_tags_get_transformed(&e->tags);
832  if (!optional)
833  {
834  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_TAGS);
835  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(tags));
836  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
837  }
838  else if (!tags)
839  optional = false;
840  FREE(&tags);
841  break;
842 
843  case 'G':
844  {
845  char format[3];
846  char *tag = NULL;
847 
848  if (!optional)
849  {
850  format[0] = op;
851  format[1] = *src;
852  format[2] = '\0';
853 
854  tag = mutt_hash_find(TagFormats, format);
855  if (tag)
856  {
857  tags = driver_tags_get_transformed_for(&e->tags, tag);
858  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_TAG);
859  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(tags));
860  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
861  FREE(&tags);
862  }
863  src++;
864  }
865  else
866  {
867  format[0] = op;
868  format[1] = *prec;
869  format[2] = '\0';
870 
871  tag = mutt_hash_find(TagFormats, format);
872  if (tag)
873  {
874  tags = driver_tags_get_transformed_for(&e->tags, tag);
875  if (!tags)
876  optional = false;
877  FREE(&tags);
878  }
879  }
880  break;
881  }
882 
883  case 'H':
884  /* (Hormel) spam score */
885  if (optional)
886  optional = !mutt_buffer_is_empty(&e->env->spam);
887 
888  mutt_format_s(buf, buflen, prec, mutt_buffer_string(&e->env->spam));
889  break;
890 
891  case 'i':
892  mutt_format_s(buf, buflen, prec, e->env->message_id ? e->env->message_id : "<no.id>");
893  break;
894 
895  case 'J':
896  {
897  bool have_tags = true;
898  tags = driver_tags_get_transformed(&e->tags);
899  if (tags)
900  {
901  if (flags & MUTT_FORMAT_TREE)
902  {
903  char *parent_tags = NULL;
904  if (e->thread->prev && e->thread->prev->message)
905  {
906  parent_tags = driver_tags_get_transformed(&e->thread->prev->message->tags);
907  }
908  if (!parent_tags && e->thread->parent && e->thread->parent->message)
909  {
910  parent_tags =
912  }
913  if (parent_tags && mutt_istr_equal(tags, parent_tags))
914  have_tags = false;
915  FREE(&parent_tags);
916  }
917  }
918  else
919  have_tags = false;
920 
921  if (optional)
922  optional = have_tags;
923 
924  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_TAGS);
925  if (have_tags)
926  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tags);
927  else
928  mutt_format_s(buf + colorlen, buflen - colorlen, prec, "");
929  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
930  FREE(&tags);
931  break;
932  }
933 
934  case 'l':
935  if (!optional)
936  {
937  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
938  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_SIZE);
939  snprintf(buf + colorlen, buflen - colorlen, fmt, (int) e->lines);
940  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
941  }
942  else if (e->lines <= 0)
943  optional = false;
944  break;
945 
946  case 'L':
947  if (!optional)
948  {
949  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
950  make_from(e->env, tmp, sizeof(tmp), true, flags);
951  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
952  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
953  }
954  else if (!check_for_mailing_list(&e->env->to, NULL, NULL, 0) &&
955  !check_for_mailing_list(&e->env->cc, NULL, NULL, 0))
956  {
957  optional = false;
958  }
959  break;
960 
961  case 'm':
962  if (m)
963  {
964  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
965  snprintf(buf, buflen, fmt, m->msg_count);
966  }
967  else
968  mutt_str_copy(buf, "(null)", buflen);
969  break;
970 
971  case 'n':
972  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_AUTHOR);
973  mutt_format_s(buf + colorlen, buflen - colorlen, prec, mutt_get_name(from));
974  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
975  break;
976 
977  case 'M':
978  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
979  if (!optional)
980  {
981  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_COLLAPSED);
982  if (threads && is_index && e->collapsed && (e->num_hidden > 1))
983  {
984  snprintf(buf + colorlen, buflen - colorlen, fmt, e->num_hidden);
985  add_index_color(buf, buflen - colorlen, flags, MT_COLOR_INDEX);
986  }
987  else if (is_index && threads)
988  {
989  mutt_format_s(buf + colorlen, buflen - colorlen, prec, " ");
990  add_index_color(buf, buflen - colorlen, flags, MT_COLOR_INDEX);
991  }
992  else
993  *buf = '\0';
994  }
995  else
996  {
997  if (!(threads && is_index && e->collapsed && (e->num_hidden > 1)))
998  optional = false;
999  }
1000  break;
1001 
1002  case 'N':
1003  if (!optional)
1004  {
1005  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
1006  snprintf(buf, buflen, fmt, e->score);
1007  }
1008  else
1009  {
1010  if (e->score == 0)
1011  optional = false;
1012  }
1013  break;
1014 
1015  case 'O':
1016  if (!optional)
1017  {
1018  make_from_addr(e->env, tmp, sizeof(tmp), true);
1019  if (!C_SaveAddress && (p = strpbrk(tmp, "%@")))
1020  *p = '\0';
1021  mutt_format_s(buf, buflen, prec, tmp);
1022  }
1023  else if (!check_for_mailing_list_addr(&e->env->to, NULL, 0) &&
1024  !check_for_mailing_list_addr(&e->env->cc, NULL, 0))
1025  {
1026  optional = false;
1027  }
1028  break;
1029 
1030  case 'P':
1031  mutt_str_copy(buf, hfi->pager_progress, buflen);
1032  break;
1033 
1034 #ifdef USE_NNTP
1035  case 'q':
1036  mutt_format_s(buf, buflen, prec, e->env->newsgroups ? e->env->newsgroups : "");
1037  break;
1038 #endif
1039 
1040  case 'r':
1041  tmp[0] = '\0';
1042  mutt_addrlist_write(&e->env->to, tmp, sizeof(tmp), true);
1043  if (optional && (tmp[0] == '\0'))
1044  optional = false;
1045  mutt_format_s(buf, buflen, prec, tmp);
1046  break;
1047 
1048  case 'R':
1049  tmp[0] = '\0';
1050  mutt_addrlist_write(&e->env->cc, tmp, sizeof(tmp), true);
1051  if (optional && (tmp[0] == '\0'))
1052  optional = false;
1053  mutt_format_s(buf, buflen, prec, tmp);
1054  break;
1055 
1056  case 's':
1057  {
1058  char *subj = NULL;
1059  if (e->env->disp_subj)
1060  subj = e->env->disp_subj;
1061  else if (!STAILQ_EMPTY(&SubjectRegexList))
1062  subj = apply_subject_mods(e->env);
1063  else
1064  subj = e->env->subject;
1065  if (flags & MUTT_FORMAT_TREE && !e->collapsed)
1066  {
1067  if (flags & MUTT_FORMAT_FORCESUBJ)
1068  {
1069  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_SUBJECT);
1070  mutt_format_s(buf + colorlen, buflen - colorlen, "", NONULL(subj));
1071  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1072  snprintf(tmp, sizeof(tmp), "%s%s", e->tree, buf);
1073  mutt_format_s_tree(buf, buflen, prec, tmp);
1074  }
1075  else
1076  mutt_format_s_tree(buf, buflen, prec, e->tree);
1077  }
1078  else
1079  {
1080  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_SUBJECT);
1081  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(subj));
1082  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1083  }
1084  break;
1085  }
1086 
1087  case 'S':
1088  {
1089  const char *wch = NULL;
1090  if (e->deleted)
1092  else if (e->attach_del)
1094  else if (e->tagged)
1096  else if (e->flagged)
1098  else if (e->replied)
1100  else if (e->read && (msg_in_pager != e->msgno))
1102  else if (e->old)
1104  else
1106 
1107  snprintf(tmp, sizeof(tmp), "%s", wch);
1108  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_FLAGS);
1109  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
1110  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1111  break;
1112  }
1113 
1114  case 't':
1115  tmp[0] = '\0';
1116  if (!check_for_mailing_list(&e->env->to, "To ", tmp, sizeof(tmp)) &&
1117  !check_for_mailing_list(&e->env->cc, "Cc ", tmp, sizeof(tmp)))
1118  {
1119  if (to)
1120  snprintf(tmp, sizeof(tmp), "To %s", mutt_get_name(to));
1121  else if (cc)
1122  snprintf(tmp, sizeof(tmp), "Cc %s", mutt_get_name(cc));
1123  }
1124  mutt_format_s(buf, buflen, prec, tmp);
1125  break;
1126 
1127  case 'T':
1128  {
1129  int i;
1130  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
1131  snprintf(buf, buflen, fmt,
1132  (C_ToChars && ((i = user_is_recipient(e))) < C_ToChars->len) ?
1133  C_ToChars->chars[i] :
1134  " ");
1135  break;
1136  }
1137 
1138  case 'u':
1139  if (from && from->mailbox)
1140  {
1141  mutt_str_copy(tmp, mutt_addr_for_display(from), sizeof(tmp));
1142  p = strpbrk(tmp, "%@");
1143  if (p)
1144  *p = '\0';
1145  }
1146  else
1147  tmp[0] = '\0';
1148  mutt_format_s(buf, buflen, prec, tmp);
1149  break;
1150 
1151  case 'v':
1152  if (mutt_addr_is_user(from))
1153  {
1154  if (to)
1155  mutt_format_s(tmp, sizeof(tmp), prec, mutt_get_name(to));
1156  else if (cc)
1157  mutt_format_s(tmp, sizeof(tmp), prec, mutt_get_name(cc));
1158  else
1159  *tmp = '\0';
1160  }
1161  else
1162  mutt_format_s(tmp, sizeof(tmp), prec, mutt_get_name(from));
1163  p = strpbrk(tmp, " %@");
1164  if (p)
1165  *p = '\0';
1166  mutt_format_s(buf, buflen, prec, tmp);
1167  break;
1168 
1169  case 'W':
1170  if (!optional)
1171  {
1172  mutt_format_s(buf, buflen, prec, e->env->organization ? e->env->organization : "");
1173  }
1174  else if (!e->env->organization)
1175  optional = false;
1176  break;
1177 
1178 #ifdef USE_NNTP
1179  case 'x':
1180  if (!optional)
1181  {
1182  mutt_format_s(buf, buflen, prec, e->env->x_comment_to ? e->env->x_comment_to : "");
1183  }
1184  else if (!e->env->x_comment_to)
1185  optional = false;
1186  break;
1187 #endif
1188 
1189  case 'X':
1190  {
1191  int count = mutt_count_body_parts(m, e);
1192 
1193  /* The recursion allows messages without depth to return 0. */
1194  if (optional)
1195  optional = (count != 0);
1196 
1197  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
1198  snprintf(buf, buflen, fmt, count);
1199  break;
1200  }
1201 
1202  case 'y':
1203  if (optional)
1204  optional = (e->env->x_label != NULL);
1205 
1206  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_LABEL);
1207  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(e->env->x_label));
1208  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1209  break;
1210 
1211  case 'Y':
1212  {
1213  bool label = true;
1214  if (e->env->x_label)
1215  {
1216  struct Email *e_tmp = NULL;
1217  if (flags & MUTT_FORMAT_TREE && (e->thread->prev && e->thread->prev->message &&
1218  e->thread->prev->message->env->x_label))
1219  {
1220  e_tmp = e->thread->prev->message;
1221  }
1222  else if (flags & MUTT_FORMAT_TREE &&
1223  (e->thread->parent && e->thread->parent->message &&
1224  e->thread->parent->message->env->x_label))
1225  {
1226  e_tmp = e->thread->parent->message;
1227  }
1228  if (e_tmp && mutt_istr_equal(e->env->x_label, e_tmp->env->x_label))
1229  label = false;
1230  }
1231  else
1232  label = false;
1233 
1234  if (optional)
1235  optional = label;
1236 
1237  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_LABEL);
1238  if (label)
1239  mutt_format_s(buf + colorlen, buflen - colorlen, prec, NONULL(e->env->x_label));
1240  else
1241  mutt_format_s(buf + colorlen, buflen - colorlen, prec, "");
1242  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1243  break;
1244  }
1245 
1246  case 'z':
1247  if (src[0] == 's') /* status: deleted/new/old/replied */
1248  {
1249  const char *ch = NULL;
1250  if (e->deleted)
1252  else if (e->attach_del)
1254  else if (threads && thread_is_new(e))
1256  else if (threads && thread_is_old(e))
1258  else if (e->read && (msg_in_pager != e->msgno))
1259  {
1260  if (e->replied)
1262  else
1264  }
1265  else
1266  {
1267  if (e->old)
1269  else
1271  }
1272 
1273  snprintf(tmp, sizeof(tmp), "%s", ch);
1274  src++;
1275  }
1276  else if (src[0] == 'c') /* crypto */
1277  {
1278  const char *ch = "";
1279  if ((WithCrypto != 0) && (e->security & SEC_GOODSIGN))
1281  else if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1283  else if ((WithCrypto != 0) && (e->security & SEC_SIGN))
1285  else if (((WithCrypto & APPLICATION_PGP) != 0) && ((e->security & PGP_KEY) == PGP_KEY))
1286  {
1288  }
1289  else
1291 
1292  snprintf(tmp, sizeof(tmp), "%s", ch);
1293  src++;
1294  }
1295  else if (src[0] == 't') /* tagged, flagged, recipient */
1296  {
1297  const char *ch = "";
1298  if (e->tagged)
1300  else if (e->flagged)
1302  else
1304 
1305  snprintf(tmp, sizeof(tmp), "%s", ch);
1306  src++;
1307  }
1308  else /* fallthrough */
1309  break;
1310 
1311  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_FLAGS);
1312  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
1313  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1314  break;
1315 
1316  case 'Z':
1317  {
1318  /* New/Old for threads; replied; New/Old for messages */
1319  const char *first = NULL;
1320  if (threads && thread_is_new(e))
1322  else if (threads && thread_is_old(e))
1324  else if (e->read && (msg_in_pager != e->msgno))
1325  {
1326  if (e->replied)
1328  else
1330  }
1331  else
1332  {
1333  if (e->old)
1335  else
1337  }
1338 
1339  /* Marked for deletion; deleted attachments; crypto */
1340  const char *second = "";
1341  if (e->deleted)
1343  else if (e->attach_del)
1345  else if ((WithCrypto != 0) && (e->security & SEC_GOODSIGN))
1347  else if ((WithCrypto != 0) && (e->security & SEC_ENCRYPT))
1349  else if ((WithCrypto != 0) && (e->security & SEC_SIGN))
1351  else if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & PGP_KEY))
1353  else
1355 
1356  /* Tagged, flagged and recipient flag */
1357  const char *third = "";
1358  if (e->tagged)
1360  else if (e->flagged)
1362  else
1364 
1365  snprintf(tmp, sizeof(tmp), "%s%s%s", first, second, third);
1366  }
1367 
1368  colorlen = add_index_color(buf, buflen, flags, MT_COLOR_INDEX_FLAGS);
1369  mutt_format_s(buf + colorlen, buflen - colorlen, prec, tmp);
1370  add_index_color(buf + colorlen, buflen - colorlen, flags, MT_COLOR_INDEX);
1371  break;
1372 
1373  case '@':
1374  {
1375  const char *end = src;
1376  static unsigned char recurse = 0;
1377 
1378  while ((*end != '\0') && (*end != '@'))
1379  end++;
1380  if ((*end == '@') && (recurse < 20))
1381  {
1382  recurse++;
1383  mutt_strn_copy(tmp, src, end - src, sizeof(tmp));
1384  mutt_expando_format(tmp, sizeof(tmp), col, cols,
1385  NONULL(mutt_idxfmt_hook(tmp, m, e)),
1386  index_format_str, data, flags);
1387  mutt_format_s_x(buf, buflen, prec, tmp, true);
1388  recurse--;
1389 
1390  src = end + 1;
1391  break;
1392  }
1393  }
1394  /* fallthrough */
1395 
1396  default:
1397  snprintf(buf, buflen, "%%%s%c", prec, op);
1398  break;
1399  }
1400 
1401  if (optional)
1402  {
1403  mutt_expando_format(buf, buflen, col, cols, if_str, index_format_str,
1404  (intptr_t) hfi, flags);
1405  }
1406  else if (flags & MUTT_FORMAT_OPTIONAL)
1407  {
1408  mutt_expando_format(buf, buflen, col, cols, else_str, index_format_str,
1409  (intptr_t) hfi, flags);
1410  }
1411 
1412  return src;
1413 }
1414 
1427 void mutt_make_string(char *buf, size_t buflen, int cols, const char *s,
1428  struct Mailbox *m, int inpgr, struct Email *e,
1429  MuttFormatFlags flags, const char *progress)
1430 {
1431  struct HdrFormatInfo hfi = { 0 };
1432 
1433  hfi.email = e;
1434  hfi.mailbox = m;
1435  hfi.msg_in_pager = inpgr;
1436  hfi.pager_progress = progress;
1437 
1438  mutt_expando_format(buf, buflen, 0, cols, s, index_format_str, (intptr_t) &hfi, flags);
1439 }
lib.h
Envelope
The header of an Email.
Definition: envelope.h:54
check_for_mailing_list_addr
bool check_for_mailing_list_addr(struct AddressList *al, char *buf, int buflen)
Check an address list for a mailing list.
Definition: maillist.c:103
maillist.h
C_ToChars
struct MbTable * C_ToChars
Config: Indicator characters for the 'To' field in the index.
Definition: hdrline.c:67
Email::date_sent
time_t date_sent
Time when the message was sent (UTC)
Definition: email.h:82
Email::msgno
int msgno
Number displayed to the user.
Definition: email.h:87
Envelope::subject
char * subject
Email's subject.
Definition: envelope.h:66
Envelope::bcc
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:60
make_from
static void make_from(struct Envelope *env, char *buf, size_t buflen, bool do_lists, MuttFormatFlags flags)
Generate a From: field (with optional prefix)
Definition: hdrline.c:225
DISP_MAX
@ DISP_MAX
Definition: hdrline.c:122
FLAG_CHAR_REPLIED
@ FLAG_CHAR_REPLIED
Character denoting an email that has been replied to.
Definition: hdrline.c:89
get_nth_wchar
static const char * get_nth_wchar(struct MbTable *table, int index)
Extract one char from a multi-byte table.
Definition: hdrline.c:172
MT_COLOR_INDEX_DATE
@ MT_COLOR_INDEX_DATE
Index: date field.
Definition: color.h:107
FLAG_CHAR_CRYPT_SIGNED
@ FLAG_CHAR_CRYPT_SIGNED
Character denoting a message is signed.
Definition: hdrline.c:105
DISP_FROM
@ DISP_FROM
From: string.
Definition: hdrline.c:120
mutt_replacelist_apply
char * mutt_replacelist_apply(struct ReplaceList *rl, char *buf, size_t buflen, const char *str)
Apply replacements to a buffer.
Definition: regex.c:353
make_from_addr
static void make_from_addr(struct Envelope *env, char *buf, size_t buflen, bool do_lists)
Create a 'from' address for a reply email.
Definition: hdrline.c:281
NONULL
#define NONULL(x)
Definition: string2.h:37
HdrFormatInfo::msg_in_pager
int msg_in_pager
Definition: hdrline.c:75
Mailbox
A mailbox.
Definition: mailbox.h:81
CryptChars
CryptChars
Index into the $crypt_chars variable ($crypt_chars)
Definition: hdrline.c:101
SORT_THREADS
@ SORT_THREADS
Sort by email threads.
Definition: sort2.h:51
nm_email_get_folder_rel_db
char * nm_email_get_folder_rel_db(struct Mailbox *m, struct Email *e)
Get the folder for a Email from the same level as the notmuch database.
Definition: notmuch.c:1558
Email::lines
int lines
How many lines in the body of this message?
Definition: email.h:85
Envelope::message_id
char * message_id
Message ID.
Definition: envelope.h:69
C_FromChars
struct MbTable * C_FromChars
Config: User-configurable index flags: to address, cc address, etc.
Definition: hdrline.c:66
mutt_make_string
void mutt_make_string(char *buf, size_t buflen, int cols, const char *s, struct Mailbox *m, int inpgr, struct Email *e, MuttFormatFlags flags, const char *progress)
Create formatted strings using mailbox expandos.
Definition: hdrline.c:1427
HdrFormatInfo::mailbox
struct Mailbox * mailbox
Definition: hdrline.c:74
Envelope::organization
char * organization
Organisation header.
Definition: envelope.h:73
MT_COLOR_INDEX_LABEL
@ MT_COLOR_INDEX_LABEL
Index: label field.
Definition: color.h:108
MUTT_FORMAT_FORCESUBJ
#define MUTT_FORMAT_FORCESUBJ
Print the subject even if unchanged.
Definition: format_flags.h:31
user_in_addr
static bool user_in_addr(struct AddressList *al)
Do any of the addresses refer to the user?
Definition: hdrline.c:311
Email::thread
struct MuttThread * thread
Thread of Emails.
Definition: email.h:95
mutt_get_name
const char * mutt_get_name(const struct Address *a)
Pick the best name to display from an address.
Definition: sort.c:158
MT_COLOR_INDEX_AUTHOR
@ MT_COLOR_INDEX_AUTHOR
Index: author field (takes a pattern)
Definition: color.h:101
FLAG_CHAR_NEW_THREAD
@ FLAG_CHAR_NEW_THREAD
Character denoting a thread containing at least one new email.
Definition: hdrline.c:93
FLAG_CHAR_SEMPTY
@ FLAG_CHAR_SEMPTY
Character denoting a read email, $index_format S expando.
Definition: hdrline.c:94
email_size
size_t email_size(const struct Email *e)
compute the size of an email
Definition: email.c:117
mutt_buffer_is_empty
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
make_from_prefix
static const char * make_from_prefix(enum FieldType disp)
Create a prefix for an author field.
Definition: hdrline.c:191
format_flags.h
SEC_ENCRYPT
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
DISP_CC
@ DISP_CC
Cc: string.
Definition: hdrline.c:118
SEC_SIGN
#define SEC_SIGN
Email is signed.
Definition: lib.h:86
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
Envelope::x_label
char * x_label
X-Label.
Definition: envelope.h:72
Email::num_hidden
size_t num_hidden
Number of hidden messages in this view (only valid when collapsed is set)
Definition: email.h:75
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
TAILQ_FOREACH
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
mutt_parse.h
mutt_messages_in_thread
int mutt_messages_in_thread(struct Mailbox *m, struct Email *e, enum MessageInThread mit)
Count the messages in a thread.
Definition: mutt_thread.c:1476
mutt_format_s_x
void mutt_format_s_x(char *buf, size_t buflen, const char *prec, const char *s, bool arboreal)
Format a string like snprintf()
Definition: curs_lib.c:1211
mutt_globals.h
Envelope::x_comment_to
char * x_comment_to
List of 'X-comment-to' fields.
Definition: envelope.h:78
MUTT_FORMAT_TREE
#define MUTT_FORMAT_TREE
Draw the thread tree.
Definition: format_flags.h:32
FREE
#define FREE(x)
Definition: memory.h:40
check_for_mailing_list
bool check_for_mailing_list(struct AddressList *al, const char *pfx, char *buf, int buflen)
Search list of addresses for a mailing list.
Definition: maillist.c:79
DISP_TO
@ DISP_TO
To: string.
Definition: hdrline.c:117
SORT_MASK
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:80
MT_COLOR_INDEX_NUMBER
@ MT_COLOR_INDEX_NUMBER
Index: index number.
Definition: color.h:109
STAILQ_EMPTY
#define STAILQ_EMPTY(head)
Definition: queue.h:345
MUTT_FORMAT_NO_FLAGS
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
FLAG_CHAR_TAGGED
@ FLAG_CHAR_TAGGED
Character denoting a tagged email.
Definition: hdrline.c:85
Email::recipient
short recipient
User_is_recipient()'s return value, cached.
Definition: email.h:78
MIT_NUM_MESSAGES
@ MIT_NUM_MESSAGES
Definition: mutt_thread.h:84
Email::zoccident
bool zoccident
True, if west of UTC, False if east.
Definition: email.h:65
FLAG_CHAR_DELETED
@ FLAG_CHAR_DELETED
Character denoting a deleted email.
Definition: hdrline.c:87
MT_COLOR_INDEX_TAGS
@ MT_COLOR_INDEX_TAGS
Index: tags field (g, J)
Definition: color.h:111
Email::tree
char * tree
Character string to print thread tree.
Definition: email.h:94
mutt_strn_copy
char * mutt_strn_copy(char *dest, const char *src, size_t len, size_t dsize)
Copy a sub-string into a buffer.
Definition: string.c:528
MuttThread::prev
struct MuttThread * prev
Previous sibling Thread.
Definition: thread.h:48
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
mutt_hash_find
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:354
MuttThread::parent
struct MuttThread * parent
Parent of this Thread.
Definition: thread.h:45
driver_tags_get_transformed
char * driver_tags_get_transformed(struct TagList *list)
Get transformed tags.
Definition: tags.c:132
lib.h
Envelope::reply_to
struct AddressList reply_to
Email's 'reply-to'.
Definition: envelope.h:62
C_SaveAddress
WHERE bool C_SaveAddress
Config: Use sender's full address as a default save folder.
Definition: mutt_globals.h:157
Email::old
bool old
Email is seen, but unread.
Definition: email.h:50
Email::received
time_t received
Time when the message was placed in the mailbox.
Definition: email.h:83
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
MIT_POSITION
@ MIT_POSITION
Definition: mutt_thread.h:85
mutt_str_pretty_size
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1663
Envelope::cc
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
thread_is_new
static bool thread_is_new(struct Email *e)
Does the email thread contain any new emails?
Definition: hdrline.c:395
thread_is_old
static bool thread_is_old(struct Email *e)
Does the email thread contain any unread emails?
Definition: hdrline.c:405
Mailbox::type
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
lib.h
muttlib.h
Email::tagged
bool tagged
Email is tagged.
Definition: email.h:44
mutt_count_body_parts
int mutt_count_body_parts(struct Mailbox *m, struct Email *e)
Count the MIME Body parts.
Definition: mutt_parse.c:208
Email::zminutes
unsigned int zminutes
Minutes away from UTC.
Definition: email.h:64
Body::length
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
APPLICATION_PGP
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
mutt_menu.h
lib.h
lib.h
mutt_date_localtime
struct tm mutt_date_localtime(time_t t)
Converts calendar time to a broken-down time structure expressed in user timezone.
Definition: date.c:643
MuttThread::message
struct Email * message
Email this Thread refers to.
Definition: thread.h:49
MbTable::len
int len
Number of characters.
Definition: mbtable.h:38
Mailbox::msg_count
int msg_count
Total number of messages.
Definition: mailbox.h:91
C_CryptChars
struct MbTable * C_CryptChars
Config: User-configurable crypto flags: signed, encrypted etc.
Definition: hdrline.c:64
MbTable::chars
char ** chars
The array of multibyte character strings.
Definition: mbtable.h:39
user_is_recipient
static int user_is_recipient(struct Email *e)
Is the user a recipient of the message.
Definition: hdrline.c:331
MUTT_FORMAT_INDEX
#define MUTT_FORMAT_INDEX
This is a main index entry.
Definition: format_flags.h:36
FLAG_CHAR_OLD
@ FLAG_CHAR_OLD
Character denoting an email that has been read.
Definition: hdrline.c:90
MUTT_NOTMUCH
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:54
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
MT_COLOR_INDEX_COLLAPSED
@ MT_COLOR_INDEX_COLLAPSED
Index: number of messages in collapsed thread.
Definition: color.h:106
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
FLAG_CHAR_CRYPT_NO_CRYPTO
@ FLAG_CHAR_CRYPT_NO_CRYPTO
Character denoting a message has no cryptography information.
Definition: hdrline.c:107
FLAG_CHAR_NEW
@ FLAG_CHAR_NEW
Character denoting an unread email.
Definition: hdrline.c:91
Email::flagged
bool flagged
Marked important?
Definition: email.h:43
Email::zhours
unsigned int zhours
Hours away from UTC.
Definition: email.h:63
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
first_mailing_list
bool first_mailing_list(char *buf, size_t buflen, struct AddressList *al)
Get the first mailing list in the list of addresses.
Definition: maillist.c:125
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
MT_COLOR_INDEX_SIZE
@ MT_COLOR_INDEX_SIZE
Index: size field.
Definition: color.h:110
Envelope::disp_subj
char * disp_subj
Display subject (modified copy of subject)
Definition: envelope.h:68
MUTT_FORMAT_PLAIN
#define MUTT_FORMAT_PLAIN
Do not prepend DISP_TO, DISP_CC ...
Definition: format_flags.h:38
Email::security
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:39
FLAG_CHAR_CRYPT_CONTAINS_KEY
@ FLAG_CHAR_CRYPT_CONTAINS_KEY
Character denoting a message contains a PGP key.
Definition: hdrline.c:106
mutt_date_epoch
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:416
apply_subject_mods
static char * apply_subject_mods(struct Envelope *env)
Apply regex modifications to the subject.
Definition: hdrline.c:372
DISP_BCC
@ DISP_BCC
Bcc: string.
Definition: hdrline.c:119
Email::collapsed
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:73
FLAG_CHAR_ZEMPTY
@ FLAG_CHAR_ZEMPTY
Character denoting a read email, $index_format Z expando.
Definition: hdrline.c:95
MUTT_DATE_NOW
#define MUTT_DATE_NOW
Constant representing the 'current time', see: mutt_date_gmtime(), mutt_date_localtime()
Definition: date.h:39
MT_COLOR_INDEX_TAG
@ MT_COLOR_INDEX_TAG
Index: tag field (g, takes a pattern)
Definition: color.h:104
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
Email::score
int score
Message score.
Definition: email.h:89
MUTT_FORMAT_OPTIONAL
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
WithCrypto
#define WithCrypto
Definition: lib.h:123
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
Envelope::newsgroups
char * newsgroups
List of newsgroups.
Definition: envelope.h:75
lib.h
lib.h
Email::deleted
bool deleted
Email is deleted.
Definition: email.h:45
lib.h
mutt_format_s_tree
void mutt_format_s_tree(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string with tree characters.
Definition: curs_lib.c:1260
Envelope::from
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
driver_tags_get_transformed_for
char * driver_tags_get_transformed_for(struct TagList *head, const char *name)
Get transformed tag for a tag name from a header.
Definition: tags.c:171
FLAG_CHAR_IMPORTANT
@ FLAG_CHAR_IMPORTANT
Character denoting a important (flagged) email.
Definition: hdrline.c:86
mutt_thread.h
MUTT_SPECIAL_INDEX
@ MUTT_SPECIAL_INDEX
Colour indicator.
Definition: mutt_thread.h:71
MT_COLOR_INDEX
@ MT_COLOR_INDEX
Index: default colour (takes a pattern)
Definition: color.h:100
C_Sort
WHERE short C_Sort
Config: Sort method for the index.
Definition: sort.h:60
TAILQ_NEXT
#define TAILQ_NEXT(elm, field)
Definition: queue.h:825
sort.h
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
FLAG_CHAR_DELETED_ATTACH
@ FLAG_CHAR_DELETED_ATTACH
Character denoting a deleted attachment.
Definition: hdrline.c:88
Email::tags
struct TagList tags
For drivers that support server tagging.
Definition: email.h:109
HdrFormatInfo::pager_progress
const char * pager_progress
Definition: hdrline.c:77
C_FlagChars
struct MbTable * C_FlagChars
Config: User-configurable index flags: tagged, new, etc.
Definition: hdrline.c:65
MT_COLOR_INDEX_FLAGS
@ MT_COLOR_INDEX_FLAGS
Index: flags field (takes a pattern)
Definition: color.h:102
mutt_idxfmt_hook
const char * mutt_idxfmt_hook(const char *name, struct Mailbox *m, struct Email *e)
Get index-format-hook format string.
Definition: hook.c:867
PGP_KEY
#define PGP_KEY
Definition: lib.h:106
mutt_date_gmtime
struct tm mutt_date_gmtime(time_t t)
Converts calendar time to a broken-down time structure expressed in UTC timezone.
Definition: date.c:661
Email::recip_valid
bool recip_valid
Is_recipient is valid.
Definition: email.h:58
Envelope::spam
struct Buffer spam
Spam header.
Definition: envelope.h:80
FlagChars
FlagChars
Index into the $flag_chars variable ($flag_chars)
Definition: hdrline.c:83
context.h
Email::index
int index
The absolute (unsorted) message number.
Definition: email.h:86
MT_COLOR_INDEX_SUBJECT
@ MT_COLOR_INDEX_SUBJECT
Index: subject field (takes a pattern)
Definition: color.h:103
HdrFormatInfo::email
struct Email * email
Definition: hdrline.c:76
MbTable
multibyte character table
Definition: mbtable.h:35
FieldType
FieldType
Header types.
Definition: hdrline.c:115
Email::attach_del
bool attach_del
Has an attachment marked for deletion.
Definition: email.h:49
mailbox_path
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:206
TagFormats
WHERE struct HashTable * TagFormats
Hash Table of tag-formats (tag -> format string)
Definition: mutt_globals.h:59
FLAG_CHAR_CRYPT_ENCRYPTED
@ FLAG_CHAR_CRYPT_ENCRYPTED
Character denoting a message is PGP-encrypted.
Definition: hdrline.c:104
C_DateFormat
WHERE char * C_DateFormat
Config: strftime format string for the d expando.
Definition: mutt_globals.h:89
Email::replied
bool replied
Email has been replied to.
Definition: email.h:54
Email
The envelope/body of an email.
Definition: email.h:37
lib.h
add_index_color
static size_t add_index_color(char *buf, size_t buflen, MuttFormatFlags flags, char color)
Insert a color marker into a string.
Definition: hdrline.c:135
FLAG_CHAR_CRYPT_GOOD_SIGN
@ FLAG_CHAR_CRYPT_GOOD_SIGN
Character denoting a message signed with a verified key.
Definition: hdrline.c:103
MUTT_FORMAT_NOFILTER
#define MUTT_FORMAT_NOFILTER
Do not allow filtering on this pass.
Definition: format_flags.h:37
Email::read
bool read
Email is read.
Definition: email.h:51
SubjectRegexList
struct ReplaceList SubjectRegexList
List of regexes to tidy the view of the email's subject.
Definition: globals.c:53
hook.h
HdrFormatInfo
Data passed to index_format_str()
Definition: hdrline.c:72
SEC_GOODSIGN
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:87
mutt_mb_get_initials
bool mutt_mb_get_initials(const char *name, char *buf, size_t buflen)
Turn a name into initials.
Definition: mbyte.c:84
hdrline.h
Address
An email address.
Definition: address.h:34
mutt_addr_is_user
bool mutt_addr_is_user(const struct Address *addr)
Does the address belong to the user.
Definition: alias.c:556
mutt_addr_for_display
const char * mutt_addr_for_display(const struct Address *a)
Convert an Address for display purposes.
Definition: address.c:986
index_format_str
static const char * index_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 index list - Implements format_t.
Definition: hdrline.c:466
MuttFormatFlags
uint8_t MuttFormatFlags
Flags for mutt_expando_format(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: format_flags.h:29
Email::body
struct Body * body
List of MIME parts.
Definition: email.h:91
mutt_thread_contains_unread
#define mutt_thread_contains_unread(e)
Definition: mutt_thread.h:91
DISP_PLAIN
@ DISP_PLAIN
Empty string.
Definition: hdrline.c:121
FLAG_CHAR_OLD_THREAD
@ FLAG_CHAR_OLD_THREAD
Character denoting a thread of emails that has been read.
Definition: hdrline.c:92
mutt_str_copy
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:716