NeoMutt  2025-12-11-435-g4ac674
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 <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 "expando.h"
+ Include dependency graph for window.c:

Go to the source code of this file.

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 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 sb_entry_set_display_name (struct SbEntry *entry)
 Set the display name for an SbEntry.
 
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() -.
 

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 89 of file window.c.

90{
91 int plen = 0;
92
93 struct Url *url_m = url_parse(mbox);
94 struct Url *url_f = url_parse(folder);
95 if (!url_m || !url_f)
96 goto done;
97
98 if (!mutt_istr_equal(url_m->host, url_f->host))
99 goto done;
100
101 if (url_m->user && url_f->user && !mutt_istr_equal(url_m->user, url_f->user))
102 goto done;
103
104 size_t mlen = mutt_str_len(url_m->path);
105 size_t flen = mutt_str_len(url_f->path);
106 if (flen > mlen)
107 goto done;
108
109 if (!mutt_strn_equal(url_m->path, url_f->path, flen))
110 goto done;
111
112 plen = strlen(mbox) - mlen + flen;
113
114done:
115 url_free(&url_m);
116 url_free(&url_f);
117
118 return plen;
119}
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:674
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:429
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:500
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 128 of file window.c.

129{
130 if (!mbox || !folder)
131 return NULL;
132
133 if (type == MUTT_IMAP)
134 {
135 int prefix = imap_is_prefix(folder, mbox);
136 if (prefix == 0)
137 return NULL;
138 return mbox + prefix;
139 }
140
141 const char *const c_sidebar_delim_chars = cs_subset_string(NeoMutt->sub, "sidebar_delim_chars");
142 if (!c_sidebar_delim_chars)
143 return NULL;
144
145 size_t flen = mutt_str_len(folder);
146 if (flen == 0)
147 return NULL;
148 if (strchr(c_sidebar_delim_chars, folder[flen - 1])) // folder ends with a delimiter
149 flen--;
150
151 size_t mlen = mutt_str_len(mbox);
152 if (mlen < flen)
153 return NULL;
154
155 if (!mutt_strn_equal(folder, mbox, flen))
156 return NULL;
157
158 // After the match, check that mbox has a delimiter
159 if (!strchr(c_sidebar_delim_chars, mbox[flen]))
160 return NULL;
161
162 if (mlen > flen)
163 {
164 return mbox + flen + 1;
165 }
166
167 // mbox and folder are equal, use the chunk after the last delimiter
168 while (mlen--)
169 {
170 if (strchr(c_sidebar_delim_chars, mbox[mlen]))
171 {
172 return mbox + mlen + 1;
173 }
174 }
175
176 return NULL;
177}
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:49
static int imap_is_prefix(const char *folder, const char *mbox)
Check if folder matches the beginning of mbox.
Definition window.c:89
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
+ 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 192 of file window.c.

193{
194 /* This is large enough to skip `notmuch://`,
195 * but not so large that it will go past the host part. */
196 const int scheme_len = 10;
197
198 size_t len = mutt_str_len(mbox);
199 if ((len < scheme_len) || ((type != MUTT_NNTP) && (type != MUTT_IMAP) &&
200 (type != MUTT_NOTMUCH) && (type != MUTT_POP)))
201 {
202 return mbox;
203 }
204
205 const char split = (type == MUTT_NOTMUCH) ? '?' : '/';
206
207 // Skip over the scheme, e.g. `imaps://`, `notmuch://`
208 const char *last = strchr(mbox + scheme_len, split);
209 if (last)
210 mbox = last + 1;
211 return mbox;
212}
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition mailbox.h:50
@ MUTT_POP
'POP3' Mailbox type
Definition mailbox.h:51
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition mailbox.h:48
+ 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 221 of file window.c.

