From 66303262cd5573617ca77c2e8b6736c27759c2ce Mon Sep 17 00:00:00 2001 From: Thierry Volpiatto Date: Sun, 8 Jun 2014 08:24:25 +0200 Subject: [PATCH 01/25] * mu4e/mu4e-main.el (mu4e-main-mode): `revert-buffer-function' should be local. --- mu4e/mu4e-main.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mu4e/mu4e-main.el b/mu4e/mu4e-main.el index 23fa4bdd..b31fad7b 100644 --- a/mu4e/mu4e-main.el +++ b/mu4e/mu4e-main.el @@ -64,11 +64,9 @@ "Major mode for the mu4e main screen. \\{mu4e-main-mode-map}." (use-local-map mu4e-main-mode-map) - (setq - truncate-lines t - overwrite-mode 'overwrite-mode-binary - revert-buffer-function 'mu4e:main-revert-buffer - )) + (setq truncate-lines t + overwrite-mode 'overwrite-mode-binary) + (set (make-local-variable 'revert-buffer-function) #'mu4e:main-revert-buffer)) (defun mu4e~main-action-str (str &optional func-or-shortcut) From a4201fe57a4b7d6c12a7620f0305b18103eca181 Mon Sep 17 00:00:00 2001 From: Thierry Volpiatto Date: Sun, 8 Jun 2014 08:24:25 +0200 Subject: [PATCH 02/25] * mu4e/mu4e-main.el (mu4e-main-mode): `revert-buffer-function' should be local. --- mu4e/mu4e-main.el | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/mu4e/mu4e-main.el b/mu4e/mu4e-main.el index 23fa4bdd..b31fad7b 100644 --- a/mu4e/mu4e-main.el +++ b/mu4e/mu4e-main.el @@ -64,11 +64,9 @@ "Major mode for the mu4e main screen. \\{mu4e-main-mode-map}." (use-local-map mu4e-main-mode-map) - (setq - truncate-lines t - overwrite-mode 'overwrite-mode-binary - revert-buffer-function 'mu4e:main-revert-buffer - )) + (setq truncate-lines t + overwrite-mode 'overwrite-mode-binary) + (set (make-local-variable 'revert-buffer-function) #'mu4e:main-revert-buffer)) (defun mu4e~main-action-str (str &optional func-or-shortcut) From 9f61a0387d64ec277b1e6be9f78c5c0e8642c398 Mon Sep 17 00:00:00 2001 From: djcb Date: Mon, 16 Jun 2014 21:47:36 +0300 Subject: [PATCH 03/25] * mu4e: add curl list to mailing lists --- mu4e/mu4e-lists.el | 1 + 1 file changed, 1 insertion(+) diff --git a/mu4e/mu4e-lists.el b/mu4e/mu4e-lists.el index 74f79947..a9676c28 100644 --- a/mu4e/mu4e-lists.el +++ b/mu4e/mu4e-lists.el @@ -31,6 +31,7 @@ ("boost-announce.lists.boost.org" . "BoostA") ("boost-interest.lists.boost.org" . "BoostI") ("conkeror.mozdev.org" . "Conkeror") + ("curl-library.cool.haxx.se" . "LibCurl") ("crypto-gram-list.schneier.com " . "CryptoGr") ("dbus.lists.freedesktop.org" . "DBus") ("desktop-devel-list.gnome.org" . "GnomeDT") From 2382abddf326fa2ba6b87c3036d0d4636ad48e8f Mon Sep 17 00:00:00 2001 From: Thierry Volpiatto Date: Wed, 18 Jun 2014 15:33:55 +0200 Subject: [PATCH 04/25] * mu4e/mu4e-compose.el (mu4e~compose-handler): Kill buffer on quit, transformed in defun*. --- mu4e/mu4e-compose.el | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index 2320e1b6..b62e096f 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -326,7 +326,7 @@ appear on disk." mu4e~compose-buffer-max-name-length nil nil t))))) -(defun mu4e~compose-handler (compose-type &optional original-msg includes) +(defun* mu4e~compose-handler (compose-type &optional original-msg includes) "Create a new draft message, or open an existing one. COMPOSE-TYPE determines the kind of message to compose and is a @@ -352,7 +352,10 @@ tempfile)." (run-hooks 'mu4e-compose-pre-hook) ;; this opens (or re-opens) a messages with all the basic headers set. - (mu4e-draft-open compose-type original-msg) + (condition-case nil + (mu4e-draft-open compose-type original-msg) + (quit (kill-buffer) (message "[mu4e] Operation aborted") + (return-from mu4e~compose-handler))) ;; insert mail-header-separator, which is needed by message mode to separate ;; headers and body. will be removed before saving to disk (mu4e~draft-insert-mail-header-separator) From 76787707fef516659258ea827e678e04cc9c5919 Mon Sep 17 00:00:00 2001 From: Thierry Volpiatto Date: Fri, 27 Jun 2014 07:28:33 +0200 Subject: [PATCH 05/25] * mu4e/mu4e-view.el (mu4e-view-fill-long-lines): New, bind it to M-q. --- mu4e/mu4e-view.el | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/mu4e/mu4e-view.el b/mu4e/mu4e-view.el index 7db8d9b2..96155d44 100644 --- a/mu4e/mu4e-view.el +++ b/mu4e/mu4e-view.el @@ -597,7 +597,8 @@ FUNC should be a function taking two arguments: ;; misc (define-key map "w" 'visual-line-mode) (define-key map "h" 'mu4e-view-toggle-hide-cited) - + (define-key map (kbd "M-q") 'mu4e-view-fill-long-lines) + ;; next 3 only warn user when attempt in the message view (define-key map "u" 'mu4e-view-unmark) (define-key map "U" 'mu4e-view-unmark-all) @@ -909,6 +910,28 @@ Add this function to `mu4e-view-mode-hook' to enable this feature." (overlay-put ov 'face 'mu4e-region-code)) (setq beg nil end nil)))))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Wash functions +(defun mu4e-view-fill-long-lines () + "Fill lines that are wider than the window width or `fill-column'." + (interactive) + (with-current-buffer mu4e~view-buffer + (save-excursion + (let ((inhibit-read-only t) + (width (window-width (get-buffer-window (current-buffer))))) + (save-restriction + (message-goto-body) + (while (not (eobp)) + (end-of-line) + (when (>= (current-column) (min fill-column width)) + (narrow-to-region (min (1+ (point)) (point-max)) + (point-at-bol)) + (let ((goback (point-marker))) + (fill-paragraph nil) + (goto-char (marker-position goback))) + (widen)) + (forward-line 1))))))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; attachment handling (defun mu4e~view-get-attach-num (prompt msg &optional multi) From fc04367e2e7aef94ff6fb3117cf16e9b8b15a347 Mon Sep 17 00:00:00 2001 From: Thierry Volpiatto Date: Fri, 27 Jun 2014 07:37:15 +0200 Subject: [PATCH 06/25] * mu4e/mu4e-view.el: Fix whitespaces in newline in previous commit, no code--change. --- mu4e/mu4e-view.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mu4e/mu4e-view.el b/mu4e/mu4e-view.el index 96155d44..5d867065 100644 --- a/mu4e/mu4e-view.el +++ b/mu4e/mu4e-view.el @@ -598,7 +598,7 @@ FUNC should be a function taking two arguments: (define-key map "w" 'visual-line-mode) (define-key map "h" 'mu4e-view-toggle-hide-cited) (define-key map (kbd "M-q") 'mu4e-view-fill-long-lines) - + ;; next 3 only warn user when attempt in the message view (define-key map "u" 'mu4e-view-unmark) (define-key map "U" 'mu4e-view-unmark-all) From ab58307feaa80392db667671136815bc0885e154 Mon Sep 17 00:00:00 2001 From: djcb Date: Fri, 27 Jun 2014 22:26:22 +0300 Subject: [PATCH 07/25] * bump version to 0.9.9.6 --- NEWS | 21 ++++++++++++++++++++- configure.ac | 4 ++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 4fb9dc56..e5b7037b 100644 --- a/NEWS +++ b/NEWS @@ -12,10 +12,29 @@ - give messages without msgids fake-message-ids; this fixes the problem where such messages were not found in --include-related queries - cleanup of the query parser + - much improved date parsing + - support recursive maildirs + - many fixes in the query parser; there are still a number of + corner cases though, which probably requires writing a custom + query parser to fix + - drop gmime 2.4 support *** mu4e - - update the emacs <-> backend protocol; documented in the mu-server man page + - update the emacs <-> backend protocol; documented in the + mu-server man page + - improve saving attachment + - allow for visiting multiple URIs + - much improved navigation within messages + + - mug + + - only support gtk+ 3.x + + - mu-guile: + + - more examples; bug fixes + ** Release 0.9.9.5 diff --git a/configure.ac b/configure.ac index f9140e17..620914cb 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -## Copyright (C) 2008-2013 Dirk-Jan C. Binnema +## Copyright (C) 2008-2014 Dirk-Jan C. Binnema ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -14,7 +14,7 @@ ## along with this program; if not, write to the Free Software Foundation, ## Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -AC_INIT([mu],[0.9.9.6pre3],[http://code.google.com/p/mu0/issues/list],[mu]) +AC_INIT([mu],[0.9.9.6],[http://code.google.com/p/mu0/issues/list],[mu]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([mu/mu.cc]) # libtoolize wants to put some stuff in here; if you have an old From b7efa1e3e338e61c161034e04503b5e344487e7f Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Mon, 7 Jul 2014 06:22:04 +0200 Subject: [PATCH 08/25] tests: threads: Use struct tinfo in all tests --- mu/tests/test-mu-threads.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index c8d75276..6779203f 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -34,6 +34,13 @@ #include "mu-query.h" #include "mu-str.h" +struct _tinfo { + const char *threadpath; + const char *msgid; + const char *subject; +}; +typedef struct _tinfo tinfo; + static gchar* fill_database (const char *testdir) { @@ -87,11 +94,7 @@ test_mu_threads_01 (void) MuMsgIter *iter; unsigned u; - struct { - const char* threadpath; - const char *msgid; - const char* subject; - } items [] = { + const tinfo items [] = { {"0", "root0@msg.id", "root0"}, {"0:0", "child0.0@msg.id", "Re: child 0.0"}, {"0:1", "child0.1@msg.id", "Re: child 0.1"}, @@ -149,14 +152,6 @@ test_mu_threads_01 (void) mu_msg_iter_destroy (iter); } - -struct _tinfo { - const char* threadpath; - const char *msgid; - const char* subject; -}; -typedef struct _tinfo tinfo; - static void test_mu_threads_rogue (void) { From 4c4b9af762a7c48ba2039f1a05a2127c6305549d Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Mon, 7 Jul 2014 06:22:31 +0200 Subject: [PATCH 09/25] tests: threads: Extract helpers for initializing and comparing thread info --- mu/tests/test-mu-threads.c | 74 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 36 deletions(-) diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index 6779203f..809ed38f 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -41,6 +41,38 @@ struct _tinfo { }; typedef struct _tinfo tinfo; +static void +assert_tinfo_equal (const tinfo *expected, const tinfo *actual) +{ + g_assert_cmpstr (expected->threadpath,==,actual->threadpath); + g_assert_cmpstr (expected->subject,==,actual->subject); + g_assert_cmpstr (expected->msgid,==,actual->msgid); +} + +static void +tinfo_init_from_iter (tinfo *item, MuMsgIter *iter) +{ + MuMsg *msg; + const MuMsgIterThreadInfo *ti; + + msg = mu_msg_iter_get_msg_floating (iter); + g_assert (msg); + + ti = mu_msg_iter_get_thread_info (iter); + if (!ti) + g_print ("%s: thread info not found\n", mu_msg_get_msgid (msg)); + g_assert (ti); + + item->threadpath = ti->threadpath; + item->subject = mu_msg_get_subject (msg); + item->msgid = mu_msg_get_msgid (msg); + + if (g_test_verbose()) + g_print ("%s %s %s\n", + item->threadpath, item->subject, item->msgid); + +} + static gchar* fill_database (const char *testdir) { @@ -120,28 +152,12 @@ test_mu_threads_01 (void) u = 0; while (!mu_msg_iter_is_done (iter) && u < G_N_ELEMENTS(items)) { - MuMsg *msg; - const MuMsgIterThreadInfo *ti; + tinfo ti; - ti = mu_msg_iter_get_thread_info (iter); - if (!ti) - g_print ("%s: thread info not found for %u\n", - __FUNCTION__, (unsigned)mu_msg_iter_get_docid(iter)); - g_assert(ti); - - msg = mu_msg_iter_get_msg_floating (iter); - g_assert (msg); - - if (g_test_verbose()) - g_print ("%s %s %s\n", ti->threadpath, - mu_msg_get_msgid(msg), - mu_msg_get_path (msg)); + tinfo_init_from_iter (&ti, iter); g_assert (u < G_N_ELEMENTS(items)); - - g_assert_cmpstr (ti->threadpath,==,items[u].threadpath); - g_assert_cmpstr (mu_msg_get_subject(msg),==,items[u].subject); - g_assert_cmpstr (mu_msg_get_msgid(msg),==,items[u].msgid); + assert_tinfo_equal (&items[u], &ti); ++u; mu_msg_iter_next (iter); @@ -191,26 +207,12 @@ test_mu_threads_rogue (void) u = 0; while (!mu_msg_iter_is_done (iter) && u < G_N_ELEMENTS(items1)) { - MuMsg *msg; - const MuMsgIterThreadInfo *ti; + tinfo ti; - ti = mu_msg_iter_get_thread_info (iter); - if (!ti) - g_print ("%s: thread info not found\n", - mu_msg_get_msgid(mu_msg_iter_get_msg_floating (iter))); - g_assert(ti); - - msg = mu_msg_iter_get_msg_floating (iter); /* don't unref */ - /* g_print ("%s %s %s\n", ti->threadpath, */ - /* mu_msg_get_msgid(msg), */ - /* mu_msg_get_path (msg) */ - /* ); */ + tinfo_init_from_iter (&ti, iter); g_assert (u < G_N_ELEMENTS(items1)); - - g_assert_cmpstr (ti->threadpath,==,(items)[u].threadpath); - g_assert_cmpstr (mu_msg_get_subject(msg),==,(items)[u].subject); - g_assert_cmpstr (mu_msg_get_msgid(msg),==,(items)[u].msgid); + assert_tinfo_equal (&items[u], &ti); ++u; mu_msg_iter_next (iter); From 80a484dc3f2ffd917beccad6f98fce53acf0c3ee Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 15 Jul 2014 07:19:25 +0200 Subject: [PATCH 10/25] tests: threads: Extract helper for checking thread info for each message --- mu/tests/test-mu-threads.c | 51 ++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index 809ed38f..d56d56b7 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -73,6 +73,26 @@ tinfo_init_from_iter (tinfo *item, MuMsgIter *iter) } +static void +foreach_assert_tinfo_equal (MuMsgIter *iter, const tinfo items[], guint n_items) +{ + guint u; + + u = 0; + while (!mu_msg_iter_is_done (iter) && u < n_items) { + tinfo ti; + + tinfo_init_from_iter (&ti, iter); + + g_assert (u < n_items); + assert_tinfo_equal (&items[u], &ti); + + ++u; + mu_msg_iter_next (iter); + } + g_assert (u == n_items); +} + static gchar* fill_database (const char *testdir) { @@ -118,13 +138,11 @@ run_and_get_iter (const char *xpath, const char *query) return iter; } - static void test_mu_threads_01 (void) { gchar *xpath; MuMsgIter *iter; - unsigned u; const tinfo items [] = { {"0", "root0@msg.id", "root0"}, @@ -150,19 +168,7 @@ test_mu_threads_01 (void) g_assert (iter); g_assert (!mu_msg_iter_is_done(iter)); - u = 0; - while (!mu_msg_iter_is_done (iter) && u < G_N_ELEMENTS(items)) { - tinfo ti; - - tinfo_init_from_iter (&ti, iter); - - g_assert (u < G_N_ELEMENTS(items)); - assert_tinfo_equal (&items[u], &ti); - - ++u; - mu_msg_iter_next (iter); - } - g_assert (u == G_N_ELEMENTS(items)); + foreach_assert_tinfo_equal (iter, items, G_N_ELEMENTS (items)); g_free (xpath); mu_msg_iter_destroy (iter); @@ -173,7 +179,6 @@ test_mu_threads_rogue (void) { gchar *xpath; MuMsgIter *iter; - unsigned u; tinfo *items; tinfo items1 [] = { @@ -205,19 +210,7 @@ test_mu_threads_rogue (void) else items = items2; - u = 0; - while (!mu_msg_iter_is_done (iter) && u < G_N_ELEMENTS(items1)) { - tinfo ti; - - tinfo_init_from_iter (&ti, iter); - - g_assert (u < G_N_ELEMENTS(items1)); - assert_tinfo_equal (&items[u], &ti); - - ++u; - mu_msg_iter_next (iter); - } - g_assert (u == G_N_ELEMENTS(items1)); + foreach_assert_tinfo_equal (iter, items, G_N_ELEMENTS (items1)); g_free (xpath); mu_msg_iter_destroy (iter); From 22927a7dcff87ce8f7e4017a752cd208eed91f46 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 15 Jul 2014 07:22:11 +0200 Subject: [PATCH 11/25] tests: threads: Test if 1st child message promotes its thread --- .../sort/1st-child-promotes-thread/cur/A | 7 ++ .../sort/1st-child-promotes-thread/cur/B | 7 ++ .../sort/1st-child-promotes-thread/cur/C | 7 ++ .../sort/1st-child-promotes-thread/cur/D | 9 ++ .../1st-child-promotes-thread/new/.noindex | 0 .../1st-child-promotes-thread/tmp/.noindex | 0 mu/tests/test-mu-threads.c | 86 ++++++++++++++++++- 7 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 lib/tests/testdir3/sort/1st-child-promotes-thread/cur/A create mode 100644 lib/tests/testdir3/sort/1st-child-promotes-thread/cur/B create mode 100644 lib/tests/testdir3/sort/1st-child-promotes-thread/cur/C create mode 100644 lib/tests/testdir3/sort/1st-child-promotes-thread/cur/D create mode 100644 lib/tests/testdir3/sort/1st-child-promotes-thread/new/.noindex create mode 100644 lib/tests/testdir3/sort/1st-child-promotes-thread/tmp/.noindex diff --git a/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/A b/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/A new file mode 100644 index 00000000..85130e80 --- /dev/null +++ b/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/A @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: A +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +A diff --git a/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/B b/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/B new file mode 100644 index 00000000..254aeb72 --- /dev/null +++ b/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/B @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: B +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +B diff --git a/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/C b/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/C new file mode 100644 index 00000000..60b7db56 --- /dev/null +++ b/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/C @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: C +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +C diff --git a/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/D b/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/D new file mode 100644 index 00000000..1e4861df --- /dev/null +++ b/lib/tests/testdir3/sort/1st-child-promotes-thread/cur/D @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: D +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +D diff --git a/lib/tests/testdir3/sort/1st-child-promotes-thread/new/.noindex b/lib/tests/testdir3/sort/1st-child-promotes-thread/new/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/lib/tests/testdir3/sort/1st-child-promotes-thread/tmp/.noindex b/lib/tests/testdir3/sort/1st-child-promotes-thread/tmp/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index d56d56b7..8bfd3fe7 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -117,7 +117,8 @@ fill_database (const char *testdir) /* note: this also *moves the iter* */ static MuMsgIter* -run_and_get_iter (const char *xpath, const char *query) +run_and_get_iter_full (const char *xpath, const char *query, + MuMsgFieldId sort_field, MuQueryFlags flags) { MuQuery *mquery; MuStore *store; @@ -130,14 +131,21 @@ run_and_get_iter (const char *xpath, const char *query) mu_store_unref (store); g_assert (query); - iter = mu_query_run (mquery, query, MU_MSG_FIELD_ID_DATE, - -1, MU_QUERY_FLAG_THREADS, NULL); + flags |= MU_QUERY_FLAG_THREADS; + iter = mu_query_run (mquery, query, sort_field, -1, flags, NULL); mu_query_destroy (mquery); g_assert (iter); return iter; } +static MuMsgIter* +run_and_get_iter (const char *xpath, const char *query) +{ + return run_and_get_iter_full (xpath, query, MU_MSG_FIELD_ID_DATE, + MU_QUERY_FLAG_NONE); +} + static void test_mu_threads_01 (void) { @@ -216,6 +224,76 @@ test_mu_threads_rogue (void) mu_msg_iter_destroy (iter); } +static MuMsgIter* +query_testdir (const char *query, MuMsgFieldId sort_field, gboolean descending) +{ + MuMsgIter *iter; + gchar *xpath; + MuQueryFlags flags; + + flags = MU_QUERY_FLAG_NONE; + if (descending) + flags |= MU_QUERY_FLAG_DESCENDING; + + xpath = fill_database (MU_TESTMAILDIR3); + g_assert (xpath != NULL); + + iter = run_and_get_iter_full (xpath, query, sort_field, flags); + g_assert (iter != NULL); + g_assert (!mu_msg_iter_is_done (iter)); + + g_free (xpath); + return iter; +} + +static void +check_sort_by_subject (const char *query, const tinfo expected[], + guint n_expected, gboolean descending) +{ + MuMsgIter *iter; + + iter = query_testdir (query, MU_MSG_FIELD_ID_SUBJECT, descending); + foreach_assert_tinfo_equal (iter, expected, n_expected); + mu_msg_iter_destroy (iter); +} + +static void +check_sort_by_subject_asc (const char *query, const tinfo expected[], + guint n_expected) +{ + check_sort_by_subject (query, expected, n_expected, FALSE); +} + +static void +check_sort_by_subject_desc (const char *query, const tinfo expected[], + guint n_expected) +{ + check_sort_by_subject (query, expected, n_expected, TRUE); +} + +static void +test_mu_threads_sort_1st_child_promotes_thread (void) +{ + const char *query = "maildir:/sort/1st-child-promotes-thread"; + + const tinfo expected_asc [] = { + { "0", "A@msg.id", "A"}, + { "1", "C@msg.id", "C"}, + { "2", "B@msg.id", "B"}, + { "2:0", "D@msg.id", "D"}, + }; + const tinfo expected_desc [] = { + { "0", "B@msg.id", "B"}, + { "0:0", "D@msg.id", "D"}, + { "1", "C@msg.id", "C"}, + { "2", "A@msg.id", "A"}, + }; + + check_sort_by_subject_asc (query, expected_asc, + G_N_ELEMENTS (expected_asc)); + check_sort_by_subject_desc (query, expected_desc, + G_N_ELEMENTS (expected_desc)); +} int @@ -227,6 +305,8 @@ main (int argc, char *argv[]) g_test_add_func ("/mu-query/test-mu-threads-01", test_mu_threads_01); g_test_add_func ("/mu-query/test-mu-threads-rogue", test_mu_threads_rogue); + g_test_add_func ("/mu-query/test-mu-threads-sort-1st-child-promotes-thread", + test_mu_threads_sort_1st_child_promotes_thread); g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION, From c5d4f7f33899d10cb24ad8f1d880778e749d276e Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 15 Jul 2014 07:22:53 +0200 Subject: [PATCH 12/25] tests: threads: Test if 2nd child message promotes its subthread --- .../sort/2nd-child-promotes-thread/cur/A | 7 +++++ .../sort/2nd-child-promotes-thread/cur/B | 7 +++++ .../sort/2nd-child-promotes-thread/cur/C | 9 +++++++ .../sort/2nd-child-promotes-thread/cur/D | 7 +++++ .../sort/2nd-child-promotes-thread/cur/E | 9 +++++++ .../2nd-child-promotes-thread/new/.noindex | 0 .../2nd-child-promotes-thread/tmp/.noindex | 0 mu/tests/test-mu-threads.c | 27 +++++++++++++++++++ 8 files changed, 66 insertions(+) create mode 100644 lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/A create mode 100644 lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/B create mode 100644 lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/C create mode 100644 lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/D create mode 100644 lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/E create mode 100644 lib/tests/testdir3/sort/2nd-child-promotes-thread/new/.noindex create mode 100644 lib/tests/testdir3/sort/2nd-child-promotes-thread/tmp/.noindex diff --git a/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/A b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/A new file mode 100644 index 00000000..85130e80 --- /dev/null +++ b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/A @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: A +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +A diff --git a/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/B b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/B new file mode 100644 index 00000000..254aeb72 --- /dev/null +++ b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/B @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: B +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +B diff --git a/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/C b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/C new file mode 100644 index 00000000..6d1e19af --- /dev/null +++ b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/C @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: C +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +C diff --git a/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/D b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/D new file mode 100644 index 00000000..de61bc13 --- /dev/null +++ b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/D @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: D +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +D diff --git a/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/E b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/E new file mode 100644 index 00000000..bb7f5f39 --- /dev/null +++ b/lib/tests/testdir3/sort/2nd-child-promotes-thread/cur/E @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: E +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +E diff --git a/lib/tests/testdir3/sort/2nd-child-promotes-thread/new/.noindex b/lib/tests/testdir3/sort/2nd-child-promotes-thread/new/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/lib/tests/testdir3/sort/2nd-child-promotes-thread/tmp/.noindex b/lib/tests/testdir3/sort/2nd-child-promotes-thread/tmp/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index 8bfd3fe7..a799b392 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -295,6 +295,31 @@ test_mu_threads_sort_1st_child_promotes_thread (void) G_N_ELEMENTS (expected_desc)); } +static void +test_mu_threads_sort_2nd_child_promotes_thread (void) +{ + const char *query = "maildir:/sort/2nd-child-promotes-thread"; + + const tinfo expected_asc [] = { + { "0", "A@msg.id", "A"}, + { "1", "D@msg.id", "D"}, + { "2", "B@msg.id", "B"}, + { "2:0", "C@msg.id", "C"}, + { "2:1", "E@msg.id", "E"}, + }; + const tinfo expected_desc [] = { + { "0", "B@msg.id", "B"}, + { "0:0", "E@msg.id", "E"}, + { "0:1", "C@msg.id", "C"}, + { "1", "D@msg.id", "D"}, + { "2", "A@msg.id", "A"}, + }; + + check_sort_by_subject_asc (query, expected_asc, + G_N_ELEMENTS (expected_asc)); + check_sort_by_subject_desc (query, expected_desc, + G_N_ELEMENTS (expected_desc)); +} int main (int argc, char *argv[]) @@ -307,6 +332,8 @@ main (int argc, char *argv[]) g_test_add_func ("/mu-query/test-mu-threads-rogue", test_mu_threads_rogue); g_test_add_func ("/mu-query/test-mu-threads-sort-1st-child-promotes-thread", test_mu_threads_sort_1st_child_promotes_thread); + g_test_add_func ("/mu-query/test-mu-threads-sort-2nd-child-promotes-thread", + test_mu_threads_sort_2nd_child_promotes_thread); g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION, From f49296759ef8749e7a286fce08d948eba2f1624a Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 15 Jul 2014 07:23:27 +0200 Subject: [PATCH 13/25] tests: threads: Test if orphan message promotes its thread --- mu/tests/test-mu-threads.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index a799b392..f059e9a5 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -321,6 +321,31 @@ test_mu_threads_sort_2nd_child_promotes_thread (void) G_N_ELEMENTS (expected_desc)); } +static void +test_mu_threads_sort_orphan_promotes_thread (void) +{ + const char *query = "maildir:/sort/2nd-child-promotes-thread NOT B"; + + /* B lost, C & E orphaned but not promoted */ + const tinfo expected_asc [] = { + { "0", "A@msg.id", "A"}, + { "1", "D@msg.id", "D"}, + { "2:0", "C@msg.id", "C"}, + { "2:1", "E@msg.id", "E"}, + }; + const tinfo expected_desc [] = { + { "0:0", "E@msg.id", "E"}, + { "0:1", "C@msg.id", "C"}, + { "1", "D@msg.id", "D"}, + { "2", "A@msg.id", "A"}, + }; + + check_sort_by_subject_asc (query, expected_asc, + G_N_ELEMENTS (expected_asc)); + check_sort_by_subject_desc (query, expected_desc, + G_N_ELEMENTS (expected_desc)); +} + int main (int argc, char *argv[]) { @@ -334,6 +359,8 @@ main (int argc, char *argv[]) test_mu_threads_sort_1st_child_promotes_thread); g_test_add_func ("/mu-query/test-mu-threads-sort-2nd-child-promotes-thread", test_mu_threads_sort_2nd_child_promotes_thread); + g_test_add_func ("/mu-query/test-mu-threads-orphan-promotes-thread", + test_mu_threads_sort_orphan_promotes_thread); g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION, From b0357a2d7a1dd01d371b24dc6e1acc14828e1597 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 15 Jul 2014 07:23:53 +0200 Subject: [PATCH 14/25] tests: threads: Test if child message doesn't promote its thread --- .../sort/child-does-not-promote-thread/cur/A | 9 +++++++ .../sort/child-does-not-promote-thread/cur/X | 7 +++++ .../sort/child-does-not-promote-thread/cur/Y | 7 +++++ .../sort/child-does-not-promote-thread/cur/Z | 7 +++++ .../new/.noindex | 0 .../tmp/.noindex | 0 mu/tests/test-mu-threads.c | 27 +++++++++++++++++++ 7 files changed, 57 insertions(+) create mode 100644 lib/tests/testdir3/sort/child-does-not-promote-thread/cur/A create mode 100644 lib/tests/testdir3/sort/child-does-not-promote-thread/cur/X create mode 100644 lib/tests/testdir3/sort/child-does-not-promote-thread/cur/Y create mode 100644 lib/tests/testdir3/sort/child-does-not-promote-thread/cur/Z create mode 100644 lib/tests/testdir3/sort/child-does-not-promote-thread/new/.noindex create mode 100644 lib/tests/testdir3/sort/child-does-not-promote-thread/tmp/.noindex diff --git a/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/A b/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/A new file mode 100644 index 00000000..c59c42fd --- /dev/null +++ b/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/A @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: A +Message-Id: +References: +In-reply-to: +Aate: Sat, 17 May 2014 10:00:00 +0000 + +A diff --git a/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/X b/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/X new file mode 100644 index 00000000..c8ac3aa2 --- /dev/null +++ b/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/X @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: X +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +X diff --git a/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/Y b/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/Y new file mode 100644 index 00000000..ceadc203 --- /dev/null +++ b/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/Y @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: Y +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +Y diff --git a/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/Z b/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/Z new file mode 100644 index 00000000..365775b8 --- /dev/null +++ b/lib/tests/testdir3/sort/child-does-not-promote-thread/cur/Z @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: Z +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +Z diff --git a/lib/tests/testdir3/sort/child-does-not-promote-thread/new/.noindex b/lib/tests/testdir3/sort/child-does-not-promote-thread/new/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/lib/tests/testdir3/sort/child-does-not-promote-thread/tmp/.noindex b/lib/tests/testdir3/sort/child-does-not-promote-thread/tmp/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index f059e9a5..edfa1602 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -346,6 +346,31 @@ test_mu_threads_sort_orphan_promotes_thread (void) G_N_ELEMENTS (expected_desc)); } +/* Won't normally happen when sorting by date. */ +static void +test_mu_threads_sort_child_does_not_promote_thread (void) +{ + const char *query = "maildir:/sort/child-does-not-promote-thread"; + + const tinfo expected_asc [] = { + { "0", "X@msg.id", "X"}, + { "1", "Y@msg.id", "Y"}, + { "1:0", "A@msg.id", "A"}, + { "2", "Z@msg.id", "Z"}, + }; + const tinfo expected_desc [] = { + { "0", "Z@msg.id", "Z"}, + { "1", "Y@msg.id", "Y"}, + { "1:0", "A@msg.id", "A"}, + { "2", "X@msg.id", "X"}, + }; + + check_sort_by_subject_asc (query, expected_asc, + G_N_ELEMENTS (expected_asc)); + check_sort_by_subject_desc (query, expected_desc, + G_N_ELEMENTS (expected_desc)); +} + int main (int argc, char *argv[]) { @@ -361,6 +386,8 @@ main (int argc, char *argv[]) test_mu_threads_sort_2nd_child_promotes_thread); g_test_add_func ("/mu-query/test-mu-threads-orphan-promotes-thread", test_mu_threads_sort_orphan_promotes_thread); + g_test_add_func ("/mu-query/test-mu-threads-sort-child-does-not-promote-thread", + test_mu_threads_sort_child_does_not_promote_thread); g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION, From cbfe28b8852da65dc1b8db17962cd3816c403606 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 15 Jul 2014 07:24:21 +0200 Subject: [PATCH 15/25] tests: threads: Test if grandchild message promotes its thread --- .../sort/grandchild-promotes-thread/cur/A | 7 +++++ .../sort/grandchild-promotes-thread/cur/B | 7 +++++ .../sort/grandchild-promotes-thread/cur/C | 9 ++++++ .../sort/grandchild-promotes-thread/cur/D | 7 +++++ .../sort/grandchild-promotes-thread/cur/E | 9 ++++++ .../grandchild-promotes-thread/new/.noindex | 0 .../grandchild-promotes-thread/tmp/.noindex | 0 mu/tests/test-mu-threads.c | 28 +++++++++++++++++++ 8 files changed, 67 insertions(+) create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-thread/cur/A create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-thread/cur/B create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-thread/cur/C create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-thread/cur/D create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-thread/cur/E create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-thread/new/.noindex create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-thread/tmp/.noindex diff --git a/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/A b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/A new file mode 100644 index 00000000..85130e80 --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/A @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: A +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +A diff --git a/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/B b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/B new file mode 100644 index 00000000..254aeb72 --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/B @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: B +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +B diff --git a/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/C b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/C new file mode 100644 index 00000000..6d1e19af --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/C @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: C +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +C diff --git a/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/D b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/D new file mode 100644 index 00000000..de61bc13 --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/D @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: D +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +D diff --git a/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/E b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/E new file mode 100644 index 00000000..d605b4b8 --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-thread/cur/E @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: E +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +E diff --git a/lib/tests/testdir3/sort/grandchild-promotes-thread/new/.noindex b/lib/tests/testdir3/sort/grandchild-promotes-thread/new/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/lib/tests/testdir3/sort/grandchild-promotes-thread/tmp/.noindex b/lib/tests/testdir3/sort/grandchild-promotes-thread/tmp/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index edfa1602..4e89d861 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -371,6 +371,32 @@ test_mu_threads_sort_child_does_not_promote_thread (void) G_N_ELEMENTS (expected_desc)); } +static void +test_mu_threads_sort_grandchild_promotes_thread (void) +{ + const char *query = "maildir:/sort/grandchild-promotes-thread"; + + const tinfo expected_asc [] = { + { "0", "A@msg.id", "A"}, + { "1", "D@msg.id", "D"}, + { "2", "B@msg.id", "B"}, + { "2:0", "C@msg.id", "C"}, + { "2:0:0", "E@msg.id", "E"}, + }; + const tinfo expected_desc [] = { + { "0", "B@msg.id", "B"}, + { "0:0", "C@msg.id", "C"}, + { "0:0:0", "E@msg.id", "E"}, + { "1", "D@msg.id", "D"}, + { "2", "A@msg.id", "A"}, + }; + + check_sort_by_subject_asc (query, expected_asc, + G_N_ELEMENTS (expected_asc)); + check_sort_by_subject_desc (query, expected_desc, + G_N_ELEMENTS (expected_desc)); +} + int main (int argc, char *argv[]) { @@ -388,6 +414,8 @@ main (int argc, char *argv[]) test_mu_threads_sort_orphan_promotes_thread); g_test_add_func ("/mu-query/test-mu-threads-sort-child-does-not-promote-thread", test_mu_threads_sort_child_does_not_promote_thread); + g_test_add_func ("/mu-query/test-mu-threads-sort-grandchild-promotes-thread", + test_mu_threads_sort_grandchild_promotes_thread); g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION, From 856a651d38a520b614d6147f01afccb0cc84fa23 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 15 Jul 2014 07:24:47 +0200 Subject: [PATCH 16/25] tests: threads: Test if grandchild message promotes only its subthread --- .../grandchild-promotes-only-subthread/cur/A | 7 +++++ .../grandchild-promotes-only-subthread/cur/B | 7 +++++ .../grandchild-promotes-only-subthread/cur/C | 9 ++++++ .../grandchild-promotes-only-subthread/cur/D | 9 ++++++ .../grandchild-promotes-only-subthread/cur/E | 9 ++++++ .../grandchild-promotes-only-subthread/cur/F | 9 ++++++ .../grandchild-promotes-only-subthread/cur/G | 7 +++++ .../new/.noindex | 0 .../tmp/.noindex | 0 mu/tests/test-mu-threads.c | 31 +++++++++++++++++++ 10 files changed, 88 insertions(+) create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/A create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/B create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/C create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/D create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/E create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/F create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/G create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/new/.noindex create mode 100644 lib/tests/testdir3/sort/grandchild-promotes-only-subthread/tmp/.noindex diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/A b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/A new file mode 100644 index 00000000..85130e80 --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/A @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: A +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +A diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/B b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/B new file mode 100644 index 00000000..254aeb72 --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/B @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: B +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +B diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/C b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/C new file mode 100644 index 00000000..6d1e19af --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/C @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: C +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +C diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/D b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/D new file mode 100644 index 00000000..1e4861df --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/D @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: D +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +D diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/E b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/E new file mode 100644 index 00000000..bb7f5f39 --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/E @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: E +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +E diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/F b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/F new file mode 100644 index 00000000..7c4275d7 --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/F @@ -0,0 +1,9 @@ +From: testfrom@example.com +To: testto@example.com +Subject: F +Message-Id: +References: +In-reply-to: +Date: Sat, 17 May 2014 10:00:00 +0000 + +F diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/G b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/G new file mode 100644 index 00000000..4849455f --- /dev/null +++ b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/cur/G @@ -0,0 +1,7 @@ +From: testfrom@example.com +To: testto@example.com +Subject: G +Message-Id: +Date: Sat, 17 May 2014 10:00:00 +0000 + +G diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/new/.noindex b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/new/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/tmp/.noindex b/lib/tests/testdir3/sort/grandchild-promotes-only-subthread/tmp/.noindex new file mode 100644 index 00000000..e69de29b diff --git a/mu/tests/test-mu-threads.c b/mu/tests/test-mu-threads.c index 4e89d861..e11046fd 100644 --- a/mu/tests/test-mu-threads.c +++ b/mu/tests/test-mu-threads.c @@ -397,6 +397,35 @@ test_mu_threads_sort_grandchild_promotes_thread (void) G_N_ELEMENTS (expected_desc)); } +static void +test_mu_threads_sort_granchild_promotes_only_subthread (void) +{ + const char *query = "maildir:/sort/grandchild-promotes-only-subthread"; + + const tinfo expected_asc [] = { + { "0", "A@msg.id", "A"}, + { "1", "B@msg.id", "B"}, + { "1:0", "C@msg.id", "C"}, + { "1:1", "E@msg.id", "E"}, + { "1:2", "D@msg.id", "D"}, + { "1:2:0", "F@msg.id", "F"}, + { "2", "G@msg.id", "G"}, + }; + const tinfo expected_desc [] = { + { "0", "G@msg.id", "G"}, + { "1", "B@msg.id", "B"}, + { "1:0", "D@msg.id", "D"}, + { "1:0:0", "F@msg.id", "F"}, + { "1:1", "E@msg.id", "E"}, + { "1:2", "C@msg.id", "C"}, + { "2", "A@msg.id", "A"}, + }; + + check_sort_by_subject_asc (query, expected_asc, + G_N_ELEMENTS (expected_asc)); + check_sort_by_subject_desc (query, expected_desc, + G_N_ELEMENTS (expected_desc)); +} int main (int argc, char *argv[]) { @@ -416,6 +445,8 @@ main (int argc, char *argv[]) test_mu_threads_sort_child_does_not_promote_thread); g_test_add_func ("/mu-query/test-mu-threads-sort-grandchild-promotes-thread", test_mu_threads_sort_grandchild_promotes_thread); + g_test_add_func ("/mu-query/test-mu-threads-sort-grandchild-promotes-only-subthread", + test_mu_threads_sort_granchild_promotes_only_subthread); g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION, From d93b8135a6df276fefd9c07ddab14aa12a53515b Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Mon, 7 Jul 2014 06:22:57 +0200 Subject: [PATCH 17/25] Revert "* bugfix for issue 164" This reverts commit c7b28419abd9d53ff36412e4fedaf308ce13c552. The reverted change fails to sort threads correctly when there is an empty container, serving as a parent to orphan messages, in the thread tree as demonstrated by the test in commit f49296759ef8 ("tests: threads: Test if orphan message promotes its thread"). Also, the reverted commit introduces a performance hit. The time it takes to sort threads has increased roughly by a factor of 4. Current state: $ perf stat --event=task-clock --repeat=10 -- \ mu find maildir:/INBOX -n 1 -t > /dev/null Performance counter stats for 'mu find maildir:/INBOX -n 1 -t' (10 runs): 4967.692519 task-clock (msec) # 1.000 CPUs utilized ( +- 0.14% ) 4.969247128 seconds time elapsed ( +- 0.14% ) With the reverted patch applied: $ perf stat --event=task-clock --repeat=10 -- \ mu find maildir:/INBOX -n 1 -t > /dev/null Performance counter stats for 'mu find maildir:/INBOX -n 1 -t' (10 runs): 1231.761588 task-clock (msec) # 0.996 CPUs utilized ( +- 1.02% ) 1.236209133 seconds time elapsed ( +- 1.08% ) The benchmark was ran on a maildir with ~16k messages: $ mu find maildir:/INBOX | wc -l 16503 --- lib/mu-container.c | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/lib/mu-container.c b/lib/mu-container.c index ec7b3795..34db96a5 100644 --- a/lib/mu-container.c +++ b/lib/mu-container.c @@ -317,22 +317,6 @@ struct _SortFuncData { }; typedef struct _SortFuncData SortFuncData; -static MuContainer* -get_top_msg (MuContainer *c, MuMsgFieldId mfid) -{ - MuContainer *piv, *extreme = c; - for (piv = c; piv != NULL && piv->msg != NULL; piv = piv->child) { - if (mu_msg_cmp (piv->msg, extreme->msg, mfid) > 0) - extreme = piv; - if (piv != c && piv->next) { - MuContainer *sub = get_top_msg (piv->next, mfid); - - if (sub->msg != NULL && mu_msg_cmp (sub->msg, extreme->msg, mfid) > 0) - extreme = sub; - } - } - return extreme; -} static int sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data) @@ -344,9 +328,6 @@ sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data) for (a1 = a; a1->msg == NULL && a1->child != NULL; a1 = a1->child); for (b1 = b; b1->msg == NULL && b1->child != NULL; b1 = b1->child); - a1 = get_top_msg (a1, data->mfid); - b1 = get_top_msg (b1, data->mfid); - if (a1 == b1) return 0; else if (!a1->msg) From dc3be515afc528ac4f5f419fae2a582d483e84ae Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 15 Jul 2014 06:33:00 +0200 Subject: [PATCH 18/25] mu: Extract function for comparing two containers --- lib/mu-container.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/mu-container.c b/lib/mu-container.c index 34db96a5..fbac6bb2 100644 --- a/lib/mu-container.c +++ b/lib/mu-container.c @@ -317,6 +317,18 @@ struct _SortFuncData { }; typedef struct _SortFuncData SortFuncData; +static int +container_cmp (MuContainer *a, MuContainer *b, MuMsgFieldId mfid) +{ + if (a == b) + return 0; + else if (!a->msg) + return 1; + else if (!b->msg) + return -1; + + return mu_msg_cmp (a->msg, b->msg, mfid); +} static int sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data) @@ -328,17 +340,10 @@ sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data) for (a1 = a; a1->msg == NULL && a1->child != NULL; a1 = a1->child); for (b1 = b; b1->msg == NULL && b1->child != NULL; b1 = b1->child); - if (a1 == b1) - return 0; - else if (!a1->msg) - return 1; - else if (!b1->msg) - return -1; - if (data->descending) - return mu_msg_cmp (b1->msg, a1->msg, data->mfid); + return container_cmp (b1, a1, data->mfid); else - return mu_msg_cmp (a1->msg, b1->msg, data->mfid); + return container_cmp (a1, b1, data->mfid); } static MuContainer* From f724f4a57d242171b68f327c572dbd5d61d70d58 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Tue, 1 Jul 2014 07:22:57 +0200 Subject: [PATCH 19/25] mu: Consider an empty container to be less than anything else Reasoning being that, arguably, it is the least surprising thing to do. --- lib/mu-container.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mu-container.c b/lib/mu-container.c index fbac6bb2..7011fec5 100644 --- a/lib/mu-container.c +++ b/lib/mu-container.c @@ -323,9 +323,9 @@ container_cmp (MuContainer *a, MuContainer *b, MuMsgFieldId mfid) if (a == b) return 0; else if (!a->msg) - return 1; - else if (!b->msg) return -1; + else if (!b->msg) + return 1; return mu_msg_cmp (a->msg, b->msg, mfid); } From 97101f1f82ba55015484c124d2f2990c0773b75c Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Mon, 7 Jul 2014 06:23:22 +0200 Subject: [PATCH 20/25] mu: Prune empty container when an only child gets promoted to the root set --- lib/mu-container.c | 17 ++++++++++++++++- lib/mu-container.h | 17 +++++++++++++++-- lib/mu-threader.c | 13 +++---------- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/lib/mu-container.c b/lib/mu-container.c index 7011fec5..a201c30c 100644 --- a/lib/mu-container.c +++ b/lib/mu-container.c @@ -263,9 +263,24 @@ mu_container_foreach (MuContainer *c, MuContainerForeachFunc func, return func (c, user_data); } +MuContainer* +mu_container_splice_children (MuContainer *c, MuContainer *sibling) +{ + MuContainer *children; + + g_return_val_if_fail (c, NULL); + g_return_val_if_fail (sibling, NULL); + + children = sibling->child; + sibling->child = NULL; + + c = mu_container_remove_sibling (c, sibling); + + return mu_container_append_siblings (c, children); +} MuContainer* -mu_container_splice_children (MuContainer *parent, MuContainer *child) +mu_container_splice_grandchildren (MuContainer *parent, MuContainer *child) { MuContainer *newchild; diff --git a/lib/mu-container.h b/lib/mu-container.h index ec9d7f72..c80f0273 100644 --- a/lib/mu-container.h +++ b/lib/mu-container.h @@ -122,6 +122,19 @@ MuContainer* mu_container_remove_child (MuContainer *c, MuContainer *child); */ MuContainer* mu_container_remove_sibling (MuContainer *c, MuContainer *sibling); +/** + * promote sibling's children to be this container's siblings and + * remove the sibling + * + * @param c a container instance + * @param sibling a sibling of this container + * + * @return the container with the sibling's children promoted and the + * sibling itself removed + */ + +MuContainer* mu_container_splice_children (MuContainer *c, + MuContainer *sibling); /** * promote child's children to be parent's children and remove child @@ -131,8 +144,8 @@ MuContainer* mu_container_remove_sibling (MuContainer *c, MuContainer *sibling); * * @return the new container with it's children's children promoted */ -MuContainer* mu_container_splice_children (MuContainer *parent, - MuContainer *child); +MuContainer* mu_container_splice_grandchildren (MuContainer *parent, + MuContainer *child); typedef gboolean (*MuContainerForeachFunc) (MuContainer*, gpointer); diff --git a/lib/mu-threader.c b/lib/mu-threader.c index 719508d2..c42e166c 100644 --- a/lib/mu-threader.c +++ b/lib/mu-threader.c @@ -388,7 +388,7 @@ prune_maybe (MuContainer *c) if (cur->flags & MU_CONTAINER_FLAG_DELETE) c = mu_container_remove_child (c, cur); else if (cur->flags & MU_CONTAINER_FLAG_SPLICE) - c = mu_container_splice_children (c, cur); + c = mu_container_splice_grandchildren (c, cur); } g_return_val_if_fail (c, FALSE); @@ -433,17 +433,10 @@ prune_empty_containers (MuContainer *root_set) /* and prune the root_set itself... */ for (cur = root_set; cur; cur = cur->next) { - if (cur->flags & MU_CONTAINER_FLAG_DELETE) root_set = mu_container_remove_sibling (root_set, cur); - - else if (cur->flags & MU_CONTAINER_FLAG_SPLICE) { - MuContainer *newchild; - newchild = cur->child; - cur->child = NULL; - root_set = mu_container_append_siblings (root_set, - newchild); - } + else if (cur->flags & MU_CONTAINER_FLAG_SPLICE) + root_set = mu_container_splice_children (root_set, cur); } return root_set; From 619fb868853b2353720785cee4596c3a6191d202 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Mon, 7 Jul 2014 06:24:01 +0200 Subject: [PATCH 21/25] mu: Update container's pointer to last sibling when converting from a list --- lib/mu-container.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/mu-container.c b/lib/mu-container.c index a201c30c..1dd83829 100644 --- a/lib/mu-container.c +++ b/lib/mu-container.c @@ -308,17 +308,28 @@ mu_container_to_list (MuContainer *c) return lst; } +static gpointer +list_last_data (GSList *lst) +{ + GSList *tail; + + tail = g_slist_last (lst); + + return tail->data; +} static MuContainer* mu_container_from_list (GSList *lst) { - MuContainer *c, *cur; + MuContainer *c, *cur, *tail; if (!lst) return NULL; + tail = list_last_data (lst); for (c = cur = (MuContainer*)lst->data; cur; lst = g_slist_next(lst)) { cur->next = lst ? (MuContainer*)lst->data : NULL; + cur->last = tail; cur=cur->next; } From 32f5c8b1f6de16bd183a38ff37452956e28cde47 Mon Sep 17 00:00:00 2001 From: Jakub Sitnicki Date: Mon, 7 Jul 2014 06:23:11 +0200 Subject: [PATCH 22/25] mu: Sort containers by comparing their subtree leaders Traverse the container tree depth first and for each container find the node in the subtree rooted at this container which comes first in the descending sort order. Remember it as the subtree leader. Then, while sorting siblings, compare their subtree leaders instead of the sibling containers themselves. IOW, make threads containing the newest message float to the top when sorting by date in the descending order. There is no significant performance degradation when sorting a mailbox with ~16k messages: $ mu find maildir:/INBOX | wc -l 16503 Current state: $ perf stat --event=task-clock --repeat=10 -- \ mu find maildir:/INBOX -n 1 -t > /dev/null Performance counter stats for 'mu find maildir:/INBOX -n 1 -t' (10 runs): 1231.761588 task-clock (msec) # 0.996 CPUs utilized ( +- 1.02% ) 1.236209133 seconds time elapsed ( +- 1.08% ) With patch applied: $ perf stat --event=task-clock --repeat=10 -- \ mu find maildir:/INBOX -n 1 -t > /dev/null Performance counter stats for 'mu find maildir:/INBOX -n 1 -t' (10 runs): 1459.883316 task-clock (msec) # 0.998 CPUs utilized ( +- 0.72% ) 1.462540088 seconds time elapsed ( +- 0.77% ) This implements https://github.com/djcb/mu/issues/164. --- lib/mu-container.c | 45 ++++++++++++++++++++++++++++++++++----------- lib/mu-container.h | 5 +++++ 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/lib/mu-container.c b/lib/mu-container.c index 1dd83829..fbe612ff 100644 --- a/lib/mu-container.c +++ b/lib/mu-container.c @@ -52,6 +52,7 @@ mu_container_new (MuMsg *msg, guint docid, const char *msgid) if (msg) c->msg = mu_msg_ref (msg); + c->leader = c; c->docid = docid; c->msgid = msgid; @@ -356,20 +357,41 @@ container_cmp (MuContainer *a, MuContainer *b, MuMsgFieldId mfid) return mu_msg_cmp (a->msg, b->msg, mfid); } +static gboolean +container_is_leaf (const MuContainer *c) +{ + return c->child == NULL; +} + +static MuContainer* +container_max (MuContainer *a, MuContainer *b, MuMsgFieldId mfid) +{ + return container_cmp (a, b, mfid) > 0 ? a : b; +} + +static MuContainer* +find_sorted_tree_leader (MuContainer *root, SortFuncData *order) +{ + MuContainer *last_child; + + if (container_is_leaf (root)) + return root; + + if (!order->descending) + last_child = root->child->last; + else /* reversed order, first is last */ + last_child = root->child; + + return container_max (root, last_child->leader, order->mfid); +} + static int sort_func_wrapper (MuContainer *a, MuContainer *b, SortFuncData *data) { - MuContainer *a1, *b1; - - /* use the first non-empty 'left child' message if this one - * is */ - for (a1 = a; a1->msg == NULL && a1->child != NULL; a1 = a1->child); - for (b1 = b; b1->msg == NULL && b1->child != NULL; b1 = b1->child); - if (data->descending) - return container_cmp (b1, a1, data->mfid); + return container_cmp (b->leader, a->leader, data->mfid); else - return container_cmp (a1, b1, data->mfid); + return container_cmp (a->leader, b->leader, data->mfid); } static MuContainer* @@ -381,9 +403,11 @@ container_sort_real (MuContainer *c, SortFuncData *sfdata) if (!c) return NULL; - for (cur = c; cur; cur = cur->next) + for (cur = c; cur; cur = cur->next) { if (cur->child) cur->child = container_sort_real (cur->child, sfdata); + cur->leader = find_sorted_tree_leader (cur, sfdata); + } /* sort siblings */ lst = mu_container_to_list (c); @@ -396,7 +420,6 @@ container_sort_real (MuContainer *c, SortFuncData *sfdata) return c; } - MuContainer* mu_container_sort (MuContainer *c, MuMsgFieldId mfid, gboolean descending, gpointer user_data) diff --git a/lib/mu-container.h b/lib/mu-container.h index c80f0273..9f2686a8 100644 --- a/lib/mu-container.h +++ b/lib/mu-container.h @@ -45,6 +45,11 @@ struct _MuContainer { * */ struct _MuContainer *last; + /* Node in the subtree rooted at this node which comes first + * in the descending sort order, e.g. the latest message if + * sorting by date. We compare the leaders when ordering + * subtrees. */ + struct _MuContainer *leader; MuMsg *msg; const char *msgid; From c99ccf9a19dee787cddb609ca9890dc5503c5cfa Mon Sep 17 00:00:00 2001 From: mjn Date: Fri, 8 Aug 2014 13:18:29 +0200 Subject: [PATCH 23/25] Lightly copyedit the documentation and docstrings --- man/mu-find.1 | 2 +- mu4e/mu4e-mark.el | 8 ++++---- mu4e/mu4e.texi | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/man/mu-find.1 b/man/mu-find.1 index 738d24f5..345befc9 100644 --- a/man/mu-find.1 +++ b/man/mu-find.1 @@ -133,7 +133,7 @@ of the message, as listed in the following table: p,passed Passed ('Handled') r,replied Replied s,seen Seen - t,thrashed Marked for deletion + t,trashed Marked for deletion a,attach Has attachment z,signed Signed message x,encrypted Encrypted message diff --git a/mu4e/mu4e-mark.el b/mu4e/mu4e-mark.el index 8ce0b177..10a84a09 100644 --- a/mu4e/mu4e-mark.el +++ b/mu4e/mu4e-mark.el @@ -138,7 +138,7 @@ The following marks are available, and the corresponding props: `flag' n mark this message for flagging `move' y move the message to some folder `read' n mark the message as read - `trash' y thrash the message to some folder + `trash' y trash the message to some folder `unflag' n mark this message for unflagging `untrash' n remove the 'trashed' flag from a message `unmark' n unmark this message @@ -286,7 +286,7 @@ user which one)." mu4e~mark-map)))) (defun mu4e~mark-check-target (target) - "Check if the target exists if not, offer to create it." + "Check if the target exists; if not, offer to create it." (let ((fulltarget (concat mu4e-maildir target))) (if (not (mu4e-create-maildir-maybe fulltarget)) (mu4e-error "Target dir %s does not exist " fulltarget) @@ -298,9 +298,9 @@ user which one)." After the actions have been executed succesfully, the affected messages are *hidden* from the current header list. Since the headers are the result of a search, we cannot be certain that the -messages no longer matches the current one - to get that +messages no longer match the current one - to get that certainty, we need to rerun the search, but we don't want to do -that automatically, as it may be too slow and/or break the users +that automatically, as it may be too slow and/or break the user's flow. Therefore, we hide the message, which in practice seems to work well. diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index e7ba8b01..4a243720 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -810,7 +810,7 @@ W toggle include-related marking ------- d mark for moving to the trash folder -= mark for remove thrash flags ('untrash') += mark for removing trash flag ('untrash') DEL,D mark for complete deletion m mark for moving to another maildir folder r mark for refiling @@ -1076,7 +1076,7 @@ M-right next query marking ------- d mark for moving to the trash folder -= mark for remove thrash flags ('untrash') += mark for removing trash flag ('untrash') DEL,D mark for complete deletion m mark for moving to another maildir folder r mark for refiling @@ -1836,12 +1836,12 @@ previous/next queries, you can use @kbd{M-x mu4e-headers-forget-queries}. It can be useful to narrow existing search results, that is, to add some clauses to the current query to match fewer messages. -For example, suppose you're looking at the some mailing list, perhaps by +For example, suppose you're looking at some mailing list, perhaps by jumping to a maildir (@kbd{M-x mu4e-headers-jump-to-maildir}, @key{j}) or because you followed some bookmark (@kbd{M-x mu4e-headers-search-bookmark}, @key{b}). Now, you want to narrow things down to only those messages that have attachments. -1 + This is when @kbd{M-x mu4e-headers-search-narrow} (@key{/}) comes in handy. It asks for an additional search pattern, which is appended to the current search query, in effect getting you the subset of the currently shown headers that From 3f077cc86d323b86994e05ea0617b9d14e7aa661 Mon Sep 17 00:00:00 2001 From: djcb Date: Mon, 11 Aug 2014 20:43:34 +0300 Subject: [PATCH 24/25] Revert "* bump version to 0.9.9.6" This reverts commit ab58307feaa80392db667671136815bc0885e154. --- NEWS | 21 +-------------------- configure.ac | 4 ++-- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/NEWS b/NEWS index e5b7037b..4fb9dc56 100644 --- a/NEWS +++ b/NEWS @@ -12,29 +12,10 @@ - give messages without msgids fake-message-ids; this fixes the problem where such messages were not found in --include-related queries - cleanup of the query parser - - much improved date parsing - - support recursive maildirs - - many fixes in the query parser; there are still a number of - corner cases though, which probably requires writing a custom - query parser to fix - - drop gmime 2.4 support *** mu4e - - update the emacs <-> backend protocol; documented in the - mu-server man page - - improve saving attachment - - allow for visiting multiple URIs - - much improved navigation within messages - - - mug - - - only support gtk+ 3.x - - - mu-guile: - - - more examples; bug fixes - + - update the emacs <-> backend protocol; documented in the mu-server man page ** Release 0.9.9.5 diff --git a/configure.ac b/configure.ac index 620914cb..f9140e17 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -## Copyright (C) 2008-2014 Dirk-Jan C. Binnema +## Copyright (C) 2008-2013 Dirk-Jan C. Binnema ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -14,7 +14,7 @@ ## along with this program; if not, write to the Free Software Foundation, ## Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -AC_INIT([mu],[0.9.9.6],[http://code.google.com/p/mu0/issues/list],[mu]) +AC_INIT([mu],[0.9.9.6pre3],[http://code.google.com/p/mu0/issues/list],[mu]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_SRCDIR([mu/mu.cc]) # libtoolize wants to put some stuff in here; if you have an old From d4be790445037e00ece05dec1eface35f19c498f Mon Sep 17 00:00:00 2001 From: djcb Date: Mon, 11 Aug 2014 23:20:27 +0300 Subject: [PATCH 25/25] * mu4e: minor doc fixes --- mu4e/mu4e.texi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mu4e/mu4e.texi b/mu4e/mu4e.texi index 4a243720..7f754f82 100644 --- a/mu4e/mu4e.texi +++ b/mu4e/mu4e.texi @@ -3231,10 +3231,10 @@ value)} pairs: ("Account2" (mu4e-sent-folder "/Account2/Saved Items") (mu4e-drafts-folder "/Account2/Drafts") - (user-mail-address "my.address@@account2.tld) - (smtpmail-default-smtp-server "smtp.account2.tld) + (user-mail-address "my.address@@account2.tld") + (smtpmail-default-smtp-server "smtp.account2.tld") (smtpmail-local-domain "account2.tld") - (smtpmail-smtp-server "smtp.account2.tld) + (smtpmail-smtp-server "smtp.account2.tld") (smtpmail-stream-type starttls) (smtpmail-smtp-service 587)))) @end lisp