NeoMutt  2025-12-11-949-g4870ee
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
dlg_browser.c
Go to the documentation of this file.
1
30
75
76#include "config.h"
77#include <dirent.h>
78#include <errno.h>
79#include <limits.h>
80#include <stdbool.h>
81#include <stdio.h>
82#include <string.h>
83#include <sys/stat.h>
84#include "mutt/lib.h"
85#include "config/lib.h"
86#include "email/lib.h"
87#include "core/lib.h"
88#include "conn/lib.h"
89#include "gui/lib.h"
90#include "lib.h"
91#include "expando/lib.h"
92#include "imap/lib.h"
93#include "key/lib.h"
94#include "menu/lib.h"
95#include "nntp/lib.h"
96#include "expando.h"
97#include "functions.h"
98#include "globals.h"
99#include "module_data.h"
100#include "mutt_logging.h"
101#include "mutt_mailbox.h"
102#include "muttlib.h"
103#include "mx.h"
104#include "nntp/adata.h" // IWYU pragma: keep
105#include "nntp/mdata.h" // IWYU pragma: keep
106#include "private_data.h"
107#include "sort.h"
108
110static const struct Mapping FolderHelp[] = {
111 // clang-format off
112 { N_("Exit"), OP_EXIT },
113 { N_("Chdir"), OP_CHANGE_DIRECTORY },
114 { N_("Goto"), OP_BROWSER_GOTO_FOLDER },
115 { N_("Mask"), OP_ENTER_MASK },
116 { N_("Help"), OP_HELP },
117 { NULL, 0 },
118 // clang-format on
119};
120
122static const struct Mapping FolderNewsHelp[] = {
123 // clang-format off
124 { N_("Exit"), OP_EXIT },
125 { N_("List"), OP_TOGGLE_MAILBOXES },
126 { N_("Subscribe"), OP_BROWSER_SUBSCRIBE },
127 { N_("Unsubscribe"), OP_BROWSER_UNSUBSCRIBE },
128 { N_("Catchup"), OP_CATCHUP },
129 { N_("Mask"), OP_ENTER_MASK },
130 { N_("Help"), OP_HELP },
131 { NULL, 0 },
132 // clang-format on
133};
134
142bool link_is_dir(const char *folder, const char *path)
143{
144 struct stat st = { 0 };
145 bool rc = false;
146
147 struct Buffer *fullpath = buf_pool_get();
148 buf_concat_path(fullpath, folder, path);
149
150 if (stat(buf_string(fullpath), &st) == 0)
151 rc = S_ISDIR(st.st_mode);
152
153 buf_pool_release(&fullpath);
154
155 return rc;
156}
157
168void browser_add_folder(const struct Menu *menu, struct BrowserState *state,
169 const char *name, const char *desc,
170 const struct stat *st, struct Mailbox *m, void *data)
171{
172 if ((!menu || state->is_mailbox_list) && m && !m->visible)
173 {
174 return;
175 }
176
177 struct FolderFile ff = { 0 };
178
179 if (st)
180 {
181 ff.mode = st->st_mode;
182 ff.mtime = st->st_mtime;
183 ff.size = st->st_size;
184 ff.gid = st->st_gid;
185 ff.uid = st->st_uid;
186 ff.nlink = st->st_nlink;
187 ff.local = true;
188 }
189 else
190 {
191 ff.local = false;
192 }
193
194 if (m)
195 {
196 ff.has_mailbox = true;
197 ff.gen = m->gen;
198 ff.has_new_mail = m->has_new;
199 ff.msg_count = m->msg_count;
200 ff.msg_unread = m->msg_unread;
201 ff.notify_user = m->notify_user;
203 }
204
205 ff.name = mutt_str_dup(name);
206 ff.desc = mutt_str_dup(desc ? desc : name);
207 ff.imap = false;
208 if (OptNews)
209 ff.nd = data;
210
211 ARRAY_ADD(&state->entry, ff);
212}
213
218void init_state(struct BrowserState *state)
219{
220 ARRAY_INIT(&state->entry);
221 ARRAY_RESERVE(&state->entry, 256);
222 state->imap_browse = false;
223}
224
235int examine_directory(struct Mailbox *m, struct Menu *menu, struct BrowserState *state,
236 const char *dirname, const char *prefix)
237{
239 int rc = -1;
240 struct Buffer *buf = buf_pool_get();
241 if (OptNews)
242 {
243 struct NntpAccountData *adata = mod_data->current_news_srv;
244
245 init_state(state);
246
247 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
248 for (unsigned int i = 0; i < adata->groups_num; i++)
249 {
250 struct NntpMboxData *mdata = adata->groups_list[i];
251 if (!mdata)
252 continue;
253 if (prefix && *prefix && !mutt_str_startswith(mdata->group, prefix))
254 continue;
255 if (!mutt_regex_match(c_mask, mdata->group))
256 {
257 continue;
258 }
259 browser_add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
260 }
261 }
262 else
263 {
264 struct stat st = { 0 };
265 DIR *dir = NULL;
266 struct dirent *de = NULL;
267
268 // Work on a mutable copy to avoid modifying the const dirname parameter
269 char dstrbuf[PATH_MAX] = { 0 };
270 mutt_str_copy(dstrbuf, dirname, sizeof(dstrbuf));
271
272 while (stat(dstrbuf, &st) == -1)
273 {
274 if (errno == ENOENT)
275 {
276 /* The last used directory is deleted, try to use the parent dir. */
277 char *c = strrchr(dstrbuf, '/');
278
279 if (c && (c > dstrbuf))
280 {
281 *c = '\0';
282 continue;
283 }
284 }
285 mutt_perror("%s", dstrbuf);
286 goto ed_out;
287 }
288
289 if (!S_ISDIR(st.st_mode))
290 {
291 mutt_error(_("%s is not a directory"), dstrbuf);
292 goto ed_out;
293 }
294
295 if (m)
297
298 dir = mutt_file_opendir(dstrbuf, MUTT_OPENDIR_NONE);
299 if (!dir)
300 {
301 mutt_perror("%s", dstrbuf);
302 goto ed_out;
303 }
304
305 init_state(state);
306
307 struct MailboxArray ma = neomutt_mailboxes_get(NeoMutt, MUTT_MAILBOX_ANY);
308
309 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
310 while ((de = readdir(dir)))
311 {
312 if (mutt_str_equal(de->d_name, "."))
313 continue; /* we don't need . */
314
315 if (prefix && *prefix && !mutt_str_startswith(de->d_name, prefix))
316 {
317 continue;
318 }
319 if (!mutt_regex_match(c_mask, de->d_name))
320 {
321 continue;
322 }
323
324 buf_concat_path(buf, dstrbuf, de->d_name);
325 if (lstat(buf_string(buf), &st) == -1)
326 continue;
327
328 /* No size for directories or symlinks */
329 if (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))
330 st.st_size = 0;
331 else if (!S_ISREG(st.st_mode))
332 continue;
333
334 struct Mailbox **mp = NULL;
335 ARRAY_FOREACH(mp, &ma)
336 {
337 if (mutt_str_equal(buf_string(buf), mailbox_path(*mp)))
338 break;
339 }
340
341 struct Mailbox *m_match = mp ? *mp : NULL;
342 if (m_match && m && m->poll_new_mail && mutt_str_equal(m_match->realpath, m->realpath))
343 {
344 m_match->msg_count = m->msg_count;
345 m_match->msg_unread = m->msg_unread;
346 }
347 browser_add_folder(menu, state, de->d_name, NULL, &st, m_match, NULL);
348 }
349 ARRAY_FREE(&ma); // Clean up the ARRAY, but not the Mailboxes
350 closedir(dir);
351 }
352 browser_sort(state);
353 rc = 0;
354ed_out:
355 buf_pool_release(&buf);
356 return rc;
357}
358
367int examine_mailboxes(struct Mailbox *m, struct Menu *menu, struct BrowserState *state)
368{
370 struct stat st = { 0 };
371 struct Buffer *md = NULL;
372 struct Buffer *mailbox = NULL;
373
374 if (OptNews)
375 {
376 struct NntpAccountData *adata = mod_data->current_news_srv;
377
378 init_state(state);
379
380 const bool c_show_only_unread = cs_subset_bool(NeoMutt->sub, "show_only_unread");
381 for (unsigned int i = 0; i < adata->groups_num; i++)
382 {
383 struct NntpMboxData *mdata = adata->groups_list[i];
384 if (mdata && (mdata->has_new_mail ||
385 (mdata->subscribed && (mdata->unread || !c_show_only_unread))))
386 {
387 browser_add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
388 }
389 }
390 }
391 else
392 {
393 init_state(state);
394
396 return -1;
397
398 mailbox = buf_pool_get();
399 md = buf_pool_get();
400
402
403 struct MailboxArray ma = neomutt_mailboxes_get(NeoMutt, MUTT_MAILBOX_ANY);
404 const bool c_browser_abbreviate_mailboxes = cs_subset_bool(NeoMutt->sub, "browser_abbreviate_mailboxes");
405
406 struct Mailbox **mp = NULL;
407 ARRAY_FOREACH(mp, &ma)
408 {
409 struct Mailbox *m_match = *mp;
410
411 if (m && m->poll_new_mail && mutt_str_equal(m_match->realpath, m->realpath))
412 {
413 m_match->msg_count = m->msg_count;
414 m_match->msg_unread = m->msg_unread;
415 }
416
417 buf_strcpy(mailbox, mailbox_path(m_match));
418 if (c_browser_abbreviate_mailboxes)
419 pretty_mailbox(mailbox);
420
421 switch (m_match->type)
422 {
423 case MUTT_IMAP:
424 case MUTT_POP:
425 browser_add_folder(menu, state, buf_string(mailbox), m_match->name,
426 NULL, m_match, NULL);
427 continue;
428 case MUTT_NOTMUCH:
429 case MUTT_NNTP:
430 browser_add_folder(menu, state, mailbox_path(m_match), m_match->name,
431 NULL, m_match, NULL);
432 continue;
433 default: /* Continue */
434 break;
435 }
436
437 if (lstat(mailbox_path(m_match), &st) == -1)
438 continue;
439
440 if ((!S_ISREG(st.st_mode)) && (!S_ISDIR(st.st_mode)) && (!S_ISLNK(st.st_mode)))
441 continue;
442
443 if (m_match->type == MUTT_MAILDIR)
444 {
445 struct stat st2 = { 0 };
446
447 buf_printf(md, "%s/new", mailbox_path(m_match));
448 if (stat(buf_string(md), &st) < 0)
449 st.st_mtime = 0;
450 buf_printf(md, "%s/cur", mailbox_path(m_match));
451 if (stat(buf_string(md), &st2) < 0)
452 st2.st_mtime = 0;
453 if (st2.st_mtime > st.st_mtime)
454 st.st_mtime = st2.st_mtime;
455 }
456
457 browser_add_folder(menu, state, buf_string(mailbox), m_match->name, &st, m_match, NULL);
458 }
459 ARRAY_FREE(&ma); // Clean up the ARRAY, but not the Mailboxes
460 }
461 browser_sort(state);
462
463 buf_pool_release(&mailbox);
464 buf_pool_release(&md);
465 return 0;
466}
467
471static int select_file_search(struct Menu *menu, regex_t *rx, int line)
472{
473 struct BrowserPrivateData *priv = menu->mdata;
474 struct BrowserEntryArray *entry = &priv->state.entry;
475 if (OptNews)
476 return regexec(rx, ARRAY_GET(entry, line)->desc, 0, NULL, 0);
477 struct FolderFile *ff = ARRAY_GET(entry, line);
478 char *search_on = ff->desc ? ff->desc : ff->name;
479
480 return regexec(rx, search_on, 0, NULL, 0);
481}
482
488static int folder_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
489{
490 struct BrowserPrivateData *priv = menu->mdata;
491 struct BrowserState *bstate = &priv->state;
492 struct BrowserEntryArray *entry = &bstate->entry;
493 struct Folder folder = {
494 .ff = ARRAY_GET(entry, line),
495 .num = line,
496 };
497
498 const bool c_arrow_cursor = cs_subset_bool(menu->sub, "arrow_cursor");
499 if (c_arrow_cursor)
500 {
501 const char *const c_arrow_string = cs_subset_string(menu->sub, "arrow_string");
502 if (max_cols > 0)
503 max_cols -= (mutt_strwidth(c_arrow_string) + 1);
504 }
505
506 if (OptNews)
507 {
508 const struct Expando *c_group_index_format = cs_subset_expando(NeoMutt->sub, "group_index_format");
509 return expando_filter(c_group_index_format, GroupIndexRenderCallbacks, &folder,
510 MUTT_FORMAT_ARROWCURSOR, max_cols, NeoMutt->env, buf);
511 }
512
513 if (bstate->is_mailbox_list)
514 {
515 const struct Expando *c_mailbox_folder_format = cs_subset_expando(NeoMutt->sub, "mailbox_folder_format");
516 return expando_filter(c_mailbox_folder_format, FolderRenderCallbacks, &folder,
517 MUTT_FORMAT_ARROWCURSOR, max_cols, NeoMutt->env, buf);
518 }
519
520 const struct Expando *c_folder_format = cs_subset_expando(NeoMutt->sub, "folder_format");
521 return expando_filter(c_folder_format, FolderRenderCallbacks, &folder,
522 MUTT_FORMAT_ARROWCURSOR, max_cols, NeoMutt->env, buf);
523}
524
533void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
534{
535 menu->top = 0;
536 /* Reset menu position to 1.
537 * We do not risk overflow as the init_menu function changes
538 * current if it is bigger than state->entrylen. */
539 if (!ARRAY_EMPTY(&state->entry) &&
540 (mutt_str_equal(ARRAY_FIRST(&state->entry)->desc, "..") ||
541 mutt_str_equal(ARRAY_FIRST(&state->entry)->desc, "../")))
542 {
543 /* Skip the first entry, unless there's only one entry. */
544 menu_set_index(menu, (menu->max > 1));
545 }
546 else
547 {
548 menu_set_index(menu, 0);
549 }
550}
551
559void init_menu(struct BrowserState *state, struct Menu *menu, struct Mailbox *m,
560 struct MuttWindow *sbar)
561{
564 char title[256] = { 0 };
565 menu->max = ARRAY_SIZE(&state->entry);
566
567 int index = menu_get_index(menu);
568 if (index >= menu->max)
569 menu_set_index(menu, menu->max - 1);
570 if (index < 0)
571 menu_set_index(menu, 0);
572 if (menu->top > index)
573 menu->top = 0;
574
575 menu->num_tagged = 0;
576
577 if (OptNews)
578 {
579 if (state->is_mailbox_list)
580 {
581 snprintf(title, sizeof(title), _("Subscribed newsgroups"));
582 }
583 else
584 {
585 snprintf(title, sizeof(title), _("Newsgroups on server [%s]"),
586 nntp_mod_data->current_news_srv->conn->account.host);
587 }
588 }
589 else
590 {
591 if (state->is_mailbox_list)
592 {
593 snprintf(title, sizeof(title), _("Mailboxes [%d]"),
595 }
596 else
597 {
598 struct Buffer *path = buf_pool_get();
599 buf_copy(path, &mod_data->last_dir);
600 pretty_mailbox(path);
601 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
602 const bool c_imap_list_subscribed = cs_subset_bool(NeoMutt->sub, "imap_list_subscribed");
603 if (state->imap_browse && c_imap_list_subscribed)
604 {
605 snprintf(title, sizeof(title), _("Subscribed [%s], File mask: %s"),
606 buf_string(path), NONULL(c_mask ? c_mask->pattern : NULL));
607 }
608 else
609 {
610 snprintf(title, sizeof(title), _("Directory [%s], File mask: %s"),
611 buf_string(path), NONULL(c_mask ? c_mask->pattern : NULL));
612 }
613 buf_pool_release(&path);
614 }
615 }
616 sbar_set_title(sbar, title);
617
618 /* Browser tracking feature.
619 * The goal is to highlight the good directory if LastDir is the parent dir
620 * of LastDirBackup (this occurs mostly when one hit "../"). It should also work
621 * properly when the user is in examine_mailboxes-mode. */
623 buf_string(&mod_data->last_dir)))
624 {
625 char target_dir[PATH_MAX] = { 0 };
626
627 /* Check what kind of dir LastDirBackup is. */
628 if (imap_path_probe(buf_string(&mod_data->last_dir_backup), NULL) == MUTT_IMAP)
629 {
630 mutt_str_copy(target_dir, buf_string(&mod_data->last_dir_backup), sizeof(target_dir));
631 imap_clean_path(target_dir, sizeof(target_dir));
632 }
633 else
634 {
635 const char *slash = strrchr(buf_string(&mod_data->last_dir_backup), '/');
636 if (slash)
637 mutt_str_copy(target_dir, slash + 1, sizeof(target_dir));
638 else
639 mutt_str_copy(target_dir, buf_string(&mod_data->last_dir_backup), sizeof(target_dir));
640 }
641
642 /* If we get here, it means that LastDir is the parent directory of
643 * LastDirBackup. I.e., we're returning from a subdirectory, and we want
644 * to position the cursor on the directory we're returning from. */
645 bool matched = false;
646 struct FolderFile *ff = NULL;
647 ARRAY_FOREACH(ff, &state->entry)
648 {
649 if (mutt_str_equal(ff->name, target_dir))
650 {
651 menu_set_index(menu, ARRAY_FOREACH_IDX_ff);
652 matched = true;
653 break;
654 }
655 }
656 if (!matched)
657 browser_highlight_default(state, menu);
658 }
659 else
660 {
661 browser_highlight_default(state, menu);
662 }
663
665}
666
678static int file_tag(struct Menu *menu, int sel, int act)
679{
681 struct BrowserPrivateData *priv = menu->mdata;
682 struct BrowserEntryArray *entry = &priv->state.entry;
683 struct FolderFile *ff = ARRAY_GET(entry, sel);
684
685 /* Allow tagging NNTP newsgroups, but disallow tagging directories for file selection */
686 bool is_nntp = (ff->nd != NULL);
687 if (!is_nntp &&
688 (S_ISDIR(ff->mode) ||
689 (S_ISLNK(ff->mode) && link_is_dir(buf_string(&mod_data->last_dir), ff->name))))
690 {
691 mutt_error(_("Can't attach a directory"));
692 return 0;
693 }
694
695 bool ot = ff->tagged;
696 ff->tagged = ((act >= 0) ? act : !ff->tagged);
697
698 return ff->tagged - ot;
699}
700
705{
706 if (nc->event_type != NT_CONFIG)
707 return 0;
708 if (!nc->global_data || !nc->event_data)
709 return -1;
710
711 struct EventConfig *ev_c = nc->event_data;
712
713 struct BrowserPrivateData *priv = nc->global_data;
714 struct Menu *menu = priv->menu;
715
716 if (mutt_str_equal(ev_c->name, "browser_sort_dirs_first"))
717 {
718 struct BrowserState *state = &priv->state;
719 browser_sort(state);
720 browser_highlight_default(state, menu);
721 }
722 else if (!mutt_str_equal(ev_c->name, "browser_abbreviate_mailboxes") &&
723 !mutt_str_equal(ev_c->name, "browser_sort") &&
724 !mutt_str_equal(ev_c->name, "date_format") &&
725 !mutt_str_equal(ev_c->name, "folder") &&
726 !mutt_str_equal(ev_c->name, "folder_format") &&
727 !mutt_str_equal(ev_c->name, "group_index_format") &&
728 !mutt_str_equal(ev_c->name, "mailbox_folder_format"))
729 {
730 return 0;
731 }
732
734 mutt_debug(LL_DEBUG5, "config done, request WA_RECALC, MENU_REDRAW_FULL\n");
735
736 return 0;
737}
738
745{
746 if (nc->event_type != NT_MAILBOX)
747 return 0;
749 return 0;
750 if (!nc->global_data || !nc->event_data)
751 return -1;
752
753 struct BrowserPrivateData *priv = nc->global_data;
754
755 struct BrowserState *state = &priv->state;
756 if (state->is_mailbox_list)
757 {
758 struct EventMailbox *ev_m = nc->event_data;
759 struct Mailbox *m = ev_m->mailbox;
760 struct FolderFile *ff = NULL;
761 ARRAY_FOREACH(ff, &state->entry)
762 {
763 if (ff->gen != m->gen)
764 continue;
765
766 ff->has_new_mail = m->has_new;
767 ff->msg_count = m->msg_count;
768 ff->msg_unread = m->msg_unread;
769 ff->notify_user = m->notify_user;
771 mutt_str_replace(&ff->desc, m->name);
772 break;
773 }
774 }
775
777 mutt_debug(LL_DEBUG5, "mailbox done, request WA_RECALC, MENU_REDRAW_FULL\n");
778
779 return 0;
780}
781
790{
791 if (nc->event_type != NT_WINDOW)
792 return 0;
793 if (!nc->global_data || !nc->event_data)
794 return -1;
796 return 0;
797
798 struct BrowserPrivateData *priv = nc->global_data;
799 struct MuttWindow *win_menu = priv->menu->win;
800
801 struct EventWindow *ev_w = nc->event_data;
802 if (ev_w->win != win_menu)
803 return 0;
804
808
809 mutt_debug(LL_DEBUG5, "window delete done\n");
810 return 0;
811}
812
823void mutt_browser_select_dir(const char *f)
824{
826
827 buf_strcpy(&mod_data->last_dir_backup, f);
828
829 /* Method that will fetch the parent path depending on the type of the path. */
830 char buf[PATH_MAX] = { 0 };
831 mutt_get_parent_path(buf_string(&mod_data->last_dir_backup), buf, sizeof(buf));
832 buf_strcpy(&mod_data->last_dir, buf);
833}
834
846void dlg_browser(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m,
847 char ***files, int *numfiles)
848{
850 ASSERT(mod_data);
852 priv->file = file;
853 priv->mailbox = m;
854 priv->files = files;
855 priv->numfiles = numfiles;
856 priv->multiple = (flags & MUTT_SEL_MULTI);
857 priv->folder = (flags & MUTT_SEL_FOLDER);
858 priv->state.is_mailbox_list = (flags & MUTT_SEL_MAILBOX) && priv->folder;
859 priv->last_selected_mailbox = -1;
860
861 if (OptNews)
862 {
863 if (buf_is_empty(file))
864 {
865 priv->state.is_mailbox_list = true;
866 // struct NntpModuleData *nntp_mod_data = neomutt_get_module_data(NeoMutt, MODULE_ID_NNTP);
867 // struct NntpAccountData *adata = nntp_mod_data->current_news_srv;
868
869 // /* default state for news reader mode is browse subscribed newsgroups */
870 // priv->state.is_mailbox_list = false;
871 // for (size_t i = 0; i < adata->groups_num; i++)
872 // {
873 // struct NntpMboxData *mdata = adata->groups_list[i];
874 // if (mdata && mdata->subscribed)
875 // {
876 // priv->state.is_mailbox_list = true;
877 // break;
878 // }
879 // }
880 }
881 else
882 {
883 buf_copy(priv->prefix, file);
884 }
885 }
886 else if (!buf_is_empty(file))
887 {
888 expand_path(file, false);
890 {
891 init_state(&priv->state);
892 priv->state.imap_browse = true;
893 if (imap_browse(buf_string(file), &priv->state) == 0)
894 {
895 buf_strcpy(&mod_data->last_dir, priv->state.folder);
896 browser_sort(&priv->state);
897 }
898 }
899 else
900 {
901 int i = buf_len(file);
902 i--;
903 for (; (i > 0) && ((buf_string(file))[i] != '/'); i--)
904 {
905 ; // do nothing
906 }
907
908 if (i > 0)
909 {
910 if ((buf_string(file))[0] == '/')
911 {
912 buf_strcpy_n(&mod_data->last_dir, buf_string(file), i);
913 }
914 else
915 {
916 mutt_path_getcwd(&mod_data->last_dir);
917 buf_addch(&mod_data->last_dir, '/');
918 buf_addstr_n(&mod_data->last_dir, buf_string(file), i);
919 }
920 }
921 else
922 {
923 if ((buf_string(file))[0] == '/')
924 buf_strcpy(&mod_data->last_dir, "/");
925 else
926 mutt_path_getcwd(&mod_data->last_dir);
927 }
928
929 if ((i <= 0) && (buf_string(file)[0] != '/'))
930 buf_copy(priv->prefix, file);
931 else
932 buf_strcpy(priv->prefix, buf_string(file) + i + 1);
933 priv->kill_prefix = true;
934 }
935 }
936 else
937 {
938 if (priv->folder)
939 {
940 /* Whether we use the tracking feature of the browser depends
941 * on which sort method we chose to use. This variable is defined
942 * only to help readability of the code. */
943 bool browser_track = false;
944
945 const enum EmailSortType c_browser_sort = cs_subset_sort(NeoMutt->sub, "browser_sort");
946 switch (c_browser_sort & SORT_MASK)
947 {
951 browser_track = true;
952 break;
953 }
954
955 /* We use mutt_browser_select_dir to initialize the two
956 * variables (LastDir, LastDirBackup) at the appropriate
957 * values.
958 *
959 * We do it only when LastDir is not set (first pass there)
960 * or when CurrentFolder and LastDirBackup are not the same.
961 * This code is executed only when we list files, not when
962 * we press up/down keys to navigate in a displayed list.
963 *
964 * We only do this when CurrentFolder has been set (ie, not
965 * when listing folders on startup with "neomutt -y").
966 *
967 * This tracker is only used when browser_track is true,
968 * meaning only with sort methods SUBJECT/DESC for now. */
969 if (CurrentFolder)
970 {
971 if (buf_is_empty(&mod_data->last_dir))
972 {
973 /* If browsing in "local"-mode, than we chose to define LastDir to
974 * MailDir */
976 {
977 case MUTT_IMAP:
978 case MUTT_MAILDIR:
979 case MUTT_MBOX:
980 case MUTT_MH:
981 case MUTT_MMDF:
982 {
983 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
984 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
985 if (c_folder)
986 buf_strcpy(&mod_data->last_dir, c_folder);
987 else if (c_spool_file)
988 mutt_browser_select_dir(c_spool_file);
989 break;
990 }
991 default:
993 break;
994 }
995 }
997 {
999 }
1000 }
1001
1002 /* When browser tracking feature is disabled, clear LastDirBackup */
1003 if (!browser_track)
1004 buf_reset(&mod_data->last_dir_backup);
1005 }
1006 else
1007 {
1008 mutt_path_getcwd(&mod_data->last_dir);
1009 }
1010
1011 if (!priv->state.is_mailbox_list &&
1012 (imap_path_probe(buf_string(&mod_data->last_dir), NULL) == MUTT_IMAP))
1013 {
1014 init_state(&priv->state);
1015 priv->state.imap_browse = true;
1016 imap_browse(buf_string(&mod_data->last_dir), &priv->state);
1017 browser_sort(&priv->state);
1018 }
1019 else
1020 {
1021 size_t i = buf_len(&mod_data->last_dir);
1022 while ((i > 0) && (buf_string(&mod_data->last_dir)[--i] == '/'))
1023 mod_data->last_dir.data[i] = '\0';
1024 buf_fix_dptr(&mod_data->last_dir);
1025 if (buf_is_empty(&mod_data->last_dir))
1026 mutt_path_getcwd(&mod_data->last_dir);
1027 }
1028 }
1029
1030 buf_reset(file);
1031
1032 const struct Mapping *help_data = NULL;
1033
1034 if (OptNews)
1035 help_data = FolderNewsHelp;
1036 else
1037 help_data = FolderHelp;
1038
1039 struct SimpleDialogWindows sdw = simple_dialog_new(mod_data->menu_browser,
1040 WT_DLG_BROWSER, help_data);
1041
1042 struct Menu *menu = sdw.menu;
1044 menu->search = select_file_search;
1045 menu->mdata = priv;
1046
1047 priv->menu = menu;
1048 /* Enable tagging for file selection (multiple) and mailbox/newsgroup lists */
1049 if (priv->multiple || priv->state.is_mailbox_list)
1050 priv->menu->tag = file_tag;
1051
1052 priv->sbar = sdw.sbar;
1053
1054 struct MuttWindow *win_menu = priv->menu->win;
1055
1056 // NT_COLOR is handled by the SimpleDialog
1060
1061 struct MuttWindow *old_focus = window_set_focus(priv->menu->win);
1062
1063 if (priv->state.is_mailbox_list)
1064 {
1065 examine_mailboxes(m, NULL, &priv->state);
1066 }
1067 else if (!priv->state.imap_browse)
1068 {
1069 // examine_directory() calls browser_add_folder() which needs the menu
1070 if (examine_directory(m, priv->menu, &priv->state, buf_string(&mod_data->last_dir),
1071 buf_string(priv->prefix)) == -1)
1072 {
1073 goto bail;
1074 }
1075 }
1076
1077 init_menu(&priv->state, priv->menu, m, priv->sbar);
1078
1079 // ---------------------------------------------------------------------------
1080 // Event Loop
1081 int op = OP_NULL;
1082 struct KeyEvent event = { 0, OP_NULL };
1083 do
1084 {
1085 menu_tagging_dispatcher(priv->menu->win, &event);
1086 window_redraw(NULL);
1087
1088 event = km_dokey(mod_data->menu_browser, GETCH_NONE);
1089 op = event.op;
1090 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
1091 if (op < 0)
1092 continue;
1093 if (op == OP_NULL)
1094 {
1095 km_error_key(mod_data->menu_browser);
1096 continue;
1097 }
1099
1100 int rc = browser_function_dispatcher(sdw.dlg, &event);
1101
1102 if (rc == FR_UNKNOWN)
1103 rc = menu_function_dispatcher(menu->win, &event);
1104 if (rc == FR_UNKNOWN)
1105 rc = global_function_dispatcher(menu->win, &event);
1106 } while (!priv->done);
1107 // ---------------------------------------------------------------------------
1108
1109bail:
1110 window_set_focus(old_focus);
1111 simple_dialog_free(&sdw.dlg);
1113}
#define ARRAY_FIRST(head)
Convenience method to get the first element.
Definition array.h:136
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition array.h:157
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
#define ARRAY_EMPTY(head)
Check if an array is empty.
Definition array.h:74
#define ARRAY_SIZE(head)
The number of elements stored.
Definition array.h:87
#define ARRAY_RESERVE(head, n)
Reserve memory for the array.
Definition array.h:191
#define ARRAY_FREE(head)
Release all memory.
Definition array.h:209
#define ARRAY_INIT(head)
Initialize an array.
Definition array.h:65
#define ARRAY_GET(head, idx)
Return the element at index.
Definition array.h:109
int imap_browse(const char *path, struct BrowserState *state)
IMAP hook into the folder browser.
Definition browse.c:196
const struct ExpandoRenderCallback FolderRenderCallbacks[]
Callbacks for Browser Expandos.
Definition expando.c:478
Browser Expando definitions.
int browser_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Browser function.
Definition functions.c:1441
Browser functions.
Select a Mailbox from a list.
void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition sort.c:186
@ MUTT_SEL_MAILBOX
Select a mailbox.
Definition lib.h:60
@ MUTT_SEL_MULTI
Multi-selection is enabled.
Definition lib.h:61
@ MUTT_SEL_FOLDER
Select a local directory.
Definition lib.h:62
uint8_t SelectFileFlags
Definition lib.h:64
Browser private Module data.
struct BrowserPrivateData * browser_private_data_new(void)
Create new Browser Data.
Private state data for the Browser.
Browser sorting functions.
@ BROWSER_SORT_ALPHA
Sort by name.
Definition sort.h:31
@ BROWSER_SORT_UNSORTED
Sort into the raw order.
Definition sort.h:37
@ BROWSER_SORT_DESC
Sort by description.
Definition sort.h:34
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition buffer.c:168
size_t buf_addstr_n(struct Buffer *buf, const char *s, size_t len)
Add a string to a Buffer, expanding it if necessary.
Definition buffer.c:109
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition buffer.c:497
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:89
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:298
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition buffer.c:189
size_t buf_strcpy_n(struct Buffer *buf, const char *s, size_t len)
Copy a string into a Buffer.
Definition buffer.c:422
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition buffer.c:248
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition buffer.c:607
size_t buf_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition buffer.c:515
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
const struct Regex * cs_subset_regex(const struct ConfigSubset *sub, const char *name)
Get a regex config item by name.
Definition helpers.c:217
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
short cs_subset_sort(const struct ConfigSubset *sub, const char *name)
Get a sort config item by name.
Definition helpers.c:266
const struct Expando * cs_subset_expando(const struct ConfigSubset *sub, const char *name)
Get an Expando config item by name.
Convenience wrapper for the config headers.
#define SORT_MASK
Mask for the sort id.
Definition sort.h:39
Connection Library.
Convenience wrapper for the core headers.
@ NT_MAILBOX_DELETE
Mailbox is about to be deleted.
Definition mailbox.h:176
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition mailbox.h:216
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition mailbox.h:50
@ MUTT_MMDF
'mmdf' Mailbox type
Definition mailbox.h:45
@ MUTT_POP
'POP3' Mailbox type
Definition mailbox.h:51
@ MUTT_MH
'MH' Mailbox type
Definition mailbox.h:46
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition mailbox.h:48
@ MUTT_IMAP
'IMAP' Mailbox type
Definition mailbox.h:49
@ MUTT_MBOX
'mbox' Mailbox type
Definition mailbox.h:44
@ MUTT_MAILBOX_ANY
Match any Mailbox type.
Definition mailbox.h:41
@ MUTT_MAILDIR
'Maildir' Mailbox type
Definition mailbox.h:47
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition curs_lib.c:445
@ FR_UNKNOWN
Unknown function.
Definition dispatcher.h:34
int examine_directory(struct Mailbox *m, struct Menu *menu, struct BrowserState *state, const char *dirname, const char *prefix)
Get list of all files/newsgroups with mask.
void init_menu(struct BrowserState *state, struct Menu *menu, struct Mailbox *m, struct MuttWindow *sbar)
Set up a new menu.
static const struct Mapping FolderNewsHelp[]
Help Bar for the NNTP Mailbox browser dialog.
void mutt_browser_select_dir(const char *f)
Remember the last directory selected.
void init_state(struct BrowserState *state)
Initialise a browser state.
static const struct Mapping FolderHelp[]
Help Bar for the File/Dir/Mailbox browser dialog.
void browser_add_folder(const struct Menu *menu, struct BrowserState *state, const char *name, const char *desc, const struct stat *st, struct Mailbox *m, void *data)
Add a folder to the browser list.
void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
int examine_mailboxes(struct Mailbox *m, struct Menu *menu, struct BrowserState *state)
Get list of mailboxes/subscribed newsgroups.
bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Structs that make up an email.
EmailSortType
Methods for sorting Emails.
Definition sort.h:53
int expando_filter(const struct Expando *exp, const struct ExpandoRenderCallback *erc, void *data, MuttFormatFlags flags, int max_cols, char **env_list, struct Buffer *buf)
Render an Expando and run the result through a filter.
Definition filter.c:139
Parse Expando string.
const struct ExpandoRenderCallback GroupIndexRenderCallbacks[]
Callbacks for Nntp Browser Expandos.
DIR * mutt_file_opendir(const char *path, enum MuttOpenDirMode mode)
Open a directory.
Definition file.c:535
@ MUTT_OPENDIR_NONE
Plain opendir()
Definition file.h:68
struct KeyEvent km_dokey(const struct MenuDefinition *md, GetChFlags flags)
Determine what a keypress should do.
Definition get.c:518
void km_error_key(const struct MenuDefinition *md)
Handle an unbound key sequence.
Definition get.c:328
@ GETCH_NONE
No flags are set.
Definition get.h:38
bool OptNews
(pseudo) used to change reader mode
Definition globals.c:53
char * CurrentFolder
Currently selected mailbox.
Definition globals.c:38
Global variables.
int menu_tagging_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform tagging operations on the Menu - Implements function_dispatcher_t -.
Definition tagging.c:239
int global_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Global function - Implements function_dispatcher_t -.
Definition global.c:182
int menu_function_dispatcher(struct MuttWindow *win, const struct KeyEvent *event)
Perform a Menu function - Implements function_dispatcher_t -.
Definition functions.c:366
void dlg_browser(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
Let the user select a file -.
#define mutt_error(...)
Definition logging2.h:94
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
#define mutt_perror(...)
Definition logging2.h:95
static int folder_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Format a Folder for the Menu - Implements Menu::make_entry() -.
static int select_file_search(struct Menu *menu, regex_t *rx, int line)
Menu search callback for matching files - Implements Menu::search() -.
static int file_tag(struct Menu *menu, int sel, int act)
Tag an entry in the menu - Implements Menu::tag() -.
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox?
Definition imap.c:2681
static int browser_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
static int browser_mailbox_observer(struct NotifyCallback *nc)
Notification that a Mailbox has changed - Implements observer_t -.
static int browser_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
void browser_private_data_free(struct BrowserPrivateData **ptr)
Free Private Browser Data - Implements MuttWindow::wdata_free() -.
Convenience wrapper for the gui headers.
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition simple.c:169
struct SimpleDialogWindows simple_dialog_new(const struct MenuDefinition *md, enum WindowType wtype, const struct Mapping *help_data)
Create a simple index Dialog.
Definition simple.c:132
IMAP network mailbox.
void imap_clean_path(char *path, size_t plen)
Cleans an IMAP path using imap_fix_path.
Definition util.c:195
Manage keymappings.
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
@ LL_DEBUG1
Log at debug level 1.
Definition logging2.h:45
GUI present the user with a selectable list.
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition menu.c:177
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition menu.c:153
@ MENU_REDRAW_FULL
Redraw everything.
Definition lib.h:64
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition menu.c:167
@ MODULE_ID_BROWSER
ModuleBrowser, Mailbox Browser
Definition module_api.h:52
@ MODULE_ID_NNTP
ModuleNntp, Nntp
Definition module_api.h:83
Convenience wrapper for the library headers.
#define N_(a)
Definition message.h:32
#define _(a)
Definition message.h:28
bool notify_observer_remove(struct Notify *notify, const observer_t callback, const void *global_data)
Remove an observer from an object.
Definition notify.c:230
bool notify_observer_add(struct Notify *notify, enum NotifyType type, observer_t callback, void *global_data)
Add an observer to an object.
Definition notify.c:191
const char * mutt_path_getcwd(struct Buffer *cwd)
Get the current working directory.
Definition path.c:476
bool mutt_regex_match(const struct Regex *regex, const char *str)
Shorthand to mutt_regex_capture()
Definition regex.c:614
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition string.c:234
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition string.c:586
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:284
#define PATH_MAX
Definition mutt.h:49
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
NeoMutt Logging.
int mutt_mailbox_check(struct Mailbox *m_cur, CheckStatsFlags flags)
Check all all Mailboxes for new mail.
Mailbox helper functions.
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
@ WT_DLG_BROWSER
Browser Dialog, dlg_browser()
Definition mutt_window.h:80
@ NT_WINDOW_DELETE
Window is about to be deleted.
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition muttlib.c:867
void pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition muttlib.c:428
void expand_path(struct Buffer *buf, bool regex)
Create the canonical path.
Definition muttlib.c:122
Some miscellaneous functions.
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition mx.c:1324
API for mailboxes.
@ MUTT_MAILBOX_CHECK_NONE
No flags are set.
Definition mxapi.h:58
struct MailboxArray neomutt_mailboxes_get(struct NeoMutt *n, enum MailboxType type)
Get an Array of matching Mailboxes.
Definition neomutt.c:607
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
Nntp-specific Account data.
Usenet network mailbox type; talk to an NNTP server.
Nntp-specific Mailbox data.
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition notify_type.h:58
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition notify_type.h:43
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition notify_type.h:50
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition opcodes.c:48
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
@ MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition render.h:41
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition sbar.c:227
#define ASSERT(COND)
Definition signal2.h:59
#define NONULL(x)
Definition string2.h:44
void * adata
Private data (for Mailbox backends)
Definition account.h:42
Browser private Module data.
Definition module_data.h:32
struct MenuDefinition * menu_browser
Browser menu definition.
Definition module_data.h:34
struct Buffer last_dir
Browser: previous selected directory.
Definition module_data.h:35
struct Buffer last_dir_backup
Browser: backup copy of the current directory.
Definition module_data.h:36
Private state data for the Browser.
char *** files
Array of selected files.
struct Menu * menu
Menu.
struct Buffer * prefix
Folder prefix string.
bool kill_prefix
Prefix is in use.
bool done
Should we close the Dialog?
bool folder
Select folders.
int last_selected_mailbox
Index of last selected Mailbox.
int * numfiles
Number of selected files.
struct Mailbox * mailbox
Mailbox.
struct BrowserState state
State containing list of files/dir/mailboxes.
struct Buffer * file
Buffer for the result.
bool multiple
Allow multiple selections.
struct MuttWindow * sbar
Status Bar.
State of the file/mailbox browser.
Definition lib.h:148
char * folder
Folder name.
Definition lib.h:151
bool is_mailbox_list
Viewing mailboxes.
Definition lib.h:152
struct BrowserEntryArray entry
Array of files / dirs / mailboxes.
Definition lib.h:149
bool imap_browse
IMAP folder.
Definition lib.h:150
String manipulation buffer.
Definition buffer.h:36
char * data
Pointer to data.
Definition buffer.h:37
struct Notify * notify
Notifications: NotifyConfig, EventConfig.
Definition subset.h:51
char host[128]
Server to login to.
Definition connaccount.h:60
struct ConnAccount account
Account details: username, password, etc.
Definition connection.h:49
A config-change event.
Definition subset.h:70
const char * name
Name of config item that changed.
Definition subset.h:72
An Event that happened to a Mailbox.
Definition mailbox.h:192
struct Mailbox * mailbox
The Mailbox this Event relates to.
Definition mailbox.h:193
An Event that happened to a Window.
struct MuttWindow * win
Window that changed.
Parsed Expando trees.
Definition expando.h:41
Browser entry representing a folder/dir.
Definition lib.h:82
bool imap
This is an IMAP folder.
Definition lib.h:99
bool has_mailbox
This is a mailbox.
Definition lib.h:102
char * name
Name of file/dir/mailbox.
Definition lib.h:90
uid_t uid
File's User ID.
Definition lib.h:86
bool tagged
Folder is tagged.
Definition lib.h:106
gid_t gid
File's Group ID.
Definition lib.h:87
bool has_new_mail
true if mailbox has "new mail"
Definition lib.h:93
bool poll_new_mail
Check mailbox for new mail.
Definition lib.h:105
bool notify_user
User will be notified of new mail.
Definition lib.h:104
nlink_t nlink
Number of hard links.
Definition lib.h:88
char * desc
Description of mailbox.
Definition lib.h:91
struct NntpMboxData * nd
Extra NNTP data.
Definition lib.h:107
off_t size
File size.
Definition lib.h:84
int gen
Unique id, used for (un)sorting.
Definition lib.h:109
bool local
Folder is on local filesystem.
Definition lib.h:103
time_t mtime
Modification time.
Definition lib.h:85
int msg_count
total number of messages
Definition lib.h:94
mode_t mode
File permissions.
Definition lib.h:83
int msg_unread
number of unread messages
Definition lib.h:95
A folder/dir in the browser.
Definition lib.h:73
An event such as a keypress.
Definition get.h:75
int op
Function opcode, e.g. OP_HELP.
Definition get.h:77
A mailbox.
Definition mailbox.h:81
bool has_new
Mailbox has new mail.
Definition mailbox.h:87
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition mailbox.h:83
int msg_count
Total number of messages.
Definition mailbox.h:90
enum MailboxType type
Mailbox type.
Definition mailbox.h:104
bool poll_new_mail
Check for new mail.
Definition mailbox.h:117
void * mdata
Driver specific data.
Definition mailbox.h:134
char * name
A short name for the Mailbox.
Definition mailbox.h:84
bool notify_user
Notify the user of new mail.
Definition mailbox.h:115
bool visible
True if a result of "mailboxes".
Definition mailbox.h:132
int msg_unread
Number of unread messages.
Definition mailbox.h:91
int gen
Generation number, for sorting.
Definition mailbox.h:149
Mapping between user-readable string and a constant.
Definition mapping.h:33
Definition lib.h:86
struct MuttWindow * win
Window holding the Menu.
Definition lib.h:94
int num_tagged
Number of tagged entries.
Definition lib.h:101
int(* search)(struct Menu *menu, regex_t *rx, int line)
Definition lib.h:127
int top
Entry that is the top of the current page.
Definition lib.h:98
int(* tag)(struct Menu *menu, int sel, int act)
Definition lib.h:139
int(* make_entry)(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Definition lib.h:114
struct ConfigSubset * sub
Inherited config items.
Definition lib.h:95
void * mdata
Private data.
Definition lib.h:155
int max
Number of entries in the menu.
Definition lib.h:88
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Container for Accounts, Notifications.
Definition neomutt.h:41
struct AccountArray accounts
All Accounts.
Definition neomutt.h:50
char ** env
Private copy of the environment variables.
Definition neomutt.h:57
struct Notify * notify
Notifications handler.
Definition neomutt.h:45
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
NNTP-specific Account data -.
Definition adata.h:36
struct NntpMboxData ** groups_list
List of newsgroups.
Definition adata.h:60
struct Connection * conn
Connection to NNTP Server.
Definition adata.h:63
unsigned int groups_num
Number of newsgroups.
Definition adata.h:58
NNTP-specific Mailbox data -.
Definition mdata.h:34
struct NntpAccountData * adata
Account data.
Definition mdata.h:48
Nntp private Module data.
Definition module_data.h:30
struct NntpAccountData * current_news_srv
Current NNTP news server.
Definition module_data.h:32
Data passed to a notification function.
Definition observer.h:34
void * event_data
Data from notify_send()
Definition observer.h:38
enum NotifyType event_type
Send: Event type, e.g. NT_ACCOUNT.
Definition observer.h:36
int event_subtype
Send: Event subtype, e.g. NT_ACCOUNT_ADD.
Definition observer.h:37
void * global_data
Data from notify_observer_add()
Definition observer.h:39
Cached regular expression.
Definition regex3.h:85
char * pattern
printable version
Definition regex3.h:86
Tuple for the results of simple_dialog_new()
Definition simple.h:35
struct MuttWindow * sbar
Simple Bar.
Definition simple.h:37
struct Menu * menu
Menu.
Definition simple.h:38
struct MuttWindow * dlg
Main Dialog Window.
Definition simple.h:36