NeoMutt  2020-03-20-65-g141838
Teaching an old dog new tricks
DOXYGEN
sidebar.c File Reference

GUI display the mailboxes in a side panel. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "sidebar.h"
#include "context.h"
#include "format_flags.h"
#include "globals.h"
#include "mutt_menu.h"
#include "muttlib.h"
#include "opcodes.h"
+ Include dependency graph for sidebar.c:

Go to the source code of this file.

Data Structures

struct  SbEntry
 Info about folders in the sidebar. More...
 

Enumerations

enum  DivType { SB_DIV_USER, SB_DIV_ASCII, SB_DIV_UTF8 }
 Source of the sidebar divider character. More...
 

Functions

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, unsigned long 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, const char *box, struct SbEntry *sbe)
 Turn mailbox data into a sidebar string. More...
 
static int cb_qsort_sbe (const void *a, const void *b)
 qsort callback to sort SbEntry's More...
 
static void update_entries_visibility (void)
 Should a sidebar_entry be displayed in the sidebar. More...
 
static void unsort_entries (void)
 Restore Entries array order to match Mailbox list order. More...
 
static void sort_entries (void)
 Sort Entries array. More...
 
static bool select_next (void)
 Selects the next unhidden mailbox. More...
 
static int select_next_new (void)
 Selects the next new mailbox. More...
 
static bool select_prev (void)
 Selects the previous unhidden mailbox. More...
 
static bool select_prev_new (void)
 Selects the previous new mailbox. More...
 
static int select_page_down (void)
 Selects the first entry in the next page of mailboxes. More...
 
static int select_page_up (void)
 Selects the last entry in the previous page of mailboxes. More...
 
static bool prepare_sidebar (int page_size)
 Prepare the list of SbEntry's for the sidebar display. More...
 
static int draw_divider (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...
 
static bool imap_is_prefix (const char *folder, const char *mbox, size_t *plen)
 Check if folder matches the beginning of mbox. More...
 
static void draw_sidebar (struct MuttWindow *win, int num_rows, int num_cols, int div_width)
 Write out a list of mailboxes, in a panel. More...
 
void mutt_sb_draw (struct MuttWindow *win)
 Completely redraw the sidebar. More...
 
void mutt_sb_change_mailbox (int op)
 Change the selected mailbox. More...
 
struct Mailboxmutt_sb_get_highlight (void)
 Get the Mailbox that's highlighted in the sidebar. More...
 
void mutt_sb_set_open_mailbox (struct Mailbox *m)
 Set the 'open' Mailbox. More...
 
void mutt_sb_notify_mailbox (struct Mailbox *m, bool created)
 The state of a Mailbox is about to change. More...
 
int mutt_sb_observer (struct NotifyCallback *nc)
 Listen for config changes affecting the sidebar - Implements observer_t. More...
 

Variables

short C_SidebarComponentDepth
 Config: (sidebar) Strip leading path components from sidebar folders. More...
 
char * C_SidebarDelimChars
 Config: (sidebar) Characters that separate nested folders. More...
 
char * C_SidebarDividerChar
 Config: (sidebar) Character to draw between the sidebar and index. More...
 
bool C_SidebarFolderIndent
 Config: (sidebar) Indent nested folders. More...
 
char * C_SidebarFormat
 Config: (sidebar) printf-like format string for the sidebar panel. More...
 
char * C_SidebarIndentString
 Config: (sidebar) Indent nested folders using this string. More...
 
bool C_SidebarNewMailOnly
 Config: (sidebar) Only show folders with new/flagged mail. More...
 
bool C_SidebarNonEmptyMailboxOnly
 Config: (sidebar) Only show folders with a non-zero number of mail. More...
 
bool C_SidebarNextNewWrap
 Config: (sidebar) Wrap around when searching for the next mailbox with new mail. More...
 
bool C_SidebarOnRight
 Config: (sidebar) Display the sidebar on the right. More...
 
bool C_SidebarShortPath
 Config: (sidebar) Abbreviate the paths using the C_Folder variable. More...
 
short C_SidebarSortMethod
 Config: (sidebar) Method to sort the sidebar. More...
 
bool C_SidebarVisible
 Config: (sidebar) Show the sidebar. More...
 
short C_SidebarWidth
 Config: (sidebar) Width of the sidebar. More...
 
static short PreviousSort = SORT_ORDER
 
static int EntryCount = 0
 
static int EntryLen = 0
 
static struct SbEntry ** Entries = NULL
 
static int TopIndex = -1
 First mailbox visible in sidebar. More...
 
static int OpnIndex = -1
 Current (open) mailbox. More...
 
static int HilIndex = -1
 Highlighted mailbox. More...
 
static int BotIndex = -1
 Last mailbox visible in sidebar. More...
 

Detailed Description

GUI display the mailboxes in a side panel.

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

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

Enumeration Type Documentation

◆ DivType

enum DivType

Source of the sidebar divider character.

Enumerator
SB_DIV_USER 

User configured using $sidebar_divider_char.

SB_DIV_ASCII 

An ASCII vertical bar (pipe)

SB_DIV_UTF8 

A unicode line-drawing character.

Definition at line 91 of file sidebar.c.

92 {
93  SB_DIV_USER,
94  SB_DIV_ASCII,
95  SB_DIV_UTF8,
96 };

Function Documentation

◆ sidebar_format_str()

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,
unsigned long  data,
MuttFormatFlags  flags 
)
static

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

Definition at line 117 of file sidebar.c.

121 {
122  struct SbEntry *sbe = (struct SbEntry *) data;
123  char fmt[256];
124 
125  if (!sbe || !buf)
126  return src;
127 
128  buf[0] = '\0'; /* Just in case there's nothing to do */
129 
130  struct Mailbox *m = sbe->mailbox;
131  if (!m)
132  return src;
133 
134  bool c = Context && Context->mailbox &&
136 
137  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
138 
139  switch (op)
140  {
141  case 'B':
142  mutt_format_s(buf, buflen, prec, sbe->box);
143  break;
144 
145  case 'd':
146  if (!optional)
147  {
148  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
149  snprintf(buf, buflen, fmt, c ? Context->mailbox->msg_deleted : 0);
150  }
151  else if ((c && (Context->mailbox->msg_deleted == 0)) || !c)
152  optional = false;
153  break;
154 
155  case 'D':
156  if (sbe->mailbox->name)
157  mutt_format_s(buf, buflen, prec, sbe->mailbox->name);
158  else
159  mutt_format_s(buf, buflen, prec, sbe->box);
160  break;
161 
162  case 'F':
163  if (!optional)
164  {
165  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
166  snprintf(buf, buflen, fmt, m->msg_flagged);
167  }
168  else if (m->msg_flagged == 0)
169  optional = false;
170  break;
171 
172  case 'L':
173  if (!optional)
174  {
175  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
176  snprintf(buf, buflen, fmt, c ? Context->mailbox->vcount : m->msg_count);
177  }
178  else if ((c && (Context->mailbox->vcount == m->msg_count)) || !c)
179  optional = false;
180  break;
181 
182  case 'N':
183  if (!optional)
184  {
185  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
186  snprintf(buf, buflen, fmt, m->msg_unread);
187  }
188  else if (m->msg_unread == 0)
189  optional = false;
190  break;
191 
192  case 'n':
193  if (!optional)
194  {
195  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
196  snprintf(buf, buflen, fmt, m->has_new ? 'N' : ' ');
197  }
198  else if (m->has_new == false)
199  optional = false;
200  break;
201 
202  case 'o':
203  if (!optional)
204  {
205  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
206  snprintf(buf, buflen, fmt, m->msg_unread - m->msg_new);
207  }
208  else if ((c && (Context->mailbox->msg_unread - Context->mailbox->msg_new) == 0) || !c)
209  optional = false;
210  break;
211 
212  case 'r':
213  if (!optional)
214  {
215  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
216  snprintf(buf, buflen, fmt, m->msg_count - m->msg_unread);
217  }
218  else if ((c && (Context->mailbox->msg_count - Context->mailbox->msg_unread) == 0) || !c)
219  optional = false;
220  break;
221 
222  case 'S':
223  if (!optional)
224  {
225  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
226  snprintf(buf, buflen, fmt, m->msg_count);
227  }
228  else if (m->msg_count == 0)
229  optional = false;
230  break;
231 
232  case 't':
233  if (!optional)
234  {
235  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
236  snprintf(buf, buflen, fmt, c ? Context->mailbox->msg_tagged : 0);
237  }
238  else if ((c && (Context->mailbox->msg_tagged == 0)) || !c)
239  optional = false;
240  break;
241 
242  case 'Z':
243  if (!optional)
244  {
245  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
246  snprintf(buf, buflen, fmt, m->msg_new);
247  }
248  else if ((c && (Context->mailbox->msg_new) == 0) || !c)
249  optional = false;
250  break;
251 
252  case '!':
253  if (m->msg_flagged == 0)
254  mutt_format_s(buf, buflen, prec, "");
255  else if (m->msg_flagged == 1)
256  mutt_format_s(buf, buflen, prec, "!");
257  else if (m->msg_flagged == 2)
258  mutt_format_s(buf, buflen, prec, "!!");
259  else
260  {
261  snprintf(fmt, sizeof(fmt), "%d!", m->msg_flagged);
262  mutt_format_s(buf, buflen, prec, fmt);
263  }
264  break;
265  }
266 
267  if (optional)
268  {
269  mutt_expando_format(buf, buflen, col, C_SidebarWidth, if_str,
270  sidebar_format_str, (unsigned long) sbe, flags);
271  }
272  else if (flags & MUTT_FORMAT_OPTIONAL)
273  {
274  mutt_expando_format(buf, buflen, col, C_SidebarWidth, else_str,
275  sidebar_format_str, (unsigned long) sbe, flags);
276  }
277 
278  /* We return the format string, unchanged */
279  return src;
280 }
The "current" mailbox.
Definition: context.h:37
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:863
int msg_count
Total number of messages.
Definition: mailbox.h:91
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:96
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
static int const char * fmt
Definition: acutest.h:473
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Info about folders in the sidebar.
Definition: sidebar.c:72
int vcount
The number of virtual messages.
Definition: mailbox.h:102
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:75
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
struct Mailbox * mailbox
Definition: context.h:51
int flags
e.g. MB_NORMAL
Definition: mailbox.h:134
char box[256]
formatted mailbox name
Definition: sidebar.c:74
A mailbox.
Definition: mailbox.h:81
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:97
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1222
int msg_new
Number of new messages.
Definition: mailbox.h:95
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ 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,
const char *  box,
struct SbEntry sbe 
)
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]boxMailbox name
[in]sbeMailbox object

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 294 of file sidebar.c.

296 {
297  if (!buf || !box || !sbe)
298  return;
299 
300  mutt_str_strfcpy(sbe->box, box, sizeof(sbe->box));
301 
302  mutt_expando_format(buf, buflen, 0, width, NONULL(C_SidebarFormat),
303  sidebar_format_str, (unsigned long) sbe, MUTT_FORMAT_NO_FLAGS);
304 
305  /* Force string to be exactly the right width */
306  int w = mutt_strwidth(buf);
307  int s = mutt_str_strlen(buf);
308  width = MIN(buflen, width);
309  if (w < width)
310  {
311  /* Pad with spaces */
312  memset(buf + s, ' ', width - w);
313  buf[s + width - w] = '\0';
314  }
315  else if (w > width)
316  {
317  /* Truncate to fit */
318  size_t len = mutt_wstr_trunc(buf, buflen, width, NULL);
319  buf[len] = '\0';
320  }
321 }
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:863
#define NONULL(x)
Definition: string2.h:37
#define MIN(a, b)
Definition: memory.h:31
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
char box[256]
formatted mailbox name
Definition: sidebar.c:74
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1337
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:1287
size_t mutt_str_strfcpy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:773
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cb_qsort_sbe()

static int cb_qsort_sbe ( const void *  a,
const void *  b 
)
static

qsort callback to sort SbEntry's

Parameters
aFirst SbEntry to compare
bSecond SbEntry to compare
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 331 of file sidebar.c.

