NeoMutt  2023-11-03-85-g512e01
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 <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  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.
 
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 -.
 
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
  • 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:292
@ 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: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:

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

250{
251 const 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
280 const struct AttrColor *ac_bg = simple_color_get(MT_COLOR_NORMAL);
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: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:69
@ MT_COLOR_SIDEBAR_UNREAD
Mailbox with unread mail.
Definition: color.h:72
@ MT_COLOR_INDICATOR
Selected item in list.
Definition: color.h:53
@ 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:58
@ 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:210
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:798
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 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 582 of file window.c.

584{
585 struct SidebarData sdata = { sbe, shared };
586
587 const char *const c_sidebar_format = cs_subset_string(NeoMutt->sub, "sidebar_format");
588 mutt_expando_format(buf, buflen, 0, width, NONULL(c_sidebar_format),
589 sidebar_format_str, (intptr_t) &sdata, MUTT_FORMAT_NO_FLAGS);
590
591 /* Force string to be exactly the right width */
592 int w = mutt_strwidth(buf);
593 int s = mutt_str_len(buf);
594 width = MIN(buflen, width);
595 if (w < width)
596 {
597 /* Pad with spaces */
598 memset(buf + s, ' ', width - w);
599 buf[s + width - w] = '\0';
600 }
601 else if (w > width)
602 {
603 /* Truncate to fit */
604 size_t len = mutt_wstr_trunc(buf, buflen, width, NULL);
605 buf[len] = '\0';
606 }
607}
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:394
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:454
#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:350
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:739
#define MIN(a, b)
Definition: memory.h:32
#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 621 of file window.c.

622{
623 /* Aliases for readability */
624 const bool c_sidebar_new_mail_only = cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
625 const bool c_sidebar_non_empty_mailbox_only = cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
626 struct SbEntry *sbe = NULL;
627
628 struct IndexSharedData *shared = wdata->shared;
629 struct SbEntry **sbep = NULL;
630 ARRAY_FOREACH(sbep, &wdata->entries)
631 {
632 int i = ARRAY_FOREACH_IDX;
633 sbe = *sbep;
634
635 sbe->is_hidden = false;
636
637 if (!sbe->mailbox->visible)
638 {
639 sbe->is_hidden = true;
640 continue;
641 }
642
643 if (shared->mailbox &&
645 {
646 /* Spool directories are always visible */
647 continue;
648 }
649
652 {
653 /* Explicitly asked to be visible */
654 continue;
655 }
656
657 if (c_sidebar_non_empty_mailbox_only && (i != wdata->opn_index) &&
658 (sbe->mailbox->msg_count == 0))
659 {
660 sbe->is_hidden = true;
661 }
662
663 if (c_sidebar_new_mail_only && (i != wdata->opn_index) &&
664 (sbe->mailbox->msg_unread == 0) && (sbe->mailbox->msg_flagged == 0) &&
665 !sbe->mailbox->has_new)
666 {
667 sbe->is_hidden = true;
668 }
669 }
670}
#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:48
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:129
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 685 of file window.c.

686{
687 if (ARRAY_EMPTY(&wdata->entries) || (page_size <= 0))
688 return false;
689
690 struct SbEntry **sbep = NULL;
691 const bool c_sidebar_new_mail_only = cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
692 const bool c_sidebar_non_empty_mailbox_only = cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
693
694 sbep = (wdata->opn_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->opn_index) : NULL;
695 const struct SbEntry *opn_entry = sbep ? *sbep : NULL;
696 sbep = (wdata->hil_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->hil_index) : NULL;
697 const struct SbEntry *hil_entry = sbep ? *sbep : NULL;
698
700 const short c_sidebar_sort_method = cs_subset_sort(NeoMutt->sub, "sidebar_sort_method");
701 sb_sort_entries(wdata, c_sidebar_sort_method);
702
703 if (opn_entry || hil_entry)
704 {
705 ARRAY_FOREACH(sbep, &wdata->entries)
706 {
707 if ((opn_entry == *sbep) && (*sbep)->mailbox->visible)
708 wdata->opn_index = ARRAY_FOREACH_IDX;
709 if ((hil_entry == *sbep) && (*sbep)->mailbox->visible)
710 wdata->hil_index = ARRAY_FOREACH_IDX;
711 }
712 }
713
714 if ((wdata->hil_index < 0) || (hil_entry && hil_entry->is_hidden) ||
715 (c_sidebar_sort_method != wdata->previous_sort))
716 {
717 if (wdata->opn_index >= 0)
718 {
719 wdata->hil_index = wdata->opn_index;
720 }
721 else
722 {
723 wdata->hil_index = 0;
724 /* Note is_hidden will only be set when `$sidebar_new_mail_only` */
725 if ((*ARRAY_GET(&wdata->entries, 0))->is_hidden && !sb_next(wdata))
726 wdata->hil_index = -1;
727 }
728 }
729
730 /* Set the Top and Bottom to frame the wdata->hil_index in groups of page_size */
731
732 /* If `$sidebar_new_mail_only` or `$sidebar_non_empty_mailbox_only` is set,
733 * some entries may be hidden so we need to scan for the framing interval */
734 if (c_sidebar_new_mail_only || c_sidebar_non_empty_mailbox_only)
735 {
736 wdata->top_index = -1;
737 wdata->bot_index = -1;
738 while (wdata->bot_index < wdata->hil_index)
739 {
740 wdata->top_index = wdata->bot_index + 1;
741 int page_entries = 0;
742 while (page_entries < page_size)
743 {
744 wdata->bot_index++;
745 if (wdata->bot_index >= ARRAY_SIZE(&wdata->entries))
746 break;
747 if (!(*ARRAY_GET(&wdata->entries, wdata->bot_index))->is_hidden)
748 page_entries++;
749 }
750 }
751 }
752 else
753 {
754 /* Otherwise we can just calculate the interval */
755 wdata->top_index = (wdata->hil_index / page_size) * page_size;
756 wdata->bot_index = wdata->top_index + page_size - 1;
757 }
758
759 if (wdata->bot_index > (ARRAY_SIZE(&wdata->entries) - 1))
760 wdata->bot_index = ARRAY_SIZE(&wdata->entries) - 1;
761
762 wdata->previous_sort = c_sidebar_sort_method;
763
764 return (wdata->hil_index >= 0);
765}
#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:267
bool sb_next(struct SidebarWindowData *wdata)
Find the next unhidden Mailbox.
Definition: functions.c:46
void sb_sort_entries(struct SidebarWindowData *wdata, enum SortType sort)
Sort the Sidebar entries.
Definition: sort.c:170
static void update_entries_visibility(struct SidebarWindowData *wdata)
Should a SbEntry be displayed in the sidebar?
Definition: window.c:621
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 891 of file window.c.

893{
894 if ((num_rows < 1) || (num_cols < 1) || (wdata->divider_width > num_cols) ||
895 (wdata->divider_width == 0))
896 {
897 return 0;
898 }
899
900 const int width = wdata->divider_width;
901 const char *const c_sidebar_divider_char = cs_subset_string(NeoMutt->sub, "sidebar_divider_char");
902
903 const struct AttrColor *ac = simple_color_get(MT_COLOR_NORMAL);
907
908 const bool c_sidebar_on_right = cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
909 const int col = c_sidebar_on_right ? 0 : (num_cols - width);
910
911 for (int i = 0; i < num_rows; i++)
912 {
913 mutt_window_move(win, col, i);
914
915 if (wdata->divider_type == SB_DIV_USER)
916 mutt_window_addstr(win, NONULL(c_sidebar_divider_char));
917 else
918 mutt_window_addch(win, '|');
919 }
920
922 return width;
923}
@ MT_COLOR_SIDEBAR_DIVIDER
Line dividing sidebar from the index/pager.
Definition: color.h:65
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:81
void mutt_curses_set_color(const struct AttrColor *ac)
Set the colour and attributes for text.
Definition: mutt_curses.c:40
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:297
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:416
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
Definition: mutt_window.c:388
@ 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 935 of file window.c.

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