]> granicus.if.org Git - neomutt/commitdiff
port the old index-color mutt patch to mutt-kz
authorEric Davis <edavis@insanum.com>
Thu, 17 Oct 2013 20:18:43 +0000 (13:18 -0700)
committerRichard Russon <rich@flatcap.org>
Mon, 4 Apr 2016 15:30:07 +0000 (16:30 +0100)
added support for individual tag coloring added "Tags:" header output in
pager showing all tags added documentation for index object highlighting

color.c
copy.c
globals.h
hdrline.c
init.c
init.h
menu.c
mutt_curses.h
mutt_notmuch.c
mutt_notmuch.h

diff --git a/color.c b/color.c
index 1893b49971e72ceff171f391f50299ae721c1c8c..54c944f0a26a4b3cbba7908f11ec797c41459588 100644 (file)
--- a/color.c
+++ b/color.c
@@ -39,6 +39,9 @@ COLOR_LINE *ColorIndexList = NULL;
 COLOR_LINE *ColorIndexAuthorList = NULL;
 COLOR_LINE *ColorIndexFlagsList = NULL;
 COLOR_LINE *ColorIndexSubjectList = NULL;
+#ifdef USE_NOTMUCH
+COLOR_LINE *ColorIndexTagList = NULL;
+#endif
 
 /* local to this file */
 static int ColorQuoteSize;
@@ -106,6 +109,10 @@ static const struct mapping_t Fields[] =
   { "index_number",    MT_COLOR_INDEX_NUMBER },
   { "index_size",      MT_COLOR_INDEX_SIZE },
   { "index_subject",   MT_COLOR_INDEX_SUBJECT },
+#ifdef USE_NOTMUCH
+  { "index_tag",       MT_COLOR_INDEX_TAG },
+  { "index_tags",      MT_COLOR_INDEX_TAGS },
+#endif
   { "prompt",          MT_COLOR_PROMPT },
 #ifdef USE_SIDEBAR
   { "sidebar_divider", MT_COLOR_DIVIDER },
@@ -520,6 +527,10 @@ static int _mutt_parse_uncolor (BUFFER *buf, BUFFER *s, unsigned long data,
     mutt_do_uncolor (buf, s, &ColorIndexFlagsList, &do_cache, parse_uncolor);
   else if (object == MT_COLOR_INDEX_SUBJECT)
     mutt_do_uncolor (buf, s, &ColorIndexSubjectList, &do_cache, parse_uncolor);
+#ifdef USE_NOTMUCH
+  else if (object == MT_COLOR_INDEX_TAG)
+    mutt_do_uncolor(buf, s, &ColorIndexTagList, &do_cache, parse_uncolor);
+#endif
 
   if (do_cache && !option (OPTNOCURSES))
   {
@@ -765,7 +776,11 @@ _mutt_parse_color (BUFFER *buf, BUFFER *s, BUFFER *err,
       (object == MT_COLOR_INDEX) ||
       (object == MT_COLOR_INDEX_AUTHOR) ||
       (object == MT_COLOR_INDEX_FLAGS) ||
-      (object == MT_COLOR_INDEX_SUBJECT)) {
+      (object == MT_COLOR_INDEX_SUBJECT)
+#ifdef USE_NOTMUCH
+      || (object == MT_COLOR_INDEX_TAG)
+#endif
+      ) {
     if (!MoreArgs (s)) {
       strfcpy (err->data, _("too few arguments"), err->dsize);
       return -1;
@@ -844,6 +859,14 @@ _mutt_parse_color (BUFFER *buf, BUFFER *s, BUFFER *err,
                    fg, bg, attr, err, 1, match);
     set_option (OPTFORCEREDRAWINDEX);
   }
+#ifdef USE_NOTMUCH
+  else if (object == MT_COLOR_INDEX_TAG)
+  {
+    r = add_pattern (&ColorIndexTagList, buf->data, 1,
+                   fg, bg, attr, err, 1, match);
+    set_option (OPTFORCEREDRAWINDEX);
+  }
+#endif
   else if (object == MT_COLOR_QUOTED)
   {
     if (q_level >= ColorQuoteSize)
diff --git a/copy.c b/copy.c
index e5610c28e94274e67d81933f5d839e1cb6f8dd1a..4d325aa4e348c80bb363838af7d501de661124f5 100644 (file)
--- a/copy.c
+++ b/copy.c
 #include "mutt_idna.h"
 #include "mutt_curses.h"
 
+#ifdef USE_NOTMUCH
+#include "mutt_notmuch.h"
+#endif
+
 #include <string.h>
 #include <stdlib.h>
 #include <ctype.h>
@@ -347,7 +351,7 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix)
   if (h->env)
     flags |= (h->env->irt_changed ? CH_UPDATE_IRT : 0)
       | (h->env->refs_changed ? CH_UPDATE_REFS : 0);
-  
+
   if (mutt_copy_hdr (in, out, h->offset, h->content->offset, flags, prefix) == -1)
     return -1;
 
@@ -413,6 +417,15 @@ mutt_copy_header (FILE *in, HEADER *h, FILE *out, int flags, const char *prefix)
       fprintf (out, "Lines: %d\n", h->lines);
   }
 
+#ifdef USE_NOTMUCH
+  if (nm_header_get_tags(h))
+  {
+    fputs ("Tags: ", out);
+    fputs (nm_header_get_tags(h), out);
+    fputc ('\n', out);
+  }
+#endif
+
   if ((flags & CH_NONEWLINE) == 0)
   {
     if (flags & CH_PREFIX)
index 3d1669e58d26f53b66b807aa72338f6a15409da3..406c3e39a99e66d19cae88b2638daca123293ad8 100644 (file)
--- a/globals.h
+++ b/globals.h
@@ -163,6 +163,7 @@ WHERE HASH *Groups;
 WHERE HASH *ReverseAlias;
 #ifdef USE_NOTMUCH
 WHERE HASH *TagTransforms;
+WHERE HASH *TagFormats;
 #endif
 
 WHERE LIST *AutoViewList INITVAL(0);
index 564e9af48e2a99aedf672935c551dfc84508b6d1..919c8f34ea4c9d040c633828f31e50a6277de8c0 100644 (file)
--- a/hdrline.c
+++ b/hdrline.c
@@ -589,14 +589,20 @@ hdr_format_str (char *dest,
       else if (mutt_addr_is_user (hdr->env->from))
         optional = 0;
       break;
+
 #ifdef USE_NOTMUCH
     case 'g':
       if (!optional)
-        mutt_format_s (dest, destlen, prefix, nm_header_get_tags_transformed(hdr));
+      {
+        colorlen = add_index_color(dest, destlen, flags, MT_COLOR_INDEX_TAGS);
+        mutt_format_s (dest+colorlen, destlen-colorlen, prefix, nm_header_get_tags_transformed(hdr));
+        add_index_color(dest+colorlen, destlen-colorlen, flags, MT_COLOR_INDEX);
+      }
       else if (!nm_header_get_tags_transformed(hdr))
         optional = 0;
       break;
 #endif
+
     case 'H':
       /* (Hormel) spam score */
       if (optional)
@@ -904,6 +910,48 @@ hdr_format_str (char *dest,
 
       break;
 
+#ifdef USE_NOTMUCH
+    case 'G':
+    {
+      char *tag_transformed;
+      char format[3];
+      char *tag;
+
+      if (!optional)
+      {
+        format[0] = op;
+        format[1] = *src;
+        format[2] = 0;
+
+        tag = hash_find(TagFormats, format);
+        if (tag != NULL)
+        {
+            tag_transformed = nm_header_get_tag_transformed(tag, hdr);
+
+            colorlen = add_index_color(dest, destlen, flags, MT_COLOR_INDEX_TAG);
+            mutt_format_s (dest+colorlen, destlen-colorlen, prefix,
+                           (tag_transformed) ? tag_transformed : "");
+            add_index_color(dest+colorlen, destlen-colorlen, flags, MT_COLOR_INDEX);
+        }
+
+        src++;
+      }
+      else
+      {
+        format[0] = op;
+        format[1] = *prefix;
+        format[2] = 0;
+
+        tag = hash_find(TagFormats, format);
+        if (tag != NULL)
+          if (nm_header_get_tag_transformed(tag, hdr) == NULL)
+            optional = 0;
+      }
+
+      break;
+    }
+#endif
+
     default:
       snprintf (dest, destlen, "%%%s%c", prefix, op);
       break;
diff --git a/init.c b/init.c
index 7f3b20b01f039734a000b6311f095163380c7e9a..81397728f5dcfaee8e6eb9437e62058bb64adc31 100644 (file)
--- a/init.c
+++ b/init.c
@@ -3072,6 +3072,7 @@ void mutt_init (int skip_sys_rc, LIST *commands)
   ReverseAlias = hash_create (1031, 1);
 #ifdef USE_NOTMUCH
   TagTransforms = hash_create (64, 1);
+  TagFormats = hash_create (64, 0);
 #endif
 
   mutt_menu_init ();
@@ -3440,6 +3441,37 @@ int parse_tag_transforms (BUFFER *b, BUFFER *s, unsigned long data, BUFFER *err)
   }
   return 0;
 }
+
+int parse_tag_formats (BUFFER *b, BUFFER *s, unsigned long data, BUFFER *err)
+{
+  char *tmp;
+
+  while (MoreArgs (s))
+  {
+    char *tag, *format;
+
+    mutt_extract_token (b, s, 0);
+    if (b->data && *b->data)
+      tag = safe_strdup (b->data);
+    else
+      continue;
+
+    mutt_extract_token (b, s, 0);
+    format = safe_strdup (b->data);
+
+    /* avoid duplicates */
+    tmp = hash_find(TagFormats, format);
+    if (tmp) {
+      dprint(3,(debugfile,"tag format '%s' already registered as '%s'\n", format, tmp));
+      FREE(&tag);
+      FREE(&format);
+      continue;
+    }
+
+    hash_insert(TagFormats, format, tag, 0);
+  }
+  return 0;
+}
 #endif
 
 static void myvar_set (const char* var, const char* val)
diff --git a/init.h b/init.h
index 4b2293cbf8d9ff679358b251d3403c048f1f3d11..ffad0a08f61f7d8aa56e4e9c24aa68fad7c57e69 100644 (file)
--- a/init.h
+++ b/init.h
@@ -3924,6 +3924,7 @@ static int parse_group_context (group_context_t **ctx, BUFFER *buf, BUFFER *s, u
 
 #ifdef USE_NOTMUCH
 static int parse_tag_transforms (BUFFER *, BUFFER *, unsigned long, BUFFER *);
+static int parse_tag_formats (BUFFER *, BUFFER *, unsigned long, BUFFER *);
 #endif
 
 struct command_t
@@ -3967,7 +3968,8 @@ const struct command_t Commands[] = {
   { "unmailboxes",     mutt_parse_mailboxes,   M_UNMAILBOXES },
 #ifdef USE_NOTMUCH
   { "virtual-mailboxes",mutt_parse_virtual_mailboxes, 0 },
-  { "tag-transforms",parse_tag_transforms, 0 },
+  { "tag-transforms",  parse_tag_transforms,   0 },
+  { "tag-formats",     parse_tag_formats,      0 },
 #endif
   { "mailto_allow",    parse_list,             UL &MailtoAllow },
   { "unmailto_allow",  parse_unlist,           UL &MailtoAllow },
diff --git a/menu.c b/menu.c
index dec077428bdafc162e5fe4e19360664c6111360d..e1aaa51adce41e9772d3a6850ca9644e0ca674af 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -50,6 +50,17 @@ get_color (int index, unsigned char *s)
                case MT_COLOR_INDEX_SUBJECT:
                        color = ColorIndexSubjectList;
                        break;
+#ifdef USE_NOTMUCH
+                case MT_COLOR_INDEX_TAG:
+                        for (color = ColorIndexTagList; color; color = color->next)
+                        {
+                               const char * transform = hash_find(TagTransforms, color->pattern);
+                               if (transform && (strncmp((const char *)(s+1),
+                                   transform, strlen(transform)) == 0))
+                                       return color->pair;
+                        }
+                        return 0;
+#endif
                default:
                        return ColorDefs[type];
        }
index 5804b5f0a3c1b05317eea9f97dd582640c592046..ce7a07bd6535e6e076d00b21851187cbfd5a26a8 100644 (file)
@@ -136,6 +136,9 @@ enum
   MT_COLOR_SB_SPOOLFILE,
 #endif
   /* please no non-MT_COLOR_INDEX objects after this point */
+#ifdef USE_NOTMUCH
+  MT_COLOR_INDEX_TAG,
+#endif
   MT_COLOR_INDEX,
   MT_COLOR_INDEX_AUTHOR,
   MT_COLOR_INDEX_FLAGS,
@@ -146,6 +149,9 @@ enum
   MT_COLOR_INDEX_LABEL,
   MT_COLOR_INDEX_NUMBER,
   MT_COLOR_INDEX_SIZE,
+#ifdef USE_NOTMUCH
+  MT_COLOR_INDEX_TAGS,
+#endif
   MT_COLOR_MAX
 };
 
@@ -204,6 +210,9 @@ extern COLOR_LINE *ColorIndexList;
 extern COLOR_LINE *ColorIndexAuthorList;
 extern COLOR_LINE *ColorIndexFlagsList;
 extern COLOR_LINE *ColorIndexSubjectList;
+#ifdef USE_NOTMUCH
+extern COLOR_LINE *ColorIndexTagList;
+#endif
 
 void ci_init_color (void);
 void ci_start_color (void);
index d4142dcee5ff30f46ad96a80df844b5356770dc1..32dcf445584262fc63b02bf22722662adba8b4bb 100644 (file)
@@ -67,6 +67,7 @@ struct nm_hdrdata {
        char *folder;
        char *tags;
        char *tags_transformed;
+       NM_HDR_TAG *tag_list;
        char *oldpath;
        int magic;
 };
@@ -169,6 +170,21 @@ err:
        return -1;
 }
 
+static void free_tag_list(NM_HDR_TAG **tag_list)
+{
+       NM_HDR_TAG *tmp;
+
+       while ((tmp = *tag_list) != NULL)
+       {
+               *tag_list = tmp->next;
+               FREE(&tmp->tag);
+               FREE(&tmp->transformed);
+               FREE(&tmp);
+       }
+
+       *tag_list = 0;
+}
+
 static void free_hdrdata(struct nm_hdrdata *data)
 {
        if (!data)
@@ -178,6 +194,7 @@ static void free_hdrdata(struct nm_hdrdata *data)
        FREE(&data->folder);
        FREE(&data->tags);
        FREE(&data->tags_transformed);
+       free_tag_list(&data->tag_list);
        FREE(&data->oldpath);
        FREE(&data);
 }
@@ -278,6 +295,29 @@ char *nm_header_get_tags_transformed(HEADER *h)
        return h && h->data ? ((struct nm_hdrdata *) h->data)->tags_transformed : NULL;
 }
 
+NM_HDR_TAG *nm_header_get_tags_list(HEADER *h)
+{
+       return h && h->data ? ((struct nm_hdrdata *) h->data)->tag_list : NULL;
+}
+
+char *nm_header_get_tag_transformed(char *tag, HEADER *h)
+{
+       NM_HDR_TAG *tmp;
+
+       if (!h || !h->data)
+               return NULL;
+
+       for (tmp = ((struct nm_hdrdata *) h->data)->tag_list;
+            tmp != NULL;
+            tmp = tmp->next)
+       {
+               if (strcmp(tag, tmp->tag) == 0)
+                       return tmp->transformed;
+       }
+
+       return NULL;
+}
+
 int nm_header_get_magic(HEADER *h)
 {
        return h && h->data ? ((struct nm_hdrdata *) h->data)->magic : 0;
@@ -554,6 +594,8 @@ static int update_header_tags(HEADER *h, notmuch_message_t *msg)
        notmuch_tags_t *tags;
        char *tstr = NULL, *ttstr = NULL, *p;
        size_t sz = 0, tsz = 0;
+       NM_HDR_TAG *tag_list = NULL;
+       NM_HDR_TAG *tmp;
 
        dprint(2, (debugfile, "nm: tags update requested (%s)\n", h->env->message_id));
 
@@ -609,20 +651,31 @@ static int update_header_tags(HEADER *h, notmuch_message_t *msg)
                }
                memcpy(p, t, xsz + 1);
                sz += xsz;
+
+               tmp = safe_calloc(1, sizeof(NM_HDR_TAG));
+               tmp->tag = safe_strdup(t);
+               tmp->transformed = safe_strdup(tt);
+               tmp->next = tag_list;
+               tag_list = tmp;
        }
 
        if (data->tags && tstr && strcmp(data->tags, tstr) == 0) {
                FREE(&tstr);
                FREE(&ttstr);
+               free_tag_list(&tag_list);
                dprint(2, (debugfile, "nm: tags unchanged\n"));
                return 1;
        }
 
        FREE(&data->tags);
+       FREE(&data->tags_transformed);
+       free_tag_list(&data->tag_list);
+
        data->tags = tstr;
        dprint(2, (debugfile, "nm: new tags: '%s'\n", tstr));
        data->tags_transformed = ttstr;
        dprint(2, (debugfile, "nm: new tag transforms: '%s'\n", ttstr));
+       data->tag_list = tag_list;
        return 0;
 }
 
index 33ba69630358ad75f2fa7958eb588d8a768c60f7..37657689d3023e8bd432fe3a73ccc69479feb464 100644 (file)
@@ -31,4 +31,17 @@ int nm_get_all_tags(CONTEXT *ctx, char **tag_list, int *tag_count);
  */
 int nm_nonctx_get_count(char *path, int *all, int *new);
 
+/*
+ * HEADER->(nm_hdrdata *)data->tag_list node
+ */
+typedef struct nm_hdr_tag
+{
+  char *tag;
+  char *transformed;
+  struct nm_hdr_tag *next;
+} NM_HDR_TAG;
+
+NM_HDR_TAG *nm_header_get_tags_list(HEADER *h);
+char *nm_header_get_tag_transformed(char *tag, HEADER *h);
+
 #endif /* _MUTT_NOTMUCH_H_ */