NeoMutt  2018-07-16 +2481-68dcde
Teaching an old dog new tricks
DOXYGEN
mutt_notmuch.c File Reference

Notmuch virtual mailbox type. More...

#include "config.h"
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <notmuch.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "notmuch_private.h"
#include "mutt/mutt.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "mutt.h"
#include "mutt_notmuch.h"
#include "curs_lib.h"
#include "globals.h"
#include "hcache/hcache.h"
#include "index.h"
#include "maildir/lib.h"
#include "mutt_thread.h"
#include "mx.h"
#include "progress.h"
#include "protos.h"
+ Include dependency graph for mutt_notmuch.c:

Go to the source code of this file.

Functions

static header_cache_tnm_hcache_open (struct Mailbox *m)
 Open a header cache. More...
 
void nm_hcache_close (header_cache_t *h)
 Close the header cache. More...
 
static enum NmQueryType string_to_query_type (const char *str)
 Lookup a query type. More...
 
void nm_adata_free (void **ptr)
 Release and clear storage in an NmAccountData structure. More...
 
struct NmAccountDatanm_adata_new (void)
 Allocate and initialise a new NmAccountData structure. More...
 
struct NmAccountDatanm_adata_get (struct Mailbox *m)
 Get the Notmuch Account data. More...
 
void nm_mdata_free (void **ptr)
 Free data attached to the Mailbox. More...
 
struct NmMboxDatanm_mdata_new (const char *uri)
 Create a new NmMboxData object from a query. More...
 
struct NmMboxDatanm_mdata_get (struct Mailbox *m)
 Get the Notmuch Mailbox data. More...
 
void nm_edata_free (void **ptr)
 Free data attached to an Email. More...
 
struct NmEmailDatanm_edata_new (void)
 Create a new NmEmailData for an email. More...
 
struct NmMboxDatanm_get_default_data (void)
 Create a Mailbox with default Notmuch settings. More...
 
static int init_mailbox (struct Mailbox *m)
 Add Notmuch data to the Mailbox. More...
 
static char * email_get_id (struct Email *e)
 Get the unique Notmuch Id. More...
 
static char * email_get_fullpath (struct Email *e, char *buf, size_t buflen)
 Get the full path of an email. More...
 
static const char * query_type_to_string (enum NmQueryType query_type)
 Turn a query type into a string. More...
 
static bool query_window_check_timebase (const char *timebase)
 Checks if a given timebase string is valid. More...
 
static void query_window_reset (void)
 Restore vfolder's search window to its original position. More...
 
static bool windowed_query_from_query (const char *query, char *buf, size_t buflen)
 transforms a vfolder search query into a windowed one More...
 
static char * get_query_string (struct NmMboxData *mdata, bool window)
 builds the notmuch vfolder search string More...
 
static int get_limit (struct NmMboxData *mdata)
 Get the database limit. More...
 
static void apply_exclude_tags (notmuch_query_t *query)
 Exclude the configured tags. More...
 
static notmuch_query_t * get_query (struct Mailbox *m, bool writable)
 Create a new query. More...
 
static int update_email_tags (struct Email *e, notmuch_message_t *msg)
 Update the Email's tags from Notmuch. More...
 
static int update_message_path (struct Email *e, const char *path)
 Set the path for a message. More...
 
static char * get_folder_from_path (const char *path)
 Find an email's folder from its path. More...
 
static char * nm2mutt_message_id (const char *id)
 converts notmuch message Id to neomutt message Id More...
 
static int init_email (struct Email *e, const char *path, notmuch_message_t *msg)
 Set up an email's Notmuch data. More...
 
static const char * get_message_last_filename (notmuch_message_t *msg)
 Get a message's last filename. More...
 
static void progress_reset (struct Mailbox *m)
 Reset the progress counter. More...
 
static void progress_update (struct Mailbox *m, notmuch_query_t *q)
 Update the progress counter. More...
 
static struct Emailget_mutt_email (struct Mailbox *m, notmuch_message_t *msg)
 Get the Email of a Notmuch message. More...
 
static void append_message (header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_message_t *msg, bool dedup)
 Associate a message. More...
 
static void append_replies (header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_message_t *top, bool dedup)
 add all the replies to a given messages into the display More...
 
static void append_thread (header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_thread_t *thread, bool dedup)
 add each top level reply in the thread More...
 
static notmuch_messages_t * get_messages (notmuch_query_t *query)
 load messages for a query More...
 
static bool read_mesgs_query (struct Mailbox *m, notmuch_query_t *q, bool dedup)
 Search for matching messages. More...
 
static notmuch_threads_t * get_threads (notmuch_query_t *query)
 load threads for a query More...
 
static bool read_threads_query (struct Mailbox *m, notmuch_query_t *q, bool dedup, int limit)
 Perform a query with threads. More...
 
static notmuch_message_t * get_nm_message (notmuch_database_t *db, struct Email *e)
 Find a Notmuch message. More...
 
static bool nm_message_has_tag (notmuch_message_t *msg, char *tag)
 Does a message have this tag? More...
 
static int update_tags (notmuch_message_t *msg, const char *tags)
 Update the tags on a message. More...
 
static int update_email_flags (struct Mailbox *m, struct Email *e, const char *tags)
 Update the Email's flags. More...
 
static int rename_maildir_filename (const char *old, char *buf, size_t buflen, struct Email *e)
 Rename a Maildir file. More...
 
static int remove_filename (struct Mailbox *m, const char *path)
 Delete a file. More...
 
static int rename_filename (struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
 Rename the file. More...
 
static unsigned int count_query (notmuch_database_t *db, const char *qstr, int limit)
 Count the results of a query. More...
 
char * nm_email_get_folder (struct Email *e)
 Get the folder for a Email. More...
 
int nm_read_entire_thread (struct Mailbox *m, struct Email *e)
 Get the entire thread of an email. More...
 
void nm_parse_type_from_query (struct NmMboxData *mdata, char *buf)
 Parse a query type out of a query. More...
 
char * nm_uri_from_query (struct Mailbox *m, char *buf, size_t buflen)
 Turn a query into a URI. More...
 
void nm_query_window_forward (void)
 Function to move the current search window forward in time. More...
 
void nm_query_window_backward (void)
 Function to move the current search window backward in time. More...
 
bool nm_message_is_still_queried (struct Mailbox *m, struct Email *e)
 Is a message still visible in the query? More...
 
int nm_update_filename (struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
 Change the filename. More...
 
static int nm_mbox_check_stats (struct Mailbox *m, int flags)
 Check the Mailbox statistics - Implements MxOps::check_stats() More...
 
int nm_record_message (struct Mailbox *m, char *path, struct Email *e)
 Add a message to the Notmuch database. More...
 
int nm_get_all_tags (struct Mailbox *m, char **tag_list, int *tag_count)
 Fill a list with all notmuch tags. More...
 
struct Accountnm_ac_find (struct Account *a, const char *path)
 Find an Account that matches a Mailbox path - Implements MxOps::ac_find() More...
 
int nm_ac_add (struct Account *a, struct Mailbox *m)
 Add a Mailbox to an Account - Implements MxOps::ac_add() More...
 
static int nm_mbox_open (struct Mailbox *m)
 Open a Mailbox - Implements MxOps::mbox_open() More...
 
static int nm_mbox_check (struct Mailbox *m, int *index_hint)
 Check for new mail - Implements MxOps::mbox_check() More...
 
static int nm_mbox_sync (struct Mailbox *m, int *index_hint)
 Save changes to the Mailbox - Implements MxOps::mbox_sync() More...
 
static int nm_mbox_close (struct Mailbox *m)
 Close a Mailbox - Implements MxOps::mbox_close() More...
 
static int nm_msg_open (struct Mailbox *m, struct Message *msg, int msgno)
 Open an email message in a Mailbox - Implements MxOps::msg_open() More...
 
static int nm_msg_commit (struct Mailbox *m, struct Message *msg)
 Save changes to an email - Implements MxOps::msg_commit() More...
 
static int nm_msg_close (struct Mailbox *m, struct Message *msg)
 Close an email - Implements MxOps::msg_close() More...
 
static int nm_tags_edit (struct Mailbox *m, const char *tags, char *buf, size_t buflen)
 Prompt and validate new messages tags - Implements MxOps::tags_edit() More...
 
static int nm_tags_commit (struct Mailbox *m, struct Email *e, char *buf)
 Save the tags to a message - Implements MxOps::tags_commit() More...
 
enum MailboxType nm_path_probe (const char *path, const struct stat *st)
 Is this a Notmuch Mailbox? - Implements MxOps::path_probe() More...
 
int nm_path_canon (char *buf, size_t buflen)
 Canonicalise a Mailbox path - Implements MxOps::path_canon() More...
 
int nm_path_pretty (char *buf, size_t buflen, const char *folder)
 Abbreviate a Mailbox path - Implements MxOps::path_pretty() More...
 
int nm_path_parent (char *buf, size_t buflen)
 Find the parent of a Mailbox path - Implements MxOps::path_parent() More...
 

Variables

const char NmUriProtocol [] = "notmuch://"
 
const int NmUriProtocolLen = sizeof(NmUriProtocol) - 1
 
int C_NmDbLimit
 Config: (notmuch) Default limit for Notmuch queries. More...
 
char * C_NmDefaultUri
 Config: (notmuch) Path to the Notmuch database. More...
 
char * C_NmExcludeTags
 Config: (notmuch) Exclude messages with these tags. More...
 
int C_NmOpenTimeout
 Config: (notmuch) Database timeout. More...
 
char * C_NmQueryType
 Config: (notmuch) Default query type: 'threads' or 'messages'. More...
 
int C_NmQueryWindowCurrentPosition
 Config: (notmuch) Position of current search window. More...
 
char * C_NmQueryWindowTimebase
 Config: (notmuch) Units for the time duration. More...
 
char * C_NmRecordTags
 Config: (notmuch) Tags to apply to the 'record' mailbox (sent mail) More...
 
char * C_NmUnreadTag
 Config: (notmuch) Tag to use for unread messages. More...
 
char * C_NmFlaggedTag
 Config: (notmuch) Tag to use for flagged messages. More...
 
char * C_NmRepliedTag
 Config: (notmuch) Tag to use for replied messages. More...
 
struct MxOps MxNotmuchOps
 Notmuch Mailbox - Implements MxOps. More...
 

Detailed Description

Notmuch virtual mailbox type.

Authors
  • Karel Zak
  • Richard Russon
  • Kevin Velghe
  • Bernard 'Guyzmo' Pratz

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Notes

  • notmuch uses private Mailbox->data and private Email->data
  • all exported functions are usable within notmuch context only
  • all functions have to be covered by "mailbox->magic == MUTT_NOTMUCH" check (it's implemented in nm_mdata_get() and init_mailbox() functions).
  • exception are nm_nonctx_* functions – these functions use nm_default_uri (or parse URI from another resource)

Definition in file mutt_notmuch.c.

Function Documentation

◆ nm_hcache_open()

static header_cache_t* nm_hcache_open ( struct Mailbox m)
static

Open a header cache.

Parameters
mMailbox
Return values
ptrHeader cache handle

Definition at line 91 of file mutt_notmuch.c.

92 {
93 #ifdef USE_HCACHE
95 #else
96  return NULL;
97 #endif
98 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
WHERE char * C_HeaderCache
Config: (hcache) Directory/file for the header cache database.
Definition: globals.h:126
header_cache_t * mutt_hcache_open(const char *path, const char *folder, hcache_namer_t namer)
Multiplexor for HcacheOps::open.
Definition: hcache.c:255
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_hcache_close()

void nm_hcache_close ( header_cache_t h)

Close the header cache.

Parameters
hHeader cache handle

Definition at line 104 of file mutt_notmuch.c.

105 {
106 #ifdef USE_HCACHE
108 #endif
109 }
void mutt_hcache_close(header_cache_t *hc)
Multiplexor for HcacheOps::close.
Definition: hcache.c:333
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ string_to_query_type()

static enum NmQueryType string_to_query_type ( const char *  str)
static

Lookup a query type.

Parameters
strString to lookup
Return values
numQuery type, e.g. NM_QUERY_TYPE_MESGS

Definition at line 116 of file mutt_notmuch.c.

117 {
118  if (mutt_str_strcmp(str, "threads") == 0)
119  return NM_QUERY_TYPE_THREADS;
120  else if (mutt_str_strcmp(str, "messages") == 0)
121  return NM_QUERY_TYPE_MESGS;
122 
123  mutt_error(_("failed to parse notmuch query type: %s"), NONULL(str));
124  return NM_QUERY_TYPE_MESGS;
125 }
#define NONULL(x)
Definition: string2.h:37
#define _(a)
Definition: message.h:28
Default: Messages only.
#define mutt_error(...)
Definition: logging.h:84
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_adata_free()

void nm_adata_free ( void **  ptr)

Release and clear storage in an NmAccountData structure.

Parameters
[out]ptrNm Account data

Definition at line 131 of file mutt_notmuch.c.

132 {
133  if (!ptr || !*ptr)
134  return;
135 
136  struct NmAccountData *adata = *ptr;
137  if (adata->db)
138  {
139  nm_db_free(adata->db);
140  adata->db = NULL;
141  }
142 
143  FREE(ptr);
144 }
void nm_db_free(notmuch_database_t *db)
decoupled way to close a Notmuch database
Definition: nm_db.c:184
notmuch_database_t * db
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
#define FREE(x)
Definition: memory.h:40
Notmuch-specific Account data -.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_adata_new()

struct NmAccountData* nm_adata_new ( void  )

Allocate and initialise a new NmAccountData structure.

Return values
ptrNew NmAccountData

Definition at line 150 of file mutt_notmuch.c.

151 {
152  struct NmAccountData *adata = mutt_mem_calloc(1, sizeof(struct NmAccountData));
153 
154  return adata;
155 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
Notmuch-specific Account data -.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_adata_get()

struct NmAccountData* nm_adata_get ( struct Mailbox m)

Get the Notmuch Account data.

Parameters
mMailbox
Return values
ptrSuccess
NULLFailure, not a Notmuch mailbox

Definition at line 163 of file mutt_notmuch.c.

164 {
165  if (!m || (m->magic != MUTT_NOTMUCH))
166  return NULL;
167 
168  struct Account *a = m->account;
169  if (!a)
170  return NULL;
171 
172  return a->adata;
173 }
A group of associated Mailboxes.
Definition: account.h:36
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
struct Account * account
Account that owns this Mailbox.
Definition: mailbox.h:142
+ Here is the caller graph for this function:

◆ nm_mdata_free()

void nm_mdata_free ( void **  ptr)

Free data attached to the Mailbox.

Parameters
[out]ptrNotmuch data

The NmMboxData struct stores global Notmuch data, such as the connection to the database. This function will close the database, free the resources and the struct itself.

Definition at line 183 of file mutt_notmuch.c.

184 {
185  if (!ptr || !*ptr)
186  return;
187 
188  struct NmMboxData *mdata = *ptr;
189 
190  mutt_debug(LL_DEBUG1, "nm: freeing context data %p\n", mdata);
191 
192  url_free(&mdata->db_url);
193  FREE(&mdata->db_query);
194  FREE(ptr);
195 }
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:147
char * db_query
Previous query.
struct Url * db_url
Parsed view url of the Notmuch database.
Log at debug level 1.
Definition: logging.h:56
void url_free(struct Url **u)
Free the contents of a URL.
Definition: url.c:288
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_mdata_new()

struct NmMboxData* nm_mdata_new ( const char *  uri)

Create a new NmMboxData object from a query.

Parameters
uriNotmuch query string
Return values
ptrNew NmMboxData struct

A new NmMboxData struct is created, then the query is parsed and saved within it. This should be freed using nm_mdata_free().

Definition at line 205 of file mutt_notmuch.c.

206 {
207  if (!uri)
208  return NULL;
209 
210  struct NmMboxData *mdata = mutt_mem_calloc(1, sizeof(struct NmMboxData));
211  mutt_debug(LL_DEBUG1, "nm: initialize mailbox mdata %p\n", (void *) mdata);
212 
213  mdata->db_limit = C_NmDbLimit;
215  mdata->db_url = url_parse(uri);
216  if (!mdata->db_url)
217  {
218  mutt_error(_("failed to parse notmuch uri: %s"), uri);
219  FREE(&mdata);
220  return NULL;
221  }
222  return mdata;
223 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
int C_NmDbLimit
Config: (notmuch) Default limit for Notmuch queries.
Definition: mutt_notmuch.c:74
#define _(a)
Definition: message.h:28
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:147
char * C_NmQueryType
Config: (notmuch) Default query type: &#39;threads&#39; or &#39;messages&#39;.
Definition: mutt_notmuch.c:78
struct Url * db_url
Parsed view url of the Notmuch database.
Log at debug level 1.
Definition: logging.h:56
#define mutt_error(...)
Definition: logging.h:84
#define FREE(x)
Definition: memory.h:40
static enum NmQueryType string_to_query_type(const char *str)
Lookup a query type.
Definition: mutt_notmuch.c:116
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
enum NmQueryType query_type
Messages or Threads.
int db_limit
Maximum number of results to return.
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:161
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_mdata_get()

struct NmMboxData* nm_mdata_get ( struct Mailbox m)

Get the Notmuch Mailbox data.

Parameters
mMailbox
Return values
ptrSuccess
NULLFailure, not a Notmuch mailbox

Definition at line 231 of file mutt_notmuch.c.

232 {
233  if (!m || (m->magic != MUTT_NOTMUCH))
234  return NULL;
235 
236  return m->mdata;
237 }
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
void * mdata
Driver specific data.
Definition: mailbox.h:147
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
+ Here is the caller graph for this function:

◆ nm_edata_free()

void nm_edata_free ( void **  ptr)

Free data attached to an Email.

Parameters
[out]ptrEmail data

Each email has an attached NmEmailData, which contains things like the tags (labels).

Definition at line 246 of file mutt_notmuch.c.

247 {
248  if (!ptr || !*ptr)
249  return;
250 
251  struct NmEmailData *edata = *ptr;
252  mutt_debug(LL_DEBUG2, "nm: freeing email %p\n", (void *) edata);
253  FREE(&edata->folder);
254  FREE(&edata->oldpath);
255  FREE(&edata->virtual_id);
256  FREE(ptr);
257 }
Log at debug level 2.
Definition: logging.h:57
char * virtual_id
Unique Notmuch Id.
char * folder
Location of the Email.
Notmuch-specific Email data -.
void * edata
Driver-specific data.
Definition: email.h:112
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the caller graph for this function:

◆ nm_edata_new()

struct NmEmailData* nm_edata_new ( void  )

Create a new NmEmailData for an email.

Return values
ptrNew NmEmailData struct

Definition at line 263 of file mutt_notmuch.c.

264 {
265  return mutt_mem_calloc(1, sizeof(struct NmEmailData));
266 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
Notmuch-specific Email data -.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_get_default_data()

struct NmMboxData* nm_get_default_data ( void  )

Create a Mailbox with default Notmuch settings.

Return values
ptrMailbox with default Notmuch settings
NULLError, it's impossible to create an NmMboxData

Definition at line 273 of file mutt_notmuch.c.

274 {
275  // path to DB + query + URI "decoration"
276  char uri[PATH_MAX + 1024 + 32];
277 
278  // Try to use C_NmDefaultUri or C_Folder.
279  // If neither are set, it is impossible to create a Notmuch URI.
280  if (C_NmDefaultUri)
281  snprintf(uri, sizeof(uri), "%s", C_NmDefaultUri);
282  else if (C_Folder)
283  snprintf(uri, sizeof(uri), "notmuch://%s", C_Folder);
284  else
285  return NULL;
286 
287  return nm_mdata_new(uri);
288 }
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:124
#define PATH_MAX
Definition: mutt.h:52
char * C_NmDefaultUri
Config: (notmuch) Path to the Notmuch database.
Definition: mutt_notmuch.c:75
struct NmMboxData * nm_mdata_new(const char *uri)
Create a new NmMboxData object from a query.
Definition: mutt_notmuch.c:205
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_mailbox()

static int init_mailbox ( struct Mailbox m)
static

Add Notmuch data to the Mailbox.

Parameters
mMailbox
Return values
0Success
-1Error Bad format

Create a new NmMboxData struct and add it Mailbox::data. Notmuch-specific data will be stored in this struct. This struct can be freed using nm_edata_free().

Definition at line 300 of file mutt_notmuch.c.

301 {
302  if (!m || (m->magic != MUTT_NOTMUCH))
303  return -1;
304 
305  if (m->mdata)
306  return 0;
307 
309  if (!m->mdata)
310  return -1;
311 
313  return 0;
314 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
void(* free_mdata)(void **)
Driver-specific data free function.
Definition: mailbox.h:148
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
void * mdata
Driver specific data.
Definition: mailbox.h:147
void nm_mdata_free(void **ptr)
Free data attached to the Mailbox.
Definition: mutt_notmuch.c:183
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
struct NmMboxData * nm_mdata_new(const char *uri)
Create a new NmMboxData object from a query.
Definition: mutt_notmuch.c:205
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ email_get_id()

static char* email_get_id ( struct Email e)
static

Get the unique Notmuch Id.

Parameters
eEmail
Return values
ptrID string
NULLError

Definition at line 322 of file mutt_notmuch.c.

323 {
324  return (e && e->edata) ? ((struct NmEmailData *) e->edata)->virtual_id : NULL;
325 }
Notmuch-specific Email data -.
void * edata
Driver-specific data.
Definition: email.h:112
+ Here is the caller graph for this function:

◆ email_get_fullpath()

static char* email_get_fullpath ( struct Email e,
char *  buf,
size_t  buflen 
)
static

Get the full path of an email.

Parameters
eEmail
bufBuffer for the path
buflenLength of the buffer
Return values
ptrPath string

Definition at line 334 of file mutt_notmuch.c.

335 {
336  snprintf(buf, buflen, "%s/%s", nm_email_get_folder(e), e->path);
337  return buf;
338 }
char * nm_email_get_folder(struct Email *e)
Get the folder for a Email.
char * path
Path of Email (for local Mailboxes)
Definition: email.h:93
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ query_type_to_string()

static const char* query_type_to_string ( enum NmQueryType  query_type)
static

Turn a query type into a string.

Parameters
query_typeQuery type
Return values
ptrString
Note
This is a static string and must not be freed.

Definition at line 347 of file mutt_notmuch.c.

348 {
349  if (query_type == NM_QUERY_TYPE_THREADS)
350  return "threads";
351  else
352  return "messages";
353 }
+ Here is the caller graph for this function:

◆ query_window_check_timebase()

static bool query_window_check_timebase ( const char *  timebase)
static

Checks if a given timebase string is valid.

Parameters
[in]timebasestring containing a time base
Return values
trueif the given time base is valid

This function returns whether a given timebase string is valid or not, which is used to validate the user settable configuration setting:

nm_query_window_timebase

Definition at line 365 of file mutt_notmuch.c.

366 {
367  if ((strcmp(timebase, "hour") == 0) || (strcmp(timebase, "day") == 0) ||
368  (strcmp(timebase, "week") == 0) || (strcmp(timebase, "month") == 0) ||
369  (strcmp(timebase, "year") == 0))
370  {
371  return true;
372  }
373  return false;
374 }
+ Here is the caller graph for this function:

◆ query_window_reset()

static void query_window_reset ( void  )
static

Restore vfolder's search window to its original position.

After moving a vfolder search window backward and forward, calling this function will reset the search position to its original value, setting to 0 the user settable variable:

nm_query_window_current_position

Definition at line 385 of file mutt_notmuch.c.

386 {
387  mutt_debug(LL_DEBUG2, "entering\n");
388  cs_str_native_set(Config, "nm_query_window_current_position", 0, NULL);
389 }
WHERE struct ConfigSet * Config
Wrapper around the user&#39;s config settings.
Definition: globals.h:40
Log at debug level 2.
Definition: logging.h:57
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int cs_str_native_set(const struct ConfigSet *cs, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: set.c:772
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ windowed_query_from_query()

static bool windowed_query_from_query ( const char *  query,
char *  buf,
size_t  buflen 
)
static

transforms a vfolder search query into a windowed one

Parameters
[in]queryvfolder search string
[out]bufallocated string buffer to receive the modified search query
[in]buflenallocated maximum size of the buf string buffer
Return values
trueTransformed search query is available as a string in buf
falseSearch query shall not be transformed

This is where the magic of windowed queries happens. Taking a vfolder search query string as parameter, it will use the following two user settings:

  • nm_query_window_duration and
  • nm_query_window_timebase

to amend given vfolder search window. Then using a third parameter:

  • nm_query_window_current_position

it will generate a proper notmuch date: parameter. For example, given a duration of 2, a timebase set to week and a position defaulting to 0, it will prepend to the 'tag:inbox' notmuch search query the following string:

  • query: tag:inbox
  • buf: date:2week..now and tag:inbox

If the position is set to 4, with duration=3 and timebase=month:

  • query: tag:archived
  • buf: date:12month..9month and tag:archived

The window won't be applied:

  • If the duration of the search query is set to 0 this function will be disabled.
  • If the timebase is invalid, it will show an error message and do nothing.

If there's no search registered in nm_query_window_current_search or this is a new search, it will reset the window and do the search.

Definition at line 429 of file mutt_notmuch.c.

430 {
431  mutt_debug(LL_DEBUG2, "nm: %s\n", query);
432 
435 
436  /* if the duration is a non positive integer, disable the window */
437  if (C_NmQueryWindowDuration <= 0)
438  {
440  return false;
441  }
442 
443  /* if the query has changed, reset the window position */
444  if (!C_NmQueryWindowCurrentSearch || (strcmp(query, C_NmQueryWindowCurrentSearch) != 0))
446 
448  {
449  mutt_message(_("Invalid nm_query_window_timebase value (valid values are: "
450  "hour, day, week, month or year)"));
451  mutt_debug(LL_DEBUG2, "Invalid nm_query_window_timebase value\n");
452  return false;
453  }
454 
455  if (end == 0)
456  {
457  // Open-ended date allows mail from the future.
458  // This may occur is the sender's time settings are off.
459  snprintf(buf, buflen, "date:%d%s.. and %s", beg, C_NmQueryWindowTimebase,
461  }
462  else
463  {
464  snprintf(buf, buflen, "date:%d%s..%d%s and %s", beg, C_NmQueryWindowTimebase,
466  }
467 
468  mutt_debug(LL_DEBUG2, "nm: %s -> %s\n", query, buf);
469 
470  return true;
471 }
char * C_NmQueryWindowTimebase
Config: (notmuch) Units for the time duration.
Definition: mutt_notmuch.c:80
static void query_window_reset(void)
Restore vfolder&#39;s search window to its original position.
Definition: mutt_notmuch.c:385
#define mutt_message(...)
Definition: logging.h:83
WHERE char * C_NmQueryWindowCurrentSearch
Config: (notmuch) Current search parameters.
Definition: globals.h:177
#define _(a)
Definition: message.h:28
Log at debug level 2.
Definition: logging.h:57
WHERE int C_NmQueryWindowDuration
Config: (notmuch) Time duration of the current search window.
Definition: globals.h:176
static bool query_window_check_timebase(const char *timebase)
Checks if a given timebase string is valid.
Definition: mutt_notmuch.c:365
int C_NmQueryWindowCurrentPosition
Config: (notmuch) Position of current search window.
Definition: mutt_notmuch.c:79
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_query_string()

static char* get_query_string ( struct NmMboxData mdata,
bool  window 
)
static

builds the notmuch vfolder search string

Parameters
mdataNotmuch Mailbox data
windowIf true enable application of the window on the search string
Return values
ptrString containing a notmuch search query
NULLIf none can be generated

This function parses the internal representation of a search, and returns a search query string ready to be fed to the notmuch API, given the search is valid.

Note
The window parameter here is here to decide contextually whether we want to return a search query with window applied (for the actual search result in mailbox) or not (for the count in the sidebar). It is not aimed at enabling/disabling the feature.

Definition at line 489 of file mutt_notmuch.c.

490 {
491  mutt_debug(LL_DEBUG2, "nm: %s\n", window ? "true" : "false");
492 
493  if (!mdata)
494  return NULL;
495  if (mdata->db_query)
496  return mdata->db_query;
497 
498  mdata->query_type = string_to_query_type(C_NmQueryType); /* user's default */
499 
500  struct UrlQuery *item = NULL;
501  STAILQ_FOREACH(item, &mdata->db_url->query_strings, entries)
502  {
503  if (!item->value || !item->name)
504  continue;
505 
506  if (strcmp(item->name, "limit") == 0)
507  {
508  if (mutt_str_atoi(item->value, &mdata->db_limit))
509  mutt_error(_("failed to parse notmuch limit: %s"), item->value);
510  }
511  else if (strcmp(item->name, "type") == 0)
512  mdata->query_type = string_to_query_type(item->value);
513 
514  else if (strcmp(item->name, "query") == 0)
515  mdata->db_query = mutt_str_strdup(item->value);
516  }
517 
518  if (!mdata->db_query)
519  return NULL;
520 
521  if (window)
522  {
523  char buf[1024];
525 
526  /* if a date part is defined, do not apply windows (to avoid the risk of
527  * having a non-intersected date frame). A good improvement would be to
528  * accept if they intersect */
529  if (!strstr(mdata->db_query, "date:") &&
530  windowed_query_from_query(mdata->db_query, buf, sizeof(buf)))
531  {
532  mdata->db_query = mutt_str_strdup(buf);
533  }
534 
535  mutt_debug(LL_DEBUG2, "nm: query (windowed) '%s'\n", mdata->db_query);
536  }
537  else
538  mutt_debug(LL_DEBUG2, "nm: query '%s'\n", mdata->db_query);
539 
540  return mdata->db_query;
541 }
char * name
Query name.
Definition: url.h:57
int mutt_str_atoi(const char *str, int *dst)
Convert ASCII string to an integer.
Definition: string.c:262
WHERE char * C_NmQueryWindowCurrentSearch
Config: (notmuch) Current search parameters.
Definition: globals.h:177
Parsed Query String.
Definition: url.h:55
#define _(a)
Definition: message.h:28
char * value
Query value.
Definition: url.h:58
Log at debug level 2.
Definition: logging.h:57
char * C_NmQueryType
Config: (notmuch) Default query type: &#39;threads&#39; or &#39;messages&#39;.
Definition: mutt_notmuch.c:78
struct UrlQueryList query_strings
List of query strings.
Definition: url.h:74
char * db_query
Previous query.
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
struct Url * db_url
Parsed view url of the Notmuch database.
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_error(...)
Definition: logging.h:84
static enum NmQueryType string_to_query_type(const char *str)
Lookup a query type.
Definition: mutt_notmuch.c:116
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static bool windowed_query_from_query(const char *query, char *buf, size_t buflen)
transforms a vfolder search query into a windowed one
Definition: mutt_notmuch.c:429
enum NmQueryType query_type
Messages or Threads.
int db_limit
Maximum number of results to return.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_limit()

static int get_limit ( struct NmMboxData mdata)
static

Get the database limit.

Parameters
mdataNotmuch Mailbox data
Return values
numCurrent limit

Definition at line 548 of file mutt_notmuch.c.

549 {
550  return mdata ? mdata->db_limit : 0;
551 }
int db_limit
Maximum number of results to return.
+ Here is the caller graph for this function:

◆ apply_exclude_tags()

static void apply_exclude_tags ( notmuch_query_t *  query)
static

Exclude the configured tags.

Parameters
queryNotmuch query

Definition at line 557 of file mutt_notmuch.c.

558 {
559  if (!C_NmExcludeTags || !query)
560  return;
561 
562  char *end = NULL, *tag = NULL;
563 
564  char *buf = mutt_str_strdup(C_NmExcludeTags);
565 
566  for (char *p = buf; p && (p[0] != '\0'); p++)
567  {
568  if (!tag && isspace(*p))
569  continue;
570  if (!tag)
571  tag = p; /* begin of the tag */
572  if ((p[0] == ',') || (p[0] == ' '))
573  end = p; /* terminate the tag */
574  else if (p[1] == '\0')
575  end = p + 1; /* end of optstr */
576  if (!tag || !end)
577  continue;
578  if (tag >= end)
579  break;
580  *end = '\0';
581 
582  mutt_debug(LL_DEBUG2, "nm: query exclude tag '%s'\n", tag);
583  notmuch_query_add_tag_exclude(query, tag);
584  end = NULL;
585  tag = NULL;
586  }
587  notmuch_query_set_omit_excluded(query, 1);
588  FREE(&buf);
589 }
char * C_NmExcludeTags
Config: (notmuch) Exclude messages with these tags.
Definition: mutt_notmuch.c:76
Log at debug level 2.
Definition: logging.h:57
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_query()

static notmuch_query_t* get_query ( struct Mailbox m,
bool  writable 
)
static

Create a new query.

Parameters
mMailbox
writableShould the query be updateable?
Return values
ptrNotmuch query
NULLError

Definition at line 598 of file mutt_notmuch.c.

599 {
600  struct NmMboxData *mdata = nm_mdata_get(m);
601  if (!mdata)
602  return NULL;
603 
604  notmuch_database_t *db = nm_db_get(m, writable);
605  const char *str = get_query_string(mdata, true);
606 
607  if (!db || !str)
608  goto err;
609 
610  notmuch_query_t *q = notmuch_query_create(db, str);
611  if (!q)
612  goto err;
613 
615  notmuch_query_set_sort(q, NOTMUCH_SORT_NEWEST_FIRST);
616  mutt_debug(LL_DEBUG2, "nm: query successfully initialized (%s)\n", str);
617  return q;
618 err:
619  nm_db_release(m);
620  return NULL;
621 }
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:143
Log at debug level 2.
Definition: logging.h:57
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
void * mdata
Driver specific data.
Definition: mailbox.h:147
static char * get_query_string(struct NmMboxData *mdata, bool window)
builds the notmuch vfolder search string
Definition: mutt_notmuch.c:489
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
static void apply_exclude_tags(notmuch_query_t *query)
Exclude the configured tags.
Definition: mutt_notmuch.c:557
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_email_tags()

static int update_email_tags ( struct Email e,
notmuch_message_t *  msg 
)
static

Update the Email's tags from Notmuch.

Parameters
eEmail
msgNotmuch message
Return values
0Success
1Tags unchanged

Definition at line 630 of file mutt_notmuch.c.

631 {
632  struct NmEmailData *edata = e->edata;
633  char *new_tags = NULL;
634  char *old_tags = NULL;
635 
636  mutt_debug(LL_DEBUG2, "nm: tags update requested (%s)\n", edata->virtual_id);
637 
638  for (notmuch_tags_t *tags = notmuch_message_get_tags(msg);
639  tags && notmuch_tags_valid(tags); notmuch_tags_move_to_next(tags))
640  {
641  const char *t = notmuch_tags_get(tags);
642  if (!t || !*t)
643  continue;
644 
645  mutt_str_append_item(&new_tags, t, ' ');
646  }
647 
648  old_tags = driver_tags_get(&e->tags);
649 
650  if (new_tags && old_tags && (strcmp(old_tags, new_tags) == 0))
651  {
652  FREE(&old_tags);
653  FREE(&new_tags);
654  mutt_debug(LL_DEBUG2, "nm: tags unchanged\n");
655  return 1;
656  }
657 
658  /* new version */
659  driver_tags_replace(&e->tags, new_tags);
660  FREE(&new_tags);
661 
662  new_tags = driver_tags_get_transformed(&e->tags);
663  mutt_debug(LL_DEBUG2, "nm: new tags: '%s'\n", new_tags);
664  FREE(&new_tags);
665 
666  new_tags = driver_tags_get(&e->tags);
667  mutt_debug(LL_DEBUG2, "nm: new tag transforms: '%s'\n", new_tags);
668  FREE(&new_tags);
669 
670  return 0;
671 }
Log at debug level 2.
Definition: logging.h:57
char * virtual_id
Unique Notmuch Id.
struct TagList tags
For drivers that support server tagging.
Definition: email.h:108
Notmuch-specific Email data -.
char * driver_tags_get(struct TagList *list)
Get tags.
Definition: tags.c:141
char * driver_tags_get_transformed(struct TagList *list)
Get transformed tags.
Definition: tags.c:129
void * edata
Driver-specific data.
Definition: email.h:112
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
bool driver_tags_replace(struct TagList *head, char *tags)
Replace all tags.
Definition: tags.c:182
void mutt_str_append_item(char **str, const char *item, char sep)
Add string to another separated by sep.
Definition: string.c:471
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_message_path()

static int update_message_path ( struct Email e,
const char *  path 
)
static

Set the path for a message.

Parameters
eEmail
pathPath
Return values
0Success
1Failure

Definition at line 680 of file mutt_notmuch.c.

681 {
682  struct NmEmailData *edata = e->edata;
683 
684  mutt_debug(LL_DEBUG2, "nm: path update requested path=%s, (%s)\n", path, edata->virtual_id);
685 
686  char *p = strrchr(path, '/');
687  if (p && ((p - path) > 3) &&
688  ((strncmp(p - 3, "cur", 3) == 0) || (strncmp(p - 3, "new", 3) == 0) ||
689  (strncmp(p - 3, "tmp", 3) == 0)))
690  {
691  edata->magic = MUTT_MAILDIR;
692 
693  FREE(&e->path);
694  FREE(&edata->folder);
695 
696  p -= 3; /* skip subfolder (e.g. "new") */
697  e->path = mutt_str_strdup(p);
698 
699  for (; (p > path) && (*(p - 1) == '/'); p--)
700  ;
701 
702  edata->folder = mutt_str_substr_dup(path, p);
703 
704  mutt_debug(LL_DEBUG2, "nm: folder='%s', file='%s'\n", edata->folder, e->path);
705  return 0;
706  }
707 
708  return 1;
709 }
Log at debug level 2.
Definition: logging.h:57
char * virtual_id
Unique Notmuch Id.
char * folder
Location of the Email.
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:50
Notmuch-specific Email data -.
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
void * edata
Driver-specific data.
Definition: email.h:112
char * path
Path of Email (for local Mailboxes)
Definition: email.h:93
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * mutt_str_substr_dup(const char *begin, const char *end)
Duplicate a sub-string.
Definition: string.c:579
enum MailboxType magic
Type of Mailbox the Email is in.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_folder_from_path()

static char* get_folder_from_path ( const char *  path)
static

Find an email's folder from its path.

Parameters
pathPath
Return values
ptrPath string
NULLError

Definition at line 717 of file mutt_notmuch.c.

718 {
719  char *p = strrchr(path, '/');
720 
721  if (p && ((p - path) > 3) &&
722  ((strncmp(p - 3, "cur", 3) == 0) || (strncmp(p - 3, "new", 3) == 0) ||
723  (strncmp(p - 3, "tmp", 3) == 0)))
724  {
725  p -= 3;
726  for (; (p > path) && (*(p - 1) == '/'); p--)
727  ;
728 
729  return mutt_str_substr_dup(path, p);
730  }
731 
732  return NULL;
733 }
char * path
Path of Email (for local Mailboxes)
Definition: email.h:93
char * mutt_str_substr_dup(const char *begin, const char *end)
Duplicate a sub-string.
Definition: string.c:579
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm2mutt_message_id()

static char* nm2mutt_message_id ( const char *  id)
static

converts notmuch message Id to neomutt message Id

Parameters
idNotmuch ID to convert
Return values
ptrNeoMutt message ID

Caller must free the NeoMutt Message ID

Definition at line 742 of file mutt_notmuch.c.

743 {
744  size_t sz;
745  char *mid = NULL;
746 
747  if (!id)
748  return NULL;
749  sz = strlen(id) + 3;
750  mid = mutt_mem_malloc(sz);
751 
752  snprintf(mid, sz, "<%s>", id);
753  return mid;
754 }
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_email()

static int init_email ( struct Email e,
const char *  path,
notmuch_message_t *  msg 
)
static

Set up an email's Notmuch data.

Parameters
eEmail
pathPath to email
msgNotmuch message
Return values
0Success
-1Failure

Definition at line 764 of file mutt_notmuch.c.

765 {
766  if (e->edata)
767  return 0;
768 
769  struct NmEmailData *edata = nm_edata_new();
770  e->edata = edata;
772 
773  /* Notmuch ensures that message Id exists (if not notmuch Notmuch will
774  * generate an ID), so it's more safe than use neomutt Email->env->id */
775  const char *id = notmuch_message_get_message_id(msg);
776  edata->virtual_id = mutt_str_strdup(id);
777 
778  mutt_debug(LL_DEBUG2, "nm: [e=%p, edata=%p] (%s)\n", (void *) e, (void *) e->edata, id);
779 
780  char *nm_msg_id = nm2mutt_message_id(id);
781  if (!e->env->message_id)
782  {
783  e->env->message_id = nm_msg_id;
784  }
785  else if (mutt_str_strcmp(e->env->message_id, nm_msg_id) != 0)
786  {
787  FREE(&e->env->message_id);
788  e->env->message_id = nm_msg_id;
789  }
790  else
791  {
792  FREE(&nm_msg_id);
793  }
794 
795  if (update_message_path(e, path) != 0)
796  return -1;
797 
798  update_email_tags(e, msg);
799 
800  return 0;
801 }
void(* free_edata)(void **)
Driver-specific data free function.
Definition: email.h:113
static int update_email_tags(struct Email *e, notmuch_message_t *msg)
Update the Email&#39;s tags from Notmuch.
Definition: mutt_notmuch.c:630
Log at debug level 2.
Definition: logging.h:57
static char * nm2mutt_message_id(const char *id)
converts notmuch message Id to neomutt message Id
Definition: mutt_notmuch.c:742
char * virtual_id
Unique Notmuch Id.
void nm_edata_free(void **ptr)
Free data attached to an Email.
Definition: mutt_notmuch.c:246
Notmuch-specific Email data -.
static int update_message_path(struct Email *e, const char *path)
Set the path for a message.
Definition: mutt_notmuch.c:680
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
void * edata
Driver-specific data.
Definition: email.h:112
char * path
Path of Email (for local Mailboxes)
Definition: email.h:93
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct NmEmailData * nm_edata_new(void)
Create a new NmEmailData for an email.
Definition: mutt_notmuch.c:263
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_message_last_filename()

static const char* get_message_last_filename ( notmuch_message_t *  msg)
static

Get a message's last filename.

Parameters
msgNotmuch message
Return values
ptrFilename
NULLError

Definition at line 809 of file mutt_notmuch.c.

810 {
811  const char *name = NULL;
812 
813  for (notmuch_filenames_t *ls = notmuch_message_get_filenames(msg);
814  ls && notmuch_filenames_valid(ls); notmuch_filenames_move_to_next(ls))
815  {
816  name = notmuch_filenames_get(ls);
817  }
818 
819  return name;
820 }
const char * name
Definition: pgpmicalg.c:45
+ Here is the caller graph for this function:

◆ progress_reset()

static void progress_reset ( struct Mailbox m)
static

Reset the progress counter.

Parameters
mMailbox

Definition at line 826 of file mutt_notmuch.c.

827 {
828  if (m->quiet)
829  return;
830 
831  struct NmMboxData *mdata = nm_mdata_get(m);
832  if (!mdata)
833  return;
834 
835  memset(&mdata->progress, 0, sizeof(mdata->progress));
836  mdata->oldmsgcount = m->msg_count;
837  mdata->ignmsgcount = 0;
838  mdata->noprogress = false;
839  mdata->progress_ready = false;
840 }
int msg_count
Total number of messages.
Definition: mailbox.h:102
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
struct Progress progress
A progress bar.
bool quiet
Inhibit status messages?
Definition: mailbox.h:129
int ignmsgcount
Ignored messages.
bool noprogress
Don&#39;t show the progress bar.
bool progress_ready
A progress bar has been initialised.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ progress_update()

static void progress_update ( struct Mailbox m,
notmuch_query_t *  q 
)
static

Update the progress counter.

Parameters
mMailbox
qNotmuch query

Definition at line 847 of file mutt_notmuch.c.

848 {
849  struct NmMboxData *mdata = nm_mdata_get(m);
850 
851  if (m->quiet || !mdata || mdata->noprogress)
852  return;
853 
854  if (!mdata->progress_ready && q)
855  {
856  // The total mail count is in oldmsgcount, so use that instead of recounting.
857  mutt_progress_init(&mdata->progress, _("Reading messages..."),
859  mdata->progress_ready = true;
860  }
861 
862  if (mdata->progress_ready)
863  {
864  mutt_progress_update(&mdata->progress, m->msg_count + mdata->ignmsgcount, -1);
865  }
866 }
int msg_count
Total number of messages.
Definition: mailbox.h:102
#define _(a)
Definition: message.h:28
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
Notmuch-specific Mailbox data -.
Progress tracks elements, according to C_ReadInc.
Definition: progress.h:40
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
struct Progress progress
A progress bar.
bool quiet
Inhibit status messages?
Definition: mailbox.h:129
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
int ignmsgcount
Ignored messages.
bool noprogress
Don&#39;t show the progress bar.
bool progress_ready
A progress bar has been initialised.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_mutt_email()

static struct Email* get_mutt_email ( struct Mailbox m,
notmuch_message_t *  msg 
)
static

Get the Email of a Notmuch message.

Parameters
mMailbox
msgNotmuch message
Return values
ptrEmail
NULLError

Definition at line 875 of file mutt_notmuch.c.

876 {
877  if (!m || !msg)
878  return NULL;
879 
880  const char *id = notmuch_message_get_message_id(msg);
881  if (!id)
882  return NULL;
883 
884  mutt_debug(LL_DEBUG2, "nm: neomutt email, id='%s'\n", id);
885 
886  if (!m->id_hash)
887  {
888  mutt_debug(LL_DEBUG2, "nm: init hash\n");
889  m->id_hash = mutt_make_id_hash(m);
890  if (!m->id_hash)
891  return NULL;
892  }
893 
894  char *mid = nm2mutt_message_id(id);
895  mutt_debug(LL_DEBUG2, "nm: neomutt id='%s'\n", mid);
896 
897  struct Email *e = mutt_hash_find(m->id_hash, mid);
898  FREE(&mid);
899  return e;
900 }
The envelope/body of an email.
Definition: email.h:39
void * mutt_hash_find(const struct Hash *table, const char *strkey)
Find the HashElem data in a Hash table element using a key.
Definition: hash.c:379
Log at debug level 2.
Definition: logging.h:57
static char * nm2mutt_message_id(const char *id)
converts notmuch message Id to neomutt message Id
Definition: mutt_notmuch.c:742
struct Hash * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1437
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Hash * id_hash
Hash table by msg id.
Definition: mailbox.h:138
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ append_message()

static void append_message ( header_cache_t h,
struct Mailbox m,
notmuch_query_t *  q,
notmuch_message_t *  msg,
bool  dedup 
)
static

Associate a message.

Parameters
hHeader cache handle
mMailbox
qNotmuch query
msgNotmuch message
dedupDe-duplicate results

Definition at line 910 of file mutt_notmuch.c.

912 {
913  struct NmMboxData *mdata = nm_mdata_get(m);
914  if (!mdata)
915  return;
916 
917  char *newpath = NULL;
918  struct Email *e = NULL;
919 
920  /* deduplicate */
921  if (dedup && get_mutt_email(m, msg))
922  {
923  mdata->ignmsgcount++;
924  progress_update(m, q);
925  mutt_debug(LL_DEBUG2, "nm: ignore id=%s, already in the m\n",
926  notmuch_message_get_message_id(msg));
927  return;
928  }
929 
930  const char *path = get_message_last_filename(msg);
931  if (!path)
932  return;
933 
934  mutt_debug(LL_DEBUG2, "nm: appending message, i=%d, id=%s, path=%s\n",
935  m->msg_count, notmuch_message_get_message_id(msg), path);
936 
937  if (m->msg_count >= m->email_max)
938  {
939  mutt_debug(LL_DEBUG2, "nm: allocate mx memory\n");
940  mx_alloc_memory(m);
941  }
942 
943 #ifdef USE_HCACHE
944  void *from_cache = mutt_hcache_fetch(h, path, mutt_str_strlen(path));
945  if (from_cache)
946  {
947  e = mutt_hcache_restore(from_cache);
948  }
949  else
950 #endif
951  {
952  if (access(path, F_OK) == 0)
953  e = maildir_parse_message(MUTT_MAILDIR, path, false, NULL);
954  else
955  {
956  /* maybe moved try find it... */
957  char *folder = get_folder_from_path(path);
958 
959  if (folder)
960  {
961  FILE *fp = maildir_open_find_message(folder, path, &newpath);
962  if (fp)
963  {
964  e = maildir_parse_stream(MUTT_MAILDIR, fp, newpath, false, NULL);
965  fclose(fp);
966 
967  mutt_debug(LL_DEBUG1, "nm: not up-to-date: %s -> %s\n", path, newpath);
968  }
969  }
970  FREE(&folder);
971  }
972  }
973 
974  if (!e)
975  {
976  mutt_debug(LL_DEBUG1, "nm: failed to parse message: %s\n", path);
977  goto done;
978  }
979 
980 #ifdef USE_HCACHE
981 
982  if (from_cache)
983  {
984  mutt_hcache_free(h, &from_cache);
985  }
986  else
987  {
988  mutt_hcache_store(h, newpath ? newpath : path,
989  mutt_str_strlen(newpath ? newpath : path), e, 0);
990  }
991 #endif
992  if (init_email(e, newpath ? newpath : path, msg) != 0)
993  {
994  email_free(&e);
995  mutt_debug(LL_DEBUG1, "nm: failed to append email!\n");
996  goto done;
997  }
998 
999  e->active = true;
1000  e->index = m->msg_count;
1001  mailbox_size_add(m, e);
1002  m->emails[m->msg_count] = e;
1003  m->msg_count++;
1004 
1005  if (newpath)
1006  {
1007  /* remember that file has been moved -- nm_mbox_sync() will update the DB */
1008  struct NmEmailData *edata = e->edata;
1009 
1010  if (edata)
1011  {
1012  mutt_debug(LL_DEBUG1, "nm: remember obsolete path: %s\n", path);
1013  edata->oldpath = mutt_str_strdup(path);
1014  }
1015  }
1016  progress_update(m, q);
1017 done:
1018  FREE(&newpath);
1019 }
void * mutt_hcache_fetch(header_cache_t *hc, const char *key, size_t keylen)
Multiplexor for HcacheOps::fetch.
Definition: hcache.c:347
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
int msg_count
Total number of messages.
Definition: mailbox.h:102
The envelope/body of an email.
Definition: email.h:39
void mailbox_size_add(struct Mailbox *m, const struct Email *e)
Add an email&#39;s size to the total size of a Mailbox.
Definition: mailbox.c:173
static const char * get_message_last_filename(notmuch_message_t *msg)
Get a message&#39;s last filename.
Definition: mutt_notmuch.c:809
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1113
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
struct Email * mutt_hcache_restore(const unsigned char *d)
restore an Email from data retrieved from the cache
Definition: serialize.c:634
Log at debug level 2.
Definition: logging.h:57
Notmuch-specific Mailbox data -.
FILE * maildir_open_find_message(const char *folder, const char *msg, char **newname)
Find a new.
Definition: shared.c:1487
static void progress_update(struct Mailbox *m, notmuch_query_t *q)
Update the progress counter.
Definition: mutt_notmuch.c:847
void * mdata
Driver specific data.
Definition: mailbox.h:147
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:50
bool active
Message is not to be removed.
Definition: email.h:61
struct Email * maildir_parse_message(enum MailboxType magic, const char *fname, bool is_old, struct Email *e)
Actually parse a maildir message.
Definition: shared.c:1330
int email_max
Number of pointers in emails.
Definition: mailbox.h:111
Notmuch-specific Email data -.
static int init_email(struct Email *e, const char *path, notmuch_message_t *msg)
Set up an email&#39;s Notmuch data.
Definition: mutt_notmuch.c:764
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
int mutt_hcache_store(header_cache_t *hc, const char *key, size_t keylen, struct Email *e, unsigned int uidvalidity)
Multiplexor for HcacheOps::store.
Definition: hcache.c:406
Log at debug level 1.
Definition: logging.h:56
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
void * edata
Driver-specific data.
Definition: email.h:112
static struct Email * get_mutt_email(struct Mailbox *m, notmuch_message_t *msg)
Get the Email of a Notmuch message.
Definition: mutt_notmuch.c:875
static char * get_folder_from_path(const char *path)
Find an email&#39;s folder from its path.
Definition: mutt_notmuch.c:717
char * path
Path of Email (for local Mailboxes)
Definition: email.h:93
int ignmsgcount
Ignored messages.
int index
The absolute (unsorted) message number.
Definition: email.h:87
#define FREE(x)
Definition: memory.h:40
void mutt_hcache_free(header_cache_t *hc, void **data)
Multiplexor for HcacheOps::free.
Definition: hcache.c:393
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct Email * maildir_parse_stream(enum MailboxType magic, FILE *fp, const char *fname, bool is_old, struct Email *e)
Parse a Maildir message.
Definition: shared.c:1290
void email_free(struct Email **ptr)
Free an Email.
Definition: email.c:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ append_replies()

static void append_replies ( header_cache_t h,
struct Mailbox m,
notmuch_query_t *  q,
notmuch_message_t *  top,
bool  dedup 
)
static

add all the replies to a given messages into the display

Parameters
hHeader cache handle
mMailbox
qNotmuch query
topNotmuch message
dedupDe-duplicate the results

Careful, this calls itself recursively to make sure we get everything.

Definition at line 1031 of file mutt_notmuch.c.

1033 {
1034  notmuch_messages_t *msgs = NULL;
1035 
1036  for (msgs = notmuch_message_get_replies(top); notmuch_messages_valid(msgs);
1037  notmuch_messages_move_to_next(msgs))
1038  {
1039  notmuch_message_t *nm = notmuch_messages_get(msgs);
1040  append_message(h, m, q, nm, dedup);
1041  /* recurse through all the replies to this message too */
1042  append_replies(h, m, q, nm, dedup);
1043  notmuch_message_destroy(nm);
1044  }
1045 }
static void append_message(header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_message_t *msg, bool dedup)
Associate a message.
Definition: mutt_notmuch.c:910
static void append_replies(header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_message_t *top, bool dedup)
add all the replies to a given messages into the display
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ append_thread()

static void append_thread ( header_cache_t h,
struct Mailbox m,
notmuch_query_t *  q,
notmuch_thread_t *  thread,
bool  dedup 
)
static

add each top level reply in the thread

Parameters
hHeader cache handle
mMailbox
qNotmuch query
threadNotmuch thread
dedupDe-duplicate the results

add each top level reply in the thread, and then add each reply to the top level replies

Definition at line 1058 of file mutt_notmuch.c.

1060 {
1061  notmuch_messages_t *msgs = NULL;
1062 
1063  for (msgs = notmuch_thread_get_toplevel_messages(thread);
1064  notmuch_messages_valid(msgs); notmuch_messages_move_to_next(msgs))
1065  {
1066  notmuch_message_t *nm = notmuch_messages_get(msgs);
1067  append_message(h, m, q, nm, dedup);
1068  append_replies(h, m, q, nm, dedup);
1069  notmuch_message_destroy(nm);
1070  }
1071 }
static void append_message(header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_message_t *msg, bool dedup)
Associate a message.
Definition: mutt_notmuch.c:910
struct MuttThread * thread
Thread of Emails.
Definition: email.h:96
static void append_replies(header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_message_t *top, bool dedup)
add all the replies to a given messages into the display
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_messages()

static notmuch_messages_t* get_messages ( notmuch_query_t *  query)
static

load messages for a query

Parameters
queryNotmuch query
Return values
ptrMessages matching query
NULLError occurred

This helper method is to be the single point for retrieving messages. It handles version specific calls, which will make maintenance easier.

Definition at line 1082 of file mutt_notmuch.c.

1083 {
1084  if (!query)
1085  return NULL;
1086 
1087  notmuch_messages_t *msgs = NULL;
1088 
1089 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
1090  if (notmuch_query_search_messages(query, &msgs) != NOTMUCH_STATUS_SUCCESS)
1091  return NULL;
1092 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
1093  if (notmuch_query_search_messages_st(query, &msgs) != NOTMUCH_STATUS_SUCCESS)
1094  return NULL;
1095 #else
1096  msgs = notmuch_query_search_messages(query);
1097 #endif
1098 
1099  return msgs;
1100 }
+ Here is the caller graph for this function:

◆ read_mesgs_query()

static bool read_mesgs_query ( struct Mailbox m,
notmuch_query_t *  q,
bool  dedup 
)
static

Search for matching messages.

Parameters
mMailbox
qNotmuch query
dedupDe-duplicate the results
Return values
trueSuccess
falseFailure

Definition at line 1110 of file mutt_notmuch.c.

1111 {
1112  struct NmMboxData *mdata = nm_mdata_get(m);
1113  if (!mdata)
1114  return false;
1115 
1116  int limit = get_limit(mdata);
1117 
1118  notmuch_messages_t *msgs = get_messages(q);
1119 
1120  if (!msgs)
1121  return false;
1122 
1124 
1125  for (; notmuch_messages_valid(msgs) && ((limit == 0) || (m->msg_count < limit));
1126  notmuch_messages_move_to_next(msgs))
1127  {
1128  if (SigInt == 1)
1129  {
1130  nm_hcache_close(h);
1131  SigInt = 0;
1132  return false;
1133  }
1134  notmuch_message_t *nm = notmuch_messages_get(msgs);
1135  append_message(h, m, q, nm, dedup);
1136  notmuch_message_destroy(nm);
1137  }
1138 
1139  nm_hcache_close(h);
1140  return true;
1141 }
int msg_count
Total number of messages.
Definition: mailbox.h:102
static void append_message(header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_message_t *msg, bool dedup)
Associate a message.
Definition: mutt_notmuch.c:910
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: globals.h:84
static notmuch_messages_t * get_messages(notmuch_query_t *query)
load messages for a query
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:147
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: mutt_notmuch.c:548
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
static header_cache_t * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: mutt_notmuch.c:91
header cache structure
Definition: hcache.h:67
void nm_hcache_close(header_cache_t *h)
Close the header cache.
Definition: mutt_notmuch.c:104
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_threads()

static notmuch_threads_t* get_threads ( notmuch_query_t *  query)
static

load threads for a query

Parameters
queryNotmuch query
Return values
ptrThreads matching query
NULLError occurred

This helper method is to be the single point for retrieving messages. It handles version specific calls, which will make maintenance easier.

Definition at line 1152 of file mutt_notmuch.c.

1153 {
1154  if (!query)
1155  return NULL;
1156 
1157  notmuch_threads_t *threads = NULL;
1158 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
1159  if (notmuch_query_search_threads(query, &threads) != NOTMUCH_STATUS_SUCCESS)
1160  return false;
1161 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
1162  if (notmuch_query_search_threads_st(query, &threads) != NOTMUCH_STATUS_SUCCESS)
1163  return false;
1164 #else
1165  threads = notmuch_query_search_threads(query);
1166 #endif
1167 
1168  return threads;
1169 }
+ Here is the caller graph for this function:

◆ read_threads_query()

static bool read_threads_query ( struct Mailbox m,
notmuch_query_t *  q,
bool  dedup,
int  limit 
)
static

Perform a query with threads.

Parameters
mMailbox
qQuery type
dedupShould the results be de-duped?
limitMaximum number of results
Return values
trueSuccess
falseFailure

Definition at line 1180 of file mutt_notmuch.c.

1181 {
1182  struct NmMboxData *mdata = nm_mdata_get(m);
1183  if (!mdata)
1184  return false;
1185 
1186  notmuch_threads_t *threads = get_threads(q);
1187  if (!threads)
1188  return false;
1189 
1191 
1192  for (; notmuch_threads_valid(threads) && ((limit == 0) || (m->msg_count < limit));
1193  notmuch_threads_move_to_next(threads))
1194  {
1195  if (SigInt == 1)
1196  {
1197  nm_hcache_close(h);
1198  SigInt = 0;
1199  return false;
1200  }
1201  notmuch_thread_t *thread = notmuch_threads_get(threads);
1202  append_thread(h, m, q, thread, dedup);
1203  notmuch_thread_destroy(thread);
1204  }
1205 
1206  nm_hcache_close(h);
1207  return true;
1208 }
int msg_count
Total number of messages.
Definition: mailbox.h:102
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: globals.h:84
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
static void append_thread(header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_thread_t *thread, bool dedup)
add each top level reply in the thread
static header_cache_t * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: mutt_notmuch.c:91
static notmuch_threads_t * get_threads(notmuch_query_t *query)
load threads for a query
header cache structure
Definition: hcache.h:67
void nm_hcache_close(header_cache_t *h)
Close the header cache.
Definition: mutt_notmuch.c:104
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_nm_message()

static notmuch_message_t* get_nm_message ( notmuch_database_t *  db,
struct Email e 
)
static

Find a Notmuch message.

Parameters
dbNotmuch database
eEmail
Return values
ptrHandle to the Notmuch message

Definition at line 1216 of file mutt_notmuch.c.

1217 {
1218  notmuch_message_t *msg = NULL;
1219  char *id = email_get_id(e);
1220 
1221  mutt_debug(LL_DEBUG2, "nm: find message (%s)\n", id);
1222 
1223  if (id && db)
1224  notmuch_database_find_message(db, id, &msg);
1225 
1226  return msg;
1227 }
static char * email_get_id(struct Email *e)
Get the unique Notmuch Id.
Definition: mutt_notmuch.c:322
Log at debug level 2.
Definition: logging.h:57
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_message_has_tag()

static bool nm_message_has_tag ( notmuch_message_t *  msg,
char *  tag 
)
static

Does a message have this tag?

Parameters
msgNotmuch message
tagTag
Return values
trueIt does

Definition at line 1235 of file mutt_notmuch.c.

1236 {
1237  const char *possible_match_tag = NULL;
1238  notmuch_tags_t *tags = NULL;
1239 
1240  for (tags = notmuch_message_get_tags(msg); notmuch_tags_valid(tags);
1241  notmuch_tags_move_to_next(tags))
1242  {
1243  possible_match_tag = notmuch_tags_get(tags);
1244  if (mutt_str_strcmp(possible_match_tag, tag) == 0)
1245  {
1246  return true;
1247  }
1248  }
1249  return false;
1250 }
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_tags()

static int update_tags ( notmuch_message_t *  msg,
const char *  tags 
)
static

Update the tags on a message.

Parameters
msgNotmuch message
tagsString of tags (space separated)
Return values
0Success
-1Failure

Definition at line 1259 of file mutt_notmuch.c.

1260 {
1261  char *buf = mutt_str_strdup(tags);
1262  if (!buf)
1263  return -1;
1264 
1265  notmuch_message_freeze(msg);
1266 
1267  char *tag = NULL, *end = NULL;
1268  for (char *p = buf; p && *p; p++)
1269  {
1270  if (!tag && isspace(*p))
1271  continue;
1272  if (!tag)
1273  tag = p; /* begin of the tag */
1274  if ((p[0] == ',') || (p[0] == ' '))
1275  end = p; /* terminate the tag */
1276  else if (p[1] == '\0')
1277  end = p + 1; /* end of optstr */
1278  if (!tag || !end)
1279  continue;
1280  if (tag >= end)
1281  break;
1282 
1283  end[0] = '\0';
1284 
1285  if (tag[0] == '-')
1286  {
1287  mutt_debug(LL_DEBUG1, "nm: remove tag: '%s'\n", tag + 1);
1288  notmuch_message_remove_tag(msg, tag + 1);
1289  }
1290  else if (tag[0] == '!')
1291  {
1292  mutt_debug(LL_DEBUG1, "nm: toggle tag: '%s'\n", tag + 1);
1293  if (nm_message_has_tag(msg, tag + 1))
1294  {
1295  notmuch_message_remove_tag(msg, tag + 1);
1296  }
1297  else
1298  {
1299  notmuch_message_add_tag(msg, tag + 1);
1300  }
1301  }
1302  else
1303  {
1304  mutt_debug(LL_DEBUG1, "nm: add tag: '%s'\n", (tag[0] == '+') ? tag + 1 : tag);
1305  notmuch_message_add_tag(msg, (tag[0] == '+') ? tag + 1 : tag);
1306  }
1307  end = NULL;
1308  tag = NULL;
1309  }
1310 
1311  notmuch_message_thaw(msg);
1312  FREE(&buf);
1313  return 0;
1314 }
static bool nm_message_has_tag(notmuch_message_t *msg, char *tag)
Does a message have this tag?
Log at debug level 1.
Definition: logging.h:56
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_email_flags()

static int update_email_flags ( struct Mailbox m,
struct Email e,
const char *  tags 
)
static

Update the Email's flags.

Parameters
mMailbox
eEmail
tagsString of tags (space separated)
Return values
0Success
-1Failure

TODO: extract parsing of string to separate function, join update_email_tags and update_email_flags, which are given an array of tags.

Definition at line 1328 of file mutt_notmuch.c.

1329 {
1330  char *buf = mutt_str_strdup(tags);
1331  if (!buf)
1332  return -1;
1333 
1334  char *tag = NULL, *end = NULL;
1335  for (char *p = buf; p && *p; p++)
1336  {
1337  if (!tag && isspace(*p))
1338  continue;
1339  if (!tag)
1340  tag = p; /* begin of the tag */
1341  if ((p[0] == ',') || (p[0] == ' '))
1342  end = p; /* terminate the tag */
1343  else if (p[1] == '\0')
1344  end = p + 1; /* end of optstr */
1345  if (!tag || !end)
1346  continue;
1347  if (tag >= end)
1348  break;
1349 
1350  end[0] = '\0';
1351 
1352  if (tag[0] == '-')
1353  {
1354  tag++;
1355  if (strcmp(tag, C_NmUnreadTag) == 0)
1356  mutt_set_flag(m, e, MUTT_READ, true);
1357  else if (strcmp(tag, C_NmRepliedTag) == 0)
1358  mutt_set_flag(m, e, MUTT_REPLIED, false);
1359  else if (strcmp(tag, C_NmFlaggedTag) == 0)
1360  mutt_set_flag(m, e, MUTT_FLAG, false);
1361  }
1362  else
1363  {
1364  tag = (tag[0] == '+') ? tag + 1 : tag;
1365  if (strcmp(tag, C_NmUnreadTag) == 0)
1366  mutt_set_flag(m, e, MUTT_READ, false);
1367  else if (strcmp(tag, C_NmRepliedTag) == 0)
1368  mutt_set_flag(m, e, MUTT_REPLIED, true);
1369  else if (strcmp(tag, C_NmFlaggedTag) == 0)
1370  mutt_set_flag(m, e, MUTT_FLAG, true);
1371  }
1372  end = NULL;
1373  tag = NULL;
1374  }
1375 
1376  FREE(&buf);
1377  return 0;
1378 }
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:69
Flagged messages.
Definition: mutt.h:108
char * C_NmUnreadTag
Config: (notmuch) Tag to use for unread messages.
Definition: mutt_notmuch.c:82
Messages that have been replied to.
Definition: mutt.h:101
char * C_NmRepliedTag
Config: (notmuch) Tag to use for replied messages.
Definition: mutt_notmuch.c:84
Messages that have been read.
Definition: mutt.h:102
char * C_NmFlaggedTag
Config: (notmuch) Tag to use for flagged messages.
Definition: mutt_notmuch.c:83
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rename_maildir_filename()

static int rename_maildir_filename ( const char *  old,
char *  buf,
size_t  buflen,
struct Email e 
)
static

Rename a Maildir file.

Parameters
oldOld path
bufBuffer for new path
buflenLength of buffer
eEmail
Return values
0Success, renamed
1Success, no change
-1Failure

Definition at line 1390 of file mutt_notmuch.c.

1391 {
1392  char filename[PATH_MAX];
1393  char suffix[PATH_MAX];
1394  char folder[PATH_MAX];
1395 
1396  mutt_str_strfcpy(folder, old, sizeof(folder));
1397  char *p = strrchr(folder, '/');
1398  if (p)
1399  {
1400  *p = '\0';
1401  p++;
1402  }
1403  else
1404  p = folder;
1405 
1406  mutt_str_strfcpy(filename, p, sizeof(filename));
1407 
1408  /* remove (new,cur,...) from folder path */
1409  p = strrchr(folder, '/');
1410  if (p)
1411  *p = '\0';
1412 
1413  /* remove old flags from filename */
1414  p = strchr(filename, ':');
1415  if (p)
1416  *p = '\0';
1417 
1418  /* compose new flags */
1419  maildir_gen_flags(suffix, sizeof(suffix), e);
1420 
1421  snprintf(buf, buflen, "%s/%s/%s%s", folder,
1422  (e->read || e->old) ? "cur" : "new", filename, suffix);
1423 
1424  if (strcmp(old, buf) == 0)
1425  return 1;
1426 
1427  if (rename(old, buf) != 0)
1428  {
1429  mutt_debug(LL_DEBUG1, "nm: rename(2) failed %s -> %s\n", old, buf);
1430  return -1;
1431  }
1432 
1433  return 0;
1434 }
bool read
Email is read.
Definition: email.h:53
bool old
Email is seen, but unread.
Definition: email.h:52
#define PATH_MAX
Definition: mutt.h:52
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
void maildir_gen_flags(char *dest, size_t destlen, struct Email *e)
Generate the Maildir flags for an email.
Definition: maildir.c:172
Log at debug level 1.
Definition: logging.h:56
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ remove_filename()

static int remove_filename ( struct Mailbox m,
const char *  path 
)
static

Delete a file.

Parameters
mMailbox
pathPath of file
Return values
0Success
-1Failure

Definition at line 1443 of file mutt_notmuch.c.

1444 {
1445  struct NmMboxData *mdata = nm_mdata_get(m);
1446  if (!mdata)
1447  return -1;
1448 
1449  mutt_debug(LL_DEBUG2, "nm: remove filename '%s'\n", path);
1450 
1451  notmuch_database_t *db = nm_db_get(m, true);
1452  if (!db)
1453  return -1;
1454 
1455  notmuch_message_t *msg = NULL;
1456  notmuch_status_t st = notmuch_database_find_message_by_filename(db, path, &msg);
1457  if (st || !msg)
1458  return -1;
1459 
1460  int trans = nm_db_trans_begin(m);
1461  if (trans < 0)
1462  return -1;
1463 
1464  /* note that unlink() is probably unnecessary here, it's already removed
1465  * by mh_sync_mailbox_message(), but for sure... */
1466  notmuch_filenames_t *ls = NULL;
1467  st = notmuch_database_remove_message(db, path);
1468  switch (st)
1469  {
1470  case NOTMUCH_STATUS_SUCCESS:
1471  mutt_debug(LL_DEBUG2, "nm: remove success, call unlink\n");
1472  unlink(path);
1473  break;
1474  case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
1475  mutt_debug(LL_DEBUG2, "nm: remove success (duplicate), call unlink\n");
1476  unlink(path);
1477  for (ls = notmuch_message_get_filenames(msg);
1478  ls && notmuch_filenames_valid(ls); notmuch_filenames_move_to_next(ls))
1479  {
1480  path = notmuch_filenames_get(ls);
1481 
1482  mutt_debug(LL_DEBUG2, "nm: remove duplicate: '%s'\n", path);
1483  unlink(path);
1484  notmuch_database_remove_message(db, path);
1485  }
1486  break;
1487  default:
1488  mutt_debug(LL_DEBUG1, "nm: failed to remove '%s' [st=%d]\n", path, (int) st);
1489  break;
1490  }
1491 
1492  notmuch_message_destroy(msg);
1493  if (trans)
1494  nm_db_trans_end(m);
1495  return 0;
1496 }
int nm_db_trans_begin(struct Mailbox *m)
Start a Notmuch database transaction.
Definition: nm_db.c:200
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:143
int nm_db_trans_end(struct Mailbox *m)
End a database transaction.
Definition: nm_db.c:222
Log at debug level 2.
Definition: logging.h:57
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
Log at debug level 1.
Definition: logging.h:56
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ rename_filename()

static int rename_filename ( struct Mailbox m,
const char *  old_file,
const char *  new_file,
struct Email e 
)
static

Rename the file.

Parameters
mNotmuch Mailbox data
old_fileOld filename
new_fileNew filename
eEmail
Return values
0Success
-1Failure

Definition at line 1507 of file mutt_notmuch.c.

1509 {
1510  struct NmMboxData *mdata = nm_mdata_get(m);
1511  if (!mdata)
1512  return -1;
1513 
1514  notmuch_database_t *db = nm_db_get(m, true);
1515  if (!db || !new_file || !old_file || (access(new_file, F_OK) != 0))
1516  return -1;
1517 
1518  int rc = -1;
1519  notmuch_status_t st;
1520  notmuch_filenames_t *ls = NULL;
1521  notmuch_message_t *msg = NULL;
1522 
1523  mutt_debug(LL_DEBUG1, "nm: rename filename, %s -> %s\n", old_file, new_file);
1524  int trans = nm_db_trans_begin(m);
1525  if (trans < 0)
1526  return -1;
1527 
1528  mutt_debug(LL_DEBUG2, "nm: rename: add '%s'\n", new_file);
1529 #ifdef HAVE_NOTMUCH_DATABASE_INDEX_FILE
1530  st = notmuch_database_index_file(db, new_file, NULL, &msg);
1531 #else
1532  st = notmuch_database_add_message(db, new_file, &msg);
1533 #endif
1534 
1535  if ((st != NOTMUCH_STATUS_SUCCESS) && (st != NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID))
1536  {
1537  mutt_debug(LL_DEBUG1, "nm: failed to add '%s' [st=%d]\n", new_file, (int) st);
1538  goto done;
1539  }
1540 
1541  mutt_debug(LL_DEBUG2, "nm: rename: rem '%s'\n", old_file);
1542  st = notmuch_database_remove_message(db, old_file);
1543  switch (st)
1544  {
1545  case NOTMUCH_STATUS_SUCCESS:
1546  break;
1547  case NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID:
1548  mutt_debug(LL_DEBUG2, "nm: rename: syncing duplicate filename\n");
1549  notmuch_message_destroy(msg);
1550  msg = NULL;
1551  notmuch_database_find_message_by_filename(db, new_file, &msg);
1552 
1553  for (ls = notmuch_message_get_filenames(msg);
1554  msg && ls && notmuch_filenames_valid(ls); notmuch_filenames_move_to_next(ls))
1555  {
1556  const char *path = notmuch_filenames_get(ls);
1557  char newpath[PATH_MAX];
1558 
1559  if (strcmp(new_file, path) == 0)
1560  continue;
1561 
1562  mutt_debug(LL_DEBUG2, "nm: rename: syncing duplicate: %s\n", path);
1563 
1564  if (rename_maildir_filename(path, newpath, sizeof(newpath), e) == 0)
1565  {
1566  mutt_debug(LL_DEBUG2, "nm: rename dup %s -> %s\n", path, newpath);
1567  notmuch_database_remove_message(db, path);
1568 #ifdef HAVE_NOTMUCH_DATABASE_INDEX_FILE
1569  notmuch_database_index_file(db, newpath, NULL, NULL);
1570 #else
1571  notmuch_database_add_message(db, newpath, NULL);
1572 #endif
1573  }
1574  }
1575  notmuch_message_destroy(msg);
1576  msg = NULL;
1577  notmuch_database_find_message_by_filename(db, new_file, &msg);
1578  st = NOTMUCH_STATUS_SUCCESS;
1579  break;
1580  default:
1581  mutt_debug(LL_DEBUG1, "nm: failed to remove '%s' [st=%d]\n", old_file, (int) st);
1582  break;
1583  }
1584 
1585  if ((st == NOTMUCH_STATUS_SUCCESS) && e && msg)
1586  {
1587  notmuch_message_maildir_flags_to_tags(msg);
1588  update_email_tags(e, msg);
1589 
1590  char *tags = driver_tags_get(&e->tags);
1591  update_tags(msg, tags);
1592  FREE(&tags);
1593  }
1594 
1595  rc = 0;
1596 done:
1597  if (msg)
1598  notmuch_message_destroy(msg);
1599  if (trans)
1600  nm_db_trans_end(m);
1601  return rc;
1602 }
int nm_db_trans_begin(struct Mailbox *m)
Start a Notmuch database transaction.
Definition: nm_db.c:200
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:143
int nm_db_trans_end(struct Mailbox *m)
End a database transaction.
Definition: nm_db.c:222
static int update_email_tags(struct Email *e, notmuch_message_t *msg)
Update the Email&#39;s tags from Notmuch.
Definition: mutt_notmuch.c:630
Log at debug level 2.
Definition: logging.h:57
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct TagList tags
For drivers that support server tagging.
Definition: email.h:108
#define PATH_MAX
Definition: mutt.h:52
char * driver_tags_get(struct TagList *list)
Get tags.
Definition: tags.c:141
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
Log at debug level 1.
Definition: logging.h:56
static int update_tags(notmuch_message_t *msg, const char *tags)
Update the tags on a message.
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static int rename_maildir_filename(const char *old, char *buf, size_t buflen, struct Email *e)
Rename a Maildir file.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ count_query()

static unsigned int count_query ( notmuch_database_t *  db,
const char *  qstr,
int  limit 
)
static

Count the results of a query.

Parameters
dbNotmuch database
qstrQuery to execute
limitMaximum number of results
Return values
numNumber of results

Definition at line 1611 of file mutt_notmuch.c.

1612 {
1613  notmuch_query_t *q = notmuch_query_create(db, qstr);
1614  if (!q)
1615  return 0;
1616 
1617  unsigned int res = 0;
1618 
1619  apply_exclude_tags(q);
1620 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
1621  if (notmuch_query_count_messages(q, &res) != NOTMUCH_STATUS_SUCCESS)
1622  res = 0; /* may not be defined on error */
1623 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
1624  if (notmuch_query_count_messages_st(q, &res) != NOTMUCH_STATUS_SUCCESS)
1625  res = 0; /* may not be defined on error */
1626 #else
1627  res = notmuch_query_count_messages(q);
1628 #endif
1629  notmuch_query_destroy(q);
1630  mutt_debug(LL_DEBUG1, "nm: count '%s', result=%d\n", qstr, res);
1631 
1632  if ((limit > 0) && (res > limit))
1633  res = limit;
1634 
1635  return res;
1636 }
static void apply_exclude_tags(notmuch_query_t *query)
Exclude the configured tags.
Definition: mutt_notmuch.c:557
Log at debug level 1.
Definition: logging.h:56
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_email_get_folder()

char* nm_email_get_folder ( struct Email e)

Get the folder for a Email.

Parameters
eEmail
Return values
ptrFolder containing email
NULLError

Definition at line 1644 of file mutt_notmuch.c.

1645 {
1646  return (e && e->edata) ? ((struct NmEmailData *) e->edata)->folder : NULL;
1647 }
Notmuch-specific Email data -.
void * edata
Driver-specific data.
Definition: email.h:112
+ Here is the caller graph for this function:

◆ nm_read_entire_thread()

int nm_read_entire_thread ( struct Mailbox m,
struct Email e 
)

Get the entire thread of an email.

Parameters
mMailbox
eEmail
Return values
0Success
-1Failure

Definition at line 1656 of file mutt_notmuch.c.

1657 {
1658  if (!m)
1659  return -1;
1660 
1661  struct NmMboxData *mdata = nm_mdata_get(m);
1662  if (!mdata)
1663  return -1;
1664 
1665  notmuch_query_t *q = NULL;
1666  notmuch_database_t *db = NULL;
1667  notmuch_message_t *msg = NULL;
1668  int rc = -1;
1669 
1670  if (!(db = nm_db_get(m, false)) || !(msg = get_nm_message(db, e)))
1671  goto done;
1672 
1673  mutt_debug(LL_DEBUG1, "nm: reading entire-thread messages...[current count=%d]\n",
1674  m->msg_count);
1675 
1676  progress_reset(m);
1677  const char *id = notmuch_message_get_thread_id(msg);
1678  if (!id)
1679  goto done;
1680 
1681  char *qstr = NULL;
1682  mutt_str_append_item(&qstr, "thread:", '\0');
1683  mutt_str_append_item(&qstr, id, '\0');
1684 
1685  q = notmuch_query_create(db, qstr);
1686  FREE(&qstr);
1687  if (!q)
1688  goto done;
1689  apply_exclude_tags(q);
1690  notmuch_query_set_sort(q, NOTMUCH_SORT_NEWEST_FIRST);
1691 
1692  read_threads_query(m, q, true, 0);
1693  m->mtime.tv_sec = mutt_date_epoch();
1694  m->mtime.tv_nsec = 0;
1695  rc = 0;
1696 
1697  if (m->msg_count > mdata->oldmsgcount)
1699 done:
1700  if (q)
1701  notmuch_query_destroy(q);
1702 
1703  nm_db_release(m);
1704 
1705  if (m->msg_count == mdata->oldmsgcount)
1706  mutt_message(_("No more messages in the thread"));
1707 
1708  mdata->oldmsgcount = 0;
1709  mutt_debug(LL_DEBUG1, "nm: reading entire-thread messages... done [rc=%d, count=%d]\n",
1710  rc, m->msg_count);
1711  return rc;
1712 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:410
int msg_count
Total number of messages.
Definition: mailbox.h:102
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:143
void mailbox_changed(struct Mailbox *m, enum MailboxNotification action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:160
#define mutt_message(...)
Definition: logging.h:83
static void progress_reset(struct Mailbox *m)
Reset the progress counter.
Definition: mutt_notmuch.c:826
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:118
#define _(a)
Definition: message.h:28
time_t tv_sec
Definition: file.h:47
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
static notmuch_message_t * get_nm_message(notmuch_database_t *db, struct Email *e)
Find a Notmuch message.
static void apply_exclude_tags(notmuch_query_t *query)
Exclude the configured tags.
Definition: mutt_notmuch.c:557
static bool read_threads_query(struct Mailbox *m, notmuch_query_t *q, bool dedup, int limit)
Perform a query with threads.
Email list was changed.
Definition: mailbox.h:64
Log at debug level 1.
Definition: logging.h:56
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
void mutt_str_append_item(char **str, const char *item, char sep)
Add string to another separated by sep.
Definition: string.c:471
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_parse_type_from_query()

void nm_parse_type_from_query ( struct NmMboxData mdata,
char *  buf 
)

Parse a query type out of a query.

Parameters
mdataMailbox, used for the query_type
bufBuffer for URI

If a user writes a query for a vfolder and includes a type= statement, that type= will be encoded, which Notmuch will treat as part of the query= statement. This method will remove the type= and set it within the Mailbox struct.

Definition at line 1724 of file mutt_notmuch.c.

1725 {
1726  // The six variations of how type= could appear.
1727  const char *variants[6] = { "&type=threads", "&type=messages",
1728  "type=threads&", "type=messages&",
1729  "type=threads", "type=messages" };
1730 
1731  int variants_size = mutt_array_size(variants);
1732  for (int i = 0; i < variants_size; i++)
1733  {
1734  if (mutt_str_strcasestr(buf, variants[i]) != NULL)
1735  {
1736  // variants[] is setup such that type can be determined via modulo 2.
1737  mdata->query_type = ((i % 2) == 0) ? NM_QUERY_TYPE_THREADS : NM_QUERY_TYPE_MESGS;
1738 
1739  mutt_str_remall_strcasestr(buf, variants[i]);
1740  }
1741  }
1742 }
int mutt_str_remall_strcasestr(char *str, const char *target)
Remove all occurrences of substring, ignoring case.
Definition: string.c:1095
const char * mutt_str_strcasestr(const char *haystack, const char *needle)
Find a substring within a string without worrying about case.
Definition: string.c:1120
#define mutt_array_size(x)
Definition: memory.h:33
Default: Messages only.
enum NmQueryType query_type
Messages or Threads.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_uri_from_query()

char* nm_uri_from_query ( struct Mailbox m,
char *  buf,
size_t  buflen 
)

Turn a query into a URI.

Parameters
mMailbox
bufBuffer for URI
buflenLength of buffer
Return values
ptrQuery as a URI
NULLError

Definition at line 1752 of file mutt_notmuch.c.

1753 {
1754  mutt_debug(LL_DEBUG2, "(%s)\n", buf);
1755  struct NmMboxData *mdata = nm_mdata_get(m);
1756  char uri[PATH_MAX + 1024 + 32]; /* path to DB + query + URI "decoration" */
1757  int added;
1758  bool using_default_data = false;
1759 
1760  // No existing data. Try to get a default NmMboxData.
1761  if (!mdata)
1762  {
1763  mdata = nm_get_default_data();
1764 
1765  // Failed to get default data.
1766  if (!mdata)
1767  return NULL;
1768 
1769  using_default_data = true;
1770  }
1771 
1772  nm_parse_type_from_query(mdata, buf);
1773 
1774  if (get_limit(mdata) != C_NmDbLimit)
1775  {
1776  added = snprintf(uri, sizeof(uri), "%s%s?type=%s&limit=%d&query=", NmUriProtocol,
1777  nm_db_get_filename(m),
1778  query_type_to_string(mdata->query_type), get_limit(mdata));
1779  }
1780  else
1781  {
1782  added = snprintf(uri, sizeof(uri), "%s%s?type=%s&query=", NmUriProtocol,
1784  }
1785 
1786  if (added >= sizeof(uri))
1787  {
1788  // snprintf output was truncated, so can't create URI
1789  return NULL;
1790  }
1791 
1792  url_pct_encode(&uri[added], sizeof(uri) - added, buf);
1793 
1794  mutt_str_strfcpy(buf, uri, buflen);
1795  buf[buflen - 1] = '\0';
1796 
1797  if (using_default_data)
1798  nm_mdata_free((void **) &mdata);
1799 
1800  mutt_debug(LL_DEBUG1, "nm: uri from query '%s'\n", buf);
1801  return buf;
1802 }
int C_NmDbLimit
Config: (notmuch) Default limit for Notmuch queries.
Definition: mutt_notmuch.c:74
struct NmMboxData * nm_get_default_data(void)
Create a Mailbox with default Notmuch settings.
Definition: mutt_notmuch.c:273
Log at debug level 2.
Definition: logging.h:57
Notmuch-specific Mailbox data -.
const char NmUriProtocol[]
Definition: mutt_notmuch.c:70
void * mdata
Driver specific data.
Definition: mailbox.h:147
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: mutt_notmuch.c:548
void nm_mdata_free(void **ptr)
Free data attached to the Mailbox.
Definition: mutt_notmuch.c:183
void url_pct_encode(char *buf, size_t buflen, const char *src)
Percent-encode a string.
Definition: url.c:315
#define PATH_MAX
Definition: mutt.h:52
const char * nm_db_get_filename(struct Mailbox *m)
Get the filename of the Notmuch database.
Definition: nm_db.c:52
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
void nm_parse_type_from_query(struct NmMboxData *mdata, char *buf)
Parse a query type out of a query.
Log at debug level 1.
Definition: logging.h:56
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
static const char * query_type_to_string(enum NmQueryType query_type)
Turn a query type into a string.
Definition: mutt_notmuch.c:347
enum NmQueryType query_type
Messages or Threads.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_query_window_forward()

void nm_query_window_forward ( void  )

Function to move the current search window forward in time.

Updates nm_query_window_current_position by decrementing it by 1, or does nothing if the current window already is set to 0.

The lower the value of nm_query_window_current_position is, the more recent the result will be.

Definition at line 1813 of file mutt_notmuch.c.

1814 {
1817 
1819 }
Log at debug level 2.
Definition: logging.h:57
int C_NmQueryWindowCurrentPosition
Config: (notmuch) Position of current search window.
Definition: mutt_notmuch.c:79
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the caller graph for this function:

◆ nm_query_window_backward()

void nm_query_window_backward ( void  )

Function to move the current search window backward in time.

Updates nm_query_window_current_position by incrementing it by 1

The higher the value of nm_query_window_current_position is, the less recent the result will be.

Definition at line 1829 of file mutt_notmuch.c.

1830 {
1833 }
Log at debug level 2.
Definition: logging.h:57
int C_NmQueryWindowCurrentPosition
Config: (notmuch) Position of current search window.
Definition: mutt_notmuch.c:79
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the caller graph for this function:

◆ nm_message_is_still_queried()

bool nm_message_is_still_queried ( struct Mailbox m,
struct Email e 
)

Is a message still visible in the query?

Parameters
mMailbox
eEmail
Return values
trueMessage is still in query

Definition at line 1841 of file mutt_notmuch.c.

1842 {
1843  struct NmMboxData *mdata = nm_mdata_get(m);
1844  notmuch_database_t *db = nm_db_get(m, false);
1845  char *orig_str = get_query_string(mdata, true);
1846 
1847  if (!db || !orig_str)
1848  return false;
1849 
1850  char *new_str = NULL;
1851  bool rc = false;
1852  if (mutt_str_asprintf(&new_str, "id:%s and (%s)", email_get_id(e), orig_str) < 0)
1853  return false;
1854 
1855  mutt_debug(LL_DEBUG2, "nm: checking if message is still queried: %s\n", new_str);
1856 
1857  notmuch_query_t *q = notmuch_query_create(db, new_str);
1858 
1859  switch (mdata->query_type)
1860  {
1861  case NM_QUERY_TYPE_MESGS:
1862  {
1863  notmuch_messages_t *messages = get_messages(q);
1864 
1865  if (!messages)
1866  return false;
1867 
1868  rc = notmuch_messages_valid(messages);
1869  notmuch_messages_destroy(messages);
1870  break;
1871  }
1872  case NM_QUERY_TYPE_THREADS:
1873  {
1874  notmuch_threads_t *threads = get_threads(q);
1875 
1876  if (!threads)
1877  return false;
1878 
1879  rc = notmuch_threads_valid(threads);
1880  notmuch_threads_destroy(threads);
1881  break;
1882  }
1883  }
1884 
1885  notmuch_query_destroy(q);
1886 
1887  mutt_debug(LL_DEBUG2, "nm: checking if message is still queried: %s = %s\n",
1888  new_str, rc ? "true" : "false");
1889 
1890  return rc;
1891 }
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:143
static notmuch_messages_t * get_messages(notmuch_query_t *query)
load messages for a query
static char * email_get_id(struct Email *e)
Get the unique Notmuch Id.
Definition: mutt_notmuch.c:322
Log at debug level 2.
Definition: logging.h:57
Notmuch-specific Mailbox data -.
Default: Messages only.
void * mdata
Driver specific data.
Definition: mailbox.h:147
static char * get_query_string(struct NmMboxData *mdata, bool window)
builds the notmuch vfolder search string
Definition: mutt_notmuch.c:489
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
static notmuch_threads_t * get_threads(notmuch_query_t *query)
load threads for a query
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1195
enum NmQueryType query_type
Messages or Threads.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_update_filename()

int nm_update_filename ( struct Mailbox m,
const char *  old_file,
const char *  new_file,
struct Email e 
)

Change the filename.

Parameters
mMailbox
old_fileOld filename
new_fileNew filename
eEmail
Return values
0Success
-1Failure

Definition at line 1902 of file mutt_notmuch.c.

1904 {
1905  char buf[PATH_MAX];
1906  struct NmMboxData *mdata = nm_mdata_get(m);
1907  if (!mdata || !new_file)
1908  return -1;
1909 
1910  if (!old_file && e && e->edata)
1911  {
1912  email_get_fullpath(e, buf, sizeof(buf));
1913  old_file = buf;
1914  }
1915 
1916  int rc = rename_filename(m, old_file, new_file, e);
1917 
1918  nm_db_release(m);
1919  m->mtime.tv_sec = mutt_date_epoch();
1920  m->mtime.tv_nsec = 0;
1921  return rc;
1922 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:410
static int rename_filename(struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
Rename the file.
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:118
static char * email_get_fullpath(struct Email *e, char *buf, size_t buflen)
Get the full path of an email.
Definition: mutt_notmuch.c:334
time_t tv_sec
Definition: file.h:47
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:147
#define PATH_MAX
Definition: mutt.h:52
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
void * edata
Driver-specific data.
Definition: email.h:112
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_mbox_check_stats()

static int nm_mbox_check_stats ( struct Mailbox m,
int  flags 
)
static

Check the Mailbox statistics - Implements MxOps::check_stats()

Definition at line 1927 of file mutt_notmuch.c.

1928 {
1929  struct UrlQuery *item = NULL;
1930  struct Url *url = NULL;
1931  char *db_filename = NULL, *db_query = NULL;
1932  notmuch_database_t *db = NULL;
1933  int rc = -1;
1934  int limit = C_NmDbLimit;
1935  mutt_debug(LL_DEBUG1, "nm: count\n");
1936 
1937  url = url_parse(mailbox_path(m));
1938  if (!url)
1939  {
1940  mutt_error(_("failed to parse notmuch uri: %s"), mailbox_path(m));
1941  goto done;
1942  }
1943 
1944  STAILQ_FOREACH(item, &url->query_strings, entries)
1945  {
1946  if (item->value && (strcmp(item->name, "query") == 0))
1947  db_query = item->value;
1948  else if (item->value && (strcmp(item->name, "limit") == 0))
1949  {
1950  // Try to parse the limit
1951  if (mutt_str_atoi(item->value, &limit) != 0)
1952  {
1953  mutt_error(_("failed to parse limit: %s"), item->value);
1954  goto done;
1955  }
1956  }
1957  }
1958 
1959  if (!db_query)
1960  goto done;
1961 
1962  db_filename = url->path;
1963  if (!db_filename)
1964  {
1965  if (C_NmDefaultUri)
1966  {
1968  db_filename = C_NmDefaultUri + NmUriProtocolLen;
1969  else
1970  db_filename = C_NmDefaultUri;
1971  }
1972  else if (C_Folder)
1973  db_filename = C_Folder;
1974  }
1975 
1976  /* don't be verbose about connection, as we're called from
1977  * sidebar/mailbox very often */
1978  db = nm_db_do_open(db_filename, false, false);
1979  if (!db)
1980  goto done;
1981 
1982  /* all emails */
1983  m->msg_count = count_query(db, db_query, limit);
1984 
1985  // holder variable for extending query to unread/flagged
1986  char *qstr = NULL;
1987 
1988  // unread messages
1989  mutt_str_asprintf(&qstr, "( %s ) tag:%s", db_query, C_NmUnreadTag);
1990  m->msg_unread = count_query(db, qstr, limit);
1991  FREE(&qstr);
1992 
1993  // flagged messages
1994  mutt_str_asprintf(&qstr, "( %s ) tag:%s", db_query, C_NmFlaggedTag);
1995  m->msg_flagged = count_query(db, qstr, limit);
1996  FREE(&qstr);
1997 
1998  rc = 0;
1999 done:
2000  if (db)
2001  {
2002  nm_db_free(db);
2003  mutt_debug(LL_DEBUG1, "nm: count close DB\n");
2004  }
2005  url_free(&url);
2006 
2007  mutt_debug(LL_DEBUG1, "nm: count done [rc=%d]\n", rc);
2008  return rc;
2009 }
char * name
Query name.
Definition: url.h:57
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
int msg_count
Total number of messages.
Definition: mailbox.h:102
int mutt_str_atoi(const char *str, int *dst)
Convert ASCII string to an integer.
Definition: string.c:262
int C_NmDbLimit
Config: (notmuch) Default limit for Notmuch queries.
Definition: mutt_notmuch.c:74
notmuch_database_t * nm_db_do_open(const char *filename, bool writable, bool verbose)
Open a Notmuch database.
Definition: nm_db.c:79
enum MailboxType nm_path_probe(const char *path, const struct stat *st)
Is this a Notmuch Mailbox? - Implements MxOps::path_probe()
int msg_unread
Number of unread messages.
Definition: mailbox.h:103
void nm_db_free(notmuch_database_t *db)
decoupled way to close a Notmuch database
Definition: nm_db.c:184
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:104
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
static unsigned int count_query(notmuch_database_t *db, const char *qstr, int limit)
Count the results of a query.
Parsed Query String.
Definition: url.h:55
#define _(a)
Definition: message.h:28
char * value
Query value.
Definition: url.h:58
char * C_NmUnreadTag
Config: (notmuch) Tag to use for unread messages.
Definition: mutt_notmuch.c:82
const int NmUriProtocolLen
Definition: mutt_notmuch.c:71
struct UrlQueryList query_strings
List of query strings.
Definition: url.h:74
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:124
char * C_NmDefaultUri
Config: (notmuch) Path to the Notmuch database.
Definition: mutt_notmuch.c:75
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:350
char * path
Path.
Definition: url.h:73
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
char * C_NmFlaggedTag
Config: (notmuch) Tag to use for flagged messages.
Definition: mutt_notmuch.c:83
Log at debug level 1.
Definition: logging.h:56
#define mutt_error(...)
Definition: logging.h:84
void url_free(struct Url **u)
Free the contents of a URL.
Definition: url.c:288
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1195
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:161
+ Here is the call graph for this function:

◆ nm_record_message()

int nm_record_message ( struct Mailbox m,
char *  path,
struct Email e 
)

Add a message to the Notmuch database.

Parameters
mMailbox
pathPath of the email
eEmail
Return values
0Success
-1Failure

Definition at line 2019 of file mutt_notmuch.c.

2020 {
2021  notmuch_database_t *db = NULL;
2022  notmuch_status_t st;
2023  notmuch_message_t *msg = NULL;
2024  int rc = -1;
2025  struct NmMboxData *mdata = nm_mdata_get(m);
2026 
2027  if (!path || !mdata || (access(path, F_OK) != 0))
2028  return 0;
2029  db = nm_db_get(m, true);
2030  if (!db)
2031  return -1;
2032 
2033  mutt_debug(LL_DEBUG1, "nm: record message: %s\n", path);
2034  int trans = nm_db_trans_begin(m);
2035  if (trans < 0)
2036  goto done;
2037 
2038 #ifdef HAVE_NOTMUCH_DATABASE_INDEX_FILE
2039  st = notmuch_database_index_file(db, path, NULL, &msg);
2040 #else
2041  st = notmuch_database_add_message(db, path, &msg);
2042 #endif
2043 
2044  if ((st != NOTMUCH_STATUS_SUCCESS) && (st != NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID))
2045  {
2046  mutt_debug(LL_DEBUG1, "nm: failed to add '%s' [st=%d]\n", path, (int) st);
2047  goto done;
2048  }
2049 
2050  if ((st == NOTMUCH_STATUS_SUCCESS) && msg)
2051  {
2052  notmuch_message_maildir_flags_to_tags(msg);
2053  if (e)
2054  {
2055  char *tags = driver_tags_get(&e->tags);
2056  update_tags(msg, tags);
2057  FREE(&tags);
2058  }
2059  if (C_NmRecordTags)
2061  }
2062 
2063  rc = 0;
2064 done:
2065  if (msg)
2066  notmuch_message_destroy(msg);
2067  if (trans == 1)
2068  nm_db_trans_end(m);
2069 
2070  nm_db_release(m);
2071  return rc;
2072 }
int nm_db_trans_begin(struct Mailbox *m)
Start a Notmuch database transaction.
Definition: nm_db.c:200
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:143
int nm_db_trans_end(struct Mailbox *m)
End a database transaction.
Definition: nm_db.c:222
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct TagList tags
For drivers that support server tagging.
Definition: email.h:108
char * driver_tags_get(struct TagList *list)
Get tags.
Definition: tags.c:141
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
Log at debug level 1.
Definition: logging.h:56
static int update_tags(notmuch_message_t *msg, const char *tags)
Update the tags on a message.
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
char * C_NmRecordTags
Config: (notmuch) Tags to apply to the &#39;record&#39; mailbox (sent mail)
Definition: mutt_notmuch.c:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_get_all_tags()

int nm_get_all_tags ( struct Mailbox m,
char **  tag_list,
int *  tag_count 
)

Fill a list with all notmuch tags.

Parameters
[in]mMailbox
[out]tag_listList of tags
[out]tag_countNumber of tags
Return values
0Success
-1Failure

If tag_list is NULL, just count the tags.

Definition at line 2084 of file mutt_notmuch.c.

2085 {
2086  struct NmMboxData *mdata = nm_mdata_get(m);
2087  if (!mdata)
2088  return -1;
2089 
2090  notmuch_database_t *db = NULL;
2091  notmuch_tags_t *tags = NULL;
2092  const char *tag = NULL;
2093  int rc = -1;
2094 
2095  if (!(db = nm_db_get(m, false)) || !(tags = notmuch_database_get_all_tags(db)))
2096  goto done;
2097 
2098  *tag_count = 0;
2099  mutt_debug(LL_DEBUG1, "nm: get all tags\n");
2100 
2101  while (notmuch_tags_valid(tags))
2102  {
2103  tag = notmuch_tags_get(tags);
2104  /* Skip empty string */
2105  if (*tag)
2106  {
2107  if (tag_list)
2108  tag_list[*tag_count] = mutt_str_strdup(tag);
2109  (*tag_count)++;
2110  }
2111  notmuch_tags_move_to_next(tags);
2112  }
2113 
2114  rc = 0;
2115 done:
2116  if (tags)
2117  notmuch_tags_destroy(tags);
2118 
2119  nm_db_release(m);
2120 
2121  mutt_debug(LL_DEBUG1, "nm: get all tags done [rc=%d tag_count=%u]\n", rc, *tag_count);
2122  return rc;
2123 }
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:143
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
Log at debug level 1.
Definition: logging.h:56
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_ac_find()

struct Account* nm_ac_find ( struct Account a,
const char *  path 
)

Find an Account that matches a Mailbox path - Implements MxOps::ac_find()

Definition at line 2128 of file mutt_notmuch.c.

2129 {
2130  if (!a || (a->magic != MUTT_NOTMUCH) || !path)
2131  return NULL;
2132 
2133  return a;
2134 }
enum MailboxType magic
Type of Mailboxes this Account contains.
Definition: account.h:38
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53

◆ nm_ac_add()

int nm_ac_add ( struct Account a,
struct Mailbox m 
)

Add a Mailbox to an Account - Implements MxOps::ac_add()

Definition at line 2139 of file mutt_notmuch.c.

2140 {
2141  if (!a || !m || (m->magic != MUTT_NOTMUCH))
2142  return -1;
2143 
2144  if (a->adata)
2145  return 0;
2146 
2147  struct NmAccountData *adata = nm_adata_new();
2148  a->adata = adata;
2150 
2151  return 0;
2152 }
void nm_adata_free(void **ptr)
Release and clear storage in an NmAccountData structure.
Definition: mutt_notmuch.c:131
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
struct NmAccountData * nm_adata_new(void)
Allocate and initialise a new NmAccountData structure.
Definition: mutt_notmuch.c:150
void(* free_adata)(void **)
Callback function to free private data.
Definition: account.h:44
Notmuch-specific Account data -.
+ Here is the call graph for this function:

◆ nm_mbox_open()

static int nm_mbox_open ( struct Mailbox m)
static

Open a Mailbox - Implements MxOps::mbox_open()

Definition at line 2157 of file mutt_notmuch.c.

2158 {
2159  if (init_mailbox(m) != 0)
2160  return -1;
2161 
2162  struct NmMboxData *mdata = nm_mdata_get(m);
2163  if (!mdata)
2164  return -1;
2165 
2166  mutt_debug(LL_DEBUG1, "nm: reading messages...[current count=%d]\n", m->msg_count);
2167 
2168  progress_reset(m);
2169 
2170  if (!m->emails)
2171  {
2172  /* Allocate some memory to get started */
2173  m->email_max = m->msg_count;
2174  m->msg_count = 0;
2175  m->vcount = 0;
2176  m->size = 0;
2177  mx_alloc_memory(m);
2178  }
2179 
2180  int rc = -1;
2181 
2182  notmuch_query_t *q = get_query(m, false);
2183  if (q)
2184  {
2185  rc = 0;
2186  switch (mdata->query_type)
2187  {
2188  case NM_QUERY_TYPE_MESGS:
2189  if (!read_mesgs_query(m, q, false))
2190  rc = -2;
2191  break;
2192  case NM_QUERY_TYPE_THREADS:
2193  if (!read_threads_query(m, q, false, get_limit(mdata)))
2194  rc = -2;
2195  break;
2196  }
2197  notmuch_query_destroy(q);
2198  }
2199 
2200  nm_db_release(m);
2201 
2202  m->mtime.tv_sec = mutt_date_epoch();
2203  m->mtime.tv_nsec = 0;
2204 
2205  mdata->oldmsgcount = 0;
2206 
2207  mutt_debug(LL_DEBUG1, "nm: reading messages... done [rc=%d, count=%d]\n", rc, m->msg_count);
2208  return rc;
2209 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:410
int msg_count
Total number of messages.
Definition: mailbox.h:102
off_t size
Size of the Mailbox.
Definition: mailbox.h:98
static notmuch_query_t * get_query(struct Mailbox *m, bool writable)
Create a new query.
Definition: mutt_notmuch.c:598
static void progress_reset(struct Mailbox *m)
Reset the progress counter.
Definition: mutt_notmuch.c:826
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:118
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1113
static bool read_mesgs_query(struct Mailbox *m, notmuch_query_t *q, bool dedup)
Search for matching messages.
int vcount
The number of virtual messages.
Definition: mailbox.h:113
time_t tv_sec
Definition: file.h:47
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
Default: Messages only.
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:147
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: mutt_notmuch.c:548
int email_max
Number of pointers in emails.
Definition: mailbox.h:111
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
static bool read_threads_query(struct Mailbox *m, notmuch_query_t *q, bool dedup, int limit)
Perform a query with threads.
static int init_mailbox(struct Mailbox *m)
Add Notmuch data to the Mailbox.
Definition: mutt_notmuch.c:300
Log at debug level 1.
Definition: logging.h:56
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
enum NmQueryType query_type
Messages or Threads.
+ Here is the call graph for this function:

◆ nm_mbox_check()

static int nm_mbox_check ( struct Mailbox m,
int *  index_hint 
)
static

Check for new mail - Implements MxOps::mbox_check()

Parameters
mMailbox
index_hintRemember our place in the index
Return values
-1Error
0Success
MUTT_NEW_MAILNew mail has arrived
MUTT_REOPENEDMailbox closed and reopened
MUTT_FLAGSFlags have changed

Definition at line 2221 of file mutt_notmuch.c.

2222 {
2223  if (!m)
2224  return -1;
2225 
2226  struct NmMboxData *mdata = nm_mdata_get(m);
2227  time_t mtime = 0;
2228  if (!mdata || (nm_db_get_mtime(m, &mtime) != 0))
2229  return -1;
2230 
2231  int new_flags = 0;
2232  bool occult = false;
2233 
2234  if (m->mtime.tv_sec >= mtime)
2235  {
2236  mutt_debug(LL_DEBUG2, "nm: check unnecessary (db=%lu mailbox=%lu)\n", mtime,
2237  m->mtime.tv_sec);
2238  return 0;
2239  }
2240 
2241  mutt_debug(LL_DEBUG1, "nm: checking (db=%lu mailbox=%lu)\n", mtime, m->mtime.tv_sec);
2242 
2243  notmuch_query_t *q = get_query(m, false);
2244  if (!q)
2245  goto done;
2246 
2247  mutt_debug(LL_DEBUG1, "nm: start checking (count=%d)\n", m->msg_count);
2248  mdata->oldmsgcount = m->msg_count;
2249  mdata->noprogress = true;
2250 
2251  for (int i = 0; i < m->msg_count; i++)
2252  m->emails[i]->active = false;
2253 
2254  int limit = get_limit(mdata);
2255 
2256  notmuch_messages_t *msgs = get_messages(q);
2257 
2258  // TODO: Analyze impact of removing this version guard.
2259 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
2260  if (!msgs)
2261  return false;
2262 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
2263  if (!msgs)
2264  goto done;
2265 #endif
2266 
2268 
2269  for (int i = 0; notmuch_messages_valid(msgs) && ((limit == 0) || (i < limit));
2270  notmuch_messages_move_to_next(msgs), i++)
2271  {
2272  notmuch_message_t *msg = notmuch_messages_get(msgs);
2273  struct Email *e = get_mutt_email(m, msg);
2274 
2275  if (!e)
2276  {
2277  /* new email */
2278  append_message(h, m, NULL, msg, false);
2279  notmuch_message_destroy(msg);
2280  continue;
2281  }
2282 
2283  /* message already exists, merge flags */
2284  e->active = true;
2285 
2286  /* Check to see if the message has moved to a different subdirectory.
2287  * If so, update the associated filename. */
2288  const char *new_file = get_message_last_filename(msg);
2289  char old_file[PATH_MAX];
2290  email_get_fullpath(e, old_file, sizeof(old_file));
2291 
2292  if (mutt_str_strcmp(old_file, new_file) != 0)
2293  update_message_path(e, new_file);
2294 
2295  if (!e->changed)
2296  {
2297  /* if the user hasn't modified the flags on this message, update the
2298  * flags we just detected. */
2299  struct Email e_tmp = { 0 };
2300  maildir_parse_flags(&e_tmp, new_file);
2301  maildir_update_flags(m, e, &e_tmp);
2302  }
2303 
2304  if (update_email_tags(e, msg) == 0)
2305  new_flags++;
2306 
2307  notmuch_message_destroy(msg);
2308  }
2309 
2310  nm_hcache_close(h);
2311 
2312  for (int i = 0; i < m->msg_count; i++)
2313  {
2314  if (!m->emails[i]->active)
2315  {
2316  occult = true;
2317  break;
2318  }
2319  }
2320 
2321  if (m->msg_count > mdata->oldmsgcount)
2323 done:
2324  if (q)
2325  notmuch_query_destroy(q);
2326 
2327  nm_db_release(m);
2328 
2329  m->mtime.tv_sec = mutt_date_epoch();
2330  m->mtime.tv_nsec = 0;
2331 
2332  mutt_debug(LL_DEBUG1, "nm: ... check done [count=%d, new_flags=%d, occult=%d]\n",
2333  m->msg_count, new_flags, occult);
2334 
2335  return occult ? MUTT_REOPENED :
2336  (m->msg_count > mdata->oldmsgcount) ? MUTT_NEW_MAIL :
2337  new_flags ? MUTT_FLAGS : 0;
2338 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:410
int msg_count
Total number of messages.
Definition: mailbox.h:102
static notmuch_query_t * get_query(struct Mailbox *m, bool writable)
Create a new query.
Definition: mutt_notmuch.c:598
The envelope/body of an email.
Definition: email.h:39
bool maildir_update_flags(struct Mailbox *m, struct Email *e_old, struct Email *e_new)
Update the mailbox flags.
Definition: shared.c:1441
static void append_message(header_cache_t *h, struct Mailbox *m, notmuch_query_t *q, notmuch_message_t *msg, bool dedup)
Associate a message.
Definition: mutt_notmuch.c:910
void mailbox_changed(struct Mailbox *m, enum MailboxNotification action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:160
static const char * get_message_last_filename(notmuch_message_t *msg)
Get a message&#39;s last filename.
Definition: mutt_notmuch.c:809
int nm_db_get_mtime(struct Mailbox *m, time_t *mtime)
Get the database modification time.
Definition: nm_db.c:249
static int update_email_tags(struct Email *e, notmuch_message_t *msg)
Update the Email&#39;s tags from Notmuch.
Definition: mutt_notmuch.c:630
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:118
bool changed
Email has been edited.
Definition: email.h:50
static notmuch_messages_t * get_messages(notmuch_query_t *query)
load messages for a query
static char * email_get_fullpath(struct Email *e, char *buf, size_t buflen)
Get the full path of an email.
Definition: mutt_notmuch.c:334
time_t tv_sec
Definition: file.h:47
void maildir_parse_flags(struct Email *e, const char *path)
Parse Maildir file flags.
Definition: shared.c:1224
Log at debug level 2.
Definition: logging.h:57
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:147
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: mutt_notmuch.c:548
bool active
Message is not to be removed.
Definition: email.h:61
#define PATH_MAX
Definition: mutt.h:52
Nondestructive flags change (IMAP)
Definition: mx.h:75
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
static int update_message_path(struct Email *e, const char *path)
Set the path for a message.
Definition: mutt_notmuch.c:680
Email list was changed.
Definition: mailbox.h:64
Log at debug level 1.
Definition: logging.h:56
static struct Email * get_mutt_email(struct Mailbox *m, notmuch_message_t *msg)
Get the Email of a Notmuch message.
Definition: mutt_notmuch.c:875
static header_cache_t * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: mutt_notmuch.c:91
bool noprogress
Don&#39;t show the progress bar.
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
New mail received in Mailbox.
Definition: mx.h:72
header cache structure
Definition: hcache.h:67
Mailbox was reopened.
Definition: mx.h:74
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
void nm_hcache_close(header_cache_t *h)
Close the header cache.
Definition: mutt_notmuch.c:104
+ Here is the call graph for this function:

◆ nm_mbox_sync()

static int nm_mbox_sync ( struct Mailbox m,
int *  index_hint 
)
static

Save changes to the Mailbox - Implements MxOps::mbox_sync()

Definition at line 2343 of file mutt_notmuch.c.

2344 {
2345  if (!m)
2346  return -1;
2347 
2348  struct NmMboxData *mdata = nm_mdata_get(m);
2349  if (!mdata)
2350  return -1;
2351 
2352  int rc = 0;
2353  struct Progress progress;
2354  char *uri = mutt_str_strdup(mailbox_path(m));
2355  bool changed = false;
2356 
2357  mutt_debug(LL_DEBUG1, "nm: sync start\n");
2358 
2359  if (!m->quiet)
2360  {
2361  /* all is in this function so we don't use data->progress here */
2362  char msg[PATH_MAX];
2363  snprintf(msg, sizeof(msg), _("Writing %s..."), mailbox_path(m));
2364  mutt_progress_init(&progress, msg, MUTT_PROGRESS_WRITE, m->msg_count);
2365  }
2366 
2368 
2369  for (int i = 0; i < m->msg_count; i++)
2370  {
2371  char old_file[PATH_MAX], new_file[PATH_MAX];
2372  struct Email *e = m->emails[i];
2373  struct NmEmailData *edata = e->edata;
2374 
2375  if (!m->quiet)
2376  mutt_progress_update(&progress, i, -1);
2377 
2378  *old_file = '\0';
2379  *new_file = '\0';
2380 
2381  if (edata->oldpath)
2382  {
2383  mutt_str_strfcpy(old_file, edata->oldpath, sizeof(old_file));
2384  old_file[sizeof(old_file) - 1] = '\0';
2385  mutt_debug(LL_DEBUG2, "nm: fixing obsolete path '%s'\n", old_file);
2386  }
2387  else
2388  email_get_fullpath(e, old_file, sizeof(old_file));
2389 
2390  mutt_buffer_strcpy(&m->pathbuf, edata->folder);
2391  m->magic = edata->magic;
2392  rc = mh_sync_mailbox_message(m, i, h);
2393  mutt_buffer_strcpy(&m->pathbuf, uri);
2394  m->magic = MUTT_NOTMUCH;
2395 
2396  if (rc)
2397  break;
2398 
2399  if (!e->deleted)
2400  email_get_fullpath(e, new_file, sizeof(new_file));
2401 
2402  if (e->deleted || (strcmp(old_file, new_file) != 0))
2403  {
2404  if (e->deleted && (remove_filename(m, old_file) == 0))
2405  changed = true;
2406  else if (*new_file && *old_file && (rename_filename(m, old_file, new_file, e) == 0))
2407  changed = true;
2408  }
2409 
2410  FREE(&edata->oldpath);
2411  }
2412 
2413  mutt_buffer_strcpy(&m->pathbuf, uri);
2414  m->magic = MUTT_NOTMUCH;
2415 
2416  nm_db_release(m);
2417 
2418  if (changed)
2419  {
2420  m->mtime.tv_sec = mutt_date_epoch();
2421  m->mtime.tv_nsec = 0;
2422  }
2423 
2424  nm_hcache_close(h);
2425 
2426  FREE(&uri);
2427  mutt_debug(LL_DEBUG1, "nm: .... sync done [rc=%d]\n", rc);
2428  return rc;
2429 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:410
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:194
int msg_count
Total number of messages.
Definition: mailbox.h:102
The envelope/body of an email.
Definition: email.h:39
static int rename_filename(struct Mailbox *m, const char *old_file, const char *new_file, struct Email *e)
Rename the file.
Progress tracks elements, according to C_WriteInc.
Definition: progress.h:41
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:118
#define _(a)
Definition: message.h:28
static char * email_get_fullpath(struct Email *e, char *buf, size_t buflen)
Get the full path of an email.
Definition: mutt_notmuch.c:334
A progress bar.
Definition: progress.h:48
time_t tv_sec
Definition: file.h:47
void mutt_progress_update(struct Progress *progress, size_t pos, int percent)
Update the state of the progress bar.
Definition: progress.c:212
Log at debug level 2.
Definition: logging.h:57
Notmuch-specific Mailbox data -.
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
char * folder
Location of the Email.
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:147
void mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:310
#define PATH_MAX
Definition: mutt.h:52
Notmuch-specific Email data -.
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:750
char msg[1024]
Definition: progress.h:50
bool quiet
Inhibit status messages?
Definition: mailbox.h:129
static int remove_filename(struct Mailbox *m, const char *path)
Delete a file.
void mutt_progress_init(struct Progress *progress, const char *msg, enum ProgressType type, size_t size)
Set up a progress bar.
Definition: progress.c:153
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
Log at debug level 1.
Definition: logging.h:56
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
bool deleted
Email is deleted.
Definition: email.h:47
void * edata
Driver-specific data.
Definition: email.h:112
static header_cache_t * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: mutt_notmuch.c:91
#define FREE(x)
Definition: memory.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
header cache structure
Definition: hcache.h:67
struct Buffer pathbuf
Definition: mailbox.h:94
int mh_sync_mailbox_message(struct Mailbox *m, int msgno, header_cache_t *hc)
Save changes to the mailbox.
Definition: shared.c:1350
void nm_hcache_close(header_cache_t *h)
Close the header cache.
Definition: mutt_notmuch.c:104
enum MailboxType magic
Type of Mailbox the Email is in.
+ Here is the call graph for this function:

◆ nm_mbox_close()

static int nm_mbox_close ( struct Mailbox m)
static

Close a Mailbox - Implements MxOps::mbox_close()

Nothing to do.

Definition at line 2436 of file mutt_notmuch.c.

2437 {
2438  return 0;
2439 }

◆ nm_msg_open()

static int nm_msg_open ( struct Mailbox m,
struct Message msg,
int  msgno 
)
static

Open an email message in a Mailbox - Implements MxOps::msg_open()

Definition at line 2444 of file mutt_notmuch.c.

2445 {
2446  if (!m || !m->emails || !msg)
2447  return -1;
2448 
2449  struct Email *e = m->emails[msgno];
2450  char path[PATH_MAX];
2451  char *folder = nm_email_get_folder(e);
2452 
2453  snprintf(path, sizeof(path), "%s/%s", folder, e->path);
2454 
2455  msg->fp = fopen(path, "r");
2456  if (!msg->fp && (errno == ENOENT) &&
2457  ((m->magic == MUTT_MAILDIR) || (m->magic == MUTT_NOTMUCH)))
2458  {
2459  msg->fp = maildir_open_find_message(folder, e->path, NULL);
2460  }
2461 
2462  if (!msg->fp)
2463  return -1;
2464 
2465  return 0;
2466 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:110
The envelope/body of an email.
Definition: email.h:39
char * nm_email_get_folder(struct Email *e)
Get the folder for a Email.
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:116
FILE * maildir_open_find_message(const char *folder, const char *msg, char **newname)
Find a new.
Definition: shared.c:1487
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:50
#define PATH_MAX
Definition: mutt.h:52
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
char * path
Path of Email (for local Mailboxes)
Definition: email.h:93
FILE * fp
pointer to the message data
Definition: mx.h:83
int msgno
Number displayed to the user.
Definition: email.h:88
+ Here is the call graph for this function:

◆ nm_msg_commit()

static int nm_msg_commit ( struct Mailbox m,
struct Message msg 
)
static

Save changes to an email - Implements MxOps::msg_commit()

Return values
-1Always

Definition at line 2472 of file mutt_notmuch.c.

2473 {
2474  mutt_error(_("Can't write to virtual folder"));
2475  return -1;
2476 }
#define _(a)
Definition: message.h:28
#define mutt_error(...)
Definition: logging.h:84

◆ nm_msg_close()

static int nm_msg_close ( struct Mailbox m,
struct Message msg 
)
static

Close an email - Implements MxOps::msg_close()

Definition at line 2481 of file mutt_notmuch.c.

2482 {
2483  if (!msg)
2484  return -1;
2485  mutt_file_fclose(&(msg->fp));
2486  return 0;
2487 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:150
FILE * fp
pointer to the message data
Definition: mx.h:83
+ Here is the call graph for this function:

◆ nm_tags_edit()

static int nm_tags_edit ( struct Mailbox m,
const char *  tags,
char *  buf,
size_t  buflen 
)
static

Prompt and validate new messages tags - Implements MxOps::tags_edit()

Definition at line 2492 of file mutt_notmuch.c.

2493 {
2494  *buf = '\0';
2495  if (mutt_get_field("Add/remove labels: ", buf, buflen, MUTT_NM_TAG) != 0)
2496  return -1;
2497  return 1;
2498 }
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:86
#define MUTT_NM_TAG
Notmuch tag +/- mode.
Definition: mutt.h:75

◆ nm_tags_commit()

static int nm_tags_commit ( struct Mailbox m,
struct Email e,
char *  buf 
)
static

Save the tags to a message - Implements MxOps::tags_commit()

Definition at line 2503 of file mutt_notmuch.c.

2504 {
2505  if (!m)
2506  return -1;
2507 
2508  struct NmMboxData *mdata = nm_mdata_get(m);
2509  if (!buf || (*buf == '\0') || !mdata)
2510  return -1;
2511 
2512  notmuch_database_t *db = NULL;
2513  notmuch_message_t *msg = NULL;
2514  int rc = -1;
2515 
2516  if (!(db = nm_db_get(m, true)) || !(msg = get_nm_message(db, e)))
2517  goto done;
2518 
2519  mutt_debug(LL_DEBUG1, "nm: tags modify: '%s'\n", buf);
2520 
2521  update_tags(msg, buf);
2522  update_email_flags(m, e, buf);
2523  update_email_tags(e, msg);
2524  mutt_set_header_color(m, e);
2525 
2526  rc = 0;
2527  e->changed = true;
2528 done:
2529  nm_db_release(m);
2530  if (e->changed)
2531  {
2532  m->mtime.tv_sec = mutt_date_epoch();
2533  m->mtime.tv_nsec = 0;
2534  }
2535  mutt_debug(LL_DEBUG1, "nm: tags modify done [rc=%d]\n", rc);
2536  return rc;
2537 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:410
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:143
static int update_email_flags(struct Mailbox *m, struct Email *e, const char *tags)
Update the Email&#39;s flags.
static int update_email_tags(struct Email *e, notmuch_message_t *msg)
Update the Email&#39;s tags from Notmuch.
Definition: mutt_notmuch.c:630
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:118
bool changed
Email has been edited.
Definition: email.h:50
time_t tv_sec
Definition: file.h:47
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:167
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:147
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:231
static notmuch_message_t * get_nm_message(notmuch_database_t *db, struct Email *e)
Find a Notmuch message.
void mutt_set_header_color(struct Mailbox *m, struct Email *e)
Select a colour for a message.
Definition: index.c:3672
Log at debug level 1.
Definition: logging.h:56
static int update_tags(notmuch_message_t *msg, const char *tags)
Update the tags on a message.
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:

◆ nm_path_probe()

enum MailboxType nm_path_probe ( const char *  path,
const struct stat *  st 
)

Is this a Notmuch Mailbox? - Implements MxOps::path_probe()

Definition at line 2542 of file mutt_notmuch.c.

2543 {
2544  if (!path || !mutt_str_startswith(path, NmUriProtocol, CASE_IGNORE))
2545  return MUTT_UNKNOWN;
2546 
2547  return MUTT_NOTMUCH;
2548 }
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:46
const char NmUriProtocol[]
Definition: mutt_notmuch.c:70
Ignore case when comparing strings.
Definition: string2.h:68
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ nm_path_canon()

int nm_path_canon ( char *  buf,
size_t  buflen 
)

Canonicalise a Mailbox path - Implements MxOps::path_canon()

Definition at line 2553 of file mutt_notmuch.c.

2554 {
2555  if (!buf)
2556  return -1;
2557 
2558  return 0;
2559 }

◆ nm_path_pretty()

int nm_path_pretty ( char *  buf,
size_t  buflen,
const char *  folder 
)

Abbreviate a Mailbox path - Implements MxOps::path_pretty()

Definition at line 2564 of file mutt_notmuch.c.

2565 {
2566  /* Succeed, but don't do anything, for now */
2567  return 0;
2568 }

◆ nm_path_parent()

int nm_path_parent ( char *  buf,
size_t  buflen 
)

Find the parent of a Mailbox path - Implements MxOps::path_parent()

Definition at line 2573 of file mutt_notmuch.c.

2574 {
2575  /* Succeed, but don't do anything, for now */
2576  return 0;
2577 }

Variable Documentation

◆ NmUriProtocol

const char NmUriProtocol[] = "notmuch://"

Definition at line 70 of file mutt_notmuch.c.

◆ NmUriProtocolLen

const int NmUriProtocolLen = sizeof(NmUriProtocol) - 1

Definition at line 71 of file mutt_notmuch.c.

◆ C_NmDbLimit

int C_NmDbLimit

Config: (notmuch) Default limit for Notmuch queries.

Definition at line 74 of file mutt_notmuch.c.

◆ C_NmDefaultUri

char* C_NmDefaultUri

Config: (notmuch) Path to the Notmuch database.

Definition at line 75 of file mutt_notmuch.c.

◆ C_NmExcludeTags

char* C_NmExcludeTags

Config: (notmuch) Exclude messages with these tags.

Definition at line 76 of file mutt_notmuch.c.

◆ C_NmOpenTimeout

int C_NmOpenTimeout

Config: (notmuch) Database timeout.

Definition at line 77 of file mutt_notmuch.c.

◆ C_NmQueryType

char* C_NmQueryType

Config: (notmuch) Default query type: 'threads' or 'messages'.

Definition at line 78 of file mutt_notmuch.c.

◆ C_NmQueryWindowCurrentPosition

int C_NmQueryWindowCurrentPosition

Config: (notmuch) Position of current search window.

Definition at line 79 of file mutt_notmuch.c.

◆ C_NmQueryWindowTimebase

char* C_NmQueryWindowTimebase

Config: (notmuch) Units for the time duration.

Definition at line 80 of file mutt_notmuch.c.

◆ C_NmRecordTags

char* C_NmRecordTags

Config: (notmuch) Tags to apply to the 'record' mailbox (sent mail)

Definition at line 81 of file mutt_notmuch.c.

◆ C_NmUnreadTag

char* C_NmUnreadTag

Config: (notmuch) Tag to use for unread messages.

Definition at line 82 of file mutt_notmuch.c.

◆ C_NmFlaggedTag

char* C_NmFlaggedTag

Config: (notmuch) Tag to use for flagged messages.

Definition at line 83 of file mutt_notmuch.c.

◆ C_NmRepliedTag

char* C_NmRepliedTag

Config: (notmuch) Tag to use for replied messages.

Definition at line 84 of file mutt_notmuch.c.

◆ MxNotmuchOps

struct MxOps MxNotmuchOps
Initial value:
= {
.magic = MUTT_NOTMUCH,
.name = "notmuch",
.ac_find = nm_ac_find,
.ac_add = nm_ac_add,
.mbox_open = nm_mbox_open,
.mbox_open_append = NULL,
.mbox_check = nm_mbox_check,
.mbox_check_stats = nm_mbox_check_stats,
.mbox_sync = nm_mbox_sync,
.mbox_close = nm_mbox_close,
.msg_open = nm_msg_open,
.msg_open_new = maildir_msg_open_new,
.msg_commit = nm_msg_commit,
.msg_close = nm_msg_close,
.msg_padding_size = NULL,
.msg_save_hcache = NULL,
.tags_edit = nm_tags_edit,
.tags_commit = nm_tags_commit,
.path_probe = nm_path_probe,
.path_canon = nm_path_canon,
.path_pretty = nm_path_pretty,
.path_parent = nm_path_parent,
}
int maildir_msg_open_new(struct Mailbox *m, struct Message *msg, struct Email *e)
Open a new message in a Mailbox - Implements MxOps::msg_open_new()
Definition: maildir.c:575
static int nm_tags_edit(struct Mailbox *m, const char *tags, char *buf, size_t buflen)
Prompt and validate new messages tags - Implements MxOps::tags_edit()
enum MailboxType nm_path_probe(const char *path, const struct stat *st)
Is this a Notmuch Mailbox? - Implements MxOps::path_probe()
int nm_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon()
int nm_path_parent(char *buf, size_t buflen)
Find the parent of a Mailbox path - Implements MxOps::path_parent()
struct Account * nm_ac_find(struct Account *a, const char *path)
Find an Account that matches a Mailbox path - Implements MxOps::ac_find()
int nm_path_pretty(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path - Implements MxOps::path_pretty()
static int nm_mbox_close(struct Mailbox *m)
Close a Mailbox - Implements MxOps::mbox_close()
static int nm_msg_commit(struct Mailbox *m, struct Message *msg)
Save changes to an email - Implements MxOps::msg_commit()
static int nm_msg_open(struct Mailbox *m, struct Message *msg, int msgno)
Open an email message in a Mailbox - Implements MxOps::msg_open()
static int nm_mbox_check(struct Mailbox *m, int *index_hint)
Check for new mail - Implements MxOps::mbox_check()
static int nm_tags_commit(struct Mailbox *m, struct Email *e, char *buf)
Save the tags to a message - Implements MxOps::tags_commit()
static int nm_mbox_sync(struct Mailbox *m, int *index_hint)
Save changes to the Mailbox - Implements MxOps::mbox_sync()
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
static int nm_mbox_open(struct Mailbox *m)
Open a Mailbox - Implements MxOps::mbox_open()
int nm_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add()
static int nm_mbox_check_stats(struct Mailbox *m, int flags)
Check the Mailbox statistics - Implements MxOps::check_stats()
static int nm_msg_close(struct Mailbox *m, struct Message *msg)
Close an email - Implements MxOps::msg_close()

Notmuch Mailbox - Implements MxOps.

Definition at line 2583 of file mutt_notmuch.c.