NeoMutt  2024-10-02-37-gfa9146
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
window.c File Reference

Sidebar Window. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "private.h"
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "color/lib.h"
#include "expando/lib.h"
#include "index/lib.h"
+ Include dependency graph for window.c:

Go to the source code of this file.

Data Structures

struct  SidebarData
 Data passed to sidebar_format_str() More...
 

Functions

static int imap_is_prefix (const char *folder, const char *mbox)
 Check if folder matches the beginning of mbox.
 
static const char * abbrev_folder (const char *mbox, const char *folder, enum MailboxType type)
 Abbreviate a Mailbox path using a folder.
 
static const char * abbrev_url (const char *mbox, enum MailboxType type)
 Abbreviate a url-style Mailbox path.
 
static size_t add_indent (char *buf, size_t buflen, const struct SbEntry *sbe)
 Generate the needed indentation.
 
static const struct AttrColorcalc_color (const struct Mailbox *m, bool current, bool highlight)
 Calculate the colour of a Sidebar row.
 
static int calc_path_depth (const char *mbox, const char *delims, const char **last_part)
 Calculate the depth of a Mailbox path.
 
void sidebar_bang (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
 Sidebar: Flagged flags - Implements ExpandoRenderData::get_string() -.
 
long sidebar_a_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Alert for new mail - Implements ExpandoRenderData::get_number() -.
 
void sidebar_B (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
 Sidebar: Name of the mailbox - Implements ExpandoRenderData::get_string() -.
 
long sidebar_d_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Number of deleted messages - Implements ExpandoRenderData::get_number() -.
 
void sidebar_D (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
 Sidebar: Descriptive name - Implements ExpandoRenderData::get_string() -.
 
long sidebar_F_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Number of flagged messages - Implements ExpandoRenderData::get_number() -.
 
long sidebar_L_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Number of limited messages - Implements ExpandoRenderData::get_number() -.
 
long sidebar_n_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: New mail flag - Implements ExpandoRenderData::get_number() -.
 
void sidebar_n (const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
 Sidebar: New mail flag - Implements ExpandoRenderData::get_string() -.
 
long sidebar_N_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Number of unread messages - Implements ExpandoRenderData::get_number() -.
 
long sidebar_o_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Number of old messages - Implements ExpandoRenderData::get_number() -.
 
long sidebar_p_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Poll for new mail - Implements ExpandoRenderData::get_number() -.
 
long sidebar_r_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Number of read messages - Implements ExpandoRenderData::get_number() -.
 
long sidebar_S_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: number of messages - Implements ExpandoRenderData::get_number() -.
 
long sidebar_t_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Number of tagged messages - Implements ExpandoRenderData::get_number() -.
 
long sidebar_Z_num (const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
 Sidebar: Number of new messages - Implements ExpandoRenderData::get_number() -.
 
static void make_sidebar_entry (char *buf, size_t buflen, int width, struct SbEntry *sbe, struct IndexSharedData *shared)
 Turn mailbox data into a sidebar string.
 
static void update_entries_visibility (struct SidebarWindowData *wdata)
 Should a SbEntry be displayed in the sidebar?
 
static bool prepare_sidebar (struct SidebarWindowData *wdata, int page_size)
 Prepare the list of SbEntry's for the sidebar display.
 
int sb_recalc (struct MuttWindow *win)
 Recalculate the Sidebar display - Implements MuttWindow::recalc() -.
 
static int draw_divider (struct SidebarWindowData *wdata, struct MuttWindow *win, int num_rows, int num_cols)
 Draw a line between the sidebar and the rest of neomutt.
 
static void fill_empty_space (struct MuttWindow *win, int first_row, int num_rows, int div_width, int num_cols)
 Wipe the remaining Sidebar space.
 
int sb_repaint (struct MuttWindow *win)
 Repaint the Sidebar display - Implements MuttWindow::repaint() -.
 

Variables

const struct ExpandoRenderData SidebarRenderData []
 Callbacks for Sidebar Expandos.
 

Detailed Description

Sidebar Window.

Authors
  • Kevin J. McCarthy
  • R Primus
  • Pietro Cerutti
  • Richard Russon
  • Ashish Panigrahi
  • Tóth János

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 window.c.

Function Documentation

◆ imap_is_prefix()

static int imap_is_prefix ( const char *  folder,
const char *  mbox 
)
static

Check if folder matches the beginning of mbox.

Parameters
folderFolder
mboxMailbox path
Return values
numLength of the prefix

Definition at line 100 of file window.c.

101{
102 int plen = 0;
103
104 struct Url *url_m = url_parse(mbox);
105 struct Url *url_f = url_parse(folder);
106 if (!url_m || !url_f)
107 goto done;
108
109 if (!mutt_istr_equal(url_m->host, url_f->host))
110 goto done;
111
112 if (url_m->user && url_f->user && !mutt_istr_equal(url_m->user, url_f->user))
113 goto done;
114
115 size_t mlen = mutt_str_len(url_m->path);
116 size_t flen = mutt_str_len(url_f->path);
117 if (flen > mlen)
118 goto done;
119
120 if (!mutt_strn_equal(url_m->path, url_f->path, flen))
121 goto done;
122
123 plen = strlen(mbox) - mlen + flen;
124
125done:
126 url_free(&url_m);
127 url_free(&url_f);
128
129 return plen;
130}
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:672
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:425
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:496
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:69
char * user
Username.
Definition: url.h:71
char * host
Host.
Definition: url.h:73
char * path
Path.
Definition: url.h:75
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:239
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:124
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ abbrev_folder()

static const char * abbrev_folder ( const char *  mbox,
const char *  folder,
enum MailboxType  type 
)
static

Abbreviate a Mailbox path using a folder.

Parameters
mboxMailbox path to shorten
folderFolder path to use
typeMailbox type
Return values
ptrPointer into the mbox param

Definition at line 139 of file window.c.

140{
141 if (!mbox || !folder)
142 return NULL;
143
144 if (type == MUTT_IMAP)
145 {
146 int prefix = imap_is_prefix(folder, mbox);
147 if (prefix == 0)
148 return NULL;
149 return mbox + prefix;
150 }
151
152 const char *const c_sidebar_delim_chars = cs_subset_string(NeoMutt->sub, "sidebar_delim_chars");
153 if (!c_sidebar_delim_chars)
154 return NULL;
155
156 size_t flen = mutt_str_len(folder);
157 if (flen == 0)
158 return NULL;
159 if (strchr(c_sidebar_delim_chars, folder[flen - 1])) // folder ends with a delimiter
160 flen--;
161
162 size_t mlen = mutt_str_len(mbox);
163 if (mlen < flen)
164 return NULL;
165
166 if (!mutt_strn_equal(folder, mbox, flen))
167 return NULL;
168
169 // After the match, check that mbox has a delimiter
170 if (!strchr(c_sidebar_delim_chars, mbox[flen]))
171 return NULL;
172
173 if (mlen > flen)
174 {
175 return mbox + flen + 1;
176 }
177
178 // mbox and folder are equal, use the chunk after the last delimiter
179 while (mlen--)
180 {
181 if (strchr(c_sidebar_delim_chars, mbox[mlen]))
182 {
183 return mbox + mlen + 1;
184 }
185 }
186
187 return NULL;
188}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:291
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
static int imap_is_prefix(const char *folder, const char *mbox)
Check if folder matches the beginning of mbox.
Definition: window.c:100
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ abbrev_url()

static const char * abbrev_url ( const char *  mbox,
enum MailboxType  type 
)
static

Abbreviate a url-style Mailbox path.

Parameters
mboxMailbox path to shorten
typeMailbox type
Return values
ptrmbox unchanged

Use heuristics to shorten a non-local Mailbox path. Strip the host part (or database part for Notmuch).

e.g.

  • imap://user@host.com/apple/banana becomes apple/banana
  • notmuch:///home/user/db?query=hello becomes query=hello

Definition at line 203 of file window.c.

204{
205 /* This is large enough to skip `notmuch://`,
206 * but not so large that it will go past the host part. */
207 const int scheme_len = 10;
208
209 size_t len = mutt_str_len(mbox);
210 if ((len < scheme_len) || ((type != MUTT_NNTP) && (type != MUTT_IMAP) &&
211 (type != MUTT_NOTMUCH) && (type != MUTT_POP)))
212 {
213 return mbox;
214 }
215
216 const char split = (type == MUTT_NOTMUCH) ? '?' : '/';
217
218 // Skip over the scheme, e.g. `imaps://`, `notmuch://`
219 const char *last = strchr(mbox + scheme_len, split);
220 if (last)
221 mbox = last + 1;
222 return mbox;
223}
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
@ MUTT_POP
'POP3' Mailbox type
Definition: mailbox.h:52
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_indent()

static size_t add_indent ( char *  buf,
size_t  buflen,
const struct SbEntry sbe 
)
static

Generate the needed indentation.

Parameters
bufOutput buffer
buflenSize of output buffer
sbeSidebar entry
Return values
numBytes written

Definition at line 232 of file window.c.

233{
234 size_t res = 0;
235 const char *const c_sidebar_indent_string = cs_subset_string(NeoMutt->sub, "sidebar_indent_string");
236 for (int i = 0; i < sbe->depth; i++)
237 {
238 res += mutt_str_copy(buf + res, c_sidebar_indent_string, buflen - res);
239 }
240 return res;
241}
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:581
int depth
Indentation depth.
Definition: private.h:44
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_color()

static const struct AttrColor * calc_color ( const struct Mailbox m,
bool  current,
bool  highlight 
)
static

Calculate the colour of a Sidebar row.

Parameters
mMailbox
currenttrue, if this is the current Mailbox
highlighttrue, if this Mailbox has the highlight on it
Return values
enumColorId, e.g. MT_COLOR_SIDEBAR_NEW

Definition at line 250 of file window.c.

251{
252 const struct AttrColor *ac = NULL;
253
254 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
256 mutt_str_equal(mailbox_path(m), c_spool_file))
257 {
259 }
260
262 {
264 }
265
267 {
269 }
270
272 {
274 }
275
277 {
279 }
280
281 const struct AttrColor *ac_bg = simple_color_get(MT_COLOR_NORMAL);
283 ac = merged_color_overlay(ac_bg, ac);
284
285 if (current || highlight)
286 {
287 int color;
288 if (current)
289 {
292 else
293 color = MT_COLOR_INDICATOR;
294 }
295 else
296 {
298 }
299
300 ac = merged_color_overlay(ac, simple_color_get(color));
301 }
302
303 return ac;
304}
bool simple_color_is_set(enum ColorId cid)
Is the object coloured?
Definition: simple.c:109
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition: simple.c:88
@ MT_COLOR_SIDEBAR_NEW
Mailbox with new mail.
Definition: color.h:70
@ MT_COLOR_SIDEBAR_UNREAD
Mailbox with unread mail.
Definition: color.h:73
@ MT_COLOR_INDICATOR
Selected item in list.
Definition: color.h:54
@ MT_COLOR_SIDEBAR_SPOOLFILE
$spool_file (Spool mailbox)
Definition: color.h:72
@ MT_COLOR_SIDEBAR_ORDINARY
Mailbox with no new or flagged messages.
Definition: color.h:71
@ MT_COLOR_SIDEBAR_BACKGROUND
Background colour for the Sidebar.
Definition: color.h:65
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:59
@ MT_COLOR_SIDEBAR_INDICATOR
Current open mailbox.
Definition: color.h:69
@ MT_COLOR_SIDEBAR_HIGHLIGHT
Select cursor.
Definition: color.h:68
@ MT_COLOR_SIDEBAR_FLAGGED
Mailbox with flagged messages.
Definition: color.h:67
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:223
const struct AttrColor * merged_color_overlay(const struct AttrColor *base, const struct AttrColor *over)
Combine two colours.
Definition: merged.c:107
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
A curses colour and its attributes.
Definition: attr.h:66
bool has_new
Mailbox has new mail.
Definition: mailbox.h:85
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:90
int msg_unread
Number of unread messages.
Definition: mailbox.h:89
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ calc_path_depth()

static int calc_path_depth ( const char *  mbox,
const char *  delims,
const char **  last_part 
)
static

Calculate the depth of a Mailbox path.

Parameters
[in]mboxMailbox path to examine
[in]delimsDelimiter characters
[out]last_partLast path component
Return values
numDepth

Definition at line 313 of file window.c.

314{
315 if (!mbox || !delims || !last_part)
316 return 0;
317
318 int depth = 0;
319 const char *match = NULL;
320 while ((match = strpbrk(mbox, delims)))
321 {
322 depth++;
323 mbox = match + 1;
324 }
325
326 *last_part = mbox;
327 return depth;
328}
+ Here is the caller graph for this function:

◆ make_sidebar_entry()

static void make_sidebar_entry ( char *  buf,
size_t  buflen,
int  width,
struct SbEntry sbe,
struct IndexSharedData shared 
)
static

Turn mailbox data into a sidebar string.

Parameters
[out]bufBuffer in which to save string
[in]buflenBuffer length
[in]widthDesired width in screen cells
[in]sbeMailbox object
[in]sharedShared Index Data

Take all the relevant mailbox data and the desired screen width and then get expando_render() to do the actual work.

See also
$sidebar_format

Definition at line 586 of file window.c.

588{
589 struct SidebarData sdata = { sbe, shared };
590
591 struct Buffer *tmp = buf_pool_get();
592 const struct Expando *c_sidebar_format = cs_subset_expando(NeoMutt->sub, "sidebar_format");
593 expando_filter(c_sidebar_format, SidebarRenderData, &sdata,
594 MUTT_FORMAT_NO_FLAGS, width, tmp);
595 mutt_str_copy(buf, buf_string(tmp), buflen);
596 buf_pool_release(&tmp);
597
598 /* Force string to be exactly the right width */
599 int w = mutt_strwidth(buf);
600 int s = mutt_str_len(buf);
601 width = MIN(buflen, width);
602 if (w < width)
603 {
604 /* Pad with spaces */
605 memset(buf + s, ' ', width - w);
606 buf[s + width - w] = '\0';
607 }
608 else if (w > width)
609 {
610 /* Truncate to fit */
611 size_t len = mutt_wstr_trunc(buf, buflen, width, NULL);
612 buf[len] = '\0';
613 }
614}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
const struct Expando * cs_subset_expando(const struct ConfigSubset *sub, const char *name)
Get an Expando config item by name.
Definition: config_type.c:357
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:383
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:443
int expando_filter(const struct Expando *exp, const struct ExpandoRenderData *rdata, void *data, MuttFormatFlags flags, int max_cols, struct Buffer *buf)
Render an Expando and run the result through a filter.
Definition: filter.c:138
#define MIN(a, b)
Definition: memory.h:32
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: render.h:33
const struct ExpandoRenderData SidebarRenderData[]
Callbacks for Sidebar Expandos.
Definition: window.c:83
String manipulation buffer.
Definition: buffer.h:36
Parsed Expando trees.
Definition: expando.h:41
Data passed to sidebar_format_str()
Definition: window.c:89
struct IndexSharedData * shared
Shared Index Data.
Definition: window.c:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_entries_visibility()

static void update_entries_visibility ( struct SidebarWindowData wdata)
static

Should a SbEntry be displayed in the sidebar?

Parameters
wdataSidebar data

For each SbEntry in the entries array, check whether we should display it. This is determined by several criteria. If the Mailbox:

  • is the currently open mailbox
  • is the currently highlighted mailbox
  • has unread messages
  • has flagged messages
  • is pinned

Definition at line 628 of file window.c.

629{
630 /* Aliases for readability */
631 const bool c_sidebar_new_mail_only = cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
632 const bool c_sidebar_non_empty_mailbox_only = cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
633 struct SbEntry *sbe = NULL;
634
635 struct IndexSharedData *shared = wdata->shared;
636 struct SbEntry **sbep = NULL;
637 ARRAY_FOREACH(sbep, &wdata->entries)
638 {
639 int i = ARRAY_FOREACH_IDX;
640 sbe = *sbep;
641
642 sbe->is_hidden = false;
643
644 if (!sbe->mailbox->visible)
645 {
646 sbe->is_hidden = true;
647 continue;
648 }
649
650 if (shared->mailbox &&
652 {
653 /* Spool directories are always visible */
654 continue;
655 }
656
659 {
660 /* Explicitly asked to be visible */
661 continue;
662 }
663
664 if (c_sidebar_non_empty_mailbox_only && (i != wdata->opn_index) &&
665 (sbe->mailbox->msg_count == 0))
666 {
667 sbe->is_hidden = true;
668 }
669
670 if (c_sidebar_new_mail_only && (i != wdata->opn_index) &&
671 (sbe->mailbox->msg_unread == 0) && (sbe->mailbox->msg_flagged == 0) &&
672 !sbe->mailbox->has_new)
673 {
674 sbe->is_hidden = true;
675 }
676 }
677}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:212
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:103
struct ListHead SidebarPinned
List of mailboxes to always display in the sidebar.
Definition: sidebar.c:43
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:37
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
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
bool visible
True if a result of "mailboxes".
Definition: mailbox.h:130
Info about folders in the sidebar.
Definition: private.h:41
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:45
bool is_hidden
Don't show, e.g. $sidebar_new_mail_only.
Definition: private.h:46
struct IndexSharedData * shared
Shared Index Data.
Definition: private.h:90
int opn_index
Current (open) mailbox.
Definition: private.h:94
struct SbEntryArray entries
Items to display in the sidebar.
Definition: private.h:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ prepare_sidebar()

static bool prepare_sidebar ( struct SidebarWindowData wdata,
int  page_size 
)
static

Prepare the list of SbEntry's for the sidebar display.

Parameters
wdataSidebar data
page_sizeNumber of lines on a page
Return values
falseNo, don't draw the sidebar
trueYes, draw the sidebar

Before painting the sidebar, we determine which are visible, sort them and set up our page pointers.

This is a lot of work to do each refresh, but there are many things that can change outside of the sidebar that we don't hear about.

Definition at line 692 of file window.c.

693{
694 if (ARRAY_EMPTY(&wdata->entries) || (page_size <= 0))
695 return false;
696
697 struct SbEntry **sbep = NULL;
698 const bool c_sidebar_new_mail_only = cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
699 const bool c_sidebar_non_empty_mailbox_only = cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
700
701 sbep = (wdata->opn_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->opn_index) : NULL;
702 const struct SbEntry *opn_entry = sbep ? *sbep : NULL;
703 sbep = (wdata->hil_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->hil_index) : NULL;
704 const struct SbEntry *hil_entry = sbep ? *sbep : NULL;
705
707 const short c_sidebar_sort_method = cs_subset_sort(NeoMutt->sub, "sidebar_sort_method");
708 sb_sort_entries(wdata, c_sidebar_sort_method);
709
710 if (opn_entry || hil_entry)
711 {
712 ARRAY_FOREACH(sbep, &wdata->entries)
713 {
714 if ((opn_entry == *sbep) && (*sbep)->mailbox->visible)
715 wdata->opn_index = ARRAY_FOREACH_IDX;
716 if ((hil_entry == *sbep) && (*sbep)->mailbox->visible)
717 wdata->hil_index = ARRAY_FOREACH_IDX;
718 }
719 }
720
721 if ((wdata->hil_index < 0) || (hil_entry && hil_entry->is_hidden) ||
722 (c_sidebar_sort_method != wdata->previous_sort))
723 {
724 if (wdata->opn_index >= 0)
725 {
726 wdata->hil_index = wdata->opn_index;
727 }
728 else
729 {
730 wdata->hil_index = 0;
731 /* Note is_hidden will only be set when `$sidebar_new_mail_only` */
732 if ((*ARRAY_GET(&wdata->entries, 0))->is_hidden && !sb_next(wdata))
733 wdata->hil_index = -1;
734 }
735 }
736
737 /* Set the Top and Bottom to frame the wdata->hil_index in groups of page_size */
738
739 /* If `$sidebar_new_mail_only` or `$sidebar_non_empty_mailbox_only` is set,
740 * some entries may be hidden so we need to scan for the framing interval */
741 if (c_sidebar_new_mail_only || c_sidebar_non_empty_mailbox_only)
742 {
743 wdata->top_index = -1;
744 wdata->bot_index = -1;
745 while (wdata->bot_index < wdata->hil_index)
746 {
747 wdata->top_index = wdata->bot_index + 1;
748 int page_entries = 0;
749 while (page_entries < page_size)
750 {
751 wdata->bot_index++;
752 if (wdata->bot_index >= ARRAY_SIZE(&wdata->entries))
753 break;
754 if (!(*ARRAY_GET(&wdata->entries, wdata->bot_index))->is_hidden)
755 page_entries++;
756 }
757 }
758 }
759 else
760 {
761 /* Otherwise we can just calculate the interval */
762 wdata->top_index = (wdata->hil_index / page_size) * page_size;
763 wdata->bot_index = wdata->top_index + page_size - 1;
764 }
765
766 if (wdata->bot_index > (ARRAY_SIZE(&wdata->entries) - 1))
767 wdata->bot_index = ARRAY_SIZE(&wdata->entries) - 1;
768
769 wdata->previous_sort = c_sidebar_sort_method;
770
771 return (wdata->hil_index >= 0);
772}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:74
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:87
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:109
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:266
bool sb_next(struct SidebarWindowData *wdata)
Find the next unhidden Mailbox.
Definition: functions.c:47
void sb_sort_entries(struct SidebarWindowData *wdata, enum SortType sort)
Sort the Sidebar entries.
Definition: sort.c:171
static void update_entries_visibility(struct SidebarWindowData *wdata)
Should a SbEntry be displayed in the sidebar?
Definition: window.c:628
short previous_sort
Old $sidebar_sort_method
Definition: private.h:98
int top_index
First mailbox visible in sidebar.
Definition: private.h:93
int bot_index
Last mailbox visible in sidebar.
Definition: private.h:96
int hil_index
Highlighted mailbox.
Definition: private.h:95
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_divider()

static int draw_divider ( struct SidebarWindowData wdata,
struct MuttWindow win,
int  num_rows,
int  num_cols 
)
static

Draw a line between the sidebar and the rest of neomutt.

Parameters
wdataSidebar data
winWindow to draw on
num_rowsHeight of the Sidebar
num_colsWidth of the Sidebar
Return values
0Empty string
numCharacter occupies n screen columns

Draw a divider using characters from the config option "sidebar_divider_char". This can be an ASCII or Unicode character. We calculate these characters' width in screen columns.

If the user hasn't set $sidebar_divider_char we pick a character for them, respecting the value of $ascii_chars.

Definition at line 898 of file window.c.

900{
901 if ((num_rows < 1) || (num_cols < 1) || (wdata->divider_width > num_cols) ||
902 (wdata->divider_width == 0))
903 {
904 return 0;
905 }
906
907 const int width = wdata->divider_width;
908 const char *const c_sidebar_divider_char = cs_subset_string(NeoMutt->sub, "sidebar_divider_char");
909
910 const struct AttrColor *ac = simple_color_get(MT_COLOR_NORMAL);
914
915 const bool c_sidebar_on_right = cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
916 const int col = c_sidebar_on_right ? 0 : (num_cols - width);
917
918 for (int i = 0; i < num_rows; i++)
919 {
920 mutt_window_move(win, col, i);
921
922 if (wdata->divider_type == SB_DIV_USER)
923 mutt_window_addstr(win, NONULL(c_sidebar_divider_char));
924 else
925 mutt_window_addch(win, '|');
926 }
927
929 return width;
930}
@ MT_COLOR_SIDEBAR_DIVIDER
Line dividing sidebar from the index/pager.
Definition: color.h:66
const struct AttrColor * mutt_curses_set_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:79
void mutt_curses_set_color(const struct AttrColor *ac)
Set the colour and attributes for text.
Definition: mutt_curses.c:38
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:296
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:415
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
Definition: mutt_window.c:387
@ SB_DIV_USER
User configured using $sidebar_divider_char.
Definition: private.h:80
#define NONULL(x)
Definition: string2.h:37
short divider_width
Width of the divider in screen columns.
Definition: private.h:100
enum DivType divider_type
Type of divider to use, e.g. SB_DIV_ASCII.
Definition: private.h:99
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fill_empty_space()

static void fill_empty_space ( struct MuttWindow win,
int  first_row,
int  num_rows,
int  div_width,
int  num_cols 
)
static

Wipe the remaining Sidebar space.

Parameters
winWindow to draw on
first_rowWindow line to start (0-based)
num_rowsNumber of rows to fill
div_widthWidth in screen characters taken by the divider
num_colsNumber of columns to fill

Write spaces over the area the sidebar isn't using.

Definition at line 942 of file window.c.

944{
945 /* Fill the remaining rows with blank space */
946 const struct AttrColor *ac = simple_color_get(MT_COLOR_NORMAL);
949
950 const bool c_sidebar_on_right = cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
951 if (!c_sidebar_on_right)
952 div_width = 0;
953 for (int r = 0; r < num_rows; r++)
954 {
955 mutt_window_move(win, div_width, first_row + r);
957
958 for (int i = 0; i < num_cols; i++)
959 mutt_window_addch(win, ' ');
960 }
961}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ SidebarRenderData

const struct ExpandoRenderData SidebarRenderData
Initial value:
= {
{ -1, -1, NULL, NULL },
}
@ ED_SIDEBAR
Sidebar ED_SID_ ExpandoDataSidebar.
Definition: domain.h:54
long sidebar_S_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: number of messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:536
long sidebar_F_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Number of flagged messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:433
long sidebar_N_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Number of unread messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:488
long sidebar_a_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Alert for new mail - Implements ExpandoRenderData::get_number() -.
Definition: window.c:361
long sidebar_L_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Number of limited messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:445
long sidebar_t_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Number of tagged messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:548
long sidebar_Z_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Number of new messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:564
long sidebar_r_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Number of read messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:524
long sidebar_o_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Number of old messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:500
long sidebar_p_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Poll for new mail - Implements ExpandoRenderData::get_number() -.
Definition: window.c:512
long sidebar_n_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: New mail flag - Implements ExpandoRenderData::get_number() -.
Definition: window.c:461
long sidebar_d_num(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Sidebar: Number of deleted messages - Implements ExpandoRenderData::get_number() -.
Definition: window.c:391
void sidebar_D(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Sidebar: Descriptive name - Implements ExpandoRenderData::get_string() -.
Definition: window.c:407
void sidebar_bang(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Sidebar: Flagged flags - Implements ExpandoRenderData::get_string() -.
Definition: window.c:333
void sidebar_B(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Sidebar: Name of the mailbox - Implements ExpandoRenderData::get_string() -.
Definition: window.c:373
void sidebar_n(const struct ExpandoNode *node, void *data, MuttFormatFlags flags, struct Buffer *buf)
Sidebar: New mail flag - Implements ExpandoRenderData::get_string() -.
Definition: window.c:473
@ ED_SID_FLAGGED_COUNT
Mailbox.msg_flagged.
Definition: private.h:61
@ ED_SID_READ_COUNT
Mailbox.msg_count, Mailbox.msg_unread.
Definition: private.h:69
@ ED_SID_DESCRIPTION
Mailbox.name.
Definition: private.h:59
@ ED_SID_NEW_MAIL
Mailbox.has_new.
Definition: private.h:65
@ ED_SID_UNSEEN_COUNT
Mailbox.msg_new.
Definition: private.h:72
@ ED_SID_POLL
Mailbox.poll_new_mail.
Definition: private.h:68
@ ED_SID_OLD_COUNT
Mailbox.msg_unread, Mailbox.msg_new.
Definition: private.h:67
@ ED_SID_MESSAGE_COUNT
Mailbox.msg_count.
Definition: private.h:63
@ ED_SID_LIMITED_COUNT
Mailbox.vcount.
Definition: private.h:62
@ ED_SID_UNREAD_COUNT
Mailbox.msg_unread.
Definition: private.h:71
@ ED_SID_TAGGED_COUNT
Mailbox.msg_tagged.
Definition: private.h:70
@ ED_SID_NOTIFY
Mailbox.notify_user.
Definition: private.h:66
@ ED_SID_NAME
SbEntry.box.
Definition: private.h:64
@ ED_SID_DELETED_COUNT
Mailbox.msg_deleted.
Definition: private.h:58
@ ED_SID_FLAGGED
Mailbox.msg_flagged.
Definition: private.h:60

Callbacks for Sidebar Expandos.

See also
SidebarFormatDef, ExpandoDataSidebar

Definition at line 83 of file window.c.