NeoMutt  2022-04-29-247-gc6aae8
Teaching an old dog new tricks
DOXYGEN
dlg_index.c File Reference

Index Dialog. More...

#include "config.h"
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "lib.h"
#include "color/lib.h"
#include "menu/lib.h"
#include "pager/lib.h"
#include "pattern/lib.h"
#include "format_flags.h"
#include "functions.h"
#include "hdrline.h"
#include "hook.h"
#include "keymap.h"
#include "mutt_globals.h"
#include "mutt_logging.h"
#include "mutt_mailbox.h"
#include "mutt_thread.h"
#include "mview.h"
#include "mx.h"
#include "opcodes.h"
#include "options.h"
#include "private_data.h"
#include "protos.h"
#include "shared_data.h"
#include "sort.h"
#include "status.h"
#include "notmuch/lib.h"
#include "nntp/lib.h"
#include "nntp/adata.h"
#include "nntp/mdata.h"
#include "monitor.h"
#include "sidebar/lib.h"
+ Include dependency graph for dlg_index.c:

Go to the source code of this file.

Functions

bool check_acl (struct Mailbox *m, AclFlags acl, const char *msg)
 Check the ACLs for a function. More...
 
void collapse_all (struct MailboxView *mv, struct Menu *menu, int toggle)
 Collapse/uncollapse all threads. More...
 
static void uncollapse_thread (struct Mailbox *m, int index)
 Open a collapsed thread. More...
 
int ci_next_undeleted (struct Mailbox *m, int msgno, bool uncollapse)
 Find the next undeleted email. More...
 
int ci_previous_undeleted (struct Mailbox *m, int msgno, bool uncollapse)
 Find the previous undeleted email. More...
 
int ci_first_message (struct Mailbox *m)
 Get index of first new message. More...
 
void resort_index (struct MailboxView *mv, struct Menu *menu)
 Resort the index. More...
 
static void update_index_threaded (struct MailboxView *mv, enum MxStatus check, int oldcount)
 Update the index (if threaded) More...
 
static void update_index_unthreaded (struct MailboxView *mv, enum MxStatus check)
 Update the index (if unthreaded) More...
 
void update_index (struct Menu *menu, struct MailboxView *mv, enum MxStatus check, int oldcount, const struct IndexSharedData *shared)
 Update the index. More...
 
void mutt_update_index (struct Menu *menu, struct MailboxView *mv, enum MxStatus check, int oldcount, struct IndexSharedData *shared)
 Update the index. More...
 
static int index_mailbox_observer (struct NotifyCallback *nc)
 Notification that a Mailbox has changed - Implements observer_t -. More...
 
void change_folder_mailbox (struct Menu *menu, struct Mailbox *m, int *oldcount, struct IndexSharedData *shared, bool read_only)
 Change to a different Mailbox by pointer. More...
 
struct Mailboxchange_folder_notmuch (struct Menu *menu, char *buf, int buflen, int *oldcount, struct IndexSharedData *shared, bool read_only)
 Change to a different Notmuch Mailbox by string. More...
 
void change_folder_string (struct Menu *menu, char *buf, size_t buflen, int *oldcount, struct IndexSharedData *shared, bool read_only)
 Change to a different Mailbox by string. More...
 
void index_make_entry (struct Menu *menu, char *buf, size_t buflen, int line)
 Format a menu item for the index list - Implements Menu::make_entry() -. More...
 
struct AttrColorindex_color (struct Menu *menu, int line)
 Calculate the colour for a line of the index - Implements Menu::color() -. More...
 
void mutt_draw_statusline (struct MuttWindow *win, int cols, const char *buf, size_t buflen)
 Draw a highlighted status bar. More...
 
struct Mailboxmutt_index_menu (struct MuttWindow *dlg, struct Mailbox *m_init)
 Display a list of emails. More...
 
void mutt_set_header_color (struct Mailbox *m, struct Email *e)
 Select a colour for a message. More...
 
struct MuttWindowindex_pager_init (void)
 Allocate the Windows for the Index/Pager. More...
 
void dlg_change_folder (struct MuttWindow *dlg, struct Mailbox *m)
 Change the current folder, cautiously. More...
 

Variables

static const struct Mapping IndexHelp []
 Help Bar for the Index dialog. More...
 
const struct Mapping IndexNewsHelp []
 Help Bar for the News Index dialog. More...
 

Detailed Description

Index Dialog.

Authors
  • Michael R. Elkins
  • R Primus

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/.

Definition in file dlg_index.c.

Function Documentation

◆ check_acl()

bool check_acl ( struct Mailbox m,
AclFlags  acl,
const char *  msg 
)

Check the ACLs for a function.

Parameters
mMailbox
aclACL, see AclFlags
msgError message for failure
Return values
trueThe function is permitted

Definition at line 143 of file dlg_index.c.

144{
145 if (!m)
146 return false;
147
148 if (!(m->rights & acl))
149 {
150 /* L10N: %s is one of the CHECK_ACL entries below. */
151 mutt_error(_("%s: Operation not permitted by ACL"), msg);
152 return false;
153 }
154
155 return true;
156}
#define mutt_error(...)
Definition: logging.h:87
#define _(a)
Definition: message.h:28
AclFlags rights
ACL bits, see AclFlags.
Definition: mailbox.h:117
+ Here is the caller graph for this function:

◆ collapse_all()

void collapse_all ( struct MailboxView mv,
struct Menu menu,
int  toggle 
)

Collapse/uncollapse all threads.

Parameters
mvMailbox View
menucurrent menu
toggletoggle collapsed state

This function is called by the OP_MAIN_COLLAPSE_ALL command and on folder enter if the $collapse_all option is set. In the first case, the toggle parameter is 1 to actually toggle collapsed/uncollapsed state on all threads. In the second case, the toggle parameter is 0, actually turning this function into a one-way collapse.

Definition at line 170 of file dlg_index.c.

171{
172 if (!mv || !mv->mailbox || (mv->mailbox->msg_count == 0) || !menu)
173 return;
174
175 struct Email *e_cur = mutt_get_virt_email(mv->mailbox, menu_get_index(menu));
176 if (!e_cur)
177 return;
178
179 int final;
180
181 /* Figure out what the current message would be after folding / unfolding,
182 * so that we can restore the cursor in a sane way afterwards. */
183 if (e_cur->collapsed && toggle)
184 final = mutt_uncollapse_thread(e_cur);
185 else if (mutt_thread_can_collapse(e_cur))
186 final = mutt_collapse_thread(e_cur);
187 else
188 final = e_cur->vnum;
189
190 if (final == -1)
191 return;
192
193 struct Email *base = mutt_get_virt_email(mv->mailbox, final);
194 if (!base)
195 return;
196
197 /* Iterate all threads, perform collapse/uncollapse as needed */
198 mv->collapsed = toggle ? !mv->collapsed : true;
200
201 /* Restore the cursor */
203 menu->max = mv->mailbox->vcount;
204 for (int i = 0; i < mv->mailbox->vcount; i++)
205 {
206 struct Email *e = mutt_get_virt_email(mv->mailbox, i);
207 if (!e)
208 break;
209 if (e->index == base->index)
210 {
211 menu_set_index(menu, i);
212 break;
213 }
214 }
215
217}
#define MENU_REDRAW_INDEX
Redraw the index.
Definition: lib.h:56
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition: menu.c:178
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition: menu.c:154
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition: menu.c:168
void mutt_thread_collapse(struct ThreadsContext *tctx, bool collapse)
Toggle collapse.
Definition: mutt_thread.c:1737
off_t mutt_set_vnum(struct Mailbox *m)
Set the virtual index number of all the messages in a mailbox.
Definition: mutt_thread.c:1363
bool mutt_thread_can_collapse(struct Email *e)
Check whether a thread can be collapsed.
Definition: mutt_thread.c:1765
#define mutt_uncollapse_thread(e)
Definition: mutt_thread.h:94
#define mutt_collapse_thread(e)
Definition: mutt_thread.h:93
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: mview.c:414
The envelope/body of an email.
Definition: email.h:37
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:120
int vnum
Virtual message number.
Definition: email.h:114
int index
The absolute (unsorted) message number.
Definition: email.h:110
bool collapsed
Are all threads collapsed?
Definition: mview.h:47
struct ThreadsContext * threads
Threads context.
Definition: mview.h:42
struct Mailbox * mailbox
Current Mailbox.
Definition: mview.h:49
int vcount
The number of virtual messages.
Definition: mailbox.h:99
int msg_count
Total number of messages.
Definition: mailbox.h:88
int max
Number of entries in the menu.
Definition: lib.h:71
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ uncollapse_thread()

static void uncollapse_thread ( struct Mailbox m,
int  index 
)
static

Open a collapsed thread.

Parameters
mMailbox
indexMessage number

Definition at line 224 of file dlg_index.c.

225{
226 struct Email *e = mutt_get_virt_email(m, index);
227 if (e && e->collapsed)
228 {
230 mutt_set_vnum(m);
231 }
232}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ci_next_undeleted()

int ci_next_undeleted ( struct Mailbox m,
int  msgno,
bool  uncollapse 
)

Find the next undeleted email.

Parameters
mMailbox
msgnoMessage number to start at
uncollapseOpen collapsed threads
Return values
>=0Message number of next undeleted email
-1No more undeleted messages

Definition at line 242 of file dlg_index.c.

243{
244 if (!m)
245 return -1;
246
247 int index = -1;
248
249 for (int i = msgno + 1; i < m->vcount; i++)
250 {
251 struct Email *e = mutt_get_virt_email(m, i);
252 if (!e)
253 continue;
254 if (!e->deleted)
255 {
256 index = i;
257 break;
258 }
259 }
260
261 if (uncollapse)
263
264 return index;
265}
static void uncollapse_thread(struct Mailbox *m, int index)
Open a collapsed thread.
Definition: dlg_index.c:224
bool deleted
Email is deleted.
Definition: email.h:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ci_previous_undeleted()

int ci_previous_undeleted ( struct Mailbox m,
int  msgno,
bool  uncollapse 
)

Find the previous undeleted email.

Parameters
mMailbox
msgnoMessage number to start at
uncollapseOpen collapsed threads
Return values
>=0Message number of next undeleted email
-1No more undeleted messages

Definition at line 275 of file dlg_index.c.

276{
277 if (!m)
278 return -1;
279
280 int index = -1;
281
282 for (int i = msgno - 1; i >= 0; i--)
283 {
284 struct Email *e = mutt_get_virt_email(m, i);
285 if (!e)
286 continue;
287 if (!e->deleted)
288 {
289 index = i;
290 break;
291 }
292 }
293
294 if (uncollapse)
296
297 return index;
298}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ci_first_message()

int ci_first_message ( struct Mailbox m)

Get index of first new message.

Parameters
mMailbox
Return values
numIndex of first new message

Return the index of the first new message, or failing that, the first unread message.

Definition at line 308 of file dlg_index.c.

309{
310 if (!m || (m->msg_count == 0))
311 return 0;
312
313 int old = -1;
314 for (int i = 0; i < m->vcount; i++)
315 {
316 struct Email *e = mutt_get_virt_email(m, i);
317 if (!e)
318 continue;
319 if (!e->read && !e->deleted)
320 {
321 if (!e->old)
322 return i;
323 if (old == -1)
324 old = i;
325 }
326 }
327 if (old != -1)
328 return old;
329
330 /* If `$use_threads` is not threaded and `$sort` is reverse, the latest
331 * message is first. Otherwise, the latest message is first if exactly
332 * one of `$use_threads` and `$sort` are reverse.
333 */
334 short c_sort = cs_subset_sort(m->sub, "sort");
335 if ((c_sort & SORT_MASK) == SORT_THREADS)
336 c_sort = cs_subset_sort(m->sub, "sort_aux");
337 bool reverse = false;
338 switch (mutt_thread_style())
339 {
340 case UT_FLAT:
341 reverse = c_sort & SORT_REVERSE;
342 break;
343 case UT_THREADS:
344 reverse = c_sort & SORT_REVERSE;
345 break;
346 case UT_REVERSE:
347 reverse = !(c_sort & SORT_REVERSE);
348 break;
349 default:
350 assert(false);
351 }
352
353 if (reverse || (m->vcount == 0))
354 return 0;
355
356 return m->vcount - 1;
357}
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
enum UseThreads mutt_thread_style(void)
Which threading style is active?
Definition: mutt_thread.c:89
@ UT_FLAT
Unthreaded.
Definition: mutt_thread.h:85
@ UT_THREADS
Normal threading (root above subthreads)
Definition: mutt_thread.h:86
@ UT_REVERSE
Reverse threading (subthreads above root)
Definition: mutt_thread.h:87
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:78
@ SORT_THREADS
Sort by email threads.
Definition: sort2.h:49
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:79
bool read
Email is read.
Definition: email.h:48
bool old
Email is seen, but unread.
Definition: email.h:47
struct ConfigSubset * sub
Inherited config items.
Definition: mailbox.h:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ resort_index()

void resort_index ( struct MailboxView mv,
struct Menu menu 
)

Resort the index.

Parameters
mvMailbox View
menuCurrent Menu

Definition at line 364 of file dlg_index.c.

365{
366 if (!mv || !mv->mailbox || !menu)
367 return;
368
369 struct Mailbox *m = mv->mailbox;
370 const int old_index = menu_get_index(menu);
371 struct Email *e_cur = mutt_get_virt_email(m, old_index);
372
373 int new_index = -1;
374 mutt_sort_headers(m, mv->threads, false, &mv->vsize);
375
376 /* Restore the current message */
377 for (int i = 0; i < m->vcount; i++)
378 {
379 struct Email *e = mutt_get_virt_email(m, i);
380 if (!e)
381 continue;
382 if (e == e_cur)
383 {
384 new_index = i;
385 break;
386 }
387 }
388
389 if (mutt_using_threads() && (old_index < 0))
390 new_index = mutt_parent_message(e_cur, false);
391
392 if (old_index < 0)
393 new_index = ci_first_message(m);
394
395 menu->max = m->vcount;
396 menu_set_index(menu, new_index);
398}
int ci_first_message(struct Mailbox *m)
Get index of first new message.
Definition: dlg_index.c:308
int mutt_parent_message(struct Email *e, bool find_root)
Find the parent of a message.
Definition: mutt_thread.c:1313
#define mutt_using_threads()
Definition: mutt_thread.h:100
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: mview.h:39
A mailbox.
Definition: mailbox.h:79
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_index_threaded()

static void update_index_threaded ( struct MailboxView mv,
enum MxStatus  check,
int  oldcount 
)
static

Update the index (if threaded)

Parameters
mvMailbox
checkFlags, e.g. MX_STATUS_REOPENED
oldcountHow many items are currently in the index

Definition at line 406 of file dlg_index.c.

407{
408 struct Email **save_new = NULL;
409 const bool lmt = mview_has_limit(mv);
410
411 struct Mailbox *m = mv->mailbox;
412 int num_new = MAX(0, m->msg_count - oldcount);
413
414 const bool c_uncollapse_new = cs_subset_bool(m->sub, "uncollapse_new");
415 /* save the list of new messages */
416 if ((check != MX_STATUS_REOPENED) && (oldcount > 0) &&
417 (lmt || c_uncollapse_new) && (num_new > 0))
418 {
419 save_new = mutt_mem_malloc(num_new * sizeof(struct Email *));
420 for (int i = oldcount; i < m->msg_count; i++)
421 save_new[i - oldcount] = m->emails[i];
422 }
423
424 /* Sort first to thread the new messages, because some patterns
425 * require the threading information.
426 *
427 * If the mailbox was reopened, need to rethread from scratch. */
428 mutt_sort_headers(m, mv->threads, (check == MX_STATUS_REOPENED), &mv->vsize);
429
430 if (lmt)
431 {
432 for (int i = 0; i < m->msg_count; i++)
433 {
434 struct Email *e = m->emails[i];
435
436 if ((e->limit_visited && e->visible) ||
438 MUTT_MATCH_FULL_ADDRESS, m, e, NULL))
439 {
440 /* vnum will get properly set by mutt_set_vnum(), which
441 * is called by mutt_sort_headers() just below. */
442 e->vnum = 1;
443 e->visible = true;
444 }
445 else
446 {
447 e->vnum = -1;
448 e->visible = false;
449 }
450
451 // mark email as visited so we don't re-apply the pattern next time
452 e->limit_visited = true;
453 }
454 /* Need a second sort to set virtual numbers and redraw the tree */
455 mutt_sort_headers(m, mv->threads, false, &mv->vsize);
456 }
457
458 /* uncollapse threads with new mail */
459 if (c_uncollapse_new)
460 {
461 if (check == MX_STATUS_REOPENED)
462 {
463 mv->collapsed = false;
465 mutt_set_vnum(m);
466 }
467 else if (oldcount > 0)
468 {
469 for (int j = 0; j < num_new; j++)
470 {
471 if (save_new[j]->visible)
472 {
473 mutt_uncollapse_thread(save_new[j]);
474 }
475 }
476 mutt_set_vnum(m);
477 }
478 }
479
480 FREE(&save_new);
481}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
bool mutt_pattern_exec(struct Pattern *pat, PatternExecFlags flags, struct Mailbox *m, struct Email *e, struct PatternCache *cache)
Match a pattern against an email header.
Definition: exec.c:1107
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:43
#define MAX(a, b)
Definition: memory.h:30
bool mview_has_limit(const struct MailboxView *mv)
Is a limit active?
Definition: mview.c:435
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition: mxapi.h:89
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:99
#define SLIST_FIRST(head)
Definition: queue.h:229
bool visible
Is this message part of the view?
Definition: email.h:121
bool limit_visited
Has the limit pattern been applied to this message?
Definition: email.h:122
struct PatternList * limit_pattern
Compiled limit pattern.
Definition: mview.h:41
struct Email ** emails
Array of Emails.
Definition: mailbox.h:96
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_index_unthreaded()

static void update_index_unthreaded ( struct MailboxView mv,
enum MxStatus  check 
)
static

Update the index (if unthreaded)

Parameters
mvMailbox
checkFlags, e.g. MX_STATUS_REOPENED

Definition at line 488 of file dlg_index.c.

489{
490 /* We are in a limited view. Check if the new message(s) satisfy
491 * the limit criteria. If they do, set their virtual msgno so that
492 * they will be visible in the limited view */
493 if (mview_has_limit(mv))
494 {
495 int padding = mx_msg_padding_size(mv->mailbox);
496 mv->mailbox->vcount = mv->vsize = 0;
497 for (int i = 0; i < mv->mailbox->msg_count; i++)
498 {
499 struct Email *e = mv->mailbox->emails[i];
500 if (!e)
501 break;
502
503 if ((e->limit_visited && e->visible) ||
505 MUTT_MATCH_FULL_ADDRESS, mv->mailbox, e, NULL))
506 {
507 assert(mv->mailbox->vcount < mv->mailbox->msg_count);
508 e->vnum = mv->mailbox->vcount;
509 mv->mailbox->v2r[mv->mailbox->vcount] = i;
510 e->visible = true;
511 mv->mailbox->vcount++;
512 struct Body *b = e->body;
513 mv->vsize += b->length + b->offset - b->hdr_offset + padding;
514 }
515 else
516 {
517 e->visible = false;
518 }
519
520 // mark email as visited so we don't re-apply the pattern next time
521 e->limit_visited = true;
522 }
523 }
524
525 /* if the mailbox was reopened, need to rethread from scratch */
526 mutt_sort_headers(mv->mailbox, mv->threads, (check == MX_STATUS_REOPENED), &mv->vsize);
527}
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size()
Definition: mx.c:1549
The body of an email.
Definition: body.h:36
LOFF_T offset
offset where the actual data begins
Definition: body.h:52
LOFF_T length
length (in bytes) of attachment
Definition: body.h:53
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:80
struct Body * body
List of MIME parts.
Definition: email.h:67
int * v2r
Mapping from virtual to real msgno.
Definition: mailbox.h:98
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_index()

void update_index ( struct Menu menu,
struct MailboxView mv,
enum MxStatus  check,
int  oldcount,
const struct IndexSharedData shared 
)

Update the index.

Parameters
menuCurrent Menu
mvMailbox
checkFlags, e.g. MX_STATUS_REOPENED
oldcountHow many items are currently in the index
sharedShared Index data

Definition at line 537 of file dlg_index.c.

539{
540 if (!menu || !mv)
541 return;
542
543 struct Mailbox *m = mv->mailbox;
544 if (mutt_using_threads())
545 update_index_threaded(mv, check, oldcount);
546 else
547 update_index_unthreaded(mv, check);
548
549 const int old_index = menu_get_index(menu);
550 int index = -1;
551 if (oldcount)
552 {
553 /* restore the current message to the message it was pointing to */
554 for (int i = 0; i < m->vcount; i++)
555 {
556 struct Email *e = mutt_get_virt_email(m, i);
557 if (!e)
558 continue;
559 if (index_shared_data_is_cur_email(shared, e))
560 {
561 index = i;
562 break;
563 }
564 }
565 }
566
567 if (index < 0)
568 {
569 index = (old_index < m->vcount) ? old_index : ci_first_message(m);
570 }
571 menu_set_index(menu, index);
572}
static void update_index_threaded(struct MailboxView *mv, enum MxStatus check, int oldcount)
Update the index (if threaded)
Definition: dlg_index.c:406
static void update_index_unthreaded(struct MailboxView *mv, enum MxStatus check)
Update the index (if unthreaded)
Definition: dlg_index.c:488
bool index_shared_data_is_cur_email(const struct IndexSharedData *shared, const struct Email *e)
Check whether an email is the currently selected Email.
Definition: shared_data.c:259
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_update_index()

void mutt_update_index ( struct Menu menu,
struct MailboxView mv,
enum MxStatus  check,
int  oldcount,
struct IndexSharedData shared 
)

Update the index.

Parameters
menuCurrent Menu
mvMailbox
checkFlags, e.g. MX_STATUS_REOPENED
oldcountHow many items are currently in the index
sharedShared Index data

Definition at line 582 of file dlg_index.c.

584{
585 update_index(menu, mv, check, oldcount, shared);
586}
void update_index(struct Menu *menu, struct MailboxView *mv, enum MxStatus check, int oldcount, const struct IndexSharedData *shared)
Update the index.
Definition: dlg_index.c:537
+ Here is the call graph for this function:

◆ change_folder_mailbox()

void change_folder_mailbox ( struct Menu menu,
struct Mailbox m,
int *  oldcount,
struct IndexSharedData shared,
bool  read_only 
)

Change to a different Mailbox by pointer.

Parameters
menuCurrent Menu
mMailbox
oldcountHow many items are currently in the index
sharedShared Index data
read_onlyOpen Mailbox in read-only mode

Definition at line 619 of file dlg_index.c.

621{
622 if (!m)
623 return;
624
625 /* keepalive failure in mutt_enter_fname may kill connection. */
626 if (shared->mailbox && (mutt_buffer_is_empty(&shared->mailbox->pathbuf)))
627 {
628 mview_free(&shared->mailboxview);
629 mailbox_free(&shared->mailbox);
630 }
631
632 if (shared->mailbox)
633 {
634 char *new_last_folder = NULL;
635#ifdef USE_INOTIFY
636 int monitor_remove_rc = mutt_monitor_remove(NULL);
637#endif
638#ifdef USE_COMP_MBOX
639 if (shared->mailbox->compress_info && (shared->mailbox->realpath[0] != '\0'))
640 new_last_folder = mutt_str_dup(shared->mailbox->realpath);
641 else
642#endif
643 new_last_folder = mutt_str_dup(mailbox_path(shared->mailbox));
644 *oldcount = shared->mailbox->msg_count;
645
646 const enum MxStatus check = mx_mbox_close(shared->mailbox);
647 if (check == MX_STATUS_OK)
648 {
649 mview_free(&shared->mailboxview);
650 if (shared->mailbox != m)
651 {
652 mailbox_free(&shared->mailbox);
653 }
654 }
655 else
656 {
657#ifdef USE_INOTIFY
658 if (monitor_remove_rc == 0)
659 mutt_monitor_add(NULL);
660#endif
661 if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED))
662 update_index(menu, shared->mailboxview, check, *oldcount, shared);
663
664 FREE(&new_last_folder);
665 OptSearchInvalid = true;
667 return;
668 }
670 LastFolder = new_last_folder;
671 }
673
674 /* If the `folder-hook` were to call `unmailboxes`, then the Mailbox (`m`)
675 * could be deleted, leaving `m` dangling. */
676 // TODO: Refactor this function to avoid the need for an observer
678 char *dup_path = mutt_str_dup(mailbox_path(m));
679 char *dup_name = mutt_str_dup(m->name);
680
681 mutt_folder_hook(dup_path, dup_name);
682 if (m)
683 {
684 /* `m` is still valid, but we won't need the observer again before the end
685 * of the function. */
687 }
688 else
689 {
690 // Recreate the Mailbox as the folder-hook might have invoked `mailboxes`
691 // and/or `unmailboxes`.
692 m = mx_path_resolve(dup_path);
693 }
694
695 FREE(&dup_path);
696 FREE(&dup_name);
697
698 if (!m)
699 return;
700
701 const OpenMailboxFlags flags = read_only ? MUTT_READONLY : MUTT_OPEN_NO_FLAGS;
702 if (mx_mbox_open(m, flags))
703 {
704 struct MailboxView *mv = mview_new(m);
706
707 menu->max = m->msg_count;
709#ifdef USE_INOTIFY
710 mutt_monitor_add(NULL);
711#endif
712 }
713 else
714 {
715 index_shared_data_set_context(shared, NULL);
717 }
718
719 const bool c_collapse_all = cs_subset_bool(shared->sub, "collapse_all");
720 if (mutt_using_threads() && c_collapse_all)
721 collapse_all(shared->mailboxview, menu, 0);
722
724 /* force the mailbox check after we have changed the folder */
725 struct EventMailbox ev_m = { shared->mailbox };
728 OptSearchInvalid = true;
729}
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:260
void collapse_all(struct MailboxView *mv, struct Menu *menu, int toggle)
Collapse/uncollapse all threads.
Definition: dlg_index.c:170
static int index_mailbox_observer(struct NotifyCallback *nc)
Notification that a Mailbox has changed - Implements observer_t -.
Definition: dlg_index.c:593
void mutt_folder_hook(const char *path, const char *desc)
Perform a folder hook.
Definition: hook.c:589
void index_shared_data_set_context(struct IndexSharedData *shared, struct MailboxView *mv)
Set the MailboxView for the Index and friends.
Definition: shared_data.c:157
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:87
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:210
#define MENU_REDRAW_FULL
Redraw everything.
Definition: lib.h:59
int mutt_monitor_add(struct Mailbox *m)
Add a watch for a mailbox.
Definition: monitor.c:481
int mutt_monitor_remove(struct Mailbox *m)
Remove a watch for a mailbox.
Definition: monitor.c:526
bool notify_observer_remove(struct Notify *notify, const observer_t callback, const void *global_data)
Remove an observer from an object.
Definition: notify.c:228
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
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:250
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:326
char * LastFolder
Previously selected mailbox.
Definition: mutt_globals.h:55
char * CurrentFolder
Currently selected mailbox.
Definition: mutt_globals.h:54
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
int mutt_mailbox_check(struct Mailbox *m_cur, CheckStatsFlags flags)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:156
void mview_free(struct MailboxView **ptr)
Free a MailboxView.
Definition: mview.c:49
struct MailboxView * mview_new(struct Mailbox *m)
Create a new MailboxView.
Definition: mview.c:77
bool mx_mbox_open(struct Mailbox *m, OpenMailboxFlags flags)
Open a mailbox and parse it.
Definition: mx.c:304
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1677
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:615
#define MUTT_READONLY
Open in read-only mode.
Definition: mxapi.h:64
uint8_t OpenMailboxFlags
Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.
Definition: mxapi.h:60
#define MUTT_OPEN_NO_FLAGS
No flags are set.
Definition: mxapi.h:61
#define MUTT_MAILBOX_CHECK_FORCE
Ignore MailboxTime and check for new mail.
Definition: mxapi.h:75
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close()
Definition: mxapi.h:84
@ MX_STATUS_OK
No changes.
Definition: mxapi.h:86
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition: mxapi.h:87
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:49
bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: options.h:57
An Event that happened to a Mailbox.
Definition: mailbox.h:186
struct Mailbox * mailbox
The Mailbox this Event relates to.
Definition: mailbox.h:187
struct MailboxView * mailboxview
Current Mailbox view.
Definition: shared_data.h:39
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
struct ConfigSubset * sub
Config set to use.
Definition: shared_data.h:38
The "current" mailbox.
Definition: mview.h:38
struct Menu * menu
Needed for pattern compilation.
Definition: mview.h:45
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
char * name
A short name for the Mailbox.
Definition: mailbox.h:82
struct Notify * notify
Notifications: NotifyMailbox, EventMailbox.
Definition: mailbox.h:144
struct Buffer pathbuf
Path of the Mailbox.
Definition: mailbox.h:80
void * compress_info
Compressed mbox module private data.
Definition: mailbox.h:120
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ change_folder_notmuch()

struct Mailbox * change_folder_notmuch ( struct Menu menu,
char *  buf,
int  buflen,
int *  oldcount,
struct IndexSharedData shared,
bool  read_only 
)

Change to a different Notmuch Mailbox by string.

Parameters
menuCurrent Menu
bufFolder to change to
buflenLength of buffer
oldcountHow many items are currently in the index
sharedShared Index data
read_onlyOpen Mailbox in read-only mode
Return values
ptrMailbox

Definition at line 742 of file dlg_index.c.

744{
745 if (!nm_url_from_query(NULL, buf, buflen))
746 {
747 mutt_message(_("Failed to create query, aborting"));
748 return NULL;
749 }
750
751 struct Mailbox *m_query = mx_path_resolve(buf);
752 change_folder_mailbox(menu, m_query, oldcount, shared, read_only);
753 return m_query;
754}
void change_folder_mailbox(struct Menu *menu, struct Mailbox *m, int *oldcount, struct IndexSharedData *shared, bool read_only)
Change to a different Mailbox by pointer.
Definition: dlg_index.c:619
#define mutt_message(...)
Definition: logging.h:86
char * nm_url_from_query(struct Mailbox *m, char *buf, size_t buflen)
Turn a query into a URL.
Definition: notmuch.c:1556
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ change_folder_string()

void change_folder_string ( struct Menu menu,
char *  buf,
size_t  buflen,
int *  oldcount,
struct IndexSharedData shared,
bool  read_only 
)

Change to a different Mailbox by string.

Parameters
menuCurrent Menu
bufFolder to change to
buflenLength of buffer
oldcountHow many items are currently in the index
sharedShared Index data
read_onlyOpen Mailbox in read-only mode

Definition at line 766 of file dlg_index.c.

768{
769#ifdef USE_NNTP
770 if (OptNews)
771 {
772 OptNews = false;
774 }
775 else
776#endif
777 {
778 const char *const c_folder = cs_subset_string(shared->sub, "folder");
779 mx_path_canon(buf, buflen, c_folder, NULL);
780 }
781
782 enum MailboxType type = mx_path_probe(buf);
783 if ((type == MUTT_MAILBOX_ERROR) || (type == MUTT_UNKNOWN))
784 {
785 // Look for a Mailbox by its description, before failing
786 struct Mailbox *m = mailbox_find_name(buf);
787 if (m)
788 {
789 change_folder_mailbox(menu, m, oldcount, shared, read_only);
790 }
791 else
792 mutt_error(_("%s is not a mailbox"), buf);
793 return;
794 }
795
796 struct Mailbox *m = mx_path_resolve(buf);
797 change_folder_mailbox(menu, m, oldcount, shared, read_only);
798}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
struct Mailbox * mailbox_find_name(const char *name)
Find the mailbox with a given name.
Definition: mailbox.c:176
MailboxType
Supported mailbox formats.
Definition: mailbox.h:41
@ MUTT_MAILBOX_ERROR
Error occurred examining Mailbox.
Definition: mailbox.h:43
@ MUTT_UNKNOWN
Mailbox wasn't recognised.
Definition: mailbox.h:44
int mx_path_canon(char *buf, size_t buflen, const char *folder, enum MailboxType *type)
Canonicalise a mailbox path - Wrapper for MxOps::path_canon()
Definition: mx.c:1373
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1327
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:561
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:77
bool OptNews
(pseudo) used to change reader mode
Definition: options.h:50
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
struct Connection * conn
Connection to NNTP Server.
Definition: adata.h:63
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_draw_statusline()

void mutt_draw_statusline ( struct MuttWindow win,
int  cols,
const char *  buf,
size_t  buflen 
)

Draw a highlighted status bar.

Parameters
winWindow
colsMaximum number of screen columns
bufMessage to be displayed
buflenLength of the buffer

Users configure the highlighting of the status bar, e.g. color status red default "[0-9][0-9]:[0-9][0-9]"

Where regexes overlap, the one nearest the start will be used. If two regexes start at the same place, the longer match will be used.

Colours of the status bar

< First character of that colour

< Last character of that colour

Definition at line 922 of file dlg_index.c.

923{
924 if (!buf || !stdscr)
925 return;
926
927 size_t i = 0;
928 size_t offset = 0;
929 bool found = false;
930 size_t chunks = 0;
931 size_t len = 0;
932
936 struct StatusSyntax
937 {
938 struct AttrColor *attr_color;
939 int first;
940 int last;
941 } *syntax = NULL;
942
945 do
946 {
947 struct RegexColor *cl = NULL;
948 found = false;
949
950 if (!buf[offset])
951 break;
952
953 /* loop through each "color status regex" */
955 {
956 regmatch_t pmatch[cl->match + 1];
957
958 if (regexec(&cl->regex, buf + offset, cl->match + 1, pmatch, 0) != 0)
959 continue; /* regex doesn't match the status bar */
960
961 int first = pmatch[cl->match].rm_so + offset;
962 int last = pmatch[cl->match].rm_eo + offset;
963
964 if (first == last)
965 continue; /* ignore an empty regex */
966
967 if (!found)
968 {
969 chunks++;
970 mutt_mem_realloc(&syntax, chunks * sizeof(struct StatusSyntax));
971 }
972
973 i = chunks - 1;
974 if (!found || (first < syntax[i].first) ||
975 ((first == syntax[i].first) && (last > syntax[i].last)))
976 {
977 struct AttrColor *ac_merge = merged_color_overlay(ac_base, &cl->attr_color);
978
979 syntax[i].attr_color = ac_merge;
980 syntax[i].first = first;
981 syntax[i].last = last;
982 }
983 found = true;
984 }
985
986 if (syntax)
987 {
988 offset = syntax[i].last;
989 }
990 } while (found);
991
992 /* Only 'len' bytes will fit into 'cols' screen columns */
993 len = mutt_wstr_trunc(buf, buflen, cols, NULL);
994
995 offset = 0;
996
997 if ((chunks > 0) && (syntax[0].first > 0))
998 {
999 /* Text before the first highlight */
1000 mutt_window_addnstr(win, buf, MIN(len, syntax[0].first));
1001 mutt_curses_set_color(ac_base);
1002 if (len <= syntax[0].first)
1003 goto dsl_finish; /* no more room */
1004
1005 offset = syntax[0].first;
1006 }
1007
1008 for (i = 0; i < chunks; i++)
1009 {
1010 /* Highlighted text */
1011 mutt_curses_set_color(syntax[i].attr_color);
1012 mutt_window_addnstr(win, buf + offset, MIN(len, syntax[i].last) - offset);
1013 if (len <= syntax[i].last)
1014 goto dsl_finish; /* no more room */
1015
1016 size_t next;
1017 if ((i + 1) == chunks)
1018 {
1019 next = len;
1020 }
1021 else
1022 {
1023 next = MIN(len, syntax[i + 1].first);
1024 }
1025
1026 mutt_curses_set_color(ac_base);
1027 offset = syntax[i].last;
1028 mutt_window_addnstr(win, buf + offset, next - offset);
1029
1030 offset = next;
1031 if (offset >= len)
1032 goto dsl_finish; /* no more room */
1033 }
1034
1035 mutt_curses_set_color(ac_base);
1036 if (offset < len)
1037 {
1038 /* Text after the last highlight */
1039 mutt_window_addnstr(win, buf + offset, len - offset);
1040 }
1041
1042 int width = mutt_strwidth(buf);
1043 if (width < cols)
1044 {
1045 /* Pad the rest of the line with whitespace */
1046 mutt_paddstr(win, cols - width, "");
1047 }
1048dsl_finish:
1049 FREE(&syntax);
1050}
struct RegexColorList * regex_colors_get_list(enum ColorId cid)
Return the RegexColorList for a colour id.
Definition: regex.c:184
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition: simple.c:74
@ MT_COLOR_STATUS
Status bar (takes a pattern)
Definition: color.h:71
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:54
size_t mutt_wstr_trunc(const char *src, size_t maxlen, size_t maxwid, size_t *width)
Work out how to truncate a widechar string.
Definition: curs_lib.c:858
void mutt_paddstr(struct MuttWindow *win, int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:816
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:907
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
#define MIN(a, b)
Definition: memory.h:31
struct AttrColor * merged_color_overlay(struct AttrColor *base, struct AttrColor *over)
Combine two colours.
Definition: merged.c:109
void mutt_curses_set_color(struct AttrColor *ac)
Set the colour and attributes for text.
Definition: mutt_curses.c:40
int mutt_window_addnstr(struct MuttWindow *win, const char *str, int num)
Write a partial string to a Window.
Definition: mutt_window.c:394
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
A curses colour and its attributes.
Definition: attr.h:35
A regular expression and a color to highlight a line.
Definition: regex4.h:37
regex_t regex
Compiled regex.
Definition: regex4.h:40
struct AttrColor attr_color
Colour and attributes to apply.
Definition: regex4.h:38
int match
Substring to match, 0 for old behaviour.
Definition: regex4.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_index_menu()

struct Mailbox * mutt_index_menu ( struct MuttWindow dlg,
struct Mailbox m_init 
)

Display a list of emails.

Parameters
dlgDialog containing Windows to draw on
m_initInitial mailbox
Return values
Mailboxopen in the index

Definition at line 1058 of file dlg_index.c.

1059{
1060 /* Make sure use_threads/sort/sort_aux are coherent */
1062
1063 struct IndexSharedData *shared = dlg->wdata;
1065
1066 struct MuttWindow *panel_index = window_find_child(dlg, WT_INDEX);
1067
1068 struct IndexPrivateData *priv = panel_index->wdata;
1069 priv->attach_msg = OptAttachMsg;
1070 priv->win_index = window_find_child(panel_index, WT_MENU);
1071
1072 int op = OP_NULL;
1073
1074#ifdef USE_NNTP
1075 if (shared->mailbox && (shared->mailbox->type == MUTT_NNTP))
1076 dlg->help_data = IndexNewsHelp;
1077 else
1078#endif
1079 dlg->help_data = IndexHelp;
1080 dlg->help_menu = MENU_INDEX;
1081
1082 priv->menu = priv->win_index->wdata;
1084 priv->menu->color = index_color;
1085 priv->menu->max = shared->mailbox ? shared->mailbox->vcount : 0;
1087 mutt_window_reflow(NULL);
1088
1089 if (!priv->attach_msg)
1090 {
1091 /* force the mailbox check after we enter the folder */
1093 }
1094#ifdef USE_INOTIFY
1095 mutt_monitor_add(NULL);
1096#endif
1097
1098 {
1099 const bool c_collapse_all = cs_subset_bool(shared->sub, "collapse_all");
1100 if (mutt_using_threads() && c_collapse_all)
1101 {
1102 collapse_all(shared->mailboxview, priv->menu, 0);
1104 }
1105 }
1106
1107 int rc = 0;
1108 do
1109 {
1110 /* Clear the tag prefix unless we just started it.
1111 * Don't clear the prefix on a timeout, but do clear on an abort */
1112 if (priv->tag && (op != OP_TAG_PREFIX) && (op != OP_TAG_PREFIX_COND) && (op != OP_TIMEOUT))
1113 {
1114 priv->tag = false;
1115 }
1116
1117 /* check if we need to resort the index because just about
1118 * any 'op' below could do mutt_enter_command(), either here or
1119 * from any new priv->menu launched, and change $sort/$sort_aux */
1120 if (OptNeedResort && shared->mailbox && (shared->mailbox->msg_count != 0) &&
1121 (menu_get_index(priv->menu) >= 0))
1122 {
1124 }
1125
1126 priv->menu->max = shared->mailbox ? shared->mailbox->vcount : 0;
1127 priv->oldcount = shared->mailbox ? shared->mailbox->msg_count : 0;
1128
1129 {
1132 {
1134 OptRedrawTree = false;
1135 }
1136 }
1137
1139 {
1141
1142 shared->mailboxview->menu = priv->menu;
1143 /* check for new mail in the mailbox. If nonzero, then something has
1144 * changed about the file (either we got new mail or the file was
1145 * modified underneath us.) */
1146 enum MxStatus check = mx_mbox_check(shared->mailbox);
1147
1148 if (check == MX_STATUS_ERROR)
1149 {
1151 {
1152 /* fatal error occurred */
1155 }
1156
1157 OptSearchInvalid = true;
1158 }
1159 else if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED) ||
1160 (check == MX_STATUS_FLAGS))
1161 {
1162 /* notify the user of new mail */
1163 if (check == MX_STATUS_REOPENED)
1164 {
1165 mutt_error(_("Mailbox was externally modified. Flags may be wrong."));
1166 }
1167 else if (check == MX_STATUS_NEW_MAIL)
1168 {
1169 for (size_t i = 0; i < shared->mailbox->msg_count; i++)
1170 {
1171 const struct Email *e = shared->mailbox->emails[i];
1172 if (e && !e->read && !e->old)
1173 {
1174 mutt_message(_("New mail in this mailbox"));
1175 const bool c_beep_new = cs_subset_bool(shared->sub, "beep_new");
1176 if (c_beep_new)
1177 mutt_beep(true);
1178 const char *const c_new_mail_command = cs_subset_string(shared->sub, "new_mail_command");
1179 if (c_new_mail_command)
1180 {
1181 char cmd[1024] = { 0 };
1182 menu_status_line(cmd, sizeof(cmd), shared, NULL, sizeof(cmd),
1183 NONULL(c_new_mail_command));
1184 if (mutt_system(cmd) != 0)
1185 mutt_error(_("Error running \"%s\""), cmd);
1186 }
1187 break;
1188 }
1189 }
1190 }
1191 else if (check == MX_STATUS_FLAGS)
1192 {
1193 mutt_message(_("Mailbox was externally modified"));
1194 }
1195
1196 /* avoid the message being overwritten by mailbox */
1197 priv->do_mailbox_notify = false;
1198
1199 bool verbose = shared->mailbox->verbose;
1200 shared->mailbox->verbose = false;
1201 update_index(priv->menu, shared->mailboxview, check, priv->oldcount, shared);
1202 shared->mailbox->verbose = verbose;
1203 priv->menu->max = shared->mailbox->vcount;
1205 OptSearchInvalid = true;
1206 }
1207
1209 menu_get_index(priv->menu)));
1210 }
1211
1212 if (!priv->attach_msg)
1213 {
1214 /* check for new mail in the incoming folders */
1215 priv->oldcount = priv->newcount;
1217 if (priv->do_mailbox_notify)
1218 {
1219 if (mutt_mailbox_notify(shared->mailbox))
1220 {
1221 const bool c_beep_new = cs_subset_bool(shared->sub, "beep_new");
1222 if (c_beep_new)
1223 mutt_beep(true);
1224 const char *const c_new_mail_command = cs_subset_string(shared->sub, "new_mail_command");
1225 if (c_new_mail_command)
1226 {
1227 char cmd[1024] = { 0 };
1228 menu_status_line(cmd, sizeof(cmd), shared, priv->menu, sizeof(cmd),
1229 NONULL(c_new_mail_command));
1230 if (mutt_system(cmd) != 0)
1231 mutt_error(_("Error running \"%s\""), cmd);
1232 }
1233 }
1234 }
1235 else
1236 priv->do_mailbox_notify = true;
1237 }
1238
1239 window_redraw(NULL);
1240
1241 /* give visual indication that the next command is a tag- command */
1242 if (priv->tag)
1244
1245 const bool c_arrow_cursor = cs_subset_bool(shared->sub, "arrow_cursor");
1246 const bool c_braille_friendly = cs_subset_bool(shared->sub, "braille_friendly");
1247 const int index = menu_get_index(priv->menu);
1248 if (c_arrow_cursor)
1249 {
1250 mutt_window_move(priv->menu->win, 2, index - priv->menu->top);
1251 }
1252 else if (c_braille_friendly)
1253 {
1254 mutt_window_move(priv->menu->win, 0, index - priv->menu->top);
1255 }
1256 else
1257 {
1258 mutt_window_move(priv->menu->win, priv->menu->win->state.cols - 1,
1259 index - priv->menu->top);
1260 }
1261 mutt_refresh();
1262
1263 if (SigWinch)
1264 {
1265 SigWinch = false;
1268 priv->menu->top = 0; /* so we scroll the right amount */
1269 /* force a real complete redraw. clrtobot() doesn't seem to be able
1270 * to handle every case without this. */
1271 clearok(stdscr, true);
1273 continue;
1274 }
1275
1276 window_redraw(NULL);
1277 op = km_dokey(MENU_INDEX);
1278
1279 /* either user abort or timeout */
1280 if (op < OP_NULL)
1281 {
1283 if (priv->tag)
1285 continue;
1286 }
1287
1288 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
1289
1290 /* special handling for the priv->tag-prefix function */
1291 const bool c_auto_tag = cs_subset_bool(shared->sub, "auto_tag");
1292 if ((op == OP_TAG_PREFIX) || (op == OP_TAG_PREFIX_COND))
1293 {
1294 /* A second priv->tag-prefix command aborts */
1295 if (priv->tag)
1296 {
1297 priv->tag = false;
1299 continue;
1300 }
1301
1302 if (!shared->mailbox)
1303 {
1304 mutt_error(_("No mailbox is open"));
1305 continue;
1306 }
1307
1308 if (shared->mailbox->msg_tagged == 0)
1309 {
1310 if (op == OP_TAG_PREFIX)
1311 mutt_error(_("No tagged messages"));
1312 else if (op == OP_TAG_PREFIX_COND)
1313 {
1315 mutt_message(_("Nothing to do"));
1316 }
1317 continue;
1318 }
1319
1320 /* get the real command */
1321 priv->tag = true;
1322 continue;
1323 }
1324 else if (c_auto_tag && shared->mailbox && (shared->mailbox->msg_tagged != 0))
1325 {
1326 priv->tag = true;
1327 }
1328
1330
1331#ifdef USE_NNTP
1332 OptNews = false; /* for any case */
1333#endif
1334
1335#ifdef USE_NOTMUCH
1336 nm_db_debug_check(shared->mailbox);
1337#endif
1338
1339 rc = index_function_dispatcher(priv->win_index, op);
1340
1341 if (rc == FR_UNKNOWN)
1342 rc = menu_function_dispatcher(priv->win_index, op);
1343
1344#ifdef USE_SIDEBAR
1345 if (rc == FR_UNKNOWN)
1346 {
1347 struct MuttWindow *win_sidebar = window_find_child(dlg, WT_SIDEBAR);
1348 rc = sb_function_dispatcher(win_sidebar, op);
1349 }
1350#endif
1351 if (rc == FR_UNKNOWN)
1352 rc = global_function_dispatcher(NULL, op);
1353
1354 if (rc == FR_UNKNOWN)
1356
1357#ifdef USE_NOTMUCH
1358 nm_db_debug_check(shared->mailbox);
1359#endif
1360 } while (rc != FR_DONE);
1361
1362 mview_free(&shared->mailboxview);
1363
1364 return shared->mailbox;
1365}
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:140
void mutt_flush_macro_to_endcond(void)
Drop a macro from the input buffer.
Definition: curs_lib.c:572
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:130
@ FR_DONE
Exit the Dialog.
Definition: dispatcher.h:35
@ FR_UNKNOWN
Unknown function.
Definition: dispatcher.h:33
const struct Mapping IndexNewsHelp[]
Help Bar for the News Index dialog.
Definition: dlg_index.c:121
static const struct Mapping IndexHelp[]
Help Bar for the Index dialog.
Definition: dlg_index.c:105
void resort_index(struct MailboxView *mv, struct Menu *menu)
Resort the index.
Definition: dlg_index.c:364
int sb_function_dispatcher(struct MuttWindow *win, int op)
Perform a Sidebar function - Implements function_dispatcher_t -.
Definition: functions.c:375
int global_function_dispatcher(struct MuttWindow *win, int op)
Perform a Global function - Implements function_dispatcher_t -.
Definition: global.c:164
int menu_function_dispatcher(struct MuttWindow *win, int op)
Perform a Menu function - Implements function_dispatcher_t -.
Definition: functions.c:320
int index_function_dispatcher(struct MuttWindow *win, int op)
Perform an Index function - Implements function_dispatcher_t -.
Definition: functions.c:2831
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
struct AttrColor * index_color(struct Menu *menu, int line)
Calculate the colour for a line of the index - Implements Menu::color() -.
Definition: dlg_index.c:890
void index_make_entry(struct Menu *menu, char *buf, size_t buflen, int line)
Format a menu item for the index list - Implements Menu::make_entry() -.
Definition: dlg_index.c:803
void mutt_timeout_hook(void)
Execute any timeout hooks.
Definition: hook.c:888
void index_shared_data_set_email(struct IndexSharedData *shared, struct Email *e)
Set the current Email for the Index and friends.
Definition: shared_data.c:230
void index_adjust_sort_threads(const struct ConfigSubset *sub)
Adjust use_threads/sort/sort_aux.
Definition: index.c:181
int km_dokey(enum MenuType mtype)
Determine what a keypress should do.
Definition: keymap.c:795
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1061
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
void mailbox_gc_run(void)
Run the garbage-collection.
Definition: mailbox.c:296
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:49
void msgwin_set_text(enum ColorId cid, const char *text)
Set the text for the Message Window.
Definition: msgwin.c:233
void msgwin_clear_text(void)
Clear the text in the Message Window.
Definition: msgwin.c:249
void mutt_resize_screen(void)
Update NeoMutt's opinion about the window size (CURSES)
Definition: resize.c:73
SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: mutt_globals.h:70
bool mutt_mailbox_notify(struct Mailbox *m_cur)
Notify the user if there's new mail.
Definition: mutt_mailbox.c:230
void mutt_draw_tree(struct ThreadsContext *tctx)
Draw a tree of threaded emails.
Definition: mutt_thread.c:384
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:604
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:340
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:293
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:522
void window_invalidate_all(void)
Mark all windows as in need of repaint.
Definition: mutt_window.c:742
@ WT_INDEX
A panel containing the Index Window.
Definition: mutt_window.h:97
@ WT_SIDEBAR
Side panel containing Accounts or groups of data.
Definition: mutt_window.h:101
@ WT_MENU
An Window containing a Menu.
Definition: mutt_window.h:98
enum MxStatus mx_mbox_check(struct Mailbox *m)
Check for new mail - Wrapper for MxOps::mbox_check()
Definition: mx.c:1126
#define MUTT_MAILBOX_CHECK_NO_FLAGS
No flags are set.
Definition: mxapi.h:74
@ MX_STATUS_ERROR
An error occurred.
Definition: mxapi.h:85
@ MX_STATUS_FLAGS
Nondestructive flags change (IMAP)
Definition: mxapi.h:90
void nm_db_debug_check(struct Mailbox *m)
Check if the database is open.
Definition: db.c:386
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:46
#define OP_TIMEOUT
Definition: opcodes.h:32
bool OptAttachMsg
(pseudo) used by attach-message
Definition: options.h:37
bool OptNeedResort
(pseudo) used to force a re-sort
Definition: options.h:48
bool OptRedrawTree
(pseudo) redraw the thread tree
Definition: options.h:55
int mutt_system(const char *cmd)
Run an external command.
Definition: system.c:51
void menu_status_line(char *buf, size_t buflen, struct IndexSharedData *shared, struct Menu *menu, int cols, const char *fmt)
Create the status line.
Definition: status.c:445
#define NONULL(x)
Definition: string2.h:37
Private state data for the Index.
Definition: private_data.h:35
struct MuttWindow * win_index
Window for the Index.
Definition: private_data.h:44
int newcount
New count of Emails in the Mailbox.
Definition: private_data.h:38
struct IndexSharedData * shared
Shared Index data.
Definition: private_data.h:42
bool do_mailbox_notify
Do we need to notify the user of new mail?
Definition: private_data.h:39
bool attach_msg
Are we in "attach message" mode?
Definition: private_data.h:40
bool tag
tag-prefix has been pressed
Definition: private_data.h:36
struct Menu * menu
Menu controlling the index.
Definition: private_data.h:43
int oldcount
Old count of Emails in the Mailbox.
Definition: private_data.h:37
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:37
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:94
bool verbose
Display status messages?
Definition: mailbox.h:114
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:76
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:96
struct AttrColor *(* color)(struct Menu *menu, int line)
Definition: lib.h:133
int top
Entry that is the top of the current page.
Definition: lib.h:80
const struct Mapping * help_data
Data for the Help Bar.
Definition: mutt_window.h:142
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:127
void * wdata
Private data.
Definition: mutt_window.h:145
int help_menu
Menu for key bindings, e.g. MENU_PAGER.
Definition: mutt_window.h:141
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:60
@ MENU_INDEX
Index panel (list of emails)
Definition: type.h:50
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_set_header_color()

void mutt_set_header_color ( struct Mailbox m,
struct Email e 
)

Select a colour for a message.

Parameters
mMailbox
eCurrent Email

Definition at line 1372 of file dlg_index.c.

1373{
1374 if (!e)
1375 return;
1376
1377 struct RegexColor *color = NULL;
1378 struct PatternCache cache = { 0 };
1379
1380 struct AttrColor *ac_merge = NULL;
1382 {
1384 MUTT_MATCH_FULL_ADDRESS, m, e, &cache))
1385 {
1386 ac_merge = merged_color_overlay(ac_merge, &color->attr_color);
1387 }
1388 }
1389
1390 struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
1391 if (ac_merge)
1392 ac_merge = merged_color_overlay(ac_normal, ac_merge);
1393 else
1394 ac_merge = ac_normal;
1395
1396 e->attr_color = ac_merge;
1397}
@ MT_COLOR_INDEX
Index: default colour.
Definition: color.h:77
struct AttrColor * attr_color
Color-pair to use when displaying in the index.
Definition: email.h:112
Cache commonly-used patterns.
Definition: lib.h:110
struct PatternList * color_pattern
Compiled pattern to speed up index color calculation.
Definition: regex4.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ index_pager_init()

struct MuttWindow * index_pager_init ( void  )

Allocate the Windows for the Index/Pager.

Return values
ptrDialog containing nested Windows

Definition at line 1403 of file dlg_index.c.

1404{
1408
1409 struct IndexSharedData *shared = index_shared_data_new();
1410 notify_set_parent(shared->notify, dlg->notify);
1411
1412 dlg->wdata = shared;
1414
1415 const bool c_status_on_top = cs_subset_bool(NeoMutt->sub, "status_on_top");
1416
1417 struct MuttWindow *panel_index = ipanel_new(c_status_on_top, shared);
1418 struct MuttWindow *panel_pager = ppanel_new(c_status_on_top, shared);
1419
1420 mutt_window_add_child(dlg, panel_index);
1421 mutt_window_add_child(dlg, panel_pager);
1422
1423 dlg->focus = panel_index;
1424
1425 return dlg;
1426}
void index_shared_data_free(struct MuttWindow *win, void **ptr)
Free Shared Index Data - Implements MuttWindow::wdata_free() -.
Definition: shared_data.c:273
struct IndexSharedData * index_shared_data_new(void)
Create new Index Data.
Definition: shared_data.c:300
struct MuttWindow * ipanel_new(bool status_on_top, struct IndexSharedData *shared)
Create the Windows for the Index panel.
Definition: ipanel.c:121
void notify_set_parent(struct Notify *notify, struct Notify *parent)
Set the parent notification handler.
Definition: notify.c:93
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:439
struct MuttWindow * mutt_window_new(enum WindowType type, enum MuttWindowOrientation orient, enum MuttWindowSize size, int cols, int rows)
Create a new Window.
Definition: mutt_window.c:181
@ WT_DLG_INDEX
Index Dialog, index_pager_init()
Definition: mutt_window.h:86
@ MUTT_WIN_ORIENT_HORIZONTAL
Window uses all available horizontal space.
Definition: mutt_window.h:39
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:52
@ MUTT_WIN_SIZE_MAXIMISE
Window wants as much space as possible.
Definition: mutt_window.h:48
struct MuttWindow * ppanel_new(bool status_on_top, struct IndexSharedData *shared)
Create the Windows for the Pager panel.
Definition: ppanel.c:122
struct Notify * notify
Notifications: NotifyIndex, IndexSharedData.
Definition: shared_data.h:44
struct MuttWindow * focus
Focused Window.
Definition: mutt_window.h:140
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Definition: mutt_window.h:160
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ dlg_change_folder()

void dlg_change_folder ( struct MuttWindow dlg,
struct Mailbox m 
)

Change the current folder, cautiously.

Parameters
dlgDialog holding the Index
mMailbox to change to

Definition at line 1433 of file dlg_index.c.

1434{
1435 if (!dlg || !m)
1436 return;
1437
1438 struct IndexSharedData *shared = dlg->wdata;
1439 if (!shared)
1440 return;
1441
1442 struct MuttWindow *panel_index = window_find_child(dlg, WT_INDEX);
1443 if (!panel_index)
1444 return;
1445
1446 struct IndexPrivateData *priv = panel_index->wdata;
1447 if (!priv)
1448 return;
1449
1450 change_folder_mailbox(priv->menu, m, &priv->oldcount, shared, false);
1451}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ IndexHelp

const struct Mapping IndexHelp[]
static
Initial value:
= {
{ N_("Quit"), OP_QUIT },
{ N_("Del"), OP_DELETE },
{ N_("Undel"), OP_UNDELETE },
{ N_("Save"), OP_SAVE },
{ N_("Mail"), OP_MAIL },
{ N_("Reply"), OP_REPLY },
{ N_("Group"), OP_GROUP_REPLY },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Help Bar for the Index dialog.

Definition at line 105 of file dlg_index.c.

◆ IndexNewsHelp

const struct Mapping IndexNewsHelp[]
Initial value:
= {
{ N_("Quit"), OP_QUIT },
{ N_("Del"), OP_DELETE },
{ N_("Undel"), OP_UNDELETE },
{ N_("Save"), OP_SAVE },
{ N_("Post"), OP_POST },
{ N_("Followup"), OP_FOLLOWUP },
{ N_("Catchup"), OP_CATCHUP },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}

Help Bar for the News Index dialog.

Definition at line 121 of file dlg_index.c.