From b0d7420c8faba73feb341d703f28ba2b58d7cdbe Mon Sep 17 00:00:00 2001 From: Pietro Cerutti Date: Fri, 11 Nov 2016 13:35:53 +0000 Subject: [PATCH] add $collapse_all to close threads automatically Implement collapse_all option to collapse all threads when entering a folder. Closes: #226 --- curs_main.c | 123 +++++++++++++++++++++++++++++------------------- doc/Makefile.am | 7 ++- doc/vimrc.misc | 4 ++ init.h | 5 ++ mutt.h | 1 + 5 files changed, 90 insertions(+), 50 deletions(-) create mode 100644 doc/vimrc.misc diff --git a/curs_main.c b/curs_main.c index 816b25e08..c46a2782b 100644 --- a/curs_main.c +++ b/curs_main.c @@ -127,6 +127,68 @@ static const char *No_visible = N_("No visible messages."); static char *tsl = "\033]0;"; static char *fsl = "\007"; +/** + * collapse/uncollapse all threads + * @param menu current menu + * @param toggle toggle collapsed state + * + * This function is called by the OP_MAIN_COLLAPSE_ALL command and on folder + * enter if the OPTCOLLAPSEALL option is set. In the first case, the @toggle + * parameter is 1 to actually toggle collapsed/uncollapsed state on all + * threads. In the second case, the @toggle parameter is 0, actually turning + * this function into a one-way collapse. + */ +static void collapse_all(MUTTMENU *menu, int toggle) +{ + HEADER *h, *base; + THREAD *thread, *top; + int final; + + /* Figure out what the current message would be after folding / unfolding, + * so that we can restore the cursor in a sane way afterwards. */ + if (CURHDR->collapsed && toggle) + final = mutt_uncollapse_thread (Context, CURHDR); + else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (CURHDR)) + final = mutt_collapse_thread (Context, CURHDR); + else + final = CURHDR->virtual; + + base = Context->hdrs[Context->v2r[final]]; + + /* Iterate all threads, perform collapse/uncollapse as needed */ + top = Context->tree; + Context->collapsed = toggle ? !Context->collapsed : 1; + while ((thread = top) != NULL) + { + while (!thread->message) + thread = thread->child; + h = thread->message; + + if (h->collapsed != Context->collapsed) + { + if (h->collapsed) + mutt_uncollapse_thread (Context, h); + else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (h)) + mutt_collapse_thread (Context, h); + } + top = top->next; + } + + /* Restore the cursor */ + mutt_set_virtual (Context); + int j; + for (j = 0; j < Context->vcount; j++) + { + if (Context->hdrs[Context->v2r[j]]->index == base->index) + { + menu->current = j; + break; + } + } + + menu->redraw = REDRAW_INDEX | REDRAW_STATUS; +} + /* terminal status capability check. terminfo must have been initialized. */ short mutt_ts_capability(void) { @@ -710,6 +772,9 @@ static int main_change_folder(MUTTMENU *menu, int op, char *buf, size_t bufsz, else menu->current = 0; + if (((Sort & SORT_MASK) == SORT_THREADS) && option (OPTCOLLAPSEALL)) + collapse_all (menu, 0); + #ifdef USE_SIDEBAR mutt_sb_set_open_buffy (); #endif @@ -782,6 +847,12 @@ int mutt_index_menu (void) if (!attach_msg) mutt_buffy_check(1); /* force the buffy check after we enter the folder */ + if (((Sort & SORT_MASK) == SORT_THREADS) && option (OPTCOLLAPSEALL)) + { + collapse_all (menu, 0); + menu->redraw = REDRAW_FULL; + } + FOREVER { tag = 0; /* clear the tag-prefix */ @@ -2501,54 +2572,10 @@ int mutt_index_menu (void) if ((Sort & SORT_MASK) != SORT_THREADS) { - mutt_error _("Threading is not enabled."); - break; - } - - { - HEADER *h, *base; - THREAD *thread, *top; - int final; - - if (CURHDR->collapsed) - final = mutt_uncollapse_thread (Context, CURHDR); - else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (CURHDR)) - final = mutt_collapse_thread (Context, CURHDR); - else - final = CURHDR->virtual; - - base = Context->hdrs[Context->v2r[final]]; - - top = Context->tree; - Context->collapsed = !Context->collapsed; - while ((thread = top) != NULL) - { - while (!thread->message) - thread = thread->child; - h = thread->message; - - if (h->collapsed != Context->collapsed) - { - if (h->collapsed) - mutt_uncollapse_thread (Context, h); - else if (option (OPTCOLLAPSEUNREAD) || !UNREAD (h)) - mutt_collapse_thread (Context, h); - } - top = top->next; - } - - mutt_set_virtual (Context); - for (j = 0; j < Context->vcount; j++) - { - if (Context->hdrs[Context->v2r[j]]->index == base->index) - { - menu->current = j; - break; - } - } - - menu->redraw = REDRAW_INDEX | REDRAW_STATUS; - } + mutt_error _("Threading is not enabled."); + break; + } + collapse_all (menu, 1); break; /* -------------------------------------------------------------------- diff --git a/doc/Makefile.am b/doc/Makefile.am index 599e8df55..f2642c21c 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -47,7 +47,8 @@ SAMPLE_MUTTRC = muttrc.attach-headers-color muttrc.compress muttrc.cond-date \ SAMPLE_VIMRC = vimrc.attach-headers-color vimrc.compress vimrc.encrypt-to-self \ vimrc.forgotten-attachment vimrc.ifdef vimrc.index-color vimrc.keywords \ vimrc.new-mail vimrc.nntp vimrc.notmuch vimrc.progress \ - vimrc.quasi-delete vimrc.reply-with-xorig vimrc.sidebar vimrc.timeout + vimrc.quasi-delete vimrc.reply-with-xorig vimrc.sidebar vimrc.timeout \ + vimrc.misc CHUNKED_DOCFILES = index.html intro.html gettingstarted.html \ configuration.html mimesupport.html advancedusage.html \ @@ -160,7 +161,9 @@ neomutt-syntax.vim: mutt-1.7.0-syntax.vim $(SAMPLE_VIMRC) ( \ sed -e '/vim:/d' -e "/This file covers/s/$$/ and NeoMutt $(VERSION)/" $(srcdir)/mutt-1.7.0-syntax.vim; \ echo; \ - cat $?; \ + for f in $(SAMPLE_VIMRC) ; do \ + cat $(srcdir)/$$f; \ + done; \ grep "vim:" $(srcdir)/mutt-1.7.0-syntax.vim; \ ) > $@ diff --git a/doc/vimrc.misc b/doc/vimrc.misc new file mode 100644 index 000000000..fa30f11ef --- /dev/null +++ b/doc/vimrc.misc @@ -0,0 +1,4 @@ +" Vim syntax file for the NeoMutt miscellany (options without features). + +syntax keyword muttrcVarBool contained skipwhite collapse_all nextgroup=muttrcSetBoolAssignment,muttrcVPrefix,muttrcVarBool,muttrcVarQuad,muttrcVarNum,muttrcVarStr + diff --git a/init.h b/init.h index a6331f98d..9de4de95f 100644 --- a/init.h +++ b/init.h @@ -4166,6 +4166,11 @@ struct option_t MuttVars[] = { ** name of original article author) to article that followuped to newsgroup. */ #endif + { "collapse_all", DT_BOOL, R_NONE, OPTCOLLAPSEALL, 0 }, + /* + ** .pp + ** When \fIset\fP, Mutt will collapse all threads when entering a folder. + */ /*--*/ { NULL, 0, 0, 0, 0 } }; diff --git a/mutt.h b/mutt.h index 132fc9b24..0a75aa834 100644 --- a/mutt.h +++ b/mutt.h @@ -380,6 +380,7 @@ enum OPTBRAILLEFRIENDLY, OPTCHECKMBOXSIZE, OPTCHECKNEW, + OPTCOLLAPSEALL, OPTCOLLAPSEUNREAD, OPTCONFIRMAPPEND, OPTCONFIRMCREATE, -- 2.40.0