NeoMutt  2019-12-07-60-g0cfa53
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/mutt.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "conn/conn.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/imap.h"
#include "nntp/nntp.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::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::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::menu_tag() More...
 
void mutt_browser_select_dir (const char *f)
 Remember the last directory selected. More...
 
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:50
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:1710
#define SORT_REVERSE
Reverse the order of the sort.
Definition: sort2.h:86
int mutt_str_strcoll(const char *a, const char *b)
Collate two strings (compare using locale), safely.
Definition: string.c:679
+ 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:679
+ 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:679
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:43
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  mutt_expando_format(buf, buflen, col, cols, if_str, folder_format_str, data,
612  else if (flags & MUTT_FORMAT_OPTIONAL)
613  mutt_expando_format(buf, buflen, col, cols, else_str, folder_format_str,
614  data, MUTT_FORMAT_NO_FLAGS);
615 
616  return src;
617 }
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:877
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
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:1778
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:1244
WHERE char * C_DateFormat
Config: strftime format string for the d expando.
Definition: globals.h:106
#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 629 of file browser.c.

632 {
633  if (m && (m->flags & MB_HIDDEN))
634  {
635  return;
636  }
637 
638  if (state->entrylen == state->entrymax)
639  {
640  /* need to allocate more space */
641  mutt_mem_realloc(&state->entry, sizeof(struct FolderFile) * (state->entrymax += 256));
642  memset(&state->entry[state->entrylen], 0, sizeof(struct FolderFile) * 256);
643  if (menu)
644  menu->data = state->entry;
645  }
646 
647  if (s)
648  {
649  (state->entry)[state->entrylen].mode = s->st_mode;
650  (state->entry)[state->entrylen].mtime = s->st_mtime;
651  (state->entry)[state->entrylen].size = s->st_size;
652  (state->entry)[state->entrylen].gid = s->st_gid;
653  (state->entry)[state->entrylen].uid = s->st_uid;
654  (state->entry)[state->entrylen].nlink = s->st_nlink;
655 
656  (state->entry)[state->entrylen].local = true;
657  }
658  else
659  (state->entry)[state->entrylen].local = false;
660 
661  if (m)
662  {
663  (state->entry)[state->entrylen].has_mailbox = true;
664  (state->entry)[state->entrylen].has_new_mail = m->has_new;
665  (state->entry)[state->entrylen].msg_count = m->msg_count;
666  (state->entry)[state->entrylen].msg_unread = m->msg_unread;
667  }
668 
669  (state->entry)[state->entrylen].name = mutt_str_strdup(name);
670  (state->entry)[state->entrylen].desc = mutt_str_strdup(desc ? desc : name);
671 #ifdef USE_IMAP
672  (state->entry)[state->entrylen].imap = false;
673 #endif
674 #ifdef USE_NNTP
675  if (OptNews)
676  (state->entry)[state->entrylen].nd = data;
677 #endif
678  (state->entrylen)++;
679 }
mode_t mode
Definition: browser.h:63
int msg_count
Total number of messages.
Definition: mailbox.h:90
int msg_unread
Number of unread messages.
Definition: mailbox.h:91
bool has_new
Mailbox has new mail.
Definition: mailbox.h:87
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:133
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:37
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:43
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 686 of file browser.c.

687 {
688  state->entrylen = 0;
689  state->entrymax = 256;
690  state->entry = mutt_mem_calloc(state->entrymax, sizeof(struct FolderFile));
691 #ifdef USE_IMAP
692  state->imap_browse = false;
693 #endif
694  if (menu)
695  menu->data = state->entry;
696 }
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 707 of file browser.c.

709 {
710  int rc = -1;
711  struct Buffer *buf = mutt_buffer_pool_get();
712 #ifdef USE_NNTP
713  if (OptNews)
714  {
716 
717  init_state(state, menu);
718 
719  for (unsigned int i = 0; i < adata->groups_num; i++)
720  {
721  struct NntpMboxData *mdata = adata->groups_list[i];
722  if (!mdata)
723  continue;
724  if (prefix && *prefix && !mutt_str_startswith(mdata->group, prefix, CASE_MATCH))
725  continue;
726  if (!mutt_regex_match(C_Mask, mdata->group))
727  {
728  continue;
729  }
730  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
731  }
732  }
733  else
734 #endif /* USE_NNTP */
735  {
736  struct stat s;
737  DIR *dp = NULL;
738  struct dirent *de = NULL;
739 
740  while (stat(d, &s) == -1)
741  {
742  if (errno == ENOENT)
743  {
744  /* The last used directory is deleted, try to use the parent dir. */
745  char *c = strrchr(d, '/');
746 
747  if (c && (c > d))
748  {
749  *c = '\0';
750  continue;
751  }
752  }
753  mutt_perror(d);
754  goto ed_out;
755  }
756 
757  if (!S_ISDIR(s.st_mode))
758  {
759  mutt_error(_("%s is not a directory"), d);
760  goto ed_out;
761  }
762 
763  if (Context && Context->mailbox)
765 
766  dp = opendir(d);
767  if (!dp)
768  {
769  mutt_perror(d);
770  goto ed_out;
771  }
772 
773  init_state(state, menu);
774 
775  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
776  while ((de = readdir(dp)))
777  {
778  if (mutt_str_strcmp(de->d_name, ".") == 0)
779  continue; /* we don't need . */
780 
781  if (prefix && *prefix && !mutt_str_startswith(de->d_name, prefix, CASE_MATCH))
782  {
783  continue;
784  }
785  if (!mutt_regex_match(C_Mask, de->d_name))
786  {
787  continue;
788  }
789 
790  mutt_buffer_concat_path(buf, d, de->d_name);
791  if (lstat(mutt_b2s(buf), &s) == -1)
792  continue;
793 
794  /* No size for directories or symlinks */
795  if (S_ISDIR(s.st_mode) || S_ISLNK(s.st_mode))
796  s.st_size = 0;
797  else if (!S_ISREG(s.st_mode))
798  continue;
799 
800  struct MailboxNode *np = NULL;
801  STAILQ_FOREACH(np, &ml, entries)
802  {
803  if (mutt_str_strcmp(mutt_b2s(buf), mailbox_path(np->mailbox)) == 0)
804  break;
805  }
806 
807  if (np && Context && Context->mailbox &&
809  {
812  }
813  add_folder(menu, state, de->d_name, NULL, &s, np ? np->mailbox : NULL, NULL);
814  }
816  closedir(dp);
817  }
818  browser_sort(state);
819  rc = 0;
820 ed_out:
822  return rc;
823 }
The "current" mailbox.
Definition: context.h:36
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
int msg_count
Total number of messages.
Definition: mailbox.h:90
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:91
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:83
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:44
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:629
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: nntp.h:75
struct Mailbox * mailbox
Definition: context.h:50
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType magic)
Get a List of all Mailboxes.
Definition: neomutt.c:157
char * group
Definition: nntp.h:140
void * mdata
Driver specific data.
Definition: mailbox.h:135
#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:125
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: nntp.h:98
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: nntp.h:138
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
#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:173
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition: regex.c:610
void ** groups_list
Definition: nntp.h:100
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
List of Mailboxes.
Definition: mailbox.h:144
static void init_state(struct BrowserState *state, struct Menu *menu)
Initialise a browser state.
Definition: browser.c:686
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:43
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:79
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:146
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 832 of file browser.c.

833 {
834  struct stat s;
835  struct Buffer *md = NULL;
836  struct Buffer *mailbox = NULL;
837 
838 #ifdef USE_NNTP
839  if (OptNews)
840  {
842 
843  init_state(state, menu);
844 
845  for (unsigned int i = 0; i < adata->groups_num; i++)
846  {
847  struct NntpMboxData *mdata = adata->groups_list[i];
848  if (mdata && (mdata->has_new_mail ||
849  (mdata->subscribed && (mdata->unread || !C_ShowOnlyUnread))))
850  {
851  add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
852  }
853  }
854  }
855  else
856 #endif
857  {
858  init_state(state, menu);
859 
861  return -1;
862  mailbox = mutt_buffer_pool_get();
863  md = mutt_buffer_pool_get();
865 
866  struct MailboxList ml = neomutt_mailboxlist_get_all(NeoMutt, MUTT_MAILBOX_ANY);
867  struct MailboxNode *np = NULL;
868  STAILQ_FOREACH(np, &ml, entries)
869  {
870  if (!np->mailbox)
871  continue;
872 
873  if (Context && Context->mailbox &&
875  {
878  }
879 
880  mutt_buffer_strcpy(mailbox, mailbox_path(np->mailbox));
883 
884  switch (np->mailbox->magic)
885  {
886  case MUTT_IMAP:
887  case MUTT_POP:
888  add_folder(menu, state, mutt_b2s(mailbox), np->mailbox->name, NULL,
889  np->mailbox, NULL);
890  continue;
891  case MUTT_NOTMUCH:
892  case MUTT_NNTP:
893  add_folder(menu, state, mailbox_path(np->mailbox), np->mailbox->name,
894  NULL, np->mailbox, NULL);
895  continue;
896  default: /* Continue */
897  break;
898  }
899 
900  if (lstat(mailbox_path(np->mailbox), &s) == -1)
901  continue;
902 
903  if ((!S_ISREG(s.st_mode)) && (!S_ISDIR(s.st_mode)) && (!S_ISLNK(s.st_mode)))
904  continue;
905 
906  if (np->mailbox->magic == MUTT_MAILDIR)
907  {
908  struct stat st2;
909 
910  mutt_buffer_printf(md, "%s/new", mailbox_path(np->mailbox));
911  if (stat(mutt_b2s(md), &s) < 0)
912  s.st_mtime = 0;
913  mutt_buffer_printf(md, "%s/cur", mailbox_path(np->mailbox));
914  if (stat(mutt_b2s(md), &st2) < 0)
915  st2.st_mtime = 0;
916  if (st2.st_mtime > s.st_mtime)
917  s.st_mtime = st2.st_mtime;
918  }
919 
920  add_folder(menu, state, mutt_b2s(mailbox), np->mailbox->name, &s, np->mailbox, NULL);
921  }
923  }
924  browser_sort(state);
925 
926  mutt_buffer_pool_release(&mailbox);
928  return 0;
929 }
bool has_new_mail
Definition: nntp.h:148
The "current" mailbox.
Definition: context.h:36
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox&#39;s path string.
Definition: mailbox.h:191
int msg_count
Total number of messages.
Definition: mailbox.h:90
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:91
&#39;NNTP&#39; (Usenet) Mailbox type
Definition: mailbox.h:51
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:83
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:44
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:629
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:703
NNTP-specific Account data -.
Definition: nntp.h:75
bool subscribed
Definition: nntp.h:147
char * name
A short name for the Mailbox.
Definition: mailbox.h:84
struct Mailbox * mailbox
Definition: context.h:50
enum MailboxType magic
Mailbox type.
Definition: mailbox.h:104
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType magic)
Get a List of all Mailboxes.
Definition: neomutt.c:157
char * group
Definition: nntp.h:140
void * mdata
Driver specific data.
Definition: mailbox.h:135
&#39;Maildir&#39; Mailbox type
Definition: mailbox.h:50
#define mutt_b2s(buf)
Definition: buffer.h:41
&#39;POP3&#39; Mailbox type
Definition: mailbox.h:54
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:125
void * adata
Private data (for Mailbox backends)
Definition: account.h:43
unsigned int groups_num
Definition: nntp.h:98
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: nntp.h:138
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:53
anum_t unread
Definition: nntp.h:146
bool C_BrowserAbbreviateMailboxes
Config: Abbreviate mailboxes using &#39;~&#39; and &#39;=&#39; in the browser.
Definition: browser.c:70
void ** groups_list
Definition: nntp.h:100
List of Mailboxes.
Definition: mailbox.h:144
#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:686
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:43
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:79
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:146
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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::menu_search()

Definition at line 934 of file browser.c.

935 {
936 #ifdef USE_NNTP
937  if (OptNews)
938  return regexec(rx, ((struct FolderFile *) menu->data)[line].desc, 0, NULL, 0);
939 #endif
940  struct FolderFile current_ff = ((struct FolderFile *) menu->data)[line];
941  char *search_on = current_ff.desc ? current_ff.desc : current_ff.name;
942 
943  return regexec(rx, search_on, 0, NULL, 0);
944 }
char * desc
Definition: browser.h:71
char * name
Definition: browser.h:70
Browser entry representing a folder/dir.
Definition: browser.h:61
const char * line
Definition: common.c:36
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:43
+ 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::menu_make_entry()

Definition at line 949 of file browser.c.

950 {
951  struct Folder folder;
952 
953  folder.ff = &((struct FolderFile *) menu->data)[line];
954  folder.num = line;
955 
956 #ifdef USE_NNTP
957  if (OptNews)
958  {
959  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
961  (unsigned long) &folder, MUTT_FORMAT_ARROWCURSOR);
962  }
963  else
964 #endif
965  {
966  mutt_expando_format(buf, buflen, 0, menu->win_index->state.cols,
968  (unsigned long) &folder, MUTT_FORMAT_ARROWCURSOR);
969  }
970 }
void mutt_expando_format(char *buf, size_t buflen, size_t col, int cols, const char *src, format_t *callback, unsigned long data, MuttFormatFlags flags)
Expand expandos (x) in a string.
Definition: muttlib.c:877
#define NONULL(x)
Definition: string2.h:37
#define 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:56
A folder/dir in the browser.
Definition: browser.h:52
Browser entry representing a folder/dir.
Definition: browser.h:61
const char * line
Definition: common.c:36
struct WindowState state
Current state of the Window.
Definition: mutt_window.h:91
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
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:43
+ 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 980 of file browser.c.

981 {
982  menu->top = 0;
983  /* Reset menu position to 1.
984  * We do not risk overflow as the init_menu function changes
985  * current if it is bigger than state->entrylen. */
986  if ((mutt_str_strcmp(state->entry[0].desc, "..") == 0) ||
987  (mutt_str_strcmp(state->entry[0].desc, "../") == 0))
988  {
989  /* Skip the first entry, unless there's only one entry. */
990  menu->current = (menu->max > 1);
991  }
992  else
993  {
994  menu->current = 0;
995  }
996 }
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:615
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 1006 of file browser.c.

1008 {
1009  menu->max = state->entrylen;
1010 
1011  if (menu->current >= menu->max)
1012  menu->current = menu->max - 1;
1013  if (menu->current < 0)
1014  menu->current = 0;
1015  if (menu->top > menu->current)
1016  menu->top = 0;
1017 
1018  menu->tagged = 0;
1019 
1020 #ifdef USE_NNTP
1021  if (OptNews)
1022  {
1023  if (mailbox)
1024  snprintf(title, titlelen, _("Subscribed newsgroups"));
1025  else
1026  {
1027  snprintf(title, titlelen, _("Newsgroups on server [%s]"),
1029  }
1030  }
1031  else
1032 #endif
1033  {
1034  if (mailbox)
1035  {
1036  menu->is_mailbox_list = true;
1037  snprintf(title, titlelen, _("Mailboxes [%d]"),
1038  mutt_mailbox_check(Context ? Context->mailbox : NULL, 0));
1039  }
1040  else
1041  {
1042  struct Buffer *path = mutt_buffer_pool_get();
1043  menu->is_mailbox_list = false;
1044  mutt_buffer_copy(path, &LastDir);
1046 #ifdef USE_IMAP
1047  if (state->imap_browse && C_ImapListSubscribed)
1048  {
1049  snprintf(title, titlelen, _("Subscribed [%s], File mask: %s"),
1050  mutt_b2s(path), NONULL(C_Mask ? C_Mask->pattern : NULL));
1051  }
1052  else
1053 #endif
1054  {
1055  snprintf(title, titlelen, _("Directory [%s], File mask: %s"),
1056  mutt_b2s(path), NONULL(C_Mask ? C_Mask->pattern : NULL));
1057  }
1058  mutt_buffer_pool_release(&path);
1059  }
1060  }
1061 
1062  /* Browser tracking feature.
1063  * The goal is to highlight the good directory if LastDir is the parent dir
1064  * of LastDirBackup (this occurs mostly when one hit "../"). It should also work
1065  * properly when the user is in examine_mailboxes-mode. */
1067  {
1068  char target_dir[PATH_MAX] = { 0 };
1069 
1070 #ifdef USE_IMAP
1071  /* Check what kind of dir LastDirBackup is. */
1073  {
1074  mutt_str_strfcpy(target_dir, mutt_b2s(&LastDirBackup), sizeof(target_dir));
1075  imap_clean_path(target_dir, sizeof(target_dir));
1076  }
1077  else
1078 #endif
1079  mutt_str_strfcpy(target_dir, strrchr(mutt_b2s(&LastDirBackup), '/') + 1,
1080  sizeof(target_dir));
1081 
1082  /* If we get here, it means that LastDir is the parent directory of
1083  * LastDirBackup. I.e., we're returning from a subdirectory, and we want
1084  * to position the cursor on the directory we're returning from. */
1085  bool matched = false;
1086  for (unsigned int i = 0; i < state->entrylen; i++)
1087  {
1088  if (mutt_str_strcmp(state->entry[i].name, target_dir) == 0)
1089  {
1090  menu->current = i;
1091  matched = true;
1092  break;
1093  }
1094  }
1095  if (!matched)
1096  browser_highlight_default(state, menu);
1097  }
1098  else
1099  browser_highlight_default(state, menu);
1100 
1101  menu->redraw = REDRAW_FULL;
1102 }
The "current" mailbox.
Definition: context.h:36
WHERE bool C_ImapListSubscribed
Config: (imap) When browsing a mailbox, only display subscribed folders.
Definition: globals.h:224
#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:2474
struct ConnAccount account
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:703
char host[128]
Definition: connaccount.h:36
static struct Buffer LastDirBackup
Definition: browser.c:101
struct Mailbox * mailbox
Definition: context.h:50
char * name
Definition: browser.h:70
#define mutt_b2s(buf)
Definition: buffer.h:41
#define PATH_MAX
Definition: mutt.h:50
int mutt_mailbox_check(struct Mailbox *m_cur, int force)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:125
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:750
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: nntp.h:102
static void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: browser.c:980
WHERE struct Regex * C_Mask
Config: Only display files/dirs matching this regex in the browser.
Definition: globals.h:173
static struct Buffer LastDir
Definition: browser.c:100
int current
Current entry.
Definition: mutt_menu.h:87
char * pattern
printable version
Definition: regex3.h:59
&#39;IMAP&#39; Mailbox type
Definition: mailbox.h:52
bool imap_browse
Definition: browser.h:101
WHERE bool OptNews
(pseudo) used to change reader mode
Definition: options.h:43
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
struct FolderFile * entry
Definition: browser.h:97
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:79
void imap_clean_path(char *path, size_t plen)
Cleans an IMAP path using imap_fix_path.
Definition: util.c:330
+ 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::menu_tag()

Definition at line 1107 of file browser.c.

1108 {
1109  struct FolderFile *ff = &(((struct FolderFile *) menu->data)[sel]);
1110  if (S_ISDIR(ff->mode) || (S_ISLNK(ff->mode) && link_is_dir(mutt_b2s(&LastDir), ff->name)))
1111  {
1112  mutt_error(_("Can't attach a directory"));
1113  return 0;
1114  }
1115 
1116  bool ot = ff->tagged;
1117  ff->tagged = ((act >= 0) ? act : !ff->tagged);
1118 
1119  return ff->tagged - ot;
1120 }
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 1132 of file browser.c.

1133 {
1134  init_lastdir();
1135 
1137 
1138  /* Method that will fetch the parent path depending on the type of the path. */
1139  char buf[PATH_MAX];
1140  mutt_get_parent_path(mutt_b2s(&LastDirBackup), buf, sizeof(buf));
1141  mutt_buffer_strcpy(&LastDir, buf);
1142 }
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:50
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:1655
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_dlg_browser_observer()

int mutt_dlg_browser_observer ( struct NotifyCallback nc)

Listen for config changes affecting the Browser menu - Implements observer_t()

Definition at line 1147 of file browser.c.

1148 {
1149  if (!nc->event_data || !nc->global_data)
1150  return -1;
1151  if (nc->event_type != NT_CONFIG)
1152  return 0;
1153 
1154  struct EventConfig *ec = nc->event_data;
1155  struct MuttWindow *dlg = nc->global_data;
1156 
1157  if (mutt_str_strcmp(ec->name, "status_on_top") != 0)
1158  return 0;
1159 
1160  struct MuttWindow *win_first = TAILQ_FIRST(&dlg->children);
1161 
1162  if ((C_StatusOnTop && (win_first->type == WT_INDEX)) ||
1163  (!C_StatusOnTop && (win_first->type != WT_INDEX)))
1164  {
1165  // Swap the Index and the IndexBar Windows
1166  TAILQ_REMOVE(&dlg->children, win_first, entries);
1167  TAILQ_INSERT_TAIL(&dlg->children, win_first, entries);
1168  }
1169 
1170  mutt_window_reflow(dlg);
1171  return 0;
1172 }
WHERE bool C_StatusOnTop
Config: Display the status bar at the top.
Definition: globals.h:255
#define TAILQ_FIRST(head)
Definition: queue.h:716
A config-change event.
Definition: subset.h:68
A division of the screen.
Definition: mutt_window.h:86
An Index Window containing a selection list.
Definition: mutt_window.h:72
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition: observer.h:42
void * global_data
Data from notify_observer_add()
Definition: observer.h:45
#define TAILQ_REMOVE(head, elm, field)
Definition: queue.h:834
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition: queue.h:802
void * event_data
Data from notify_send()
Definition: observer.h:44
Config has changed.
Definition: notify_type.h:34
void mutt_window_reflow(struct MuttWindow *win)
Resize a Window and its children.
Definition: mutt_window.c:346
struct MuttWindowList children
Children Windows.
Definition: mutt_window.h:99
enum WindowType type
Window type, e.g. WT_SIDEBAR.
Definition: mutt_window.h:101
const char * name
Name of config item that changed.
Definition: subset.h:71
int mutt_str_strcmp(const char *a, const char *b)
Compare two strings, safely.
Definition: string.c:615
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 1181 of file browser.c.

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

2257 {
2258  struct Buffer *f_buf = mutt_buffer_pool_get();
2259 
2260  mutt_buffer_strcpy(f_buf, NONULL(file));
2261  mutt_buffer_select_file(f_buf, flags, files, numfiles);
2262  mutt_str_strfcpy(file, mutt_b2s(f_buf), filelen);
2263 
2264  mutt_buffer_pool_release(&f_buf);
2265 }
#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:1181
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:750
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
+ 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.