NeoMutt  2024-12-12-19-ge4b57e
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
dlg_browser.c
Go to the documentation of this file.
1
76#include "config.h"
77#include <dirent.h>
78#include <errno.h>
79#include <limits.h>
80#include <locale.h>
81#include <stdbool.h>
82#include <stdio.h>
83#include <string.h>
84#include <sys/stat.h>
85#include "mutt/lib.h"
86#include "config/lib.h"
87#include "email/lib.h"
88#include "core/lib.h"
89#include "conn/lib.h"
90#include "gui/lib.h"
91#include "lib.h"
92#include "expando/lib.h"
93#include "imap/lib.h"
94#include "key/lib.h"
95#include "menu/lib.h"
96#include "nntp/lib.h"
97#include "expando.h"
98#include "functions.h"
99#include "globals.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
136struct Buffer LastDir = { 0 };
138struct Buffer LastDirBackup = { 0 };
139
145static void init_lastdir(void)
146{
147 static bool done = false;
148 if (!done)
149 {
152 done = true;
153 }
154}
155
160{
163}
164
172bool link_is_dir(const char *folder, const char *path)
173{
174 struct stat st = { 0 };
175 bool rc = false;
176
177 struct Buffer *fullpath = buf_pool_get();
178 buf_concat_path(fullpath, folder, path);
179
180 if (stat(buf_string(fullpath), &st) == 0)
181 rc = S_ISDIR(st.st_mode);
182
183 buf_pool_release(&fullpath);
184
185 return rc;
186}
187
198void browser_add_folder(const struct Menu *menu, struct BrowserState *state,
199 const char *name, const char *desc,
200 const struct stat *st, struct Mailbox *m, void *data)
201{
202 if ((!menu || state->is_mailbox_list) && m && !m->visible)
203 {
204 return;
205 }
206
207 struct FolderFile ff = { 0 };
208
209 if (st)
210 {
211 ff.mode = st->st_mode;
212 ff.mtime = st->st_mtime;
213 ff.size = st->st_size;
214 ff.gid = st->st_gid;
215 ff.uid = st->st_uid;
216 ff.nlink = st->st_nlink;
217 ff.local = true;
218 }
219 else
220 {
221 ff.local = false;
222 }
223
224 if (m)
225 {
226 ff.has_mailbox = true;
227 ff.gen = m->gen;
228 ff.has_new_mail = m->has_new;
229 ff.msg_count = m->msg_count;
230 ff.msg_unread = m->msg_unread;
231 ff.notify_user = m->notify_user;
233 }
234
235 ff.name = mutt_str_dup(name);
236 ff.desc = mutt_str_dup(desc ? desc : name);
237 ff.imap = false;
238 if (OptNews)
239 ff.nd = data;
240
241 ARRAY_ADD(&state->entry, ff);
242}
243
248void init_state(struct BrowserState *state)
249{
250 ARRAY_INIT(&state->entry);
251 ARRAY_RESERVE(&state->entry, 256);
252 state->imap_browse = false;
253}
254
265int examine_directory(struct Mailbox *m, struct Menu *menu, struct BrowserState *state,
266 const char *dirname, const char *prefix)
267{
268 int rc = -1;
269 struct Buffer *buf = buf_pool_get();
270 if (OptNews)
271 {
273
274 init_state(state);
275
276 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
277 for (unsigned int i = 0; i < adata->groups_num; i++)
278 {
279 struct NntpMboxData *mdata = adata->groups_list[i];
280 if (!mdata)
281 continue;
282 if (prefix && *prefix && !mutt_str_startswith(mdata->group, prefix))
283 continue;
284 if (!mutt_regex_match(c_mask, mdata->group))
285 {
286 continue;
287 }
288 browser_add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
289 }
290 }
291 else
292 {
293 struct stat st = { 0 };
294 DIR *dir = NULL;
295 struct dirent *de = NULL;
296
297 while (stat(dirname, &st) == -1)
298 {
299 if (errno == ENOENT)
300 {
301 /* The last used directory is deleted, try to use the parent dir. */
302 char *c = strrchr(dirname, '/');
303
304 if (c && (c > dirname))
305 {
306 *c = '\0';
307 continue;
308 }
309 }
310 mutt_perror("%s", dirname);
311 goto ed_out;
312 }
313
314 if (!S_ISDIR(st.st_mode))
315 {
316 mutt_error(_("%s is not a directory"), dirname);
317 goto ed_out;
318 }
319
320 if (m)
322
323 dir = mutt_file_opendir(dirname, MUTT_OPENDIR_NONE);
324 if (!dir)
325 {
326 mutt_perror("%s", dirname);
327 goto ed_out;
328 }
329
330 init_state(state);
331
332 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
334
335 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
336 while ((de = readdir(dir)))
337 {
338 if (mutt_str_equal(de->d_name, "."))
339 continue; /* we don't need . */
340
341 if (prefix && *prefix && !mutt_str_startswith(de->d_name, prefix))
342 {
343 continue;
344 }
345 if (!mutt_regex_match(c_mask, de->d_name))
346 {
347 continue;
348 }
349
350 buf_concat_path(buf, dirname, de->d_name);
351 if (lstat(buf_string(buf), &st) == -1)
352 continue;
353
354 /* No size for directories or symlinks */
355 if (S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))
356 st.st_size = 0;
357 else if (!S_ISREG(st.st_mode))
358 continue;
359
360 struct MailboxNode *np = NULL;
361 STAILQ_FOREACH(np, &ml, entries)
362 {
364 break;
365 }
366
367 if (np && m && m->poll_new_mail && mutt_str_equal(np->mailbox->realpath, m->realpath))
368 {
369 np->mailbox->msg_count = m->msg_count;
370 np->mailbox->msg_unread = m->msg_unread;
371 }
372 browser_add_folder(menu, state, de->d_name, NULL, &st, np ? np->mailbox : NULL, NULL);
373 }
375 closedir(dir);
376 }
377 browser_sort(state);
378 rc = 0;
379ed_out:
380 buf_pool_release(&buf);
381 return rc;
382}
383
392int examine_mailboxes(struct Mailbox *m, struct Menu *menu, struct BrowserState *state)
393{
394 struct stat st = { 0 };
395 struct Buffer *md = NULL;
396 struct Buffer *mailbox = NULL;
397
398 if (OptNews)
399 {
401
402 init_state(state);
403
404 const bool c_show_only_unread = cs_subset_bool(NeoMutt->sub, "show_only_unread");
405 for (unsigned int i = 0; i < adata->groups_num; i++)
406 {
407 struct NntpMboxData *mdata = adata->groups_list[i];
408 if (mdata && (mdata->has_new_mail ||
409 (mdata->subscribed && (mdata->unread || !c_show_only_unread))))
410 {
411 browser_add_folder(menu, state, mdata->group, NULL, NULL, NULL, mdata);
412 }
413 }
414 }
415 else
416 {
417 init_state(state);
418
420 return -1;
421 mailbox = buf_pool_get();
422 md = buf_pool_get();
423
425
426 struct MailboxList ml = STAILQ_HEAD_INITIALIZER(ml);
428 struct MailboxNode *np = NULL;
429 const bool c_browser_abbreviate_mailboxes = cs_subset_bool(NeoMutt->sub, "browser_abbreviate_mailboxes");
430
431 STAILQ_FOREACH(np, &ml, entries)
432 {
433 if (!np->mailbox)
434 continue;
435
436 if (m && m->poll_new_mail && mutt_str_equal(np->mailbox->realpath, m->realpath))
437 {
438 np->mailbox->msg_count = m->msg_count;
439 np->mailbox->msg_unread = m->msg_unread;
440 }
441
443 if (c_browser_abbreviate_mailboxes)
445
446 switch (np->mailbox->type)
447 {
448 case MUTT_IMAP:
449 case MUTT_POP:
451 np->mailbox->name, NULL, np->mailbox, NULL);
452 continue;
453 case MUTT_NOTMUCH:
454 case MUTT_NNTP:
455 browser_add_folder(menu, state, mailbox_path(np->mailbox),
456 np->mailbox->name, NULL, np->mailbox, NULL);
457 continue;
458 default: /* Continue */
459 break;
460 }
461
462 if (lstat(mailbox_path(np->mailbox), &st) == -1)
463 continue;
464
465 if ((!S_ISREG(st.st_mode)) && (!S_ISDIR(st.st_mode)) && (!S_ISLNK(st.st_mode)))
466 continue;
467
468 if (np->mailbox->type == MUTT_MAILDIR)
469 {
470 struct stat st2 = { 0 };
471
472 buf_printf(md, "%s/new", mailbox_path(np->mailbox));
473 if (stat(buf_string(md), &st) < 0)
474 st.st_mtime = 0;
475 buf_printf(md, "%s/cur", mailbox_path(np->mailbox));
476 if (stat(buf_string(md), &st2) < 0)
477 st2.st_mtime = 0;
478 if (st2.st_mtime > st.st_mtime)
479 st.st_mtime = st2.st_mtime;
480 }
481
482 browser_add_folder(menu, state, buf_string(mailbox), np->mailbox->name,
483 &st, np->mailbox, NULL);
484 }
486 }
487 browser_sort(state);
488
489 buf_pool_release(&mailbox);
490 buf_pool_release(&md);
491 return 0;
492}
493
497static int select_file_search(struct Menu *menu, regex_t *rx, int line)
498{
499 struct BrowserPrivateData *priv = menu->mdata;
500 struct BrowserEntryArray *entry = &priv->state.entry;
501 if (OptNews)
502 return regexec(rx, ARRAY_GET(entry, line)->desc, 0, NULL, 0);
503 struct FolderFile *ff = ARRAY_GET(entry, line);
504 char *search_on = ff->desc ? ff->desc : ff->name;
505
506 return regexec(rx, search_on, 0, NULL, 0);
507}
508
514static int folder_make_entry(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
515{
516 struct BrowserPrivateData *priv = menu->mdata;
517 struct BrowserState *bstate = &priv->state;
518 struct BrowserEntryArray *entry = &bstate->entry;
519 struct Folder folder = {
520 .ff = ARRAY_GET(entry, line),
521 .num = line,
522 };
523
524 const bool c_arrow_cursor = cs_subset_bool(menu->sub, "arrow_cursor");
525 if (c_arrow_cursor)
526 {
527 const char *const c_arrow_string = cs_subset_string(menu->sub, "arrow_string");
528 if (max_cols > 0)
529 max_cols -= (mutt_strwidth(c_arrow_string) + 1);
530 }
531
532 if (OptNews)
533 {
534 const struct Expando *c_group_index_format = cs_subset_expando(NeoMutt->sub, "group_index_format");
535 return expando_filter(c_group_index_format, GroupIndexRenderCallbacks,
536 &folder, MUTT_FORMAT_ARROWCURSOR, max_cols, buf);
537 }
538
539 if (bstate->is_mailbox_list)
540 {
541 const struct Expando *c_mailbox_folder_format = cs_subset_expando(NeoMutt->sub, "mailbox_folder_format");
542 return expando_filter(c_mailbox_folder_format, FolderRenderCallbacks,
543 &folder, MUTT_FORMAT_ARROWCURSOR, max_cols, buf);
544 }
545
546 const struct Expando *c_folder_format = cs_subset_expando(NeoMutt->sub, "folder_format");
547 return expando_filter(c_folder_format, FolderRenderCallbacks, &folder,
548 MUTT_FORMAT_ARROWCURSOR, max_cols, buf);
549}
550
559void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
560{
561 menu->top = 0;
562 /* Reset menu position to 1.
563 * We do not risk overflow as the init_menu function changes
564 * current if it is bigger than state->entrylen. */
565 if (!ARRAY_EMPTY(&state->entry) &&
566 (mutt_str_equal(ARRAY_FIRST(&state->entry)->desc, "..") ||
567 mutt_str_equal(ARRAY_FIRST(&state->entry)->desc, "../")))
568 {
569 /* Skip the first entry, unless there's only one entry. */
570 menu_set_index(menu, (menu->max > 1));
571 }
572 else
573 {
574 menu_set_index(menu, 0);
575 }
576}
577
585void init_menu(struct BrowserState *state, struct Menu *menu, struct Mailbox *m,
586 struct MuttWindow *sbar)
587{
588 char title[256] = { 0 };
589 menu->max = ARRAY_SIZE(&state->entry);
590
591 int index = menu_get_index(menu);
592 if (index >= menu->max)
593 menu_set_index(menu, menu->max - 1);
594 if (index < 0)
595 menu_set_index(menu, 0);
596 if (menu->top > index)
597 menu->top = 0;
598
599 menu->num_tagged = 0;
600
601 if (OptNews)
602 {
603 if (state->is_mailbox_list)
604 {
605 snprintf(title, sizeof(title), _("Subscribed newsgroups"));
606 }
607 else
608 {
609 snprintf(title, sizeof(title), _("Newsgroups on server [%s]"),
611 }
612 }
613 else
614 {
615 if (state->is_mailbox_list)
616 {
617 snprintf(title, sizeof(title), _("Mailboxes [%d]"),
619 }
620 else
621 {
622 struct Buffer *path = buf_pool_get();
623 buf_copy(path, &LastDir);
624 buf_pretty_mailbox(path);
625 const struct Regex *c_mask = cs_subset_regex(NeoMutt->sub, "mask");
626 const bool c_imap_list_subscribed = cs_subset_bool(NeoMutt->sub, "imap_list_subscribed");
627 if (state->imap_browse && c_imap_list_subscribed)
628 {
629 snprintf(title, sizeof(title), _("Subscribed [%s], File mask: %s"),
630 buf_string(path), NONULL(c_mask ? c_mask->pattern : NULL));
631 }
632 else
633 {
634 snprintf(title, sizeof(title), _("Directory [%s], File mask: %s"),
635 buf_string(path), NONULL(c_mask ? c_mask->pattern : NULL));
636 }
637 buf_pool_release(&path);
638 }
639 }
640 sbar_set_title(sbar, title);
641
642 /* Browser tracking feature.
643 * The goal is to highlight the good directory if LastDir is the parent dir
644 * of LastDirBackup (this occurs mostly when one hit "../"). It should also work
645 * properly when the user is in examine_mailboxes-mode. */
647 {
648 char target_dir[PATH_MAX] = { 0 };
649
650 /* Check what kind of dir LastDirBackup is. */
652 {
653 mutt_str_copy(target_dir, buf_string(&LastDirBackup), sizeof(target_dir));
654 imap_clean_path(target_dir, sizeof(target_dir));
655 }
656 else
657 {
658 mutt_str_copy(target_dir, strrchr(buf_string(&LastDirBackup), '/') + 1,
659 sizeof(target_dir));
660 }
661
662 /* If we get here, it means that LastDir is the parent directory of
663 * LastDirBackup. I.e., we're returning from a subdirectory, and we want
664 * to position the cursor on the directory we're returning from. */
665 bool matched = false;
666 struct FolderFile *ff = NULL;
667 ARRAY_FOREACH(ff, &state->entry)
668 {
669 if (mutt_str_equal(ff->name, target_dir))
670 {
671 menu_set_index(menu, ARRAY_FOREACH_IDX);
672 matched = true;
673 break;
674 }
675 }
676 if (!matched)
677 browser_highlight_default(state, menu);
678 }
679 else
680 {
681 browser_highlight_default(state, menu);
682 }
683
685}
686
690static int file_tag(struct Menu *menu, int sel, int act)
691{
692 struct BrowserPrivateData *priv = menu->mdata;
693 struct BrowserEntryArray *entry = &priv->state.entry;
694 struct FolderFile *ff = ARRAY_GET(entry, sel);
695 if (S_ISDIR(ff->mode) ||
696 (S_ISLNK(ff->mode) && link_is_dir(buf_string(&LastDir), ff->name)))
697 {
698 mutt_error(_("Can't attach a directory"));
699 return 0;
700 }
701
702 bool ot = ff->tagged;
703 ff->tagged = ((act >= 0) ? act : !ff->tagged);
704
705 return ff->tagged - ot;
706}
707
712{
713 if (nc->event_type != NT_CONFIG)
714 return 0;
715 if (!nc->global_data || !nc->event_data)
716 return -1;
717
718 struct EventConfig *ev_c = nc->event_data;
719
720 struct BrowserPrivateData *priv = nc->global_data;
721 struct Menu *menu = priv->menu;
722
723 if (mutt_str_equal(ev_c->name, "browser_sort_dirs_first"))
724 {
725 struct BrowserState *state = &priv->state;
726 browser_sort(state);
727 browser_highlight_default(state, menu);
728 }
729 else if (!mutt_str_equal(ev_c->name, "browser_abbreviate_mailboxes") &&
730 !mutt_str_equal(ev_c->name, "browser_sort") &&
731 !mutt_str_equal(ev_c->name, "date_format") &&
732 !mutt_str_equal(ev_c->name, "folder") &&
733 !mutt_str_equal(ev_c->name, "folder_format") &&
734 !mutt_str_equal(ev_c->name, "group_index_format") &&
735 !mutt_str_equal(ev_c->name, "mailbox_folder_format"))
736 {
737 return 0;
738 }
739
741 mutt_debug(LL_DEBUG5, "config done, request WA_RECALC, MENU_REDRAW_FULL\n");
742
743 return 0;
744}
745
752{
753 if (nc->event_type != NT_MAILBOX)
754 return 0;
756 return 0;
757 if (!nc->global_data || !nc->event_data)
758 return -1;
759
760 struct BrowserPrivateData *priv = nc->global_data;
761
762 struct BrowserState *state = &priv->state;
763 if (state->is_mailbox_list)
764 {
765 struct EventMailbox *ev_m = nc->event_data;
766 struct Mailbox *m = ev_m->mailbox;
767 struct FolderFile *ff = NULL;
768 ARRAY_FOREACH(ff, &state->entry)
769 {
770 if (ff->gen != m->gen)
771 continue;
772
773 ff->has_new_mail = m->has_new;
774 ff->msg_count = m->msg_count;
775 ff->msg_unread = m->msg_unread;
776 ff->notify_user = m->notify_user;
778 mutt_str_replace(&ff->desc, m->name);
779 break;
780 }
781 }
782
784 mutt_debug(LL_DEBUG5, "mailbox done, request WA_RECALC, MENU_REDRAW_FULL\n");
785
786 return 0;
787}
788
797{
798 if (nc->event_type != NT_WINDOW)
799 return 0;
800 if (!nc->global_data || !nc->event_data)
801 return -1;
803 return 0;
804
805 struct BrowserPrivateData *priv = nc->global_data;
806 struct MuttWindow *win_menu = priv->menu->win;
807
808 struct EventWindow *ev_w = nc->event_data;
809 if (ev_w->win != win_menu)
810 return 0;
811
815
816 mutt_debug(LL_DEBUG5, "window delete done\n");
817 return 0;
818}
819
830void mutt_browser_select_dir(const char *f)
831{
832 init_lastdir();
833
835
836 /* Method that will fetch the parent path depending on the type of the path. */
837 char buf[PATH_MAX] = { 0 };
838 mutt_get_parent_path(buf_string(&LastDirBackup), buf, sizeof(buf));
839 buf_strcpy(&LastDir, buf);
840}
841
853void dlg_browser(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m,
854 char ***files, int *numfiles)
855{
857 priv->file = file;
858 priv->mailbox = m;
859 priv->files = files;
860 priv->numfiles = numfiles;
861 priv->multiple = (flags & MUTT_SEL_MULTI);
862 priv->folder = (flags & MUTT_SEL_FOLDER);
863 priv->state.is_mailbox_list = (flags & MUTT_SEL_MAILBOX) && priv->folder;
864 priv->last_selected_mailbox = -1;
865
866 init_lastdir();
867
868 if (OptNews)
869 {
870 if (buf_is_empty(file))
871 {
873
874 /* default state for news reader mode is browse subscribed newsgroups */
875 priv->state.is_mailbox_list = false;
876 for (size_t i = 0; i < adata->groups_num; i++)
877 {
878 struct NntpMboxData *mdata = adata->groups_list[i];
879 if (mdata && mdata->subscribed)
880 {
881 priv->state.is_mailbox_list = true;
882 break;
883 }
884 }
885 }
886 else
887 {
888 buf_copy(priv->prefix, file);
889 }
890 }
891 else if (!buf_is_empty(file))
892 {
893 buf_expand_path(file);
894 if (imap_path_probe(buf_string(file), NULL) == MUTT_IMAP)
895 {
896 init_state(&priv->state);
897 priv->state.imap_browse = true;
898 if (imap_browse(buf_string(file), &priv->state) == 0)
899 {
901 browser_sort(&priv->state);
902 }
903 }
904 else
905 {
906 int i = buf_len(file);
907 i--;
908 for (; (i > 0) && ((buf_string(file))[i] != '/'); i--)
909 {
910 ; // do nothing
911 }
912
913 if (i > 0)
914 {
915 if ((buf_string(file))[0] == '/')
916 {
917 buf_strcpy_n(&LastDir, buf_string(file), i);
918 }
919 else
920 {
922 buf_addch(&LastDir, '/');
923 buf_addstr_n(&LastDir, buf_string(file), i);
924 }
925 }
926 else
927 {
928 if ((buf_string(file))[0] == '/')
929 buf_strcpy(&LastDir, "/");
930 else
932 }
933
934 if ((i <= 0) && (buf_string(file)[0] != '/'))
935 buf_copy(priv->prefix, file);
936 else
937 buf_strcpy(priv->prefix, buf_string(file) + i + 1);
938 priv->kill_prefix = true;
939 }
940 }
941 else
942 {
943 if (priv->folder)
944 {
945 /* Whether we use the tracking feature of the browser depends
946 * on which sort method we chose to use. This variable is defined
947 * only to help readability of the code. */
948 bool browser_track = false;
949
950 const enum EmailSortType c_browser_sort = cs_subset_sort(NeoMutt->sub, "browser_sort");
951 switch (c_browser_sort & SORT_MASK)
952 {
956 browser_track = true;
957 break;
958 }
959
960 /* We use mutt_browser_select_dir to initialize the two
961 * variables (LastDir, LastDirBackup) at the appropriate
962 * values.
963 *
964 * We do it only when LastDir is not set (first pass there)
965 * or when CurrentFolder and LastDirBackup are not the same.
966 * This code is executed only when we list files, not when
967 * we press up/down keys to navigate in a displayed list.
968 *
969 * We only do this when CurrentFolder has been set (ie, not
970 * when listing folders on startup with "neomutt -y").
971 *
972 * This tracker is only used when browser_track is true,
973 * meaning only with sort methods SUBJECT/DESC for now. */
974 if (CurrentFolder)
975 {
976 if (buf_is_empty(&LastDir))
977 {
978 /* If browsing in "local"-mode, than we chose to define LastDir to
979 * MailDir */
981 {
982 case MUTT_IMAP:
983 case MUTT_MAILDIR:
984 case MUTT_MBOX:
985 case MUTT_MH:
986 case MUTT_MMDF:
987 {
988 const char *const c_folder = cs_subset_string(NeoMutt->sub, "folder");
989 const char *const c_spool_file = cs_subset_string(NeoMutt->sub, "spool_file");
990 if (c_folder)
991 buf_strcpy(&LastDir, c_folder);
992 else if (c_spool_file)
993 mutt_browser_select_dir(c_spool_file);
994 break;
995 }
996 default:
998 break;
999 }
1000 }
1002 {
1004 }
1005 }
1006
1007 /* When browser tracking feature is disabled, clear LastDirBackup */
1008 if (!browser_track)
1010 }
1011 else
1012 {
1014 }
1015
1016 if (!priv->state.is_mailbox_list &&
1018 {
1019 init_state(&priv->state);
1020 priv->state.imap_browse = true;
1022 browser_sort(&priv->state);
1023 }
1024 else
1025 {
1026 size_t i = buf_len(&LastDir);
1027 while ((i > 0) && (buf_string(&LastDir)[--i] == '/'))
1028 LastDir.data[i] = '\0';
1030 if (buf_is_empty(&LastDir))
1032 }
1033 }
1034
1035 buf_reset(file);
1036
1037 const struct Mapping *help_data = NULL;
1038
1039 if (OptNews)
1040 help_data = FolderNewsHelp;
1041 else
1042 help_data = FolderHelp;
1043
1045
1046 struct Menu *menu = sdw.menu;
1048 menu->search = select_file_search;
1049 menu->mdata = priv;
1050
1051 priv->menu = menu;
1052 if (priv->multiple)
1053 priv->menu->tag = file_tag;
1054
1055 priv->sbar = sdw.sbar;
1056
1057 struct MuttWindow *win_menu = priv->menu->win;
1058
1059 // NT_COLOR is handled by the SimpleDialog
1063
1064 struct MuttWindow *old_focus = window_set_focus(priv->menu->win);
1065
1066 if (priv->state.is_mailbox_list)
1067 {
1068 examine_mailboxes(m, NULL, &priv->state);
1069 }
1070 else if (!priv->state.imap_browse)
1071 {
1072 // examine_directory() calls browser_add_folder() which needs the menu
1073 if (examine_directory(m, priv->menu, &priv->state, buf_string(&LastDir),
1074 buf_string(priv->prefix)) == -1)
1075 {
1076 goto bail;
1077 }
1078 }
1079
1080 init_menu(&priv->state, priv->menu, m, priv->sbar);
1081
1082 // ---------------------------------------------------------------------------
1083 // Event Loop
1084 int op = OP_NULL;
1085 do
1086 {
1087 menu_tagging_dispatcher(priv->menu->win, op);
1088 window_redraw(NULL);
1089
1091 mutt_debug(LL_DEBUG1, "Got op %s (%d)\n", opcodes_get_name(op), op);
1092 if (op < 0)
1093 continue;
1094 if (op == OP_NULL)
1095 {
1097 continue;
1098 }
1100
1101 int rc = browser_function_dispatcher(sdw.dlg, op);
1102
1103 if (rc == FR_UNKNOWN)
1104 rc = menu_function_dispatcher(menu->win, op);
1105 if (rc == FR_UNKNOWN)
1106 rc = global_function_dispatcher(NULL, op);
1107 } while (!priv->done);
1108 // ---------------------------------------------------------------------------
1109
1110bail:
1111 window_set_focus(old_focus);
1112 simple_dialog_free(&sdw.dlg);
1114}
#define ARRAY_RESERVE(head, num)
Reserve memory for the array.
Definition: array.h:189
#define ARRAY_FIRST(head)
Convenience method to get the first element.
Definition: array.h:135
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition: array.h:156
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition: array.h:212
#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_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:197
const struct ExpandoRenderCallback FolderRenderCallbacks[]
Callbacks for Browser Expandos.
Definition: expando.c:482
int browser_function_dispatcher(struct MuttWindow *win, int op)
Perform a Browser function.
Definition: functions.c:1126
#define MUTT_SEL_MAILBOX
Select a mailbox.
Definition: lib.h:58
void browser_sort(struct BrowserState *state)
Sort the entries in the browser.
Definition: sort.c:186
#define MUTT_SEL_FOLDER
Select a local directory.
Definition: lib.h:60
#define MUTT_SEL_MULTI
Multi-selection is enabled.
Definition: lib.h:59
uint8_t SelectFileFlags
Flags for mutt_select_file(), e.g. MUTT_SEL_MAILBOX.
Definition: lib.h:56
struct BrowserPrivateData * browser_private_data_new(void)
Create new Browser Data.
Definition: private_data.c:55
@ BROWSER_SORT_ALPHA
Sort alphabetically 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:161
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:96
size_t buf_len(const struct Buffer *buf)
Calculate the length of a Buffer.
Definition: buffer.c:491
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:377
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
void buf_fix_dptr(struct Buffer *buf)
Move the dptr to end of the Buffer.
Definition: buffer.c:182
size_t buf_strcpy_n(struct Buffer *buf, const char *s, size_t len)
Copy a string into a Buffer.
Definition: buffer.c:416
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:241
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:601
size_t buf_concat_path(struct Buffer *buf, const char *dir, const char *fname)
Join a directory name and a filename.
Definition: buffer.c:509
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition: buffer.c:337
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.
Definition: config_type.c:357
Convenience wrapper for the config headers.
#define SORT_MASK
Mask for the sort id.
Definition: sort.h:38
Connection Library.
Convenience wrapper for the core headers.
@ NT_MAILBOX_DELETE
Mailbox is about to be deleted.
Definition: mailbox.h:183
static const char * mailbox_path(const struct Mailbox *m)
Get the Mailbox's path string.
Definition: mailbox.h:223
@ MUTT_NOTMUCH
'Notmuch' (virtual) Mailbox type
Definition: mailbox.h:51
@ MUTT_MMDF
'mmdf' Mailbox type
Definition: mailbox.h:46
@ MUTT_POP
'POP3' Mailbox type
Definition: mailbox.h:52
@ MUTT_MH
'MH' Mailbox type
Definition: mailbox.h:47
@ MUTT_NNTP
'NNTP' (Usenet) Mailbox type
Definition: mailbox.h:49
@ MUTT_IMAP
'IMAP' Mailbox type
Definition: mailbox.h:50
@ MUTT_MBOX
'mbox' Mailbox type
Definition: mailbox.h:45
@ MUTT_MAILBOX_ANY
Match any Mailbox type.
Definition: mailbox.h:42
@ MUTT_MAILDIR
'Maildir' Mailbox type
Definition: mailbox.h:48
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:443
@ FR_UNKNOWN
Unknown function.
Definition: dispatcher.h:33
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.
Definition: dlg_browser.c:265
void init_menu(struct BrowserState *state, struct Menu *menu, struct Mailbox *m, struct MuttWindow *sbar)
Set up a new menu.
Definition: dlg_browser.c:585
static void init_lastdir(void)
Initialise the browser directories.
Definition: dlg_browser.c:145
static const struct Mapping FolderNewsHelp[]
Help Bar for the NNTP Mailbox browser dialog.
Definition: dlg_browser.c:122
struct Buffer LastDir
Browser: previous selected directory.
Definition: dlg_browser.c:136
void mutt_browser_select_dir(const char *f)
Remember the last directory selected.
Definition: dlg_browser.c:830
void init_state(struct BrowserState *state)
Initialise a browser state.
Definition: dlg_browser.c:248
struct Buffer LastDirBackup
Browser: backup copy of the current directory.
Definition: dlg_browser.c:138
static const struct Mapping FolderHelp[]
Help Bar for the File/Dir/Mailbox browser dialog.
Definition: dlg_browser.c:110
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.
Definition: dlg_browser.c:198
void mutt_browser_cleanup(void)
Clean up working Buffers.
Definition: dlg_browser.c:159
void browser_highlight_default(struct BrowserState *state, struct Menu *menu)
Decide which browser item should be highlighted.
Definition: dlg_browser.c:559
int examine_mailboxes(struct Mailbox *m, struct Menu *menu, struct BrowserState *state)
Get list of mailboxes/subscribed newsgroups.
Definition: dlg_browser.c:392
bool link_is_dir(const char *folder, const char *path)
Does this symlink point to a directory?
Definition: dlg_browser.c:172
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, struct Buffer *buf)
Render an Expando and run the result through a filter.
Definition: filter.c:138
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:642
@ MUTT_OPENDIR_NONE
Plain opendir()
Definition: file.h:63
int km_dokey(enum MenuType mtype, GetChFlags flags)
Determine what a keypress should do.
Definition: get.c:464
void km_error_key(enum MenuType mtype)
Handle an unbound key sequence.
Definition: get.c:294
bool OptNews
(pseudo) used to change reader mode
Definition: globals.c:67
char * CurrentFolder
Currently selected mailbox.
Definition: globals.c:42
int menu_tagging_dispatcher(struct MuttWindow *win, int op)
Perform tagging operations on the Menu - Implements function_dispatcher_t -.
Definition: tagging.c:230
int global_function_dispatcher(struct MuttWindow *win, int op)
Perform a Global function - Implements function_dispatcher_t -.
Definition: global.c:172
int menu_function_dispatcher(struct MuttWindow *win, int op)
Perform a Menu function - Implements function_dispatcher_t -.
Definition: functions.c:318
void dlg_browser(struct Buffer *file, SelectFileFlags flags, struct Mailbox *m, char ***files, int *numfiles)
Let the user select a file -.
Definition: dlg_browser.c:853
#define mutt_error(...)
Definition: logging2.h:92
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
#define mutt_perror(...)
Definition: logging2.h:93
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() -.
Definition: dlg_browser.c:514
static int select_file_search(struct Menu *menu, regex_t *rx, int line)
Menu search callback for matching files - Implements Menu::search() -.
Definition: dlg_browser.c:497
static int file_tag(struct Menu *menu, int sel, int act)
Tag an entry in the menu - Implements Menu::tag() -.
Definition: dlg_browser.c:690
enum MailboxType imap_path_probe(const char *path, const struct stat *st)
Is this an IMAP Mailbox? - Implements MxOps::path_probe() -.
Definition: imap.c:2344
static int browser_config_observer(struct NotifyCallback *nc)
Notification that a Config Variable has changed - Implements observer_t -.
Definition: dlg_browser.c:711
static int browser_mailbox_observer(struct NotifyCallback *nc)
Notification that a Mailbox has changed - Implements observer_t -.
Definition: dlg_browser.c:751
static int browser_window_observer(struct NotifyCallback *nc)
Notification that a Window has changed - Implements observer_t -.
Definition: dlg_browser.c:796
void browser_private_data_free(struct BrowserPrivateData **ptr)
Free Private Browser Data - Implements MuttWindow::wdata_free() -.
Definition: private_data.c:37
Convenience wrapper for the gui headers.
void simple_dialog_free(struct MuttWindow **ptr)
Destroy a simple index Dialog.
Definition: simple.c:168
struct SimpleDialogWindows simple_dialog_new(enum MenuType mtype, 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:191
Manage keymappings.
#define GETCH_NO_FLAGS
No flags are set.
Definition: lib.h:51
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
@ LL_DEBUG1
Log at debug level 1.
Definition: logging2.h:43
GUI present the user with a selectable list.
#define MENU_REDRAW_FULL
Redraw everything.
Definition: lib.h:59
void menu_queue_redraw(struct Menu *menu, MenuRedrawFlags redraw)
Queue a request for a redraw.
Definition: menu.c:184
int menu_get_index(struct Menu *menu)
Get the current selection in the Menu.
Definition: menu.c:160
MenuRedrawFlags menu_set_index(struct Menu *menu, int index)
Set the current selection in the Menu.
Definition: menu.c:174
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:253
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
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:581
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:280
#define PATH_MAX
Definition: mutt.h:42
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
NeoMutt Logging.
int mutt_mailbox_check(struct Mailbox *m_cur, CheckStatsFlags flags)
Check all all Mailboxes for new mail.
Definition: mutt_mailbox.c:169
Mailbox helper functions.
void window_redraw(struct MuttWindow *win)
Reflow, recalc and repaint a tree of Windows.
Definition: mutt_window.c:634
struct MuttWindow * window_set_focus(struct MuttWindow *win)
Set the Window focus.
Definition: mutt_window.c:684
@ WT_DLG_BROWSER
Browser Dialog, dlg_browser()
Definition: mutt_window.h:81
@ NT_WINDOW_DELETE
Window is about to be deleted.
Definition: mutt_window.h:229
void mutt_get_parent_path(const char *path, char *buf, size_t buflen)
Find the parent of a path (or mailbox)
Definition: muttlib.c:936
void buf_pretty_mailbox(struct Buffer *buf)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:519
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:315
Some miscellaneous functions.
enum MailboxType mx_path_probe(const char *path)
Find a mailbox that understands a path.
Definition: mx.c:1321
API for mailboxes.
#define MUTT_MAILBOX_CHECK_NO_FLAGS
No flags are set.
Definition: mxapi.h:53
void neomutt_mailboxlist_clear(struct MailboxList *ml)
Free a Mailbox List.
Definition: neomutt.c:168
size_t neomutt_mailboxlist_get_all(struct MailboxList *head, struct NeoMutt *n, enum MailboxType type)
Get a List of all Mailboxes.
Definition: neomutt.c:191
Nntp-specific Account data.
Usenet network mailbox type; talk to an NNTP server.
struct NntpAccountData * CurrentNewsSrv
Current NNTP news server.
Definition: nntp.c:77
Nntp-specific Mailbox data.
@ NT_WINDOW
MuttWindow has changed, NotifyWindow, EventWindow.
Definition: notify_type.h:57
@ NT_CONFIG
Config has changed, NotifyConfig, EventConfig.
Definition: notify_type.h:43
@ NT_MAILBOX
Mailbox has changed, NotifyMailbox, EventMailbox.
Definition: notify_type.h:49
const char * opcodes_get_name(int op)
Get the name of an opcode.
Definition: opcodes.c:48
Private state data for the Pager.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define TAILQ_EMPTY(head)
Definition: queue.h:739
#define MUTT_FORMAT_ARROWCURSOR
Reserve space for arrow_cursor.
Definition: render.h:37
void sbar_set_title(struct MuttWindow *win, const char *title)
Set the title for the Simple Bar.
Definition: sbar.c:227
Sidebar Expando definitions.
Sidebar functions.
Sidebar sorting functions.
Key value store.
#define NONULL(x)
Definition: string2.h:37
void * adata
Private data (for Mailbox backends)
Definition: account.h:42
Private state data for the Browser.
Definition: private_data.h:34
char *** files
Array of selected files.
Definition: private_data.h:38
struct Menu * menu
Menu.
Definition: private_data.h:43
struct Buffer * prefix
Folder prefix string.
Definition: private_data.h:49
bool kill_prefix
Prefix is in use.
Definition: private_data.h:44
bool done
Should we close the Dialog?
Definition: private_data.h:52
bool folder
Select folders.
Definition: private_data.h:46
int last_selected_mailbox
Index of last selected Mailbox.
Definition: private_data.h:50
int * numfiles
Number of selected files.
Definition: private_data.h:39
struct Mailbox * mailbox
Mailbox.
Definition: private_data.h:37
struct BrowserState state
State containing list of files/dir/mailboxes.
Definition: private_data.h:42
struct Buffer * file
Buffer for the result.
Definition: private_data.h:36
bool multiple
Allow multiple selections.
Definition: private_data.h:45
struct MuttWindow * sbar
Status Bar.
Definition: private_data.h:51
State of the file/mailbox browser.
Definition: lib.h:144
char * folder
Folder name.
Definition: lib.h:147
bool is_mailbox_list
Viewing mailboxes.
Definition: lib.h:148
struct BrowserEntryArray entry
Array of files / dirs / mailboxes.
Definition: lib.h:145
bool imap_browse
IMAP folder.
Definition: lib.h:146
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:52
char host[128]
Server to login to.
Definition: connaccount.h:54
struct ConnAccount account
Account details: username, password, etc.
Definition: connection.h:49
A config-change event.
Definition: subset.h:71
const char * name
Name of config item that changed.
Definition: subset.h:73
An Event that happened to a Mailbox.
Definition: mailbox.h:199
struct Mailbox * mailbox
The Mailbox this Event relates to.
Definition: mailbox.h:200
An Event that happened to a Window.
Definition: mutt_window.h:239
struct MuttWindow * win
Window that changed.
Definition: mutt_window.h:240
WindowNotifyFlags flags
Attributes of Window that changed.
Definition: mutt_window.h:241
Parsed Expando trees.
Definition: expando.h:41
Browser entry representing a folder/dir.
Definition: lib.h:78
bool imap
This is an IMAP folder.
Definition: lib.h:95
bool has_mailbox
This is a mailbox.
Definition: lib.h:98
char * name
Name of file/dir/mailbox.
Definition: lib.h:86
uid_t uid
File's User ID.
Definition: lib.h:82
bool tagged
Folder is tagged.
Definition: lib.h:102
gid_t gid
File's Group ID.
Definition: lib.h:83
bool has_new_mail
true if mailbox has "new mail"
Definition: lib.h:89
bool poll_new_mail
Check mailbox for new mail.
Definition: lib.h:101
bool notify_user
User will be notified of new mail.
Definition: lib.h:100
nlink_t nlink
Number of hard links.
Definition: lib.h:84
char * desc
Description of mailbox.
Definition: lib.h:87
struct NntpMboxData * nd
Extra NNTP data.
Definition: lib.h:103
off_t size
File size.
Definition: lib.h:80
int gen
Unique id, used for (un)sorting.
Definition: lib.h:105
time_t mtime
Modification time.
Definition: lib.h:81
int msg_count
total number of messages
Definition: lib.h:90
mode_t mode
File permissions.
Definition: lib.h:79
int msg_unread
number of unread messages
Definition: lib.h:91
A folder/dir in the browser.
Definition: lib.h:69
struct FolderFile * ff
File / Dir / Mailbox.
Definition: lib.h:70
List of Mailboxes.
Definition: mailbox.h:166
struct Mailbox * mailbox
Mailbox in the list.
Definition: mailbox.h:167
A mailbox.
Definition: mailbox.h:79
bool has_new
Mailbox has new mail.
Definition: mailbox.h:85
char * realpath
Used for duplicate detection, context comparison, and the sidebar.
Definition: mailbox.h:81
int msg_count
Total number of messages.
Definition: mailbox.h:88
enum MailboxType type
Mailbox type.
Definition: mailbox.h:102
bool poll_new_mail
Check for new mail.
Definition: mailbox.h:115
void * mdata
Driver specific data.
Definition: mailbox.h:132
char * name
A short name for the Mailbox.
Definition: mailbox.h:82
bool notify_user
Notify the user of new mail.
Definition: mailbox.h:113
bool visible
True if a result of "mailboxes".
Definition: mailbox.h:130
int msg_unread
Number of unread messages.
Definition: mailbox.h:89
int gen
Generation number, for sorting.
Definition: mailbox.h:147
Mapping between user-readable string and a constant.
Definition: mapping.h:33
Definition: lib.h:79
struct MuttWindow * win
Window holding the Menu.
Definition: lib.h:86
int num_tagged
Number of tagged entries.
Definition: lib.h:93
int(* search)(struct Menu *menu, regex_t *rx, int line)
Definition: lib.h:119
int top
Entry that is the top of the current page.
Definition: lib.h:90
int(* tag)(struct Menu *menu, int sel, int act)
Definition: lib.h:131
int(* make_entry)(struct Menu *menu, int line, int max_cols, struct Buffer *buf)
Definition: lib.h:106
struct ConfigSubset * sub
Inherited config items.
Definition: lib.h:87
void * mdata
Private data.
Definition: lib.h:147
int max
Number of entries in the menu.
Definition: lib.h:81
struct Notify * notify
Notifications: NotifyWindow, EventWindow.
Definition: mutt_window.h:138
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct AccountList accounts
List of all Accounts.
Definition: neomutt.h:47
struct Notify * notify
Notifications handler.
Definition: neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
NNTP-specific Account data -.
Definition: adata.h:36
struct NntpMboxData ** groups_list
Definition: adata.h:60
struct Connection * conn
Connection to NNTP Server.
Definition: adata.h:62
unsigned int groups_num
Definition: adata.h:58
NNTP-specific Mailbox data -.
Definition: mdata.h:34
struct NntpAccountData * adata
Definition: mdata.h:48
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:86
char * pattern
printable version
Definition: regex3.h:87
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
@ MENU_FOLDER
General file/mailbox browser.
Definition: type.h:45