NeoMutt  2021-10-22-8-g9cb437
Teaching an old dog new tricks
context.h File Reference

The "currently-open" mailbox. More...

#include <stdbool.h>
#include <sys/types.h>
+ Include dependency graph for context.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  Context
 The "current" mailbox. More...
struct  EventContext
 An Event that happened to an Context. More...


 Types of Context Event. More...


void ctx_free (struct Context **ptr)
 Free a Context. More...
int ctx_mailbox_observer (struct NotifyCallback *nc)
 Notification that a Mailbox has changed - Implements observer_t -. More...
struct Contextctx_new (struct Mailbox *m)
 Create a new Context. More...
void ctx_update (struct Context *ctx)
 Update the Context's message counts. More...
bool ctx_has_limit (const struct Context *ctx)
 Is a limit active? More...
struct Mailboxctx_mailbox (struct Context *ctx)
 Wrapper to get the mailbox in a Context, or NULL. More...
bool message_is_tagged (struct Email *e)
 Is a message in the index tagged (and within limit) More...
struct Emailmutt_get_virt_email (struct Mailbox *m, int vnum)
 Get a virtual Email. More...
int el_add_tagged (struct EmailList *el, struct Context *ctx, struct Email *e, bool use_tagged)
 Get a list of the tagged Emails. More...

Detailed Description

The "currently-open" mailbox.

  • Richard Russon

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

Definition in file context.h.

Enumeration Type Documentation

◆ NotifyContext

Types of Context Event.

Observers of NT_CONTEXT will be passed an EventContext.


The Context has been opened.


The Context is about to be destroyed.


The Context has changed.

Definition at line 58 of file context.h.

59 {
63 };
The Context is about to be destroyed.
Definition: context.h:61
The Context has been opened.
Definition: context.h:60
The Context has changed.
Definition: context.h:62

Function Documentation

◆ ctx_free()

void ctx_free ( struct Context **  ptr)

Free a Context.

[out]ptrContext to free

Definition at line 49 of file context.c.

50 {
51  if (!ptr || !*ptr)
52  return;
54  struct Context *ctx = *ptr;
56  struct EventContext ev_c = { ctx };
57  mutt_debug(LL_NOTIFY, "NT_CONTEXT_DELETE: %p\n", ctx);
60  if (ctx->mailbox)
65  FREE(&ctx->pattern);
68  FREE(&ctx);
69  *ptr = NULL;
70 }
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:1038
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
int ctx_mailbox_observer(struct NotifyCallback *nc)
Notification that a Mailbox has changed - Implements observer_t -.
Definition: context.c:313
Log of notifications.
Definition: logging.h:45
#define FREE(x)
Definition: memory.h:40
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:228
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:171
void notify_free(struct Notify **ptr)
Free a notification handler.
Definition: notify.c:73
void mutt_thread_ctx_free(struct ThreadsContext **tctx)
Finalize a threading context.
Definition: mutt_thread.c:369
Context has changed, NotifyContext, EventContext.
Definition: notify_type.h:43
The "current" mailbox.
Definition: context.h:38
char * pattern
Limit pattern string.
Definition: context.h:40
struct Mailbox * mailbox
Current Mailbox.
Definition: context.h:49
struct ThreadsContext * threads
Threads context.
Definition: context.h:42
struct PatternList * limit_pattern
Compiled limit pattern.
Definition: context.h:41
struct Notify * notify
Notifications: NotifyContext, EventContext.
Definition: context.h:50
An Event that happened to an Context.
Definition: context.h:69
struct Context * ctx
The Context this Event relates to.
Definition: context.h:70
struct Notify * notify
Notifications: NotifyMailbox, EventMailbox.
Definition: mailbox.h:148
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ctx_new()

struct Context* ctx_new ( struct Mailbox m)

Create a new Context.

Return values
ptrNew Context

Definition at line 77 of file context.c.

78 {
79  if (!m)
80  return NULL;
82  struct Context *ctx = mutt_mem_calloc(1, sizeof(struct Context));
84  ctx->notify = notify_new();
86  struct EventContext ev_c = { ctx };
87  mutt_debug(LL_NOTIFY, "NT_CONTEXT_ADD: %p\n", ctx);
89  // If the Mailbox is closed, ctx->mailbox must be set to NULL
92  ctx->mailbox = m;
94  ctx->msg_in_pager = -1;
95  ctx->collapsed = false;
96  ctx_update(ctx);
98  return ctx;
99 }
void ctx_update(struct Context *ctx)
Update the Context's message counts.
Definition: context.c:125
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
struct Notify * notify_new(void)
Create a new notifications handler.
Definition: notify.c:60
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:189
void notify_set_parent(struct Notify *notify, struct Notify *parent)
Set the parent notification handler.
Definition: notify.c:93
struct ThreadsContext * mutt_thread_ctx_init(struct Mailbox *m)
Initialize a threading context.
Definition: mutt_thread.c:356
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:48
int msg_in_pager
Message currently shown in the pager.
Definition: context.h:43
bool collapsed
Are all threads collapsed?
Definition: context.h:47
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct Notify * notify
Notifications handler.
Definition: neomutt.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ctx_update()