222{
223 const struct AttrColor *ac = NULL;
224
225 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
227 mutt_str_equal(mailbox_path(m), c_spool_file))
228 {
230 }
231
233 {
235 }
236
238 {
240 }
241
243 {
245 }
246
248 {
250 }
251
252 const struct AttrColor *ac_bg = simple_color_get(MT_COLOR_NORMAL);
254 ac = merged_color_overlay(ac_bg, ac);
255
256 if (current || highlight)
257 {
258 int color;
259 if (current)
260 {
263 else
264 color = MT_COLOR_INDICATOR;
265 }
266 else
267 {
269 }
270
271 ac = merged_color_overlay(ac, simple_color_get(color));
272 }
273
274 return ac;
275}
bool simple_color_is_set(enum ColorId cid)
Is the object coloured?
Definition simple.c:116
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition simple.c:95
@ MT_COLOR_SIDEBAR_NEW
Mailbox with new mail.
Definition color.h:73
@ MT_COLOR_SIDEBAR_UNREAD
Mailbox with unread mail.
Definition color.h:76
@ MT_COLOR_INDICATOR
Selected item in list.
Definition color.h:49
@ MT_COLOR_SIDEBAR_SPOOLFILE
$spool_file (Spool mailbox)
Definition color.h:75
@ MT_COLOR_SIDEBAR_ORDINARY
Mailbox with no new or flagged messages.
Definition color.h:74
@ MT_COLOR_SIDEBAR_BACKGROUND
Background colour for the Sidebar.
Definition color.h:68
@ MT_COLOR_NORMAL
Plain text.
Definition color.h:53
@ MT_COLOR_SIDEBAR_INDICATOR
Current open mailbox.
Definition color.h:72
@ MT_COLOR_SIDEBAR_HIGHLIGHT
Select cursor.
Definition color.h:71
@ MT_COLOR_SIDEBAR_FLAGGED
Mailbox with flagged messages.
Definition color.h:70
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:213
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:662
A curses colour and its attributes.
Definition attr.h:65
bool has_new
Mailbox has new mail.
Definition mailbox.h:84
int msg_flagged
Number of flagged messages.
Definition mailbox.h:89
int msg_unread
Number of unread messages.
Definition mailbox.h:88
+ 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 284 of file window.c.

285{
286 if (!mbox || !delims || !last_part)
287 return 0;
288
289 int depth = 0;
290 const char *match = NULL;
291 while ((match = strpbrk(mbox, delims)))
292 {
293 depth++;
294 mbox = match + 1;
295 }
296
297 *last_part = mbox;
298 return depth;
299}
+ Here is the caller graph for this function:

◆ sb_entry_set_display_name()

void sb_entry_set_display_name ( struct SbEntry * entry)

Set the display name for an SbEntry.

Parameters
entrySbEntry to update

Definition at line 305 of file window.c.

