NeoMutt  2019-12-07-60-g0cfa53
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 <time.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 "gui/lib.h"
#include "mutt.h"
#include "mutt_notmuch.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...
 
static 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...
 
static 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...
 
static struct Accountnm_ac_find (struct Account *a, const char *path)
 Find an Account that matches a Mailbox path - Implements MxOps::ac_find() More...
 
static 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...
 
static int nm_path_canon (char *buf, size_t buflen)
 Canonicalise a Mailbox path - Implements MxOps::path_canon() More...
 
static int nm_path_pretty (char *buf, size_t buflen, const char *folder)
 Abbreviate a Mailbox path - Implements MxOps::path_pretty() More...
 
static 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 92 of file mutt_notmuch.c.

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

◆ nm_hcache_close()

static void nm_hcache_close ( header_cache_t h)
static

Close the header cache.

Parameters
hHeader cache handle

Definition at line 105 of file mutt_notmuch.c.

106 {
107 #ifdef USE_HCACHE
109 #endif
110 }
void mutt_hcache_close(header_cache_t *hc)
Multiplexor for HcacheOps::close.
Definition: hcache.c:329
+ 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 117 of file mutt_notmuch.c.

118 {
119  if (mutt_str_strcmp(str, "threads") == 0)
120  return NM_QUERY_TYPE_THREADS;
121  if (mutt_str_strcmp(str, "messages") == 0)
122  return NM_QUERY_TYPE_MESGS;
123 
124  mutt_error(_("failed to parse notmuch query type: %s"), NONULL(str));
125  return NM_QUERY_TYPE_MESGS;
126 }
#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 132 of file mutt_notmuch.c.

133 {
134  if (!ptr || !*ptr)
135  return;
136 
137  struct NmAccountData *adata = *ptr;
138  if (adata->db)
139  {
140  nm_db_free(adata->db);
141  adata->db = NULL;
142  }
143 
144  FREE(ptr);
145 }
void nm_db_free(notmuch_database_t *db)
decoupled way to close a Notmuch database
Definition: nm_db.c:188
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 151 of file mutt_notmuch.c.

152 {
153  struct NmAccountData *adata = mutt_mem_calloc(1, sizeof(struct NmAccountData));
154 
155  return adata;
156 }
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 164 of file mutt_notmuch.c.

165 {
166  if (!m || (m->magic != MUTT_NOTMUCH))
167  return NULL;
168 
169  struct Account *a = m->account;
170  if (!a)
171  return NULL;
172 
173  return a->adata;
174 }
A group of associated Mailboxes.
Definition: account.h:36
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
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:130
+ 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 184 of file mutt_notmuch.c.

185 {
186  if (!ptr || !*ptr)
187  return;
188 
189  struct NmMboxData *mdata = *ptr;
190 
191  mutt_debug(LL_DEBUG1, "nm: freeing context data %p\n", mdata);
192 
193  url_free(&mdata->db_url);
194  FREE(&mdata->db_query);
195  FREE(ptr);
196 }
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:135
char * db_query
Previous query.
struct Url * db_url
Parsed view url of the Notmuch database.
Log at debug level 1.
Definition: logging.h:40
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 206 of file mutt_notmuch.c.

207 {
208  if (!uri)
209  return NULL;
210 
211  struct NmMboxData *mdata = mutt_mem_calloc(1, sizeof(struct NmMboxData));
212  mutt_debug(LL_DEBUG1, "nm: initialize mailbox mdata %p\n", (void *) mdata);
213 
214  mdata->db_limit = C_NmDbLimit;
216  mdata->db_url = url_parse(uri);
217  if (!mdata->db_url)
218  {
219  mutt_error(_("failed to parse notmuch uri: %s"), uri);
220  FREE(&mdata);
221  return NULL;
222  }
223  return mdata;
224 }
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:75
#define _(a)
Definition: message.h:28
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:135
char * C_NmQueryType
Config: (notmuch) Default query type: &#39;threads&#39; or &#39;messages&#39;.
Definition: mutt_notmuch.c:79
struct Url * db_url
Parsed view url of the Notmuch database.
Log at debug level 1.
Definition: logging.h:40
#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:117
#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 232 of file mutt_notmuch.c.

233 {
234  if (!m || (m->magic != MUTT_NOTMUCH))
235  return NULL;
236 
237  return m->mdata;
238 }
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
void * mdata
Driver specific data.
Definition: mailbox.h:135
&#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 247 of file mutt_notmuch.c.

248 {
249  if (!ptr || !*ptr)
250  return;
251 
252  struct NmEmailData *edata = *ptr;
253  mutt_debug(LL_DEBUG2, "nm: freeing email %p\n", (void *) edata);
254  FREE(&edata->folder);
255  FREE(&edata->oldpath);
256  FREE(&edata->virtual_id);
257  FREE(ptr);
258 }
Log at debug level 2.
Definition: logging.h:41
char * virtual_id
Unique Notmuch Id.
char * folder
Location of the Email.
Notmuch-specific Email data -.
void * edata
Driver-specific data.
Definition: email.h:106
#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 264 of file mutt_notmuch.c.

265 {
266  return mutt_mem_calloc(1, sizeof(struct NmEmailData));
267 }
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()

static struct NmMboxData* nm_get_default_data ( void  )
static

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 274 of file mutt_notmuch.c.

275 {
276  // path to DB + query + URI "decoration"
277  char uri[PATH_MAX + 1024 + 32];
278 
279  // Try to use C_NmDefaultUri or C_Folder.
280  // If neither are set, it is impossible to create a Notmuch URI.
281  if (C_NmDefaultUri)
282  snprintf(uri, sizeof(uri), "%s", C_NmDefaultUri);
283  else if (C_Folder)
284  snprintf(uri, sizeof(uri), "notmuch://%s", C_Folder);
285  else
286  return NULL;
287 
288  return nm_mdata_new(uri);
289 }
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:119
#define PATH_MAX
Definition: mutt.h:50
char * C_NmDefaultUri
Config: (notmuch) Path to the Notmuch database.
Definition: mutt_notmuch.c:76
struct NmMboxData * nm_mdata_new(const char *uri)
Create a new NmMboxData object from a query.
Definition: mutt_notmuch.c:206
+ 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 301 of file mutt_notmuch.c.

302 {
303  if (!m || (m->magic != MUTT_NOTMUCH))
304  return -1;
305 
306  if (m->mdata)
307  return 0;
308 
310  if (!m->mdata)
311  return -1;
312 
314  return 0;
315 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
void(* free_mdata)(void **)
Driver-specific data free function.
Definition: mailbox.h:136
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
void * mdata
Driver specific data.
Definition: mailbox.h:135
void nm_mdata_free(void **ptr)
Free data attached to the Mailbox.
Definition: mutt_notmuch.c:184
&#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:206
+ 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 323 of file mutt_notmuch.c.

324 {
325  return (e && e->edata) ? ((struct NmEmailData *) e->edata)->virtual_id : NULL;
326 }
Notmuch-specific Email data -.
void * edata
Driver-specific data.
Definition: email.h:106
+ 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 335 of file mutt_notmuch.c.

336 {
337  snprintf(buf, buflen, "%s/%s", nm_email_get_folder(e), e->path);
338  return buf;
339 }
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:91
+ 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 348 of file mutt_notmuch.c.

349 {
350  if (query_type == NM_QUERY_TYPE_THREADS)
351  return "threads";
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_subset_str_native_set(NeoMutt->sub, "nm_query_window_current_position", 0, NULL);
389 }
Container for Accounts, Notifications.
Definition: neomutt.h:35
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:243
Log at debug level 2.
Definition: logging.h:41
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:38
+ 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:81
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:169
#define _(a)
Definition: message.h:28
Log at debug level 2.
Definition: logging.h:41
WHERE int C_NmQueryWindowDuration
Config: (notmuch) Time duration of the current search window.
Definition: globals.h:168
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:80
#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  else if (strcmp(item->name, "query") == 0)
514  mdata->db_query = mutt_str_strdup(item->value);
515  }
516 
517  if (!mdata->db_query)
518  return NULL;
519 
520  if (window)
521  {
522  char buf[1024];
524 
525  /* if a date part is defined, do not apply windows (to avoid the risk of
526  * having a non-intersected date frame). A good improvement would be to
527  * accept if they intersect */
528  if (!strstr(mdata->db_query, "date:") &&
529  windowed_query_from_query(mdata->db_query, buf, sizeof(buf)))
530  {
531  mdata->db_query = mutt_str_strdup(buf);
532  }
533 
534  mutt_debug(LL_DEBUG2, "nm: query (windowed) '%s'\n", mdata->db_query);
535  }
536  else
537  mutt_debug(LL_DEBUG2, "nm: query '%s'\n", mdata->db_query);
538 
539  return mdata->db_query;
540 }
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:169
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:41
char * C_NmQueryType
Config: (notmuch) Default query type: &#39;threads&#39; or &#39;messages&#39;.
Definition: mutt_notmuch.c:79
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:349
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:117
#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 547 of file mutt_notmuch.c.

548 {
549  return mdata ? mdata->db_limit : 0;
550 }
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 556 of file mutt_notmuch.c.

557 {
558  if (!C_NmExcludeTags || !query)
559  return;
560 
561  char *end = NULL, *tag = NULL;
562 
563  char *buf = mutt_str_strdup(C_NmExcludeTags);
564 
565  for (char *p = buf; p && (p[0] != '\0'); p++)
566  {
567  if (!tag && isspace(*p))
568  continue;
569  if (!tag)
570  tag = p; /* begin of the tag */
571  if ((p[0] == ',') || (p[0] == ' '))
572  end = p; /* terminate the tag */
573  else if (p[1] == '\0')
574  end = p + 1; /* end of optstr */
575  if (!tag || !end)
576  continue;
577  if (tag >= end)
578  break;
579  *end = '\0';
580 
581  mutt_debug(LL_DEBUG2, "nm: query exclude tag '%s'\n", tag);
582  notmuch_query_add_tag_exclude(query, tag);
583  end = NULL;
584  tag = NULL;
585  }
586  notmuch_query_set_omit_excluded(query, 1);
587  FREE(&buf);
588 }
char * C_NmExcludeTags
Config: (notmuch) Exclude messages with these tags.
Definition: mutt_notmuch.c:77
Log at debug level 2.
Definition: logging.h:41
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 597 of file mutt_notmuch.c.

598 {
599  struct NmMboxData *mdata = nm_mdata_get(m);
600  if (!mdata)
601  return NULL;
602 
603  notmuch_database_t *db = nm_db_get(m, writable);
604  const char *str = get_query_string(mdata, true);
605 
606  if (!db || !str)
607  goto err;
608 
609  notmuch_query_t *q = notmuch_query_create(db, str);
610  if (!q)
611  goto err;
612 
614  notmuch_query_set_sort(q, NOTMUCH_SORT_NEWEST_FIRST);
615  mutt_debug(LL_DEBUG2, "nm: query successfully initialized (%s)\n", str);
616  return q;
617 err:
618  nm_db_release(m);
619  return NULL;
620 }
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:147
Log at debug level 2.
Definition: logging.h:41
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:171
void * mdata
Driver specific data.
Definition: mailbox.h:135
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:232
static void apply_exclude_tags(notmuch_query_t *query)
Exclude the configured tags.
Definition: mutt_notmuch.c:556
#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 629 of file mutt_notmuch.c.

630 {
631  struct NmEmailData *edata = e->edata;
632  char *new_tags = NULL;
633  char *old_tags = NULL;
634 
635  mutt_debug(LL_DEBUG2, "nm: tags update requested (%s)\n", edata->virtual_id);
636 
637  for (notmuch_tags_t *tags = notmuch_message_get_tags(msg);
638  tags && notmuch_tags_valid(tags); notmuch_tags_move_to_next(tags))
639  {
640  const char *t = notmuch_tags_get(tags);
641  if (!t || !*t)
642  continue;
643 
644  mutt_str_append_item(&new_tags, t, ' ');
645  }
646 
647  old_tags = driver_tags_get(&e->tags);
648 
649  if (new_tags && old_tags && (strcmp(old_tags, new_tags) == 0))
650  {
651  FREE(&old_tags);
652  FREE(&new_tags);
653  mutt_debug(LL_DEBUG2, "nm: tags unchanged\n");
654  return 1;
655  }
656 
657  /* new version */
658  driver_tags_replace(&e->tags, new_tags);
659  FREE(&new_tags);
660 
661  new_tags = driver_tags_get_transformed(&e->tags);
662  mutt_debug(LL_DEBUG2, "nm: new tags: '%s'\n", new_tags);
663  FREE(&new_tags);
664 
665  new_tags = driver_tags_get(&e->tags);
666  mutt_debug(LL_DEBUG2, "nm: new tag transforms: '%s'\n", new_tags);
667  FREE(&new_tags);
668 
669  return 0;
670 }
Log at debug level 2.
Definition: logging.h:41
char * virtual_id
Unique Notmuch Id.
struct TagList tags
For drivers that support server tagging.
Definition: email.h:102
Notmuch-specific Email data -.
char * driver_tags_get(struct TagList *list)
Get tags.
Definition: tags.c:142
char * driver_tags_get_transformed(struct TagList *list)
Get transformed tags.
Definition: tags.c:130
void * edata
Driver-specific data.
Definition: email.h:106
#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:183
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 679 of file mutt_notmuch.c.

680 {
681  struct NmEmailData *edata = e->edata;
682 
683  mutt_debug(LL_DEBUG2, "nm: path update requested path=%s, (%s)\n", path, edata->virtual_id);
684 
685  char *p = strrchr(path, '/');
686  if (p && ((p - path) > 3) &&
687  ((strncmp(p - 3, "cur", 3) == 0) || (strncmp(p - 3, "new", 3) == 0) ||
688  (strncmp(p - 3, "tmp", 3) == 0)))
689  {
690  edata->magic = MUTT_MAILDIR;
691 
692  FREE(&e->path);
693  FREE(&edata->folder);
694 
695  p -= 3; /* skip subfolder (e.g. "new") */
696  e->path = mutt_str_strdup(p);
697 
698  for (; (p > path) && (*(p - 1) == '/'); p--)
699  ;
700 
701  edata->folder = mutt_str_substr_dup(path, p);
702 
703  mutt_debug(LL_DEBUG2, "nm: folder='%s', file='%s'\n", edata->folder, e->path);
704  return 0;
705  }
706 
707  return 1;
708 }
Log at debug level 2.
Definition: logging.h:41
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:106
char * path
Path of Email (for local Mailboxes)
Definition: email.h:91
#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 716 of file mutt_notmuch.c.

717 {
718  char *p = strrchr(path, '/');
719 
720  if (p && ((p - path) > 3) &&
721  ((strncmp(p - 3, "cur", 3) == 0) || (strncmp(p - 3, "new", 3) == 0) ||
722  (strncmp(p - 3, "tmp", 3) == 0)))
723  {
724  p -= 3;
725  for (; (p > path) && (*(p - 1) == '/'); p--)
726  ;
727 
728  return mutt_str_substr_dup(path, p);
729  }
730 
731  return NULL;
732 }
char * path
Path of Email (for local Mailboxes)
Definition: email.h:91
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 741 of file mutt_notmuch.c.

742 {
743  size_t sz;
744  char *mid = NULL;
745 
746  if (!id)
747  return NULL;
748  sz = strlen(id) + 3;
749  mid = mutt_mem_malloc(sz);
750 
751  snprintf(mid, sz, "<%s>", id);
752  return mid;
753 }
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 763 of file mutt_notmuch.c.

764 {
765  if (e->edata)
766  return 0;
767 
768  struct NmEmailData *edata = nm_edata_new();
769  e->edata = edata;
771 
772  /* Notmuch ensures that message Id exists (if not notmuch Notmuch will
773  * generate an ID), so it's more safe than use neomutt Email->env->id */
774  const char *id = notmuch_message_get_message_id(msg);
775  edata->virtual_id = mutt_str_strdup(id);
776 
777  mutt_debug(LL_DEBUG2, "nm: [e=%p, edata=%p] (%s)\n", (void *) e, (void *) e->edata, id);
778 
779  char *nm_msg_id = nm2mutt_message_id(id);
780  if (!e->env->message_id)
781  {
782  e->env->message_id = nm_msg_id;
783  }
784  else if (mutt_str_strcmp(e->env->message_id, nm_msg_id) != 0)
785  {
786  FREE(&e->env->message_id);
787  e->env->message_id = nm_msg_id;
788  }
789  else
790  {
791  FREE(&nm_msg_id);
792  }
793 
794  if (update_message_path(e, path) != 0)
795  return -1;
796 
797  update_email_tags(e, msg);
798 
799  return 0;
800 }
void(* free_edata)(void **)
Driver-specific data free function.
Definition: email.h:107
static int update_email_tags(struct Email *e, notmuch_message_t *msg)
Update the Email&#39;s tags from Notmuch.
Definition: mutt_notmuch.c:629
Log at debug level 2.
Definition: logging.h:41
static char * nm2mutt_message_id(const char *id)
converts notmuch message Id to neomutt message Id
Definition: mutt_notmuch.c:741
char * virtual_id
Unique Notmuch Id.
void nm_edata_free(void **ptr)
Free data attached to an Email.
Definition: mutt_notmuch.c:247
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:679
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
void * edata
Driver-specific data.
Definition: email.h:106
char * path
Path of Email (for local Mailboxes)
Definition: email.h:91
#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:264
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 808 of file mutt_notmuch.c.

809 {
810  const char *name = NULL;
811 
812  for (notmuch_filenames_t *ls = notmuch_message_get_filenames(msg);
813  ls && notmuch_filenames_valid(ls); notmuch_filenames_move_to_next(ls))
814  {
815  name = notmuch_filenames_get(ls);
816  }
817 
818  return name;
819 }
const char * name
Definition: pgpmicalg.c:46
+ 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 825 of file mutt_notmuch.c.

826 {
827  if (m->quiet)
828  return;
829 
830  struct NmMboxData *mdata = nm_mdata_get(m);
831  if (!mdata)
832  return;
833 
834  memset(&mdata->progress, 0, sizeof(mdata->progress));
835  mdata->oldmsgcount = m->msg_count;
836  mdata->ignmsgcount = 0;
837  mdata->noprogress = false;
838  mdata->progress_ready = false;
839 }
int msg_count
Total number of messages.
Definition: mailbox.h:90
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:135
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
struct Progress progress
A progress bar.
bool quiet
Inhibit status messages?
Definition: mailbox.h:117
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 846 of file mutt_notmuch.c.

847 {
848  struct NmMboxData *mdata = nm_mdata_get(m);
849 
850  if (m->quiet || !mdata || mdata->noprogress)
851  return;
852 
853  if (!mdata->progress_ready && q)
854  {
855  // The total mail count is in oldmsgcount, so use that instead of recounting.
856  mutt_progress_init(&mdata->progress, _("Reading messages..."),
858  mdata->progress_ready = true;
859  }
860 
861  if (mdata->progress_ready)
862  {
863  mutt_progress_update(&mdata->progress, m->msg_count + mdata->ignmsgcount, -1);
864  }
865 }
int msg_count
Total number of messages.
Definition: mailbox.h:90
#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:41
void * mdata
Driver specific data.
Definition: mailbox.h:135
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
struct Progress progress
A progress bar.
bool quiet
Inhibit status messages?
Definition: mailbox.h:117
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 874 of file mutt_notmuch.c.

875 {
876  if (!m || !msg)
877  return NULL;
878 
879  const char *id = notmuch_message_get_message_id(msg);
880  if (!id)
881  return NULL;
882 
883  mutt_debug(LL_DEBUG2, "nm: neomutt email, id='%s'\n", id);
884 
885  if (!m->id_hash)
886  {
887  mutt_debug(LL_DEBUG2, "nm: init hash\n");
888  m->id_hash = mutt_make_id_hash(m);
889  if (!m->id_hash)
890  return NULL;
891  }
892 
893  char *mid = nm2mutt_message_id(id);
894  mutt_debug(LL_DEBUG2, "nm: neomutt id='%s'\n", mid);
895 
896  struct Email *e = mutt_hash_find(m->id_hash, mid);
897  FREE(&mid);
898  return e;
899 }
The envelope/body of an email.
Definition: email.h:37
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:378
Log at debug level 2.
Definition: logging.h:41
static char * nm2mutt_message_id(const char *id)
converts notmuch message Id to neomutt message Id
Definition: mutt_notmuch.c:741
struct Hash * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1456
#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:126
+ 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 909 of file mutt_notmuch.c.

911 {
912  struct NmMboxData *mdata = nm_mdata_get(m);
913  if (!mdata)
914  return;
915 
916  char *newpath = NULL;
917  struct Email *e = NULL;
918 
919  /* deduplicate */
920  if (dedup && get_mutt_email(m, msg))
921  {
922  mdata->ignmsgcount++;
923  progress_update(m, q);
924  mutt_debug(LL_DEBUG2, "nm: ignore id=%s, already in the m\n",
925  notmuch_message_get_message_id(msg));
926  return;
927  }
928 
929  const char *path = get_message_last_filename(msg);
930  if (!path)
931  return;
932 
933  mutt_debug(LL_DEBUG2, "nm: appending message, i=%d, id=%s, path=%s\n",
934  m->msg_count, notmuch_message_get_message_id(msg), path);
935 
936  if (m->msg_count >= m->email_max)
937  {
938  mutt_debug(LL_DEBUG2, "nm: allocate mx memory\n");
939  mx_alloc_memory(m);
940  }
941 
942 #ifdef USE_HCACHE
943  void *from_cache = mutt_hcache_fetch(h, path, mutt_str_strlen(path));
944  if (from_cache)
945  {
946  e = mutt_hcache_restore(from_cache);
947  }
948  else
949 #endif
950  {
951  if (access(path, F_OK) == 0)
952  e = maildir_parse_message(MUTT_MAILDIR, path, false, NULL);
953  else
954  {
955  /* maybe moved try find it... */
956  char *folder = get_folder_from_path(path);
957 
958  if (folder)
959  {
960  FILE *fp = maildir_open_find_message(folder, path, &newpath);
961  if (fp)
962  {
963  e = maildir_parse_stream(MUTT_MAILDIR, fp, newpath, false, NULL);
964  mutt_file_fclose(&fp);
965 
966  mutt_debug(LL_DEBUG1, "nm: not up-to-date: %s -> %s\n", path, newpath);
967  }
968  }
969  FREE(&folder);
970  }
971  }
972 
973  if (!e)
974  {
975  mutt_debug(LL_DEBUG1, "nm: failed to parse message: %s\n", path);
976  goto done;
977  }
978 
979 #ifdef USE_HCACHE
980 
981  if (from_cache)
982  {
983  mutt_hcache_free(h, &from_cache);
984  }
985  else
986  {
987  mutt_hcache_store(h, newpath ? newpath : path,
988  mutt_str_strlen(newpath ? newpath : path), e, 0);
989  }
990 #endif
991  if (init_email(e, newpath ? newpath : path, msg) != 0)
992  {
993  email_free(&e);
994  mutt_debug(LL_DEBUG1, "nm: failed to append email!\n");
995  goto done;
996  }
997 
998  e->active = true;
999  e->index = m->msg_count;
1000  mailbox_size_add(m, e);
1001  m->emails[m->msg_count] = e;
1002  m->msg_count++;
1003 
1004  if (newpath)
1005  {
1006  /* remember that file has been moved -- nm_mbox_sync() will update the DB */
1007  struct NmEmailData *edata = e->edata;
1008 
1009  if (edata)
1010  {
1011  mutt_debug(LL_DEBUG1, "nm: remember obsolete path: %s\n", path);
1012  edata->oldpath = mutt_str_strdup(path);
1013  }
1014  }
1015  progress_update(m, q);
1016 done:
1017  FREE(&newpath);
1018 }
void * mutt_hcache_fetch(header_cache_t *hc, const char *key, size_t keylen)
Multiplexor for HcacheOps::fetch.
Definition: hcache.c:343
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
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:185
static const char * get_message_last_filename(notmuch_message_t *msg)
Get a message&#39;s last filename.
Definition: mutt_notmuch.c:808
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1166
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:41
Notmuch-specific Mailbox data -.
FILE * maildir_open_find_message(const char *folder, const char *msg, char **newname)
Find a new.
Definition: shared.c:1481
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
static void progress_update(struct Mailbox *m, notmuch_query_t *q)
Update the progress counter.
Definition: mutt_notmuch.c:846
void * mdata
Driver specific data.
Definition: mailbox.h:135
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:50
bool active
Message is not to be removed.
Definition: email.h:59
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:1322
int email_max
Number of pointers in emails.
Definition: mailbox.h:99
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:763
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
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:405
Log at debug level 1.
Definition: logging.h:40
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
void * edata
Driver-specific data.
Definition: email.h:106
static struct Email * get_mutt_email(struct Mailbox *m, notmuch_message_t *msg)
Get the Email of a Notmuch message.
Definition: mutt_notmuch.c:874
static char * get_folder_from_path(const char *path)
Find an email&#39;s folder from its path.
Definition: mutt_notmuch.c:716
char * path
Path of Email (for local Mailboxes)
Definition: email.h:91
int ignmsgcount
Ignored messages.
int index
The absolute (unsorted) message number.
Definition: email.h:85
#define FREE(x)
Definition: memory.h:40
void mutt_hcache_free(header_cache_t *hc, void **data)
Multiplexor for HcacheOps::free.
Definition: hcache.c:392
#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:1282
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 1030 of file mutt_notmuch.c.

1032 {
1033  notmuch_messages_t *msgs = NULL;
1034 
1035  for (msgs = notmuch_message_get_replies(top); notmuch_messages_valid(msgs);
1036  notmuch_messages_move_to_next(msgs))
1037  {
1038  notmuch_message_t *nm = notmuch_messages_get(msgs);
1039  append_message(h, m, q, nm, dedup);
1040  /* recurse through all the replies to this message too */
1041  append_replies(h, m, q, nm, dedup);
1042  notmuch_message_destroy(nm);
1043  }
1044 }
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:909
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 1057 of file mutt_notmuch.c.

1059 {
1060  notmuch_messages_t *msgs = NULL;
1061 
1062  for (msgs = notmuch_thread_get_toplevel_messages(thread);
1063  notmuch_messages_valid(msgs); notmuch_messages_move_to_next(msgs))
1064  {
1065  notmuch_message_t *nm = notmuch_messages_get(msgs);
1066  append_message(h, m, q, nm, dedup);
1067  append_replies(h, m, q, nm, dedup);
1068  notmuch_message_destroy(nm);
1069  }
1070 }
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:909
struct MuttThread * thread
Thread of Emails.
Definition: email.h:94
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 1081 of file mutt_notmuch.c.

1082 {
1083  if (!query)
1084  return NULL;
1085 
1086  notmuch_messages_t *msgs = NULL;
1087 
1088 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
1089  if (notmuch_query_search_messages(query, &msgs) != NOTMUCH_STATUS_SUCCESS)
1090  return NULL;
1091 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
1092  if (notmuch_query_search_messages_st(query, &msgs) != NOTMUCH_STATUS_SUCCESS)
1093  return NULL;
1094 #else
1095  msgs = notmuch_query_search_messages(query);
1096 #endif
1097 
1098  return msgs;
1099 }
+ 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 1109 of file mutt_notmuch.c.

1110 {
1111  struct NmMboxData *mdata = nm_mdata_get(m);
1112  if (!mdata)
1113  return false;
1114 
1115  int limit = get_limit(mdata);
1116 
1117  notmuch_messages_t *msgs = get_messages(q);
1118 
1119  if (!msgs)
1120  return false;
1121 
1123 
1124  for (; notmuch_messages_valid(msgs) && ((limit == 0) || (m->msg_count < limit));
1125  notmuch_messages_move_to_next(msgs))
1126  {
1127  if (SigInt == 1)
1128  {
1129  nm_hcache_close(h);
1130  SigInt = 0;
1131  return false;
1132  }
1133  notmuch_message_t *nm = notmuch_messages_get(msgs);
1134  append_message(h, m, q, nm, dedup);
1135  notmuch_message_destroy(nm);
1136  }
1137 
1138  nm_hcache_close(h);
1139  return true;
1140 }
int msg_count
Total number of messages.
Definition: mailbox.h:90
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:909
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: globals.h:79
static void nm_hcache_close(header_cache_t *h)
Close the header cache.
Definition: mutt_notmuch.c:105
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:135
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: mutt_notmuch.c:547
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
static header_cache_t * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: mutt_notmuch.c:92
header cache structure
Definition: hcache.h:67
+ 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 1151 of file mutt_notmuch.c.

1152 {
1153  if (!query)
1154  return NULL;
1155 
1156  notmuch_threads_t *threads = NULL;
1157 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
1158  if (notmuch_query_search_threads(query, &threads) != NOTMUCH_STATUS_SUCCESS)
1159  return false;
1160 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
1161  if (notmuch_query_search_threads_st(query, &threads) != NOTMUCH_STATUS_SUCCESS)
1162  return false;
1163 #else
1164  threads = notmuch_query_search_threads(query);
1165 #endif
1166 
1167  return threads;
1168 }
+ 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 1179 of file mutt_notmuch.c.

1180 {
1181  struct NmMboxData *mdata = nm_mdata_get(m);
1182  if (!mdata)
1183  return false;
1184 
1185  notmuch_threads_t *threads = get_threads(q);
1186  if (!threads)
1187  return false;
1188 
1190 
1191  for (; notmuch_threads_valid(threads) && ((limit == 0) || (m->msg_count < limit));
1192  notmuch_threads_move_to_next(threads))
1193  {
1194  if (SigInt == 1)
1195  {
1196  nm_hcache_close(h);
1197  SigInt = 0;
1198  return false;
1199  }
1200  notmuch_thread_t *thread = notmuch_threads_get(threads);
1201  append_thread(h, m, q, thread, dedup);
1202  notmuch_thread_destroy(thread);
1203  }
1204 
1205  nm_hcache_close(h);
1206  return true;
1207 }
int msg_count
Total number of messages.
Definition: mailbox.h:90
WHERE SIG_ATOMIC_VOLATILE_T SigInt
true after SIGINT is received
Definition: globals.h:79
static void nm_hcache_close(header_cache_t *h)
Close the header cache.
Definition: mutt_notmuch.c:105
Notmuch-specific Mailbox data -.
void * mdata
Driver specific data.
Definition: mailbox.h:135
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
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:92
static notmuch_threads_t * get_threads(notmuch_query_t *query)
load threads for a query
header cache structure
Definition: hcache.h:67
+ 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 1215 of file mutt_notmuch.c.

1216 {
1217  notmuch_message_t *msg = NULL;
1218  char *id = email_get_id(e);
1219 
1220  mutt_debug(LL_DEBUG2, "nm: find message (%s)\n", id);
1221 
1222  if (id && db)
1223  notmuch_database_find_message(db, id, &msg);
1224 
1225  return msg;
1226 }
static char * email_get_id(struct Email *e)
Get the unique Notmuch Id.
Definition: mutt_notmuch.c:323
Log at debug level 2.
Definition: logging.h:41
#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 1234 of file mutt_notmuch.c.

1235 {
1236  const char *possible_match_tag = NULL;
1237  notmuch_tags_t *tags = NULL;
1238 
1239  for (tags = notmuch_message_get_tags(msg); notmuch_tags_valid(tags);
1240  notmuch_tags_move_to_next(tags))
1241  {
1242  possible_match_tag = notmuch_tags_get(tags);
1243  if (mutt_str_strcmp(possible_match_tag, tag) == 0)
1244  {
1245  return true;
1246  }
1247  }
1248  return false;
1249 }
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 1258 of file mutt_notmuch.c.

1259 {
1260  char *buf = mutt_str_strdup(tags);
1261  if (!buf)
1262  return -1;
1263 
1264  notmuch_message_freeze(msg);
1265 
1266  char *tag = NULL, *end = NULL;
1267  for (char *p = buf; p && *p; p++)
1268  {
1269  if (!tag && isspace(*p))
1270  continue;
1271  if (!tag)
1272  tag = p; /* begin of the tag */
1273  if ((p[0] == ',') || (p[0] == ' '))
1274  end = p; /* terminate the tag */
1275  else if (p[1] == '\0')
1276  end = p + 1; /* end of optstr */
1277  if (!tag || !end)
1278  continue;
1279  if (tag >= end)
1280  break;
1281 
1282  end[0] = '\0';
1283 
1284  if (tag[0] == '-')
1285  {
1286  mutt_debug(LL_DEBUG1, "nm: remove tag: '%s'\n", tag + 1);
1287  notmuch_message_remove_tag(msg, tag + 1);
1288  }
1289  else if (tag[0] == '!')
1290  {
1291  mutt_debug(LL_DEBUG1, "nm: toggle tag: '%s'\n", tag + 1);
1292  if (nm_message_has_tag(msg, tag + 1))
1293  {
1294  notmuch_message_remove_tag(msg, tag + 1);
1295  }
1296  else
1297  {
1298  notmuch_message_add_tag(msg, tag + 1);
1299  }
1300  }
1301  else
1302  {
1303  mutt_debug(LL_DEBUG1, "nm: add tag: '%s'\n", (tag[0] == '+') ? tag + 1 : tag);
1304  notmuch_message_add_tag(msg, (tag[0] == '+') ? tag + 1 : tag);
1305  }
1306  end = NULL;
1307  tag = NULL;
1308  }
1309 
1310  notmuch_message_thaw(msg);
1311  FREE(&buf);
1312  return 0;
1313 }
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:40
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 1327 of file mutt_notmuch.c.

1328 {
1329  char *buf = mutt_str_strdup(tags);
1330  if (!buf)
1331  return -1;
1332 
1333  char *tag = NULL, *end = NULL;
1334  for (char *p = buf; p && *p; p++)
1335  {
1336  if (!tag && isspace(*p))
1337  continue;
1338  if (!tag)
1339  tag = p; /* begin of the tag */
1340  if ((p[0] == ',') || (p[0] == ' '))
1341  end = p; /* terminate the tag */
1342  else if (p[1] == '\0')
1343  end = p + 1; /* end of optstr */
1344  if (!tag || !end)
1345  continue;
1346  if (tag >= end)
1347  break;
1348 
1349  end[0] = '\0';
1350 
1351  if (tag[0] == '-')
1352  {
1353  tag++;
1354  if (strcmp(tag, C_NmUnreadTag) == 0)
1355  mutt_set_flag(m, e, MUTT_READ, true);
1356  else if (strcmp(tag, C_NmRepliedTag) == 0)
1357  mutt_set_flag(m, e, MUTT_REPLIED, false);
1358  else if (strcmp(tag, C_NmFlaggedTag) == 0)
1359  mutt_set_flag(m, e, MUTT_FLAG, false);
1360  }
1361  else
1362  {
1363  tag = (tag[0] == '+') ? tag + 1 : tag;
1364  if (strcmp(tag, C_NmUnreadTag) == 0)
1365  mutt_set_flag(m, e, MUTT_READ, false);
1366  else if (strcmp(tag, C_NmRepliedTag) == 0)
1367  mutt_set_flag(m, e, MUTT_REPLIED, true);
1368  else if (strcmp(tag, C_NmFlaggedTag) == 0)
1369  mutt_set_flag(m, e, MUTT_FLAG, true);
1370  }
1371  end = NULL;
1372  tag = NULL;
1373  }
1374 
1375  FREE(&buf);
1376  return 0;
1377 }
#define mutt_set_flag(m, e, flag, bf)
Definition: protos.h:70
Flagged messages.
Definition: mutt.h:106
char * C_NmUnreadTag
Config: (notmuch) Tag to use for unread messages.
Definition: mutt_notmuch.c:83
Messages that have been replied to.
Definition: mutt.h:99
char * C_NmRepliedTag
Config: (notmuch) Tag to use for replied messages.
Definition: mutt_notmuch.c:85
Messages that have been read.
Definition: mutt.h:100
char * C_NmFlaggedTag
Config: (notmuch) Tag to use for flagged messages.
Definition: mutt_notmuch.c:84
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 1389 of file mutt_notmuch.c.

1390 {
1391  char filename[PATH_MAX];
1392  char suffix[PATH_MAX];
1393  char folder[PATH_MAX];
1394 
1395  mutt_str_strfcpy(folder, old, sizeof(folder));
1396  char *p = strrchr(folder, '/');
1397  if (p)
1398  {
1399  *p = '\0';
1400  p++;
1401  }
1402  else
1403  p = folder;
1404 
1405  mutt_str_strfcpy(filename, p, sizeof(filename));
1406 
1407  /* remove (new,cur,...) from folder path */
1408  p = strrchr(folder, '/');
1409  if (p)
1410  *p = '\0';
1411 
1412  /* remove old flags from filename */
1413  p = strchr(filename, ':');
1414  if (p)
1415  *p = '\0';
1416 
1417  /* compose new flags */
1418  maildir_gen_flags(suffix, sizeof(suffix), e);
1419 
1420  snprintf(buf, buflen, "%s/%s/%s%s", folder,
1421  (e->read || e->old) ? "cur" : "new", filename, suffix);
1422 
1423  if (strcmp(old, buf) == 0)
1424  return 1;
1425 
1426  if (rename(old, buf) != 0)
1427  {
1428  mutt_debug(LL_DEBUG1, "nm: rename(2) failed %s -> %s\n", old, buf);
1429  return -1;
1430  }
1431 
1432  return 0;
1433 }
bool read
Email is read.
Definition: email.h:51
bool old
Email is seen, but unread.
Definition: email.h:50
#define PATH_MAX
Definition: mutt.h:50
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:173
Log at debug level 1.
Definition: logging.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:

◆ 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 1442 of file mutt_notmuch.c.

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

◆ 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 1506 of file mutt_notmuch.c.

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

1611 {
1612  notmuch_query_t *q = notmuch_query_create(db, qstr);
1613  if (!q)
1614  return 0;
1615 
1616  unsigned int res = 0;
1617 
1618  apply_exclude_tags(q);
1619 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
1620  if (notmuch_query_count_messages(q, &res) != NOTMUCH_STATUS_SUCCESS)
1621  res = 0; /* may not be defined on error */
1622 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
1623  if (notmuch_query_count_messages_st(q, &res) != NOTMUCH_STATUS_SUCCESS)
1624  res = 0; /* may not be defined on error */
1625 #else
1626  res = notmuch_query_count_messages(q);
1627 #endif
1628  notmuch_query_destroy(q);
1629  mutt_debug(LL_DEBUG1, "nm: count '%s', result=%d\n", qstr, res);
1630 
1631  if ((limit > 0) && (res > limit))
1632  res = limit;
1633 
1634  return res;
1635 }
static void apply_exclude_tags(notmuch_query_t *query)
Exclude the configured tags.
Definition: mutt_notmuch.c:556
Log at debug level 1.
Definition: logging.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_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 1643 of file mutt_notmuch.c.

1644 {
1645  return (e && e->edata) ? ((struct NmEmailData *) e->edata)->folder : NULL;
1646 }
Notmuch-specific Email data -.
void * edata
Driver-specific data.
Definition: email.h:106
+ 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 1655 of file mutt_notmuch.c.

1656 {
1657  if (!m)
1658  return -1;
1659 
1660  struct NmMboxData *mdata = nm_mdata_get(m);
1661  if (!mdata)
1662  return -1;
1663 
1664  notmuch_query_t *q = NULL;
1665  notmuch_database_t *db = NULL;
1666  notmuch_message_t *msg = NULL;
1667  int rc = -1;
1668 
1669  if (!(db = nm_db_get(m, false)) || !(msg = get_nm_message(db, e)))
1670  goto done;
1671 
1672  mutt_debug(LL_DEBUG1, "nm: reading entire-thread messages...[current count=%d]\n",
1673  m->msg_count);
1674 
1675  progress_reset(m);
1676  const char *id = notmuch_message_get_thread_id(msg);
1677  if (!id)
1678  goto done;
1679 
1680  char *qstr = NULL;
1681  mutt_str_append_item(&qstr, "thread:", '\0');
1682  mutt_str_append_item(&qstr, id, '\0');
1683 
1684  q = notmuch_query_create(db, qstr);
1685  FREE(&qstr);
1686  if (!q)
1687  goto done;
1688  apply_exclude_tags(q);
1689  notmuch_query_set_sort(q, NOTMUCH_SORT_NEWEST_FIRST);
1690 
1691  read_threads_query(m, q, true, 0);
1692  m->mtime.tv_sec = mutt_date_epoch();
1693  m->mtime.tv_nsec = 0;
1694  rc = 0;
1695 
1696  if (m->msg_count > mdata->oldmsgcount)
1698 done:
1699  if (q)
1700  notmuch_query_destroy(q);
1701 
1702  nm_db_release(m);
1703 
1704  if (m->msg_count == mdata->oldmsgcount)
1705  mutt_message(_("No more messages in the thread"));
1706 
1707  mdata->oldmsgcount = 0;
1708  mutt_debug(LL_DEBUG1, "nm: reading entire-thread messages... done [rc=%d, count=%d]\n",
1709  rc, m->msg_count);
1710  return rc;
1711 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
int msg_count
Total number of messages.
Definition: mailbox.h:90
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:147
#define mutt_message(...)
Definition: logging.h:83
static void progress_reset(struct Mailbox *m)
Reset the progress counter.
Definition: mutt_notmuch.c:825
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:106
#define _(a)
Definition: message.h:28
Email list was changed.
Definition: mailbox.h:170
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:171
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:135
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
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:556
static bool read_threads_query(struct Mailbox *m, notmuch_query_t *q, bool dedup, int limit)
Perform a query with threads.
Log at debug level 1.
Definition: logging.h:40
#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
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:171
+ 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 1723 of file mutt_notmuch.c.

1724 {
1725  // The six variations of how type= could appear.
1726  const char *variants[6] = { "&type=threads", "&type=messages",
1727  "type=threads&", "type=messages&",
1728  "type=threads", "type=messages" };
1729 
1730  int variants_size = mutt_array_size(variants);
1731  for (int i = 0; i < variants_size; i++)
1732  {
1733  if (mutt_str_strcasestr(buf, variants[i]) != NULL)
1734  {
1735  // variants[] is setup such that type can be determined via modulo 2.
1736  mdata->query_type = ((i % 2) == 0) ? NM_QUERY_TYPE_THREADS : NM_QUERY_TYPE_MESGS;
1737 
1738  mutt_str_remall_strcasestr(buf, variants[i]);
1739  }
1740  }
1741 }
int mutt_str_remall_strcasestr(char *str, const char *target)
Remove all occurrences of substring, ignoring case.
Definition: string.c:1094
const char * mutt_str_strcasestr(const char *haystack, const char *needle)
Find a substring within a string without worrying about case.
Definition: string.c:1119
#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 1751 of file mutt_notmuch.c.

1752 {
1753  mutt_debug(LL_DEBUG2, "(%s)\n", buf);
1754  struct NmMboxData *mdata = nm_mdata_get(m);
1755  char uri[PATH_MAX + 1024 + 32]; /* path to DB + query + URI "decoration" */
1756  int added;
1757  bool using_default_data = false;
1758 
1759  // No existing data. Try to get a default NmMboxData.
1760  if (!mdata)
1761  {
1762  mdata = nm_get_default_data();
1763 
1764  // Failed to get default data.
1765  if (!mdata)
1766  return NULL;
1767 
1768  using_default_data = true;
1769  }
1770 
1771  nm_parse_type_from_query(mdata, buf);
1772 
1773  if (get_limit(mdata) == C_NmDbLimit)
1774  {
1775  added = snprintf(uri, sizeof(uri), "%s%s?type=%s&query=", NmUriProtocol,
1777  }
1778  else
1779  {
1780  added = snprintf(uri, sizeof(uri), "%s%s?type=%s&limit=%d&query=", NmUriProtocol,
1781  nm_db_get_filename(m),
1782  query_type_to_string(mdata->query_type), get_limit(mdata));
1783  }
1784 
1785  if (added >= sizeof(uri))
1786  {
1787  // snprintf output was truncated, so can't create URI
1788  return NULL;
1789  }
1790 
1791  url_pct_encode(&uri[added], sizeof(uri) - added, buf);
1792 
1793  mutt_str_strfcpy(buf, uri, buflen);
1794  buf[buflen - 1] = '\0';
1795 
1796  if (using_default_data)
1797  nm_mdata_free((void **) &mdata);
1798 
1799  mutt_debug(LL_DEBUG1, "nm: uri from query '%s'\n", buf);
1800  return buf;
1801 }
int C_NmDbLimit
Config: (notmuch) Default limit for Notmuch queries.
Definition: mutt_notmuch.c:75
static struct NmMboxData * nm_get_default_data(void)
Create a Mailbox with default Notmuch settings.
Definition: mutt_notmuch.c:274
Log at debug level 2.
Definition: logging.h:41
Notmuch-specific Mailbox data -.
const char NmUriProtocol[]
Definition: mutt_notmuch.c:71
void * mdata
Driver specific data.
Definition: mailbox.h:135
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: mutt_notmuch.c:547
void nm_mdata_free(void **ptr)
Free data attached to the Mailbox.
Definition: mutt_notmuch.c:184
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:50
const char * nm_db_get_filename(struct Mailbox *m)
Get the filename of the Notmuch database.
Definition: nm_db.c:53
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
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:40
#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:348
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 1812 of file mutt_notmuch.c.

1813 {
1816 
1818 }
Log at debug level 2.
Definition: logging.h:41
int C_NmQueryWindowCurrentPosition
Config: (notmuch) Position of current search window.
Definition: mutt_notmuch.c:80
#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 1828 of file mutt_notmuch.c.

1829 {
1832 }
Log at debug level 2.
Definition: logging.h:41
int C_NmQueryWindowCurrentPosition
Config: (notmuch) Position of current search window.
Definition: mutt_notmuch.c:80
#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 1840 of file mutt_notmuch.c.

1841 {
1842  struct NmMboxData *mdata = nm_mdata_get(m);
1843  notmuch_database_t *db = nm_db_get(m, false);
1844  char *orig_str = get_query_string(mdata, true);
1845 
1846  if (!db || !orig_str)
1847  return false;
1848 
1849  char *new_str = NULL;
1850  bool rc = false;
1851  if (mutt_str_asprintf(&new_str, "id:%s and (%s)", email_get_id(e), orig_str) < 0)
1852  return false;
1853 
1854  mutt_debug(LL_DEBUG2, "nm: checking if message is still queried: %s\n", new_str);
1855 
1856  notmuch_query_t *q = notmuch_query_create(db, new_str);
1857 
1858  switch (mdata->query_type)
1859  {
1860  case NM_QUERY_TYPE_MESGS:
1861  {
1862  notmuch_messages_t *messages = get_messages(q);
1863 
1864  if (!messages)
1865  return false;
1866 
1867  rc = notmuch_messages_valid(messages);
1868  notmuch_messages_destroy(messages);
1869  break;
1870  }
1871  case NM_QUERY_TYPE_THREADS:
1872  {
1873  notmuch_threads_t *threads = get_threads(q);
1874 
1875  if (!threads)
1876  return false;
1877 
1878  rc = notmuch_threads_valid(threads);
1879  notmuch_threads_destroy(threads);
1880  break;
1881  }
1882  }
1883 
1884  notmuch_query_destroy(q);
1885 
1886  mutt_debug(LL_DEBUG2, "nm: checking if message is still queried: %s = %s\n",
1887  new_str, rc ? "true" : "false");
1888 
1889  return rc;
1890 }
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:147
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:323
Log at debug level 2.
Definition: logging.h:41
Notmuch-specific Mailbox data -.
Default: Messages only.
void * mdata
Driver specific data.
Definition: mailbox.h:135
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:232
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:1194
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 1901 of file mutt_notmuch.c.

1903 {
1904  char buf[PATH_MAX];
1905  struct NmMboxData *mdata = nm_mdata_get(m);
1906  if (!mdata || !new_file)
1907  return -1;
1908 
1909  if (!old_file && e && e->edata)
1910  {
1911  email_get_fullpath(e, buf, sizeof(buf));
1912  old_file = buf;
1913  }
1914 
1915  int rc = rename_filename(m, old_file, new_file, e);
1916 
1917  nm_db_release(m);
1918  m->mtime.tv_sec = mutt_date_epoch();
1919  m->mtime.tv_nsec = 0;
1920  return rc;
1921 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
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:106
static char * email_get_fullpath(struct Email *e, char *buf, size_t buflen)
Get the full path of an email.
Definition: mutt_notmuch.c:335
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:171
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:135
#define PATH_MAX
Definition: mutt.h:50
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
void * edata
Driver-specific data.
Definition: email.h:106
+ 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 1926 of file mutt_notmuch.c.

1927 {
1928  struct UrlQuery *item = NULL;
1929  struct Url *url = NULL;
1930  char *db_filename = NULL, *db_query = NULL;
1931  notmuch_database_t *db = NULL;
1932  int rc = -1;
1933  int limit = C_NmDbLimit;
1934  mutt_debug(LL_DEBUG1, "nm: count\n");
1935 
1936  url = url_parse(mailbox_path(m));
1937  if (!url)
1938  {
1939  mutt_error(_("failed to parse notmuch uri: %s"), mailbox_path(m));
1940  goto done;
1941  }
1942 
1943  STAILQ_FOREACH(item, &url->query_strings, entries)
1944  {
1945  if (item->value && (strcmp(item->name, "query") == 0))
1946  db_query = item->value;
1947  else if (item->value && (strcmp(item->name, "limit") == 0))
1948  {
1949  // Try to parse the limit
1950  if (mutt_str_atoi(item->value, &limit) != 0)
1951  {
1952  mutt_error(_("failed to parse limit: %s"), item->value);
1953  goto done;
1954  }
1955  }
1956  }
1957 
1958  if (!db_query)
1959  goto done;
1960 
1961  db_filename = url->path;
1962  if (!db_filename)
1963  {
1964  if (C_NmDefaultUri)
1965  {
1967  db_filename = C_NmDefaultUri + NmUriProtocolLen;
1968  else
1969  db_filename = C_NmDefaultUri;
1970  }
1971  else if (C_Folder)
1972  db_filename = C_Folder;
1973  }
1974 
1975  /* don't be verbose about connection, as we're called from
1976  * sidebar/mailbox very often */
1977  db = nm_db_do_open(db_filename, false, false);
1978  if (!db)
1979  goto done;
1980 
1981  /* all emails */
1982  m->msg_count = count_query(db, db_query, limit);
1983  while (m->email_max < m->msg_count)
1984  mx_alloc_memory(m);
1985 
1986  // holder variable for extending query to unread/flagged
1987  char *qstr = NULL;
1988 
1989  // unread messages
1990  mutt_str_asprintf(&qstr, "( %s ) tag:%s", db_query, C_NmUnreadTag);
1991  m->msg_unread = count_query(db, qstr, limit);
1992  FREE(&qstr);
1993 
1994  // flagged messages
1995  mutt_str_asprintf(&qstr, "( %s ) tag:%s", db_query, C_NmFlaggedTag);
1996  m->msg_flagged = count_query(db, qstr, limit);
1997  FREE(&qstr);
1998 
1999  rc = (m->msg_new > 0);
2000 done:
2001  if (db)
2002  {
2003  nm_db_free(db);
2004  mutt_debug(LL_DEBUG1, "nm: count close DB\n");
2005  }
2006  url_free(&url);
2007 
2008  mutt_debug(LL_DEBUG1, "nm: count done [rc=%d]\n", rc);
2009  return rc;
2010 }
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:191
int msg_count
Total number of messages.
Definition: mailbox.h:90
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:75
notmuch_database_t * nm_db_do_open(const char *filename, bool writable, bool verbose)
Open a Notmuch database.
Definition: nm_db.c:83
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:91
void nm_db_free(notmuch_database_t *db)
decoupled way to close a Notmuch database
Definition: nm_db.c:188
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:92
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
void mx_alloc_memory(struct Mailbox *m)
Create storage for the emails.
Definition: mx.c:1166
#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:83
const int NmUriProtocolLen
Definition: mutt_notmuch.c:72
struct UrlQueryList query_strings
List of query strings.
Definition: url.h:74
int email_max
Number of pointers in emails.
Definition: mailbox.h:99
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:119
char * C_NmDefaultUri
Config: (notmuch) Path to the Notmuch database.
Definition: mutt_notmuch.c:76
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
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:84
Log at debug level 1.
Definition: logging.h:40
int msg_new
Number of new messages.
Definition: mailbox.h:94
#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:1194
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 2020 of file mutt_notmuch.c.

2021 {
2022  notmuch_database_t *db = NULL;
2023  notmuch_status_t st;
2024  notmuch_message_t *msg = NULL;
2025  int rc = -1;
2026  struct NmMboxData *mdata = nm_mdata_get(m);
2027 
2028  if (!path || !mdata || (access(path, F_OK) != 0))
2029  return 0;
2030  db = nm_db_get(m, true);
2031  if (!db)
2032  return -1;
2033 
2034  mutt_debug(LL_DEBUG1, "nm: record message: %s\n", path);
2035  int trans = nm_db_trans_begin(m);
2036  if (trans < 0)
2037  goto done;
2038 
2039 #ifdef HAVE_NOTMUCH_DATABASE_INDEX_FILE
2040  st = notmuch_database_index_file(db, path, NULL, &msg);
2041 #else
2042  st = notmuch_database_add_message(db, path, &msg);
2043 #endif
2044 
2045  if ((st != NOTMUCH_STATUS_SUCCESS) && (st != NOTMUCH_STATUS_DUPLICATE_MESSAGE_ID))
2046  {
2047  mutt_debug(LL_DEBUG1, "nm: failed to add '%s' [st=%d]\n", path, (int) st);
2048  goto done;
2049  }
2050 
2051  if ((st == NOTMUCH_STATUS_SUCCESS) && msg)
2052  {
2053  notmuch_message_maildir_flags_to_tags(msg);
2054  if (e)
2055  {
2056  char *tags = driver_tags_get(&e->tags);
2057  update_tags(msg, tags);
2058  FREE(&tags);
2059  }
2060  if (C_NmRecordTags)
2062  }
2063 
2064  rc = 0;
2065 done:
2066  if (msg)
2067  notmuch_message_destroy(msg);
2068  if (trans == 1)
2069  nm_db_trans_end(m);
2070 
2071  nm_db_release(m);
2072  return rc;
2073 }
int nm_db_trans_begin(struct Mailbox *m)
Start a Notmuch database transaction.
Definition: nm_db.c:204
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:147
int nm_db_trans_end(struct Mailbox *m)
End a database transaction.
Definition: nm_db.c:226
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:171
void * mdata
Driver specific data.
Definition: mailbox.h:135
struct TagList tags
For drivers that support server tagging.
Definition: email.h:102
char * driver_tags_get(struct TagList *list)
Get tags.
Definition: tags.c:142
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
Log at debug level 1.
Definition: logging.h:40
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:82
+ 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 2085 of file mutt_notmuch.c.

2086 {
2087  struct NmMboxData *mdata = nm_mdata_get(m);
2088  if (!mdata)
2089  return -1;
2090 
2091  notmuch_database_t *db = NULL;
2092  notmuch_tags_t *tags = NULL;
2093  const char *tag = NULL;
2094  int rc = -1;
2095 
2096  if (!(db = nm_db_get(m, false)) || !(tags = notmuch_database_get_all_tags(db)))
2097  goto done;
2098 
2099  *tag_count = 0;
2100  mutt_debug(LL_DEBUG1, "nm: get all tags\n");
2101 
2102  while (notmuch_tags_valid(tags))
2103  {
2104  tag = notmuch_tags_get(tags);
2105  /* Skip empty string */
2106  if (*tag)
2107  {
2108  if (tag_list)
2109  tag_list[*tag_count] = mutt_str_strdup(tag);
2110  (*tag_count)++;
2111  }
2112  notmuch_tags_move_to_next(tags);
2113  }
2114 
2115  rc = 0;
2116 done:
2117  if (tags)
2118  notmuch_tags_destroy(tags);
2119 
2120  nm_db_release(m);
2121 
2122  mutt_debug(LL_DEBUG1, "nm: get all tags done [rc=%d tag_count=%u]\n", rc, *tag_count);
2123  return rc;
2124 }
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:147
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:171
void * mdata
Driver specific data.
Definition: mailbox.h:135
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
Log at debug level 1.
Definition: logging.h:40
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()

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

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

Definition at line 2129 of file mutt_notmuch.c.

2130 {
2131  if (!a || (a->magic != MUTT_NOTMUCH) || !path)
2132  return NULL;
2133 
2134  return a;
2135 }
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()

static int nm_ac_add ( struct Account a,
struct Mailbox m 
)
static

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

Definition at line 2140 of file mutt_notmuch.c.

2141 {
2142  if (!a || !m || (m->magic != MUTT_NOTMUCH))
2143  return -1;
2144 
2145  if (a->adata)
2146  return 0;
2147 
2148  struct NmAccountData *adata = nm_adata_new();
2149  a->adata = adata;
2151 
2152  return 0;
2153 }
void nm_adata_free(void **ptr)
Release and clear storage in an NmAccountData structure.
Definition: mutt_notmuch.c:132
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
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:151
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 2158 of file mutt_notmuch.c.

2159 {
2160  if (init_mailbox(m) != 0)
2161  return -1;
2162 
2163  struct NmMboxData *mdata = nm_mdata_get(m);
2164  if (!mdata)
2165  return -1;
2166 
2167  mutt_debug(LL_DEBUG1, "nm: reading messages...[current count=%d]\n", m->msg_count);
2168 
2169  progress_reset(m);
2170 
2171  int rc = -1;
2172 
2173  notmuch_query_t *q = get_query(m, false);
2174  if (q)
2175  {
2176  rc = 0;
2177  switch (mdata->query_type)
2178  {
2179  case NM_QUERY_TYPE_MESGS:
2180  if (!read_mesgs_query(m, q, false))
2181  rc = -2;
2182  break;
2183  case NM_QUERY_TYPE_THREADS:
2184  if (!read_threads_query(m, q, false, get_limit(mdata)))
2185  rc = -2;
2186  break;
2187  }
2188  notmuch_query_destroy(q);
2189  }
2190 
2191  nm_db_release(m);
2192 
2193  m->mtime.tv_sec = mutt_date_epoch();
2194  m->mtime.tv_nsec = 0;
2195 
2196  mdata->oldmsgcount = 0;
2197 
2198  mutt_debug(LL_DEBUG1, "nm: reading messages... done [rc=%d, count=%d]\n", rc, m->msg_count);
2199  return rc;
2200 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
int msg_count
Total number of messages.
Definition: mailbox.h:90
static notmuch_query_t * get_query(struct Mailbox *m, bool writable)
Create a new query.
Definition: mutt_notmuch.c:597
static void progress_reset(struct Mailbox *m)
Reset the progress counter.
Definition: mutt_notmuch.c:825
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:106
static bool read_mesgs_query(struct Mailbox *m, notmuch_query_t *q, bool dedup)
Search for matching messages.
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:171
Default: Messages only.
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:135
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: mutt_notmuch.c:547
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
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:301
Log at debug level 1.
Definition: logging.h:40
#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 2212 of file mutt_notmuch.c.

2213 {
2214  if (!m)
2215  return -1;
2216 
2217  struct NmMboxData *mdata = nm_mdata_get(m);
2218  time_t mtime = 0;
2219  if (!mdata || (nm_db_get_mtime(m, &mtime) != 0))
2220  return -1;
2221 
2222  int new_flags = 0;
2223  bool occult = false;
2224 
2225  if (m->mtime.tv_sec >= mtime)
2226  {
2227  mutt_debug(LL_DEBUG2, "nm: check unnecessary (db=%lu mailbox=%lu)\n", mtime,
2228  m->mtime.tv_sec);
2229  return 0;
2230  }
2231 
2232  mutt_debug(LL_DEBUG1, "nm: checking (db=%lu mailbox=%lu)\n", mtime, m->mtime.tv_sec);
2233 
2234  notmuch_query_t *q = get_query(m, false);
2235  if (!q)
2236  goto done;
2237 
2238  mutt_debug(LL_DEBUG1, "nm: start checking (count=%d)\n", m->msg_count);
2239  mdata->oldmsgcount = m->msg_count;
2240  mdata->noprogress = true;
2241 
2242  for (int i = 0; i < m->msg_count; i++)
2243  {
2244  struct Email *e = m->emails[i];
2245  if (!e)
2246  break;
2247 
2248  e->active = false;
2249  }
2250 
2251  int limit = get_limit(mdata);
2252 
2253  notmuch_messages_t *msgs = get_messages(q);
2254 
2255  // TODO: Analyze impact of removing this version guard.
2256 #if LIBNOTMUCH_CHECK_VERSION(5, 0, 0)
2257  if (!msgs)
2258  return false;
2259 #elif LIBNOTMUCH_CHECK_VERSION(4, 3, 0)
2260  if (!msgs)
2261  goto done;
2262 #endif
2263 
2265 
2266  for (int i = 0; notmuch_messages_valid(msgs) && ((limit == 0) || (i < limit));
2267  notmuch_messages_move_to_next(msgs), i++)
2268  {
2269  notmuch_message_t *msg = notmuch_messages_get(msgs);
2270  struct Email *e = get_mutt_email(m, msg);
2271 
2272  if (!e)
2273  {
2274  /* new email */
2275  append_message(h, m, NULL, msg, false);
2276  notmuch_message_destroy(msg);
2277  continue;
2278  }
2279 
2280  /* message already exists, merge flags */
2281  e->active = true;
2282 
2283  /* Check to see if the message has moved to a different subdirectory.
2284  * If so, update the associated filename. */
2285  const char *new_file = get_message_last_filename(msg);
2286  char old_file[PATH_MAX];
2287  email_get_fullpath(e, old_file, sizeof(old_file));
2288 
2289  if (mutt_str_strcmp(old_file, new_file) != 0)
2290  update_message_path(e, new_file);
2291 
2292  if (!e->changed)
2293  {
2294  /* if the user hasn't modified the flags on this message, update the
2295  * flags we just detected. */
2296  struct Email e_tmp = { 0 };
2297  maildir_parse_flags(&e_tmp, new_file);
2298  maildir_update_flags(m, e, &e_tmp);
2299  }
2300 
2301  if (update_email_tags(e, msg) == 0)
2302  new_flags++;
2303 
2304  notmuch_message_destroy(msg);
2305  }
2306 
2307  nm_hcache_close(h);
2308 
2309  for (int i = 0; i < m->msg_count; i++)
2310  {
2311  struct Email *e = m->emails[i];
2312  if (!e)
2313  break;
2314 
2315  if (!e->active)
2316  {
2317  occult = true;
2318  break;
2319  }
2320  }
2321 
2322  if (m->msg_count > mdata->oldmsgcount)
2324 done:
2325  if (q)
2326  notmuch_query_destroy(q);
2327 
2328  nm_db_release(m);
2329 
2330  m->mtime.tv_sec = mutt_date_epoch();
2331  m->mtime.tv_nsec = 0;
2332 
2333  mutt_debug(LL_DEBUG1, "nm: ... check done [count=%d, new_flags=%d, occult=%d]\n",
2334  m->msg_count, new_flags, occult);
2335 
2336  return occult ? MUTT_REOPENED :
2337  (m->msg_count > mdata->oldmsgcount) ? MUTT_NEW_MAIL :
2338  new_flags ? MUTT_FLAGS : 0;
2339 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
int msg_count
Total number of messages.
Definition: mailbox.h:90
static notmuch_query_t * get_query(struct Mailbox *m, bool writable)
Create a new query.
Definition: mutt_notmuch.c:597
The envelope/body of an email.
Definition: email.h:37
bool maildir_update_flags(struct Mailbox *m, struct Email *e_old, struct Email *e_new)
Update the mailbox flags.
Definition: shared.c:1435
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:909
static const char * get_message_last_filename(notmuch_message_t *msg)
Get a message&#39;s last filename.
Definition: mutt_notmuch.c:808
int nm_db_get_mtime(struct Mailbox *m, time_t *mtime)
Get the database modification time.
Definition: nm_db.c:253
static void nm_hcache_close(header_cache_t *h)
Close the header cache.
Definition: mutt_notmuch.c:105
static int update_email_tags(struct Email *e, notmuch_message_t *msg)
Update the Email&#39;s tags from Notmuch.
Definition: mutt_notmuch.c:629
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:106
bool changed
Email has been edited.
Definition: email.h:48
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:335
Email list was changed.
Definition: mailbox.h:170
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:1216
Log at debug level 2.
Definition: logging.h:41
Notmuch-specific Mailbox data -.
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:171
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:135
static int get_limit(struct NmMboxData *mdata)
Get the database limit.
Definition: mutt_notmuch.c:547
bool active
Message is not to be removed.
Definition: email.h:59
#define PATH_MAX
Definition: mutt.h:50
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:232
static int update_message_path(struct Email *e, const char *path)
Set the path for a message.
Definition: mutt_notmuch.c:679
Log at debug level 1.
Definition: logging.h:40
static struct Email * get_mutt_email(struct Mailbox *m, notmuch_message_t *msg)
Get the Email of a Notmuch message.
Definition: mutt_notmuch.c:874
static header_cache_t * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: mutt_notmuch.c:92
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
void mailbox_changed(struct Mailbox *m, enum NotifyMailbox action)
Notify observers of a change to a Mailbox.
Definition: mailbox.c:171
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:

◆ 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 2344 of file mutt_notmuch.c.

2345 {
2346  if (!m)
2347  return -1;
2348 
2349  struct NmMboxData *mdata = nm_mdata_get(m);
2350  if (!mdata)
2351  return -1;
2352 
2353  int rc = 0;
2354  struct Progress progress;
2355  char *uri = mutt_str_strdup(mailbox_path(m));
2356  bool changed = false;
2357 
2358  mutt_debug(LL_DEBUG1, "nm: sync start\n");
2359 
2360  if (!m->quiet)
2361  {
2362  /* all is in this function so we don't use data->progress here */
2363  char msg[PATH_MAX];
2364  snprintf(msg, sizeof(msg), _("Writing %s..."), mailbox_path(m));
2365  mutt_progress_init(&progress, msg, MUTT_PROGRESS_WRITE, m->msg_count);
2366  }
2367 
2369 
2370  for (int i = 0; i < m->msg_count; i++)
2371  {
2372  char old_file[PATH_MAX], new_file[PATH_MAX];
2373  struct Email *e = m->emails[i];
2374  if (!e)
2375  break;
2376 
2377  struct NmEmailData *edata = e->edata;
2378 
2379  if (!m->quiet)
2380  mutt_progress_update(&progress, i, -1);
2381 
2382  *old_file = '\0';
2383  *new_file = '\0';
2384 
2385  if (edata->oldpath)
2386  {
2387  mutt_str_strfcpy(old_file, edata->oldpath, sizeof(old_file));
2388  old_file[sizeof(old_file) - 1] = '\0';
2389  mutt_debug(LL_DEBUG2, "nm: fixing obsolete path '%s'\n", old_file);
2390  }
2391  else
2392  email_get_fullpath(e, old_file, sizeof(old_file));
2393 
2394  mutt_buffer_strcpy(&m->pathbuf, edata->folder);
2395  m->magic = edata->magic;
2396  rc = mh_sync_mailbox_message(m, i, h);
2397  mutt_buffer_strcpy(&m->pathbuf, uri);
2398  m->magic = MUTT_NOTMUCH;
2399 
2400  if (rc)
2401  break;
2402 
2403  if (!e->deleted)
2404  email_get_fullpath(e, new_file, sizeof(new_file));
2405 
2406  if (e->deleted || (strcmp(old_file, new_file) != 0))
2407  {
2408  if (e->deleted && (remove_filename(m, old_file) == 0))
2409  changed = true;
2410  else if (*new_file && *old_file && (rename_filename(m, old_file, new_file, e) == 0))
2411  changed = true;
2412  }
2413 
2414  FREE(&edata->oldpath);
2415  }
2416 
2417  mutt_buffer_strcpy(&m->pathbuf, uri);
2418  m->magic = MUTT_NOTMUCH;
2419 
2420  nm_db_release(m);
2421 
2422  if (changed)
2423  {
2424  m->mtime.tv_sec = mutt_date_epoch();
2425  m->mtime.tv_nsec = 0;
2426  }
2427 
2428  nm_hcache_close(h);
2429 
2430  FREE(&uri);
2431  mutt_debug(LL_DEBUG1, "nm: .... sync done [rc=%d]\n", rc);
2432  return rc;
2433 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
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:42
static void nm_hcache_close(header_cache_t *h)
Close the header cache.
Definition: mutt_notmuch.c:105
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:106
#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:335
A progress bar.
Definition: progress.h:49
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:41
Notmuch-specific Mailbox data -.
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
int nm_db_release(struct Mailbox *m)
Close the Notmuch database.
Definition: nm_db.c:171
char * folder
Location of the Email.
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:135
#define PATH_MAX
Definition: mutt.h:50
Notmuch-specific Email data -.
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
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:51
bool quiet
Inhibit status messages?
Definition: mailbox.h:117
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
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
Log at debug level 1.
Definition: logging.h:40
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
bool deleted
Email is deleted.
Definition: email.h:45
void * edata
Driver-specific data.
Definition: email.h:106
static header_cache_t * nm_hcache_open(struct Mailbox *m)
Open a header cache.
Definition: mutt_notmuch.c:92
#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:82
int mh_sync_mailbox_message(struct Mailbox *m, int msgno, header_cache_t *hc)
Save changes to the mailbox.
Definition: shared.c:1342
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 2440 of file mutt_notmuch.c.

2441 {
2442  return 0;
2443 }

◆ 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 2448 of file mutt_notmuch.c.

2449 {
2450  if (!m || !m->emails || (msgno >= m->msg_count) || !msg)
2451  return -1;
2452 
2453  struct Email *e = m->emails[msgno];
2454  if (!e)
2455  return -1;
2456 
2457  char path[PATH_MAX];
2458  char *folder = nm_email_get_folder(e);
2459 
2460  snprintf(path, sizeof(path), "%s/%s", folder, e->path);
2461 
2462  msg->fp = fopen(path, "r");
2463  if (!msg->fp && (errno == ENOENT) &&
2464  ((m->magic == MUTT_MAILDIR) || (m->magic == MUTT_NOTMUCH)))
2465  {
2466  msg->fp = maildir_open_find_message(folder, e->path, NULL);
2467  }
2468 
2469  if (!msg->fp)
2470  return -1;
2471 
2472  return 0;
2473 }
struct Email ** emails
Array of Emails.
Definition: mailbox.h:98
int msg_count
Total number of messages.
Definition: mailbox.h:90
The envelope/body of an email.
Definition: email.h:37
char * nm_email_get_folder(struct Email *e)
Get the folder for a Email.
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
FILE * maildir_open_find_message(const char *folder, const char *msg, char **newname)
Find a new.
Definition: shared.c:1481
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:50
#define PATH_MAX
Definition: mutt.h:50
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:53
char * path
Path of Email (for local Mailboxes)
Definition: email.h:91
FILE * fp
pointer to the message data
Definition: mx.h:83
int msgno
Number displayed to the user.
Definition: email.h:86
+ 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 2479 of file mutt_notmuch.c.

2480 {
2481  mutt_error(_("Can't write to virtual folder"));
2482  return -1;
2483 }
#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 2488 of file mutt_notmuch.c.

2489 {
2490  if (!msg)
2491  return -1;
2492  mutt_file_fclose(&(msg->fp));
2493  return 0;
2494 }
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
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 2499 of file mutt_notmuch.c.

2500 {
2501  *buf = '\0';
2502  if (mutt_get_field("Add/remove labels: ", buf, buflen, MUTT_NM_TAG) != 0)
2503  return -1;
2504  return 1;
2505 }
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:92
#define MUTT_NM_TAG
Notmuch tag +/- mode.
Definition: mutt.h:73

◆ 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 2510 of file mutt_notmuch.c.

2511 {
2512  if (!m)
2513  return -1;
2514 
2515  struct NmMboxData *mdata = nm_mdata_get(m);
2516  if (!buf || (*buf == '\0') || !mdata)
2517  return -1;
2518 
2519  notmuch_database_t *db = NULL;
2520  notmuch_message_t *msg = NULL;
2521  int rc = -1;
2522 
2523  if (!(db = nm_db_get(m, true)) || !(msg = get_nm_message(db, e)))
2524  goto done;
2525 
2526  mutt_debug(LL_DEBUG1, "nm: tags modify: '%s'\n", buf);
2527 
2528  update_tags(msg, buf);
2529  update_email_flags(m, e, buf);
2530  update_email_tags(e, msg);
2531  mutt_set_header_color(m, e);
2532 
2533  rc = 0;
2534  e->changed = true;
2535 done:
2536  nm_db_release(m);
2537  if (e->changed)
2538  {
2539  m->mtime.tv_sec = mutt_date_epoch();
2540  m->mtime.tv_nsec = 0;
2541  }
2542  mutt_debug(LL_DEBUG1, "nm: tags modify done [rc=%d]\n", rc);
2543  return rc;
2544 }
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
notmuch_database_t * nm_db_get(struct Mailbox *m, bool writable)
Get the Notmuch database.
Definition: nm_db.c:147
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:629
struct timespec mtime
Time Mailbox was last changed.
Definition: mailbox.h:106
bool changed
Email has been edited.
Definition: email.h:48
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:171
long tv_nsec
Definition: file.h:48
void * mdata
Driver specific data.
Definition: mailbox.h:135
struct NmMboxData * nm_mdata_get(struct Mailbox *m)
Get the Notmuch Mailbox data.
Definition: mutt_notmuch.c:232
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:3921
Log at debug level 1.
Definition: logging.h:40
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 2549 of file mutt_notmuch.c.

2550 {
2551  if (!path || !mutt_str_startswith(path, NmUriProtocol, CASE_IGNORE))
2552  return MUTT_UNKNOWN;
2553 
2554  return MUTT_NOTMUCH;
2555 }
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:46
const char NmUriProtocol[]
Definition: mutt_notmuch.c:71
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()

static int nm_path_canon ( char *  buf,
size_t  buflen 
)
static

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

Definition at line 2560 of file mutt_notmuch.c.

2561 {
2562  if (!buf)
2563  return -1;
2564 
2565  return 0;
2566 }

◆ nm_path_pretty()

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

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

Definition at line 2571 of file mutt_notmuch.c.

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

◆ nm_path_parent()

static int nm_path_parent ( char *  buf,
size_t  buflen 
)
static

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

Definition at line 2580 of file mutt_notmuch.c.

2581 {
2582  /* Succeed, but don't do anything, for now */
2583  return 0;
2584 }

Variable Documentation

◆ NmUriProtocol

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

Definition at line 71 of file mutt_notmuch.c.

◆ NmUriProtocolLen

const int NmUriProtocolLen = sizeof(NmUriProtocol) - 1

Definition at line 72 of file mutt_notmuch.c.

◆ C_NmDbLimit

int C_NmDbLimit

Config: (notmuch) Default limit for Notmuch queries.

Definition at line 75 of file mutt_notmuch.c.

◆ C_NmDefaultUri

char* C_NmDefaultUri

Config: (notmuch) Path to the Notmuch database.

Definition at line 76 of file mutt_notmuch.c.

◆ C_NmExcludeTags

char* C_NmExcludeTags

Config: (notmuch) Exclude messages with these tags.

Definition at line 77 of file mutt_notmuch.c.

◆ C_NmOpenTimeout

int C_NmOpenTimeout

Config: (notmuch) Database timeout.

Definition at line 78 of file mutt_notmuch.c.

◆ C_NmQueryType

char* C_NmQueryType

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

Definition at line 79 of file mutt_notmuch.c.

◆ C_NmQueryWindowCurrentPosition

int C_NmQueryWindowCurrentPosition

Config: (notmuch) Position of current search window.

Definition at line 80 of file mutt_notmuch.c.

◆ C_NmQueryWindowTimebase

char* C_NmQueryWindowTimebase

Config: (notmuch) Units for the time duration.

Definition at line 81 of file mutt_notmuch.c.

◆ C_NmRecordTags

char* C_NmRecordTags

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

Definition at line 82 of file mutt_notmuch.c.

◆ C_NmUnreadTag

char* C_NmUnreadTag

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

Definition at line 83 of file mutt_notmuch.c.

◆ C_NmFlaggedTag

char* C_NmFlaggedTag

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

Definition at line 84 of file mutt_notmuch.c.

◆ C_NmRepliedTag

char* C_NmRepliedTag

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

Definition at line 85 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:585
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()
static struct Account * nm_ac_find(struct Account *a, const char *path)
Find an Account that matches a Mailbox path - Implements MxOps::ac_find()
static int nm_path_canon(char *buf, size_t buflen)
Canonicalise a Mailbox path - Implements MxOps::path_canon()
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_ac_add(struct Account *a, struct Mailbox *m)
Add a Mailbox to an Account - Implements MxOps::ac_add()
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()
static int nm_path_pretty(char *buf, size_t buflen, const char *folder)
Abbreviate a Mailbox path - Implements MxOps::path_pretty()
static int nm_mbox_check_stats(struct Mailbox *m, int flags)
Check the Mailbox statistics - Implements MxOps::check_stats()
static int nm_path_parent(char *buf, size_t buflen)
Find the parent of a Mailbox path - Implements MxOps::path_parent()
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 2590 of file mutt_notmuch.c.