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

GUI component for displaying/selecting items from a list. More...

#include "config.h"
#include <dirent.h>
#include <errno.h>
#include <grp.h>
#include <limits.h>
#include <locale.h>
#include <pwd.h>
#include <regex.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "browser.h"
#include "context.h"
#include "format_flags.h"
#include "globals.h"
#include "keymap.h"
#include "mutt_attach.h"
#include "mutt_mailbox.h"
#include "mutt_menu.h"
#include "muttlib.h"
#include "mx.h"
#include "opcodes.h"
#include "options.h"
#include "sendlib.h"
#include "imap/lib.h"
#include "nntp/lib.h"
+ Include dependency graph for browser.c:

Go to the source code of this file.

Functions

static void init_lastdir (void)
 Initialise the browser directories. More...
 
void mutt_browser_cleanup (void)
 Clean up working Buffers. More...
 
static void destroy_state (struct BrowserState *state)
 Free the BrowserState. More...
 
static int browser_compare_subject (const void *a, const void *b)
 Compare the subject of two browser entries. More...
 
static int browser_compare_desc (const void *a, const void *b)
 Compare the descriptions of two browser entries. More...
 
static int browser_compare_date (const void *a, const void *b)
 Compare the date of two browser entries. More...
 
static int browser_compare_size (const void *a, const void *b)
 Compare the size of two browser entries. More...
 
static int browser_compare_count (const void *a, const void *b)
 Compare the message count of two browser entries. More...
 
static int browser_compare_count_new (const void *a, const void *b)
 Compare the new count of two browser entries. More...
 
static int browser_compare (const void *a, const void *b)
 Sort the items in the browser. More...
 
static void browser_sort (struct BrowserState *state)
 Sort the entries in the browser. More...
 
static bool link_is_dir (const char *folder, const char *path)
 Does this symlink point to a directory? More...
 
static const char * folder_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 folder browser - Implements format_t. More...
 
