NeoMutt  2019-12-07-60-g0cfa53
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/mutt.h"
#include "config/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 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 90 of file sidebar.c.

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

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, blank otherwise
%N Number of unread messages in the mailbox
%S Size of mailbox (total number of messages)
%t Number of tagged messages

Definition at line 113 of file sidebar.c.

117 {
118  struct SbEntry *sbe = (struct SbEntry *) data;
119  char fmt[256];
120 
121  if (!sbe || !buf)
122  return src;
123 
124  buf[0] = '\0'; /* Just in case there's nothing to do */
125 
126  struct Mailbox *m = sbe->mailbox;
127  if (!m)
128  return src;
129 
130  bool c = Context && Context->mailbox &&
132 
133  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
134 
135  switch (op)
136  {
137  case 'B':
138  mutt_format_s(buf, buflen, prec, sbe->box);
139  break;
140 
141  case 'd':
142  if (!optional)
143  {
144  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
145  snprintf(buf, buflen, fmt, c ? Context->mailbox->msg_deleted : 0);
146  }
147  else if ((c && (Context->mailbox->msg_deleted == 0)) || !c)
148  optional = false;
149  break;
150 
151  case 'D':
152  if (sbe->mailbox->name)
153  mutt_format_s(buf, buflen, prec, sbe->mailbox->name);
154  else
155  mutt_format_s(buf, buflen, prec, sbe->box);
156  break;
157 
158  case 'F':
159  if (!optional)
160  {
161  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
162  snprintf(buf, buflen, fmt, m->msg_flagged);
163  }
164  else if (m->msg_flagged == 0)
165  optional = false;
166  break;
167 
168  case 'L':
169  if (!optional)
170  {
171  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
172  snprintf(buf, buflen, fmt, c ? Context->mailbox->vcount : m->msg_count);
173  }
174  else if ((c && (Context->mailbox->vcount == m->msg_count)) || !c)
175  optional = false;
176  break;
177 
178  case 'N':
179  if (!optional)
180  {
181  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
182  snprintf(buf, buflen, fmt, m->msg_unread);
183  }
184  else if (m->msg_unread == 0)
185  optional = false;
186  break;
187 
188  case 'n':
189  if (!optional)
190  {
191  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
192  snprintf(buf, buflen, fmt, m->has_new ? 'N' : ' ');
193  }
194  else if (m->has_new == false)
195  optional = false;
196  break;
197 
198  case 'S':
199  if (!optional)
200  {
201  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
202  snprintf(buf, buflen, fmt, m->msg_count);
203  }
204  else if (m->msg_count == 0)
205  optional = false;
206  break;
207 
208  case 't':
209  if (!optional)
210  {
211  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
212  snprintf(buf, buflen, fmt, c ? Context->mailbox->msg_tagged : 0);
213  }
214  else if ((c && (Context->mailbox->msg_tagged == 0)) || !c)
215  optional = false;
216  break;
217 
218  case '!':
219  if (m->msg_flagged == 0)
220  mutt_format_s(buf, buflen, prec, "");
221  else if (m->msg_flagged == 1)
222  mutt_format_s(buf, buflen, prec, "!");
223  else if (m->msg_flagged == 2)
224  mutt_format_s(buf, buflen, prec, "!!");
225  else
226  {
227  snprintf(fmt, sizeof(fmt), "%d!", m->msg_flagged);
228  mutt_format_s(buf, buflen, prec, fmt);
229  }
230  break;
231  }
232 
233  if (optional)
234  {
235  mutt_expando_format(buf, buflen, col, C_SidebarWidth, if_str,
236  sidebar_format_str, (unsigned long) sbe, flags);
237  }
238  else if (flags & MUTT_FORMAT_OPTIONAL)
239  {
240  mutt_expando_format(buf, buflen, col, C_SidebarWidth, else_str,
241  sidebar_format_str, (unsigned long) sbe, flags);
242  }
243 
244  /* We return the format string, unchanged */
245  return src;
246 }
The "current" mailbox.
Definition: context.h:36
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:877
int msg_count
Total number of messages.
Definition: mailbox.h:90
int msg_deleted
Number of deleted messages.
Definition: mailbox.h:95
int msg_unread
Number of unread messages.
Definition: mailbox.h:91
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:92
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:83
Info about folders in the sidebar.
Definition: sidebar.c:71
int vcount
The number of virtual messages.
Definition: mailbox.h:101
bool has_new
Mailbox has new mail.
Definition: mailbox.h:87
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:74
char * name
A short name for the Mailbox.
Definition: mailbox.h:84
struct Mailbox * mailbox
Definition: context.h:50
int flags
e.g. MB_NORMAL
Definition: mailbox.h:133
char box[256]
formatted mailbox name
Definition: sidebar.c:73
A mailbox.
Definition: mailbox.h:80
int msg_tagged
How many messages are tagged?
Definition: mailbox.h:96
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1244
#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:615
+ 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 260 of file sidebar.c.

262 {
263  if (!buf || !box || !sbe)
264  return;
265 
266  mutt_str_strfcpy(sbe->box, box, sizeof(sbe->box));
267 
268  mutt_expando_format(buf, buflen, 0, width, NONULL(C_SidebarFormat),
269  sidebar_format_str, (unsigned long) sbe, MUTT_FORMAT_NO_FLAGS);
270 
271  /* Force string to be exactly the right width */
272  int w = mutt_strwidth(buf);
273  int s = mutt_str_strlen(buf);
274  width = MIN(buflen, width);
275  if (w < width)
276  {
277  /* Pad with spaces */
278  memset(buf + s, ' ', width - w);
279  buf[s + width - w] = '\0';
280  }
281  else if (w > width)
282  {
283  /* Truncate to fit */
284  size_t len = mutt_wstr_trunc(buf, buflen, width, NULL);
285  buf[len] = '\0';
286  }
287 }
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:877
#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:666
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
char box[256]
formatted mailbox name
Definition: sidebar.c:73
int mutt_strwidth(const char *s)
Measure a string&#39;s width in screen cells.
Definition: curs_lib.c:1359
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:1309
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:750
+ 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 297 of file sidebar.c.

298 {
299  const struct SbEntry *sbe1 = *(struct SbEntry const *const *) a;
300  const struct SbEntry *sbe2 = *(struct SbEntry const *const *) b;
301  const struct Mailbox *m1 = sbe1->mailbox;
302  const struct Mailbox *m2 = sbe2->mailbox;
303 
304  int rc = 0;
305 
306  switch ((C_SidebarSortMethod & SORT_MASK))
307  {
308  case SORT_COUNT:
309  if (m2->msg_count == m1->msg_count)
311  else
312  rc = (m2->msg_count - m1->msg_count);
313  break;
314  case SORT_UNREAD:
315  if (m2->msg_unread == m1->msg_unread)
317  else
318  rc = (m2->msg_unread - m1->msg_unread);
319  break;
320  case SORT_DESC:
321  rc = mutt_str_strcmp(m1->name, m2->name);
322  break;
323  case SORT_FLAGGED:
324  if (m2->msg_flagged == m1->msg_flagged)
326  else
327  rc = (m2->msg_flagged - m1->msg_flagged);
328  break;
329  case SORT_PATH:
330  {
332  if (rc == 0)
334  break;
335  }
336  }
337 
339  rc = -rc;
340 
341  return rc;
342 }
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
int msg_count
Total number of messages.
Definition: mailbox.h:90
int msg_unread
Number of unread messages.
Definition: mailbox.h:91
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:92
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:71
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:74
char * name
A short name for the Mailbox.
Definition: mailbox.h:84
A mailbox.
Definition: mailbox.h:80
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:1710
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:679
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
#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 355 of file sidebar.c.

356 {
357  /* Aliases for readability */
358  const bool new_only = C_SidebarNewMailOnly;
359  const bool non_empty_only = C_SidebarNonEmptyMailboxOnly;
360  struct SbEntry *sbe = NULL;
361 
362  /* Take the fast path if there is no need to test visibilities */
363  if (!new_only && !non_empty_only)
364  {
365  for (int i = 0; i < EntryCount; i++)
366  {
367  Entries[i]->is_hidden = false;
368  }
369  return;
370  }
371 
372  for (int i = 0; i < EntryCount; i++)
373  {
374  sbe = Entries[i];
375 
376  sbe->is_hidden = false;
377 
379  {
380  /* Spool directories are always visible */
381  continue;
382  }
383 
384  if (mutt_list_find(&SidebarWhitelist, mailbox_path(sbe->mailbox)) ||
385  mutt_list_find(&SidebarWhitelist, sbe->mailbox->name))
386  {
387  /* Explicitly asked to be visible */
388  continue;
389  }
390 
391  if (non_empty_only && (i != OpnIndex) && (sbe->mailbox->msg_count == 0))
392  {
393  sbe->is_hidden = true;
394  }
395 
396  if (new_only && (i != OpnIndex) && (sbe->mailbox->msg_unread == 0) &&
397  (sbe->mailbox->msg_flagged == 0) && !sbe->mailbox->has_new)
398  {
399  sbe->is_hidden = true;
400  }
401  }
402 }
The "current" mailbox.
Definition: context.h:36
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
int msg_count
Total number of messages.
Definition: mailbox.h:90
int msg_unread
Number of unread messages.
Definition: mailbox.h:91
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:92
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:83
Info about folders in the sidebar.
Definition: sidebar.c:71
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:75
bool has_new
Mailbox has new mail.
Definition: mailbox.h:87
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:74
char * name
A short name for the Mailbox.
Definition: mailbox.h:84
struct Mailbox * mailbox
Definition: context.h:50
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:615
+ 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 407 of file sidebar.c.

