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;
{ "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 },
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))
{
(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;
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)
#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>
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;
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)
WHERE HASH *ReverseAlias;
#ifdef USE_NOTMUCH
WHERE HASH *TagTransforms;
+WHERE HASH *TagFormats;
#endif
WHERE LIST *AutoViewList INITVAL(0);
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)
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;
ReverseAlias = hash_create (1031, 1);
#ifdef USE_NOTMUCH
TagTransforms = hash_create (64, 1);
+ TagFormats = hash_create (64, 0);
#endif
mutt_menu_init ();
}
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)
#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
{ "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 },
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];
}
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,
MT_COLOR_INDEX_LABEL,
MT_COLOR_INDEX_NUMBER,
MT_COLOR_INDEX_SIZE,
+#ifdef USE_NOTMUCH
+ MT_COLOR_INDEX_TAGS,
+#endif
MT_COLOR_MAX
};
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);
char *folder;
char *tags;
char *tags_transformed;
+ NM_HDR_TAG *tag_list;
char *oldpath;
int magic;
};
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)
FREE(&data->folder);
FREE(&data->tags);
FREE(&data->tags_transformed);
+ free_tag_list(&data->tag_list);
FREE(&data->oldpath);
FREE(&data);
}
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;
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));
}
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;
}
*/
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_ */