306{
307 const char *path = mailbox_path(entry->mailbox);
308
309 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
310 // Try to abbreviate the full path
311 const char *abbr = abbrev_folder(path, c_folder, entry->mailbox->type);
312 if (!abbr)
313 abbr = abbrev_url(path, entry->mailbox->type);
314 const char *short_path = abbr ? abbr : path;
315
316 /* Compute the depth */
317 const char *last_part = abbr;
318 const char *const c_sidebar_delim_chars = cs_subset_string(NeoMutt->sub, "sidebar_delim_chars");
319 entry->depth = calc_path_depth(abbr, c_sidebar_delim_chars, &last_part);
320
321 const bool short_path_is_abbr = (short_path == abbr);
322 const bool c_sidebar_short_path = cs_subset_bool(NeoMutt->sub, "sidebar_short_path");
323 if (c_sidebar_short_path)
324 {
325 short_path = last_part;
326 }
327
328 // Don't indent if we were unable to create an abbreviation.
329 // Otherwise, the full path will be indent, and it looks unusual.
330 const bool c_sidebar_folder_indent = cs_subset_bool(NeoMutt->sub, "sidebar_folder_indent");
331 if (c_sidebar_folder_indent && short_path_is_abbr)
332 {
333 const short c_sidebar_component_depth = cs_subset_number(NeoMutt->sub, "sidebar_component_depth");
334 if (c_sidebar_component_depth > 0)
335 entry->depth -= c_sidebar_component_depth;
336 }
337 else if (!c_sidebar_folder_indent)
338 {
339 entry->depth = 0;
340 }
341
342 mutt_str_copy(entry->box, short_path, sizeof(entry->box));
343}
short cs_subset_number(const struct ConfigSubset *sub, const char *name)
Get a number config item by name.
Definition helpers.c:143
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
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:583
static const char * abbrev_url(const char *mbox, enum MailboxType type)
Abbreviate a url-style Mailbox path.
Definition window.c:192
static const char * abbrev_folder(const char *mbox, const char *folder, enum MailboxType type)
Abbreviate a Mailbox path using a folder.
Definition window.c:128
static int calc_path_depth(const char *mbox, const char *delims, const char **last_part)
Calculate the depth of a Mailbox path.
Definition window.c:284
enum MailboxType type
Mailbox type.
Definition mailbox.h:101
int depth
Indentation depth.
Definition private.h:45
struct Mailbox * mailbox
Mailbox this represents.
Definition private.h:46
char box[256]
Mailbox path (possibly abbreviated)
Definition private.h:43
+ Here is the call graph for this function:
+ 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 358 of file window.c.

360{
361 struct SidebarData sdata = { sbe, shared };
362
363 struct Buffer *tmp = buf_pool_get();
364 const struct Expando *c_sidebar_format = cs_subset_expando(NeoMutt->sub, "sidebar_format");
365 expando_filter(c_sidebar_format, SidebarRenderCallbacks, &sdata,
366 MUTT_FORMAT_NO_FLAGS, width, NeoMutt->env, tmp);
367 mutt_str_copy(buf, buf_string(tmp), buflen);
368 buf_pool_release(&tmp);
369
370 /* Force string to be exactly the right width */
371 int w = mutt_strwidth(buf);
372 int s = mutt_str_len(buf);
373 width = MIN(buflen, width);
374 if (w < width)
375 {
376 /* Pad with spaces, capping to available buffer space */
377 int pad = width - w;
378 if ((s + pad) >= (int) buflen)
379 pad = (int) buflen - s - 1;
380 if (pad > 0)
381 {
382 memset(buf + s, ' ', pad);
383 buf[s + pad] = '\0';
384 }
385 }
386 else if (w > width)
387 {
388 /* Truncate to fit */
389 size_t len = mutt_wstr_trunc(buf, buflen, width, NULL);
390 buf[len] = '\0';
391 }
392}
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.
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:384
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition curs_lib.c:444
int expando_filter(const struct Expando *exp, const struct ExpandoRenderCallback *erc, void *data, MuttFormatFlags flags, int max_cols, char **env_list, struct Buffer *buf)
Render an Expando and run the result through a filter.
Definition filter.c:139
#define MIN(a, b)
Return the minimum of two values.
Definition memory.h:40
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition render.h:33
const struct ExpandoRenderCallback SidebarRenderCallbacks[]
Callbacks for Sidebar Expandos.
Definition expando.c:290
String manipulation buffer.
Definition buffer.h:36
Parsed Expando trees.
Definition expando.h:41
char ** env
Private copy of the environment variables.
Definition neomutt.h:58
Data passed to sidebar_format_str()
Definition expando.h:34
struct IndexSharedData * shared
Shared Index Data.
Definition expando.h:36
+ 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 406 of file window.c.