408 {
409  int i = 0;
410 
411  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
412  struct MailboxNode *np = NULL;
413  STAILQ_FOREACH(np, &ml, entries)
414  {
415  if (i >= EntryCount)
416  break;
417 
418  int j = i;
419  while ((j < EntryCount) && (Entries[j]->mailbox != np->mailbox))
420  j++;
421  if (j < EntryCount)
422  {
423  if (j != i)
424  {
425  struct SbEntry *tmp = Entries[i];
426  Entries[i] = Entries[j];
427  Entries[j] = tmp;
428  }
429  i++;
430  }
431  }
433 }
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
Match any Mailbox type.
Definition: mailbox.h:44
Info about folders in the sidebar.
Definition: sidebar.c:71
Container for Accounts, Notifications.
Definition: neomutt.h:35
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType magic)
Get a List of all Mailboxes.
Definition: neomutt.c:157
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
List of Mailboxes.
Definition: mailbox.h:144
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:146
+ 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 444 of file sidebar.c.

445 {
446  enum SortType ssm = (C_SidebarSortMethod & SORT_MASK);
447 
448  /* These are the only sort methods we understand */
449  if ((ssm == SORT_COUNT) || (ssm == SORT_UNREAD) || (ssm == SORT_FLAGGED) || (ssm == SORT_PATH))
450  qsort(Entries, EntryCount, sizeof(*Entries), cb_qsort_sbe);
451  else if ((ssm == SORT_ORDER) && (C_SidebarSortMethod != PreviousSort))
452  unsort_entries();
453 }
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 460 of file sidebar.c.

461 {
462  int entry = HilIndex;
463 
464  if (!EntryCount || (HilIndex < 0))
465  return false;
466 
467  do
468  {
469  entry++;
470  if (entry == EntryCount)
471  return false;
472  } while (Entries[entry]->is_hidden);
473 
474  HilIndex = entry;
475  return true;
476 }
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:75
+ 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 485 of file sidebar.c.

486 {
487  int entry = HilIndex;
488 
489  if (!EntryCount || (HilIndex < 0))
490  return false;
491 
492  do
493  {
494  entry++;
495  if (entry == EntryCount)
496  {
498  entry = 0;
499  else
500  return false;
501  }
502  if (entry == HilIndex)
503  return false;
504  } while (!Entries[entry]->mailbox->has_new && (Entries[entry]->mailbox->msg_unread == 0));
505 
506  HilIndex = entry;
507  return true;
508 }
int msg_unread
Number of unread messages.
Definition: mailbox.h:91
bool has_new
Mailbox has new mail.
Definition: mailbox.h:87
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:74
+ 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 515 of file sidebar.c.

516 {
517  int entry = HilIndex;
518 
519  if (!EntryCount || (HilIndex < 0))
520  return false;
521 
522  do
523  {
524  entry--;
525  if (entry < 0)
526  return false;
527  } while (Entries[entry]->is_hidden);
528 
529  HilIndex = entry;
530  return true;
531 }
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:75
+ 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 540 of file sidebar.c.

541 {
542  int entry = HilIndex;
543 
544  if (!EntryCount || (HilIndex < 0))
545  return false;
546 
547  do
548  {
549  entry--;
550  if (entry < 0)
551  {
553  entry = EntryCount - 1;
554  else
555  return false;
556  }
557  if (entry == HilIndex)
558  return false;
559  } while (!Entries[entry]->mailbox->has_new && (Entries[entry]->mailbox->msg_unread == 0));
560 
561  HilIndex = entry;
562  return true;
563 }
int msg_unread
Number of unread messages.
Definition: mailbox.h:91
bool has_new
Mailbox has new mail.
Definition: mailbox.h:87
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:74
+ 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 570 of file sidebar.c.

571 {
572  int orig_hil_index = HilIndex;
573 
574  if (!EntryCount || (BotIndex < 0))
575  return 0;
576 
577  HilIndex = BotIndex;
578  select_next();
579  /* If the rest of the entries are hidden, go up to the last unhidden one */
580  if (Entries[HilIndex]->is_hidden)
581  select_prev();
582 
583  return orig_hil_index != HilIndex;
584 }
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:75
+ 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 591 of file sidebar.c.

592 {
593  int orig_hil_index = HilIndex;
594 
595  if (!EntryCount || (TopIndex < 0))
596  return 0;
597 
598  HilIndex = TopIndex;
599  select_prev();
600  /* If the rest of the entries are hidden, go down to the last unhidden one */
601  if (Entries[HilIndex]->is_hidden)
602  select_next();
603 
604  return orig_hil_index != HilIndex;
605 }
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:75
+ 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 619 of file sidebar.c.

620 {
621  if (!EntryCount || (page_size <= 0))
622  return false;
623 
624  const struct SbEntry *opn_entry = (OpnIndex >= 0) ? Entries[OpnIndex] : NULL;
625  const struct SbEntry *hil_entry = (HilIndex >= 0) ? Entries[HilIndex] : NULL;
626 
628  sort_entries();
629 
630  for (int i = 0; i < EntryCount; i++)
631  {
632  if (opn_entry == Entries[i])
633  OpnIndex = i;
634  if (hil_entry == Entries[i])
635  HilIndex = i;
636  }
637 
639  {
640  if (OpnIndex >= 0)
641  HilIndex = OpnIndex;
642  else
643  {
644  HilIndex = 0;
645  if (Entries[HilIndex]->is_hidden)
646  select_next();
647  }
648  }
649 
650  /* Set the Top and Bottom to frame the HilIndex in groups of page_size */
651 
652  /* If C_SidebarNewMailOnly or C_SidebarNonEmptyMailboxOnly is set, some entries
653  * may be hidden so we need to scan for the framing interval */
655  {
656  TopIndex = -1;
657  BotIndex = -1;
658  while (BotIndex < HilIndex)
659  {
660  TopIndex = BotIndex + 1;
661  int page_entries = 0;
662  while (page_entries < page_size)
663  {
664  BotIndex++;
665  if (BotIndex >= EntryCount)
666  break;
667  if (!Entries[BotIndex]->is_hidden)
668  page_entries++;
669  }
670  }
671  }
672  /* Otherwise we can just calculate the interval */
673  else
674  {
675  TopIndex = (HilIndex / page_size) * page_size;
676  BotIndex = TopIndex + page_size - 1;
677  }
678 
679  if (BotIndex > (EntryCount - 1))
680  BotIndex = EntryCount - 1;
681 
683  return true;
684 }
Info about folders in the sidebar.
Definition: sidebar.c:71
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:75
+ 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 701 of file sidebar.c.

702 {
703  if ((num_rows < 1) || (num_cols < 1))
704  return 0;
705 
706  int delim_len;
707  enum DivType altchar = SB_DIV_UTF8;
708 
709  /* Calculate the width of the delimiter in screen cells */
710  delim_len = mutt_strwidth(C_SidebarDividerChar);
711  if (delim_len < 0)
712  {
713  delim_len = 1; /* Bad character */
714  }
715  else if (delim_len == 0)
716  {
718  return 0; /* User has set empty string */
719 
720  delim_len = 1; /* Unset variable */
721  }
722  else
723  {
724  altchar = SB_DIV_USER; /* User config */
725  }
726 
727  if (C_AsciiChars && (altchar != SB_DIV_ASCII))
728  {
729  /* $ascii_chars overrides Unicode divider chars */
730  if (altchar == SB_DIV_UTF8)
731  {
732  altchar = SB_DIV_ASCII;
733  }
734  else if (C_SidebarDividerChar)
735  {
736  for (int i = 0; i < delim_len; i++)
737  {
738  if (C_SidebarDividerChar[i] & ~0x7F) /* high-bit is set */
739  {
740  altchar = SB_DIV_ASCII;
741  delim_len = 1;
742  break;
743  }
744  }
745  }
746  }
747 
748  if (delim_len > num_cols)
749  return 0;
750 
752 
753  int col = C_SidebarOnRight ? 0 : (C_SidebarWidth - delim_len);
754 
755  for (int i = 0; i < num_rows; i++)
756  {
757  mutt_window_move(win, i, col);
758 
759  switch (altchar)
760  {
761  case SB_DIV_USER:
763  break;
764  case SB_DIV_ASCII:
765  mutt_window_addch('|');
766  break;
767  case SB_DIV_UTF8:
768  mutt_window_addch(ACS_VLINE);
769  break;
770  }
771  }
772 
773  return delim_len;
774 }
#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:1359
WHERE bool C_AsciiChars
Config: Use plain ASCII characters, when drawing email threads.
Definition: globals.h:194
int mutt_window_move(struct MuttWindow *win, int row, int col)
Move the cursor in a Window.
Definition: mutt_window.c:279
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:398
int mutt_window_addstr(const char *str)
Write a string to a Window.
Definition: mutt_window.c:428
+ 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 786 of file sidebar.c.

