<div dir="ltr"><div>Hi,</div><div><br></div><div>I'm scratching an itch, here.  I want to limit email messages to those with</div><div>pdf attachments, or text/calendar, or images, etc.  Is a merge request</div><div>on gitlab preferable to a patch like this?</div><div><br></div><div>Cheers,</div><div>Ammon</div><div><br></div><div>---</div><div> doc/manual.xml.head |  2 ++</div><div> doc/muttrc.man.head |  6 ++++++</div><div> mutt.h              |  1 +</div><div> pattern.c           | 30 +++++++++++++++++++++++++++++-</div><div> 4 files changed, 38 insertions(+), 1 deletion(-)</div><div><br></div><div>diff --git a/doc/manual.xml.head b/doc/manual.xml.head</div><div>index 0188803..3596c1b 100644</div><div>--- a/doc/manual.xml.head</div><div>+++ b/doc/manual.xml.head</div><div>@@ -5199,6 +5199,8 @@ shows several ways to select messages.</div><div> <row><entry>%L <emphasis>GROUP</emphasis></entry><entry>message either originated or received by any member of <emphasis>GROUP</emphasis></entry></row></div><div> <row><entry>~l</entry><entry>messages addressed to a known mailing list</entry></row></div><div> <row><entry>~m [<emphasis>MIN</emphasis>]-[<emphasis>MAX</emphasis>]</entry><entry>messages in the range <emphasis>MIN</emphasis> to <emphasis>MAX</emphasis> *)</entry></row></div><div>+<row><entry>~M <emphasis>EXPR</emphasis></entry><entry>messages which contain a mime Content-Type matching <emphasis>EXPR</emphasis></entry></row></div><div>+<row><entry>=M <emphasis>STRING</emphasis></entry><entry>messages which contain a mime Content-Type containing <emphasis>STRING</emphasis></entry></row></div><div> <row><entry>~n [<emphasis>MIN</emphasis>]-[<emphasis>MAX</emphasis>]</entry><entry>messages with a score in the range <emphasis>MIN</emphasis> to <emphasis>MAX</emphasis> *)</entry></row></div><div> <row><entry>~N</entry><entry>new messages</entry></row></div><div> <row><entry>~O</entry><entry>old messages</entry></row></div><div>diff --git a/doc/muttrc.man.head b/doc/muttrc.man.head</div><div>index 28591f0..b72e31d 100644</div><div>--- a/doc/muttrc.man.head</div><div>+++ b/doc/muttrc.man.head</div><div>@@ -575,6 +575,12 @@ messages either originated or received by any member of \fIGROUP\fP</div><div> ~m \fIMIN\fP-\fIMAX\fP</div><div> message in the range \fIMIN\fP to \fIMAX\fP</div><div> .TP</div><div>+~M \fIEXPR\fP</div><div>+messages which contain a mime Content-Type matching \fIEXPR\fP</div><div>+.TP</div><div>+=M \fISTRING\fP</div><div>+messages which contain a mime Content-Type containing \fISTRING\fP</div><div>+.TP</div><div> ~n \fIMIN\fP-\fIMAX\fP</div><div> messages with a score in the range \fIMIN\fP to \fIMAX\fP</div><div> .TP</div><div>diff --git a/mutt.h b/mutt.h</div><div>index 4fe7ce4..7c5bec2 100644</div><div>--- a/mutt.h</div><div>+++ b/mutt.h</div><div>@@ -253,6 +253,7 @@ enum</div><div>   MUTT_PGP_KEY,</div><div>   MUTT_XLABEL,</div><div>   MUTT_MIMEATTACH,</div><div>+  MUTT_MIMETYPE,</div><div>   </div><div>   /* Options for Mailcap lookup */</div><div>   MUTT_EDIT,</div><div>diff --git a/pattern.c b/pattern.c</div><div>index 285cbfa..2c70d5c 100644</div><div>--- a/pattern.c</div><div>+++ b/pattern.c</div><div>@@ -25,6 +25,7 @@</div><div> #include "keymap.h"</div><div> #include "mailbox.h"</div><div> #include "copy.h"</div><div>+#include "mime.h"</div><div> </div><div> #include <string.h></div><div> #include <stdlib.h></div><div>@@ -76,6 +77,7 @@ Flags[] =</div><div>   { 'l', MUTT_LIST,            0,              NULL },</div><div>   { 'L', MUTT_ADDRESS,         0,              eat_regexp },</div><div>   { 'm', MUTT_MESSAGE,         0,              eat_range },</div><div>+  { 'M', MUTT_MIMETYPE,                MUTT_FULL_MSG,  eat_regexp },</div><div>   { 'n', MUTT_SCORE,           0,              eat_range },</div><div>   { 'N', MUTT_NEW,                     0,              NULL },</div><div>   { 'O', MUTT_OLD,                     0,              NULL },</div><div>@@ -1138,6 +1140,29 @@ static int match_threadchildren(struct pattern_t *pat, pattern_exec_flag flags,</div><div>   return 0;</div><div> }</div><div> </div><div>+static int match_content_type(const pattern_t* pat, BODY *b)</div><div>+{</div><div>+  char buffer[STRING];</div><div>+  if (b == 0)</div><div>+    return 0;</div><div>+</div><div>+  if (snprintf(buffer, STRING, "%s/%s", TYPE (b), b->subtype) >= STRING)</div><div>+    buffer[STRING-1] = '\0';</div><div>+</div><div>+  if (b->subtype != 0 && (patmatch (pat, buffer) == 0))</div><div>+    return 1;</div><div>+  if (match_content_type (pat, b->parts))</div><div>+    return 1;</div><div>+  if (match_content_type (pat, b->next))</div><div>+    return 1;</div><div>+  return 0;</div><div>+}</div><div>+</div><div>+static int match_mime_content_type(const pattern_t *pat, CONTEXT *ctx, HEADER *hdr)</div><div>+{</div><div>+  mutt_parse_mime_message(ctx, hdr);</div><div>+  return match_content_type(pat, hdr->content);</div><div>+}</div><div> </div><div> /* Sets a value in the pattern_cache_t cache entry.</div><div>  * Normalizes the "true" value to 2. */</div><div>@@ -1158,7 +1183,6 @@ static int is_pattern_cache_set (int cache_entry)</div><div>   return cache_entry != 0;</div><div> }</div><div> </div><div>-</div><div> /*</div><div>  * flags: MUTT_MATCH_FULL_ADDRESS - match both personal and machine address</div><div>  * cache: For repeated matches against the same HEADER, passing in non-NULL will</div><div>@@ -1338,6 +1362,10 @@ mutt_pattern_exec (struct pattern_t *pat, pattern_exec_flag flags, CONTEXT *ctx,</div><div>       return (pat->not ^ (count >= pat->min && (pat->max == MUTT_MAXRANGE ||</div><div>                                                 count <= pat->max)));</div><div>       }</div><div>+    case MUTT_MIMETYPE:</div><div>+      if (!ctx)</div><div>+        return 0;</div><div>+      return (pat->not ^ match_mime_content_type (pat, ctx, h));</div><div>     case MUTT_UNREFERENCED:</div><div>       return (pat->not ^ (h->thread && !h->thread->child));</div><div>   }</div><div>-- </div><div>2.8.0.rc3</div><div><br></div></div>