332 {
333  const struct SbEntry *sbe1 = *(struct SbEntry const *const *) a;
334  const struct SbEntry *sbe2 = *(struct SbEntry const *const *) b;
335  const struct Mailbox *m1 = sbe1->mailbox;
336  const struct Mailbox *m2 = sbe2->mailbox;
337 
338  int rc = 0;
339 
340  switch ((C_SidebarSortMethod & SORT_MASK))
341  {
342  case SORT_COUNT:
343  if (m2->msg_count == m1->msg_count)
345  else
346  rc = (m2->msg_count - m1->msg_count);
347  break;
348  case SORT_UNREAD:
349  if (m2->msg_unread == m1->msg_unread)
351  else
352  rc = (m2->msg_unread - m1->msg_unread);
353  break;
354  case SORT_DESC:
355  rc = mutt_str_strcmp(m1->name, m2->name);
356  break;
357  case SORT_FLAGGED:
358  if (m2->msg_flagged == m1->msg_flagged)
360  else
361  rc = (m2->msg_flagged - m1->msg_flagged);
362  break;
363  case SORT_PATH:
364  {
366  if (rc == 0)
368  break;
369  }
370  }
371 
373  rc = -rc;
374 
375  return rc;
376 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:192
int msg_count
Total number of messages.
Definition: mailbox.h:91
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
Sort by the number of flagged emails.
Definition: sort2.h:67
Sort by the folder&#39;s path.
Definition: sort2.h:68
Info about folders in the sidebar.
Definition: sidebar.c:72
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:75
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
A mailbox.
Definition: mailbox.h:81
int mutt_inbox_cmp(const char *a, const char *b)
do two folders share the same path and one is an inbox
Definition: muttlib.c:1683
Sort by the number of unread emails.
Definition: sort2.h:66
Sort by the folder&#39;s description.
Definition: sort2.h:70
Sort by number of emails in a folder.
Definition: sort2.h:65
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
int mutt_str_strcoll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:702
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_entries_visibility()

static void update_entries_visibility ( void  )
static

Should a sidebar_entry 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 389 of file sidebar.c.

390 {
391  /* Aliases for readability */
392  const bool new_only = C_SidebarNewMailOnly;
393  const bool non_empty_only = C_SidebarNonEmptyMailboxOnly;
394  struct SbEntry *sbe = NULL;
395 
396  /* Take the fast path if there is no need to test visibilities */
397  if (!new_only && !non_empty_only)
398  {
399  for (int i = 0; i < EntryCount; i++)
400  {
401  Entries[i]->is_hidden = false;
402  }
403  return;
404  }
405 
406  for (int i = 0; i < EntryCount; i++)
407  {
408  sbe = Entries[i];
409 
410  sbe->is_hidden = false;
411 
413  {
414  /* Spool directories are always visible */
415  continue;
416  }
417 
418  if (mutt_list_find(&SidebarWhitelist, mailbox_path(sbe->mailbox)) ||
419  mutt_list_find(&SidebarWhitelist, sbe->mailbox->name))
420  {
421  /* Explicitly asked to be visible */
422  continue;
423  }
424 
425  if (non_empty_only && (i != OpnIndex) && (sbe->mailbox->msg_count == 0))
426  {
427  sbe->is_hidden = true;
428  }
429 
430  if (new_only && (i != OpnIndex) && (sbe->mailbox->msg_unread == 0) &&
431  (sbe->mailbox->msg_flagged == 0) && !sbe->mailbox->has_new)
432  {
433  sbe->is_hidden = true;
434  }
435  }
436 }
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:192
int msg_count
Total number of messages.
Definition: mailbox.h:91
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
Info about folders in the sidebar.
Definition: sidebar.c:72
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:76
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:75
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
struct Mailbox * mailbox
Definition: context.h:51
struct ListNode * mutt_list_find(const struct ListHead *h, const char *data)
Find a string in a List.
Definition: list.c:103
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ unsort_entries()

static void unsort_entries ( void  )
static

Restore Entries array order to match Mailbox list order.

Definition at line 441 of file sidebar.c.

442 {
443  int i = 0;
444 
445  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
446  struct MailboxNode *np = NULL;
447  STAILQ_FOREACH(np, &ml, entries)
448  {
449  if (i >= EntryCount)
450  break;
451 
452  int j = i;
453  while ((j < EntryCount) && (Entries[j]->mailbox != np->mailbox))
454  j++;
455  if (j < EntryCount)
456  {
457  if (j != i)
458  {
459  struct SbEntry *tmp = Entries[i];
460  Entries[i] = Entries[j];
461  Entries[j] = tmp;
462  }
463  i++;
464  }
465  }
467 }
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
Match any Mailbox type.
Definition: mailbox.h:45
Info about folders in the sidebar.
Definition: sidebar.c:72
Container for Accounts, Notifications.
Definition: neomutt.h:35
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:157
List of Mailboxes.
Definition: mailbox.h:145
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sort_entries()

static void sort_entries ( void  )
static

Sort Entries array.

Sort the Entries array according to the current sort config option "sidebar_sort_method". This calls qsort to do the work which calls our callback function "cb_qsort_sbe".

Once sorted, the prev/next links will be reconstructed.

Definition at line 478 of file sidebar.c.

479 {
480  enum SortType ssm = (C_SidebarSortMethod & SORT_MASK);
481 
482  /* These are the only sort methods we understand */
483  if ((ssm == SORT_COUNT) || (ssm == SORT_UNREAD) || (ssm == SORT_FLAGGED) || (ssm == SORT_PATH))
484  qsort(Entries, EntryCount, sizeof(*Entries), cb_qsort_sbe);
485  else if ((ssm == SORT_ORDER) && (C_SidebarSortMethod != PreviousSort))
486  unsort_entries();
487 }
SortType
Methods for sorting.
Definition: sort2.h:48
Sort by the number of flagged emails.
Definition: sort2.h:67
Sort by the folder&#39;s path.
Definition: sort2.h:68
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
Sort by the number of unread emails.
Definition: sort2.h:66
Sort by number of emails in a folder.
Definition: sort2.h:65
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ select_next()

static bool select_next ( void  )
static

Selects the next unhidden mailbox.

Return values
trueSuccess
falseFailure

Definition at line 494 of file sidebar.c.

495 {
496  int entry = HilIndex;
497 
498  if (!EntryCount || (HilIndex < 0))
499  return false;
500 
501  do
502  {
503  entry++;
504  if (entry == EntryCount)
505  return false;
506  } while (Entries[entry]->is_hidden);
507 
508  HilIndex = entry;
509  return true;
510 }
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:76
+ Here is the caller graph for this function:

◆ select_next_new()

static int select_next_new ( void  )
static

Selects the next new mailbox.

Return values
trueSuccess
falseFailure

Search down the list of mail folders for one containing new mail.

Definition at line 519 of file sidebar.c.

520 {
521  int entry = HilIndex;
522 
523  if (!EntryCount || (HilIndex < 0))
524  return false;
525 
526  do
527  {
528  entry++;
529  if (entry == EntryCount)
530  {
532  entry = 0;
533  else
534  return false;
535  }
536  if (entry == HilIndex)
537  return false;
538  } while (!Entries[entry]->mailbox->has_new && (Entries[entry]->mailbox->msg_unread == 0));
539 
540  HilIndex = entry;
541  return true;
542 }
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:75
+ Here is the caller graph for this function:

◆ select_prev()

static bool select_prev ( void  )
static

Selects the previous unhidden mailbox.

Return values
trueSuccess
falseFailure

Definition at line 549 of file sidebar.c.

550 {
551  int entry = HilIndex;
552 
553  if (!EntryCount || (HilIndex < 0))
554  return false;
555 
556  do
557  {
558  entry--;
559  if (entry < 0)
560  return false;
561  } while (Entries[entry]->is_hidden);
562 
563  HilIndex = entry;
564  return true;
565 }
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:76
+ Here is the caller graph for this function:

◆ select_prev_new()

static bool select_prev_new ( void  )
static

Selects the previous new mailbox.

Return values
trueSuccess
falseFailure

Search up the list of mail folders for one containing new mail.

Definition at line 574 of file sidebar.c.

575 {
576  int entry = HilIndex;
577 
578  if (!EntryCount || (HilIndex < 0))
579  return false;
580 
581  do
582  {
583  entry--;
584  if (entry < 0)
585  {
587  entry = EntryCount - 1;
588  else
589  return false;
590  }
591  if (entry == HilIndex)
592  return false;
593  } while (!Entries[entry]->mailbox->has_new && (Entries[entry]->mailbox->msg_unread == 0));
594 
595  HilIndex = entry;
596  return true;
597 }
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:75
+ Here is the caller graph for this function:

◆ select_page_down()

static int select_page_down ( void  )
static

Selects the first entry in the next page of mailboxes.

Return values
trueSuccess
falseFailure

Definition at line 604 of file sidebar.c.

605 {
606  int orig_hil_index = HilIndex;
607 
608  if (!EntryCount || (BotIndex < 0))
609  return 0;
610 
611  HilIndex = BotIndex;
612  select_next();
613  /* If the rest of the entries are hidden, go up to the last unhidden one */
614  if (Entries[HilIndex]->is_hidden)
615  select_prev();
616 
617  return orig_hil_index != HilIndex;
618 }
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ select_page_up()

static int select_page_up ( void  )
static

Selects the last entry in the previous page of mailboxes.

Return values
trueSuccess
falseFailure

Definition at line 625 of file sidebar.c.

626 {
627  int orig_hil_index = HilIndex;
628 
629  if (!EntryCount || (TopIndex < 0))
630  return 0;
631 
632  HilIndex = TopIndex;
633  select_prev();
634  /* If the rest of the entries are hidden, go down to the last unhidden one */
635  if (Entries[HilIndex]->is_hidden)
636  select_next();
637 
638  return orig_hil_index != HilIndex;
639 }
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ prepare_sidebar()

static bool prepare_sidebar ( int  page_size)
static

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

Parameters
page_sizeThe number 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 653 of file sidebar.c.

654 {
655  if (!EntryCount || (page_size <= 0))
656  return false;
657 
658  const struct SbEntry *opn_entry = (OpnIndex >= 0) ? Entries[OpnIndex] : NULL;
659  const struct SbEntry *hil_entry = (HilIndex >= 0) ? Entries[HilIndex] : NULL;
660 
662  sort_entries();
663 
664  for (int i = 0; i < EntryCount; i++)
665  {
666  if (opn_entry == Entries[i])
667  OpnIndex = i;
668  if (hil_entry == Entries[i])
669  HilIndex = i;
670  }
671 
673  {
674  if (OpnIndex >= 0)
675  HilIndex = OpnIndex;
676  else
677  {
678  HilIndex = 0;
679  if (Entries[HilIndex]->is_hidden)
680  select_next();
681  }
682  }
683 
684  /* Set the Top and Bottom to frame the HilIndex in groups of page_size */
685 
686  /* If C_SidebarNewMailOnly or C_SidebarNonEmptyMailboxOnly is set, some entries
687  * may be hidden so we need to scan for the framing interval */
689  {
690  TopIndex = -1;
691  BotIndex = -1;
692  while (BotIndex < HilIndex)
693  {
694  TopIndex = BotIndex + 1;
695  int page_entries = 0;
696  while (page_entries < page_size)
697  {
698  BotIndex++;
699  if (BotIndex >= EntryCount)
700  break;
701  if (!Entries[BotIndex]->is_hidden)
702  page_entries++;
703  }
704  }
705  }
706  /* Otherwise we can just calculate the interval */
707  else
708  {
709  TopIndex = (HilIndex / page_size) * page_size;
710  BotIndex = TopIndex + page_size - 1;
711  }
712 
713  if (BotIndex > (EntryCount - 1))
714  BotIndex = EntryCount - 1;
715 
717  return true;
718 }
Info about folders in the sidebar.
Definition: sidebar.c:72
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_divider()

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

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

Parameters
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 735 of file sidebar.c.

736 {
737  if ((num_rows < 1) || (num_cols < 1))
738  return 0;
739 
740  int delim_len;
741  enum DivType altchar = SB_DIV_UTF8;
742 
743  /* Calculate the width of the delimiter in screen cells */
744  delim_len = mutt_strwidth(C_SidebarDividerChar);
745  if (delim_len < 0)
746  {
747  delim_len = 1; /* Bad character */
748  }
749  else if (delim_len == 0)
750  {
752  return 0; /* User has set empty string */
753 
754  delim_len = 1; /* Unset variable */
755  }
756  else
757  {
758  altchar = SB_DIV_USER; /* User config */
759  }
760 
761  if (C_AsciiChars && (altchar != SB_DIV_ASCII))
762  {
763  /* $ascii_chars overrides Unicode divider chars */
764  if (altchar == SB_DIV_UTF8)
765  {
766  altchar = SB_DIV_ASCII;
767  }
768  else if (C_SidebarDividerChar)
769  {
770  for (int i = 0; i < delim_len; i++)
771  {
772  if (C_SidebarDividerChar[i] & ~0x7F) /* high-bit is set */
773  {
774  altchar = SB_DIV_ASCII;
775  delim_len = 1;
776  break;
777  }
778  }
779  }
780  }
781 
782  if (delim_len > num_cols)
783  return 0;
784 
786 
787  int col = C_SidebarOnRight ? 0 : (C_SidebarWidth - delim_len);
788 
789  for (int i = 0; i < num_rows; i++)
790  {
791  mutt_window_move(win, i, col);
792 
793  switch (altchar)
794  {
795  case SB_DIV_USER:
797  break;
798  case SB_DIV_ASCII:
799  mutt_window_addch('|');
800  break;
801  case SB_DIV_UTF8:
802  mutt_window_addch(ACS_VLINE);
803  break;
804  }
805  }
806 
807  return delim_len;
808 }
#define NONULL(x)
Definition: string2.h:37
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
Line dividing sidebar from the index/pager.
Definition: color.h:85
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1337
WHERE bool C_AsciiChars
Config: Use plain ASCII characters, when drawing email threads.
Definition: globals.h:196
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:278
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:400
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:430
+ 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 820 of file sidebar.c.

822 {
823  /* Fill the remaining rows with blank space */
825 
826  if (!C_SidebarOnRight)
827  div_width = 0;
828  for (int r = 0; r < num_rows; r++)
829  {
830  mutt_window_move(win, first_row + r, div_width);
831 
832  for (int i = 0; i < num_cols; i++)
833  mutt_window_addch(' ');
834  }
835 }
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
Plain text.
Definition: color.h:78
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:278
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:400
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ imap_is_prefix()

static bool imap_is_prefix ( const char *  folder,
const char *  mbox,
size_t *  plen 
)
static

Check if folder matches the beginning of mbox.

Parameters
folderFolder
mboxMailbox path
plenPrefix length
Return values
trueIf folder is the prefix of mbox

Definition at line 844 of file sidebar.c.

845 {
846  bool rc = false;
847 
848  struct Url *url_m = url_parse(mbox);
849  struct Url *url_f = url_parse(folder);
850  if (!url_m || !url_f)
851  goto done;
852 
853  if (mutt_str_strcasecmp(url_m->host, url_f->host) != 0)
854  goto done;
855 
856  if (url_m->user && url_f->user && (mutt_str_strcasecmp(url_m->user, url_f->user) != 0))
857  goto done;
858 
859  size_t mlen = mutt_str_strlen(url_m->path);
860  size_t flen = mutt_str_strlen(url_f->path);
861  if (flen > mlen)
862  goto done;
863 
864  if (mutt_str_strncmp(url_m->path, url_f->path, flen) != 0)
865  goto done;
866 
867  if (url_m->user && !url_f->user)
868  *plen += mutt_str_strlen(url_m->user) + 1;
869  rc = true;
870 
871 done:
872  url_free(&url_m);
873  url_free(&url_f);
874 
875  return rc;
876 }
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:121
char * user
Username.
Definition: url.h:69
char * host
Host.
Definition: url.h:71
char * path
Path.
Definition: url.h:73
int mutt_str_strncmp(const char *a, const char *b, size_t l)
Compare two strings (to a maximum), safely.
Definition: string.c:665
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:651
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:232
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ draw_sidebar()

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

Write out a list of mailboxes, in a panel.

Parameters
winWindow to draw on
num_rowsHeight of the Sidebar
num_colsWidth of the Sidebar
div_widthWidth in screen characters taken by the divider

Display a list of mailboxes in a panel on the left. What's displayed will depend on our index markers: TopMailbox, OpnMailbox, HilMailbox, BotMailbox. On the first run they'll be NULL, so we display the top of NeoMutt's list.

  • TopMailbox - first visible mailbox
  • BotMailbox - last visible mailbox
  • OpnMailbox - mailbox shown in NeoMutt's Index Panel
  • HilMailbox - Unselected mailbox (the paging follows this)

The entries are formatted using "sidebar_format" and may be abbreviated: "sidebar_short_path", indented: "sidebar_folder_indent", "sidebar_indent_string" and sorted: "sidebar_sort_method". Finally, they're trimmed to fit the available space.

Definition at line 899 of file sidebar.c.

900 {
901  struct SbEntry *entry = NULL;
902  struct Mailbox *m = NULL;
903  if (TopIndex < 0)
904  return;
905 
906  int w = MIN(num_cols, (C_SidebarWidth - div_width));
907  int row = 0;
908  for (int entryidx = TopIndex; (entryidx < EntryCount) && (row < num_rows); entryidx++)
909  {
910  entry = Entries[entryidx];
911  if (entry->is_hidden)
912  continue;
913  m = entry->mailbox;
914 
915  if (entryidx == OpnIndex)
916  {
919  else
921  }
922  else if (entryidx == HilIndex)
924  else if (m->has_new)
926  else if (m->msg_unread > 0)
928  else if (m->msg_flagged > 0)
930  else if ((Colors->defs[MT_COLOR_SIDEBAR_SPOOLFILE] != 0) &&
932  {
934  }
935  else
936  {
939  else
941  }
942 
943  int col = 0;
944  if (C_SidebarOnRight)
945  col = div_width;
946 
947  mutt_window_move(win, row, col);
948  if (Context && Context->mailbox && (Context->mailbox->realpath[0] != '\0') &&
950  {
954  }
955 
956  /* compute length of C_Folder without trailing separator */
957  size_t maildirlen = mutt_str_strlen(C_Folder);
958  if (maildirlen && C_SidebarDelimChars &&
959  strchr(C_SidebarDelimChars, C_Folder[maildirlen - 1]))
960  {
961  maildirlen--;
962  }
963 
964  /* check whether C_Folder is a prefix of the current folder's path */
965  bool maildir_is_prefix = false;
966  if (m->type == MUTT_IMAP)
967  {
968  maildir_is_prefix = imap_is_prefix(C_Folder, mailbox_path(m), &maildirlen);
969  }
970  else
971  {
972  if ((mutt_buffer_len(&m->pathbuf) > maildirlen) &&
973  (mutt_str_strncmp(C_Folder, mailbox_path(m), maildirlen) == 0) && C_SidebarDelimChars &&
974  strchr(C_SidebarDelimChars, mailbox_path(m)[maildirlen]))
975  {
976  maildir_is_prefix = true;
977  }
978  }
979 
980  if (m->name)
981  maildir_is_prefix = false;
982 
983  /* calculate depth of current folder and generate its display name with indented spaces */
984  int sidebar_folder_depth = 0;
985  const char *sidebar_folder_name = m->name ? m->name : mailbox_path(m);
986  struct Buffer *short_folder_name = NULL;
987 
988  if (C_SidebarShortPath)
989  {
990  /* disregard a trailing separator, so strlen() - 2 */
991  for (int i = mutt_str_strlen(sidebar_folder_name) - 2; i >= 0; i--)
992  {
993  if (C_SidebarDelimChars && strchr(C_SidebarDelimChars, sidebar_folder_name[i]))
994  {
995  sidebar_folder_name += (i + 1);
996  break;
997  }
998  }
999  }
1000  else if ((C_SidebarComponentDepth > 0) && C_SidebarDelimChars)
1001  {
1002  sidebar_folder_name += maildir_is_prefix * (maildirlen + 1);
1003  for (int i = 0; i < C_SidebarComponentDepth; i++)
1004  {
1005  char *chars_after_delim = strpbrk(sidebar_folder_name, C_SidebarDelimChars);
1006  if (!chars_after_delim)
1007  break;
1008 
1009  sidebar_folder_name = chars_after_delim + 1;
1010  }
1011  }
1012  else
1013  sidebar_folder_name += maildir_is_prefix * (maildirlen + 1);
1014 
1015  if ((m->name || maildir_is_prefix) && C_SidebarFolderIndent)
1016  {
1017  int lastsep = 0;
1018  const char *tmp_folder_name = m->name ? m->name : mailbox_path(m) + maildirlen + 1;
1019  int tmplen = (int) mutt_str_strlen(tmp_folder_name) - 1;
1020  for (int i = 0; i < tmplen; i++)
1021  {
1022  if (C_SidebarDelimChars && strchr(C_SidebarDelimChars, tmp_folder_name[i]))
1023  {
1024  sidebar_folder_depth++;
1025  lastsep = i + 1;
1026  }
1027  }
1028  if (sidebar_folder_depth > 0)
1029  {
1030  if (C_SidebarShortPath)
1031  tmp_folder_name += lastsep; /* basename */
1032  short_folder_name = mutt_buffer_pool_get();
1033  for (int i = 0; i < sidebar_folder_depth; i++)
1034  mutt_buffer_addstr(short_folder_name, NONULL(C_SidebarIndentString));
1035  mutt_buffer_addstr(short_folder_name, tmp_folder_name);
1036  sidebar_folder_name = mutt_b2s(short_folder_name);
1037  }
1038  }
1039  char str[256];
1040  make_sidebar_entry(str, sizeof(str), w, sidebar_folder_name, entry);
1041  mutt_window_printf("%s", str);
1042  mutt_buffer_pool_release(&short_folder_name);
1043  row++;
1044  }
1045 
1046  fill_empty_space(win, row, num_rows - row, div_width, w);
1047 }
The "current" mailbox.
Definition: context.h:37
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:192
enum MailboxType type
Mailbox type.
Definition: mailbox.h:105
#define NONULL(x)
Definition: string2.h:37
int msg_count
Total number of messages.
Definition: mailbox.h:91
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define MIN(a, b)
Definition: memory.h:31
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:93
void mutt_curses_set_color(enum ColorId color)
Set the current colour for text.
Definition: mutt_curses.c:55
Mailbox with no new or flagged messages.
Definition: color.h:90
int * defs
Array of all fixed colours, see enum ColorId.
Definition: color.h:132
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
String manipulation buffer.
Definition: buffer.h:33
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:689
Select cursor.
Definition: color.h:87
Info about folders in the sidebar.
Definition: sidebar.c:72
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:76
Mailbox with new mail.
Definition: color.h:89
Current open mailbox.
Definition: color.h:88
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:75
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
struct Mailbox * mailbox
Definition: context.h:51
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
Plain text.
Definition: color.h:78
#define mutt_b2s(buf)
Definition: buffer.h:41
WHERE char * C_Folder
Config: Base folder for a set of mailboxes.
Definition: globals.h:121
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
A mailbox.
Definition: mailbox.h:81
Selected item in list.
Definition: color.h:74
Definition: color.h:130
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:278
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:458
WHERE char * C_Spoolfile
Config: Inbox.
Definition: globals.h:145
int mutt_str_strncmp(const char *a, const char *b, size_t l)
Compare two strings (to a maximum), safely.
Definition: string.c:665
Mailbox with unread mail.
Definition: color.h:92
struct Buffer pathbuf
Definition: mailbox.h:83
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
Mailbox with flagged messages.
Definition: color.h:86
$spoolfile (Spool mailbox)
Definition: color.h:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sb_draw()

void mutt_sb_draw ( struct MuttWindow win)

Completely redraw the sidebar.

Parameters
winWindow to draw on

Completely refresh the sidebar region. First draw the divider; then, for each Mailbox, call make_sidebar_entry; finally blank out any remaining space.

Definition at line 1056 of file sidebar.c.

1057 {
1058  if (!C_SidebarVisible || !win)
1059  return;
1060 
1061  if (!mutt_window_is_visible(win))
1062  return;
1063 
1064  int row = 0, col = 0;
1065  mutt_window_get_coords(win, &row, &col);
1066 
1067  int num_rows = win->state.rows;
1068  int num_cols = win->state.cols;
1069 
1070  int div_width = draw_divider(win, num_rows, num_cols);
1071 
1072  if (!Entries)
1073  {
1074  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
1075  struct MailboxNode *np = NULL;
1076  STAILQ_FOREACH(np, &ml, entries)
1077  {
1078  mutt_sb_notify_mailbox(np->mailbox, true);
1079  }
1081  }
1082 
1083  if (!prepare_sidebar(num_rows))
1084  {
1085  fill_empty_space(win, 0, num_rows, div_width, num_cols - div_width);
1086  return;
1087  }
1088 
1089  draw_sidebar(win, num_rows, num_cols, div_width);
1090  mutt_window_move(win, row, col);
1091 }
void mutt_window_get_coords(struct MuttWindow *win, int *row, int *col)
Get the cursor position in the Window.
Definition: mutt_window.c:220
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
Match any Mailbox type.
Definition: mailbox.h:45
Container for Accounts, Notifications.
Definition: neomutt.h:35
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
bool mutt_window_is_visible(struct MuttWindow *win)
Is the Window visible?
Definition: mutt_window.c:539
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:278
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:157
List of Mailboxes.
Definition: mailbox.h:145
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sb_change_mailbox()

void mutt_sb_change_mailbox ( int  op)

Change the selected mailbox.

Parameters
opOperation code

Change the selected mailbox, e.g. "Next mailbox", "Previous Mailbox with new mail". The operations are listed in opcodes.h.

If the operation is successful, HilMailbox will be set to the new mailbox. This function only selects the mailbox, doesn't open it.

Allowed values are: OP_SIDEBAR_NEXT, OP_SIDEBAR_NEXT_NEW, OP_SIDEBAR_PAGE_DOWN, OP_SIDEBAR_PAGE_UP, OP_SIDEBAR_PREV, OP_SIDEBAR_PREV_NEW.

Definition at line 1107 of file sidebar.c.

1108 {
1109  if (!C_SidebarVisible)
1110  return;
1111 
1112  if (HilIndex < 0) /* It'll get reset on the next draw */
1113  return;
1114 
1115  switch (op)
1116  {
1117  case OP_SIDEBAR_NEXT:
1118  if (!select_next())
1119  return;
1120  break;
1121  case OP_SIDEBAR_NEXT_NEW:
1122  if (!select_next_new())
1123  return;
1124  break;
1125  case OP_SIDEBAR_PAGE_DOWN:
1126  if (!select_page_down())
1127  return;
1128  break;
1129  case OP_SIDEBAR_PAGE_UP:
1130  if (!select_page_up())
1131  return;
1132  break;
1133  case OP_SIDEBAR_PREV:
1134  if (!select_prev())
1135  return;
1136  break;
1137  case OP_SIDEBAR_PREV_NEW:
1138  if (!select_prev_new())
1139  return;
1140  break;
1141  default:
1142  return;
1143  }
1145 }
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sb_get_highlight()

struct Mailbox* mutt_sb_get_highlight ( void  )

Get the Mailbox that's highlighted in the sidebar.

Return values
ptrMailbox

Definition at line 1151 of file sidebar.c.

1152 {
1153  if (!C_SidebarVisible)
1154  return NULL;
1155 
1156  if (!EntryCount || (HilIndex < 0))
1157  return NULL;
1158 
1159  return Entries[HilIndex]->mailbox;
1160 }
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:75
+ Here is the caller graph for this function:

◆ mutt_sb_set_open_mailbox()

void mutt_sb_set_open_mailbox ( struct Mailbox m)

Set the 'open' Mailbox.

Parameters
mMailbox

Search through the list of mailboxes. If a Mailbox has a matching path, set OpnMailbox to it.

Definition at line 1169 of file sidebar.c.

1170 {
1171  OpnIndex = -1;
1172 
1173  if (!m)
1174  return;
1175 
1176  for (int entry = 0; entry < EntryCount; entry++)
1177  {
1178  if (mutt_str_strcmp(Entries[entry]->mailbox->realpath, m->realpath) == 0)
1179  {
1180  OpnIndex = entry;
1181  HilIndex = entry;
1182  break;
1183  }
1184  }
1185 }
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sb_notify_mailbox()

void mutt_sb_notify_mailbox ( struct Mailbox m,
bool  created 
)

The state of a Mailbox is about to change.

Parameters
mFolder
createdTrue if folder created, false if deleted

We receive a notification:

Before a deletion, check that our pointers won't be invalidated.

Definition at line 1198 of file sidebar.c.

1199 {
1200  if (!m)
1201  return;
1202 
1203  /* Any new/deleted mailboxes will cause a refresh. As long as
1204  * they're valid, our pointers will be updated in prepare_sidebar() */
1205 
1206  if (created)
1207  {
1208  if (EntryCount >= EntryLen)
1209  {
1210  EntryLen += 10;
1211  mutt_mem_realloc(&Entries, EntryLen * sizeof(struct SbEntry *));
1212  }
1213  Entries[EntryCount] = mutt_mem_calloc(1, sizeof(struct SbEntry));
1214  Entries[EntryCount]->mailbox = m;
1215 
1216  if (TopIndex < 0)
1217  TopIndex = EntryCount;
1218  if (BotIndex < 0)
1219  BotIndex = EntryCount;
1220  if ((OpnIndex < 0) && Context &&
1222  OpnIndex = EntryCount;
1223 
1224  EntryCount++;
1225  }
1226  else
1227  {
1228  int del_index;
1229  for (del_index = 0; del_index < EntryCount; del_index++)
1230  if (Entries[del_index]->mailbox == m)
1231  break;
1232  if (del_index == EntryCount)
1233  return;
1234  FREE(&Entries[del_index]);
1235  EntryCount--;
1236 
1237  if ((TopIndex > del_index) || (TopIndex == EntryCount))
1238  TopIndex--;
1239  if (OpnIndex == del_index)
1240  OpnIndex = -1;
1241  else if (OpnIndex > del_index)
1242  OpnIndex--;
1243  if ((HilIndex > del_index) || (HilIndex == EntryCount))
1244  HilIndex--;
1245  if ((BotIndex > del_index) || (BotIndex == EntryCount))
1246  BotIndex--;
1247 
1248  for (; del_index < EntryCount; del_index++)
1249  Entries[del_index] = Entries[del_index + 1];
1250  }
1251 
1253 }
The "current" mailbox.
Definition: context.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:84
Info about folders in the sidebar.
Definition: sidebar.c:72
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:75
struct Mailbox * mailbox
Definition: context.h:51
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
#define FREE(x)
Definition: memory.h:40
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:147
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_sb_observer()

int mutt_sb_observer ( struct NotifyCallback nc)

Listen for config changes affecting the sidebar - Implements observer_t.

Parameters
ncNotification data
Return values
boolTrue, if successful

Definition at line 1260 of file sidebar.c.

1261 {
1262  if (!nc->event_data || !nc->global_data)
1263  return -1;
1264  if (nc->event_type != NT_CONFIG)
1265  return 0;
1266 
1267  struct MuttWindow *win = nc->global_data;
1268  struct EventConfig *ec = nc->event_data;
1269 
1270  if (mutt_str_strncmp(ec->name, "sidebar_", 8) != 0)
1271  return 0;
1272 
1273  bool repaint = false;
1274 
1275  if (win->state.visible == !C_SidebarVisible)
1276  {
1278  repaint = true;
1279  }
1280 
1281  if (win->req_cols != C_SidebarWidth)
1282  {
1283  win->req_cols = C_SidebarWidth;
1284  repaint = true;
1285  }
1286 
1287  struct MuttWindow *parent = win->parent;
1288  struct MuttWindow *first = TAILQ_FIRST(&parent->children);
1289 
1290  if ((C_SidebarOnRight && (first == win)) || (!C_SidebarOnRight && (first != win)))
1291  {
1292  // Swap the Sidebar and the Container of the Index/Pager
1293  TAILQ_REMOVE(&parent->children, first, entries);
1294  TAILQ_INSERT_TAIL(&parent->children, first, entries);
1295  repaint = true;
1296  }
1297 
1298  if (repaint)
1299  {
1300  mutt_debug(LL_NOTIFY, "repaint sidebar\n");
1303  }
1304 
1305  return 0;
1306 }
#define TAILQ_FIRST(head)
Definition: queue.h:716
Log of notifications.
Definition: logging.h:45
A config-change event.
Definition: subset.h:70
A division of the screen.
Definition: mutt_window.h:88
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:41
void * global_data
Data from notify_observer_add()
Definition: observer.h:44
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
bool visible
Window is visible.
Definition: mutt_window.h:56
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
void * event_data
Data from notify_send()
Definition: observer.h:43
Config has changed.
Definition: notify_type.h:34
int mutt_str_strncmp(const char *a, const char *b, size_t l)
Compare two strings (to a maximum), safely.
Definition: string.c:665
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:345
struct MuttWindow * parent
Parent Window.
Definition: mutt_window.h:100
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:101
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct MuttWindow * MuttDialogWindow
Parent of all Dialogs.
Definition: mutt_window.c:44
const char * name
Name of config item that changed.
Definition: subset.h:73
short req_cols
Number of columns required.
Definition: mutt_window.h:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_SidebarComponentDepth

short C_SidebarComponentDepth

Config: (sidebar) Strip leading path components from sidebar folders.

Definition at line 51 of file sidebar.c.

◆ C_SidebarDelimChars

char* C_SidebarDelimChars

Config: (sidebar) Characters that separate nested folders.

Definition at line 52 of file sidebar.c.

◆ C_SidebarDividerChar

char* C_SidebarDividerChar

Config: (sidebar) Character to draw between the sidebar and index.

Definition at line 53 of file sidebar.c.

◆ C_SidebarFolderIndent

bool C_SidebarFolderIndent

Config: (sidebar) Indent nested folders.

Definition at line 54 of file sidebar.c.

◆ C_SidebarFormat

char* C_SidebarFormat

Config: (sidebar) printf-like format string for the sidebar panel.

Definition at line 55 of file sidebar.c.

◆ C_SidebarIndentString

char* C_SidebarIndentString

Config: (sidebar) Indent nested folders using this string.

Definition at line 56 of file sidebar.c.

◆ C_SidebarNewMailOnly

bool C_SidebarNewMailOnly

Config: (sidebar) Only show folders with new/flagged mail.

Definition at line 57 of file sidebar.c.

◆ C_SidebarNonEmptyMailboxOnly

bool C_SidebarNonEmptyMailboxOnly

Config: (sidebar) Only show folders with a non-zero number of mail.

Definition at line 58 of file sidebar.c.

◆ C_SidebarNextNewWrap

bool C_SidebarNextNewWrap

Config: (sidebar) Wrap around when searching for the next mailbox with new mail.

Definition at line 59 of file sidebar.c.

◆ C_SidebarOnRight

bool C_SidebarOnRight

Config: (sidebar) Display the sidebar on the right.

Definition at line 60 of file sidebar.c.

◆ C_SidebarShortPath

bool C_SidebarShortPath

Config: (sidebar) Abbreviate the paths using the C_Folder variable.

Definition at line 61 of file sidebar.c.

◆ C_SidebarSortMethod

short C_SidebarSortMethod

Config: (sidebar) Method to sort the sidebar.

Definition at line 62 of file sidebar.c.

◆ C_SidebarVisible

bool C_SidebarVisible

Config: (sidebar) Show the sidebar.

Definition at line 63 of file sidebar.c.

◆ C_SidebarWidth

short C_SidebarWidth

Config: (sidebar) Width of the sidebar.

Definition at line 64 of file sidebar.c.

◆ PreviousSort

short PreviousSort = SORT_ORDER
static

Definition at line 67 of file sidebar.c.

◆ EntryCount

int EntryCount = 0
static

Definition at line 79 of file sidebar.c.

◆ EntryLen

int EntryLen = 0
static

Definition at line 80 of file sidebar.c.

◆ Entries

struct SbEntry** Entries = NULL
static

Definition at line 81 of file sidebar.c.

◆ TopIndex

int TopIndex = -1
static

First mailbox visible in sidebar.

Definition at line 83 of file sidebar.c.

◆ OpnIndex

int OpnIndex = -1
static

Current (open) mailbox.

Definition at line 84 of file sidebar.c.

◆ HilIndex

int HilIndex = -1
static

Highlighted mailbox.

Definition at line 85 of file sidebar.c.

◆ BotIndex

int BotIndex = -1
static

Last mailbox visible in sidebar.

Definition at line 86 of file sidebar.c.