NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
lib.h File Reference

GUI manage the main index (list of emails) More...

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "core/lib.h"
#include "functions.h"
#include "mx.h"
#include "shared_data.h"
+ Include dependency graph for lib.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define NT_INDEX_NO_FLAGS   0
 No flags are set.
 
#define NT_INDEX_ADD   (1 << 0)
 New Index Shared Data has been created.
 
#define NT_INDEX_DELETE   (1 << 1)
 Index Shared Data is about to be freed.
 
#define NT_INDEX_SUBSET   (1 << 2)
 Config Subset has changed.
 
#define NT_INDEX_ACCOUNT   (1 << 3)
 Account has changed.
 
#define NT_INDEX_MVIEW   (1 << 4)
 MailboxView has changed.
 
#define NT_INDEX_MAILBOX   (1 << 5)
 Mailbox has changed.
 
#define NT_INDEX_EMAIL   (1 << 6)
 Email has changed.
 
#define CHECK_NO_FLAGS   0
 No flags are set.
 
#define CHECK_IN_MAILBOX   (1 << 0)
 Is there a mailbox open?
 
#define CHECK_MSGCOUNT   (1 << 1)
 Are there any messages?
 
#define CHECK_VISIBLE   (1 << 2)
 Is the selected message visible in the index?
 
#define CHECK_READONLY   (1 << 3)
 Is the mailbox readonly?
 
#define CHECK_ATTACH   (1 << 4)
 Is the user in message-attach mode?
 

Typedefs

typedef uint8_t NotifyIndex
 Flags, e.g. NT_INDEX_ACCOUNT.
 
typedef uint8_t CheckFlags
 Flags, e.g. CHECK_IN_MAILBOX.
 

Functions

const struct AttrColorindex_color (struct Menu *menu, int line)
 Calculate the colour for a line of the index - Implements Menu::color() -.
 
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() -.
 
void mutt_draw_statusline (struct MuttWindow *win, int cols, const char *buf, size_t buflen)
 Draw a highlighted status bar.
 
struct Mailboxdlg_index (struct MuttWindow *dlg, struct Mailbox *m)
 Display a list of emails -.
 
void mutt_set_header_color (struct Mailbox *m, struct Email *e)
 Select a colour for a message.
 
struct MuttWindowindex_pager_init (void)
 Allocate the Windows for the Index/Pager.
 
int mutt_dlgindex_observer (struct NotifyCallback *nc)
 
bool check_acl (struct Mailbox *m, AclFlags acl, const char *msg)
 Check the ACLs for a function.
 
int find_next_undeleted (struct MailboxView *mv, int msgno, bool uncollapse)
 Find the next undeleted email.
 
void update_index (struct Menu *menu, struct MailboxView *mv, enum MxStatus check, int oldcount, const struct IndexSharedData *shared)
 Update the index.
 
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.
 
void collapse_all (struct MailboxView *mv, struct Menu *menu, int toggle)
 Collapse/uncollapse all threads.
 
void change_folder_string (struct Menu *menu, struct Buffer *buf, int *oldcount, struct IndexSharedData *shared, bool read_only)
 Change to a different Mailbox by string.
 
int find_previous_undeleted (struct MailboxView *mv, int msgno, bool uncollapse)
 Find the previous undeleted email.
 
int find_first_message (struct MailboxView *mv)
 Get index of first new message.
 
void resort_index (struct MailboxView *mv, struct Menu *menu)
 Resort the index.
 
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.
 
struct Mailboxget_current_mailbox (void)
 Get the current Mailbox.
 
struct MailboxViewget_current_mailbox_view (void)
 Get the current Mailbox view.
 
struct Menuget_current_menu (void)
 Get the current Menu.
 
void index_change_folder (struct MuttWindow *dlg, struct Mailbox *m)
 Change the current folder, cautiously.
 

Variables

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

Detailed Description

GUI manage the main index (list of emails)

Authors
  • Richard Russon

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

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

Definition in file lib.h.

Macro Definition Documentation

◆ NT_INDEX_NO_FLAGS

#define NT_INDEX_NO_FLAGS   0

No flags are set.

Definition at line 59 of file lib.h.

◆ NT_INDEX_ADD

#define NT_INDEX_ADD   (1 << 0)

New Index Shared Data has been created.

Definition at line 60 of file lib.h.

◆ NT_INDEX_DELETE

#define NT_INDEX_DELETE   (1 << 1)

Index Shared Data is about to be freed.

Definition at line 61 of file lib.h.

◆ NT_INDEX_SUBSET

#define NT_INDEX_SUBSET   (1 << 2)

Config Subset has changed.

Definition at line 62 of file lib.h.

◆ NT_INDEX_ACCOUNT

#define NT_INDEX_ACCOUNT   (1 << 3)

Account has changed.

Definition at line 63 of file lib.h.

◆ NT_INDEX_MVIEW

#define NT_INDEX_MVIEW   (1 << 4)

MailboxView has changed.

Definition at line 64 of file lib.h.

◆ NT_INDEX_MAILBOX

#define NT_INDEX_MAILBOX   (1 << 5)

Mailbox has changed.

Definition at line 65 of file lib.h.

◆ NT_INDEX_EMAIL

#define NT_INDEX_EMAIL   (1 << 6)

Email has changed.

Definition at line 66 of file lib.h.

◆ CHECK_NO_FLAGS

#define CHECK_NO_FLAGS   0

No flags are set.

Definition at line 69 of file lib.h.

◆ CHECK_IN_MAILBOX

#define CHECK_IN_MAILBOX   (1 << 0)

Is there a mailbox open?

Definition at line 70 of file lib.h.

◆ CHECK_MSGCOUNT

#define CHECK_MSGCOUNT   (1 << 1)

Are there any messages?

Definition at line 71 of file lib.h.

◆ CHECK_VISIBLE

#define CHECK_VISIBLE   (1 << 2)

Is the selected message visible in the index?

Definition at line 72 of file lib.h.

◆ CHECK_READONLY

#define CHECK_READONLY   (1 << 3)

Is the mailbox readonly?

Definition at line 73 of file lib.h.

◆ CHECK_ATTACH

#define CHECK_ATTACH   (1 << 4)

Is the user in message-attach mode?

Definition at line 74 of file lib.h.

Typedef Documentation

◆ NotifyIndex

typedef uint8_t NotifyIndex

Flags, e.g. NT_INDEX_ACCOUNT.

Definition at line 58 of file lib.h.

◆ CheckFlags

typedef uint8_t CheckFlags

Flags, e.g. CHECK_IN_MAILBOX.

Definition at line 68 of file lib.h.

Function Documentation

◆ 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 924 of file dlg_index.c.

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

1375{
1376 if (!e)
1377 return;
1378
1379 struct RegexColor *color = NULL;
1380 struct PatternCache cache = { 0 };
1381
1382 const struct AttrColor *ac_merge = NULL;
1384 {
1386 MUTT_MATCH_FULL_ADDRESS, m, e, &cache))
1387 {
1388 ac_merge = merged_color_overlay(ac_merge, &color->attr_color);
1389 }
1390 }
1391
1392 struct AttrColor *ac_normal = simple_color_get(MT_COLOR_NORMAL);
1393 if (ac_merge)
1394 ac_merge = merged_color_overlay(ac_normal, ac_merge);
1395 else
1396 ac_merge = ac_normal;
1397
1398 e->attr_color = ac_merge;
1399}
@ MT_COLOR_INDEX
Index: default colour.
Definition: color.h:83
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:1137
#define MUTT_MATCH_FULL_ADDRESS
Match the full address.
Definition: lib.h:106
#define SLIST_FIRST(head)
Definition: queue.h:229
const struct AttrColor * attr_color
Color-pair to use when displaying in the index.
Definition: email.h:111
Cache commonly-used patterns.
Definition: lib.h:117
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 1405 of file dlg_index.c.

1406{
1410
1411 struct IndexSharedData *shared = index_shared_data_new();
1412 notify_set_parent(shared->notify, dlg->notify);
1413
1414 dlg->wdata = shared;
1416
1417 const bool c_status_on_top = cs_subset_bool(NeoMutt->sub, "status_on_top");
1418
1419 struct MuttWindow *panel_index = ipanel_new(c_status_on_top, shared);
1420 struct MuttWindow *panel_pager = ppanel_new(c_status_on_top, shared);
1421
1422 mutt_window_add_child(dlg, panel_index);
1423 mutt_window_add_child(dlg, panel_pager);
1424
1425 return dlg;
1426}
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
void index_shared_data_free(struct MuttWindow *win, void **ptr)
Free Shared Index Data - Implements MuttWindow::wdata_free() -.
Definition: shared_data.c:277
struct IndexSharedData * index_shared_data_new(void)
Create new Index Data.
Definition: shared_data.c:306
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:95
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:446
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:182
@ WT_DLG_INDEX
Index Dialog, dlg_index()
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
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:37
struct Notify * notify
Notifications: NotifyIndex, IndexSharedData.
Definition: shared_data.h:44
void * wdata
Private data.
Definition: mutt_window.h:145
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
void(* wdata_free)(struct MuttWindow *win, void **ptr)
Definition: mutt_window.h:159
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_dlgindex_observer()

int mutt_dlgindex_observer ( struct NotifyCallback nc)

◆ 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 140 of file dlg_index.c.

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

◆ find_next_undeleted()

int find_next_undeleted ( struct MailboxView mv,
int  msgno,
bool  uncollapse 
)

Find the next undeleted email.

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

Definition at line 243 of file dlg_index.c.

244{
245 if (!mv || !mv->mailbox)
246 return -1;
247
248 struct Mailbox *m = mv->mailbox;
249
250 int index = -1;
251 for (int i = msgno + 1; i < m->vcount; i++)
252 {
253 struct Email *e = mutt_get_virt_email(m, i);
254 if (!e)
255 continue;
256 if (!e->deleted)
257 {
258 index = i;
259 break;
260 }
261 }
262
263 if (uncollapse)
265
266 return index;
267}
static void uncollapse_thread(struct MailboxView *mv, int index)
Open a collapsed thread.
Definition: dlg_index.c:221
struct Email * mutt_get_virt_email(struct Mailbox *m, int vnum)
Get a virtual Email.
Definition: mview.c:419
The envelope/body of an email.
Definition: email.h:37
bool deleted
Email is deleted.
Definition: email.h:76
int index
The absolute (unsorted) message number.
Definition: email.h:109
struct Mailbox * mailbox
Current Mailbox.
Definition: mview.h:50
A mailbox.
Definition: mailbox.h:79
int vcount
The number of virtual messages.
Definition: mailbox.h:99
+ 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 544 of file dlg_index.c.

546{
547 if (!menu || !mv)
548 return;
549
550 struct Mailbox *m = mv->mailbox;
551 if (mutt_using_threads())
552 update_index_threaded(mv, check, oldcount);
553 else
554 update_index_unthreaded(mv, check);
555
556 const int old_index = menu_get_index(menu);
557 int index = -1;
558 if (oldcount)
559 {
560 /* restore the current message to the message it was pointing to */
561 for (int i = 0; i < m->vcount; i++)
562 {
563 struct Email *e = mutt_get_virt_email(m, i);
564 if (!e)
565 continue;
566 if (index_shared_data_is_cur_email(shared, e))
567 {
568 index = i;
569 break;
570 }
571 }
572 }
573
574 if (index < 0)
575 {
576 index = (old_index < m->vcount) ? old_index : find_first_message(mv);
577 }
578 menu_set_index(menu, index);
579}
int find_first_message(struct MailboxView *mv)
Get index of first new message.
Definition: dlg_index.c:311
static void update_index_threaded(struct MailboxView *mv, enum MxStatus check, int oldcount)
Update the index (if threaded)
Definition: dlg_index.c:413
static void update_index_unthreaded(struct MailboxView *mv, enum MxStatus check)
Update the index (if unthreaded)
Definition: dlg_index.c:495
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:263
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition: menu.c:156
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition: menu.c:170
#define mutt_using_threads()
Definition: mutt_thread.h:112
+ Here is the call graph for this function:
+ Here is the caller 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 612 of file dlg_index.c.