788 {
789  /* Fill the remaining rows with blank space */
791 
792  if (!C_SidebarOnRight)
793  div_width = 0;
794  for (int r = 0; r < num_rows; r++)
795  {
796  mutt_window_move(win, first_row + r, div_width);
797 
798  for (int i = 0; i < num_cols; i++)
799  mutt_window_addch(' ');
800  }
801 }
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:279
int mutt_window_addch(int ch)
Write one character to a Window.
Definition: mutt_window.c:398
+ 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 824 of file sidebar.c.

825 {
826  struct SbEntry *entry = NULL;
827  struct Mailbox *m = NULL;
828  if (TopIndex < 0)
829  return;
830 
831  int w = MIN(num_cols, (C_SidebarWidth - div_width));
832  int row = 0;
833  for (int entryidx = TopIndex; (entryidx < EntryCount) && (row < num_rows); entryidx++)
834  {
835  entry = Entries[entryidx];
836  if (entry->is_hidden)
837  continue;
838  m = entry->mailbox;
839 
840  if (entryidx == OpnIndex)
841  {
844  else
846  }
847  else if (entryidx == HilIndex)
849  else if (m->has_new)
851  else if (m->msg_unread > 0)
853  else if (m->msg_flagged > 0)
855  else if ((Colors->defs[MT_COLOR_SIDEBAR_SPOOLFILE] != 0) &&
857  {
859  }
860  else
861  {
864  else
866  }
867 
868  int col = 0;
869  if (C_SidebarOnRight)
870  col = div_width;
871 
872  mutt_window_move(win, row, col);
873  if (Context && Context->mailbox && (Context->mailbox->realpath[0] != '\0') &&
875  {
879  }
880 
881  /* compute length of C_Folder without trailing separator */
882  size_t maildirlen = mutt_str_strlen(C_Folder);
883  if (maildirlen && C_SidebarDelimChars &&
884  strchr(C_SidebarDelimChars, C_Folder[maildirlen - 1]))
885  maildirlen--;
886 
887  /* check whether C_Folder is a prefix of the current folder's path */
888  bool maildir_is_prefix = false;
889  if ((mutt_buffer_len(&m->pathbuf) > maildirlen) &&
890  (mutt_str_strncmp(C_Folder, mailbox_path(m), maildirlen) == 0) &&
891  C_SidebarDelimChars && strchr(C_SidebarDelimChars, mailbox_path(m)[maildirlen]))
892  {
893  maildir_is_prefix = true;
894  }
895 
896  /* calculate depth of current folder and generate its display name with indented spaces */
897  int sidebar_folder_depth = 0;
898  const char *sidebar_folder_name = NULL;
899  struct Buffer *short_folder_name = NULL;
900  if (C_SidebarShortPath)
901  {
902  /* disregard a trailing separator, so strlen() - 2 */
903  sidebar_folder_name = mailbox_path(m);
904  for (int i = mutt_str_strlen(sidebar_folder_name) - 2; i >= 0; i--)
905  {
906  if (C_SidebarDelimChars && strchr(C_SidebarDelimChars, sidebar_folder_name[i]))
907  {
908  sidebar_folder_name += (i + 1);
909  break;
910  }
911  }
912  }
914  {
915  sidebar_folder_name = mailbox_path(m) + maildir_is_prefix * (maildirlen + 1);
916  for (int i = 0; i < C_SidebarComponentDepth; i++)
917  {
918  char *chars_after_delim = strpbrk(sidebar_folder_name, C_SidebarDelimChars);
919  if (!chars_after_delim)
920  break;
921 
922  sidebar_folder_name = chars_after_delim + 1;
923  }
924  }
925  else
926  sidebar_folder_name = mailbox_path(m) + maildir_is_prefix * (maildirlen + 1);
927 
928  if (m->name)
929  {
930  sidebar_folder_name = m->name;
931  }
932  else if (maildir_is_prefix && C_SidebarFolderIndent)
933  {
934  int lastsep = 0;
935  const char *tmp_folder_name = mailbox_path(m) + maildirlen + 1;
936  int tmplen = (int) mutt_str_strlen(tmp_folder_name) - 1;
937  for (int i = 0; i < tmplen; i++)
938  {
939  if (C_SidebarDelimChars && strchr(C_SidebarDelimChars, tmp_folder_name[i]))
940  {
941  sidebar_folder_depth++;
942  lastsep = i + 1;
943  }
944  }
945  if (sidebar_folder_depth > 0)
946  {
947  if (C_SidebarShortPath)
948  tmp_folder_name += lastsep; /* basename */
949  short_folder_name = mutt_buffer_pool_get();
950  for (int i = 0; i < sidebar_folder_depth; i++)
951  mutt_buffer_addstr(short_folder_name, NONULL(C_SidebarIndentString));
952  mutt_buffer_addstr(short_folder_name, tmp_folder_name);
953  sidebar_folder_name = mutt_b2s(short_folder_name);
954  }
955  }
956  char str[256];
957  make_sidebar_entry(str, sizeof(str), w, sidebar_folder_name, entry);
958  mutt_window_printf("%s", str);
959  mutt_buffer_pool_release(&short_folder_name);
960  row++;
961  }
962 
963  fill_empty_space(win, row, num_rows - row, div_width, w);
964 }
The "current" mailbox.
Definition: context.h:36
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
#define NONULL(x)
Definition: string2.h:37
int msg_count
Total number of messages.
Definition: mailbox.h:90
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:91
int msg_flagged
Number of flagged messages.
Definition: mailbox.h:92
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:83
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:666
Select cursor.
Definition: color.h:87
Info about folders in the sidebar.
Definition: sidebar.c:71
bool is_hidden
Don&#39;t show, e.g. $sidebar_new_mail_only.
Definition: sidebar.c:75
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:87
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:74
char * name
A short name for the Mailbox.
Definition: mailbox.h:84
struct Mailbox * mailbox
Definition: context.h:50
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:119
size_t mutt_buffer_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:356
A mailbox.
Definition: mailbox.h:80
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:279
int mutt_window_printf(const char *fmt,...)
Write a formatted string to a Window.
Definition: mutt_window.c:456
WHERE char * C_Spoolfile
Config: Inbox.
Definition: globals.h:144
int mutt_str_strncmp(const char *a, const char *b, size_t l)
Compare two strings (to a maximum), safely.
Definition: string.c:642
Mailbox with unread mail.
Definition: color.h:92
struct Buffer pathbuf
Definition: mailbox.h:82
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
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 973 of file sidebar.c.

974 {
975  if (!C_SidebarVisible || !win)
976  return;
977 
978  if (!mutt_window_is_visible(win))
979  return;
980 
981  int row = 0, col = 0;
982  mutt_window_get_coords(win, &row, &col);
983 
984  int num_rows = win->state.rows;
985  int num_cols = win->state.cols;
986 
987  int div_width = draw_divider(win, num_rows, num_cols);
988 
989  if (!Entries)
990  {
991  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
992  struct MailboxNode *np = NULL;
993  STAILQ_FOREACH(np, &ml, entries)
994  {
995  mutt_sb_notify_mailbox(np->mailbox, true);
996  }
998  }
999 
1000  if (!prepare_sidebar(num_rows))
1001  {
1002  fill_empty_space(win, 0, num_rows, div_width, num_cols - div_width);
1003  return;
1004  }
1005 
1006  draw_sidebar(win, num_rows, num_cols, div_width);
1007  mutt_window_move(win, row, col);
1008 }
void mutt_window_get_coords(struct MuttWindow *win, int *row, int *col)
Get the cursor position in the Window.
Definition: mutt_window.c:221
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
Match any Mailbox type.
Definition: mailbox.h:44
Container for Accounts, Notifications.
Definition: neomutt.h:35
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType magic)
Get a List of all Mailboxes.
Definition: neomutt.c:157
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:56
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
bool mutt_window_is_visible(struct MuttWindow *win)
Is the Window visible?
Definition: mutt_window.c:537
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:55
#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:279
List of Mailboxes.
Definition: mailbox.h:144
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:146
+ 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 1024 of file sidebar.c.

1025 {
1026  if (!C_SidebarVisible)
1027  return;
1028 
1029  if (HilIndex < 0) /* It'll get reset on the next draw */
1030  return;
1031 
1032  switch (op)
1033  {
1034  case OP_SIDEBAR_NEXT:
1035  if (!select_next())
1036  return;
1037  break;
1038  case OP_SIDEBAR_NEXT_NEW:
1039  if (!select_next_new())
1040  return;
1041  break;
1042  case OP_SIDEBAR_PAGE_DOWN:
1043  if (!select_page_down())
1044  return;
1045  break;
1046  case OP_SIDEBAR_PAGE_UP:
1047  if (!select_page_up())
1048  return;
1049  break;
1050  case OP_SIDEBAR_PREV:
1051  if (!select_prev())
1052  return;
1053  break;
1054  case OP_SIDEBAR_PREV_NEW:
1055  if (!select_prev_new())
1056  return;
1057  break;
1058  default:
1059  return;
1060  }
1062 }
#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 1068 of file sidebar.c.

1069 {
1070  if (!C_SidebarVisible)
1071  return NULL;
1072 
1073  if (!EntryCount || (HilIndex < 0))
1074  return NULL;
1075 
1076  return Entries[HilIndex]->mailbox;
1077 }
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:74
+ 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 1086 of file sidebar.c.

1087 {
1088  OpnIndex = -1;
1089 
1090  if (!m)
1091  return;
1092 
1093  for (int entry = 0; entry < EntryCount; entry++)
1094  {
1095  if (mutt_str_strcmp(Entries[entry]->mailbox->realpath, m->realpath) == 0)
1096  {
1097  OpnIndex = entry;
1098  HilIndex = entry;
1099  break;
1100  }
1101  }
1102 }
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:83
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:146
+ 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 1115 of file sidebar.c.

1116 {
1117  if (!m)
1118  return;
1119 
1120  /* Any new/deleted mailboxes will cause a refresh. As long as
1121  * they're valid, our pointers will be updated in prepare_sidebar() */
1122 
1123  if (created)
1124  {
1125  if (EntryCount >= EntryLen)
1126  {
1127  EntryLen += 10;
1128  mutt_mem_realloc(&Entries, EntryLen * sizeof(struct SbEntry *));
1129  }
1130  Entries[EntryCount] = mutt_mem_calloc(1, sizeof(struct SbEntry));
1131  Entries[EntryCount]->mailbox = m;
1132 
1133  if (TopIndex < 0)
1134  TopIndex = EntryCount;
1135  if (BotIndex < 0)
1136  BotIndex = EntryCount;
1137  if ((OpnIndex < 0) && Context &&
1139  OpnIndex = EntryCount;
1140 
1141  EntryCount++;
1142  }
1143  else
1144  {
1145  int del_index;
1146  for (del_index = 0; del_index < EntryCount; del_index++)
1147  if (Entries[del_index]->mailbox == m)
1148  break;
1149  if (del_index == EntryCount)
1150  return;
1151  FREE(&Entries[del_index]);
1152  EntryCount--;
1153 
1154  if ((TopIndex > del_index) || (TopIndex == EntryCount))
1155  TopIndex--;
1156  if (OpnIndex == del_index)
1157  OpnIndex = -1;
1158  else if (OpnIndex > del_index)
1159  OpnIndex--;
1160  if ((HilIndex > del_index) || (HilIndex == EntryCount))
1161  HilIndex--;
1162  if ((BotIndex > del_index) || (BotIndex == EntryCount))
1163  BotIndex--;
1164 
1165  for (; del_index < EntryCount; del_index++)
1166  Entries[del_index] = Entries[del_index + 1];
1167  }
1168 
1170 }
The "current" mailbox.
Definition: context.h:36
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:83
Info about folders in the sidebar.
Definition: sidebar.c:71
#define REDRAW_SIDEBAR
Redraw the sidebar.
Definition: mutt_menu.h:51
struct Mailbox * mailbox
Mailbox this represents.
Definition: sidebar.c:74
struct Mailbox * mailbox
Definition: context.h:50
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:615
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:146
+ 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 1177 of file sidebar.c.

1178 {
1179  if (!nc->event_data || !nc->global_data)
1180  return -1;
1181  if (nc->event_type != NT_CONFIG)
1182  return 0;
1183 
1184  struct MuttWindow *win = nc->global_data;
1185  struct EventConfig *ec = nc->event_data;
1186 
1187  if (mutt_str_strncmp(ec->name, "sidebar_", 8) != 0)
1188  return 0;
1189 
1190  bool repaint = false;
1191 
1192  if (win->state.visible == !C_SidebarVisible)
1193  {
1195  repaint = true;
1196  }
1197 
1198  if (win->req_cols != C_SidebarWidth)
1199  {
1200  win->req_cols = C_SidebarWidth;
1201  repaint = true;
1202  }
1203 
1204  struct MuttWindow *parent = win->parent;
1205  struct MuttWindow *first = TAILQ_FIRST(&parent->children);
1206 
1207  if ((C_SidebarOnRight && (first == win)) || (!C_SidebarOnRight && (first != win)))
1208  {
1209  // Swap the Sidebar and the Container of the Index/Pager
1210  TAILQ_REMOVE(&parent->children, first, entries);
1211  TAILQ_INSERT_TAIL(&parent->children, first, entries);
1212  repaint = true;
1213  }
1214 
1215  if (repaint)
1216  {
1217  mutt_debug(LL_NOTIFY, "repaint sidebar\n");
1220  }
1221 
1222  return 0;
1223 }
#define TAILQ_FIRST(head)
Definition: queue.h:716
Log of notifications.
Definition: logging.h:45
A config-change event.
Definition: subset.h:68
A division of the screen.
Definition: mutt_window.h:86
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
bool visible
Window is visible.
Definition: mutt_window.h:54
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
void * event_data
Data from notify_send()
Definition: observer.h:44
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:642
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:346
struct MuttWindow * parent
Parent Window.
Definition: mutt_window.h:98
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:99
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
struct MuttWindow * MuttDialogWindow
Parent of all Dialogs.
Definition: mutt_window.c:45
const char * name
Name of config item that changed.
Definition: subset.h:71
short req_cols
Number of columns required.
Definition: mutt_window.h:89
+ 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 50 of file sidebar.c.

◆ C_SidebarDelimChars

char* C_SidebarDelimChars

Config: (sidebar) Characters that separate nested folders.

Definition at line 51 of file sidebar.c.

◆ C_SidebarDividerChar

char* C_SidebarDividerChar

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

Definition at line 52 of file sidebar.c.

◆ C_SidebarFolderIndent

bool C_SidebarFolderIndent

Config: (sidebar) Indent nested folders.

Definition at line 53 of file sidebar.c.

◆ C_SidebarFormat

char* C_SidebarFormat

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

Definition at line 54 of file sidebar.c.

◆ C_SidebarIndentString

char* C_SidebarIndentString

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

Definition at line 55 of file sidebar.c.

◆ C_SidebarNewMailOnly

bool C_SidebarNewMailOnly

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

Definition at line 56 of file sidebar.c.

◆ C_SidebarNonEmptyMailboxOnly

bool C_SidebarNonEmptyMailboxOnly

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

Definition at line 57 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 58 of file sidebar.c.

◆ C_SidebarOnRight

bool C_SidebarOnRight

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

Definition at line 59 of file sidebar.c.

◆ C_SidebarShortPath

bool C_SidebarShortPath

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

Definition at line 60 of file sidebar.c.

◆ C_SidebarSortMethod

short C_SidebarSortMethod

Config: (sidebar) Method to sort the sidebar.

Definition at line 61 of file sidebar.c.

◆ C_SidebarVisible

bool C_SidebarVisible

Config: (sidebar) Show the sidebar.

Definition at line 62 of file sidebar.c.

◆ C_SidebarWidth

short C_SidebarWidth

Config: (sidebar) Width of the sidebar.

Definition at line 63 of file sidebar.c.

◆ PreviousSort

short PreviousSort = SORT_ORDER
static

Definition at line 66 of file sidebar.c.

◆ EntryCount

int EntryCount = 0
static

Definition at line 78 of file sidebar.c.

◆ EntryLen

int EntryLen = 0
static

Definition at line 79 of file sidebar.c.

◆ Entries

struct SbEntry** Entries = NULL
static

Definition at line 80 of file sidebar.c.

◆ TopIndex

int TopIndex = -1
static

First mailbox visible in sidebar.

Definition at line 82 of file sidebar.c.

◆ OpnIndex

int OpnIndex = -1
static

Current (open) mailbox.

Definition at line 83 of file sidebar.c.

◆ HilIndex

int HilIndex = -1
static

Highlighted mailbox.

Definition at line 84 of file sidebar.c.

◆ BotIndex

int BotIndex = -1
static

Last mailbox visible in sidebar.

Definition at line 85 of file sidebar.c.