static void add_folder (struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
 Add a folder to the browser list. More...
 
static void init_state (struct BrowserState *state, struct Menu *menu)
 Initialise a browser state. More...
 
static int examine_directory (struct Menu *menu, struct BrowserState *state, const char *d, const char *prefix)
 Get list of all files/newsgroups with mask. More...
 
static int examine_mailboxes (struct Menu *menu, struct BrowserState *state)
 Get list of mailboxes/subscribed newsgroups. More...
 
static int select_file_search (struct Menu *menu, regex_t *rx, int line)
 Menu search callback for matching files - Implements Menu::search() More...
 
static void folder_make_entry (char *buf, size_t buflen, struct Menu *menu, int line)
 Format a menu item for the folder browser - Implements Menu::make_entry() More...
 
static void browser_highlight_default (struct BrowserState *state, struct Menu *menu)
 Decide which browser item should be highlighted. More...
 
static void init_menu (struct BrowserState *state, struct Menu *menu, char *title, size_t titlelen, bool mailbox)
 Set up a new menu. More...
 
static int file_tag (struct Menu *menu, int sel, int act)
 Tag an entry in the menu - Implements Menu::tag() More...
 
void mutt_browser_select_dir (const char *f)
 Remember the last directory selected. More...
 
static int mutt_dlg_browser_observer (struct NotifyCallback *nc)
 Listen for config changes affecting the Browser menu - Implements observer_t. More...
 
void mutt_buffer_select_file (struct Buffer *file, SelectFileFlags flags, char ***files, int *numfiles)
 Let the user select a file. More...
 
void mutt_select_file (char *file, size_t filelen, SelectFileFlags flags, char ***files, int *numfiles)
 Let the user select a file. More...
 

Variables

bool C_BrowserAbbreviateMailboxes
 Config: Abbreviate mailboxes using '~' and '=' in the browser. More...
 
char * C_FolderFormat
 Config: printf-like format string for the browser's display of folders. More...
 
char * C_GroupIndexFormat
 Config: (nntp) printf-like format string for the browser's display of newsgroups. More...
 
char * C_NewsgroupsCharset
 Config: (nntp) Character set of newsgroups' descriptions. More...
 
bool C_ShowOnlyUnread
 Config: (nntp) Only show subscribed newsgroups with unread articles. More...
 
short C_SortBrowser
 Config: Sort method for the browser. More...
 
char * C_VfolderFormat
 Config: (notmuch) printf-like format string for the browser's display of virtual folders. More...
 
static const struct Mapping FolderHelp []
 
static struct Mapping FolderNewsHelp []
 
static struct Buffer LastDir = { 0 }
 
static struct Buffer LastDirBackup = { 0 }
 

Detailed Description

GUI component for displaying/selecting items from a list.

Authors
  • Michael R. Elkins

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

Function Documentation

◆ init_lastdir()

static void init_lastdir ( void  )
static

Initialise the browser directories.

These keep track of where the browser used to be looking.

Definition at line 108 of file browser.c.

109 {
110  static bool done = false;
111  if (!done)
112  {
115  done = true;
116  }
117 }
static struct Buffer LastDirBackup
Definition: browser.c:101
#define PATH_MAX
Definition: mutt.h:44
static struct Buffer LastDir
Definition: browser.c:100
void mutt_buffer_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:265
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_browser_cleanup()

void mutt_browser_cleanup ( void  )

Clean up working Buffers.

Definition at line 122 of file browser.c.

123 {
126 }
static struct Buffer LastDirBackup
Definition: browser.c:101
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
static struct Buffer LastDir
Definition: browser.c:100
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ destroy_state()

static void destroy_state ( struct BrowserState state)
static

Free the BrowserState.

Parameters
stateState to free

Frees up the memory allocated for the local-global variables.

Definition at line 134 of file browser.c.

135 {
136  for (size_t c = 0; c < state->entrylen; c++)
137  {
138  FREE(&((state->entry)[c].name));
139  FREE(&((state->entry)[c].desc));
140  }
141 #ifdef USE_IMAP
142  FREE(&state->folder);
143 #endif
144  FREE(&state->entry);
145 }
char * folder
Definition: browser.h:102
size_t entrylen
number of real entries
Definition: browser.h:98
#define FREE(x)
Definition: memory.h:40
struct FolderFile * entry
Definition: browser.h:97
+ Here is the caller graph for this function:

◆ browser_compare_subject()

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

Compare the subject of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 155 of file browser.c.

156 {
157  const struct FolderFile *pa = (const struct FolderFile *) a;
158  const struct FolderFile *pb = (const struct FolderFile *) b;
159 
160  /* inbox should be sorted ahead of its siblings */
161  int r = mutt_inbox_cmp(pa->name, pb->name);
162  if (r == 0)
163  r = mutt_str_strcoll(pa->name, pb->name);
164  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
165 }
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
char * name
Definition: browser.h:70
Browser entry representing a folder/dir.
Definition: browser.h:61
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
#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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_desc()

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

Compare the descriptions of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 175 of file browser.c.

176 {
177  const struct FolderFile *pa = (const struct FolderFile *) a;
178  const struct FolderFile *pb = (const struct FolderFile *) b;
179 
180  int r = mutt_str_strcoll(pa->desc, pb->desc);
181 
182  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
183 }
char * desc
Definition: browser.h:71
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
Browser entry representing a folder/dir.
Definition: browser.h:61
#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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_compare_date()

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

Compare the date of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 193 of file browser.c.

194 {
195  const struct FolderFile *pa = (const struct FolderFile *) a;
196  const struct FolderFile *pb = (const struct FolderFile *) b;
197 
198  int r = pa->mtime - pb->mtime;
199 
200  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
201 }
time_t mtime
Definition: browser.h:65
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
Browser entry representing a folder/dir.
Definition: browser.h:61
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the caller graph for this function:

◆ browser_compare_size()

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

Compare the size of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 211 of file browser.c.

212 {
213  const struct FolderFile *pa = (const struct FolderFile *) a;
214  const struct FolderFile *pb = (const struct FolderFile *) b;
215 
216  int r = pa->size - pb->size;
217 
218  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
219 }
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
off_t size
Definition: browser.h:64
Browser entry representing a folder/dir.
Definition: browser.h:61
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the caller graph for this function:

◆ browser_compare_count()

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

Compare the message count of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 229 of file browser.c.

230 {
231  const struct FolderFile *pa = (const struct FolderFile *) a;
232  const struct FolderFile *pb = (const struct FolderFile *) b;
233 
234  int r = 0;
235  if (pa->has_mailbox && pb->has_mailbox)
236  r = pa->msg_count - pb->msg_count;
237  else if (pa->has_mailbox)
238  r = -1;
239  else
240  r = 1;
241 
242  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
243 }
bool has_mailbox
Definition: browser.h:84
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
Browser entry representing a folder/dir.
Definition: browser.h:61
int msg_count
total number of messages
Definition: browser.h:74
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the caller graph for this function:

◆ browser_compare_count_new()

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

Compare the new count of two browser entries.

Parameters
aFirst browser entry
bSecond browser entry
Return values
-1a precedes b
0a and b are identical
1b precedes a

Definition at line 253 of file browser.c.

254 {
255  const struct FolderFile *pa = (const struct FolderFile *) a;
256  const struct FolderFile *pb = (const struct FolderFile *) b;
257 
258  int r = 0;
259  if (pa->has_mailbox && pb->has_mailbox)
260  r = pa->msg_unread - pb->msg_unread;
261  else if (pa->has_mailbox)
262  r = -1;
263  else
264  r = 1;
265 
266  return (C_SortBrowser & SORT_REVERSE) ? -r : r;
267 }
int msg_unread
number of unread messages
Definition: browser.h:75
bool has_mailbox
Definition: browser.h:84
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
Browser entry representing a folder/dir.
Definition: browser.h:61
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
+ Here is the caller graph for this function:

◆ browser_compare()

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

Sort the items in the browser.

Parameters
aFirst item
bSecond item
Return values
-1a precedes b
0a and b are identical
1b precedes a

Wild compare function that calls the others. It's useful because it provides a way to tell "../" is always on the top of the list, independently of the sort method.

Definition at line 281 of file browser.c.

282 {
283  const struct FolderFile *pa = (const struct FolderFile *) a;
284  const struct FolderFile *pb = (const struct FolderFile *) b;
285 
286  if ((mutt_str_strcoll(pa->desc, "../") == 0) || (mutt_str_strcoll(pa->desc, "..") == 0))
287  return -1;
288  if ((mutt_str_strcoll(pb->desc, "../") == 0) || (mutt_str_strcoll(pb->desc, "..") == 0))
289  return 1;
290 
291  switch (C_SortBrowser & SORT_MASK)
292  {
293  case SORT_COUNT:
294  return browser_compare_count(a, b);
295  case SORT_DATE:
296  return browser_compare_date(a, b);
297  case SORT_DESC:
298  return browser_compare_desc(a, b);
299  case SORT_SIZE:
300  return browser_compare_size(a, b);
301  case SORT_UNREAD:
302  return browser_compare_count_new(a, b);
303  case SORT_SUBJECT:
304  default:
305  return browser_compare_subject(a, b);
306  }
307 }
static int browser_compare_date(const void *a, const void *b)
Compare the date of two browser entries.
Definition: browser.c:193
char * desc
Definition: browser.h:71
static int browser_compare_desc(const void *a, const void *b)
Compare the descriptions of two browser entries.
Definition: browser.c:175
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
static int browser_compare_count(const void *a, const void *b)
Compare the message count of two browser entries.
Definition: browser.c:229
Sort by the size of the email.
Definition: sort2.h:51
Browser entry representing a folder/dir.
Definition: browser.h:61
static int browser_compare_count_new(const void *a, const void *b)
Compare the new count of two browser entries.
Definition: browser.c:253
static int browser_compare_size(const void *a, const void *b)
Compare the size of two browser entries.
Definition: browser.c:211
static int browser_compare_subject(const void *a, const void *b)
Compare the subject of two browser entries.
Definition: browser.c:155
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
Sort by the date the email was sent.
Definition: sort2.h:50
int mutt_str_strcoll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:702
Sort by the email&#39;s subject.
Definition: sort2.h:53
#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:

◆ browser_sort()

static void browser_sort ( struct BrowserState state)
static

Sort the entries in the browser.

Parameters
stateBrowser state

Call to qsort using browser_compare function. Some specific sort methods are not used via NNTP.

Definition at line 316 of file browser.c.

317 {
318  switch (C_SortBrowser & SORT_MASK)
319  {
320  /* Also called "I don't care"-sort-method. */
321  case SORT_ORDER:
322  return;
323 #ifdef USE_NNTP
324  case SORT_SIZE:
325  case SORT_DATE:
326  if (OptNews)
327  return;
328 #endif
329  default:
330  break;
331  }
332 
333  qsort(state->entry, state->entrylen, sizeof(struct FolderFile), browser_compare);
334 }
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
Sort by the size of the email.
Definition: sort2.h:51
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
Browser entry representing a folder/dir.
Definition: browser.h:61
size_t entrylen
number of real entries
Definition: browser.h:98
static int browser_compare(const void *a, const void *b)
Sort the items in the browser.
Definition: browser.c:281
Sort by the date the email was sent.
Definition: sort2.h:50
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
struct FolderFile * entry
Definition: browser.h:97
#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:

◆ link_is_dir()

static bool link_is_dir ( const char *  folder,
const char *  path 
)
static

Does this symlink point to a directory?

Parameters
folderFolder
pathLink name
Return values
trueLinks to a directory
falseOtherwise

Definition at line 343 of file browser.c.

344 {
345  struct stat st;
346  bool retval = false;
347 
348  struct Buffer *fullpath = mutt_buffer_pool_get();
349  mutt_buffer_concat_path(fullpath, folder, path);
350 
351  if (stat(mutt_b2s(fullpath), &st) == 0)
352  retval = S_ISDIR(st.st_mode);
353 
354  mutt_buffer_pool_release(&fullpath);
355 
356  return retval;
357 }
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
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
#define mutt_b2s(buf)
Definition: buffer.h:41
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ folder_format_str()

static const char* folder_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 folder browser - Implements format_t.

Expando Description
%C Current file number
%d Date/time folder was last modified
%D Date/time folder was last modified using $date_format.
%F File permissions
%f Filename (with suffix /, @ or *)
%g Group name (or numeric gid, if missing)
%i Description of the folder
%l Number of hard links
%m Number of messages in the mailbox
%N N if mailbox has new mail, blank otherwise
%n Number of unread messages in the mailbox
%s Size in bytes
%t * if the file is tagged, blank otherwise
%u Owner name (or numeric uid, if missing)

Definition at line 379 of file browser.c.

383 {
384  char fn[128], fmt[128];
385  struct Folder *folder = (struct Folder *) data;
386  bool optional = (flags & MUTT_FORMAT_OPTIONAL);
387 
388  switch (op)
389  {
390  case 'C':
391  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
392  snprintf(buf, buflen, fmt, folder->num + 1);
393  break;
394 
395  case 'd':
396  case 'D':
397  if (folder->ff->local)
398  {
399  bool do_locales = true;
400 
401  char *t_fmt = NULL;
402  if (op == 'D')
403  {
404  t_fmt = NONULL(C_DateFormat);
405  if (*t_fmt == '!')
406  {
407  t_fmt++;
408  do_locales = false;
409  }
410  }
411  else
412  {
413  static const time_t one_year = 31536000;
414  t_fmt = ((mutt_date_epoch() - folder->ff->mtime) < one_year) ?
415  "%b %d %H:%M" :
416  "%b %d %Y";
417  }
418 
419  if (!do_locales)
420  setlocale(LC_TIME, "C");
421  char date[128];
422  mutt_date_localtime_format(date, sizeof(date), t_fmt, folder->ff->mtime);
423  if (!do_locales)
424  setlocale(LC_TIME, "");
425 
426  mutt_format_s(buf, buflen, prec, date);
427  }
428  else
429  mutt_format_s(buf, buflen, prec, "");
430  break;
431 
432  case 'f':
433  {
434  char *s = NULL;
435 
436  s = NONULL(folder->ff->name);
437 
438  snprintf(fn, sizeof(fn), "%s%s", s,
439  folder->ff->local ?
440  (S_ISLNK(folder->ff->mode) ?
441  "@" :
442  (S_ISDIR(folder->ff->mode) ?
443  "/" :
444  (((folder->ff->mode & S_IXUSR) != 0) ? "*" : ""))) :
445  "");
446 
447  mutt_format_s(buf, buflen, prec, fn);
448  break;
449  }
450  case 'F':
451  {
452  if (folder->ff->local)
453  {
454  char permission[11];
455  snprintf(permission, sizeof(permission), "%c%c%c%c%c%c%c%c%c%c",
456  S_ISDIR(folder->ff->mode) ? 'd' : (S_ISLNK(folder->ff->mode) ? 'l' : '-'),
457  ((folder->ff->mode & S_IRUSR) != 0) ? 'r' : '-',
458  ((folder->ff->mode & S_IWUSR) != 0) ? 'w' : '-',
459  ((folder->ff->mode & S_ISUID) != 0) ?
460  's' :
461  ((folder->ff->mode & S_IXUSR) != 0) ? 'x' : '-',
462  ((folder->ff->mode & S_IRGRP) != 0) ? 'r' : '-',
463  ((folder->ff->mode & S_IWGRP) != 0) ? 'w' : '-',
464  ((folder->ff->mode & S_ISGID) != 0) ?
465  's' :
466  ((folder->ff->mode & S_IXGRP) != 0) ? 'x' : '-',
467  ((folder->ff->mode & S_IROTH) != 0) ? 'r' : '-',
468  ((folder->ff->mode & S_IWOTH) != 0) ? 'w' : '-',
469  ((folder->ff->mode & S_ISVTX) != 0) ?
470  't' :
471  ((folder->ff->mode & S_IXOTH) != 0) ? 'x' : '-');
472  mutt_format_s(buf, buflen, prec, permission);
473  }
474 #ifdef USE_IMAP
475  else if (folder->ff->imap)
476  {
477  char permission[11];
478  /* mark folders with subfolders AND mail */
479  snprintf(permission, sizeof(permission), "IMAP %c",
480  (folder->ff->inferiors && folder->ff->selectable) ? '+' : ' ');
481  mutt_format_s(buf, buflen, prec, permission);
482  }
483 #endif
484  else
485  mutt_format_s(buf, buflen, prec, "");
486  break;
487  }
488 
489  case 'g':
490  if (folder->ff->local)
491  {
492  struct group *gr = getgrgid(folder->ff->gid);
493  if (gr)
494  mutt_format_s(buf, buflen, prec, gr->gr_name);
495  else
496  {
497  snprintf(fmt, sizeof(fmt), "%%%sld", prec);
498  snprintf(buf, buflen, fmt, folder->ff->gid);
499  }
500  }
501  else
502  mutt_format_s(buf, buflen, prec, "");
503  break;
504 
505  case 'i':
506  {
507  char *s = NULL;
508  if (folder->ff->desc)
509  s = folder->ff->desc;
510  else
511  s = folder->ff->name;
512 
513  snprintf(fn, sizeof(fn), "%s%s", s,
514  folder->ff->local ?
515  (S_ISLNK(folder->ff->mode) ?
516  "@" :
517  (S_ISDIR(folder->ff->mode) ?
518  "/" :
519  (((folder->ff->mode & S_IXUSR) != 0) ? "*" : ""))) :
520  "");
521 
522  mutt_format_s(buf, buflen, prec, fn);
523  break;
524  }
525 
526  case 'l':
527  if (folder->ff->local)
528  {
529  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
530  snprintf(buf, buflen, fmt, folder->ff->nlink);
531  }
532  else
533  mutt_format_s(buf, buflen, prec, "");
534  break;
535 
536  case 'm':
537  if (!optional)
538  {
539  if (folder->ff->has_mailbox)
540  {
541  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
542  snprintf(buf, buflen, fmt, folder->ff->msg_count);
543  }
544  else
545  mutt_format_s(buf, buflen, prec, "");
546  }
547  else if (folder->ff->msg_count == 0)
548  optional = false;
549  break;
550 
551  case 'N':
552  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
553  snprintf(buf, buflen, fmt, folder->ff->has_new_mail ? 'N' : ' ');
554  break;
555 
556  case 'n':
557  if (!optional)
558  {
559  if (folder->ff->has_mailbox)
560  {
561  snprintf(fmt, sizeof(fmt), "%%%sd", prec);
562  snprintf(buf, buflen, fmt, folder->ff->msg_unread);
563  }
564  else
565  mutt_format_s(buf, buflen, prec, "");
566  }
567  else if (folder->ff->msg_unread == 0)
568  optional = false;
569  break;
570 
571  case 's':
572  if (folder->ff->local)
573  {
574  mutt_str_pretty_size(fn, sizeof(fn), folder->ff->size);
575  snprintf(fmt, sizeof(fmt), "%%%ss", prec);
576  snprintf(buf, buflen, fmt, fn);
577  }
578  else
579  mutt_format_s(buf, buflen, prec, "");
580  break;
581 
582  case 't':
583  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
584  snprintf(buf, buflen, fmt, folder->ff->tagged ? '*' : ' ');
585  break;
586 
587  case 'u':
588  if (folder->ff->local)
589  {
590  struct passwd *pw = getpwuid(folder->ff->uid);
591  if (pw)
592  mutt_format_s(buf, buflen, prec, pw->pw_name);
593  else
594  {
595  snprintf(fmt, sizeof(fmt), "%%%sld", prec);
596  snprintf(buf, buflen, fmt, folder->ff->uid);
597  }
598  }
599  else
600  mutt_format_s(buf, buflen, prec, "");
601  break;
602 
603  default:
604  snprintf(fmt, sizeof(fmt), "%%%sc", prec);
605  snprintf(buf, buflen, fmt, op);
606  break;
607  }
608 
609  if (optional)
610  {
611  mutt_expando_format(buf, buflen, col, cols, if_str, folder_format_str, data,
613  }
614  else if (flags & MUTT_FORMAT_OPTIONAL)
615  {
616  mutt_expando_format(buf, buflen, col, cols, else_str, folder_format_str,
617  data, MUTT_FORMAT_NO_FLAGS);
618  }
619 
620  return src;
621 }
int msg_unread
number of unread messages
Definition: browser.h:75
mode_t mode
Definition: browser.h:63
time_t mutt_date_epoch(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:411
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
time_t mtime
Definition: browser.h:65
#define NONULL(x)
Definition: string2.h:37
bool has_mailbox
Definition: browser.h:84
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:774
char * desc
Definition: browser.h:71
static int const char * fmt
Definition: acutest.h:473
gid_t gid
Definition: browser.h:67
#define MUTT_FORMAT_NO_FLAGS
No flags are set.
Definition: format_flags.h:30
struct FolderFile * ff
Definition: browser.h:54
off_t size
Definition: browser.h:64
bool selectable
Definition: browser.h:81
uid_t uid
Definition: browser.h:66
nlink_t nlink
Definition: browser.h:68
char * name
Definition: browser.h:70
int num
Definition: browser.h:55
bool imap
Definition: browser.h:80
A folder/dir in the browser.
Definition: browser.h:52
void mutt_str_pretty_size(char *buf, size_t buflen, size_t num)
Display an abbreviated size, like 3.4K.
Definition: muttlib.c:1751
static const char * folder_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 folder browser - Implements format_t.
Definition: browser.c:379
int msg_count
total number of messages
Definition: browser.h:74
void mutt_format_s(char *buf, size_t buflen, const char *prec, const char *s)
Format a simple string.
Definition: curs_lib.c:1222
WHERE char * C_DateFormat
Config: strftime format string for the d expando.
Definition: globals.h:108
#define MUTT_FORMAT_OPTIONAL
Allow optional field processing.
Definition: format_flags.h:33
bool tagged
Definition: browser.h:86
bool local
folder is on local filesystem
Definition: browser.h:85
bool inferiors
Definition: browser.h:82
bool has_new_mail
true if mailbox has "new mail"
Definition: browser.h:73
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_folder()

static void add_folder ( struct Menu menu,
struct BrowserState state,
const char *  name,
const char *  desc,
const struct stat *  s,
struct Mailbox m,
void *  data 
)
static

Add a folder to the browser list.

Parameters
menuMenu to use
stateBrowser state
nameName of folder
descDescription of folder
sstat info for the folder
mMailbox
dataData to associate with the folder

Definition at line 633 of file browser.c.

636 {
637  if (m && (m->flags & MB_HIDDEN))
638  {
639  return;
640  }
641 
642  if (state->entrylen == state->entrymax)
643  {
644  /* need to allocate more space */
645  mutt_mem_realloc(&state->entry, sizeof(struct FolderFile) * (state->entrymax += 256));
646  memset(&state->entry[state->entrylen], 0, sizeof(struct FolderFile) * 256);
647  if (menu)
648  menu->data = state->entry;
649  }
650 
651  if (s)
652  {
653  (state->entry)[state->entrylen].mode = s->st_mode;
654  (state->entry)[state->entrylen].mtime = s->st_mtime;
655  (state->entry)[state->entrylen].size = s->st_size;
656  (state->entry)[state->entrylen].gid = s->st_gid;
657  (state->entry)[state->entrylen].uid = s->st_uid;
658  (state->entry)[state->entrylen].nlink = s->st_nlink;
659 
660  (state->entry)[state->entrylen].local = true;
661  }
662  else
663  (state->entry)[state->entrylen].local = false;
664 
665  if (m)
666  {
667  (state->entry)[state->entrylen].has_mailbox = true;
668  (state->entry)[state->entrylen].has_new_mail = m->has_new;
669  (state->entry)[state->entrylen].msg_count = m->msg_count;
670  (state->entry)[state->entrylen].msg_unread = m->msg_unread;
671  }
672 
673  (state->entry)[state->entrylen].name = mutt_str_strdup(name);
674  (state->entry)[state->entrylen].desc = mutt_str_strdup(desc ? desc : name);
675 #ifdef USE_IMAP
676  (state->entry)[state->entrylen].imap = false;
677 #endif
678 #ifdef USE_NNTP
679  if (OptNews)
680  (state->entry)[state->entrylen].nd = data;
681 #endif
682  (state->entrylen)++;
683 }
mode_t mode
Definition: browser.h:63
int msg_count
Total number of messages.
Definition: mailbox.h:91
if(!test_colorize_)
Definition: acutest.h:484
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
bool has_new
Mailbox has new mail.
Definition: mailbox.h:88
const char * name
Definition: pgpmicalg.c:46
unsigned int entrymax
max entry
Definition: browser.h:99
int flags
e.g. MB_NORMAL
Definition: mailbox.h:134
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Browser entry representing a folder/dir.
Definition: browser.h:61
#define MB_HIDDEN
Definition: mailbox.h:38
size_t entrylen
number of real entries
Definition: browser.h:98
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
struct FolderFile * entry
Definition: browser.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_state()

static void init_state ( struct BrowserState state,
struct Menu menu 
)
static

Initialise a browser state.

Parameters
stateBrowserState to initialise
menuCurrent menu

Definition at line 690 of file browser.c.

691 {
692  state->entrylen = 0;
693  state->entrymax = 256;
694  state->entry = mutt_mem_calloc(state->entrymax, sizeof(struct FolderFile));
695 #ifdef USE_IMAP
696  state->imap_browse = false;
697 #endif
698  if (menu)
699  menu->data = state->entry;
700 }
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
unsigned int entrymax
max entry
Definition: browser.h:99
Browser entry representing a folder/dir.
Definition: browser.h:61
size_t entrylen
number of real entries
Definition: browser.h:98
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
bool imap_browse
Definition: browser.h:101
struct FolderFile * entry
Definition: browser.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ examine_directory()

static int examine_directory ( struct Menu menu,
struct BrowserState state,
const char *  d,
const char *  prefix 
)
static

Get list of all files/newsgroups with mask.

Parameters
menuCurrent Menu
stateState of browser
dDirectory
prefixFiles/newsgroups must match this prefix
Return values
0Success
-1Error

Definition at line 711 of file browser.c.

713 {
714  int rc = -1;
715  struct Buffer *buf = mutt_buffer_pool_get();
716 #ifdef USE_NNTP
717  if (OptNews)
718  {
720 
721  init_state(state, menu);
722 
723  for (unsigned int i = 0; i < adata->groups_num; i++)
724  {
725  struct NntpMboxData *mdata = adata->groups_list[i];
726  if (!mdata)
727  continue;
728  if (prefix && *prefix && !mutt_str_startswith(mdata->group, prefix, CASE_MATCH))
729  continue;
730  if (!mutt_regex_match(C_Mask, mdata->group))
731  {
732  continue;
733  }
734  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
735  }
736  }
737  else
738 #endif /* USE_NNTP */
739  {
740  struct stat s;
741  DIR *dp = NULL;
742  struct dirent *de = NULL;
743 
744  while (stat(d, &s) == -1)
745  {
746  if (errno == ENOENT)
747  {
748  /* The last used directory is deleted, try to use the parent dir. */
749  char *c = strrchr(d, '/');
750 
751  if (c && (c > d))
752  {
753  *c = '\0';
754  continue;
755  }
756  }
757  mutt_perror(d);
758  goto ed_out;
759  }
760 
761  if (!S_ISDIR(s.st_mode))
762  {
763  mutt_error(_("%s is not a directory"), d);
764  goto ed_out;
765  }
766 
767  if (Context && Context->mailbox)
769 
770  dp = opendir(d);
771  if (!dp)
772  {
773  mutt_perror(d);
774  goto ed_out;
775  }
776 
777  init_state(state, menu);
778 
779  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
780  while ((de = readdir(dp)))
781  {
782  if (mutt_str_strcmp(de->d_name, ".") == 0)
783  continue; /* we don't need . */
784 
785  if (prefix && *prefix && !mutt_str_startswith(de->d_name, prefix, CASE_MATCH))
786  {
787  continue;
788  }
789  if (!mutt_regex_match(C_Mask, de->d_name))
790  {
791  continue;
792  }
793 
794  mutt_buffer_concat_path(buf, d, de->d_name);
795  if (lstat(mutt_b2s(buf), &s) == -1)
796  continue;
797 
798  /* No size for directories or symlinks */
799  if (S_ISDIR(s.st_mode) || S_ISLNK(s.st_mode))
800  s.st_size = 0;
801  else if (!S_ISREG(s.st_mode))
802  continue;
803 
804  struct MailboxNode *np = NULL;
805  STAILQ_FOREACH(np, &ml, entries)
806  {
807  if (mutt_str_strcmp(mutt_b2s(buf), mailbox_path(np->mailbox)) == 0)
808  break;
809  }
810 
811  if (np && Context && Context->mailbox &&
813  {
816  }
817  add_folder(menu, state, de->d_name, NULL, &s, np ? np->mailbox : NULL, NULL);
818  }
820  closedir(dp);
821  }
822  browser_sort(state);
823  rc = 0;
824 ed_out:
826  return rc;
827 }
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
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
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
Match any Mailbox type.
Definition: mailbox.h:45
static void add_folder(struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
Add a folder to the browser list.
Definition: browser.c:633
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
Match case when comparing strings.
Definition: string2.h:67
Container for Accounts, Notifications.
Definition: neomutt.h:35
NNTP-specific Account data -.
Definition: lib.h:77
struct Mailbox * mailbox
Definition: context.h:51
char * group
Definition: lib.h:142
void * mdata
Driver specific data.
Definition: mailbox.h:136
#define mutt_b2s(buf)
Definition: buffer.h:41
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:152
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: lib.h:100
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:316
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
NNTP-specific Mailbox data -.
Definition: lib.h:140
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:157
#define mutt_error(...)
Definition: logging.h:84
WHERE struct Regex * C_Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:174
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:610
void ** groups_list
Definition: lib.h:102
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
List of Mailboxes.
Definition: mailbox.h:145
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:690
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
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:

◆ examine_mailboxes()

static int examine_mailboxes ( struct Menu menu,
struct BrowserState state 
)
static

Get list of mailboxes/subscribed newsgroups.

Parameters
menuCurrent menu
stateState of browser
Return values
0Success
-1Error

Definition at line 836 of file browser.c.

837 {
838  struct stat s;
839  struct Buffer *md = NULL;
840  struct Buffer *mailbox = NULL;
841 
842 #ifdef USE_NNTP
843  if (OptNews)
844  {
846 
847  init_state(state, menu);
848 
849  for (unsigned int i = 0; i < adata->groups_num; i++)
850  {
851  struct NntpMboxData *mdata = adata->groups_list[i];
852  if (mdata && (mdata->has_new_mail ||
853  (mdata->subscribed && (mdata->unread || !C_ShowOnlyUnread))))
854  {
855  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
856  }
857  }
858  }
859  else
860 #endif
861  {
862  init_state(state, menu);
863 
865  return -1;
866  mailbox = mutt_buffer_pool_get();
867  md = mutt_buffer_pool_get();
869 
870  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
871  struct MailboxNode *np = NULL;
872  STAILQ_FOREACH(np, &ml, entries)
873  {
874  if (!np->mailbox)
875  continue;
876 
877  if (Context && Context->mailbox &&
879  {
882  }
883 
884  mutt_buffer_strcpy(mailbox, mailbox_path(np->mailbox));
887 
888  switch (np->mailbox->type)
889  {
890  case MUTT_IMAP:
891  case MUTT_POP:
892  add_folder(menu, state, mutt_b2s(mailbox), np->mailbox->name, NULL,
893  np->mailbox, NULL);
894  continue;
895  case MUTT_NOTMUCH:
896  case MUTT_NNTP:
897  add_folder(menu, state, mailbox_path(np->mailbox), np->mailbox->name,
898  NULL, np->mailbox, NULL);
899  continue;
900  default: /* Continue */
901  break;
902  }
903 
904  if (lstat(mailbox_path(np->mailbox), &s) == -1)
905  continue;
906 
907  if ((!S_ISREG(s.st_mode)) && (!S_ISDIR(s.st_mode)) && (!S_ISLNK(s.st_mode)))
908  continue;
909 
910  if (np->mailbox->type == MUTT_MAILDIR)
911  {
912  struct stat st2;
913 
914  mutt_buffer_printf(md, "%s/new", mailbox_path(np->mailbox));
915  if (stat(mutt_b2s(md), &s) < 0)
916  s.st_mtime = 0;
917  mutt_buffer_printf(md, "%s/cur", mailbox_path(np->mailbox));
918  if (stat(mutt_b2s(md), &st2) < 0)
919  st2.st_mtime = 0;
920  if (st2.st_mtime > s.st_mtime)
921  s.st_mtime = st2.st_mtime;
922  }
923 
924  add_folder(menu, state, mutt_b2s(mailbox), np->mailbox->name, &s, np->mailbox, NULL);
925  }
927  }
928  browser_sort(state);
929 
930  mutt_buffer_pool_release(&mailbox);
932  return 0;
933 }
bool has_new_mail
Definition: lib.h:150
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
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
int msg_unread
Number of unread messages.
Definition: mailbox.h:92
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:52
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:39
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:135
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
Match any Mailbox type.
Definition: mailbox.h:45
static void add_folder(struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
Add a folder to the browser list.
Definition: browser.c:633
String manipulation buffer.
Definition: buffer.h:33
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Container for Accounts, Notifications.
Definition: neomutt.h:35
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:689
NNTP-specific Account data -.
Definition: lib.h:77
bool subscribed
Definition: lib.h:149
char * name
A short name for the Mailbox.
Definition: mailbox.h:85
struct Mailbox * mailbox
Definition: context.h:51
char * group
Definition: lib.h:142
void * mdata
Driver specific data.
Definition: mailbox.h:136
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
#define mutt_b2s(buf)
Definition: buffer.h:41
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:55
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:152
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: lib.h:100
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:316
bool C_ShowOnlyUnread
Config: (nntp) Only show subscribed newsgroups with unread articles.
Definition: browser.c:74
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
NNTP-specific Mailbox data -.
Definition: lib.h:140
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
&#39;Notmuch&#39; (virtual) Mailbox type
Definition: mailbox.h:54
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:157
anum_t unread
Definition: lib.h:148
bool C_BrowserAbbreviateMailboxes
Config: Abbreviate mailboxes using &#39;~&#39; and &#39;=&#39; in the browser.
Definition: browser.c:70
void ** groups_list
Definition: lib.h:102
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
List of Mailboxes.
Definition: mailbox.h:145
#define TAILQ_EMPTY(head)
Definition: queue.h:714
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:690
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
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:

◆ select_file_search()

static int select_file_search ( struct Menu menu,
regex_t *  rx,
int  line 
)
static

Menu search callback for matching files - Implements Menu::search()

Definition at line 938 of file browser.c.

939 {
940 #ifdef USE_NNTP
941  if (OptNews)
942  return regexec(rx, ((struct FolderFile *) menu->data)[line].desc, 0, NULL, 0);
943 #endif
944  struct FolderFile current_ff = ((struct FolderFile *) menu->data)[line];
945  char *search_on = current_ff.desc ? current_ff.desc : current_ff.name;
946 
947  return regexec(rx, search_on, 0, NULL, 0);
948 }
char * desc
Definition: browser.h:71
char * name
Definition: browser.h:70
Browser entry representing a folder/dir.
Definition: browser.h:61
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
int const char int line
Definition: acutest.h:602
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
+ Here is the caller graph for this function:

◆ folder_make_entry()

static void folder_make_entry ( char *  buf,
size_t  buflen,
struct Menu menu,
int  line 
)
static

Format a menu item for the folder browser - Implements Menu::make_entry()

Definition at line 953 of file browser.c.

954 {
955  struct Folder folder;
956 
957  folder.ff = &((struct FolderFile *) menu->data)[line];
958  folder.num = line;
959 
960 #ifdef USE_NNTP
961  if (OptNews)
962  {
963  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
965  (unsigned long) &folder, MUTT_FORMAT_ARROWCURSOR);
966  }
967  else
968 #endif
969  {
970  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
972  (unsigned long) &folder, MUTT_FORMAT_ARROWCURSOR);
973  }
974 }
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 MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: format_flags.h:35
char * C_FolderFormat
Config: printf-like format string for the browser&#39;s display of folders.
Definition: browser.c:71
struct FolderFile * ff
Definition: browser.h:54
short cols
Number of columns, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:58
A folder/dir in the browser.
Definition: browser.h:52
Browser entry representing a folder/dir.
Definition: browser.h:61
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
static const char * folder_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 folder browser - Implements format_t.
Definition: browser.c:379
const char * group_index_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 newsgroup menu - Implements format_t.
Definition: browse.c:51
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
int const char int line
Definition: acutest.h:602
struct MuttWindow * win_index
Definition: mutt_menu.h:95
char * C_GroupIndexFormat
Config: (nntp) printf-like format string for the browser&#39;s display of newsgroups. ...
Definition: browser.c:72
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ browser_highlight_default()

static void browser_highlight_default ( struct BrowserState state,
struct Menu menu 
)
static

Decide which browser item should be highlighted.

Parameters
stateBrowser state
menuCurrent Menu

This function takes a menu and a state and defines the current entry that should be highlighted.

Definition at line 984 of file browser.c.

985 {
986  menu->top = 0;
987  /* Reset menu position to 1.
988  * We do not risk overflow as the init_menu function changes
989  * current if it is bigger than state->entrylen. */
990  if ((mutt_str_strcmp(state->entry[0].desc, "..") == 0) ||
991  (mutt_str_strcmp(state->entry[0].desc, "../") == 0))
992  {
993  /* Skip the first entry, unless there's only one entry. */
994  menu->current = (menu->max > 1);
995  }
996  else
997  {
998  menu->current = 0;
999  }
1000 }
char * desc
Definition: browser.h:71
int top
Entry that is the top of the current page.
Definition: mutt_menu.h:108
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
int current
Current entry.
Definition: mutt_menu.h:87
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
struct FolderFile * entry
Definition: browser.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ init_menu()

static void init_menu ( struct BrowserState state,
struct Menu menu,
char *  title,
size_t  titlelen,
bool  mailbox 
)
static

Set up a new menu.

Parameters
stateBrowser state
menuCurrent menu
titleBuffer for the title
titlelenLength of buffer
mailboxIf true, select mailboxes

Definition at line 1010 of file browser.c.

1012 {
1013  menu->max = state->entrylen;
1014 
1015  if (menu->current >= menu->max)
1016  menu->current = menu->max - 1;
1017  if (menu->current < 0)
1018  menu->current = 0;
1019  if (menu->top > menu->current)
1020  menu->top = 0;
1021 
1022  menu->tagged = 0;
1023 
1024 #ifdef USE_NNTP
1025  if (OptNews)
1026  {
1027  if (mailbox)
1028  snprintf(title, titlelen, _("Subscribed newsgroups"));
1029  else
1030  {
1031  snprintf(title, titlelen, _("Newsgroups on server [%s]"),
1033  }
1034  }
1035  else
1036 #endif
1037  {
1038  if (mailbox)
1039  {
1040  menu->is_mailbox_list = true;
1041  snprintf(title, titlelen, _("Mailboxes [%d]"),
1042  mutt_mailbox_check(Context ? Context->mailbox : NULL, 0));
1043  }
1044  else
1045  {
1046  struct Buffer *path = mutt_buffer_pool_get();
1047  menu->is_mailbox_list = false;
1048  mutt_buffer_copy(path, &LastDir);
1050 #ifdef USE_IMAP
1051  if (state->imap_browse && C_ImapListSubscribed)
1052  {
1053  snprintf(title, titlelen, _("Subscribed [%s], File mask: %s"),
1054  mutt_b2s(path), NONULL(C_Mask ? C_Mask->pattern : NULL));
1055  }
1056  else
1057 #endif
1058  {
1059  snprintf(title, titlelen, _("Directory [%s], File mask: %s"),
1060  mutt_b2s(path), NONULL(C_Mask ? C_Mask->pattern : NULL));
1061  }
1062  mutt_buffer_pool_release(&path);
1063  }
1064  }
1065 
1066  /* Browser tracking feature.
1067  * The goal is to highlight the good directory if LastDir is the parent dir
1068  * of LastDirBackup (this occurs mostly when one hit "../"). It should also work
1069  * properly when the user is in examine_mailboxes-mode. */
1071  {
1072  char target_dir[PATH_MAX] = { 0 };
1073 
1074 #ifdef USE_IMAP
1075  /* Check what kind of dir LastDirBackup is. */
1077  {
1078  mutt_str_strfcpy(target_dir, mutt_b2s(&LastDirBackup), sizeof(target_dir));
1079  imap_clean_path(target_dir, sizeof(target_dir));
1080  }
1081  else
1082 #endif
1083  mutt_str_strfcpy(target_dir, strrchr(mutt_b2s(&LastDirBackup), '/') + 1,
1084  sizeof(target_dir));
1085 
1086  /* If we get here, it means that LastDir is the parent directory of
1087  * LastDirBackup. I.e., we're returning from a subdirectory, and we want
1088  * to position the cursor on the directory we're returning from. */
1089  bool matched = false;
1090  for (unsigned int i = 0; i < state->entrylen; i++)
1091  {
1092  if (mutt_str_strcmp(state->entry[i].name, target_dir) == 0)
1093  {
1094  menu->current = i;
1095  matched = true;
1096  break;
1097  }
1098  }
1099  if (!matched)
1100  browser_highlight_default(state, menu);
1101  }
1102  else
1103  browser_highlight_default(state, menu);
1104 
1105  menu->redraw = REDRAW_FULL;
1106 }
The "current" mailbox.
Definition: context.h:37
WHERE bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: globals.h:221
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2516
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:36
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
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
#define _(a)
Definition: message.h:28
Match case when comparing strings.
Definition: string2.h:67
void mutt_buffer_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using &#39;~&#39; or &#39;=&#39;.
Definition: muttlib.c:689
char host[128]
Server to login to.
Definition: connaccount.h:53
static struct Buffer LastDirBackup
Definition: browser.c:101
struct Mailbox * mailbox
Definition: context.h:51
char * name
Definition: browser.h:70
#define mutt_b2s(buf)
Definition: buffer.h:41
#define PATH_MAX
Definition: mutt.h:44
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:152
int top
Entry that is the top of the current page.
Definition: mutt_menu.h:108
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
bool is_mailbox_list
Definition: mutt_menu.h:94
int tagged
Number of tagged entries.
Definition: mutt_menu.h:111
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
size_t entrylen
number of real entries
Definition: browser.h:98
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
struct Connection * conn
Definition: lib.h:104
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:984
void imap_clean_path(char *path, size_t plen)
Cleans an IMAP path using imap_fix_path.
Definition: util.c:334
WHERE struct Regex * C_Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:174
static struct Buffer LastDir
Definition: browser.c:100
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
int current
Current entry.
Definition: mutt_menu.h:87
char * pattern
printable version
Definition: regex3.h:89
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
bool imap_browse
Definition: browser.h:101
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
struct FolderFile * entry
Definition: browser.h:97
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ file_tag()

static int file_tag ( struct Menu menu,
int  sel,
int  act 
)
static

Tag an entry in the menu - Implements Menu::tag()

Definition at line 1111 of file browser.c.

1112 {
1113  struct FolderFile *ff = &(((struct FolderFile *) menu->data)[sel]);
1114  if (S_ISDIR(ff->mode) || (S_ISLNK(ff->mode) && link_is_dir(mutt_b2s(&LastDir), ff->name)))
1115  {
1116  mutt_error(_("Can't attach a directory"));
1117  return 0;
1118  }
1119 
1120  bool ot = ff->tagged;
1121  ff->tagged = ((act >= 0) ? act : !ff->tagged);
1122 
1123  return ff->tagged - ot;
1124 }
mode_t mode
Definition: browser.h:63
static bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Definition: browser.c:343
#define _(a)
Definition: message.h:28
char * name
Definition: browser.h:70
#define mutt_b2s(buf)
Definition: buffer.h:41
Browser entry representing a folder/dir.
Definition: browser.h:61
#define mutt_error(...)
Definition: logging.h:84
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
static struct Buffer LastDir
Definition: browser.c:100
bool tagged
Definition: browser.h:86
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_browser_select_dir()

void mutt_browser_select_dir ( const char *  f)

Remember the last directory selected.

Parameters
fDirectory name to save

This function helps the browser to know which directory has been selected. It should be called anywhere a confirm hit is done to open a new directory/file which is a maildir/mbox.

We could check if the sort method is appropriate with this feature.

Definition at line 1136 of file browser.c.

1137 {
1138  init_lastdir();
1139 
1141 
1142  /* Method that will fetch the parent path depending on the type of the path. */
1143  char buf[PATH_MAX];
1144  mutt_get_parent_path(mutt_b2s(&LastDirBackup), buf, sizeof(buf));
1145  mutt_buffer_strcpy(&LastDir, buf);
1146 }
static void init_lastdir(void)
Initialise the browser directories.
Definition: browser.c:108
static struct Buffer LastDirBackup
Definition: browser.c:101
#define mutt_b2s(buf)
Definition: buffer.h:41
#define PATH_MAX
Definition: mutt.h:44
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
static struct Buffer LastDir
Definition: browser.c:100
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:1628
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_dlg_browser_observer()

static int mutt_dlg_browser_observer ( struct NotifyCallback nc)
static

Listen for config changes affecting the Browser menu - Implements observer_t.

Definition at line 1151 of file browser.c.

1152 {
1153  if (!nc->event_data || !nc->global_data)
1154  return -1;
1155  if (nc->event_type != NT_CONFIG)
1156  return 0;
1157 
1158  struct EventConfig *ec = nc->event_data;
1159  struct MuttWindow *dlg = nc->global_data;
1160 
1161  if (mutt_str_strcmp(ec->name, "status_on_top") != 0)
1162  return 0;
1163 
1164  struct MuttWindow *win_first = TAILQ_FIRST(&dlg->children);
1165 
1166  if ((C_StatusOnTop && (win_first->type == WT_INDEX)) ||
1167  (!C_StatusOnTop && (win_first->type != WT_INDEX)))
1168  {
1169  // Swap the Index and the IndexBar Windows
1170  TAILQ_REMOVE(&dlg->children, win_first, entries);
1171  TAILQ_INSERT_TAIL(&dlg->children, win_first, entries);
1172  }
1173 
1174  mutt_window_reflow(dlg);
1175  return 0;
1176 }
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:252
#define TAILQ_FIRST(head)
Definition: queue.h:716
A config-change event.
Definition: subset.h:70
A division of the screen.
Definition: mutt_window.h:88
An Index Window containing a selection list.
Definition: mutt_window.h:74
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
#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
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:345
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:101
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:103
const char * name
Name of config item that changed.
Definition: subset.h:73
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:

◆ mutt_buffer_select_file()

void mutt_buffer_select_file ( struct Buffer file,
SelectFileFlags  flags,
char ***  files,
int *  numfiles 
)

Let the user select a file.

Parameters
[in]fileBuffer for the result
[in]flagsFlags, see SelectFileFlags
[out]filesArray of selected files
[out]numfilesNumber of selected files

Definition at line 1185 of file browser.c.

1187 {
1188  char helpstr[1024];
1189  char title[256];
1190  struct BrowserState state = { 0 };
1191  struct Menu *menu = NULL;
1192  bool kill_prefix = false;
1193  bool multiple = (flags & MUTT_SEL_MULTI);
1194  bool folder = (flags & MUTT_SEL_FOLDER);
1195  bool mailbox = (flags & MUTT_SEL_MAILBOX);
1196 
1197  /* Keeps in memory the directory we were in when hitting '='
1198  * to go directly to $folder (#C_Folder) */
1199  char goto_swapper[PATH_MAX] = { 0 };
1200 
1201  mailbox = mailbox && folder;
1202 
1203  struct Buffer *OldLastDir = mutt_buffer_pool_get();
1204  struct Buffer *tmp = mutt_buffer_pool_get();
1205  struct Buffer *buf = mutt_buffer_pool_get();
1206  struct Buffer *prefix = mutt_buffer_pool_get();
1207 
1208  init_lastdir();
1209 
1210 #ifdef USE_NNTP
1211  if (OptNews)
1212  {
1213  if (mutt_buffer_is_empty(file))
1214  {
1216 
1217  /* default state for news reader mode is browse subscribed newsgroups */
1218  mailbox = false;
1219  for (size_t i = 0; i < adata->groups_num; i++)
1220  {
1221  struct NntpMboxData *mdata = adata->groups_list[i];
1222  if (mdata && mdata->subscribed)
1223  {
1224  mailbox = true;
1225  break;
1226  }
1227  }
1228  }
1229  else
1230  {
1231  mutt_buffer_copy(prefix, file);
1232  }
1233  }
1234  else
1235 #endif
1236  if (!mutt_buffer_is_empty(file))
1237  {
1239 #ifdef USE_IMAP
1240  if (imap_path_probe(mutt_b2s(file), NULL) == MUTT_IMAP)
1241  {
1242  init_state(&state, NULL);
1243  state.imap_browse = true;
1244  if (imap_browse(mutt_b2s(file), &state) == 0)
1245  {
1247  browser_sort(&state);
1248  }
1249  }
1250  else
1251  {
1252 #endif
1253  int i;
1254  for (i = mutt_buffer_len(file) - 1; (i > 0) && ((mutt_b2s(file))[i] != '/'); i--)
1255  ;
1256  if (i > 0)
1257  {
1258  if ((mutt_b2s(file))[0] == '/')
1260  else
1261  {
1263  mutt_buffer_addch(&LastDir, '/');
1265  }
1266  }
1267  else
1268  {
1269  if ((mutt_b2s(file))[0] == '/')
1270  mutt_buffer_strcpy(&LastDir, "/");
1271  else
1273  }
1274 
1275  if ((i <= 0) && (mutt_b2s(file)[0] != '/'))
1276  mutt_buffer_copy(prefix, file);
1277  else
1278  mutt_buffer_strcpy(prefix, mutt_b2s(file) + i + 1);
1279  kill_prefix = true;
1280 #ifdef USE_IMAP
1281  }
1282 #endif
1283  }
1284  else
1285  {
1286  if (!folder)
1288  else
1289  {
1290  /* Whether we use the tracking feature of the browser depends
1291  * on which sort method we chose to use. This variable is defined
1292  * only to help readability of the code. */
1293  bool browser_track = false;
1294 
1295  switch (C_SortBrowser & SORT_MASK)
1296  {
1297  case SORT_DESC:
1298  case SORT_SUBJECT:
1299  case SORT_ORDER:
1300  browser_track = true;
1301  break;
1302  }
1303 
1304  /* We use mutt_browser_select_dir to initialize the two
1305  * variables (LastDir, LastDirBackup) at the appropriate
1306  * values.
1307  *
1308  * We do it only when LastDir is not set (first pass there)
1309  * or when CurrentFolder and LastDirBackup are not the same.
1310  * This code is executed only when we list files, not when
1311  * we press up/down keys to navigate in a displayed list.
1312  *
1313  * We only do this when CurrentFolder has been set (ie, not
1314  * when listing folders on startup with "neomutt -y").
1315  *
1316  * This tracker is only used when browser_track is true,
1317  * meaning only with sort methods SUBJECT/DESC for now. */
1318  if (CurrentFolder)
1319  {
1321  {
1322  /* If browsing in "local"-mode, than we chose to define LastDir to
1323  * MailDir */
1324  switch (mx_path_probe(CurrentFolder))
1325  {
1326  case MUTT_IMAP:
1327  case MUTT_MAILDIR:
1328  case MUTT_MBOX:
1329  case MUTT_MH:
1330  case MUTT_MMDF:
1331  if (C_Folder)
1333  else if (C_Spoolfile)
1335  break;
1336  default:
1338  break;
1339  }
1340  }
1342  {
1344  }
1345  }
1346 
1347  /* When browser tracking feature is disabled, clear LastDirBackup */
1348  if (!browser_track)
1350  }
1351 
1352 #ifdef USE_IMAP
1353  if (!mailbox && (imap_path_probe(mutt_b2s(&LastDir), NULL) == MUTT_IMAP))
1354  {
1355  init_state(&state, NULL);
1356  state.imap_browse = true;
1357  imap_browse(mutt_b2s(&LastDir), &state);
1358  browser_sort(&state);
1359  }
1360  else
1361 #endif
1362  {
1363  size_t i = mutt_buffer_len(&LastDir);
1364  while ((i > 0) && (mutt_b2s(&LastDir)[--i] == '/'))
1365  LastDir.data[i] = '\0';
1369  }
1370  }
1371 
1372  mutt_buffer_reset(file);
1373 
1374  if (mailbox)
1375  {
1376  examine_mailboxes(NULL, &state);
1377  }
1378  else
1379 #ifdef USE_IMAP
1380  if (!state.imap_browse)
1381 #endif
1382  {
1383  if (examine_directory(NULL, &state, mutt_b2s(&LastDir), mutt_b2s(prefix)) == -1)
1384  goto bail;
1385  }
1386 
1387  struct MuttWindow *dlg =
1390 #ifdef USE_DEBUG_WINDOW
1391  dlg->name = "browser";
1392 #endif
1393  dlg->type = WT_DIALOG;
1394  struct MuttWindow *index =
1397  index->type = WT_INDEX;
1398  struct MuttWindow *ibar = mutt_window_new(
1400  ibar->type = WT_INDEX_BAR;
1401 
1402  if (C_StatusOnTop)
1403  {
1404  mutt_window_add_child(dlg, ibar);
1405  mutt_window_add_child(dlg, index);
1406  }
1407  else
1408  {
1409  mutt_window_add_child(dlg, index);
1410  mutt_window_add_child(dlg, ibar);
1411  }
1412 
1414  dialog_push(dlg);
1415 
1416  menu = mutt_menu_new(MENU_FOLDER);
1417 
1418  menu->pagelen = index->state.rows;
1419  menu->win_index = index;
1420  menu->win_ibar = ibar;
1421 
1422  menu->make_entry = folder_make_entry;
1423  menu->search = select_file_search;
1424  menu->title = title;
1425  menu->data = state.entry;
1426  if (multiple)
1427  menu->tag = file_tag;
1428 
1429  menu->help = mutt_compile_help(helpstr, sizeof(helpstr), MENU_FOLDER,
1430 #ifdef USE_NNTP
1432 #endif
1433  FolderHelp);
1434  mutt_menu_push_current(menu);
1435 
1436  init_menu(&state, menu, title, sizeof(title), mailbox);
1437 
1438  int op;
1439  while (true)
1440  {
1441  switch (op = mutt_menu_loop(menu))
1442  {
1443  case OP_DESCEND_DIRECTORY:
1444  case OP_GENERIC_SELECT_ENTRY:
1445 
1446  if (state.entrylen == 0)
1447  {
1448  mutt_error(_("No files match the file mask"));
1449  break;
1450  }
1451 
1452  if (S_ISDIR(state.entry[menu->current].mode) ||
1453  (S_ISLNK(state.entry[menu->current].mode) &&
1454  link_is_dir(mutt_b2s(&LastDir), state.entry[menu->current].name))
1455 #ifdef USE_IMAP
1456  || state.entry[menu->current].inferiors
1457 #endif
1458  )
1459  {
1460  /* make sure this isn't a MH or maildir mailbox */
1461  if (mailbox)
1462  {
1463  mutt_buffer_strcpy(buf, state.entry[menu->current].name);
1465  }
1466 #ifdef USE_IMAP
1467  else if (state.imap_browse)
1468  {
1469  mutt_buffer_strcpy(buf, state.entry[menu->current].name);
1470  }
1471 #endif
1472  else
1473  {
1475  state.entry[menu->current].name);
1476  }
1477 
1478  enum MailboxType type = mx_path_probe(mutt_b2s(buf));
1479  if ((op == OP_DESCEND_DIRECTORY) || (type == MUTT_MAILBOX_ERROR) ||
1480  (type == MUTT_UNKNOWN)
1481 #ifdef USE_IMAP
1482  || state.entry[menu->current].inferiors
1483 #endif
1484  )
1485  {
1486  /* save the old directory */
1487  mutt_buffer_copy(OldLastDir, &LastDir);
1488 
1489  if (mutt_str_strcmp(state.entry[menu->current].name, "..") == 0)
1490  {
1491  size_t lastdirlen = mutt_buffer_len(&LastDir);
1492  if ((lastdirlen > 1) &&
1493  (mutt_str_strcmp("..", mutt_b2s(&LastDir) + lastdirlen - 2) == 0))
1494  {
1495  mutt_buffer_addstr(&LastDir, "/..");
1496  }
1497  else
1498  {
1499  char *p = NULL;
1500  if (lastdirlen > 1)
1501  p = strrchr(mutt_b2s(&LastDir) + 1, '/');
1502 
1503  if (p)
1504  {
1505  *p = '\0';
1507  }
1508  else
1509  {
1510  if (mutt_b2s(&LastDir)[0] == '/')
1511  mutt_buffer_strcpy(&LastDir, "/");
1512  else
1513  mutt_buffer_addstr(&LastDir, "/..");
1514  }
1515  }
1516  }
1517  else if (mailbox)
1518  {
1519  mutt_buffer_strcpy(&LastDir, state.entry[menu->current].name);
1521  }
1522 #ifdef USE_IMAP
1523  else if (state.imap_browse)
1524  {
1525  mutt_buffer_strcpy(&LastDir, state.entry[menu->current].name);
1526  /* tack on delimiter here */
1527 
1528  /* special case "" needs no delimiter */
1529  struct Url *url = url_parse(state.entry[menu->current].name);
1530  if (url->path && (state.entry[menu->current].delim != '\0'))
1531  {
1532  mutt_buffer_addch(&LastDir, state.entry[menu->current].delim);
1533  }
1534  url_free(&url);
1535  }
1536 #endif
1537  else
1538  {
1540  state.entry[menu->current].name);
1541  mutt_buffer_copy(&LastDir, tmp);
1542  }
1543 
1544  destroy_state(&state);
1545  if (kill_prefix)
1546  {
1547  mutt_buffer_reset(prefix);
1548  kill_prefix = false;
1549  }
1550  mailbox = false;
1551 #ifdef USE_IMAP
1552  if (state.imap_browse)
1553  {
1554  init_state(&state, NULL);
1555  state.imap_browse = true;
1556  imap_browse(mutt_b2s(&LastDir), &state);
1557  browser_sort(&state);
1558  menu->data = state.entry;
1559  }
1560  else
1561 #endif
1562  {
1563  if (examine_directory(menu, &state, mutt_b2s(&LastDir), mutt_b2s(prefix)) == -1)
1564  {
1565  /* try to restore the old values */
1566  mutt_buffer_copy(&LastDir, OldLastDir);
1567  if (examine_directory(menu, &state, mutt_b2s(&LastDir),
1568  mutt_b2s(prefix)) == -1)
1569  {
1571  goto bail;
1572  }
1573  }
1574  /* resolve paths navigated from GUI */
1575  if (mutt_path_realpath(LastDir.data) == 0)
1576  break;
1577  }
1578 
1579  browser_highlight_default(&state, menu);
1580  init_menu(&state, menu, title, sizeof(title), mailbox);
1581  goto_swapper[0] = '\0';
1582  break;
1583  }
1584  }
1585  else if (op == OP_DESCEND_DIRECTORY)
1586  {
1587  mutt_error(_("%s is not a directory"), state.entry[menu->current].name);
1588  break;
1589  }
1590 
1591  if (mailbox || OptNews) /* USE_NNTP */
1592  {
1593  mutt_buffer_strcpy(file, state.entry[menu->current].name);
1595  }
1596 #ifdef USE_IMAP
1597  else if (state.imap_browse)
1598  mutt_buffer_strcpy(file, state.entry[menu->current].name);
1599 #endif
1600  else
1601  {
1603  state.entry[menu->current].name);
1604  }
1605  /* fallthrough */
1606 
1607  case OP_EXIT:
1608 
1609  if (multiple)
1610  {
1611  char **tfiles = NULL;
1612 
1613  if (menu->tagged)
1614  {
1615  *numfiles = menu->tagged;
1616  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
1617  for (int i = 0, j = 0; i < state.entrylen; i++)
1618  {
1619  struct FolderFile ff = state.entry[i];
1620  if (ff.tagged)
1621  {
1624  tfiles[j++] = mutt_buffer_strdup(tmp);
1625  }
1626  }
1627  *files = tfiles;
1628  }
1629  else if (!mutt_buffer_is_empty(file)) /* no tagged entries. return selected entry */
1630  {
1631  *numfiles = 1;
1632  tfiles = mutt_mem_calloc(*numfiles, sizeof(char *));
1634  tfiles[0] = mutt_buffer_strdup(file);
1635  *files = tfiles;
1636  }
1637  }
1638 
1639  destroy_state(&state);
1640  goto bail;
1641 
1642  case OP_BROWSER_TELL:
1643  if (state.entrylen)
1644  mutt_message("%s", state.entry[menu->current].name);
1645  break;
1646 
1647 #ifdef USE_IMAP
1648  case OP_BROWSER_TOGGLE_LSUB:
1649  bool_str_toggle(NeoMutt->sub, "imap_list_subscribed", NULL);
1650 
1651  mutt_unget_event(0, OP_CHECK_NEW);
1652  break;
1653 
1654  case OP_CREATE_MAILBOX:
1655  if (!state.imap_browse)
1656  {
1657  mutt_error(_("Create is only supported for IMAP mailboxes"));
1658  break;
1659  }
1660 
1661  if (imap_mailbox_create(mutt_b2s(&LastDir)) == 0)
1662  {
1663  /* TODO: find a way to detect if the new folder would appear in
1664  * this window, and insert it without starting over. */
1665  destroy_state(&state);
1666  init_state(&state, NULL);
1667  state.imap_browse = true;
1668  imap_browse(mutt_b2s(&LastDir), &state);
1669  browser_sort(&state);
1670  menu->data = state.entry;
1671  browser_highlight_default(&state, menu);
1672  init_menu(&state, menu, title, sizeof(title), mailbox);
1673  }
1674  /* else leave error on screen */
1675  break;
1676 
1677  case OP_RENAME_MAILBOX:
1678  if (!state.entry[menu->current].imap)
1679  mutt_error(_("Rename is only supported for IMAP mailboxes"));
1680  else
1681  {
1682  int nentry = menu->current;
1683 
1684  if (imap_mailbox_rename(state.entry[nentry].name) >= 0)
1685  {
1686  destroy_state(&state);
1687  init_state(&state, NULL);
1688  state.imap_browse = true;
1689  imap_browse(mutt_b2s(&LastDir), &state);
1690  browser_sort(&state);
1691  menu->data = state.entry;
1692  browser_highlight_default(&state, menu);
1693  init_menu(&state, menu, title, sizeof(title), mailbox);
1694  }
1695  }
1696  break;
1697 
1698  case OP_DELETE_MAILBOX:
1699  if (!state.entry[menu->current].imap)
1700  mutt_error(_("Delete is only supported for IMAP mailboxes"));
1701  else
1702  {
1703  char msg[128];
1704  int nentry = menu->current;
1705 
1706  // TODO(sileht): It could be better to select INBOX instead. But I
1707  // don't want to manipulate Context/Mailboxes/mailbox->account here for now.
1708  // Let's just protect neomutt against crash for now. #1417
1710  state.entry[nentry].name) == 0)
1711  {
1712  mutt_error(_("Can't delete currently selected mailbox"));
1713  break;
1714  }
1715 
1716  snprintf(msg, sizeof(msg), _("Really delete mailbox \"%s\"?"),
1717  state.entry[nentry].name);
1718  if (mutt_yesorno(msg, MUTT_NO) == MUTT_YES)
1719  {
1720  if (imap_delete_mailbox(Context->mailbox, state.entry[nentry].name) == 0)
1721  {
1722  /* free the mailbox from the browser */
1723  FREE(&((state.entry)[nentry].name));
1724  FREE(&((state.entry)[nentry].desc));
1725  /* and move all other entries up */
1726  if ((nentry + 1) < state.entrylen)
1727  {
1728  memmove(state.entry + nentry, state.entry + nentry + 1,
1729  sizeof(struct FolderFile) * (state.entrylen - (nentry + 1)));
1730  }
1731  memset(&state.entry[state.entrylen - 1], 0, sizeof(struct FolderFile));
1732  state.entrylen--;
1733  mutt_message(_("Mailbox deleted"));
1734  init_menu(&state, menu, title, sizeof(title), mailbox);
1735  }
1736  else
1737  mutt_error(_("Mailbox deletion failed"));
1738  }
1739  else
1740  mutt_message(_("Mailbox not deleted"));
1741  }
1742  break;
1743 #endif
1744 
1745  case OP_GOTO_PARENT:
1746  case OP_CHANGE_DIRECTORY:
1747 
1748 #ifdef USE_NNTP
1749  if (OptNews)
1750  break;
1751 #endif
1752 
1753  mutt_buffer_copy(buf, &LastDir);
1754 #ifdef USE_IMAP
1755  if (!state.imap_browse)
1756 #endif
1757  {
1758  /* add '/' at the end of the directory name if not already there */
1759  size_t len = mutt_buffer_len(buf);
1760  if ((len > 0) && (mutt_b2s(&LastDir)[len - 1] != '/'))
1761  mutt_buffer_addch(buf, '/');
1762  }
1763 
1764  if (op == OP_CHANGE_DIRECTORY)
1765  {
1766  /* buf comes from the buffer pool, so defaults to size 1024 */
1767  int ret = mutt_buffer_get_field(_("Chdir to: "), buf, MUTT_FILE);
1768  if ((ret != 0) && mutt_buffer_is_empty(buf))
1769  break;
1770  }
1771  else if (op == OP_GOTO_PARENT)
1772  mutt_get_parent_path(mutt_b2s(buf), buf->data, buf->dsize);
1773 
1774  if (!mutt_buffer_is_empty(buf))
1775  {
1776  mailbox = false;
1778 #ifdef USE_IMAP
1779  if (imap_path_probe(mutt_b2s(buf), NULL) == MUTT_IMAP)
1780  {
1781  mutt_buffer_copy(&LastDir, buf);
1782  destroy_state(&state);
1783  init_state(&state, NULL);
1784  state.imap_browse = true;
1785  imap_browse(mutt_b2s(&LastDir), &state);
1786  browser_sort(&state);
1787  menu->data = state.entry;
1788  browser_highlight_default(&state, menu);
1789  init_menu(&state, menu, title, sizeof(title), mailbox);
1790  }
1791  else
1792 #endif
1793  {
1794  if (mutt_b2s(buf)[0] != '/')
1795  {
1796  /* in case dir is relative, make it relative to LastDir,
1797  * not current working dir */
1799  mutt_buffer_copy(buf, tmp);
1800  }
1801  /* Resolve path from <chdir>
1802  * Avoids buildup such as /a/b/../../c
1803  * Symlinks are always unraveled to keep code simple */
1804  if (mutt_path_realpath(buf->data) == 0)
1805  break;
1806 
1807  struct stat st;
1808  if (stat(mutt_b2s(buf), &st) == 0)
1809  {
1810  if (S_ISDIR(st.st_mode))
1811  {
1812  destroy_state(&state);
1813  if (examine_directory(menu, &state, mutt_b2s(buf), mutt_b2s(prefix)) == 0)
1814  mutt_buffer_copy(&LastDir, buf);
1815  else
1816  {
1817  mutt_error(_("Error scanning directory"));
1818  if (examine_directory(menu, &state, mutt_b2s(&LastDir),
1819  mutt_b2s(prefix)) == -1)
1820  {
1821  goto bail;
1822  }
1823  }
1824  browser_highlight_default(&state, menu);
1825  init_menu(&state, menu, title, sizeof(title), mailbox);
1826  }
1827  else
1828  mutt_error(_("%s is not a directory"), mutt_b2s(buf));
1829  }
1830  else
1831  mutt_perror(mutt_b2s(buf));
1832  }
1833  }
1834  break;
1835 
1836  case OP_ENTER_MASK:
1837  {
1838  mutt_buffer_strcpy(buf, C_Mask ? C_Mask->pattern : NULL);
1839  if (mutt_get_field(_("File Mask: "), buf->data, buf->dsize, MUTT_COMP_NO_FLAGS) != 0)
1840  break;
1841 
1842  mutt_buffer_fix_dptr(buf);
1843 
1844  mailbox = false;
1845  /* assume that the user wants to see everything */
1846  if (mutt_buffer_is_empty(buf))
1847  mutt_buffer_strcpy(buf, ".");
1848 
1849  struct Buffer errmsg = mutt_buffer_make(256);
1850  int rc = cs_subset_str_string_set(NeoMutt->sub, "mask", mutt_b2s(buf), &errmsg);
1851  if (CSR_RESULT(rc) != CSR_SUCCESS)
1852  {
1853  if (!mutt_buffer_is_empty(&errmsg))
1854  {
1855  mutt_error("%s", mutt_b2s(&errmsg));
1856  mutt_buffer_dealloc(&errmsg);
1857  }
1858  break;
1859  }
1860 
1861  destroy_state(&state);
1862 #ifdef USE_IMAP
1863  if (state.imap_browse)
1864  {
1865  init_state(&state, NULL);
1866  state.imap_browse = true;
1867  imap_browse(mutt_b2s(&LastDir), &state);
1868  browser_sort(&state);
1869  menu->data = state.entry;
1870  init_menu(&state, menu, title, sizeof(title), mailbox);
1871  }
1872  else
1873 #endif
1874  if (examine_directory(menu, &state, mutt_b2s(&LastDir), NULL) == 0)
1875  init_menu(&state, menu, title, sizeof(title), mailbox);
1876  else
1877  {
1878  mutt_error(_("Error scanning directory"));
1879  goto bail;
1880  }
1881  kill_prefix = false;
1882  if (state.entrylen == 0)
1883  {
1884  mutt_error(_("No files match the file mask"));
1885  break;
1886  }
1887  break;
1888  }
1889 
1890  case OP_SORT:
1891  case OP_SORT_REVERSE:
1892 
1893  {
1894  bool resort = true;
1895  int sort = -1;
1896  int reverse = (op == OP_SORT_REVERSE);
1897 
1898  switch (mutt_multi_choice(
1899  (reverse) ?
1900  /* L10N: The highlighted letters must match the "Sort" options */
1901  _("Reverse sort by (d)ate, (a)lpha, si(z)e, d(e)scription, "
1902  "(c)ount, ne(w) count, or do(n)'t sort?") :
1903  /* L10N: The highlighted letters must match the "Reverse Sort" options */
1904  _("Sort by (d)ate, (a)lpha, si(z)e, d(e)scription, (c)ount, "
1905  "ne(w) count, or do(n)'t sort?"),
1906  /* L10N: These must match the highlighted letters from "Sort" and "Reverse Sort" */
1907  _("dazecwn")))
1908  {
1909  case -1: /* abort */
1910  resort = false;
1911  break;
1912 
1913  case 1: /* (d)ate */
1914  sort = SORT_DATE;
1915  break;
1916 
1917  case 2: /* (a)lpha */
1918  sort = SORT_SUBJECT;
1919  break;
1920 
1921  case 3: /* si(z)e */
1922  sort = SORT_SIZE;
1923  break;
1924 
1925  case 4: /* d(e)scription */
1926  sort = SORT_DESC;
1927  break;
1928 
1929  case 5: /* (c)ount */
1930  sort = SORT_COUNT;
1931  break;
1932 
1933  case 6: /* ne(w) count */
1934  sort = SORT_UNREAD;
1935  break;
1936 
1937  case 7: /* do(n)'t sort */
1938  sort = SORT_ORDER;
1939  resort = false;
1940  break;
1941  }
1942  if (resort)
1943  {
1944  sort |= reverse ? SORT_REVERSE : 0;
1945  cs_subset_str_native_set(NeoMutt->sub, "sort_browser", sort, NULL);
1946  browser_sort(&state);
1947  browser_highlight_default(&state, menu);
1948  menu->redraw = REDRAW_FULL;
1949  }
1950  else
1951  {
1952  cs_subset_str_native_set(NeoMutt->sub, "sort_browser", sort, NULL);
1953  }
1954  break;
1955  }
1956 
1957  case OP_TOGGLE_MAILBOXES:
1958  case OP_BROWSER_GOTO_FOLDER:
1959  case OP_CHECK_NEW:
1960  if (op == OP_TOGGLE_MAILBOXES)
1961  mailbox = !mailbox;
1962 
1963  if (op == OP_BROWSER_GOTO_FOLDER)
1964  {
1965  /* When in mailboxes mode, disables this feature */
1966  if (C_Folder)
1967  {
1968  mutt_debug(LL_DEBUG3, "= hit! Folder: %s, LastDir: %s\n", C_Folder,
1969  mutt_b2s(&LastDir));
1970  if (goto_swapper[0] == '\0')
1971  {
1973  {
1974  /* Stores into goto_swapper LastDir, and swaps to C_Folder */
1975  mutt_str_strfcpy(goto_swapper, mutt_b2s(&LastDir), sizeof(goto_swapper));
1978  }
1979  }
1980  else
1981  {
1983  mutt_buffer_strcpy(&LastDir, goto_swapper);
1984  goto_swapper[0] = '\0';
1985  }
1986  }
1987  }
1988  destroy_state(&state);
1989  mutt_buffer_reset(prefix);
1990  kill_prefix = false;
1991 
1992  if (mailbox)
1993  {
1994  examine_mailboxes(menu, &state);
1995  }
1996 #ifdef USE_IMAP
1997  else if (imap_path_probe(mutt_b2s(&LastDir), NULL) == MUTT_IMAP)
1998  {
1999  init_state(&state, NULL);
2000  state.imap_browse = true;
2001  imap_browse(mutt_b2s(&LastDir), &state);
2002  browser_sort(&state);
2003  menu->data = state.entry;
2004  }
2005 #endif
2006  else if (examine_directory(menu, &state, mutt_b2s(&LastDir), mutt_b2s(prefix)) == -1)
2007  goto bail;
2008  init_menu(&state, menu, title, sizeof(title), mailbox);
2009  break;
2010 
2011  case OP_MAILBOX_LIST:
2013  break;
2014 
2015  case OP_BROWSER_NEW_FILE:
2016  mutt_buffer_printf(buf, "%s/", mutt_b2s(&LastDir));
2017  /* buf comes from the buffer pool, so defaults to size 1024 */
2018  if (mutt_buffer_get_field(_("New file name: "), buf, MUTT_FILE) == 0)
2019  {
2020  mutt_buffer_copy(file, buf);
2021  destroy_state(&state);
2022  goto bail;
2023  }
2024  break;
2025 
2026  case OP_BROWSER_VIEW_FILE:
2027  if (state.entrylen == 0)
2028  {
2029  mutt_error(_("No files match the file mask"));
2030  break;
2031  }
2032 
2033 #ifdef USE_IMAP
2034  if (state.entry[menu->current].selectable)
2035  {
2036  mutt_buffer_strcpy(file, state.entry[menu->current].name);
2037  destroy_state(&state);
2038  goto bail;
2039  }
2040  else
2041 #endif
2042  if (S_ISDIR(state.entry[menu->current].mode) ||
2043  (S_ISLNK(state.entry[menu->current].mode) &&
2044  link_is_dir(mutt_b2s(&LastDir), state.entry[menu->current].name)))
2045  {
2046  mutt_error(_("Can't view a directory"));
2047  break;
2048  }
2049  else
2050  {
2051  char buf2[PATH_MAX];
2052 
2054  state.entry[menu->current].name, sizeof(buf2));
2055  struct Body *b = mutt_make_file_attach(buf2);
2056  if (b)
2057  {
2058  mutt_view_attachment(NULL, b, MUTT_VA_REGULAR, NULL, NULL, menu->win_index);
2059  mutt_body_free(&b);
2060  menu->redraw = REDRAW_FULL;
2061  }
2062  else
2063  mutt_error(_("Error trying to view file"));
2064  }
2065  break;
2066 
2067 #ifdef USE_NNTP
2068  case OP_CATCHUP:
2069  case OP_UNCATCHUP:
2070  {
2071  if (!OptNews)
2072  break;
2073 
2074  struct FolderFile *ff = &state.entry[menu->current];
2075  struct NntpMboxData *mdata = NULL;
2076 
2078  if (rc < 0)
2079  break;
2080 
2081  if (op == OP_CATCHUP)
2083  else
2085 
2086  if (mdata)
2087  {
2089  if ((menu->current + 1) < menu->max)
2090  menu->current++;
2091  menu->redraw = REDRAW_MOTION_RESYNC;
2092  }
2093  if (rc)
2094  menu->redraw = REDRAW_INDEX;
2096  break;
2097  }
2098 
2099  case OP_LOAD_ACTIVE:
2100  {
2101  if (!OptNews)
2102  break;
2103 
2104  struct NntpAccountData *adata = CurrentNewsSrv;
2105 
2106  if (nntp_newsrc_parse(adata) < 0)
2107  break;
2108 
2109  for (size_t i = 0; i < adata->groups_num; i++)
2110  {
2111  struct NntpMboxData *mdata = adata->groups_list[i];
2112  if (mdata)
2113  mdata->deleted = true;
2114  }
2115  nntp_active_fetch(adata, true);
2116  nntp_newsrc_update(adata);
2117  nntp_newsrc_close(adata);
2118 
2119  destroy_state(&state);
2120  if (mailbox)
2121  examine_mailboxes(menu, &state);
2122  else
2123  {
2124  if (examine_directory(menu, &state, NULL, NULL) == -1)
2125  break;
2126  }
2127  init_menu(&state, menu, title, sizeof(title), mailbox);
2128  break;
2129  }
2130 #endif /* USE_NNTP */
2131 
2132 #if defined(USE_IMAP) || defined(USE_NNTP)
2133  case OP_BROWSER_SUBSCRIBE:
2134  case OP_BROWSER_UNSUBSCRIBE:
2135 #endif
2136 #ifdef USE_NNTP
2137  case OP_SUBSCRIBE_PATTERN:
2138  case OP_UNSUBSCRIBE_PATTERN:
2139  if (OptNews)
2140  {
2141  struct NntpAccountData *adata = CurrentNewsSrv;
2142  regex_t rx;
2143  memset(&rx, 0, sizeof(rx));
2144  char *s = buf->data;
2145  int i = menu->current;
2146 
2147  if ((op == OP_SUBSCRIBE_PATTERN) || (op == OP_UNSUBSCRIBE_PATTERN))
2148  {
2149  char tmp2[256];
2150 
2151  mutt_buffer_reset(buf);
2152  if (op == OP_SUBSCRIBE_PATTERN)
2153  snprintf(tmp2, sizeof(tmp2), _("Subscribe pattern: "));
2154  else
2155  snprintf(tmp2, sizeof(tmp2), _("Unsubscribe pattern: "));
2156  /* buf comes from the buffer pool, so defaults to size 1024 */
2157  if ((mutt_buffer_get_field(tmp2, buf, MUTT_COMP_NO_FLAGS) != 0) ||
2158  mutt_buffer_is_empty(buf))
2159  {
2160  break;
2161  }
2162 
2163  int err = REG_COMP(&rx, s, REG_NOSUB);
2164  if (err != 0)
2165  {
2166  regerror(err, &rx, buf->data, buf->dsize);
2167  regfree(&rx);
2168  mutt_error("%s", mutt_b2s(buf));
2169  break;
2170  }
2171  menu->redraw = REDRAW_FULL;
2172  i = 0;
2173  }
2174  else if (state.entrylen == 0)
2175  {
2176  mutt_error(_("No newsgroups match the mask"));
2177  break;
2178  }
2179 
2180  int rc = nntp_newsrc_parse(adata);
2181  if (rc < 0)
2182  break;
2183 
2184  for (; i < state.entrylen; i++)
2185  {
2186  struct FolderFile *ff = &state.entry[i];
2187 
2188  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_BROWSER_UNSUBSCRIBE) ||
2189  (regexec(&rx, ff->name, 0, NULL, 0) == 0))
2190  {
2191  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_SUBSCRIBE_PATTERN))
2192  mutt_newsgroup_subscribe(adata, ff->name);
2193  else
2194  mutt_newsgroup_unsubscribe(adata, ff->name);
2195  }
2196  if ((op == OP_BROWSER_SUBSCRIBE) || (op == OP_BROWSER_UNSUBSCRIBE))
2197  {
2198  if ((menu->current + 1) < menu->max)
2199  menu->current++;
2200  menu->redraw = REDRAW_MOTION_RESYNC;
2201  break;
2202  }
2203  }
2204  if (op == OP_SUBSCRIBE_PATTERN)
2205  {
2206  for (size_t j = 0; adata && (j < adata->groups_num); j++)
2207  {
2208  struct NntpMboxData *mdata = adata->groups_list[j];
2209  if (mdata && mdata->group && !mdata->subscribed)
2210  {
2211  if (regexec(&rx, mdata->group, 0, NULL, 0) == 0)
2212  {
2213  mutt_newsgroup_subscribe(adata, mdata->group);
2214  add_folder(menu, &state, mdata->group, NULL, NULL, NULL, mdata);
2215  }
2216  }
2217  }
2218  init_menu(&state, menu, title, sizeof(title), mailbox);
2219  }
2220  if (rc > 0)
2221  menu->redraw = REDRAW_FULL;
2222  nntp_newsrc_update(adata);
2223  nntp_clear_cache(adata);
2224  nntp_newsrc_close(adata);
2225  if ((op != OP_BROWSER_SUBSCRIBE) && (op != OP_BROWSER_UNSUBSCRIBE))
2226  regfree(&rx);
2227  }
2228 #ifdef USE_IMAP
2229  else
2230 #endif /* USE_IMAP && USE_NNTP */
2231 #endif /* USE_NNTP */
2232 #ifdef USE_IMAP
2233  {
2234  char tmp2[256];
2235  mutt_str_strfcpy(tmp2, state.entry[menu->current].name, sizeof(tmp2));
2236  mutt_expand_path(tmp2, sizeof(tmp2));
2237  imap_subscribe(tmp2, (op == OP_BROWSER_SUBSCRIBE));
2238  }
2239 #endif /* USE_IMAP */
2240  }
2241  }
2242 
2243 bail:
2244  mutt_buffer_pool_release(&OldLastDir);
2247  mutt_buffer_pool_release(&prefix);
2248 
2249  if (menu)
2250  {
2251  mutt_menu_pop_current(menu);
2252  mutt_menu_free(&menu);
2253  dialog_pop();
2255  mutt_window_free(&dlg);
2256  }
2257 
2258  goto_swapper[0] = '\0';
2259 }
mode_t mode
Definition: browser.h:63
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
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:252
#define REDRAW_FULL
Redraw everything.
Definition: mutt_menu.h:47
bool mutt_mailbox_list(void)
List the mailboxes with new mail.
Definition: mutt_mailbox.c:230
#define NONULL(x)
Definition: string2.h:37
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
static bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Definition: browser.c:343
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:79
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
GUI selectable list of items.
Definition: mutt_menu.h:82
#define CSR_RESULT(x)
Definition: set.h:52
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe()
Definition: imap.c:2516
static void destroy_state(struct BrowserState *state)
Free the BrowserState.
Definition: browser.c:134
size_t mutt_buffer_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer&#39;s contents to another Buffer.
Definition: buffer.c:445
static int mutt_dlg_browser_observer(struct NotifyCallback *nc)
Listen for config changes affecting the Browser menu - Implements observer_t.
Definition: browser.c:1151
Dialog (nested Windows) displayed to the user.
Definition: mutt_window.h:70
#define mutt_message(...)
Definition: logging.h:83
int imap_delete_mailbox(struct Mailbox *m, char *path)
Delete a mailbox.
Definition: imap.c:646
A parsed URL proto://user:password@host:port/path?a=1&b=2
Definition: url.h:66
void nntp_clear_cache(struct NntpAccountData *adata)
Clear the NNTP cache.
Definition: newsrc.c:845
Window uses all available vertical space.
Definition: mutt_window.h:35
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
static int file_tag(struct Menu *menu, int sel, int act)
Tag an entry in the menu - Implements Menu::tag()
Definition: browser.c:1111
void dialog_pop(void)
Hide a Window from the user.
Definition: mutt_window.c:628
struct NntpMboxData * mutt_newsgroup_uncatchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Uncatchup newsgroup.
Definition: newsrc.c:1338
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
State of the file/mailbox browser.
Definition: browser.h:95
void dialog_push(struct MuttWindow *dlg)
Display a Window to the user.
Definition: mutt_window.c:605
General file/mailbox browser.
Definition: keymap.h:75
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:61
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
static void add_folder(struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *s, struct Mailbox *m, void *data)
Add a folder to the browser list.
Definition: browser.c:633
String manipulation buffer.
Definition: buffer.h:33
struct NntpMboxData * mutt_newsgroup_subscribe(struct NntpAccountData *adata, char *group)
Subscribe newsgroup.
Definition: newsrc.c:1249
void mutt_unget_event(int ch, int op)
Return a keystroke to the input buffer.
Definition: curs_lib.c:812
#define _(a)
Definition: message.h:28
Mailbox wasn&#39;t recognised.
Definition: mailbox.h:47
Error occurred examining Mailbox.
Definition: mailbox.h:46
int imap_mailbox_create(const char *path)
Create a new IMAP mailbox.
Definition: browse.c:382
const char * mutt_path_getcwd(struct Buffer *cwd)
Get the current working directory.
Definition: path.c:563
A division of the screen.
Definition: mutt_window.h:88
void nntp_newsrc_close(struct NntpAccountData *adata)
Unlock and close .newsrc file.
Definition: newsrc.c:123
short C_SortBrowser
Config: Sort method for the browser.
Definition: browser.c:75
static void init_lastdir(void)
Initialise the browser directories.
Definition: browser.c:108
void url_free(struct Url **ptr)
Free the contents of a URL.
Definition: url.c:121
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
static void folder_make_entry(char *buf, size_t buflen, struct Menu *menu, int line)
Format a menu item for the folder browser - Implements Menu::make_entry()
Definition: browser.c:953
View using default method.
Definition: mutt_attach.h:42
static int select_file_search(struct Menu *menu, regex_t *rx, int line)
Menu search callback for matching files - Implements Menu::search()
Definition: browser.c:938
int cs_subset_str_string_set(const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:395
Container for Accounts, Notifications.
Definition: neomutt.h:35
NNTP-specific Account data -.
Definition: lib.h:77
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:90
bool subscribed
Definition: lib.h:149
The body of an email.
Definition: body.h:34
An Index Window containing a selection list.
Definition: mutt_window.h:74
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: browser.h:47
char * HomeDir
User&#39;s home directory.
Definition: globals.h:49
char * folder
Definition: browser.h:102
bool selectable
Definition: browser.h:81
void mutt_window_free(struct MuttWindow **ptr)
Free a Window and its children.
Definition: mutt_window.c:74
int cs_subset_str_native_set(const struct ConfigSubset *sub, const char *name, intptr_t value, struct Buffer *err)
Natively set the value of a string config item.
Definition: subset.c:292
Sort by the size of the email.
Definition: sort2.h:51
size_t dsize
Length of data.
Definition: buffer.h:37
char * mutt_expand_path(char *buf, size_t buflen)
Create the canonical path.
Definition: muttlib.c:133
int nntp_active_fetch(struct NntpAccountData *adata, bool mark_new)
Fetch list of all newsgroups from server.
Definition: nntp.c:2058
enum QuadOption mutt_yesorno(const char *msg, enum QuadOption def)
Ask the user a Yes/No question.
Definition: curs_lib.c:378
static struct Buffer LastDirBackup
Definition: browser.c:101
struct Mailbox * mailbox
Definition: context.h:51
struct Body * mutt_make_file_attach(const char *path)
Create a file attachment.
Definition: sendlib.c:1645
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
struct MuttWindow * win_ibar
Definition: mutt_menu.h:96
const char * title
Title of this menu.
Definition: mutt_menu.h:84
Sort by the order the messages appear in the mailbox.
Definition: sort2.h:55
static int examine_mailboxes(struct Menu *menu, struct BrowserState *state)
Get list of mailboxes/subscribed newsgroups.
Definition: browser.c:836
char * name
Definition: browser.h:70
#define REG_COMP(preg, regex, cflags)
Compile a regular expression.
Definition: regex3.h:52
char * group
Definition: lib.h:142
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:294
size_t mutt_path_realpath(char *buf)
resolve path, unraveling symlinks
Definition: path.c:440
WHERE char * CurrentFolder
Currently selected mailbox.
Definition: globals.h:54
bool imap
Definition: browser.h:80
void * mdata
Driver specific data.
Definition: mailbox.h:136
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:51
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
void mutt_buffer_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:181
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:36
Window has a fixed size.
Definition: mutt_window.h:44
const char * help
Quickref for the current menu.
Definition: mutt_menu.h:85
#define REDRAW_MOTION_RESYNC
Redraw any changing the menu selection.
Definition: mutt_menu.h:44
#define mutt_b2s(buf)
Definition: buffer.h:41
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: curs_lib.c:911
Browser entry representing a folder/dir.
Definition: browser.h:61
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:93
struct MuttWindow * mutt_window_new(enum MuttWindowOrientation orient, enum MuttWindowSize size, int rows, int cols)
Create a new Window.
Definition: mutt_window.c:56
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
#define PATH_MAX
Definition: mutt.h:44
User answered &#39;No&#39;, or assume &#39;No&#39;.
Definition: quad.h:39
#define MUTT_WIN_SIZE_UNLIMITED
Use as much space as possible.
Definition: mutt_window.h:49
short rows
Number of rows, can be MUTT_WIN_SIZE_UNLIMITED.
Definition: mutt_window.h:57
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
size_t mutt_buffer_strcpy_n(struct Buffer *buf, const char *s, size_t len)
Copy a string into a Buffer.
Definition: buffer.c:327
size_t mutt_buffer_addstr_n(struct Buffer *buf, const char *s, size_t len)
Add a string to a Buffer, expanding it if necessary.
Definition: buffer.c:99
char * data
Pointer to data.
Definition: buffer.h:35
int bool_str_toggle(struct ConfigSubset *sub, const char *name, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:239
unsigned int groups_num
Definition: lib.h:100
static void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: browser.c:316
&#39;mmdf&#39; Mailbox type
Definition: mailbox.h:49
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
int nntp_newsrc_parse(struct NntpAccountData *adata)
Parse .newsrc file.
Definition: newsrc.c:167
&#39;MH&#39; Mailbox type
Definition: mailbox.h:50
struct NntpMboxData * mutt_newsgroup_unsubscribe(struct NntpAccountData *adata, char *group)
Unsubscribe newsgroup.
Definition: newsrc.c:1273
int(* tag)(struct Menu *menu, int sel, int act)
Tag some menu items.
Definition: mutt_menu.h:139
int pagelen
Number of entries per screen.
Definition: mutt_menu.h:92
struct Notify * notify
Notifications handler.
Definition: neomutt.h:37
size_t mutt_buffer_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:240
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: browser.h:46
NNTP-specific Mailbox data -.
Definition: lib.h:140
int tagged
Number of tagged entries.
Definition: mutt_menu.h:111
bool notify_observer_add(struct Notify *notify, observer_t callback, void *global_data)
Add an observer to an object.
Definition: notify.c:153
#define MUTT_FILE
Do file completion.
Definition: mutt.h:58
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
char * path
Path.
Definition: url.h:73
int max
Number of entries in the menu.
Definition: mutt_menu.h:88
void mutt_window_add_child(struct MuttWindow *parent, struct MuttWindow *child)
Add a child to Window.
Definition: mutt_window.c:473
&#39;mbox&#39; Mailbox type
Definition: mailbox.h:48
size_t entrylen
number of real entries
Definition: browser.h:98
#define mutt_buffer_get_field(field, buf, complete)
Definition: curs_lib.h:84
MuttRedrawFlags redraw
When to redraw the screen.
Definition: mutt_menu.h:89
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: browser.h:45
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:984
static int examine_directory(struct Menu *menu, struct BrowserState *state, const char *d, const char *prefix)
Get list of all files/newsgroups with mask.
Definition: browser.c:711
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1318
void mutt_buffer_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:328
MailboxType
Supported mailbox formats.
Definition: mailbox.h:43
bool deleted
Definition: lib.h:152
Sort by the number of unread emails.
Definition: sort2.h:66
WHERE char * C_Spoolfile
Config: Inbox.
Definition: globals.h:145
void mutt_browser_select_dir(const char *f)
Remember the last directory selected.
Definition: browser.c:1136
static void init_menu(struct BrowserState *state, struct Menu *menu, char *title, size_t titlelen, bool mailbox)
Set up a new menu.
Definition: browser.c:1010
#define REDRAW_INDEX
Redraw the index.
Definition: mutt_menu.h:42
#define mutt_error(...)
Definition: logging.h:84
WHERE struct Regex * C_Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:174
int imap_browse(const char *path, struct BrowserState *state)
IMAP hook into the folder browser.
Definition: browse.c:184
Sort by the folder&#39;s description.
Definition: sort2.h:70
void ** groups_list
Definition: lib.h:102
#define FREE(x)
Definition: memory.h:40
size_t mutt_buffer_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:374
int imap_mailbox_rename(const char *path)
Rename a mailbox.
Definition: browse.c:434
void * data
Extra data for the current menu.
Definition: mutt_menu.h:86
static struct Buffer LastDir
Definition: browser.c:100
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:84
bool notify_observer_remove(struct Notify *notify, observer_t callback, void *global_data)
Remove an observer from an object.
Definition: notify.c:185
Sort by number of emails in a folder.
Definition: sort2.h:65
char * mutt_path_concat(char *d, const char *dir, const char *fname, size_t l)
Join a directory name and a filename.
Definition: path.c:351
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
bool tagged
Definition: browser.h:86
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:38
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
int nntp_newsrc_update(struct NntpAccountData *adata)
Update .newsrc file.
Definition: newsrc.c:445
int current
Current entry.
Definition: mutt_menu.h:87
char * pattern
printable version
Definition: regex3.h:89
Sort by the date the email was sent.
Definition: sort2.h:50
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:690
struct NntpMboxData * mutt_newsgroup_catchup(struct Mailbox *m, struct NntpAccountData *adata, char *group)
Catchup newsgroup.
Definition: newsrc.c:1299
struct MuttWindow * win_index
Definition: mutt_menu.h:95
bool inferiors
Definition: browser.h:82
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
char * mutt_compile_help(char *buf, size_t buflen, enum MenuType menu, const struct Mapping *items)
Create the text for the help menu.
Definition: help.c:116
static const struct Mapping FolderHelp[]
Definition: browser.c:78
Window wants as much space as possible.
Definition: mutt_window.h:45
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:252
static struct Mapping FolderNewsHelp[]
Definition: browser.c:88
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:53
bool imap_browse
Definition: browser.h:101
Index Bar containing status info about the Index.
Definition: mutt_window.h:75
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:103
int(* search)(struct Menu *menu, regex_t *rx, int line)
Search a menu for a item matching a regex.
Definition: mutt_menu.h:130
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:1628
void(* make_entry)(char *buf, size_t buflen, struct Menu *menu, int line)
Format a item for a menu.
Definition: mutt_menu.h:120
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:46
char delim
Definition: browser.h:78
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:638
Sort by the email&#39;s subject.
Definition: sort2.h:53
struct FolderFile * entry
Definition: browser.h:97
Log at debug level 3.
Definition: logging.h:42
#define SORT_MASK
Mask for the sort id.
Definition: sort2.h:85
int imap_subscribe(char *path, bool subscribe)
Subscribe to a mailbox.
Definition: imap.c:1400
int mutt_view_attachment(FILE *fp, struct Body *a, enum ViewAttachMode mode, struct Email *e, struct AttachCtx *actx, struct MuttWindow *win)
View an attachment.
Definition: mutt_attach.c:415
struct Url * url_parse(const char *src)
Fill in Url.
Definition: url.c:232
+ Here is the caller graph for this function:

◆ mutt_select_file()

void mutt_select_file ( char *  file,
size_t  filelen,
SelectFileFlags  flags,
char ***  files,
int *  numfiles 
)

Let the user select a file.

Parameters
[in]fileBuffer for the result
[in]filelenLength of buffer
[in]flagsFlags, see SelectFileFlags
[out]filesArray of selected files
[out]numfilesNumber of selected files

Definition at line 2269 of file browser.c.

2271 {
2272  struct Buffer *f_buf = mutt_buffer_pool_get();
2273 
2274  mutt_buffer_strcpy(f_buf, NONULL(file));
2275  mutt_buffer_select_file(f_buf, flags, files, numfiles);
2276  mutt_str_strfcpy(file, mutt_b2s(f_buf), filelen);
2277 
2278  mutt_buffer_pool_release(&f_buf);
2279 }
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
void mutt_buffer_select_file(struct Buffer *file, SelectFileFlags flags, char ***files, int *numfiles)
Let the user select a file.
Definition: browser.c:1185
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
#define mutt_b2s(buf)
Definition: buffer.h:41
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
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
int const char * file
Definition: acutest.h:602
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ C_BrowserAbbreviateMailboxes

bool C_BrowserAbbreviateMailboxes

Config: Abbreviate mailboxes using '~' and '=' in the browser.

Definition at line 70 of file browser.c.

◆ C_FolderFormat

char* C_FolderFormat

Config: printf-like format string for the browser's display of folders.

Definition at line 71 of file browser.c.

◆ C_GroupIndexFormat

char* C_GroupIndexFormat

Config: (nntp) printf-like format string for the browser's display of newsgroups.

Definition at line 72 of file browser.c.

◆ C_NewsgroupsCharset

char* C_NewsgroupsCharset

Config: (nntp) Character set of newsgroups' descriptions.

Definition at line 73 of file browser.c.

◆ C_ShowOnlyUnread

bool C_ShowOnlyUnread

Config: (nntp) Only show subscribed newsgroups with unread articles.

Definition at line 74 of file browser.c.

◆ C_SortBrowser

short C_SortBrowser

Config: Sort method for the browser.

Definition at line 75 of file browser.c.

◆ C_VfolderFormat

char* C_VfolderFormat

Config: (notmuch) printf-like format string for the browser's display of virtual folders.

Definition at line 76 of file browser.c.

◆ FolderHelp

const struct Mapping FolderHelp[]
static
Initial value:
= {
{ N_("Exit"), OP_EXIT },
{ N_("Chdir"), OP_CHANGE_DIRECTORY },
{ N_("Goto"), OP_BROWSER_GOTO_FOLDER },
{ N_("Mask"), OP_ENTER_MASK },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Definition at line 78 of file browser.c.

◆ FolderNewsHelp

struct Mapping FolderNewsHelp[]
static
Initial value:
= {
{ N_("Exit"), OP_EXIT },
{ N_("List"), OP_TOGGLE_MAILBOXES },
{ N_("Subscribe"), OP_BROWSER_SUBSCRIBE },
{ N_("Unsubscribe"), OP_BROWSER_UNSUBSCRIBE },
{ N_("Catchup"), OP_CATCHUP },
{ N_("Mask"), OP_ENTER_MASK },
{ N_("Help"), OP_HELP },
{ NULL, 0 },
}
#define N_(a)
Definition: message.h:32

Definition at line 88 of file browser.c.

◆ LastDir

struct Buffer LastDir = { 0 }
static

Definition at line 100 of file browser.c.

◆ LastDirBackup

struct Buffer LastDirBackup = { 0 }
static

Definition at line 101 of file browser.c.