614{
615 if (!m)
616 return;
617
618 /* keepalive failure in mutt_enter_fname may kill connection. */
619 if (shared->mailbox && (buf_is_empty(&shared->mailbox->pathbuf)))
620 {
621 mview_free(&shared->mailbox_view);
622 mailbox_free(&shared->mailbox);
623 }
624
625 if (shared->mailbox)
626 {
627 char *new_last_folder = NULL;
628#ifdef USE_INOTIFY
629 int monitor_remove_rc = mutt_monitor_remove(NULL);
630#endif
631#ifdef USE_COMP_MBOX
632 if (shared->mailbox->compress_info && (shared->mailbox->realpath[0] != '\0'))
633 new_last_folder = mutt_str_dup(shared->mailbox->realpath);
634 else
635#endif
636 new_last_folder = mutt_str_dup(mailbox_path(shared->mailbox));
637 *oldcount = shared->mailbox->msg_count;
638
639 const enum MxStatus check = mx_mbox_close(shared->mailbox);
640 if (check == MX_STATUS_OK)
641 {
642 mview_free(&shared->mailbox_view);
643 if (shared->mailbox != m)
644 {
645 mailbox_free(&shared->mailbox);
646 }
647 }
648 else
649 {
650#ifdef USE_INOTIFY
651 if (monitor_remove_rc == 0)
652 mutt_monitor_add(NULL);
653#endif
654 if ((check == MX_STATUS_NEW_MAIL) || (check == MX_STATUS_REOPENED))
655 update_index(menu, shared->mailbox_view, check, *oldcount, shared);
656
657 FREE(&new_last_folder);
660 return;
661 }
663 LastFolder = new_last_folder;
664 }
666
667 /* If the `folder-hook` were to call `unmailboxes`, then the Mailbox (`m`)
668 * could be deleted, leaving `m` dangling. */
669 // TODO: Refactor this function to avoid the need for an observer
671 char *dup_path = mutt_str_dup(mailbox_path(m));
672 char *dup_name = mutt_str_dup(m->name);
673
674 mutt_folder_hook(dup_path, dup_name);
675 if (m)
676 {
677 /* `m` is still valid, but we won't need the observer again before the end
678 * of the function. */
680 }
681 else
682 {
683 // Recreate the Mailbox as the folder-hook might have invoked `mailboxes`
684 // and/or `unmailboxes`.
685 m = mx_path_resolve(dup_path);
686 }
687
688 FREE(&dup_path);
689 FREE(&dup_name);
690
691 if (!m)
692 return;
693
694 const OpenMailboxFlags flags = read_only ? MUTT_READONLY : MUTT_OPEN_NO_FLAGS;
695 if (mx_mbox_open(m, flags))
696 {
697 struct MailboxView *mv = mview_new(m, NeoMutt->notify);
698 index_shared_data_set_mview(shared, mv);
699
700 menu->max = m->msg_count;
702#ifdef USE_INOTIFY
703 mutt_monitor_add(NULL);
704#endif
705 }
706 else
707 {
708 index_shared_data_set_mview(shared, NULL);
710 }
711
712 const bool c_collapse_all = cs_subset_bool(shared->sub, "collapse_all");
713 if (mutt_using_threads() && c_collapse_all)
714 collapse_all(shared->mailbox_view, menu, 0);
715
717 /* force the mailbox check after we have changed the folder */
718 struct EventMailbox ev_m = { shared->mailbox };
722}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:303
void mutt_pattern_free(struct PatternList **pat)
Free a Pattern.
Definition: compile.c:778
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:544
void collapse_all(struct MailboxView *mv, struct Menu *menu, int toggle)
Collapse/uncollapse all threads.
Definition: dlg_index.c:167
char * LastFolder
Previously selected mailbox.
Definition: globals.c:45
char * CurrentFolder
Currently selected mailbox.
Definition: globals.c:44
static int index_mailbox_observer(struct NotifyCallback *nc)
Notification that a Mailbox has changed - Implements observer_t -.
Definition: dlg_index.c:586
void mutt_folder_hook(const char *path, const char *desc)
Perform a folder hook.
Definition: hook.c:588
void index_shared_data_set_mview(struct IndexSharedData *shared, struct MailboxView *mv)
Set the MailboxView for the Index and friends.
Definition: shared_data.c:159
void mailbox_free(struct Mailbox **ptr)
Free a Mailbox.
Definition: mailbox.c:90
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:60
#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:180
int mutt_monitor_add(struct Mailbox *m)
Add a watch for a mailbox.
Definition: monitor.c:480
int mutt_monitor_remove(struct Mailbox *m)
Remove a watch for a mailbox.
Definition: monitor.c:524
bool notify_observer_remove(struct Notify *notify, const observer_t callback, const void *global_data)
Remove an observer from an object.
Definition: notify.c:230
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:191
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:327
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:165
void mview_free(struct MailboxView **ptr)
Free a MailboxView.
Definition: mview.c:49
struct MailboxView * mview_new(struct Mailbox *m, struct Notify *parent)
Create a new MailboxView.
Definition: mview.c:90
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:1697
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:43
uint8_t OpenMailboxFlags
Flags for mutt_open_mailbox(), e.g. MUTT_NOSORT.
Definition: mxapi.h:39
#define MUTT_OPEN_NO_FLAGS
No flags are set.
Definition: mxapi.h:40
#define MUTT_MAILBOX_CHECK_FORCE
Ignore MailboxTime and check for new mail.
Definition: mxapi.h:54
MxStatus
Return values from mbox_check(), mbox_check_stats(), mbox_snc(), and mbox_close()
Definition: mxapi.h:63
@ MX_STATUS_OK
No changes.
Definition: mxapi.h:65
@ MX_STATUS_REOPENED
Mailbox was reopened.
Definition: mxapi.h:68
@ MX_STATUS_NEW_MAIL
New mail received in Mailbox.
Definition: mxapi.h:66
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:49
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 Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
struct ConfigSubset * sub
Config set to use.
Definition: shared_data.h:38
struct MailboxView * mailbox_view
Current Mailbox view.
Definition: shared_data.h:40
struct SearchState * search_state
State of the current search.
Definition: shared_data.h:45
View of a Mailbox.
Definition: mview.h:39
struct Menu * menu
Needed for pattern compilation.
Definition: mview.h:46
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
int msg_count
Total number of messages.
Definition: mailbox.h:88
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:121
int max
Number of entries in the menu.
Definition: lib.h:72
struct Notify * notify
Notifications handler.
Definition: neomutt.h:42
struct PatternList * pattern
compiled search pattern
Definition: search_state.h:36
+ Here is the call graph for this function:
+ 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 167 of file dlg_index.c.

