[PATCH v4 08/11] emacs: add notmuch-tag-undo

Subject: [PATCH v4 08/11] emacs: add notmuch-tag-undo

Date: Sat, 12 Feb 2022 16:27:39 -0400

To: notmuch@notmuchmail.org

Cc:

From: David Bremner


Keybindings are deferred to a future commit.
---
 doc/notmuch-emacs.rst      | 15 ++++++++++++
 emacs/notmuch-tag.el       | 14 +++++++++++
 test/T315-emacs-tagging.sh | 50 ++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+)

diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst
index f2667de1..991539bf 100644
--- a/doc/notmuch-emacs.rst
+++ b/doc/notmuch-emacs.rst
@@ -383,6 +383,21 @@ operations specified in ``notmuch-tagging-keys``; i.e. each
 
   |docstring::notmuch-tagging-keys|
 
+.. _notmuch-tag-undo:
+
+notmuch-tag-undo
+----------------
+
+Each notmuch buffer supporting tagging operations (i.e buffers in
+:any:`notmuch-show`, :any:`notmuch-search`, :any:`notmuch-tree`, and
+:any:`notmuch-unthreaded` mode) keeps a local stack of tagging
+operations. These can be undone via ``notmuch-tag-undo``. By default
+this is bound to the usual Emacs keys for undo.
+
+:index:`notmuch-tag-undo`
+
+   |docstring::notmuch-tag-undo|
+
 Buffer navigation
 =================
 
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 4c974679..95977881 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -278,6 +278,7 @@ This can be used with `notmuch-tag-format-image-data'."
 ;;; track history of tag operations
 (defvar-local notmuch-tag-history nil
   "Buffer local history of `notmuch-tag' function.")
+(put 'notmuch-tag-history 'permanent-local t)
 
 ;;; Format Handling
 
@@ -502,6 +503,19 @@ notmuch-after-tag-hook will be run."
 		 (query query))
     (run-hooks 'notmuch-after-tag-hook)))
 
+(defun notmuch-tag-undo ()
+  "Undo the previous tagging operation in the current buffer. Uses
+buffer local variable `notmuch-tag-history' to determine what
+that operation was."
+  (interactive)
+  (when (null notmuch-tag-history)
+    (error "no further notmuch undo information"))
+  (let* ((action (pop notmuch-tag-history))
+	 (query (plist-get action :query))
+	 (changes (notmuch-tag-change-list (plist-get action :tag-changes) t)))
+    (notmuch-tag query changes t))
+  (notmuch-refresh-this-buffer))
+
 (defun notmuch-tag-change-list (tags &optional reverse)
   "Convert TAGS into a list of tag changes.
 
diff --git a/test/T315-emacs-tagging.sh b/test/T315-emacs-tagging.sh
index 02fd3d27..fbaf5f22 100755
--- a/test/T315-emacs-tagging.sh
+++ b/test/T315-emacs-tagging.sh
@@ -103,5 +103,55 @@ test_emacs '(notmuch-search "subject:\"search race test\" -subject:two")
 output=$(notmuch search --output=messages 'tag:search-global-race-tag')
 test_expect_equal "$output" "id:$gen_msg_id_1"
 
+test_begin_subtest "undo with empty history is an error"
+test_emacs "(let ((notmuch-tag-history nil))
+  (test-log-error
+   (notmuch-tag-undo)))
+  "
+cat <<EOF > EXPECTED
+(error no further notmuch undo information)
+EOF
+test_expect_equal_file EXPECTED MESSAGES
+
+for mode in search show tree unthreaded; do
+    test_begin_subtest "undo tagging in $mode mode"
+    test_emacs "(let ((notmuch-tag-history nil))
+      (notmuch-$mode \"$os_x_darwin_thread\")
+      (notmuch-test-wait)
+      (execute-kbd-macro \"+tag-to-be-undone-$mode\")
+      (notmuch-tag-undo)
+      (notmuch-test-wait))"
+    count=$(notmuch count "tag:tag-to-be-undone-$mode")
+    test_expect_equal "$count" "0"
+
+    test_begin_subtest "undo tagging in $mode mode (multiple operations)"
+    test_emacs "(let ((notmuch-tag-history nil))
+      (notmuch-$mode \"$os_x_darwin_thread\")
+      (notmuch-test-wait)
+      (execute-kbd-macro \"+one-$mode\")
+      (execute-kbd-macro \"+two-$mode\")
+      (notmuch-tag-undo)
+      (notmuch-test-wait)
+      (execute-kbd-macro \"+three-$mode\"))"
+    output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+    notmuch tag "-one-$mode" "-three-$mode" $os_x_darwin_thread
+    test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox one-$mode three-$mode unread)"
+
+    test_begin_subtest "undo tagging in $mode mode (multiple undo)"
+    test_emacs "(let ((notmuch-tag-history nil))
+      (notmuch-$mode \"$os_x_darwin_thread\")
+      (notmuch-test-wait)
+      (execute-kbd-macro \"+one-$mode\")
+      (execute-kbd-macro \"+two-$mode\")
+      (notmuch-tag-undo)
+      (notmuch-test-wait)
+      (notmuch-tag-undo)
+      (notmuch-test-wait)
+      (execute-kbd-macro \"+three-$mode\"))"
+    output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+    notmuch tag "-one-$mode" "-three-$mode" $os_x_darwin_thread
+    test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox three-$mode unread)"
+done
+
 
 test_done
-- 
2.34.1

_______________________________________________
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-leave@notmuchmail.org

Thread: