the sidebar. It's possible to toggle between virtual and normal folders by
sidebar-toggle command.
+ nm_record = <boolean>
+
+ Add messages stored to the mutt record (see $record in the mutt docs)
+ also to notmuch DB. If you reply to an email then the new email inherits
+ tags from the original email.
+
+ nm_record_tags = <comma delimited list>
+
+ Tags that should be removed or added to the to the messages stored in the mutt record.
+
+ example:
+
+ set record = "~/sent-mails"
+ set nm_record = yes
+ set nm_record_tags = "-inbox,archive,me"
+
nm_open_timeout = <seconds>
This option specifies timeout for Notmuch database. Default is 5 seconds.
* .muttrc example:
+ set record="~/Mail/Maildir/sent-mail"
+ set nm_record = yes
+ set nm_record_tags ="-inbox me archive"
+
set nm_default_uri="notmuch:///home/kzak/Mail/Maildir"
set virtual_spoolfile = yes
if (msg->content->next)
msg->content = mutt_make_multipart (msg->content);
- if (mutt_write_fcc (fname, msg, NULL, 0, NULL) < 0)
+ if (mutt_write_fcc (fname, msg, NULL, 0, NULL, NULL) < 0)
msg->content = mutt_remove_multipart (msg->content);
else
mutt_message _("Message written.");
WHERE char *VirtFolderFormat;
WHERE int NotmuchDBLimit;
WHERE char *NotmuchQueryType;
+WHERE char *NotmuchRecordTags;
#endif
** .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" },
/*
#ifdef USE_NOTMUCH
OPTVIRTSPOOLFILE,
+ OPTNOTMUCHRECORD,
#endif
OPTMAX
new_flags ? M_FLAGS : 0;
}
+int nm_record_message(CONTEXT *ctx, char *path, HEADER *h)
+{
+ notmuch_database_t *db;
+ notmuch_status_t st;
+ notmuch_message_t *msg;
+ int rc = -1;
+ struct nm_ctxdata *data = get_ctxdata(ctx);
+
+ if (!path || !data || access(path, F_OK) != 0)
+ return 0;
+ db = get_db(data, TRUE);
+ if (!db)
+ return -1;
+
+ dprint(1, (debugfile, "nm: record message: %s\n", path));
+ st = notmuch_database_begin_atomic(db);
+ if (st)
+ return -1;
+
+ st = notmuch_database_add_message(db, path, &msg);
+
+ if (st != NOTMUCH_STATUS_SUCCESS &&
+ st != NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID) {
+ dprint(1, (debugfile, "nm: failed to add '%s' [st=%d]\n", path, (int) st));
+ goto done;
+ }
+
+ if (st == NOTMUCH_STATUS_SUCCESS && msg) {
+ notmuch_message_maildir_flags_to_tags(msg);
+ if (h)
+ update_tags(msg, nm_header_get_tags(h));
+ if (NotmuchRecordTags)
+ update_tags(msg, NotmuchRecordTags);
+ }
+
+ rc = 0;
+done:
+ if (msg)
+ notmuch_message_destroy(msg);
+ notmuch_database_end_atomic(db);
+
+ if (!is_longrun(data))
+ release_db(data);
+ return rc;
+}
+
/*
* Fill a list with all notmuch tags.
*
if (!data)
return -1;
- if (!(db = get_db(data, TRUE)) ||
+ if (!(db = get_db(data, FALSE)) ||
!(tags = notmuch_database_get_all_tags(db)))
goto done;
char *nm_get_description(CONTEXT *ctx);
+int nm_record_message(CONTEXT *ctx, char *path, HEADER *h);
+
void nm_debug_check(CONTEXT *ctx);
int nm_get_all_tags(CONTEXT *ctx, char **tag_list, int *tag_count);
void mutt_update_num_postponed (void);
int mutt_wait_filter (pid_t);
int mutt_which_case (const char *);
-int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int, char *);
+int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int, char *, char **);
int mutt_write_mime_body (BODY *, FILE *);
int mutt_write_mime_header (BODY *, FILE *);
int mutt_write_one_header (FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, int flags);
#include "remailer.h"
#endif
+#ifdef USE_NOTMUCH
+#include "mutt_notmuch.h"
+#endif
static void append_signature (FILE *f)
{
char *smime_default_key = NULL;
char *tag = NULL, *err = NULL;
char *ctype;
+ char *finalpath = NULL;
int rv = -1;
mutt_prepare_envelope (msg->env, 0);
mutt_env_to_idna (msg->env, NULL, NULL); /* Handle bad IDNAs the next time. */
- if (!Postponed || mutt_write_fcc (NONULL (Postponed), msg, (cur && (flags & SENDREPLY)) ? cur->env->message_id : NULL, 1, fcc) < 0)
+ if (!Postponed || mutt_write_fcc (NONULL (Postponed), msg,
+ (cur && (flags & SENDREPLY)) ?
+ cur->env->message_id : NULL, 1, fcc, NULL) < 0)
{
msg->content = mutt_remove_multipart (msg->content);
decode_descriptions (msg->content);
* message was first postponed.
*/
msg->received = time (NULL);
- if (mutt_write_fcc (fcc, msg, NULL, 0, NULL) == -1)
+ if (mutt_write_fcc (fcc, msg, NULL, 0, NULL, &finalpath) == -1)
{
/*
* Error writing FCC, we should abort sending.
msg->content = mutt_remove_multipart (msg->content);
decode_descriptions (msg->content);
mutt_unprepare_envelope (msg->env);
+ FREE(&finalpath);
goto main_loop;
}
else
goto cleanup;
}
}
- else if (!option (OPTNOCURSES) && ! (flags & SENDMAILX))
+ else if (!option (OPTNOCURSES) && ! (flags & SENDMAILX)) {
mutt_message (i == 0 ? _("Mail sent.") : _("Sending in background."));
+#ifdef USE_NOTMUCH
+ if (option(OPTNOTMUCHRECORD))
+ nm_record_message(ctx, finalpath, cur);
+#endif
+ }
if (WithCrypto && (msg->security & ENCRYPT))
FREE (&pgpkeylist);
safe_fclose (&tempfp);
mutt_free_header (&msg);
-
+ FREE(&finalpath);
return rv;
}
}
}
-int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid, int post, char *fcc)
+int mutt_write_fcc (const char *path, HEADER *hdr, const char *msgid,
+ int post, char *fcc, char **finalpath)
{
CONTEXT f;
MESSAGE *msg;
if (mx_commit_message (msg, &f) != 0)
r = -1;
+ else if (finalpath)
+ *finalpath = safe_strdup(msg->commited_path);
mx_close_message (&msg);
mx_close_mailbox (&f, NULL);