168{
169 if (!mv || !mv->mailbox || (mv->mailbox->msg_count == 0) || !menu)
170 return;
171
172 struct Email *e_cur = mutt_get_virt_email(mv->mailbox, menu_get_index(menu));
173 if (!e_cur)
174 return;
175
176 int final;
177
178 /* Figure out what the current message would be after folding / unfolding,
179 * so that we can restore the cursor in a sane way afterwards. */
180 if (e_cur->collapsed && toggle)
181 final = mutt_uncollapse_thread(e_cur);
182 else if (mutt_thread_can_collapse(e_cur))
183 final = mutt_collapse_thread(e_cur);
184 else
185 final = e_cur->vnum;
186
187 if (final == -1)
188 return;
189
190 struct Email *base = mutt_get_virt_email(mv->mailbox, final);
191 if (!base)
192 return;
193
194 /* Iterate all threads, perform collapse/uncollapse as needed */
195 mv->collapsed = toggle ? !mv->collapsed : true;
197
198 /* Restore the cursor */
200 menu->max = mv->mailbox->vcount;
201 for (int i = 0; i < mv->mailbox->vcount; i++)
202 {
203 struct Email *e = mutt_get_virt_email(mv->mailbox, i);
204 if (!e)
205 break;
206 if (e->index == base->index)
207 {
208 menu_set_index(menu, i);
209 break;
210 }
211 }
212
214}
void mutt_thread_collapse(struct ThreadsContext *tctx, bool collapse)
Toggle collapse.
Definition: mutt_thread.c:1786
off_t mutt_set_vnum(struct Mailbox *m)
Set the virtual index number of all the messages in a mailbox.
Definition: mutt_thread.c:1401
bool mutt_thread_can_collapse(struct Email *e)
Check whether a thread can be collapsed.
Definition: mutt_thread.c:1814
#define mutt_uncollapse_thread(e)
Definition: mutt_thread.h:106
#define mutt_collapse_thread(e)
Definition: mutt_thread.h:105
bool collapsed
Is this message part of a collapsed thread?
Definition: email.h:119
int vnum
Virtual message number.
Definition: email.h:113
bool collapsed
Are all threads collapsed?
Definition: mview.h:48
struct ThreadsContext * threads
Threads context.
Definition: mview.h:43
+ 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,
struct Buffer buf,
int *  oldcount,
struct IndexSharedData shared,
bool  read_only 
)

Change to a different Mailbox by string.

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

Definition at line 758 of file dlg_index.c.

760{
761#ifdef USE_NNTP
762 if (OptNews)
763 {
764 OptNews = false;
766 }
767 else
768#endif
769 {
770 const char *const c_folder = cs_subset_string(shared->sub, "folder");
771 mx_path_canon(buf, c_folder, NULL);
772 }
773
774 enum MailboxType type = mx_path_probe(buf_string(buf));
775 if ((type == MUTT_MAILBOX_ERROR) || (type == MUTT_UNKNOWN))
776 {
777 // Look for a Mailbox by its description, before failing
778 struct Mailbox *m = mailbox_find_name(buf_string(buf));
779 if (m)
780 {
781 change_folder_mailbox(menu, m, oldcount, shared, read_only);
782 }
783 else
784 {
785 mutt_error(_("%s is not a mailbox"), buf_string(buf));
786 }
787 return;
788 }
789
790 struct Mailbox *m = mx_path_resolve(buf_string(buf));
791 change_folder_mailbox(menu, m, oldcount, shared, read_only);
792}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:292
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:612
bool OptNews
(pseudo) used to change reader mode
Definition: globals.c:76
struct Mailbox * mailbox_find_name(const char *name)
Find the mailbox with a given name.
Definition: mailbox.c:180
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(struct Buffer *path, const char *folder, enum MailboxType *type)
Canonicalise a mailbox path - Wrapper for MxOps::path_canon()
Definition: mx.c:1389
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1343
void nntp_expand_path(char *buf, size_t buflen, struct ConnAccount *acct)
Make fully qualified url from newsgroup name.
Definition: newsrc.c:564
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:77
size_t dsize
Length of data.
Definition: buffer.h:37
char * data
Pointer to data.
Definition: buffer.h:35
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:50
struct Connection * conn
Connection to NNTP Server.
Definition: adata.h:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ find_previous_undeleted()

int find_previous_undeleted ( struct MailboxView mv,
int  msgno,
bool  uncollapse 
)

Find the previous undeleted email.

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

Definition at line 277 of file dlg_index.c.

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

◆ find_first_message()

int find_first_message ( struct MailboxView mv)

Get index of first new message.

Parameters
mvMailbox view
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 311 of file dlg_index.c.

312{
313 if (!mv)
314 return 0;
315
316 struct Mailbox *m = mv->mailbox;
317 if (!m || (m->msg_count == 0))
318 return 0;
319
320 int old = -1;
321 for (int i = 0; i < m->vcount; i++)
322 {
323 struct Email *e = mutt_get_virt_email(m, i);
324 if (!e)
325 continue;
326 if (!e->read && !e->deleted)
327 {
328 if (!e->old)
329 return i;
330 if (old == -1)
331 old = i;
332 }
333 }
334 if (old != -1)
335 return old;
336
337 /* If `$use_threads` is not threaded and `$sort` is reverse, the latest
338 * message is first. Otherwise, the latest message is first if exactly
339 * one of `$use_threads` and `$sort` are reverse.
340 */
341 enum SortType c_sort = cs_subset_sort(m->sub, "sort");
342 if ((c_sort & SORT_MASK) == SORT_THREADS)
343 c_sort = cs_subset_sort(m->sub, "sort_aux");
344 bool reverse = false;
345 switch (mutt_thread_style())
346 {
347 case UT_FLAT:
348 reverse = c_sort & SORT_REVERSE;
349 break;
350 case UT_THREADS:
351 reverse = c_sort & SORT_REVERSE;
352 break;
353 case UT_REVERSE:
354 reverse = !(c_sort & SORT_REVERSE);
355 break;
356 default:
357 assert(false);
358 }
359
360 if (reverse || (m->vcount == 0))
361 return 0;
362
363 return m->vcount - 1;
364}
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:267
enum UseThreads mutt_thread_style(void)
Which threading style is active?
Definition: mutt_thread.c:79
@ UT_FLAT
Unthreaded.
Definition: mutt_thread.h:97
@ UT_THREADS
Normal threading (root above subthreads)
Definition: mutt_thread.h:98
@ UT_REVERSE
Reverse threading (subthreads above root)
Definition: mutt_thread.h:99
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:74
SortType
Methods for sorting.
Definition: sort2.h:38
@ 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 371 of file dlg_index.c.

372{
373 if (!mv || !mv->mailbox || !menu)
374 return;
375
376 struct Mailbox *m = mv->mailbox;
377 const int old_index = menu_get_index(menu);
378 struct Email *e_cur = mutt_get_virt_email(m, old_index);
379
380 int new_index = -1;
381 mutt_sort_headers(mv, false);
382
383 /* Restore the current message */
384 for (int i = 0; i < m->vcount; i++)
385 {
386 struct Email *e = mutt_get_virt_email(m, i);
387 if (!e)
388 continue;
389 if (e == e_cur)
390 {
391 new_index = i;
392 break;
393 }
394 }
395
396 if (mutt_using_threads() && (old_index < 0))
397 new_index = mutt_parent_message(e_cur, false);
398
399 if (old_index < 0)
400 new_index = find_first_message(mv);
401
402 menu->max = m->vcount;
403 menu_set_index(menu, new_index);
405}
int mutt_parent_message(struct Email *e, bool find_root)
Find the parent of a message.
Definition: mutt_thread.c:1351
void mutt_sort_headers(struct MailboxView *mv, bool init)
Sort emails by their headers.
Definition: sort.c:352
+ 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 735 of file dlg_index.c.

737{
738 if (!nm_url_from_query(NULL, buf, buflen))
739 {
740 mutt_message(_("Failed to create query, aborting"));
741 return NULL;
742 }
743
744 struct Mailbox *m_query = mx_path_resolve(buf);
745 change_folder_mailbox(menu, m_query, oldcount, shared, read_only);
746 return m_query;
747}
#define mutt_message(...)
Definition: logging2.h:91
char * nm_url_from_query(struct Mailbox *m, char *buf, size_t buflen)
Turn a query into a URL.
Definition: notmuch.c:1565
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_current_mailbox()

struct Mailbox * get_current_mailbox ( void  )

Get the current Mailbox.

Return values
ptrCurrent Mailbox

Search for the last (most recent) dialog that has an Index. Then return the Mailbox from its shared data.

Definition at line 662 of file index.c.

663{
665 if (mv)
666 return mv->mailbox;
667
668 return NULL;
669}
struct MailboxView * get_current_mailbox_view(void)
Get the current Mailbox view.
Definition: index.c:630
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_current_mailbox_view()

struct MailboxView * get_current_mailbox_view ( void  )

Get the current Mailbox view.

Return values
ptrCurrent Mailbox view

Search for the last (most recent) dialog that has an Index. Then return the Mailbox from its shared data.

Definition at line 630 of file index.c.

631{
632 if (!AllDialogsWindow)
633 return NULL;
634
635 struct MuttWindow *np = NULL;
636 TAILQ_FOREACH_REVERSE(np, &AllDialogsWindow->children, MuttWindowList, entries)
637 {
638 struct MuttWindow *win = window_find_child(np, WT_DLG_INDEX);
639 if (win)
640 {
641 struct IndexSharedData *shared = win->wdata;
642 return shared->mailbox_view;
643 }
644
646 if (win)
647 {
648 return postponed_get_mailbox_view(win);
649 }
650 }
651
652 return NULL;
653}
struct MuttWindow * AllDialogsWindow
Parent of all Dialogs.
Definition: dialog.c:80
struct MuttWindow * window_find_child(struct MuttWindow *win, enum WindowType type)
Recursively find a child Window of a given type.
Definition: mutt_window.c:533
@ WT_DLG_POSTPONED
Postponed Dialog, dlg_postponed()
Definition: mutt_window.h:89
struct MailboxView * postponed_get_mailbox_view(struct MuttWindow *dlg)
Extract the Mailbox from the Postponed Dialog.
Definition: functions.c:212
#define TAILQ_FOREACH_REVERSE(var, head, headname, field)
Definition: queue.h:745
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:136
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ get_current_menu()

struct Menu * get_current_menu ( void  )

Get the current Menu.

Return values
ptrCurrent Menu

Search for the last (most recent) dialog that has an Index. Then return the Menu from its private data.

Definition at line 678 of file index.c.

679{
680 if (!AllDialogsWindow)
681 return NULL;
682
683 struct MuttWindow *np = NULL;
684 TAILQ_FOREACH_REVERSE(np, &AllDialogsWindow->children, MuttWindowList, entries)
685 {
686 struct MuttWindow *dlg = window_find_child(np, WT_DLG_INDEX);
687 if (dlg)
688 {
689 struct MuttWindow *panel_index = window_find_child(dlg, WT_INDEX);
690 struct IndexPrivateData *priv = panel_index->wdata;
691 return priv->menu;
692 }
693 }
694
695 return NULL;
696}
@ WT_INDEX
A panel containing the Index Window.
Definition: mutt_window.h:97
Private state data for the Index.
Definition: private_data.h:35
struct Menu * menu
Menu controlling the index.
Definition: private_data.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ index_change_folder()

void index_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}
struct IndexSharedData * shared
Shared Index data.
Definition: private_data.h:41
int oldcount
Old count of Emails in the Mailbox.
Definition: private_data.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ IndexNewsHelp

const struct Mapping IndexNewsHelp[]
extern

Help Bar for the News Index dialog.

Definition at line 118 of file dlg_index.c.