This obsolete the series starting at id:20210602233108.855449-1-david@tethera.net Alan reported that this fix worked for him in tree-mode, which is great. In my tests, there is actually an uncaught exception that makes me think the tree / subject window is not quite working in tree-mode, but according to my tests (included in the new series), it _is_ working in unthreaded view. The other change since the initial series is that both invocations of notmuch-show are now wrapped in a let-binding of notmuch-show-single-message. From an API point of view, the thing we have to decide is if we are going to support notmuch-show-single-message for the forseeable future, or if we should namespace it to indicate it is internal.
Initial focus is on behaviour with large threads. The second test replicates a bug reported by Alan Schmitt in id:87lf7sojbq.fsf@m4x.org. --- test/T465-emacs-unthreaded.sh | 40 +++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100755 test/T465-emacs-unthreaded.sh diff --git a/test/T465-emacs-unthreaded.sh b/test/T465-emacs-unthreaded.sh new file mode 100755 index 00000000..f9abcebd --- /dev/null +++ b/test/T465-emacs-unthreaded.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +test_description="emacs unthreaded interface" +. $(dirname "$0")/test-lib.sh || exit 1 +. $(dirname "$0")/test-lib-emacs.sh || exit 1 + +test_require_emacs + +generate_message "[id]=large-thread-1" '[subject]="large thread"' +printf " 2001-01-05 Notmuch Test Suite large thread (inbox unread)\n" \ + >> EXPECTED.unthreaded + +for num in $(seq 2 64); do + prev=$((num - 1)) + generate_message '[subject]="large thread"' "[id]=large-thread-$num" "[in-reply-to]=\<large-thread-$prev\>" + printf " 2001-01-05 Notmuch Test Suite large thread (inbox unread)\n" \ + >> EXPECTED.unthreaded +done +printf "End of search results.\n" >> EXPECTED.unthreaded + +notmuch new > new.output 2>&1 + +test_begin_subtest "large thread" +test_emacs '(let ((max-lisp-eval-depth 10)) + (notmuch-unthreaded "subject:large-thread") + (notmuch-test-wait) + (test-output))' +test_expect_equal_file EXPECTED.unthreaded OUTPUT + +test_begin_subtest "message from large thread (status)" +test_subtest_known_broken +output=$(test_emacs '(let ((max-lisp-eval-depth 10)) + (notmuch-unthreaded "subject:large-thread") + (notmuch-test-wait) + (notmuch-tree-show-message nil) + (notmuch-test-wait) + "SUCCESS")' ) +test_expect_equal "$output" '"SUCCESS"' + +test_done -- 2.30.2
This dynamically bound variable can be set when the caller of notmuch-show guarantees that exactly one message will match the query. It avoids transporting and parsing the complete thread structure. --- emacs/notmuch-show.el | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index ba93febb..9dca5d7e 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -178,6 +178,8 @@ indentation." (defvar-local notmuch-show-indent-content t) +(defvar-local notmuch-show-single-message nil) + (defvar notmuch-show-attachment-debug nil "If t log stdout and stderr from attachment handlers. @@ -1314,9 +1316,9 @@ Apply the previously saved STATE if supplied, otherwise show the first relevant message. If no messages match the query return NIL." - (let* ((cli-args (cons "--exclude=false" - (and notmuch-show-elide-non-matching-messages - (list "--entire-thread=false")))) + (let* ((cli-args (list "--exclude=false")) + (cli-args (if notmuch-show-elide-non-matching-messages (cons "--entire-thread=false" cli-args) cli-args)) + (cli-args (if notmuch-show-single-message (cons "--part=0" cli-args) cli-args)) (queries (notmuch-show--build-queries notmuch-show-thread-id notmuch-show-query-context)) (forest nil) @@ -1327,6 +1329,8 @@ If no messages match the query return NIL." (while (and (not forest) queries) (setq forest (notmuch-query-get-threads (append cli-args (list "'") (car queries) (list "'")))) + (when (and forest notmuch-show-single-message) + (setq forest (list (list (list forest))))) (setq queries (cdr queries))) (when forest (notmuch-show-insert-forest forest) -- 2.30.2
This is more efficient that notmuch-show-only-matching-messages, since we do not parse the potentially large thread structure to find a single message. This is only a partial fix for notmuch-tree view, because displaying the thread structure in the tree-mode window still crashes on long threads. It is however enough to make unthreaded view handle long threads. --- emacs/notmuch-tree.el | 6 ++++-- test/T465-emacs-unthreaded.sh | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el index 13007a13..605c0593 100644 --- a/emacs/notmuch-tree.el +++ b/emacs/notmuch-tree.el @@ -574,7 +574,7 @@ NOT change the database." (with-selected-window notmuch-tree-message-window (let (;; Since we are only displaying one message do not indent. (notmuch-show-indent-messages-width 0) - (notmuch-show-only-matching-messages t) + (notmuch-show-single-message t) ;; Ensure that `pop-to-buffer-same-window' uses the ;; window we want it to use. (display-buffer-overriding-action @@ -598,7 +598,9 @@ NOT change the database." (when id ;; We close the window to kill off un-needed buffers. (notmuch-tree-close-message-window) - (notmuch-show id)))) + ;; n-s-s-m is buffer local, so use inner let. + (let ((notmuch-show-single-message t)) + (notmuch-show id))))) (defun notmuch-tree-show-message (arg) "Show the current message. diff --git a/test/T465-emacs-unthreaded.sh b/test/T465-emacs-unthreaded.sh index f9abcebd..0dc52f3a 100755 --- a/test/T465-emacs-unthreaded.sh +++ b/test/T465-emacs-unthreaded.sh @@ -28,7 +28,6 @@ test_emacs '(let ((max-lisp-eval-depth 10)) test_expect_equal_file EXPECTED.unthreaded OUTPUT test_begin_subtest "message from large thread (status)" -test_subtest_known_broken output=$(test_emacs '(let ((max-lisp-eval-depth 10)) (notmuch-unthreaded "subject:large-thread") (notmuch-test-wait) -- 2.30.2