+patch-compress-neomutt
+patch-cond-date-neomutt
+patch-fmemopen-neomutt
+patch-ifdef-neomutt
+patch-index-color-neomutt
+patch-initials-neomutt
+patch-keywords-neomutt
+patch-limit-current-thread-neomutt
+patch-lmdb-neomutt
+patch-nested-if-neomutt
+patch-new-mail-neomutt
+patch-nntp-neomutt
+ patch-notmuch-neomutt
+patch-progress-neomutt
+patch-quasi-delete-neomutt
+patch-sidebar-neomutt
+patch-skip-quoted-neomutt
+patch-smime-encrypt-self-neomutt
+patch-status-color-neomutt
+patch-tls-sni-neomutt
#ifdef USE_IMAP
#include "imap.h"
#endif
+#ifdef USE_NNTP
+#include "nntp.h"
+#endif
+ #ifdef USE_NOTMUCH
+ #include "mutt_notmuch.h"
+ #endif
#include <stdlib.h>
#include <dirent.h>
return 0;
}
-#if 0 /* MERGE with "browser sort by description" patch */
- add_folder (menu, state, tmp->path, tmp->desc, NULL, tmp->msg_unread, tmp->msg_count);
-#endif
- add_folder (menu, state, tmp->path, NULL, tmp);
+ #ifdef USE_NOTMUCH
+ static int examine_vfolders (MUTTMENU *menu, struct browser_state *state)
+ {
+ BUFFY *tmp = VirtIncoming;
+
+ if (!VirtIncoming)
+ return (-1);
+ mutt_buffy_check (0);
+
+ init_state (state, menu);
+
+ do
+ {
+ if (mx_is_notmuch (tmp->path))
+ {
+ nm_nonctx_get_count(tmp->path, &tmp->msg_count, &tmp->msg_unread);
++ add_folder (menu, state, tmp->path, tmp->desc, NULL, tmp, NULL);
+ continue;
+ }
+ }
+ while ((tmp = tmp->next));
+ browser_sort (state);
+ return 0;
+ }
+ #endif
+
+/* get list of mailboxes/subscribed newsgroups */
static int examine_mailboxes (MUTTMENU *menu, struct browser_state *state)
{
struct stat s;
if (multiple)
menu->tag = file_tag;
+ #ifdef USE_NOTMUCH
+ if (flags & MUTT_SEL_VFOLDER) {
+ menu->make_entry = vfolder_entry;
+ menu->search = select_vfolder_search;
+ } else
+ #endif
+ menu->make_entry = folder_entry;
+
menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_FOLDER,
+#ifdef USE_NNTP
+ option (OPTNEWS) ? FolderNewsHelp :
+#endif
FolderHelp);
init_menu (&state, menu, title, sizeof (title), buffy);
tmp->magic = MUTT_POP;
else
#endif
+#ifdef USE_NNTP
+ if ((tmp->magic == MUTT_NNTP) || mx_is_nntp (tmp->path))
+ tmp->magic = MUTT_NNTP;
++#endif
+ #ifdef USE_NOTMUCH
+ if (mx_is_notmuch (tmp->path))
+ tmp->magic = MUTT_NOTMUCH;
else
#endif
if (stat (tmp->path, &sb) != 0 || (S_ISREG(sb.st_mode) && sb.st_size == 0) ||
/* check to see if the folder is the currently selected folder
* before polling */
if (!Context || !Context->path ||
- (( tmp->magic == MUTT_IMAP || tmp->magic == MUTT_POP )
+#ifdef USE_NNTP
+ (( tmp->magic == MUTT_IMAP || tmp->magic == MUTT_POP || tmp->magic == MUTT_NNTP )
+#else
+ (( tmp->magic == MUTT_IMAP || tmp->magic == MUTT_POP || tmp->magic == MUTT_NOTMUCH)
+#endif
? mutt_strcmp (tmp->path, Context->path) :
- (sb.st_dev != contex_sb.st_dev || sb.st_ino != contex_sb.st_ino)))
+ (sb.st_dev != contex_sb->st_dev || sb.st_ino != contex_sb->st_ino)))
{
switch (tmp->magic)
{
tmp->notified = 0;
else if (!tmp->notified)
BuffyNotify++;
+ }
+
+ /* Check all Incoming for new mail and total/new/flagged messages
+ * force: if true, ignore BuffyTimeout and check for new mail anyway
+ */
+ int mutt_buffy_check (int force)
+ {
+ BUFFY *tmp;
+ struct stat contex_sb;
+ time_t t;
+ int check_stats = 0;
+ contex_sb.st_dev=0;
+ contex_sb.st_ino=0;
+
+ #ifdef USE_IMAP
+ /* update postponed count as well, on force */
+ if (force)
+ mutt_update_num_postponed ();
+ #endif
+
+ /* fastest return if there are no mailboxes */
+ #ifdef USE_NOTMUCH
+ if (!Incoming && !VirtIncoming)
+ return 0;
+ #else
+ if (!Incoming)
+ return 0;
+ #endif
+ t = time (NULL);
+ if (!force && (t - BuffyTime < BuffyTimeout))
+ return BuffyCount;
+
+ if (option (OPTMAILCHECKSTATS) &&
+ (t - BuffyStatsTime >= BuffyCheckStatsInterval))
+ {
+ check_stats = 1;
+ BuffyStatsTime = t;
+ }
+
+ BuffyTime = t;
+ BuffyCount = 0;
+ BuffyNotify = 0;
+
+ #ifdef USE_IMAP
+ BuffyCount += imap_buffy_check (force, check_stats);
+ #endif
+
+ /* check device ID and serial number instead of comparing paths */
+ if (!Context || Context->magic == MUTT_IMAP || Context->magic == MUTT_POP
++#ifdef USE_NNTP
++ || Context->magic == MUTT_NNTP
++#endif
+ || stat (Context->path, &contex_sb) != 0)
+ {
+ contex_sb.st_dev=0;
+ contex_sb.st_ino=0;
}
+ for (tmp = Incoming; tmp; tmp = tmp->next)
+ buffy_check(tmp, &contex_sb, check_stats);
+
+ #ifdef USE_NOTMUCH
+ for (tmp = VirtIncoming; tmp; tmp = tmp->next)
+ buffy_check(tmp, &contex_sb, check_stats);
+ #endif
+
BuffyDoneTime = BuffyTime;
return (BuffyCount);
}
int ColorDefs[MT_COLOR_MAX];
COLOR_LINE *ColorHdrList = NULL;
COLOR_LINE *ColorBodyList = NULL;
+COLOR_LINE *ColorStatusList = NULL;
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;
{ "bold", MT_COLOR_BOLD },
{ "underline", MT_COLOR_UNDERLINE },
{ "index", MT_COLOR_INDEX },
+ { "progress", MT_COLOR_PROGRESS },
+ { "index_author", MT_COLOR_INDEX_AUTHOR },
+ { "index_collapsed", MT_COLOR_INDEX_COLLAPSED },
+ { "index_date", MT_COLOR_INDEX_DATE },
+ { "index_flags", MT_COLOR_INDEX_FLAGS },
+ { "index_label", MT_COLOR_INDEX_LABEL },
+ { "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 },
return 0;
}
-#if 0 /* MERGE with "index-color" patch */
+ if (object == MT_COLOR_BODY)
+ mutt_do_uncolor (buf, s, &ColorBodyList, &do_cache, parse_uncolor);
+ else if (object == MT_COLOR_HEADER)
+ mutt_do_uncolor (buf, s, &ColorHdrList, &do_cache, parse_uncolor);
+ else if (object == MT_COLOR_INDEX)
+ mutt_do_uncolor (buf, s, &ColorIndexList, &do_cache, parse_uncolor);
+ else if (object == MT_COLOR_INDEX_AUTHOR)
+ mutt_do_uncolor (buf, s, &ColorIndexAuthorList, &do_cache, parse_uncolor);
+ else if (object == MT_COLOR_INDEX_FLAGS)
+ 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
-#endif
- do
- {
- mutt_extract_token (buf, s, 0);
- if (!mutt_strcmp ("*", buf->data))
- {
- for (tmp = *list; tmp; )
- {
- if (!do_cache)
- do_cache = 1;
- last = tmp;
- tmp = tmp->next;
- mutt_free_color_line(&last, parse_uncolor);
- }
- *list = NULL;
- }
- else
- {
- for (last = NULL, tmp = *list; tmp; last = tmp, tmp = tmp->next)
- {
- if (!mutt_strcmp (buf->data, tmp->pattern))
- {
- if (!do_cache)
- do_cache = 1;
- dprint(1,(debugfile,"Freeing pattern \"%s\" from color list\n",
- tmp->pattern));
- if (last)
- last->next = tmp->next;
- else
- *list = tmp->next;
- mutt_free_color_line(&tmp, parse_uncolor);
- break;
- }
- }
- }
- }
- while (MoreArgs (s));
-
if (do_cache && !option (OPTNOCURSES))
{
/* extract a regular expression if needed */
-#if 0 /* MERGE with "index-color" patch */
+ if ((object == MT_COLOR_BODY) ||
+ (object == MT_COLOR_HEADER) ||
+ (object == MT_COLOR_INDEX) ||
+ (object == MT_COLOR_INDEX_AUTHOR) ||
+ (object == MT_COLOR_INDEX_FLAGS) ||
- (object == MT_COLOR_INDEX_SUBJECT))
- {
+ #ifdef USE_NOTMUCH
- || (object == MT_COLOR_INDEX_TAG)
++ (object == MT_COLOR_INDEX_TAG) ||
+ #endif
-#endif
- if (object == MT_COLOR_HEADER || object == MT_COLOR_BODY || object == MT_COLOR_INDEX)
- {
++ (object == MT_COLOR_INDEX_SUBJECT)) {
if (!MoreArgs (s))
{
strfcpy (err->data, _("too few arguments"), err->dsize);
#endif
if (object == MT_COLOR_HEADER)
- r = add_pattern (&ColorHdrList, buf->data, 0, fg, bg, attr, err,0);
+ r = add_pattern (&ColorHdrList, buf->data, 0, fg, bg, attr, err, 0, match);
else if (object == MT_COLOR_BODY)
- r = add_pattern (&ColorBodyList, buf->data, 1, fg, bg, attr, err, 0);
+ r = add_pattern (&ColorBodyList, buf->data, 1, fg, bg, attr, err, 0, match);
+ else if ((object == MT_COLOR_STATUS) && MoreArgs (s)) {
+ /* 'color status fg bg' can have up to 2 arguments:
+ * 0 arguments: sets the default status color (handled below by else part)
+ * 1 argument : colorize pattern on match
+ * 2 arguments: colorize nth submatch of pattern
+ */
+ mutt_extract_token (buf, s, 0);
+
+ if (MoreArgs (s)) {
+ BUFFER temporary;
+ memset (&temporary, 0, sizeof (BUFFER));
+ mutt_extract_token (&temporary, s, 0);
+ match = atoi (temporary.data);
+ FREE(&temporary.data);
+ }
+
+ if (MoreArgs (s)) {
+ strfcpy (err->data, _("too many arguments"), err->dsize);
+ return -1;
+ }
+
+ r = add_pattern (&ColorStatusList, buf->data, 1,
+ fg, bg, attr, err, 0, match);
+ }
else if (object == MT_COLOR_INDEX)
{
- r = add_pattern (&ColorIndexList, buf->data, 1, fg, bg, attr, err, 1);
+ r = add_pattern (&ColorIndexList, buf->data, 1,
+ fg, bg, attr, err, 1, match);
+ set_option (OPTFORCEREDRAWINDEX);
+ }
+ else if (object == MT_COLOR_INDEX_AUTHOR)
+ {
+ r = add_pattern (&ColorIndexAuthorList, buf->data, 1,
+ fg, bg, attr, err, 1, match);
+ set_option (OPTFORCEREDRAWINDEX);
+ }
+ else if (object == MT_COLOR_INDEX_FLAGS)
+ {
+ r = add_pattern (&ColorIndexFlagsList, buf->data, 1,
+ fg, bg, attr, err, 1, match);
+ set_option (OPTFORCEREDRAWINDEX);
+ }
+ else if (object == MT_COLOR_INDEX_SUBJECT)
+ {
+ r = add_pattern (&ColorIndexSubjectList, buf->data, 1,
+ fg, bg, attr, err, 1, match);
set_option (OPTFORCEREDRAWINDEX);
}
- fg, bg, attr, err, 1);
+ #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)
if (Context->hdrs[Context->v2r[i]]->tagged)
{
mutt_message_hook (Context, Context->hdrs[Context->v2r[i]], MUTT_MESSAGEHOOK);
+ if (_mutt_save_message(Context->hdrs[Context->v2r[i]],
+ &ctx, delete, decode, decrypt) != 0)
+ {
+ mx_close_mailbox (&ctx, NULL);
+ return -1;
+ }
+#ifdef USE_COMPRESSED
+ if (cm)
+ {
+ HEADER *h = Context->hdrs[Context->v2r[i]];
+ cm->msg_count++;
+ if (!h->read)
+ cm->msg_unread++;
+ if (h->flagged)
+ cm->msg_flagged++;
+ }
+#endif
+ if ((rc = _mutt_save_message(Context->hdrs[Context->v2r[i]],
+ &ctx, delete, decode, decrypt) != 0))
+ break;
}
}
+ #ifdef USE_NOTMUCH
+ if (Context->magic == MUTT_NOTMUCH)
+ nm_longrun_done(Context);
+ #endif
+ if (rc != 0) {
+ mx_close_mailbox (&ctx, NULL);
+ return -1;
+ }
}
need_buffy_cleanup = (ctx.magic == MUTT_MBOX || ctx.magic == MUTT_MMDF);
SMIMEAUX_TARGET="smime_keys"
fi
-AC_ARG_ENABLE(sidebar, AC_HELP_STRING([--enable-sidebar], [Enable Sidebar support]),
-[ if test x$enableval = xyes ; then
- AC_DEFINE(USE_SIDEBAR, 1, [Define if you want support for the sidebar.])
- OPS="$OPS \$(srcdir)/OPS.SIDEBAR"
- MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS sidebar.o"
- fi
+AC_ARG_ENABLE(sidebar, AC_HELP_STRING([--enable-sidebar], [Enable Sidebar support]), enable_sidebar=$enableval, enable_sidebar=no)
+AS_IF([test x$enable_sidebar = "xyes"], [
+ AC_DEFINE(USE_SIDEBAR, 1, [Define if you want support for the sidebar.])
+ OPS="$OPS \$(srcdir)/OPS.SIDEBAR"
+ MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS sidebar.o"
+])
+
+AC_ARG_ENABLE(compressed, AC_HELP_STRING([--enable-compressed], [Enable compressed folders support]),
+ enable_compressed=$enableval, enable_compressed=no
+)
+AS_IF([test x$enable_compressed = "xyes"], [
+ AC_DEFINE(USE_COMPRESSED, 1, [Define to enable compressed folders support.])
+ MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS compress.o"
])
+AM_CONDITIONAL(BUILD_COMPRESS, test x$enable_compressed = xyes)
+ AC_ARG_ENABLE(notmuch, AC_HELP_STRING([--enable-notmuch], [Enable NOTMUCH support]), enable_notmuch=$enableval, enable_notmuch=no)
+ AS_IF([test x$enable_notmuch = "xyes"], [
+ AC_CHECK_LIB(notmuch, notmuch_database_open,,
+ AC_MSG_ERROR([Unable to find Notmuch library]))
+ AC_DEFINE(USE_NOTMUCH,1,[ Define if you want support for the notmuch. ])
+ NOTMUCH_LIBS="-lnotmuch"
+ OPS="$OPS \$(srcdir)/OPS.NOTMUCH"
+ need_notmuch="yes"
+
+ AC_MSG_CHECKING([for notmuch api version 3])
+ AC_COMPILE_IFELSE( [AC_LANG_PROGRAM(
+ [[#include <notmuch.h>]],
+ [[notmuch_database_open("/path", NOTMUCH_DATABASE_MODE_READ_ONLY, (notmuch_database_t**)NULL);]]
+ )],
+ [notmuch_api_3=yes
+ AC_DEFINE([NOTMUCH_API_3], 1, [Define to 1 if you have the notmuch api version 3.])
+ ],
+ [notmuch_api_3=no]
+ )
+ AC_MSG_RESULT([$notmuch_api_3])
+ ])
+ AM_CONDITIONAL(BUILD_NOTMUCH, test x$need_notmuch = xyes)
+
+
AC_ARG_WITH(mixmaster, AS_HELP_STRING([--with-mixmaster@<:@=PATH@:>@],[Include Mixmaster support]),
[if test "$withval" != no
then
fprintf (out, "Lines: %d\n", h->lines);
}
+ #ifdef USE_NOTMUCH
+ if ((flags & CH_VIRTUAL) && nm_header_get_tags(h))
+ {
+ fputs ("Tags: ", out);
+ fputs (nm_header_get_tags(h), out);
+ fputc ('\n', out);
+ }
+ #endif
+
+ if (flags & CH_UPDATE_LABEL && h->label_changed)
+ {
+ h->label_changed = 0;
+ if (h->env->labels != NULL)
+ {
+ char buf[HUGE_STRING];
+ char *tmp = NULL;
+ int fail = 0;
+
+ if (fail == 0 &&
+ ((h->env->kwtypes & MUTT_X_LABEL) || (h->env->kwtypes == 0)) &&
+ (option(OPTKEYWORDSLEGACY) || option(OPTKEYWORDSSTANDARD) == 0))
+ {
+ mutt_labels(buf, sizeof(buf), h->env, XlabelDelim);
+ tmp = safe_strdup(buf);
+ rfc2047_encode_string(&tmp);
+ fail = fprintf(out, "X-Label: %s\n", tmp) != 10 + strlen(tmp);
+ FREE(&tmp);
+ }
+
+ if (fail == 0 && (h->env->kwtypes & MUTT_X_KEYWORDS) &&
+ (option(OPTKEYWORDSLEGACY) || option(OPTKEYWORDSSTANDARD) == 0))
+ {
+ mutt_labels(buf, sizeof(buf), h->env, " ");
+ tmp = safe_strdup(buf);
+ rfc2047_encode_string(&tmp);
+ fail = fprintf(out, "X-Keywords: %s\n", tmp) != 13 + strlen(tmp);
+ FREE(&tmp);
+ }
+
+ if (fail == 0 && (h->env->kwtypes & MUTT_X_MOZILLA_KEYS) &&
+ (option(OPTKEYWORDSLEGACY) || option(OPTKEYWORDSSTANDARD) == 0))
+ {
+ mutt_labels(buf, sizeof(buf), h->env, " ");
+ tmp = safe_strdup(buf);
+ rfc2047_encode_string(&tmp);
+ fail = fprintf(out, "X-Mozilla-Keys: %s\n", tmp) != 17 + strlen(tmp);
+ FREE(&tmp);
+ }
+
+ if (fail == 0 && ((h->env->kwtypes & MUTT_KEYWORDS) ||
+ option(OPTKEYWORDSSTANDARD)))
+ {
+ mutt_labels(buf, sizeof(buf), h->env, NULL);
+ tmp = safe_strdup(buf);
+ rfc2047_encode_string(&tmp);
+ fail = fprintf(out, "Keywords: %s\n", tmp) != 11 + strlen(tmp);
+ FREE(&tmp);
+ }
+
+ if (fail)
+ return -1;
+ }
+ }
+
if ((flags & CH_NONEWLINE) == 0)
{
if (flags & CH_PREFIX)
#define CH_UPDATE_IRT (1<<16) /* update In-Reply-To: */
#define CH_UPDATE_REFS (1<<17) /* update References: */
#define CH_DISPLAY (1<<18) /* display result to user */
-#define CH_VIRTUAL (1<<19) /* write virtual header lines too */
+#define CH_UPDATE_LABEL (1<<19) /* update X-Label: from hdr->env->x_label? */
++#define CH_VIRTUAL (1<<20) /* write virtual header lines too */
int mutt_copy_hdr (FILE *, FILE *, LOFF_T, LOFF_T, int, const char *);
#include "imap_private.h"
#endif
+ #ifdef USE_NOTMUCH
+ #include "mutt_notmuch.h"
+ #endif
+
#include "mutt_crypt.h"
+#ifdef USE_NNTP
+#include "nntp.h"
+#endif
+
#include <ctype.h>
#include <stdlib.h>
menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
}
- int *oldcount, int *index_hint)
+/**
+ * mutt_draw_statusline - Draw a highlighted status bar
+ * @cols: Maximum number of screen columns
+ * @buf: Message to be displayed
+ *
+ * Users configure the highlighting of the status bar, e.g.
+ * color status red default "[0-9][0-9]:[0-9][0-9]"
+ *
+ * Where regexes overlap, the one nearest the start will be used.
+ * If two regexes start at the same place, the longer match will be used.
+ */
+void
+mutt_draw_statusline (int cols, const char *buf, int buflen)
+{
+ int i = 0;
+ int offset = 0;
+ int found = 0;
+ int chunks = 0;
+ int len = 0;
+
+ struct syntax_t
+ {
+ int color;
+ int first;
+ int last;
+ } *syntax = NULL;
+
+ if (!buf)
+ return;
+
+ do
+ {
+ COLOR_LINE *cl;
+ found = 0;
+
+ if (!buf[offset])
+ break;
+
+ /* loop through each "color status regex" */
+ for (cl = ColorStatusList; cl; cl = cl->next)
+ {
+ regmatch_t pmatch[cl->match + 1];
+
+ if (regexec (&cl->rx, buf + offset, cl->match + 1, pmatch, 0) != 0)
+ continue; /* regex doesn't match the status bar */
+
+ int first = pmatch[cl->match].rm_so + offset;
+ int last = pmatch[cl->match].rm_eo + offset;
+
+ if (first == last)
+ continue; /* ignore an empty regex */
+
+ if (!found)
+ {
+ chunks++;
+ safe_realloc (&syntax, chunks * sizeof (struct syntax_t));
+ }
+
+ i = chunks - 1;
+ if (!found || (first < syntax[i].first) || ((first == syntax[i].first) && (last > syntax[i].last)))
+ {
+ syntax[i].color = cl->pair;
+ syntax[i].first = first;
+ syntax[i].last = last;
+ }
+ found = 1;
+ }
+
+ if (syntax)
+ {
+ offset = syntax[i].last;
+ }
+ } while (found);
+
+ /* Only 'len' bytes will fit into 'cols' screen columns */
+ len = mutt_wstr_trunc (buf, buflen, cols, NULL);
+
+ offset = 0;
+
+ if ((chunks > 0) && (syntax[0].first > 0))
+ {
+ /* Text before the first highlight */
+ addnstr (buf, MIN(len, syntax[0].first));
+ attrset (ColorDefs[MT_COLOR_STATUS]);
+ if (len <= syntax[0].first)
+ goto dsl_finish; /* no more room */
+
+ offset = syntax[0].first;
+ }
+
+ for (i = 0; i < chunks; i++)
+ {
+ /* Highlighted text */
+ attrset (syntax[i].color);
+ addnstr (buf + offset, MIN(len, syntax[i].last) - offset);
+ if (len <= syntax[i].last)
+ goto dsl_finish; /* no more room */
+
+ int next;
+ if ((i + 1) == chunks)
+ {
+ next = len;
+ }
+ else
+ {
+ next = MIN (len, syntax[i+1].first);
+ }
+
+ attrset (ColorDefs[MT_COLOR_STATUS]);
+ offset = syntax[i].last;
+ addnstr (buf + offset, next - offset);
+
+ offset = next;
+ if (offset >= len)
+ goto dsl_finish; /* no more room */
+ }
+
+ attrset (ColorDefs[MT_COLOR_STATUS]);
+ if (offset < len)
+ {
+ /* Text after the last highlight */
+ addnstr (buf + offset, len - offset);
+ }
+
+ int width = mutt_strwidth (buf);
+ if (width < cols)
+ {
+ /* Pad the rest of the line with whitespace */
+ mutt_paddstr (cols - width, "");
+ }
+dsl_finish:
+ FREE(&syntax);
+}
+
+ static int main_change_folder(MUTTMENU *menu, int op, char *buf, size_t bufsz,
++ int *oldcount, int *index_hint, int flags)
+ {
++#ifdef USE_NNTP
++ if (option (OPTNEWS))
++ {
++ unset_option (OPTNEWS);
++ nntp_expand_path (buf, bufsz, &CurrentNewsSrv->conn->account);
++ }
++ else
++#endif
+ mutt_expand_path (buf, bufsz);
+ if (mx_get_magic (buf) <= 0)
+ {
+ mutt_error (_("%s is not a mailbox."), buf);
+ return -1;
+ }
+ mutt_str_replace (&CurrentFolder, buf);
+
+ /* keepalive failure in mutt_enter_fname may kill connection. #3028 */
+ if (Context && !Context->path)
+ FREE (&Context);
+
+ if (Context)
+ {
+ int check;
+
++#ifdef USE_COMPRESSED
++ if (Context->compress_info && Context->realpath)
++ mutt_str_replace (&LastFolder, Context->realpath);
++ else
++#endif
+ mutt_str_replace (&LastFolder, Context->path);
+ *oldcount = Context ? Context->msgcount : 0;
+
+ if ((check = mx_close_mailbox (Context, index_hint)) != 0)
+ {
+ if (check == MUTT_NEW_MAIL || check == MUTT_REOPENED)
+ update_index (menu, Context, check, *oldcount, *index_hint);
+
+ set_option (OPTSEARCHINVALID);
+ menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
+ return 0;
+ }
+ FREE (&Context);
+ }
+
++ if (Labels)
++ hash_destroy(&Labels, NULL);
++
+ mutt_sleep (0);
+
+ /* Set CurrentMenu to MENU_MAIN before executing any folder
+ * hooks so that all the index menu functions are available to
+ * the exec command.
+ */
+
+ CurrentMenu = MENU_MAIN;
+ mutt_folder_hook (buf);
+
+ if ((Context = mx_open_mailbox (buf,
+ (option (OPTREADONLY) || op == OP_MAIN_CHANGE_FOLDER_READONLY) ?
+ MUTT_READONLY : 0, NULL)) != NULL)
+ {
++ Labels = hash_create(131, 0);
++ mutt_scan_labels(Context);
+ menu->current = ci_first_message ();
+ }
+ else
+ menu->current = 0;
+
+ #ifdef USE_SIDEBAR
+ mutt_sb_set_open_buffy ();
+ #endif
+
+ mutt_clear_error ();
+ mutt_buffy_check(1); /* force the buffy check after we have changed the folder */
+ menu->redraw = REDRAW_FULL;
+ set_option (OPTSEARCHINVALID);
+
+ return 0;
+ }
+
static const struct mapping_t IndexHelp[] = {
{ N_("Quit"), OP_QUIT },
{ N_("Del"), OP_DELETE },
mutt_curs_set (1); /* fallback from the pager */
}
+#ifdef USE_NNTP
+ unset_option (OPTNEWS); /* for any case */
+#endif
++
+ #ifdef USE_NOTMUCH
+ if (Context)
+ nm_debug_check(Context);
+ #endif
+
switch (op)
{
menu->redraw = REDRAW_FULL;
break;
- main_change_folder(menu, op, buf, sizeof (buf), &oldcount, &index_hint);
+ case OP_MAIN_QUASI_DELETE:
+ if (tag) {
+ for (j = 0; j < Context->vcount; j++) {
+ if (Context->hdrs[Context->v2r[j]]->tagged) {
+ Context->hdrs[Context->v2r[j]]->quasi_deleted = TRUE;
+ Context->changed = TRUE;
+ }
+ }
+ } else {
+ CURHDR->quasi_deleted = TRUE;
+ Context->changed = 1;
+ }
+ break;
+
+ #ifdef USE_NOTMUCH
+ case OP_MAIN_ENTIRE_THREAD:
+ {
+ int oldcount = Context->msgcount;
+ if (Context->magic != MUTT_NOTMUCH) {
+ mutt_message _("No virtual folder, aborting.");
+ break;
+ }
+ CHECK_MSGCOUNT;
+ CHECK_VISIBLE;
+ if (nm_read_entire_thread(Context, CURHDR) < 0) {
+ mutt_message _("Failed to read thread, aborting.");
+ break;
+ }
+ if (oldcount < Context->msgcount) {
+ HEADER *oldcur = CURHDR;
+
+ if ((Sort & SORT_MASK) == SORT_THREADS)
+ mutt_sort_headers (Context, 0);
+ menu->current = oldcur->virtual;
+ menu->redraw = REDRAW_STATUS | REDRAW_INDEX;
+
+ if (oldcur->collapsed || Context->collapsed) {
+ menu->current = mutt_uncollapse_thread(Context, CURHDR);
+ mutt_set_virtual(Context);
+ }
+ }
+ if (menu->menu == MENU_PAGER)
+ {
+ op = OP_DISPLAY_MESSAGE;
+ continue;
+ }
+ break;
+ }
+
+ case OP_MAIN_MODIFY_LABELS:
+ case OP_MAIN_MODIFY_LABELS_THEN_HIDE:
+ {
+ if (Context->magic != MUTT_NOTMUCH) {
+ mutt_message _("No virtual folder, aborting.");
+ break;
+ }
+ CHECK_MSGCOUNT;
+ CHECK_VISIBLE;
+ *buf = '\0';
+ if (mutt_get_field ("Add/remove labels: ", buf, sizeof (buf), MUTT_NM_TAG) || !*buf)
+ {
+ mutt_message _("No label specified, aborting.");
+ break;
+ }
+ if (tag)
+ {
+ char msgbuf[STRING];
+ progress_t progress;
+ int px;
+
+ if (!Context->quiet) {
+ snprintf(msgbuf, sizeof (msgbuf), _("Update labels..."));
+ mutt_progress_init(&progress, msgbuf, MUTT_PROGRESS_MSG,
+ 1, Context->tagged);
+ }
+ nm_longrun_init(Context, TRUE);
+ for (px = 0, j = 0; j < Context->vcount; j++) {
+ if (Context->hdrs[Context->v2r[j]]->tagged) {
+ if (!Context->quiet)
+ mutt_progress_update(&progress, ++px, -1);
+ nm_modify_message_tags(Context, Context->hdrs[Context->v2r[j]], buf);
+ if (op == OP_MAIN_MODIFY_LABELS_THEN_HIDE)
+ {
+ Context->hdrs[Context->v2r[j]]->quasi_deleted = TRUE;
+ Context->changed = TRUE;
+ }
+ }
+ }
+ nm_longrun_done(Context);
+ menu->redraw = REDRAW_STATUS | REDRAW_INDEX;
+ }
+ else
+ {
+ if (nm_modify_message_tags(Context, CURHDR, buf)) {
+ mutt_message _("Failed to modify labels, aborting.");
+ break;
+ }
+ if (op == OP_MAIN_MODIFY_LABELS_THEN_HIDE)
+ {
+ CURHDR->quasi_deleted = TRUE;
+ Context->changed = TRUE;
+ }
+ if (menu->menu == MENU_PAGER)
+ {
+ op = OP_DISPLAY_MESSAGE;
+ continue;
+ }
+ if (option (OPTRESOLVE))
+ {
+ if ((menu->current = ci_next_undeleted (menu->current)) == -1)
+ {
+ menu->current = menu->oldcurrent;
+ menu->redraw = REDRAW_CURRENT;
+ }
+ else
+ menu->redraw = REDRAW_MOTION_RESYNCH;
+ }
+ else
+ menu->redraw = REDRAW_CURRENT;
+ }
+ menu->redraw |= REDRAW_STATUS;
+ break;
+ }
+
+ case OP_MAIN_VFOLDER_FROM_QUERY:
+ buf[0] = '\0';
+ if (mutt_get_field ("Query: ", buf, sizeof (buf), MUTT_NM_QUERY) != 0 || !buf[0])
+ {
+ mutt_message _("No query, aborting.");
+ break;
+ }
+ if (!nm_uri_from_query(Context, buf, sizeof (buf)))
+ mutt_message _("Failed to create query, aborting.");
+ else
++ main_change_folder(menu, op, buf, sizeof (buf), &oldcount, &index_hint, 0);
+ break;
+
+ case OP_MAIN_CHANGE_VFOLDER:
+ #endif
++
#ifdef USE_SIDEBAR
case OP_SIDEBAR_OPEN:
#endif
case OP_MAIN_CHANGE_FOLDER:
case OP_MAIN_NEXT_UNREAD_MAILBOX:
-
- if (attach_msg)
- op = OP_MAIN_CHANGE_FOLDER_READONLY;
-
- /* fallback to the readonly case */
-
case OP_MAIN_CHANGE_FOLDER_READONLY:
+#ifdef USE_NNTP
+ case OP_MAIN_CHANGE_GROUP:
+ case OP_MAIN_CHANGE_GROUP_READONLY:
+ unset_option (OPTNEWS);
+#endif
+ if (attach_msg || option (OPTREADONLY) ||
+#ifdef USE_NNTP
+ op == OP_MAIN_CHANGE_GROUP_READONLY ||
+#endif
+ op == OP_MAIN_CHANGE_FOLDER_READONLY)
+ flags = MUTT_READONLY;
+ else
+ flags = 0;
- if ((op == OP_MAIN_CHANGE_FOLDER_READONLY) || option (OPTREADONLY))
+ if (flags)
cp = _("Open mailbox in read-only mode");
- else
+ #ifdef USE_NOTMUCH
+ else if (op == OP_MAIN_CHANGE_VFOLDER)
+ cp = _("Open virtual folder");
+ #endif
+ else
cp = _("Open mailbox");
buf[0] = '\0';
}
}
- #ifdef USE_NNTP
- if (option (OPTNEWS))
- {
- unset_option (OPTNEWS);
- nntp_expand_path (buf, sizeof (buf), &CurrentNewsSrv->conn->account);
- }
- else
- #endif
- mutt_expand_path (buf, sizeof (buf));
- if (mx_get_magic (buf) <= 0)
- {
- mutt_error (_("%s is not a mailbox."), buf);
- break;
- }
- mutt_str_replace (&CurrentFolder, buf);
-
- /* keepalive failure in mutt_enter_fname may kill connection. #3028 */
- if (Context && !Context->path)
- FREE (&Context);
-
- if (Context)
- {
- int check;
-
- #ifdef USE_COMPRESSED
- if (Context->compress_info && Context->realpath)
- mutt_str_replace (&LastFolder, Context->realpath);
- else
- #endif
- mutt_str_replace (&LastFolder, Context->path);
- oldcount = Context ? Context->msgcount : 0;
-
- if ((check = mx_close_mailbox (Context, &index_hint)) != 0)
- {
- if (check == MUTT_NEW_MAIL || check == MUTT_REOPENED)
- update_index (menu, Context, check, oldcount, index_hint);
-
- set_option (OPTSEARCHINVALID);
- menu->redraw = REDRAW_INDEX | REDRAW_STATUS;
- break;
- }
- FREE (&Context);
- }
-
- if (Labels)
- hash_destroy(&Labels, NULL);
-
- mutt_sleep (0);
-
- /* Set CurrentMenu to MENU_MAIN before executing any folder
- * hooks so that all the index menu functions are available to
- * the exec command.
- */
-
- CurrentMenu = MENU_MAIN;
- mutt_folder_hook (buf);
-
- if ((Context = mx_open_mailbox (buf, flags, NULL)) != NULL)
- {
- Labels = hash_create(131, 0);
- mutt_scan_labels(Context);
- menu->current = ci_first_message ();
- }
- else
- menu->current = 0;
-
- #ifdef USE_SIDEBAR
- mutt_sb_set_open_buffy ();
- #endif
-
- main_change_folder(menu, op, buf, sizeof (buf), &oldcount, &index_hint);
++ main_change_folder(menu, op, buf, sizeof (buf), &oldcount, &index_hint, flags);
+#ifdef USE_NNTP
+ /* mutt_buffy_check() must be done with mail-reader mode! */
+ menu->help = mutt_compile_help (helpstr, sizeof (helpstr), MENU_MAIN,
+ (Context && (Context->magic == MUTT_NNTP)) ? IndexNewsHelp : IndexHelp);
+#endif
- mutt_clear_error ();
- mutt_buffy_check(1); /* force the buffy check after we have changed
- the folder */
- menu->redraw = REDRAW_FULL;
- set_option (OPTSEARCHINVALID);
++ mutt_expand_path (buf, sizeof (buf));
++#ifdef USE_SIDEBAR
++ mutt_sb_set_open_buffy();
++#endif
break;
case OP_DISPLAY_MESSAGE:
WHERE const char *ReleaseDate;
WHERE HASH *Groups;
+WHERE HASH *Labels;
WHERE HASH *ReverseAlias;
+ #ifdef USE_NOTMUCH
+ WHERE HASH *TagTransforms;
+ WHERE HASH *TagFormats;
+ #endif
WHERE LIST *AutoViewList INITVAL(0);
WHERE LIST *AlternativeOrderList INITVAL(0);
* %E = number of messages in current thread
* %f = entire from line
* %F = like %n, unless from self
+ * %g = newsgroup name (if compiled with NNTP support)
+ * %g = message labels (e.g. notmuch tags)
* %i = message-id
+ * %I = initials of author
* %l = number of lines in the message
* %L = like %F, except `lists' are displayed first
* %m = number of messages in the mailbox
optional = 0;
break;
-#if 0 /* MERGE with "index-color" patch */
+ #ifdef USE_NOTMUCH
+ case 'g':
+ if (!optional)
+ {
-#endif
- 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;
- case 'g':
+#ifdef USE_NNTP
++ case 'q':
+ mutt_format_s (dest, destlen, prefix, hdr->env->newsgroups ? hdr->env->newsgroups : "");
+ break;
+#endif
+
case 'i':
mutt_format_s (dest, destlen, prefix, hdr->env->message_id ? hdr->env->message_id : "<no.id>");
break;
break;
-#if 0 /* MERGE with "index-color" patch */
+ #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);
+
-#endif
- mutt_format_s (dest, destlen, prefix, (tag_transformed) ? tag_transformed : "");
+ 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);
Groups = hash_create (1031, 0);
ReverseAlias = hash_create (1031, 1);
-
+ #ifdef USE_NOTMUCH
+ TagTransforms = hash_create (64, 1);
+ TagFormats = hash_create (64, 0);
+ #endif
+
mutt_menu_init ();
- mutt_srandom ();
- /*
- * XXX - use something even more difficult to predict?
- */
snprintf (AttachmentMarker, sizeof (AttachmentMarker),
- "\033]9;%ld\a", (long) time (NULL));
+ "\033]9;%" PRIu64 "\a", mutt_rand64());
/* on one of the systems I use, getcwd() does not return the same prefix
as is listed in the passwd file */
** .dt %E .dd number of messages in current thread
** .dt %f .dd sender (address + real name), either From: or Return-Path:
** .dt %F .dd author name, or recipient name if the message is from you
+ ** .dt %g .dd newsgroup name (if compiled with NNTP support)
+ ** .dt %g .dd message labels (e.g. notmuch tags)
** .dt %H .dd spam attribute(s) of this message
** .dt %i .dd message-id of the current message
** .dt %l .dd number of lines in the message (does not work with maildir,
** See also $$read_inc, $$write_inc and $$net_inc.
*/
#endif
+#ifdef USE_NNTP
+ { "news_cache_dir", DT_PATH, R_NONE, UL &NewsCacheDir, UL "~/.mutt" },
+ /*
+ ** .pp
+ ** This variable pointing to directory where Mutt will save cached news
+ ** articles and headers in. If \fIunset\fP, articles and headers will not be
+ ** saved at all and will be reloaded from the server each time.
+ */
+ { "news_server", DT_STR, R_NONE, UL &NewsServer, 0 },
+ /*
+ ** .pp
+ ** This variable specifies domain name or address of NNTP server. It
+ ** defaults to the news server specified in the environment variable
+ ** $$$NNTPSERVER or contained in the file /etc/nntpserver. You can also
+ ** specify username and an alternative port for each news server, ie:
+ ** .pp
+ ** [[s]news://][username[:password]@]server[:port]
+ */
+ { "newsgroups_charset", DT_STR, R_NONE, UL &NewsgroupsCharset, UL "utf-8" },
+ /*
+ ** .pp
+ ** Character set of newsgroups descriptions.
+ */
+ { "newsrc", DT_PATH, R_NONE, UL &NewsRc, UL "~/.newsrc" },
+ /*
+ ** .pp
+ ** The file, containing info about subscribed newsgroups - names and
+ ** indexes of read articles. The following printf-style sequence
+ ** is understood:
+ ** .dl
+ ** .dt %a .dd account url
+ ** .dt %p .dd port
+ ** .dt %P .dd port if specified
+ ** .dt %s .dd news server name
+ ** .dt %S .dd url schema
+ ** .dt %u .dd username
+ ** .de
+ */
+ { "nntp_authenticators", DT_STR, R_NONE, UL &NntpAuthenticators, UL 0 },
+ /*
+ ** .pp
+ ** This is a colon-delimited list of authentication methods mutt may
+ ** attempt to use to log in to a news server, in the order mutt should
+ ** try them. Authentication methods are either ``user'' or any
+ ** SASL mechanism, e.g. ``digest-md5'', ``gssapi'' or ``cram-md5''.
+ ** This option is case-insensitive. If it's \fIunset\fP (the default)
+ ** mutt will try all available methods, in order from most-secure to
+ ** least-secure.
+ ** .pp
+ ** Example:
+ ** .ts
+ ** set nntp_authenticators="digest-md5:user"
+ ** .te
+ ** .pp
+ ** \fBNote:\fP Mutt will only fall back to other authentication methods if
+ ** the previous methods are unavailable. If a method is available but
+ ** authentication fails, mutt will not connect to the IMAP server.
+ */
+ { "nntp_context", DT_NUM, R_NONE, UL &NntpContext, 1000 },
+ /*
+ ** .pp
+ ** This variable defines number of articles which will be in index when
+ ** newsgroup entered. If active newsgroup have more articles than this
+ ** number, oldest articles will be ignored. Also controls how many
+ ** articles headers will be saved in cache when you quit newsgroup.
+ */
+ { "nntp_listgroup", DT_BOOL, R_NONE, OPTLISTGROUP, 1 },
+ /*
+ ** .pp
+ ** This variable controls whether or not existence of each article is
+ ** checked when newsgroup is entered.
+ */
+ { "nntp_load_description", DT_BOOL, R_NONE, OPTLOADDESC, 1 },
+ /*
+ ** .pp
+ ** This variable controls whether or not descriptions for each newsgroup
+ ** must be loaded when newsgroup is added to list (first time list
+ ** loading or new newsgroup adding).
+ */
+ { "nntp_user", DT_STR, R_NONE, UL &NntpUser, UL "" },
+ /*
+ ** .pp
+ ** Your login name on the NNTP server. If \fIunset\fP and NNTP server requires
+ ** authentication, Mutt will prompt you for your account name when you
+ ** connect to news server.
+ */
+ { "nntp_pass", DT_STR, R_NONE, UL &NntpPass, UL "" },
+ /*
+ ** .pp
+ ** Your password for NNTP account.
+ */
+ { "nntp_poll", DT_NUM, R_NONE, UL &NewsPollTimeout, 60 },
+ /*
+ ** .pp
+ ** The time in seconds until any operations on newsgroup except post new
+ ** article will cause recheck for new news. If set to 0, Mutt will
+ ** recheck newsgroup on each operation in index (stepping, read article,
+ ** etc.).
+ */
++#endif
+ #ifdef USE_NOTMUCH
+ { "nm_open_timeout", DT_NUM, R_NONE, UL &NotmuchOpenTimeout, 5 },
+ /*
+ ** .pp
+ ** This variable specifies the timeout for database open in seconds.
+ */
+
+ { "nm_default_uri", DT_STR, R_NONE, UL &NotmuchDefaultUri, 0 },
+ /*
+ ** .pp
+ ** This variable specifies the default Notmuch database in format
+ ** notmuch://<absolute path>.
+ */
+
+ { "nm_hidden_tags", DT_STR, R_NONE, UL &NotmuchHiddenTags, UL "unread,draft,flagged,passed,replied,attachment,signed,encrypted" },
+ /*
+ ** .pp
+ ** This variable specifies private notmuch tags which should not be printed
+ ** on screen.
+ */
+ { "nm_exclude_tags", DT_STR, R_NONE, UL &NotmuchExcludeTags, 0 },
+ /*
+ ** .pp
+ ** The messages tagged with these tags are excluded and not loaded
+ ** from notmuch DB to mutt unless specified explicitly.
+ */
+ { "nm_unread_tag", DT_STR, R_NONE, UL &NotmuchUnreadTag, UL "unread" },
+ /*
+ ** .pp
+ ** This variable specifies notmuch tag which is used for unread messages. The
+ ** variable is used to count unread messages in DB only. All other mutt commands
+ ** use standard (e.g. maildir) flags.
+ */
+ { "nm_db_limit", DT_NUM, R_NONE, UL &NotmuchDBLimit, 0 },
+ /*
+ ** .pp
+ ** This variable specifies the default limit used in notmuch queries.
+ */
+ { "nm_query_type", DT_STR, R_NONE, UL &NotmuchQueryType, UL "messages" },
+ /*
+ ** .pp
+ ** This variable specifies the default query type (threads or messages) used in notmuch queries.
+ */
+ { "nm_record", DT_BOOL, R_NONE, OPTNOTMUCHRECORD, 0 },
+ /*
+ ** .pp
+ ** This variable specifies if the mutt record should indexed by notmuch.
+ */
+ { "nm_record_tags", DT_STR, R_NONE, UL &NotmuchRecordTags, 0 },
+ /*
+ ** .pp
+ ** This variable specifies the default tags applied to messages stored to the mutt record.
+ */
#endif
{ "pager", DT_PATH, R_NONE, UL &Pager, UL "builtin" },
/*
static int
get_color (int index, unsigned char *s)
{
- 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;
+ COLOR_LINE *color;
+ HEADER *hdr = Context->hdrs[Context->v2r[index]];
+ int type = *s;
+
+ switch (type)
+ {
+ case MT_COLOR_INDEX_AUTHOR:
+ color = ColorIndexAuthorList;
+ break;
+ case MT_COLOR_INDEX_FLAGS:
+ color = ColorIndexFlagsList;
+ break;
+ 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];
+ }
+
+ for (; color; color = color->next)
+ if (mutt_pattern_exec (color->color_pattern, MUTT_MATCH_FULL_ADDRESS,
+ Context, hdr))
+ return color->pair;
+
+ return 0;
}
-#endif
-static void print_enriched_string (int attr, unsigned char *s, int do_color)
+static void print_enriched_string (int index, int attr, unsigned char *s, int do_color)
{
wchar_t wc;
size_t k;
}
}
- else if (ctx->hdrs[i]->changed || ctx->hdrs[i]->attach_del ||
- ctx->hdrs[i]->label_changed ||
+ else if (h->changed || h->attach_del ||
++ h->label_changed ||
(ctx->magic == MUTT_MAILDIR
- && (option (OPTMAILDIRTRASH) || ctx->hdrs[i]->trash)
- && (ctx->hdrs[i]->deleted != ctx->hdrs[i]->trash)))
+ && (option (OPTMAILDIRTRASH) || h->trash)
+ && (h->deleted != h->trash)))
{
if (ctx->magic == MUTT_MAILDIR)
{
#define MUTT_CLEAR (1<<5) /* clear input if printable character is pressed */
#define MUTT_COMMAND (1<<6) /* do command completion */
#define MUTT_PATTERN (1<<7) /* pattern mode - only used for history classes */
-#define MUTT_NM_QUERY (1<<8) /* Notmuch query mode. */
-#define MUTT_NM_TAG (1<<9) /* Notmuch tag +/- mode. */
+#define MUTT_LABEL (1<<8) /* do label completion */
+ #if USE_NOTMUCH
++#define MUTT_NM_QUERY (1<<9) /* Notmuch query mode. */
++#define MUTT_NM_TAG (1<<10) /* Notmuch tag +/- mode. */
+ #endif
/* flags for mutt_get_token() */
#define MUTT_TOKEN_EQUAL 1 /* treat '=' as a special */
MUTT_CRYPT_ENCRYPT,
MUTT_PGP_KEY,
MUTT_XLABEL,
+ #ifdef USE_NOTMUCH
+ MUTT_NOTMUCH_LABEL,
+ #endif
MUTT_MIMEATTACH,
+#ifdef USE_NNTP
+ MUTT_NEWSGROUPS,
+#endif
/* Options for Mailcap lookup */
MUTT_EDIT,
OPTDONTHANDLEPGPKEYS, /* (pseudo) used to extract PGP keys */
OPTIGNOREMACROEVENTS, /* (pseudo) don't process macro/push/exec events while set */
+#ifdef USE_NNTP
+ OPTNEWS, /* (pseudo) used to change reader mode */
+ OPTNEWSSEND, /* (pseudo) used to change behavior when posting */
+#endif
+ #ifdef USE_NOTMUCH
+ OPTVIRTSPOOLFILE,
+ OPTNOTMUCHRECORD,
+ #endif
OPTMAX
};
int refno; /* message number on server */
#endif
- #if defined USE_POP || defined USE_IMAP || defined USE_NNTP
-#if defined USE_POP || defined USE_IMAP || defined USE_NOTMUCH
++#if defined USE_POP || defined USE_IMAP || defined USE_NNTP || defined USE_NOTMUCH
void *data; /* driver-specific data */
+ void (*free_cb)(struct header *); /* driver-specific data free function */
#endif
char *maildir_flags; /* unknown maildir flags */
MT_COLOR_SB_INDICATOR,
MT_COLOR_SB_SPOOLFILE,
#endif
+ /* please no non-MT_COLOR_INDEX objects after this point */
+ MT_COLOR_INDEX,
+ MT_COLOR_INDEX_AUTHOR,
+ MT_COLOR_INDEX_FLAGS,
+ MT_COLOR_INDEX_SUBJECT,
+ /* below here - only index coloring stuff that doesn't have a pattern */
+ MT_COLOR_INDEX_COLLAPSED,
+ MT_COLOR_INDEX_DATE,
+ MT_COLOR_INDEX_LABEL,
+ MT_COLOR_INDEX_NUMBER,
+ MT_COLOR_INDEX_SIZE,
+ #ifdef USE_NOTMUCH
+ MT_COLOR_INDEX_TAG,
+ MT_COLOR_INDEX_TAGS,
+ #endif
MT_COLOR_MAX
};
extern int ColorDefs[];
extern COLOR_LINE *ColorHdrList;
extern COLOR_LINE *ColorBodyList;
+extern COLOR_LINE *ColorStatusList;
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);
#ifdef MIXMASTER
mutt_free_list (&(*h)->chain);
#endif
- #if defined USE_POP || defined USE_IMAP || defined USE_NNTP
-#if defined USE_POP || defined USE_IMAP || defined USE_NOTMUCH
++#if defined USE_POP || defined USE_IMAP || defined USE_NNTP || defined USE_NOTMUCH
+ if ((*h)->free_cb)
+ (*h)->free_cb(*h);
FREE (&(*h)->data);
#endif
FREE (h); /* __FREE_CHECKED__ */
#include "pop.h"
#endif
+#ifdef USE_NNTP
+#include "nntp.h"
+#endif
+
+ #ifdef USE_NOTMUCH
+ #include "mutt_notmuch.h"
+ #endif
+
#include "buffy.h"
#ifdef USE_DOTLOCK
case MUTT_POP:
return &mx_pop_ops;
#endif
+#ifdef USE_COMPRESSED
+ case MUTT_COMPRESSED:
+ return &mx_comp_ops;
+#endif
+#ifdef USE_NNTP
+ case MUTT_NNTP:
+ return &mx_nntp_ops;
++#endif
+ #ifdef USE_NOTMUCH
+ case MUTT_NOTMUCH:
+ return &mx_notmuch_ops;
#endif
default:
return NULL;
}
#endif
+#ifdef USE_NNTP
+int mx_is_nntp (const char *p)
+{
+ url_scheme_t scheme;
+
+ if (!p)
+ return 0;
+
+ scheme = url_check_scheme (p);
+ if (scheme == U_NNTP || scheme == U_NNTPS)
+ return 1;
+
+ return 0;
+}
+#endif
+
+ #ifdef USE_NOTMUCH
+
+ int mx_is_notmuch(const char *p)
+ {
+ url_scheme_t scheme;
+
+ if (!p)
+ return 0;
+
+ scheme = url_check_scheme (p);
+ if (scheme == U_NOTMUCH)
+ return 1;
+
+ return 0;
+ }
+
+ #endif
+
int mx_get_magic (const char *path)
{
struct stat st;
return MUTT_POP;
#endif /* USE_POP */
+#ifdef USE_NNTP
+ if (mx_is_nntp (path))
+ return MUTT_NNTP;
+#endif /* USE_NNTP */
+
+ #ifdef USE_NOTMUCH
+ if (mx_is_notmuch(path))
+ return MUTT_NOTMUCH;
+ #endif
+
if (stat (path, &st) == -1)
{
dprint (1, (debugfile, "mx_get_magic(): unable to stat %s: %s (errno %d).\n",
break;
#endif /* USE_POP */
+#ifdef USE_NNTP
+ case MUTT_NNTP:
+ rc = nntp_sync_mailbox (ctx);
+ break;
+#endif /* USE_NNTP */
++
+ #ifdef USE_NOTMUCH
+ case MUTT_NOTMUCH:
+ rc = nm_sync (ctx, index_hint);
+ break;
+ #endif /* USE_NOTMUCH */
+
}
#if 0
MUTT_MMDF,
MUTT_MH,
MUTT_MAILDIR,
+#ifdef USE_NNTP
+ MUTT_NNTP,
+#endif
MUTT_IMAP,
+ MUTT_NOTMUCH,
MUTT_POP
+#ifdef USE_COMPRESSED
+ , MUTT_COMPRESSED
+#endif
};
WHERE short DefaultMagic INITVAL (MUTT_MBOX);
break;
return (pat->not ^ ((h->security & APPLICATION_PGP) && (h->security & PGPKEY)));
case MUTT_XLABEL:
+ {
+ LIST *label;
+ int result = 0;
+ for (label = h->env->labels; label; label = label->next)
+ {
+ if (label->data == NULL)
+ continue;
+ result = patmatch (pat, label->data) == 0;
+ if (result)
+ break;
+ }
+ return pat->not ^ result;
+ }
+ return (pat->not ^ (h->env->x_label && patmatch (pat, h->env->x_label) == 0));
+ #ifdef USE_NOTMUCH
+ case MUTT_NOTMUCH_LABEL:
+ {
+ char *tags = nm_header_get_tags(h);
+ return (pat->not ^ (tags && patmatch (pat, tags) == 0));
+ }
+ #endif
case MUTT_HORMEL:
return (pat->not ^ (h->env->spam && h->env->spam->data && patmatch (pat, h->env->spam->data) == 0));
case MUTT_DUPLICATED:
goto cleanup;
}
}
- else if (!option (OPTNOCURSES) && ! (flags & SENDMAILX))
+ else if (!option (OPTNOCURSES) && ! (flags & SENDMAILX)) {
- mutt_message (i == 0 ? _("Mail sent.") : _("Sending in background."));
+ mutt_message (i != 0 ? _("Sending in background.") :
+#ifdef USE_NNTP
+ (flags & SENDNEWS) ? _("Article posted.") : _("Mail sent."));
+#else
+ _("Mail sent."));
+#endif
+ #ifdef USE_NOTMUCH
+ if (option(OPTNOTMUCHRECORD))
+ nm_record_message(ctx, finalpath, cur);
+ #endif
+ }
if (WithCrypto && (msg->security & ENCRYPT))
FREE (&pgpkeylist);
if (div_width < 0)
return;
- if (!Incoming)
+ BUFFY *b;
+ if (Entries == NULL)
+ for (b = get_incoming(); b; b = b->next)
+ mutt_sb_notify_mailbox (b, 1);
+
+ if (!get_incoming())
{
- fill_empty_space (0, num_rows, SidebarWidth - div_width);
+ fill_empty_space (0, num_rows, div_width, num_cols - div_width);
return;
}
break;
case 'f':
- snprintf (fmt, sizeof(fmt), "%%%ss", prefix);
+ {
+ #ifdef USE_NOTMUCH
+ char *p;
+ if (Context && Context->magic == MUTT_NOTMUCH &&
+ (p = nm_get_description(Context)))
+ strfcpy(tmp, p, sizeof (tmp));
+ else
++#endif
+#ifdef USE_COMPRESSED
+ if (Context && Context->compress_info && Context->realpath) {
+ strfcpy (tmp, Context->realpath, sizeof (tmp));
+ mutt_pretty_mailbox (tmp, sizeof (tmp));
+ } else
#endif
if (Context && Context->path)
{
{ "imaps", U_IMAPS },
{ "pop", U_POP },
{ "pops", U_POPS },
+ { "news", U_NNTP },
+ { "snews", U_NNTPS },
{ "mailto", U_MAILTO },
+ #ifdef USE_NOTMUCH
+ { "notmuch", U_NOTMUCH },
+ #endif
{ "smtp", U_SMTP },
{ "smtps", U_SMTPS },
{ NULL, U_UNKNOWN }