NeoMutt  2021-02-05-666-ge300cd
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 "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 enum ColorId calc_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 -
Expando Description
%! 'n!' Flagged messages
%B Name of the mailbox
%D Description of the mailbox
%d Number of deleted messages
%F Number of Flagged messages in the mailbox
%L Number of messages after limiting
%n 'N' if mailbox has new mail, ' ' (space) otherwise
%N Number of unread messages in the mailbox
%o Number of old unread messages in the mailbox
%r Number of read messages in the mailbox
%S Size of mailbox (total number of messages)
%t Number of tagged messages
%Z Number of new unseen messages in the mailbox
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 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 
125 done:
126  url_free(&url_m);
127  url_free(&url_f);
128 
129  return plen;
130 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:68
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:123
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:916
char * user
Username.
Definition: url.h:71
char * host
Host.
Definition: url.h:73
char * path
Path.
Definition: url.h:75
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
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:593
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:234
+ 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 =
153  cs_subset_string(NeoMutt->sub, "sidebar_delim_chars");
154  if (!c_sidebar_delim_chars)
155  return NULL;
156 
157  size_t flen = mutt_str_len(folder);
158  if (flen == 0)
159  return NULL;
160  if (strchr(c_sidebar_delim_chars, folder[flen - 1])) // folder ends with a delimiter
161  flen--;
162 
163  size_t mlen = mutt_str_len(mbox);
164  if (mlen < flen)
165  return NULL;
166 
167  if (!mutt_strn_equal(folder, mbox, flen))
168  return NULL;
169 
170  // After the match, check that mbox has a delimiter
171  if (!strchr(c_sidebar_delim_chars, mbox[flen]))
172  return NULL;
173 
174  if (mlen > flen)
175  {
176  return mbox + flen + 1;
177  }
178 
179  // mbox and folder are equal, use the chunk after the last delimiter
180  while (mlen--)
181  {
182  if (strchr(c_sidebar_delim_chars, mbox[mlen]))
183  {
184  return mbox + mlen + 1;
185  }
186  }
187 
188  return NULL;
189 }
Container for Accounts, Notifications.
Definition: neomutt.h:36
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
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:593
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ 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

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 }
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
+ 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 bufer
buflenSize of output buffer
sbeSidebar entry
Return values
Numberof bytes written

Definition at line 232 of file window.c.

233 {
234  size_t res = 0;
235  const char *const c_sidebar_indent_string =
236  cs_subset_string(NeoMutt->sub, "sidebar_indent_string");
237  for (int i = 0; i < sbe->depth; i++)
238  {
239  res += mutt_str_copy(buf + res, c_sidebar_indent_string, buflen - res);
240  }
241  return res;
242 }
Container for Accounts, Notifications.
Definition: neomutt.h:36
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
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:749
int depth
Indentation depth.
Definition: private.h:43
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:

◆ calc_color()

static enum ColorId 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 251 of file window.c.

252 {
253  if (current)
254  {
257  return MT_COLOR_INDICATOR;
258  }
259 
260  if (highlight)
262 
263  if (m->has_new)
264  return MT_COLOR_SIDEBAR_NEW;
265  if (m->msg_unread > 0)
267  if (m->msg_flagged > 0)
269 
270  const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
272  mutt_str_equal(mailbox_path(m), c_spool_file))
273  {
275  }
276 
279 
280  return MT_COLOR_NORMAL;
281 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
Mailbox with no new or flagged messages.
Definition: color.h:70
Select cursor.
Definition: color.h:67
Container for Accounts, Notifications.
Definition: neomutt.h:36
Mailbox with new mail.
Definition: color.h:69
Current open mailbox.
Definition: color.h:68
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
Plain text.
Definition: color.h:58
Selected item in list.
Definition: color.h:54
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
int mutt_color(enum ColorId id)
Return the color of an object.
Definition: color.c:1427
Mailbox with unread mail.
Definition: color.h:72
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Mailbox with flagged messages.
Definition: color.h:66
$spool_file (Spool mailbox)
Definition: color.h:71
+ 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

Definition at line 289 of file window.c.

290 {
291  if (!mbox || !delims || !last_part)
292  return 0;
293 
294  int depth = 0;
295  const char *match = NULL;
296  while ((match = strpbrk(mbox, delims)))
297  {
298  depth++;
299  mbox = match + 1;
300  }
301 
302  *last_part = mbox;
303  return depth;
304 }
+ 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. mutt_expando_format will callback to us using sidebar_format_str() for the sidebar specific formatting characters.

Definition at line 504 of file window.c.