407{
408 /* Aliases for readability */
409 const bool c_sidebar_new_mail_only = cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
410 const bool c_sidebar_non_empty_mailbox_only = cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
411 struct SbEntry *sbe = NULL;
412
413 struct IndexSharedData *shared = wdata->shared;
414 struct SbEntry **sbep = NULL;
415 ARRAY_FOREACH(sbep, &wdata->entries)
416 {
417 int i = ARRAY_FOREACH_IDX_sbep;
418 sbe = *sbep;
419
420 sbe->is_hidden = false;
421
422 if (!sbe->mailbox->visible)
423 {
424 sbe->is_hidden = true;
425 continue;
426 }
427
428 if (shared->mailbox &&
430 {
431 /* Spool directories are always visible */
432 continue;
433 }
434
437 {
438 /* Explicitly asked to be visible */
439 continue;
440 }
441
442 if (c_sidebar_non_empty_mailbox_only && (i != wdata->opn_index) &&
443 (sbe->mailbox->msg_count == 0))
444 {
445 sbe->is_hidden = true;
446 }
447
448 if (c_sidebar_new_mail_only && (i != wdata->opn_index) &&
449 (sbe->mailbox->msg_unread == 0) && (sbe->mailbox->msg_flagged == 0) &&
450 !sbe->mailbox->has_new)
451 {
452 sbe->is_hidden = true;
453 }
454 }
455}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
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:44
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:80
int msg_count
Total number of messages.
Definition mailbox.h:87
char * name
A short name for the Mailbox.
Definition mailbox.h:81
bool visible
True if a result of "mailboxes".
Definition mailbox.h:129
Info about folders in the sidebar.
Definition private.h:42
bool is_hidden
Don't show, e.g. $sidebar_new_mail_only.
Definition private.h:47
struct IndexSharedData * shared
Shared Index Data.
Definition private.h:91
int opn_index
Current (open) mailbox.
Definition private.h:95
struct SbEntryArray entries
Items to display in the sidebar.
Definition private.h:92
+ 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 470 of file window.c.

471{
472 if (ARRAY_EMPTY(&wdata->entries) || (page_size <= 0))
473 return false;
474
475 struct SbEntry **sbep = NULL;
476 const bool c_sidebar_new_mail_only = cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
477 const bool c_sidebar_non_empty_mailbox_only = cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
478
479 sbep = (wdata->opn_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->opn_index) : NULL;
480 const struct SbEntry *opn_entry = sbep ? *sbep : NULL;
481 sbep = (wdata->hil_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->hil_index) : NULL;
482 const struct SbEntry *hil_entry = sbep ? *sbep : NULL;
483
485 const enum EmailSortType c_sidebar_sort = cs_subset_sort(NeoMutt->sub, "sidebar_sort");
486 sb_sort_entries(wdata, c_sidebar_sort);
487
488 if (opn_entry || hil_entry)
489 {
490 ARRAY_FOREACH(sbep, &wdata->entries)
491 {
492 if ((opn_entry == *sbep) && (*sbep)->mailbox->visible)
493 wdata->opn_index = ARRAY_FOREACH_IDX_sbep;
494 if ((hil_entry == *sbep) && (*sbep)->mailbox->visible)
495 wdata->hil_index = ARRAY_FOREACH_IDX_sbep;
496 }
497 }
498
499 if ((wdata->hil_index < 0) || (hil_entry && hil_entry->is_hidden) ||
500 (c_sidebar_sort != wdata->previous_sort))
501 {
502 if (wdata->opn_index >= 0)
503 {
504 wdata->hil_index = wdata->opn_index;
505 }
506 else
507 {
508 wdata->hil_index = 0;
509 /* Note is_hidden will only be set when `$sidebar_new_mail_only` */
510 if ((*ARRAY_GET(&wdata->entries, 0))->is_hidden && !sb_next(wdata))
511 wdata->hil_index = -1;
512 }
513 }
514
515 /* Set the Top and Bottom to frame the wdata->hil_index in groups of page_size */
516
517 /* If `$sidebar_new_mail_only` or `$sidebar_non_empty_mailbox_only` is set,
518 * some entries may be hidden so we need to scan for the framing interval */
519 if (c_sidebar_new_mail_only || c_sidebar_non_empty_mailbox_only)
520 {
521 wdata->top_index = -1;
522 wdata->bot_index = -1;
523 while (wdata->bot_index < wdata->hil_index)
524 {
525 wdata->top_index = wdata->bot_index + 1;
526 int page_entries = 0;
527 while (page_entries < page_size)
528 {
529 wdata->bot_index++;
530 if (wdata->bot_index >= ARRAY_SIZE(&wdata->entries))
531 break;
532 if (!(*ARRAY_GET(&wdata->entries, wdata->bot_index))->is_hidden)
533 page_entries++;
534 }
535 }
536 }
537 else
538 {
539 /* Otherwise we can just calculate the interval */
540 wdata->top_index = (wdata->hil_index / page_size) * page_size;
541 wdata->bot_index = wdata->top_index + page_size - 1;
542 }
543
544 if (wdata->bot_index > (ARRAY_SIZE(&wdata->entries) - 1))
545 wdata->bot_index = ARRAY_SIZE(&wdata->entries) - 1;
546
547 wdata->previous_sort = c_sidebar_sort;
548
549 return (wdata->hil_index >= 0);
550}
#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
EmailSortType
Methods for sorting Emails.
Definition sort.h:53
bool sb_next(struct SidebarWindowData *wdata)
Find the next unhidden Mailbox.
Definition functions.c:100
void sb_sort_entries(struct SidebarWindowData *wdata, enum EmailSortType sort)
Sort the Sidebar entries.
Definition sort.c:161
static void update_entries_visibility(struct SidebarWindowData *wdata)
Should a SbEntry be displayed in the sidebar?
Definition window.c:406
short previous_sort
Old $sidebar_sort
Definition private.h:99
int top_index
First mailbox visible in sidebar.
Definition private.h:94
int bot_index
Last mailbox visible in sidebar.
Definition private.h:97
int hil_index
Highlighted mailbox.
Definition private.h:96
+ 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 642 of file window.c.

644{
645 if ((num_rows < 1) || (num_cols < 1) || (wdata->divider_width > num_cols) ||
646 (wdata->divider_width == 0))
647 {
648 return 0;
649 }
650
651 const int width = wdata->divider_width;
652 const char *const c_sidebar_divider_char = cs_subset_string(NeoMutt->sub, "sidebar_divider_char");
653
654 const struct AttrColor *ac = simple_color_get(MT_COLOR_NORMAL);
658
659 const bool c_sidebar_on_right = cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
660 const int col = c_sidebar_on_right ? 0 : (num_cols - width);
661
662 for (int i = 0; i < num_rows; i++)
663 {
664 mutt_window_move(win, i, col);
665
666 if (wdata->divider_type == SB_DIV_USER)
667 mutt_window_addstr(win, NONULL(c_sidebar_divider_char));
668 else
669 mutt_window_addch(win, '|');
670 }
671
673 return width;
674}
@ MT_COLOR_SIDEBAR_DIVIDER
Line dividing sidebar from the index/pager.
Definition color.h:69
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 row, int col)
Move the cursor in a Window.
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
@ SB_DIV_USER
User configured using $sidebar_divider_char.
Definition private.h:81
#define NONULL(x)
Definition string2.h:44
short divider_width
Width of the divider in screen columns.
Definition private.h:101
enum DivType divider_type
Type of divider to use, e.g. SB_DIV_ASCII.
Definition private.h:100
+ 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 686 of file window.c.

688{
689 /* Fill the remaining rows with blank space */
690 const struct AttrColor *ac = simple_color_get(MT_COLOR_NORMAL);
693
694 const bool c_sidebar_on_right = cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
695 if (!c_sidebar_on_right)
696 div_width = 0;
697 for (int r = 0; r < num_rows; r++)
698 {
699 mutt_window_move(win, first_row + r, div_width);
701
702 for (int i = 0; i < num_cols; i++)
703 mutt_window_addch(win, ' ');
704 }
705}
+ Here is the call graph for this function:
+ Here is the caller graph for this function: