]> git.cworth.org Git - notmuch/commitdiff
emacs/show: provide notmuch-show-choose-duplicate
authorDavid Bremner <david@tethera.net>
Fri, 1 Jul 2022 21:45:45 +0000 (18:45 -0300)
committerDavid Bremner <david@tethera.net>
Sat, 30 Jul 2022 11:42:12 +0000 (08:42 -0300)
This new command allows the user to interactively choose a different
duplicate (file) to display for a given message in
notmuch-show-mode. Since both tree and unthreaded view use
notmuch-show-mode, this provides the same facility there.

devel/emacs-keybindings.org
emacs/notmuch-lib.el
emacs/notmuch-show.el
test/T450-emacs-show.sh
test/T460-emacs-tree.sh
test/T465-emacs-unthreaded.sh

index 00977bc3a11213030320327965c77eac61b577df..ad7f72ef0bb3ce039a9bd3fd22988c93b80565c6 100644 (file)
@@ -40,6 +40,7 @@
 | Z            | notmuch-tree-from-search-current-query | notmuch-tree-from-show-current-query                  |                                         |
 | =!=          |                                        | notmuch-show-toggle-elide-non-matching                |                                         |
 | =#=          |                                        | notmuch-show-print-message                            |                                         |
+| =%=          |                                        | notmuch-show-replace-msg                              |                                         |
 | =$=          |                                        | notmuch-show-toggle-process-crypto                    |                                         |
 | =*=          | notmuch-search-tag-all                 | notmuch-show-tag-all                                  | notmuch-tree-tag-thread                 |
 | +            | notmuch-search-add-tag                 | notmuch-show-add-tag                                  | notmuch-tree-add-tag                    |
index cc706924a7efcb9ab9e209c59f4fa641372eb7eb..84ba8c5e56de2aa151682bea74e30a4f3808b2e3 100644 (file)
@@ -1029,7 +1029,7 @@ status."
 
 (defvar-local notmuch-show-process-crypto nil)
 
-(defun notmuch--run-show (search-terms)
+(defun notmuch--run-show (search-terms &optional duplicate)
   "Return a list of threads of messages matching SEARCH-TERMS.
 
 A thread is a forest or list of trees. A tree is a two element
@@ -1038,6 +1038,8 @@ is a possibly empty forest of replies."
   (let ((args '("show" "--format=sexp" "--format-version=5")))
     (when notmuch-show-process-crypto
       (setq args (append args '("--decrypt=true"))))
+    (when duplicate
+      (setq args (append args (list (format "--duplicate=%d" duplicate)))))
     (setq args (append args search-terms))
     (apply #'notmuch-call-notmuch-sexp args)))
 
index 64b3919b7d4c12054394b4ed10ef21ab1991990c..a4b0c432be98d8e73d3fefd2c5a69abe89e05faf 100644 (file)
@@ -1127,6 +1127,30 @@ is t, hide the part initially and show the button."
 (defvar notmuch-show-previous-subject "")
 (make-variable-buffer-local 'notmuch-show-previous-subject)
 
+(defun notmuch-show-choose-duplicate (duplicate)
+  (interactive "Nduplicate: ")
+  (let ((count (length (notmuch-show-get-prop :filename))))
+    (when (or (> duplicate count)
+             (< duplicate 1))
+      (error "Duplicate %d out of range [1,%d]" duplicate count)))
+  (notmuch-show-move-to-message-top)
+  (save-excursion
+    (let* ((extent (notmuch-show-message-extent))
+          (id (notmuch-show-get-message-id))
+          (depth (notmuch-show-get-depth))
+          (inhibit-read-only t)
+          (new-msg (notmuch--run-show (list id) duplicate)))
+      ;; clean up existing overlays to avoid extending them.
+      (dolist (o (overlays-in (car extent) (cdr extent)))
+       (delete-overlay o))
+      ;; pretend insertion is happening at end of buffer
+      (narrow-to-region (point-min) (car extent))
+      ;; Insert first, then delete, to avoid marker for start of next
+      ;; message being in same place as the start of this one.
+      (notmuch-show-insert-msg new-msg depth)
+      (widen)
+      (delete-region (point) (cdr extent)))))
+
 (defun notmuch-show-insert-msg (msg depth)
   "Insert the message MSG at depth DEPTH in the current thread."
   (let* ((headers (plist-get msg :headers))
@@ -1583,6 +1607,7 @@ reset based on the original query."
     (define-key map "#" 'notmuch-show-print-message)
     (define-key map "!" 'notmuch-show-toggle-elide-non-matching)
     (define-key map "$" 'notmuch-show-toggle-process-crypto)
+    (define-key map "%" 'notmuch-show-choose-duplicate)
     (define-key map "<" 'notmuch-show-toggle-thread-indentation)
     (define-key map "t" 'toggle-truncate-lines)
     (define-key map "." 'notmuch-show-part-map)
index 64f174cf63d709576234f41c639828ea964c5c7b..9cc90d91650cf230d033d6c14c3ac90a09dcb0fa 100755 (executable)
@@ -338,4 +338,33 @@ when we detect the word "attachment" and there's no attach? :p
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+add_email_corpus duplicate
+
+ID3=87r2ecrr6x.fsf@zephyr.silentflame.com
+test_begin_subtest "duplicate=3"
+test_emacs "(notmuch-show \"id:${ID3}\")
+          (notmuch-show-choose-duplicate 3)
+          (test-visible-output \"OUTPUT\")"
+output=$(grep "Subject:" OUTPUT)
+file=$(notmuch search --output=files id:${ID3} | head -n 3 | tail -n 1)
+subject=$(grep '^Subject:' $file)
+test_expect_equal "$output" "$subject"
+
+test_begin_subtest "duplicate=0"
+test_emacs "(test-log-error
+             (notmuch-show \"id:${ID3}\")
+             (notmuch-show-choose-duplicate 0))"
+cat <<EOF > EXPECTED
+(error Duplicate 0 out of range [1,5])
+EOF
+test_expect_equal_file EXPECTED MESSAGES
+
+test_begin_subtest "duplicate=1000"
+test_emacs "(test-log-error
+             (notmuch-show \"id:${ID3}\")
+             (notmuch-show-choose-duplicate 1000))"
+cat <<EOF > EXPECTED
+(error Duplicate 1000 out of range [1,5])
+EOF
+test_expect_equal_file EXPECTED MESSAGES
 test_done
index 0f23b418ecfa1bd8da04676f9d327a14b2e7fe5e..bae26e3bb49cb7e4e189e10d01e51f7ac3fab958 100755 (executable)
@@ -200,4 +200,18 @@ test_emacs '(test-log-error
                (notmuch-tree "*")))'
 test_expect_equal "$(cat MESSAGES)" "COMPLETE"
 
+add_email_corpus duplicate
+
+ID3=87r2ecrr6x.fsf@zephyr.silentflame.com
+test_begin_subtest "duplicate=3"
+test_emacs "(notmuch-tree \"id:${ID3}\")
+          (notmuch-test-wait)
+          (notmuch-tree-show-message t)
+          (notmuch-show-choose-duplicate 3)
+          (test-visible-output \"OUTPUT\")"
+output=$(grep "Subject:" OUTPUT)
+file=$(notmuch search --output=files id:${ID3} | head -n 3 | tail -n 1)
+subject=$(grep '^Subject:' $file)
+test_expect_equal "$output" "$subject"
+
 test_done
index e7bc1439c50dc66632d5b3f905c55a5a59f9335b..9b96c7d75d43741f782ed47f6ca4c0851014f237 100755 (executable)
@@ -57,4 +57,19 @@ test_emacs '(test-log-error
                (notmuch-unthreaded "*")))'
 test_expect_equal "$(cat MESSAGES)" "COMPLETE"
 
+add_email_corpus duplicate
+
+ID3=87r2ecrr6x.fsf@zephyr.silentflame.com
+test_begin_subtest "duplicate=3"
+test_emacs "(let ((notmuch-tree-show-out t))
+             (notmuch-unthreaded \"id:${ID3}\")
+             (notmuch-test-wait)
+             (notmuch-tree-show-message nil)
+             (notmuch-show-choose-duplicate 3)
+             (test-visible-output \"OUTPUT\"))"
+output=$(grep "Subject:" OUTPUT)
+file=$(notmuch search --output=files id:${ID3} | head -n 3 | tail -n 1)
+subject=$(grep '^Subject:' $file)
+test_expect_equal "$output" "$subject"
+
 test_done