emacs: add notmuch-tag-undo

Keybindings are deferred to a future commit.
This commit is contained in:
David Bremner 2022-02-12 16:27:39 -04:00
parent 9b2a548189
commit cc2c3a383d
3 changed files with 79 additions and 0 deletions

View file

@ -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
=================

View file

@ -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.

View file

@ -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