506 {
507  struct SidebarFormatData data = { sbe, shared };
508 
509  const char *const c_sidebar_format =
510  cs_subset_string(NeoMutt->sub, "sidebar_format");
511  mutt_expando_format(buf, buflen, 0, width, NONULL(c_sidebar_format),
512  sidebar_format_str, (intptr_t) &data, MUTT_FORMAT_NO_FLAGS);
513 
514  /* Force string to be exactly the right width */
515  int w = mutt_strwidth(buf);
516  int s = mutt_str_len(buf);
517  width = MIN(buflen, width);
518  if (w < width)
519  {
520  /* Pad with spaces */
521  memset(buf + s, ' ', width - w);
522  buf[s + width - w] = '\0';
523  }
524  else if (w > width)
525  {
526  /* Truncate to fit */
527  size_t len = mutt_wstr_trunc(buf, buflen, width, NULL);
528  buf[len] = '\0';
529  }
530 }
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:780
#define NONULL(x)
Definition: string2.h:37
Data passed to sidebar_format_str()
Definition: window.c:88
#define MIN(a, b)
Definition: memory.h:31
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 -Expando Description %! &#39;n!&#39; Flagged messages ...
Definition: window.c:325
Container for Accounts, Notifications.
Definition: neomutt.h:36
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:983
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:933
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:664
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:

◆ update_entries_visibility()

static void update_entries_visibility ( struct SidebarWindowData wdata)
static

Should a SbEntry be displayed in the sidebar?

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 whitelisted

Definition at line 543 of file window.c.

544 {
545  /* Aliases for readability */
546  const bool c_sidebar_new_mail_only =
547  cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
548  const bool c_sidebar_non_empty_mailbox_only =
549  cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
550  struct SbEntry *sbe = NULL;
551 
552  struct IndexSharedData *shared = wdata->shared;
553  struct SbEntry **sbep = NULL;
554  ARRAY_FOREACH(sbep, &wdata->entries)
555  {
556  int i = ARRAY_FOREACH_IDX;
557  sbe = *sbep;
558 
559  sbe->is_hidden = false;
560 
561  if (sbe->mailbox->flags & MB_HIDDEN)
562  {
563  sbe->is_hidden = true;
564  continue;
565  }
566 
567  if (shared->mailbox &&
569  {
570  /* Spool directories are always visible */
571  continue;
572  }
573 
576  {
577  /* Explicitly asked to be visible */
578  continue;
579  }
580 
581  if (c_sidebar_non_empty_mailbox_only && (i != wdata->opn_index) &&
582  (sbe->mailbox->msg_count == 0))
583  {
584  sbe->is_hidden = true;
585  }
586 
587  if (c_sidebar_new_mail_only && (i != wdata->opn_index) &&
588  (sbe->mailbox->msg_unread == 0) && (sbe->mailbox->msg_flagged == 0) &&
589  !sbe->mailbox->has_new)
590  {
591  sbe->is_hidden = true;
592  }
593  }
594 }
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:904
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:215
int msg_count
Total number of messages.
Definition: mailbox.h:91
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int opn_index
Current (open) mailbox.
Definition: private.h:68
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
Data shared between Index, Pager and Sidebar.
Definition: shared_data.h:36
Info about folders in the sidebar.
Definition: private.h:39
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: private.h:45
Container for Accounts, Notifications.
Definition: neomutt.h:36
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: private.h:44
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:102
#define MB_HIDDEN
Definition: mailbox.h:38
uint8_t flags
e.g. MB_NORMAL
Definition: mailbox.h:134
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
struct Mailbox * mailbox
Current Mailbox.
Definition: shared_data.h:41
struct IndexSharedData * shared
Definition: private.h:64
+ 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 609 of file window.c.

610 {
611  if (ARRAY_EMPTY(&wdata->entries) || (page_size <= 0))
612  return false;
613 
614  struct SbEntry **sbep = NULL;
615  const bool c_sidebar_new_mail_only =
616  cs_subset_bool(NeoMutt->sub, "sidebar_new_mail_only");
617  const bool c_sidebar_non_empty_mailbox_only =
618  cs_subset_bool(NeoMutt->sub, "sidebar_non_empty_mailbox_only");
619 
620  sbep = (wdata->opn_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->opn_index) : NULL;
621  const struct SbEntry *opn_entry = sbep ? *sbep : NULL;
622  sbep = (wdata->hil_index >= 0) ? ARRAY_GET(&wdata->entries, wdata->hil_index) : NULL;
623  const struct SbEntry *hil_entry = sbep ? *sbep : NULL;
624 
626  const short c_sidebar_sort_method =
627  cs_subset_sort(NeoMutt->sub, "sidebar_sort_method");
628  sb_sort_entries(wdata, c_sidebar_sort_method);
629 
630  if (opn_entry || hil_entry)
631  {
632  ARRAY_FOREACH(sbep, &wdata->entries)
633  {
634  if ((opn_entry == *sbep) && ((*sbep)->mailbox->flags != MB_HIDDEN))
635  wdata->opn_index = ARRAY_FOREACH_IDX;
636  if ((hil_entry == *sbep) && ((*sbep)->mailbox->flags != MB_HIDDEN))
637  wdata->hil_index = ARRAY_FOREACH_IDX;
638  }
639  }
640 
641  if ((wdata->hil_index < 0) || (hil_entry && hil_entry->is_hidden) ||
642  (c_sidebar_sort_method != wdata->previous_sort))
643  {
644  if (wdata->opn_index >= 0)
645  wdata->hil_index = wdata->opn_index;
646  else
647  {
648  wdata->hil_index = 0;
649  /* Note is_hidden will only be set when `$sidebar_new_mail_only` */
650  if ((*ARRAY_GET(&wdata->entries, 0))->is_hidden && !select_next(wdata))
651  wdata->hil_index = -1;
652  }
653  }
654 
655  /* Set the Top and Bottom to frame the wdata->hil_index in groups of page_size */
656 
657  /* If `$sidebar_new_mail_only` or `$sidebar_non_empty_mailbox_only` is set,
658  * some entries may be hidden so we need to scan for the framing interval */
659  if (c_sidebar_new_mail_only || c_sidebar_non_empty_mailbox_only)
660  {
661  wdata->top_index = -1;
662  wdata->bot_index = -1;
663  while (wdata->bot_index < wdata->hil_index)
664  {
665  wdata->top_index = wdata->bot_index + 1;
666  int page_entries = 0;
667  while (page_entries < page_size)
668  {
669  wdata->bot_index++;
670  if (wdata->bot_index >= ARRAY_SIZE(&wdata->entries))
671  break;
672  if (!(*ARRAY_GET(&wdata->entries, wdata->bot_index))->is_hidden)
673  page_entries++;
674  }
675  }
676  }
677  /* Otherwise we can just calculate the interval */
678  else
679  {
680  wdata->top_index = (wdata->hil_index / page_size) * page_size;
681  wdata->bot_index = wdata->top_index + page_size - 1;
682  }
683 
684  if (wdata->bot_index > (ARRAY_SIZE(&wdata->entries) - 1))
685  wdata->bot_index = ARRAY_SIZE(&wdata->entries) - 1;
686 
687  wdata->previous_sort = c_sidebar_sort_method;
688 
689  return (wdata->hil_index >= 0);
690 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
int opn_index
Current (open) mailbox.
Definition: private.h:68
int top_index
First mailbox visible in sidebar.
Definition: private.h:67
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:206
#define ARRAY_GET(head, idx)
Return the element at index.
Definition: array.h:105
Info about folders in the sidebar.
Definition: private.h:39
int hil_index
Highlighted mailbox.
Definition: private.h:69
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: private.h:45
Container for Accounts, Notifications.
Definition: neomutt.h:36
short previous_sort
Old $sidebar_sort_method
Definition: private.h:72
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition: helpers.c:292
#define MB_HIDDEN
Definition: mailbox.h:38
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition: array.h:70
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int bot_index
Last mailbox visible in sidebar.
Definition: private.h:70
#define ARRAY_SIZE(head)
The number of elements stored.
Definition: array.h:83
+ 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 821 of file window.c.

823 {
824  if ((num_rows < 1) || (num_cols < 1) || (wdata->divider_width > num_cols))
825  return 0;
826 
827  const int width = wdata->divider_width;
828  const char *const c_sidebar_divider_char =
829  cs_subset_string(NeoMutt->sub, "sidebar_divider_char");
830 
832 
833  const bool c_sidebar_on_right =
834  cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
835  const int col = c_sidebar_on_right ? 0 : (num_cols - width);
836 
837  for (int i = 0; i < num_rows; i++)
838  {
839  mutt_window_move(win, col, i);
840 
841  switch (wdata->divider_type)
842  {
843  case SB_DIV_USER:
844  mutt_window_addstr(win, NONULL(c_sidebar_divider_char));
845  break;
846  case SB_DIV_ASCII:
847  mutt_window_addch(win, '|');
848  break;
849  case SB_DIV_UTF8:
850  mutt_window_addch(win, ACS_VLINE);
851  break;
852  }
853  }
854 
856  return width;
857 }
#define NONULL(x)
Definition: string2.h:37
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
enum DivType divider_type
Type of divider to use, e.g. SB_DIV_ASCII.
Definition: private.h:73
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:56
Line dividing sidebar from the index/pager.
Definition: color.h:65
Container for Accounts, Notifications.
Definition: neomutt.h:36
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:310
int mutt_window_addstr(struct MuttWindow *win, const char *str)
Write a string to a Window.
Definition: mutt_window.c:434
Plain text.
Definition: color.h:58
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
short divider_width
Width of the divider in screen columns.
Definition: private.h:74
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
Definition: mutt_window.c:402
+ 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 869 of file window.c.

871 {
872  /* Fill the remaining rows with blank space */
874 
875  const bool c_sidebar_on_right =
876  cs_subset_bool(NeoMutt->sub, "sidebar_on_right");
877  if (!c_sidebar_on_right)
878  div_width = 0;
879  for (int r = 0; r < num_rows; r++)
880  {
881  mutt_window_move(win, div_width, first_row + r);
882 
883  for (int i = 0; i < num_cols; i++)
884  mutt_window_addch(win, ' ');
885  }
886 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:56
Container for Accounts, Notifications.
Definition: neomutt.h:36
int mutt_window_move(struct MuttWindow *win, int col, int row)
Move the cursor in a Window.
Definition: mutt_window.c:310
Plain text.
Definition: color.h:58
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
int mutt_window_addch(struct MuttWindow *win, int ch)
Write one character to a Window.
Definition: mutt_window.c:402
+ Here is the call graph for this function:
+ Here is the caller graph for this function: