NeoMutt  2023-03-22-27-g3cb248
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 "globals.h"
#include "hdrline.h"
#include "hook.h"
#include "keymap.h"
#include "mutt_logging.h"
#include "mutt_mailbox.h"
#include "mutt_thread.h"
#include "mview.h"
#include "mx.h"
#include "opcodes.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 "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 141 of file dlg_index.c.

142{
143 if (!m)
144 return false;
145
146 if (!(m->rights & acl))
147 {
148 /* L10N: %s is one of the CHECK_ACL entries below. */
149 mutt_error(_("%s: Operation not permitted by ACL"), msg);
150 return false;
151 }
152
153 return true;
154}
#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 168 of file dlg_index.c.

169{
170 if (!mv || !mv->mailbox || (mv->mailbox->msg_count == 0) || !menu)
171 return;
172
173 struct Email *e_cur = mutt_get_virt_email(mv->mailbox, menu_get_index(menu));
174 if (!e_cur)
175 return;
176
177 int final;
178
179 /* Figure out what the current message would be after folding / unfolding,
180 * so that we can restore the cursor in a sane way afterwards. */
181 if (e_cur->collapsed && toggle)
182 final = mutt_uncollapse_thread(e_cur);
183 else if (mutt_thread_can_collapse(e_cur))
184 final = mutt_collapse_thread(e_cur);
185 else
186 final = e_cur->vnum;
187
188 if (final == -1)
189 return;
190
191 struct Email *base = mutt_get_virt_email(mv->mailbox, final);
192 if (!base)
193 return;
194
195 /* Iterate all threads, perform collapse/uncollapse as needed */
196 mv->collapsed = toggle ? !mv->collapsed : true;
198
199 /* Restore the cursor */
201 menu->max = mv->mailbox->vcount;
202 for (int i = 0; i < mv->mailbox->vcount; i++)
203 {
204 struct Email *e = mutt_get_virt_email(mv->mailbox, i);
205 if (!e)
206 break;
207 if (e->index == base->index)
208 {
209 menu_set_index(menu, i);
210 break;
211 }
212 }
213
215}
#define MENU_REDRAW_INDEX
Redraw the index.
Definition: lib.h:57
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:1755
off_t mutt_set_vnum(struct Mailbox *m)
Set the virtual index number of all the messages in a mailbox.
Definition: mutt_thread.c:1379
bool mutt_thread_can_collapse(struct Email *e)
Check whether a thread can be collapsed.
Definition: mutt_thread.c:1783
#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:119
int vnum
Virtual message number.
Definition: email.h:113
int index
The absolute (unsorted) message number.
Definition: email.h:109
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:72
+ 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 222 of file dlg_index.c.

223{
224 struct Email *e = mutt_get_virt_email(m, index);
225 if (e && e->collapsed)
226 {
228 mutt_set_vnum(m);
229 }
230}
+ 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 240 of file dlg_index.c.

241{
242 if (!m)
243 return -1;
244
245 int index = -1;
246
247 for (int i = msgno + 1; i < m->vcount; i++)
248 {
249 struct Email *e = mutt_get_virt_email(m, i);
250 if (!e)
251 continue;
252 if (!e->deleted)
253 {
254 index = i;
255 break;
256 }
257 }
258
259 if (uncollapse)
261
262 return index;
263}
static void uncollapse_thread(struct Mailbox *m, int index)
Open a collapsed thread.
Definition: dlg_index.c:222
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 273 of file dlg_index.c.

274{
275 if (!m)
276 return -1;
277
278 int index = -1;
279
280 for (int i = msgno - 1; i >= 0; i--)
281 {
282 struct Email *e = mutt_get_virt_email(m, i);
283 if (!e)
284 continue;
285 if (!e->deleted)
286 {
287 index = i;
288 break;
289 }
290 }
291
292 if (uncollapse)
294
295 return index;
296}
+ 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 306 of file dlg_index.c.

307{
308 if (!m || (m->msg_count == 0))
309 return 0;
310
311 int old = -1;
312 for (int i = 0; i < m->vcount; i++)
313 {
314 struct Email *e = mutt_get_virt_email(m, i);
315 if (!e)
316 continue;
317 if (!e->read && !e->deleted)
318 {
319 if (!e->old)
320 return i;
321 if (old == -1)
322 old = i;
323 }
324 }
325 if (old != -1)
326 return old;
327
328 /* If `$use_threads` is not threaded and `$sort` is reverse, the latest
329 * message is first. Otherwise, the latest message is first if exactly
330 * one of `$use_threads` and `$sort` are reverse.
331 */
332 short c_sort = cs_subset_sort(m->sub, "sort");
333 if ((c_sort & SORT_MASK) == SORT_THREADS)
334 c_sort = cs_subset_sort(m->sub, "sort_aux");
335 bool reverse = false;
336 switch (mutt_thread_style())
337 {
338 case UT_FLAT:
339 reverse = c_sort & SORT_REVERSE;
340 break;
341 case UT_THREADS:
342 reverse = c_sort & SORT_REVERSE;
343 break;
344 case UT_REVERSE:
345 reverse = !(c_sort & SORT_REVERSE);
346 break;
347 default:
348 assert(false);
349 }
350
351 if (reverse || (m->vcount == 0))
352 return 0;
353
354 return m->vcount - 1;
355}
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:74
@ SORT_THREADS
Sort by email threads.
Definition: sort2.h:45
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:75
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 362 of file dlg_index.c.

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

405{
406 struct Email **save_new = NULL;
407 const bool lmt = mview_has_limit(mv);
408
409 struct Mailbox *m = mv->mailbox;
410 int num_new = MAX(0, m->msg_count - oldcount);
411
412 const bool c_uncollapse_new = cs_subset_bool(m->sub, "uncollapse_new");
413 /* save the list of new messages */
414 if ((check != MX_STATUS_REOPENED) && (oldcount > 0) &&
415 (lmt || c_uncollapse_new) && (num_new > 0))
416 {
417 save_new = mutt_mem_malloc(num_new * sizeof(struct Email *));
418 for (int i = oldcount; i < m->msg_count; i++)
419 save_new[i - oldcount] = m->emails[i];
420 }
421
422 /* Sort first to thread the new messages, because some patterns
423 * require the threading information.
424 *
425 * If the mailbox was reopened, need to rethread from scratch. */
426 mutt_sort_headers(m, mv->threads, (check == MX_STATUS_REOPENED), &mv->vsize);
427
428 if (lmt)
429 {
430 for (int i = 0; i < m->msg_count; i++)
431 {
432 struct Email *e = m->emails[i];
433
434 if ((e->limit_visited && e->visible) ||
436 MUTT_MATCH_FULL_ADDRESS, m, e, NULL))
437 {
438 /* vnum will get properly set by mutt_set_vnum(), which
439 * is called by mutt_sort_headers() just below. */
440 e->vnum = 1;
441 e->visible = true;
442 }
443 else
444 {
445 e->vnum = -1;
446 e->visible = false;
447 }
448
449 // mark email as visited so we don't re-apply the pattern next time
450 e->limit_visited = true;
451 }
452 /* Need a second sort to set virtual numbers and redraw the tree */
453 mutt_sort_headers(m, mv->threads, false, &mv->vsize);
454 }
455
456 /* uncollapse threads with new mail */
457 if (c_uncollapse_new)
458 {
459 if (check == MX_STATUS_REOPENED)
460 {
461 mv->collapsed = false;
463 mutt_set_vnum(m);
464 }
465 else if (oldcount > 0)
466 {
467 for (int j = 0; j < num_new; j++)
468 {
469 if (save_new[j]->visible)
470 {
471 mutt_uncollapse_thread(save_new[j]);
472 }
473 }
474 mutt_set_vnum(m);
475 }
476 }
477
478 FREE(&save_new);
479}
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:1119
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:120
bool limit_visited
Has the limit pattern been applied to this message?
Definition: email.h:121
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 486 of file dlg_index.c.

487{
488 /* We are in a limited view. Check if the new message(s) satisfy
489 * the limit criteria. If they do, set their virtual msgno so that
490 * they will be visible in the limited view */
491 if (mview_has_limit(mv))
492 {
493 int padding = mx_msg_padding_size(mv->mailbox);
494 mv->mailbox->vcount = mv->vsize = 0;
495 for (int i = 0; i < mv->mailbox->msg_count; i++)
496 {
497 struct Email *e = mv->mailbox->emails[i];
498 if (!e)
499 break;
500
501 if ((e->limit_visited && e->visible) ||
503 MUTT_MATCH_FULL_ADDRESS, mv->mailbox, e, NULL))
504 {
505 assert(mv->mailbox->vcount < mv->mailbox->msg_count);
506 e->vnum = mv->mailbox->vcount;
507 mv->mailbox->v2r[mv->mailbox->vcount] = i;
508 e->visible = true;
509 mv->mailbox->vcount++;
510 struct Body *b = e->body;
511 mv->vsize += b->length + b->offset - b->hdr_offset + padding;
512 }
513 else
514 {
515 e->visible = false;
516 }
517
518 // mark email as visited so we don't re-apply the pattern next time
519 e->limit_visited = true;
520 }
521 }
522
523 /* if the mailbox was reopened, need to rethread from scratch */
524 mutt_sort_headers(mv->mailbox, mv->threads, (check == MX_STATUS_REOPENED), &mv->vsize);
525}
int mx_msg_padding_size(struct Mailbox *m)
Bytes of padding between messages - Wrapper for MxOps::msg_padding_size()
Definition: mx.c:1556
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 535 of file dlg_index.c.

537{
538 if (!menu || !mv)
539 return;
540
541 struct Mailbox *m = mv->mailbox;
542 if (mutt_using_threads())
543 update_index_threaded(mv, check, oldcount);
544 else
545 update_index_unthreaded(mv, check);
546
547 const int old_index = menu_get_index(menu);
548 int index = -1;
549 if (oldcount)
550 {
551 /* restore the current message to the message it was pointing to */
552 for (int i = 0; i < m->vcount; i++)
553 {
554 struct Email *e = mutt_get_virt_email(m, i);
555 if (!e)
556 continue;
557 if (index_shared_data_is_cur_email(shared, e))
558 {
559 index = i;
560 break;
561 }
562 }
563 }
564
565 if (index < 0)
566 {
567 index = (old_index < m->vcount) ? old_index : ci_first_message(m);
568 }
569 menu_set_index(menu, index);
570}
static void update_index_threaded(struct MailboxView *mv, enum MxStatus check, int oldcount)
Update the index (if threaded)
Definition: dlg_index.c:404
static void update_index_unthreaded(struct MailboxView *mv, enum MxStatus check)
Update the index (if unthreaded)
Definition: dlg_index.c:486
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 580 of file dlg_index.c.

582{
583 update_index(menu, mv, check, oldcount, shared);
584}
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:535
+ 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 617 of file dlg_index.c.

619{
620 if (!m)
621 return;
622
623 /* keepalive failure in mutt_enter_fname may kill connection. */
624 if (shared->mailbox && (mutt_buffer_is_empty(&shared->mailbox->pathbuf)))
625 {
626 mview_free(&shared->mailboxview);
627 mailbox_free(&shared->mailbox);
628 }
629
630 if (shared->mailbox)
631 {
632 char *new_last_folder = NULL;
633#ifdef USE_INOTIFY
634 int monitor_remove_rc = mutt_monitor_remove(NULL);
635#endif
636#ifdef USE_COMP_MBOX
637 if (shared->mailbox->compress_info && (shared->mailbox->realpath[0] != '\0'))
638 new_last_folder = mutt_str_dup(shared->mailbox->realpath);
639 else
640#endif
641 new_last_folder = mutt_str_dup(mailbox_path(shared->mailbox));
642 *oldcount = shared->mailbox->msg_count;
643
644 const enum MxStatus check = mx_mbox_close(shared->mailbox);
645 if (check == MX_STATUS_OK)
646 {
647 mview_free(&shared->mailboxview);
648 if (shared->mailbox != m)
649 {
650 mailbox_free(&shared->mailbox);
651 }
652 }
653 else
654 {
655#ifdef USE_INOTIFY
656 if (monitor_remove_rc == 0)
657 mutt_monitor_add(NULL);
658#endif
659 if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED))
660 update_index(menu, shared->mailboxview, check, *oldcount, shared);
661
662 FREE(&new_last_folder);
663 OptSearchInvalid = true;
665 return;
666 }
668 LastFolder = new_last_folder;
669 }
671
672 /* If the `folder-hook` were to call `unmailboxes`, then the Mailbox (`m`)
673 * could be deleted, leaving `m` dangling. */
674 // TODO: Refactor this function to avoid the need for an observer
676 char *dup_path = mutt_str_dup(mailbox_path(m));
677 char *dup_name = mutt_str_dup(m->name);
678
679 mutt_folder_hook(dup_path, dup_name);
680 if (m)
681 {
682 /* `m` is still valid, but we won't need the observer again before the end
683 * of the function. */
685 }
686 else
687 {
688 // Recreate the Mailbox as the folder-hook might have invoked `mailboxes`
689 // and/or `unmailboxes`.
690 m = mx_path_resolve(dup_path);
691 }
692
693 FREE(&dup_path);
694 FREE(&dup_name);
695
696 if (!m)
697 return;
698
699 const OpenMailboxFlags flags = read_only ? MUTT_READONLY : MUTT_OPEN_NO_FLAGS;
700 if (mx_mbox_open(m, flags))
701 {
702 struct MailboxView *mv = mview_new(m);
704
705 menu->max = m->msg_count;
707#ifdef USE_INOTIFY
708 mutt_monitor_add(NULL);
709#endif
710 }
711 else
712 {
713 index_shared_data_set_context(shared, NULL);
715 }
716
717 const bool c_collapse_all = cs_subset_bool(shared->sub, "collapse_all");
718 if (mutt_using_threads() && c_collapse_all)
719 collapse_all(shared->mailboxview, menu, 0);
720
722 /* force the mailbox check after we have changed the folder */
723 struct EventMailbox ev_m = { shared->mailbox };
726 OptSearchInvalid = true;
727}
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:298
void collapse_all(struct MailboxView *mv, struct Menu *menu, int toggle)
Collapse/uncollapse all threads.
Definition: dlg_index.c:168
char * LastFolder
Previously selected mailbox.
Definition: globals.c:44
bool OptSearchInvalid
(pseudo) used to invalidate the search pattern
Definition: globals.c:85
char * CurrentFolder
Currently selected mailbox.
Definition: globals.c:43
static int index_mailbox_observer(struct NotifyCallback *nc)
Notification that a Mailbox has changed - Implements observer_t -.
Definition: dlg_index.c:591
void mutt_folder_hook(const char *path, const char *desc)
Perform a folder hook.
Definition: hook.c:587
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:209
#define MENU_REDRAW_FULL
Redraw everything.
Definition: lib.h:60
int mutt_monitor_add(struct Mailbox *m)
Add a watch for a mailbox.
Definition: monitor.c:482
int mutt_monitor_remove(struct Mailbox *m)
Remove a watch for a mailbox.
Definition: monitor.c:527
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
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:73
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:305
struct Mailbox * mx_path_resolve(const char *path)
Get a Mailbox for a path.
Definition: mx.c:1684
enum MxStatus mx_mbox_close(struct Mailbox *m)
Save changes and close mailbox.
Definition: mx.c:616
#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
An Event that happened to a Mailbox.
Definition: mailbox.h:185
struct Mailbox * mailbox
The Mailbox this Event relates to.
Definition: mailbox.h:186
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:143
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 740 of file dlg_index.c.

742{
743 if (!nm_url_from_query(NULL, buf, buflen))
744 {
745 mutt_message(_("Failed to create query, aborting"));
746 return NULL;
747 }
748
749 struct Mailbox *m_query = mx_path_resolve(buf);
750 change_folder_mailbox(menu, m_query, oldcount, shared, read_only);
751 return m_query;
752}
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:617
#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:1562
+ 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 764 of file dlg_index.c.

766{
767#ifdef USE_NNTP
768 if (OptNews)
769 {
770 OptNews = false;
772 }
773 else
774#endif
775 {
776 const char *const c_folder = cs_subset_string(shared->sub, "folder");
777 mx_path_canon(buf, buflen, c_folder, NULL);
778 }
779
780 enum MailboxType type = mx_path_probe(buf);
781 if ((type == MUTT_MAILBOX_ERROR) || (type == MUTT_UNKNOWN))
782 {
783 // Look for a Mailbox by its description, before failing
784 struct Mailbox *m = mailbox_find_name(buf);
785 if (m)
786 {
787 change_folder_mailbox(menu, m, oldcount, shared, read_only);
788 }
789 else
790 {
791 mutt_error(_("%s is not a mailbox"), buf);
792 }
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
bool OptNews
(pseudo) used to change reader mode
Definition: globals.c:78
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:1380
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1334
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:565
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:77
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 928 of file dlg_index.c.

929{
930 if (!buf || !stdscr)
931 return;
932
933 size_t i = 0;
934 size_t offset = 0;
935 bool found = false;
936 size_t chunks = 0;
937 size_t len = 0;
938
942 struct StatusSyntax
943 {
944 struct AttrColor *attr_color;
945 int first;
946 int last;
947 } *syntax = NULL;
948
951 do
952 {
953 struct RegexColor *cl = NULL;
954 found = false;
955
956 if (!buf[offset])
957 break;
958
959 /* loop through each "color status regex" */
961 {
962 regmatch_t pmatch[cl->match + 1];
963
964 if (regexec(&cl->regex, buf + offset, cl->match + 1, pmatch, 0) != 0)
965 continue; /* regex doesn't match the status bar */
966
967 int first = pmatch[cl->match].rm_so + offset;
968 int last = pmatch[cl->match].rm_eo + offset;
969
970 if (first == last)
971 continue; /* ignore an empty regex */
972
973 if (!found)
974 {
975 chunks++;
976 mutt_mem_realloc(&syntax, chunks * sizeof(struct StatusSyntax));
977 }
978
979 i = chunks - 1;
980 if (!found || (first < syntax[i].first) ||
981 ((first == syntax[i].first) && (last > syntax[i].last)))
982 {
983 struct AttrColor *ac_merge = merged_color_overlay(ac_base, &cl->attr_color);
984
985 syntax[i].attr_color = ac_merge;
986 syntax[i].first = first;
987 syntax[i].last = last;
988 }
989 found = true;
990 }
991
992 if (syntax)
993 {
994 offset = syntax[i].last;
995 }
996 } while (found);
997
998 /* Only 'len' bytes will fit into 'cols' screen columns */
999 len = mutt_wstr_trunc(buf, buflen, cols, NULL);
1000
1001 offset = 0;
1002
1003 if ((chunks > 0) && (syntax[0].first > 0))
1004 {
1005 /* Text before the first highlight */
1006 mutt_window_addnstr(win, buf, MIN(len, syntax[0].first));
1007 mutt_curses_set_color(ac_base);
1008 if (len <= syntax[0].first)
1009 goto dsl_finish; /* no more room */
1010
1011 offset = syntax[0].first;
1012 }
1013
1014 for (i = 0; i < chunks; i++)
1015 {
1016 /* Highlighted text */
1017 mutt_curses_set_color(syntax[i].attr_color);
1018 mutt_window_addnstr(win, buf + offset, MIN(len, syntax[i].last) - offset);
1019 if (len <= syntax[i].last)
1020 goto dsl_finish; /* no more room */
1021
1022 size_t next;
1023 if ((i + 1) == chunks)
1024 {
1025 next = len;
1026 }
1027 else
1028 {
1029 next = MIN(len, syntax[i + 1].first);
1030 }
1031
1032 mutt_curses_set_color(ac_base);
1033 offset = syntax[i].last;
1034 mutt_window_addnstr(win, buf + offset, next - offset);
1035
1036 offset = next;
1037 if (offset >= len)
1038 goto dsl_finish; /* no more room */
1039 }
1040
1041 mutt_curses_set_color(ac_base);
1042 if (offset < len)
1043 {
1044 /* Text after the last highlight */
1045 mutt_window_addnstr(win, buf + offset, len - offset);
1046 }
1047
1048 int width = mutt_strwidth(buf);
1049 if (width < cols)
1050 {
1051 /* Pad the rest of the line with whitespace */
1052 mutt_paddstr(win, cols - width, "");
1053 }
1054dsl_finish:
1055 FREE(&syntax);
1056}
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:75
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:57
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:859
void mutt_paddstr(struct MuttWindow *win, int n, const char *s)
Display a string on screen, padded if necessary.
Definition: curs_lib.c:817
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:908
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:395
#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 1064 of file dlg_index.c.

1065{
1066 /* Make sure use_threads/sort/sort_aux are coherent */
1068
1069 struct IndexSharedData *shared = dlg->wdata;
1071
1072 struct MuttWindow *panel_index = window_find_child(dlg, WT_INDEX);
1073
1074 struct IndexPrivateData *priv = panel_index->wdata;
1075 priv->attach_msg = OptAttachMsg;
1076 priv->win_index = window_find_child(panel_index, WT_MENU);
1077
1078 int op = OP_NULL;
1079
1080#ifdef USE_NNTP
1081 if (shared->mailbox && (shared->mailbox->type == MUTT_NNTP))
1082 dlg->help_data = IndexNewsHelp;
1083 else
1084#endif
1085 dlg->help_data = IndexHelp;
1086 dlg->help_menu = MENU_INDEX;
1087
1088 priv->menu = priv->win_index->wdata;
1090 priv->menu->color = index_color;
1091 priv->menu->max = shared->mailbox ? shared->mailbox->vcount : 0;
1093 mutt_window_reflow(NULL);
1094
1095 if (!priv->attach_msg)
1096 {
1097 /* force the mailbox check after we enter the folder */
1099 }
1100#ifdef USE_INOTIFY
1101 mutt_monitor_add(NULL);
1102#endif
1103
1104 {
1105 const bool c_collapse_all = cs_subset_bool(shared->sub, "collapse_all");
1106 if (mutt_using_threads() && c_collapse_all)
1107 {
1108 collapse_all(shared->mailboxview, priv->menu, 0);
1110 }
1111 }
1112
1113 int rc = 0;
1114 do
1115 {
1116 /* Clear the tag prefix unless we just started it.
1117 * Don't clear the prefix on a timeout, but do clear on an abort */
1118 if (priv->tag && (op != OP_TAG_PREFIX) && (op != OP_TAG_PREFIX_COND) && (op != OP_TIMEOUT))
1119 {
1120 priv->tag = false;
1121 }
1122
1123 /* check if we need to resort the index because just about
1124 * any 'op' below could do mutt_enter_command(), either here or
1125 * from any new priv->menu launched, and change $sort/$sort_aux */
1126 if (OptNeedResort && shared->mailbox && (shared->mailbox->msg_count != 0) &&
1127 (menu_get_index(priv->menu) >= 0))
1128 {
1130 }
1131
1132 priv->menu->max = shared->mailbox ? shared->mailbox->vcount : 0;
1133 priv->oldcount = shared->mailbox ? shared->mailbox->msg_count : 0;
1134
1135 {
1138 {
1140 OptRedrawTree = false;
1141 }
1142 }
1143
1145 {
1147
1148 shared->mailboxview->menu = priv->menu;
1149 /* check for new mail in the mailbox. If nonzero, then something has
1150 * changed about the file (either we got new mail or the file was
1151 * modified underneath us.) */
1152 enum MxStatus check = mx_mbox_check(shared->mailbox);
1153
1154 if (check == MX_STATUS_ERROR)
1155 {
1157 {
1158 /* fatal error occurred */
1161 }
1162
1163 OptSearchInvalid = true;
1164 }
1165 else if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED) ||
1166 (check == MX_STATUS_FLAGS))
1167 {
1168 /* notify the user of new mail */
1169 if (check == MX_STATUS_REOPENED)
1170 {
1171 mutt_error(_("Mailbox was externally modified. Flags may be wrong."));
1172 }
1173 else if (check == MX_STATUS_NEW_MAIL)
1174 {
1175 for (size_t i = 0; i < shared->mailbox->msg_count; i++)
1176 {
1177 const struct Email *e = shared->mailbox->emails[i];
1178 if (e && !e->read && !e->old)
1179 {
1180 mutt_message(_("New mail in this mailbox"));
1181 const bool c_beep_new = cs_subset_bool(shared->sub, "beep_new");
1182 if (c_beep_new)
1183 mutt_beep(true);
1184 const char *const c_new_mail_command = cs_subset_string(shared->sub, "new_mail_command");
1185 if (c_new_mail_command)
1186 {
1187 char cmd[1024] = { 0 };
1188 menu_status_line(cmd, sizeof(cmd), shared, NULL, sizeof(cmd),
1189 NONULL(c_new_mail_command));
1190 if (mutt_system(cmd) != 0)
1191 mutt_error(_("Error running \"%s\""), cmd);
1192 }
1193 break;
1194 }
1195 }
1196 }
1197 else if (check == MX_STATUS_FLAGS)
1198 {
1199 mutt_message(_("Mailbox was externally modified"));
1200 }
1201
1202 /* avoid the message being overwritten by mailbox */
1203 priv->do_mailbox_notify = false;
1204
1205 bool verbose = shared->mailbox->verbose;
1206 shared->mailbox->verbose = false;
1207 update_index(priv->menu, shared->mailboxview, check, priv->oldcount, shared);
1208 shared->mailbox->verbose = verbose;
1209 priv->menu->max = shared->mailbox->vcount;
1211 OptSearchInvalid = true;
1212 }
1213
1215 menu_get_index(priv->menu)));
1216 }
1217
1218 if (!priv->attach_msg)
1219 {
1220 /* check for new mail in the incoming folders */
1221 priv->oldcount = priv->newcount;
1223 if (priv->do_mailbox_notify)
1224 {
1225 if (mutt_mailbox_notify(shared->mailbox))
1226 {
1227 const bool c_beep_new = cs_subset_bool(shared->sub, "beep_new");
1228 if (c_beep_new)
1229 mutt_beep(true);
1230 const char *const c_new_mail_command = cs_subset_string(shared->sub, "new_mail_command");
1231 if (c_new_mail_command)
1232 {
1233 char cmd[1024] = { 0 };
1234 menu_status_line(cmd, sizeof(cmd), shared, priv->menu, sizeof(cmd),
1235 NONULL(c_new_mail_command));
1236 if (mutt_system(cmd) != 0)
1237 mutt_error(_("Error running \"%s\""), cmd);
1238 }
1239 }
1240 }
1241 else
1242 {
1243 priv->do_mailbox_notify = true;
1244 }
1245 }
1246
1247 window_redraw(NULL);
1248
1249 /* give visual indication that the next command is a tag- command */
1250 if (priv->tag)
1252
1253 const bool c_arrow_cursor = cs_subset_bool(shared->sub, "arrow_cursor");
1254 const bool c_braille_friendly = cs_subset_bool(shared->sub, "braille_friendly");
1255 const int index = menu_get_index(priv->menu);
1256 if (c_arrow_cursor)
1257 {
1258 mutt_window_move(priv->menu->win, 2, index - priv->menu->top);
1259 }
1260 else if (c_braille_friendly)
1261 {
1262 mutt_window_move(priv->menu->win, 0, index - priv->menu->top);
1263 }
1264 else
1265 {
1266 mutt_window_move(priv->menu->win, priv->menu->win->state.cols - 1,
1267 index - priv->menu->top);
1268 }
1269 mutt_refresh();
1270
1271 if (SigWinch)
1272 {
1273 SigWinch = false;
1276 priv->menu->top = 0; /* so we scroll the right amount */
1277 /* force a real complete redraw. clrtobot() doesn't seem to be able
1278 * to handle every case without this. */
1279 clearok(stdscr, true);
1281 continue;
1282 }
1283
1284 window_redraw(NULL);
1285 op = km_dokey(MENU_INDEX);
1286
1287 /* either user abort or timeout */
1288 if (op < OP_NULL)
1289 {
1291 if (priv->tag)
1293 continue;
1294 }
1295
1296 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
1297
1298 /* special handling for the priv->tag-prefix function */
1299 const bool c_auto_tag = cs_subset_bool(shared->sub, "auto_tag");
1300 if ((op == OP_TAG_PREFIX) || (op == OP_TAG_PREFIX_COND))
1301 {
1302 /* A second priv->tag-prefix command aborts */
1303 if (priv->tag)
1304 {
1305 priv->tag = false;
1307 continue;
1308 }
1309
1310 if (!shared->mailbox)
1311 {
1312 mutt_error(_("No mailbox is open"));
1313 continue;
1314 }
1315
1316 if (shared->mailbox->msg_tagged == 0)
1317 {
1318 if (op == OP_TAG_PREFIX)
1319 {
1320 mutt_error(_("No tagged messages"));
1321 }
1322 else if (op == OP_TAG_PREFIX_COND)
1323 {
1325 mutt_message(_("Nothing to do"));
1326 }
1327 continue;
1328 }
1329
1330 /* get the real command */
1331 priv->tag = true;
1332 continue;
1333 }
1334 else if (c_auto_tag && shared->mailbox && (shared->mailbox->msg_tagged != 0))
1335 {
1336 priv->tag = true;
1337 }
1338
1340
1341#ifdef USE_NNTP
1342 OptNews = false; /* for any case */
1343#endif
1344
1345#ifdef USE_NOTMUCH
1346 nm_db_debug_check(shared->mailbox);
1347#endif
1348
1349 rc = index_function_dispatcher(priv->win_index, op);
1350
1351 if (rc == FR_UNKNOWN)
1352 rc = menu_function_dispatcher(priv->win_index, op);
1353
1354#ifdef USE_SIDEBAR
1355 if (rc == FR_UNKNOWN)
1356 {
1357 struct MuttWindow *win_sidebar = window_find_child(dlg, WT_SIDEBAR);
1358 rc = sb_function_dispatcher(win_sidebar, op);
1359 }
1360#endif
1361 if (rc == FR_UNKNOWN)
1362 rc = global_function_dispatcher(NULL, op);
1363
1364 if (rc == FR_UNKNOWN)
1366
1367#ifdef USE_NOTMUCH
1368 nm_db_debug_check(shared->mailbox);
1369#endif
1370 } while (rc != FR_DONE);
1371
1372 mview_free(&shared->mailboxview);
1373
1374 return shared->mailbox;
1375}
void mutt_refresh(void)
Force a refresh of the screen.
Definition: curs_lib.c:139
void mutt_flush_macro_to_endcond(void)
Drop a macro from the input buffer.
Definition: curs_lib.c:571
void mutt_beep(bool force)
Irritate the user.
Definition: curs_lib.c:129
@ 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:119
static const struct Mapping IndexHelp[]
Help Bar for the Index dialog.
Definition: dlg_index.c:103
void resort_index(struct MailboxView *mv, struct Menu *menu)
Resort the index.
Definition: dlg_index.c:362
bool OptAttachMsg
(pseudo) used by attach-message
Definition: globals.c:65
SIG_ATOMIC_VOLATILE_T SigWinch
true after SIGWINCH is received
Definition: globals.c:59
bool OptNeedResort
(pseudo) used to force a re-sort
Definition: globals.c:76
bool OptRedrawTree
(pseudo) redraw the thread tree
Definition: globals.c:83
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:2837
#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:896
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:890
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:797
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: keymap.c:1065
@ LL_DEBUG1
Log at debug level 1.
Definition: logging.h:40
void mailbox_gc_run(void)
Run the garbage-collection.
Definition: mailbox.c:297
@ 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:72
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:390
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:605
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:341
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:294
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:523
void window_invalidate_all(void)
Mark all windows as in need of repaint.
Definition: mutt_window.c:743
@ 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:1133
#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:388
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:46
#define OP_TIMEOUT
Definition: opcodes.h:32
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:446
#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:77
void(* make_entry)(struct Menu *menu, char *buf, size_t buflen, int line)
Definition: lib.h:97
struct AttrColor *(* color)(struct Menu *menu, int line)
Definition: lib.h:134
int top
Entry that is the top of the current page.
Definition: lib.h:81
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 1382 of file dlg_index.c.

1383{
1384 if (!e)
1385 return;
1386
1387 struct RegexColor *color = NULL;
1388 struct PatternCache cache = { 0 };
1389
1390 struct AttrColor *ac_merge = NULL;
1392 {
1394 MUTT_MATCH_FULL_ADDRESS, m, e, &cache))
1395 {
1396 ac_merge = merged_color_overlay(ac_merge, &color->attr_color);
1397 }
1398 }
1399
1400 struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
1401 if (ac_merge)
1402 ac_merge = merged_color_overlay(ac_normal, ac_merge);
1403 else
1404 ac_merge = ac_normal;
1405
1406 e->attr_color = ac_merge;
1407}
@ MT_COLOR_INDEX
Index: default colour.
Definition: color.h:81
struct AttrColor * attr_color
Color-pair to use when displaying in the index.
Definition: email.h:111
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 1413 of file dlg_index.c.

1414{
1418
1419 struct IndexSharedData *shared = index_shared_data_new();
1420 notify_set_parent(shared->notify, dlg->notify);
1421
1422 dlg->wdata = shared;
1424
1425 const bool c_status_on_top = cs_subset_bool(NeoMutt->sub, "status_on_top");
1426
1427 struct MuttWindow *panel_index = ipanel_new(c_status_on_top, shared);
1428 struct MuttWindow *panel_pager = ppanel_new(c_status_on_top, shared);
1429
1430 mutt_window_add_child(dlg, panel_index);
1431 mutt_window_add_child(dlg, panel_pager);
1432
1433 dlg->focus = panel_index;
1434
1435 return dlg;
1436}
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:440
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:180
@ 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:159
+ 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 1443 of file dlg_index.c.

1444{
1445 if (!dlg || !m)
1446 return;
1447
1448 struct IndexSharedData *shared = dlg->wdata;
1449 if (!shared)
1450 return;
1451
1452 struct MuttWindow *panel_index = window_find_child(dlg, WT_INDEX);
1453 if (!panel_index)
1454 return;
1455
1456 struct IndexPrivateData *priv = panel_index->wdata;
1457 if (!priv)
1458 return;
1459
1460 change_folder_mailbox(priv->menu, m, &priv->oldcount, shared, false);
1461}
+ 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 103 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 119 of file dlg_index.c.