void ctx_update ( struct Context ctx)

Update the Context's message counts.


this routine is called to update the counts in the context structure

Definition at line 125 of file context.c.

126 {
127  if (!ctx || !ctx->mailbox)
128  return;
130  struct Mailbox *m = ctx->mailbox;
133  mutt_hash_free(&m->id_hash);
135  /* reset counters */
136  m->msg_unread = 0;
137  m->msg_flagged = 0;
138  m->msg_new = 0;
139  m->msg_deleted = 0;
140  m->msg_tagged = 0;
141  m->vcount = 0;
142  m->changed = false;
146  const bool c_score = cs_subset_bool(NeoMutt->sub, "score");
147  struct Email *e = NULL;
148  for (int msgno = 0; msgno < m->msg_count; msgno++)
149  {
150  e = m->emails[msgno];
151  if (!e)
152  continue;
154  if (WithCrypto)
155  {
156  /* NOTE: this _must_ be done before the check for mailcap! */
157  e->security = crypt_query(e->body);
158  }
160  if (ctx_has_limit(ctx))
161  {
162  e->vnum = -1;
163  }
164  else
165  {
166  m->v2r[m->vcount] = msgno;
167  e->vnum = m->vcount++;
168  }
169  e->msgno = msgno;
171  if (e->env->supersedes)
172  {
173  struct Email *e2 = NULL;
175  if (!m->id_hash)
176  m->id_hash = mutt_make_id_hash(m);
178  e2 = mutt_hash_find(m->id_hash, e->env->supersedes);
179  if (e2)
180  {
181  e2->superseded = true;
182  if (c_score)
183  mutt_score_message(ctx->mailbox, e2, true);
184  }
185  }
187  /* add this message to the hash tables */
188  if (m->id_hash && e->env->message_id)
190  if (m->subj_hash && e->env->real_subj)
192  mutt_label_hash_add(m, e);
194  if (c_score)
195  mutt_score_message(ctx->mailbox, e, false);
197  if (e->changed)
198  m->changed = true;
199  if (e->flagged)
200  m->msg_flagged++;
201  if (e->deleted)
202  m->msg_deleted++;
203  if (e->tagged)
204  m->msg_tagged++;
205  if (!e->read)
206  {
207  m->msg_unread++;
208  if (!e->old)
209  m->msg_new++;
210  }
211  }
213  /* rethread from scratch */
214  mutt_sort_headers(ctx->mailbox, ctx->threads, true, &ctx->vsize);
215 }
bool ctx_has_limit(const struct Context *ctx)
Is a limit active?
Definition: context.c:433
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:692
struct HashElem * mutt_hash_insert(struct HashTable *table, const char *strkey, void *data)
Add a new element to the Hash Table (with string keys)
Definition: hash.c:327
void * mutt_hash_find(const struct HashTable *table, const char *strkey)
Find the HashElem data in a Hash Table element using a key.
Definition: hash.c:354
void mutt_hash_free(struct HashTable **ptr)
Free a hash table.
Definition: hash.c:449
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_label_hash_add(struct Mailbox *m, struct Email *e)
Add a message's labels to the Hash Table.
Definition: mutt_header.c:379
void mutt_clear_threads(struct ThreadsContext *tctx)
Clear the threading of message in a mailbox.
Definition: mutt_thread.c:714
struct HashTable * mutt_make_id_hash(struct Mailbox *m)
Create a Hash Table for message-ids.
Definition: mutt_thread.c:1658
#define WithCrypto
Definition: lib.h:113
void mutt_score_message(struct Mailbox *m, struct Email *e, bool upd_mbox)
Apply scoring to an email.
Definition: score.c:160
void mutt_sort_headers(struct Mailbox *m, struct ThreadsContext *threads, bool init, off_t *vsize)
Sort emails by their headers.
Definition: sort.c:356
off_t vsize
Size (in bytes) of the messages shown.
Definition: context.h:39
The envelope/body of an email.
Definition: email.h:37
bool read
Email is read.
Definition: email.h:48
struct Envelope * env
Envelope information.
Definition: email.h:66
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
struct Body * body
List of MIME parts.
Definition: email.h:67
bool old
Email is seen, but unread.
Definition: email.h:47
bool changed
Email has been edited.
Definition: email.h:75
bool flagged
Marked important?
Definition: email.h:45
int vnum
Virtual message number.
Definition: email.h:114
int msgno
Number displayed to the user.
Definition: email.h:111
bool deleted
Email is deleted.
Definition: email.h:76
bool tagged
Email is tagged.
Definition: email.h:107
bool superseded
Got superseded?
Definition: email.h:50
char * supersedes
Supersedes header.
Definition: envelope.h:72
char * message_id
Message ID.
Definition: envelope.h:71
char * real_subj
Offset of the real subject.
Definition: envelope.h:69
A mailbox.
Definition: mailbox.h:82
int vcount
The number of virtual messages.
Definition: mailbox.h:102
bool changed
Mailbox has been modified.
Definition: mailbox.h:114
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:101
int msg_new
Number of new messages.
Definition: mailbox.h:95
int msg_count
Total number of messages.
Definition: mailbox.h:91
struct HashTable * subj_hash
Hash Table by subject.
Definition: mailbox.h:128
struct Email ** emails
Array of Emails.
Definition: mailbox.h:99
struct HashTable * id_hash
Hash Table by msg id.
Definition: mailbox.h:127
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:97
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ctx_has_limit()

bool ctx_has_limit ( const struct Context ctx)

Is a limit active?

Return values
trueA limit is active
falseNo limit is active

Definition at line 433 of file context.c.

434 {
435  return ctx && ctx->pattern;
436 }
+ Here is the caller graph for this function:

◆ ctx_mailbox()

struct Mailbox* ctx_mailbox ( struct Context ctx)

Wrapper to get the mailbox in a Context, or NULL.

Return values
ptrThe mailbox in the Context
NULLContext is NULL or doesn't have a mailbox

Definition at line 444 of file context.c.

445 {
446  return ctx ? ctx->mailbox : NULL;
447 }
+ Here is the caller graph for this function:

◆ message_is_tagged()

bool message_is_tagged ( struct Email e)

Is a message in the index tagged (and within limit)

Return values
trueThe message is both tagged and within limit

If a limit is in effect, the message must be visible within it.

Definition at line 350 of file context.c.

351 {
352  return e->visible && e->tagged;
353 }
bool visible
Is this message part of the view?
Definition: email.h:121
+ Here is the caller graph for this function:

◆ mutt_get_virt_email()

struct Email* mutt_get_virt_email ( struct Mailbox m,
int  vnum 

Get a virtual Email.

vnumVirtual index number
Return values
NULLNo Email selected, or bad index values

This safely gets the result of the following:

  • mailbox->emails[mailbox->v2r[vnum]]

Definition at line 412 of file context.c.

413 {
414  if (!m || !m->emails || !m->v2r)
415  return NULL;
417  if ((vnum < 0) || (vnum >= m->vcount))
418  return NULL;
420  int inum = m->v2r[vnum];
421  if ((inum < 0) || (inum >= m->msg_count))
422  return NULL;
424  return m->emails[inum];
425 }
+ Here is the caller graph for this function:

◆ el_add_tagged()

int el_add_tagged ( struct EmailList *  el,
struct Context ctx,
struct Email e,
bool  use_tagged 

Get a list of the tagged Emails.

elEmpty EmailList to populate
ctxCurrent Mailbox
eCurrent Email
use_taggedUse tagged Emails
Return values
numNumber of selected emails

Definition at line 364 of file context.c.

365 {
366  int count = 0;
368  if (use_tagged)
369  {
370  if (!ctx || !ctx->mailbox || !ctx->mailbox->emails)
371  return -1;
373  struct Mailbox *m = ctx->mailbox;
374  for (size_t i = 0; i < m->msg_count; i++)
375  {
376  e = m->emails[i];
377  if (!e)
378  break;
379  if (!message_is_tagged(e))
380  continue;
382  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
383  en->email = e;
384  STAILQ_INSERT_TAIL(el, en, entries);
385  count++;
386  }
387  }
388  else
389  {
390  if (!e)
391  return -1;
393  struct EmailNode *en = mutt_mem_calloc(1, sizeof(*en));
394  en->email = e;
395  STAILQ_INSERT_TAIL(el, en, entries);
396  count = 1;
397  }
399  return count;
400 }
bool message_is_tagged(struct Email *e)
Is a message in the index tagged (and within limit)
Definition: context.c:350
#define STAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:389
List of Emails.
Definition: email.h:131
struct Email * email
Email in the list.
Definition: email.h:132
+ Here is the call graph for this function:
+ Here is the caller graph for this function: