NeoMutt  2023-05-17-16-g61469c
Teaching an old dog new tricks
DOXYGEN
window.c File Reference

Sidebar Window. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.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 "index/lib.h"
#include "format_flags.h"
#include "muttlib.h"
+ Include dependency graph for window.c:

Go to the source code of this file.

Data Structures

struct  SidebarFormatData
 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. More...
 
static const char * abbrev_folder (const char *mbox, const char *folder, enum MailboxType type)
 Abbreviate a Mailbox path using a folder. More...
 
static const char * abbrev_url (const char *mbox, enum MailboxType type)
 Abbreviate a url-style Mailbox path. More...
 
static size_t add_indent (char *buf, size_t buflen, const struct SbEntry *sbe)
 Generate the needed indentation. More...
 
static struct AttrColorcalc_color (const struct Mailbox *m, bool current, bool highlight)
 Calculate the colour of a Sidebar row. More...
 
static int calc_path_depth (const char *mbox, const char *delims, const char **last_part)
 Calculate the depth of a Mailbox path. More...
 
static const char * sidebar_format_str (char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
 Format a string for the sidebar - Implements format_t -. More...
 
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. More...
 
static void update_entries_visibility (struct SidebarWindowData *wdata)
 Should a SbEntry be displayed in the sidebar? More...
 
static bool prepare_sidebar (struct SidebarWindowData *wdata, int page_size)
 Prepare the list of SbEntry's for the sidebar display. More...
 
int sb_recalc (struct MuttWindow *win)
 Recalculate the Sidebar display - Implements MuttWindow::recalc() -. More...
 
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. More...
 
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. More...
 
int sb_repaint (struct MuttWindow *win)
 Repaint the Sidebar display - Implements MuttWindow::repaint() -. More...
 

Detailed Description

Sidebar Window.

Authors
  • Justin Hibbits
  • Thomer M. Gil
  • Richard Russon
  • Kevin J. McCarthy
  • R Primus

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

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

Definition in file 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 99 of file window.c.

100{
101 int plen = 0;
102
103 struct Url *url_m = url_parse(mbox);
104 struct Url *url_f = url_parse(folder);
105 if (!url_m || !url_f)
106 goto done;
107
108 if (!mutt_istr_equal(url_m->host, url_f->host))
109 goto done;
110
111 if (url_m->user && url_f->user && !mutt_istr_equal(url_m->user, url_f->user))
112 goto done;
113
114 size_t mlen = mutt_str_len(url_m->path);
115 size_t flen = mutt_str_len(url_f->path);
116 if (flen > mlen)
117 goto done;
118
119 if (!mutt_strn_equal(url_m->path, url_f->path, flen))
120 goto done;
121
122 plen = strlen(mbox) - mlen + flen;
123
124done:
125 url_free(&url_m);
126 url_free(&url_f);
127
128 return plen;
129}
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
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:497
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:568
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:238
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
+ 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 138 of file window.c.

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

203{
204 /* This is large enough to skip `notmuch://`,
205 * but not so large that it will go past the host part. */
206 const int scheme_len = 10;
207
208 size_t len = mutt_str_len(mbox);
209 if ((len < scheme_len) || ((type != MUTT_NNTP) && (type != MUTT_IMAP) &&
210 (type != MUTT_NOTMUCH) && (type != MUTT_POP)))
211 {
212 return mbox;
213 }
214
215 const char split = (type == MUTT_NOTMUCH) ? '?' : '/';
216
217 // Skip over the scheme, e.g. `imaps://`, `notmuch://`
218 const char *last = strchr(mbox + scheme_len, split);
219 if (last)
220 mbox = last + 1;
221 return mbox;
222}
@ 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 231 of file window.c.

232{
233 size_t res = 0;
234 const char *const c_sidebar_indent_string = cs_subset_string(NeoMutt->sub, "sidebar_indent_string");
235 for (int i = 0; i < sbe->depth; i++)
236 {
237 res += mutt_str_copy(buf + res, c_sidebar_indent_string, buflen - res);
238 }
239 return res;
240}
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:653
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 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
numColorId, e.g. MT_COLOR_SIDEBAR_NEW

Definition at line 249 of file window.c.

250{
251 struct AttrColor *ac = NULL;
252
253 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
255 mutt_str_equal(mailbox_path(m), c_spool_file))
256 {
258 }
259
261 {
263 }
264
266 {
268 }
269
271 {
273 }
274
276 {
278 }
279
282 ac = merged_color_overlay(ac_bg, ac);
283
284 if (current || highlight)
285 {
286 int color;
287 if (current)
288 {
291 else
292 color = MT_COLOR_INDICATOR;
293 }
294 else
295 {
297 }
298
299 ac = merged_color_overlay(ac, simple_color_get(color));
300 }
301
302 return ac;
303}
bool simple_color_is_set(enum ColorId cid)
Is the object coloured?
Definition: simple.c:95
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition: simple.c:74
@ MT_COLOR_SIDEBAR_NEW
Mailbox with new mail.
Definition: color.h:69
@ MT_COLOR_SIDEBAR_UNREAD
Mailbox with unread mail.
Definition: color.h:72
@ MT_COLOR_INDICATOR
Selected item in list.
Definition: color.h:52
@ MT_COLOR_SIDEBAR_SPOOLFILE
$spool_file (Spool mailbox)
Definition: color.h:71
@ MT_COLOR_SIDEBAR_ORDINARY
Mailbox with no new or flagged messages.
Definition: color.h:70
@ MT_COLOR_SIDEBAR_BACKGROUND
Background colour for the Sidebar.
Definition: color.h:64
@ MT_COLOR_NORMAL
Plain text.
Definition: color.h:57
@ MT_COLOR_SIDEBAR_INDICATOR
Current open mailbox.
Definition: color.h:68
@ MT_COLOR_SIDEBAR_HIGHLIGHT
Select cursor.
Definition: color.h:67
@ MT_COLOR_SIDEBAR_FLAGGED
Mailbox with flagged messages.
Definition: color.h:66
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:209
struct AttrColor * merged_color_overlay(struct AttrColor *base, struct AttrColor *over)
Combine two colours.
Definition: merged.c:109
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:798
A curses colour and its attributes.
Definition: attr.h:35
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 312 of file window.c.

313{
314 if (!mbox || !delims || !last_part)
315 return 0;
316
317 int depth = 0;
318 const char *match = NULL;
319 while ((match = strpbrk(mbox, delims)))
320 {
321 depth++;
322 mbox = match + 1;
323 }
324
325 *last_part = mbox;
326 return depth;
327}
+ 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 mutt_expando_format to do the actual work.

See also
$sidebar_format, sidebar_format_str()

Definition at line 554 of file window.c.

556{
557 struct SidebarFormatData data = { sbe, shared };
558
559 const char *const c_sidebar_format = cs_subset_string(NeoMutt->sub, "sidebar_format");
560 mutt_expando_format(buf, buflen, 0, width, NONULL(c_sidebar_format),
561 sidebar_format_str, (intptr_t) &data, MUTT_FORMAT_NO_FLAGS);
562
563 /* Force string to be exactly the right width */
564 int w = mutt_strwidth(buf);
565 int s = mutt_str_len(buf);
566 width = MIN(buflen, width);
567 if (w < width)
568 {
569 /* Pad with spaces */
570 memset(buf + s, ' ', width - w);
571 buf[s + width - w] = '\0';
572 }
573 else if (w > width)
574 {
575 /* Truncate to fit */
576 size_t len = mutt_wstr_trunc(buf, buflen, width, NULL);
577 buf[len] = '\0';
578 }
579}
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:861
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:914
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
static const char * sidebar_format_str(char *buf, size_t buflen, size_t col, int cols, char op, const char *src, const char *prec, const char *if_str, const char *else_str, intptr_t data, MuttFormatFlags flags)
Format a string for the sidebar - Implements format_t -.
Definition: window.c:348
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t callback, intptr_t data, MuttFormatFlags flags)
Expand expandos (x) in a string -.
Definition: muttlib.c:742
#define MIN(a, b)
Definition: memory.h:31
#define NONULL(x)
Definition: string2.h:37
Data passed to sidebar_format_str()
Definition: window.c:88
struct IndexSharedData * shared
Shared Index Data.
Definition: window.c:90
+ 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 593 of file window.c.

594{
595 /* Aliases for readability */
596 const bool c_sidebar_new_mail_only = cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
597 const bool c_sidebar_non_empty_mailbox_only = cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
598 struct SbEntry *sbe = NULL;
599
600 struct IndexSharedData *shared = wdata->shared;
601 struct SbEntry **sbep = NULL;
602 ARRAY_FOREACH(sbep, &wdata->entries)
603 {
604 int i = ARRAY_FOREACH_IDX;
605 sbe = *sbep;
606
607 sbe->is_hidden = false;
608
609 if (!sbe->mailbox->visible)
610 {
611 sbe->is_hidden = true;
612 continue;
613 }
614
615 if (shared->mailbox &&
617 {
618 /* Spool directories are always visible */
619 continue;
620 }
621
624 {
625 /* Explicitly asked to be visible */
626 continue;
627 }
628
629 if (c_sidebar_non_empty_mailbox_only && (i != wdata->opn_index) &&
630 (sbe->mailbox->msg_count == 0))
631 {
632 sbe->is_hidden = true;
633 }
634
635 if (c_sidebar_new_mail_only && (i != wdata->opn_index) &&
636 (sbe->mailbox->msg_unread == 0) && (sbe->mailbox->msg_flagged == 0) &&
637 !sbe->mailbox->has_new)
638 {
639 sbe->is_hidden = true;
640 }
641 }
642}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:211
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:102
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:66
int opn_index
Current (open) mailbox.
Definition: private.h:70
struct SbEntryArray entries
Items to display in the sidebar.
Definition: private.h:67
+ 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 657 of file window.c.

658{
659 if (ARRAY_EMPTY(&wdata->entries) || (page_size <= 0))
660 return false;
661
662 struct SbEntry **sbep = NULL;
663 const bool c_sidebar_new_mail_only = cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
664 const bool c_sidebar_non_empty_mailbox_only = cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
665
666 sbep = (wdata->opn_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->opn_index) : NULL;
667 const struct SbEntry *opn_entry = sbep ? *sbep : NULL;
668 sbep = (wdata->hil_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->hil_index) : NULL;
669 const struct SbEntry *hil_entry = sbep ? *sbep : NULL;
670
672 const short c_sidebar_sort_method = cs_subset_sort(NeoMutt->sub, "sidebar_sort_method");
673 sb_sort_entries(wdata, c_sidebar_sort_method);
674
675 if (opn_entry || hil_entry)
676 {
677 ARRAY_FOREACH(sbep, &wdata->entries)
678 {
679 if ((opn_entry == *sbep) && (*sbep)->mailbox->visible)
680 wdata->opn_index = ARRAY_FOREACH_IDX;
681 if ((hil_entry == *sbep) && (*sbep)->mailbox->visible)
682 wdata->hil_index = ARRAY_FOREACH_IDX;
683 }
684 }
685
686 if ((wdata->hil_index < 0) || (hil_entry && hil_entry->is_hidden) ||
687 (c_sidebar_sort_method != wdata->previous_sort))
688 {
689 if (wdata->opn_index >= 0)
690 {
691 wdata->hil_index = wdata->opn_index;
692 }
693 else
694 {
695 wdata->hil_index = 0;
696 /* Note is_hidden will only be set when `$sidebar_new_mail_only` */
697 if ((*ARRAY_GET(&wdata->entries, 0))->is_hidden && !sb_next(wdata))
698 wdata->hil_index = -1;
699 }
700 }
701
702 /* Set the Top and Bottom to frame the wdata->hil_index in groups of page_size */
703
704 /* If `$sidebar_new_mail_only` or `$sidebar_non_empty_mailbox_only` is set,
705 * some entries may be hidden so we need to scan for the framing interval */
706 if (c_sidebar_new_mail_only || c_sidebar_non_empty_mailbox_only)
707 {
708 wdata->top_index = -1;
709 wdata->bot_index = -1;
710 while (wdata->bot_index < wdata->hil_index)
711 {
712 wdata->top_index = wdata->bot_index + 1;
713 int page_entries = 0;
714 while (page_entries < page_size)
715 {
716 wdata->bot_index++;
717 if (wdata->bot_index >= ARRAY_SIZE(&wdata->entries))
718 break;
719 if (!(*ARRAY_GET(&wdata->entries, wdata->bot_index))->is_hidden)
720 page_entries++;
721 }
722 }
723 }
724 else
725 {
726 /* Otherwise we can just calculate the interval */
727 wdata->top_index = (wdata->hil_index / page_size) * page_size;
728 wdata->bot_index = wdata->top_index + page_size - 1;
729 }
730
731 if (wdata->bot_index > (ARRAY_SIZE(&wdata->entries) - 1))
732 wdata->bot_index = ARRAY_SIZE(&wdata->entries) - 1;
733
734 wdata->previous_sort = c_sidebar_sort_method;
735
736 return (wdata->hil_index >= 0);
737}
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:73
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:86
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:108
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
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:177
static void update_entries_visibility(struct SidebarWindowData *wdata)
Should a SbEntry be displayed in the sidebar?
Definition: window.c:593
short previous_sort
Old $sidebar_sort_method
Definition: private.h:74
int top_index
First mailbox visible in sidebar.
Definition: private.h:69
int bot_index
Last mailbox visible in sidebar.
Definition: private.h:72
int hil_index
Highlighted mailbox.
Definition: private.h:71
+ 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 863 of file window.c.

865{
866 if ((num_rows < 1) || (num_cols < 1) || (wdata->divider_width > num_cols) ||
867 (wdata->divider_width == 0))
868 {
869 return 0;
870 }
871
872 const int width = wdata->divider_width;
873 const char *const c_sidebar_divider_char = cs_subset_string(NeoMutt->sub, "sidebar_divider_char");
874
879
880 const bool c_sidebar_on_right = cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
881 const int col = c_sidebar_on_right ? 0 : (num_cols - width);
882
883 for (int i = 0; i < num_rows; i++)
884 {
885 mutt_window_move(win, col, i);
886
887 if (wdata->divider_type == SB_DIV_USER)
888 mutt_window_addstr(win, NONULL(c_sidebar_divider_char));
889 else
890 mutt_window_addch(win, '|');
891 }
892
894 return width;
895}
@ MT_COLOR_SIDEBAR_DIVIDER
Line dividing sidebar from the index/pager.
Definition: color.h:65
void mutt_curses_set_color(struct AttrColor *ac)
Set the colour and attributes for text.
Definition: mutt_curses.c:40
struct AttrColor * mutt_curses_set_color_by_id(enum ColorId cid)
Set the colour and attributes by the colour id.
Definition: mutt_curses.c:81
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:294
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:410
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
Definition: mutt_window.c:382
@ SB_DIV_USER
User configured using $sidebar_divider_char.
Definition: private.h:56
short divider_width
Width of the divider in screen columns.
Definition: private.h:76
enum DivType divider_type
Type of divider to use, e.g. SB_DIV_ASCII.
Definition: private.h:75
+ 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 907 of file window.c.

909{
910 /* Fill the remaining rows with blank space */
914
915 const bool c_sidebar_on_right = cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
916 if (!c_sidebar_on_right)
917 div_width = 0;
918 for (int r = 0; r < num_rows; r++)
919 {
920 mutt_window_move(win, div_width, first_row + r);
922
923 for (int i = 0; i < num_cols; i++)
924 mutt_window_addch(win, ' ');
925 }
926}
+ Here is the call graph for this function:
+ Here is the caller graph for this function: