unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* v3 support undo in emacs frontend.
@ 2022-02-03 14:32 David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 01/12] doc/emacs: add minimal documentation for notmuch-unthreaded mode David Bremner
                   ` (11 more replies)
  0 siblings, 12 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

This obsoletes the series at [1].  Unlike that series it does not
modify the CLI, only the emacs front end. I realized we were already
expanding thread queries into lists of message-ids, which was my main
worry about query stability.

I am currently trying to track down a race condition in one of the new
tests, which is why the series is still marked RFC/WIP.

[1]: id:20220129194439.2790761-1-david@tethera.net

 [RFC PATCH v2 01/12] doc/emacs: add minimal documentation for
 [RFC PATCH v2 02/12] test: split variable settings to their own file
 [RFC PATCH v2 03/12] test/emacs: split out emacs related tests
 [RFC PATCH v2 04/12] test/emacs: write *Notmuch errors* buffer from
 [RFC PATCH v2 05/12] perf-test: allow running test_emacs from
 [RFC PATCH v2 06/12] perf-test: emacs tagging

The first six patches are not strictly needed for this feature, but
are reasonable changes I think.

 [RFC PATCH v2 07/12] emacs: remove non-batch code path from function

This is again not strictly needed, but makes further changes to this
code easier

 [RFC PATCH v2 08/12] emacs/tag: keep tag history
 [RFC PATCH v2 09/12] emacs: add notmuch-tag-undo

These add the actual undo.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 01/12] doc/emacs: add minimal documentation for notmuch-unthreaded mode.
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 02/12] test: split variable settings to their own file David Bremner
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

If nothing else it means the mode is discoverable by browsing the
documentation, and also provides a target for links when enumerating
modes.
---
 doc/notmuch-emacs.rst | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst
index 85b2c0ea..f2667de1 100644
--- a/doc/notmuch-emacs.rst
+++ b/doc/notmuch-emacs.rst
@@ -331,11 +331,21 @@ tags.
 As is the case with :ref:`notmuch-search`, the presentation of results
 can be controlled by the variable ``notmuch-search-oldest-first``.
 
+.. _notmuch-unthreaded:
+
+notmuch-unthreaded
+------------------
+
+``notmuch-unthreaded-mode`` is similar to :any:`notmuch-tree` in that
+each line corresponds to a single message, but no thread information
+is presented.
+
+Keybindings are the same as :any:`notmuch-tree`.
 
 Global key bindings
 ===================
 
-Several features are accessible from anywhere in notmuch through the
+Several features are accessible from most places in notmuch through the
 following key bindings:
 
 ``j``
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 02/12] test: split variable settings to their own file
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 01/12] doc/emacs: add minimal documentation for notmuch-unthreaded mode David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 03/12] test/emacs: split out emacs related tests David Bremner
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

This allows sharing more variable settings between the (correctness)
tests and the performance-tests. Unfortunately it seems a bit tricky
to move settings to test-lib-common.sh, as that is sourced late in
test-lib.sh, and moving it earlier breaks things.
---
 performance-test/perf-test-lib.sh |  2 ++
 test/test-lib.sh                  | 55 +----------------------------
 test/test-vars.sh                 | 58 +++++++++++++++++++++++++++++++
 3 files changed, 61 insertions(+), 54 deletions(-)
 create mode 100644 test/test-vars.sh

diff --git a/performance-test/perf-test-lib.sh b/performance-test/perf-test-lib.sh
index 41b1ddfd..0e4915e3 100644
--- a/performance-test/perf-test-lib.sh
+++ b/performance-test/perf-test-lib.sh
@@ -41,6 +41,8 @@ done
 # Ensure NOTMUCH_SRCDIR and NOTMUCH_BUILDDIR are set.
 . $(dirname "$0")/../test/export-dirs.sh || exit 1
 
+. "$NOTMUCH_SRCDIR/test/test-vars.sh" || exit 1
+
 # Where to run the tests
 TEST_DIRECTORY=$NOTMUCH_BUILDDIR/performance-test
 
diff --git a/test/test-lib.sh b/test/test-lib.sh
index 833bf5fe..89e5c6d8 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -64,55 +64,7 @@ exec 6>&1 7>&2
 BASH_XTRACEFD=7
 export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
 
-# Keep the original TERM for say_color and test_emacs
-ORIGINAL_TERM=$TERM
-
-# Set SMART_TERM to vt100 for known dumb/unknown terminal.
-# Otherwise use whatever TERM is currently used so that
-# users' actual TERM environments are being used in tests.
-case ${TERM-} in
-	'' | dumb | unknown )
-		SMART_TERM=vt100 ;;
-	*)
-		SMART_TERM=$TERM ;;
-esac
-
-# For repeatability, reset the environment to known value.
-LANG=C
-LC_ALL=C
-PAGER=cat
-TZ=UTC
-TERM=dumb
-export LANG LC_ALL PAGER TERM TZ
-GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
-if [[ ( -n "$TEST_EMACS" && -z "$TEST_EMACSCLIENT" ) || \
-      ( -z "$TEST_EMACS" && -n "$TEST_EMACSCLIENT" ) ]]; then
-    echo "error: must specify both or neither of TEST_EMACS and TEST_EMACSCLIENT" >&2
-    exit 1
-fi
-TEST_EMACS=${TEST_EMACS:-${EMACS:-emacs}}
-TEST_EMACSCLIENT=${TEST_EMACSCLIENT:-emacsclient}
-TEST_GDB=${TEST_GDB:-gdb}
-TEST_CC=${TEST_CC:-cc}
-TEST_CFLAGS=${TEST_CFLAGS:-"-g -O0"}
-TEST_SHIM_CFLAGS=${TEST_SHIM_CFLAGS:-"-fpic -shared"}
-TEST_SHIM_LDFLAGS=${TEST_SHIM_LDFLAGS:-"-ldl"}
-
-# Protect ourselves from common misconfiguration to export
-# CDPATH into the environment
-unset CDPATH
-
-unset GREP_OPTIONS
-
-# For lib/open.cc:_load_key_file
-unset XDG_CONFIG_HOME
-
-# For emacsclient
-unset ALTERNATE_EDITOR
-
-# for reproducibility
-unset EMAIL
-unset NAME
+. "$NOTMUCH_SRCDIR/test/test-vars.sh" || exit 1
 
 add_gnupg_home () {
     [ -e "${GNUPGHOME}/gpg.conf" ] && return
@@ -330,11 +282,6 @@ die () {
 	exit 1
 }
 
-GIT_EXIT_OK=
-# Note: TEST_TMPDIR *NOT* exported!
-TEST_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/notmuch-test-$$.XXXXXX")
-# Put GNUPGHOME in TMPDIR to avoid problems with long paths.
-export GNUPGHOME="${TEST_TMPDIR}/gnupg"
 trap 'trap_exit' EXIT
 trap 'trap_signal' HUP INT TERM
 
diff --git a/test/test-vars.sh b/test/test-vars.sh
new file mode 100644
index 00000000..812bcf81
--- /dev/null
+++ b/test/test-vars.sh
@@ -0,0 +1,58 @@
+# Common variable settings for (correctness) tests and performance
+# tests.
+
+# Keep the original TERM for say_color and test_emacs
+ORIGINAL_TERM=$TERM
+
+# Set SMART_TERM to vt100 for known dumb/unknown terminal.
+# Otherwise use whatever TERM is currently used so that
+# users' actual TERM environments are being used in tests.
+case ${TERM-} in
+	'' | dumb | unknown )
+		SMART_TERM=vt100 ;;
+	*)
+		SMART_TERM=$TERM ;;
+esac
+
+# For repeatability, reset the environment to known value.
+LANG=C
+LC_ALL=C
+PAGER=cat
+TZ=UTC
+TERM=dumb
+export LANG LC_ALL PAGER TERM TZ
+GIT_TEST_CMP=${GIT_TEST_CMP:-diff -u}
+if [[ ( -n "$TEST_EMACS" && -z "$TEST_EMACSCLIENT" ) || \
+      ( -z "$TEST_EMACS" && -n "$TEST_EMACSCLIENT" ) ]]; then
+    echo "error: must specify both or neither of TEST_EMACS and TEST_EMACSCLIENT" >&2
+    exit 1
+fi
+TEST_EMACS=${TEST_EMACS:-${EMACS:-emacs}}
+TEST_EMACSCLIENT=${TEST_EMACSCLIENT:-emacsclient}
+TEST_GDB=${TEST_GDB:-gdb}
+TEST_CC=${TEST_CC:-cc}
+TEST_CFLAGS=${TEST_CFLAGS:-"-g -O0"}
+TEST_SHIM_CFLAGS=${TEST_SHIM_CFLAGS:-"-fpic -shared"}
+TEST_SHIM_LDFLAGS=${TEST_SHIM_LDFLAGS:-"-ldl"}
+
+# Protect ourselves from common misconfiguration to export
+# CDPATH into the environment
+unset CDPATH
+
+unset GREP_OPTIONS
+
+# For lib/open.cc:_load_key_file
+unset XDG_CONFIG_HOME
+
+# For emacsclient
+unset ALTERNATE_EDITOR
+
+# for reproducibility
+unset EMAIL
+unset NAME
+
+GIT_EXIT_OK=
+# Note: TEST_TMPDIR *NOT* exported!
+TEST_TMPDIR=$(mktemp -d "${TMPDIR:-/tmp}/notmuch-test-$$.XXXXXX")
+# Put GNUPGHOME in TMPDIR to avoid problems with long paths.
+export GNUPGHOME="${TEST_TMPDIR}/gnupg"
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 03/12] test/emacs: split out emacs related tests
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 01/12] doc/emacs: add minimal documentation for notmuch-unthreaded mode David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 02/12] test: split variable settings to their own file David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 04/12] test/emacs: write *Notmuch errors* buffer from test macro David Bremner
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

T310-emacs is one of the largest and longest running sets of
tests. Splitting out the tagging operations will help maintainability
as well as potentially improve the parallel running time of the test
suite. Some slowdown in running the tests sequentially may result
since there is repeated setup.
---
 test/T310-emacs.sh         |  93 --------------------------------
 test/T315-emacs-tagging.sh | 107 +++++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 93 deletions(-)
 create mode 100755 test/T315-emacs-tagging.sh

diff --git a/test/T310-emacs.sh b/test/T310-emacs.sh
index a05b828a..9d0df187 100755
--- a/test/T310-emacs.sh
+++ b/test/T310-emacs.sh
@@ -130,75 +130,6 @@ test_emacs '(notmuch-search "tag:inbox")
 	    (test-output)'
 test_expect_equal_file $EXPECTED/notmuch-show-thread-maildir-storage OUTPUT
 
-test_begin_subtest "Add tag from search view"
-os_x_darwin_thread=$(notmuch search --output=threads id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com)
-test_emacs "(notmuch-search \"$os_x_darwin_thread\")
-	    (notmuch-test-wait)
-	    (execute-kbd-macro \"+tag-from-search-view\")"
-output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-search-view unread)"
-
-test_begin_subtest "Remove tag from search view"
-test_emacs "(notmuch-search \"$os_x_darwin_thread\")
-	    (notmuch-test-wait)
-	    (execute-kbd-macro \"-tag-from-search-view\")"
-output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)"
-
-test_begin_subtest "Add tag (large query)"
-# We use a long query to force us into batch mode and use a funny tag
-# that requires escaping for batch tagging.
-test_emacs "(notmuch-tag (concat \"$os_x_darwin_thread\" \" or \" (mapconcat #'identity (make-list notmuch-tag-argument-limit \"x\") \"-\")) (list \"+tag-from-%-large-query\"))"
-output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-%-large-query unread)"
-notmuch tag -tag-from-%-large-query $os_x_darwin_thread
-
-test_begin_subtest "notmuch-show: add single tag to single message"
-test_emacs "(notmuch-show \"$os_x_darwin_thread\")
-	    (execute-kbd-macro \"+tag-from-show-view\")"
-output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-show-view unread)"
-
-test_begin_subtest "notmuch-show: remove single tag from single message"
-test_emacs "(notmuch-show \"$os_x_darwin_thread\")
-	    (execute-kbd-macro \"-tag-from-show-view\")"
-output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)"
-
-test_begin_subtest "notmuch-show: add multiple tags to single message"
-test_emacs "(notmuch-show \"$os_x_darwin_thread\")
-	    (execute-kbd-macro \"+tag1-from-show-view +tag2-from-show-view\")"
-output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag1-from-show-view tag2-from-show-view unread)"
-
-test_begin_subtest "notmuch-show: remove multiple tags from single message"
-test_emacs "(notmuch-show \"$os_x_darwin_thread\")
-	    (execute-kbd-macro \"-tag1-from-show-view -tag2-from-show-view\")"
-output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
-test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)"
-
-test_begin_subtest "notmuch-show: before-tag-hook is run, variables are defined"
-output=$(test_emacs '(let ((notmuch-test-tag-hook-output nil)
-	          (notmuch-before-tag-hook (function notmuch-test-tag-hook)))
-	       (notmuch-show "id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com")
-	       (execute-kbd-macro "+activate-hook\n")
-	       (execute-kbd-macro "-activate-hook\n")
-	       notmuch-test-tag-hook-output)')
-test_expect_equal "$output" \
-'(("id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com" "-activate-hook")
- ("id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com" "+activate-hook"))'
-
-test_begin_subtest "notmuch-show: after-tag-hook is run, variables are defined"
-output=$(test_emacs '(let ((notmuch-test-tag-hook-output nil)
-	          (notmuch-after-tag-hook (function notmuch-test-tag-hook)))
-	       (notmuch-show "id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com")
-	       (execute-kbd-macro "+activate-hook\n")
-	       (execute-kbd-macro "-activate-hook\n")
-	       notmuch-test-tag-hook-output)')
-test_expect_equal "$output" \
-'(("id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com" "-activate-hook")
- ("id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com" "+activate-hook"))'
-
 test_begin_subtest "Message with .. in Message-Id:"
 add_message [id]=123..456@example '[subject]="Message with .. in Message-Id"'
 test_emacs '(notmuch-search "id:\"123..456@example\"")
@@ -1133,30 +1064,6 @@ This is a warning (see *Notmuch errors* for more details)
 This is a warning
 This is another warning"
 
-test_begin_subtest "Search thread tag operations are race-free"
-add_message '[subject]="Search race test"'
-gen_msg_id_1=$gen_msg_id
-generate_message '[in-reply-to]="<'$gen_msg_id_1'>"' \
-	    '[references]="<'$gen_msg_id_1'>"' \
-	    '[subject]="Search race test two"'
-test_emacs '(notmuch-search "subject:\"search race test\"")
-	    (notmuch-test-wait)
-	    (notmuch-poll)
-	    (execute-kbd-macro "+search-thread-race-tag")'
-output=$(notmuch search --output=messages 'tag:search-thread-race-tag')
-test_expect_equal "$output" "id:$gen_msg_id_1"
-
-test_begin_subtest "Search global tag operations are race-free"
-generate_message '[in-reply-to]="<'$gen_msg_id_1'>"' \
-	    '[references]="<'$gen_msg_id_1'>"' \
-	    '[subject]="Re: Search race test"'
-test_emacs '(notmuch-search "subject:\"search race test\" -subject:two")
-	    (notmuch-test-wait)
-	    (notmuch-poll)
-	    (execute-kbd-macro "*+search-global-race-tag")'
-output=$(notmuch search --output=messages 'tag:search-global-race-tag')
-test_expect_equal "$output" "id:$gen_msg_id_1"
-
 test_begin_subtest "Term escaping"
 output=$(test_emacs "(mapcar 'notmuch-escape-boolean-term (list
 	\"\"
diff --git a/test/T315-emacs-tagging.sh b/test/T315-emacs-tagging.sh
new file mode 100755
index 00000000..02fd3d27
--- /dev/null
+++ b/test/T315-emacs-tagging.sh
@@ -0,0 +1,107 @@
+#!/usr/bin/env bash
+
+test_description="emacs interface"
+. $(dirname "$0")/test-lib.sh || exit 1
+. $NOTMUCH_SRCDIR/test/test-lib-emacs.sh || exit 1
+
+EXPECTED=$NOTMUCH_SRCDIR/test/emacs.expected-output
+
+test_require_emacs
+add_email_corpus
+
+test_begin_subtest "Add tag from search view"
+os_x_darwin_thread=$(notmuch search --output=threads id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com)
+test_emacs "(notmuch-search \"$os_x_darwin_thread\")
+	    (notmuch-test-wait)
+	    (execute-kbd-macro \"+tag-from-search-view\")"
+output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-search-view unread)"
+
+test_begin_subtest "Remove tag from search view"
+test_emacs "(notmuch-search \"$os_x_darwin_thread\")
+	    (notmuch-test-wait)
+	    (execute-kbd-macro \"-tag-from-search-view\")"
+output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)"
+
+test_begin_subtest "Add tag (large query)"
+# We use a long query to force us into batch mode and use a funny tag
+# that requires escaping for batch tagging.
+test_emacs "(notmuch-tag (concat \"$os_x_darwin_thread\" \" or \" (mapconcat #'identity (make-list notmuch-tag-argument-limit \"x\") \"-\")) (list \"+tag-from-%-large-query\"))"
+output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-%-large-query unread)"
+notmuch tag -tag-from-%-large-query $os_x_darwin_thread
+
+test_begin_subtest "notmuch-show: add single tag to single message"
+test_emacs "(notmuch-show \"$os_x_darwin_thread\")
+	    (execute-kbd-macro \"+tag-from-show-view\")"
+output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-show-view unread)"
+
+test_begin_subtest "notmuch-show: remove single tag from single message"
+test_emacs "(notmuch-show \"$os_x_darwin_thread\")
+	    (execute-kbd-macro \"-tag-from-show-view\")"
+output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)"
+
+test_begin_subtest "notmuch-show: add multiple tags to single message"
+test_emacs "(notmuch-show \"$os_x_darwin_thread\")
+	    (execute-kbd-macro \"+tag1-from-show-view +tag2-from-show-view\")"
+output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag1-from-show-view tag2-from-show-view unread)"
+
+test_begin_subtest "notmuch-show: remove multiple tags from single message"
+test_emacs "(notmuch-show \"$os_x_darwin_thread\")
+	    (execute-kbd-macro \"-tag1-from-show-view -tag2-from-show-view\")"
+output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize)
+test_expect_equal "$output" "thread:XXX   2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)"
+
+test_begin_subtest "notmuch-show: before-tag-hook is run, variables are defined"
+output=$(test_emacs '(let ((notmuch-test-tag-hook-output nil)
+	          (notmuch-before-tag-hook (function notmuch-test-tag-hook)))
+	       (notmuch-show "id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com")
+	       (execute-kbd-macro "+activate-hook\n")
+	       (execute-kbd-macro "-activate-hook\n")
+	       notmuch-test-tag-hook-output)')
+test_expect_equal "$output" \
+'(("id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com" "-activate-hook")
+ ("id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com" "+activate-hook"))'
+
+test_begin_subtest "notmuch-show: after-tag-hook is run, variables are defined"
+output=$(test_emacs '(let ((notmuch-test-tag-hook-output nil)
+	          (notmuch-after-tag-hook (function notmuch-test-tag-hook)))
+	       (notmuch-show "id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com")
+	       (execute-kbd-macro "+activate-hook\n")
+	       (execute-kbd-macro "-activate-hook\n")
+	       notmuch-test-tag-hook-output)')
+test_expect_equal "$output" \
+'(("id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com" "-activate-hook")
+ ("id:ddd65cda0911171950o4eea4389v86de9525e46052d3@mail.gmail.com" "+activate-hook"))'
+
+
+test_begin_subtest "Search thread tag operations are race-free"
+add_message '[subject]="Search race test"'
+gen_msg_id_1=$gen_msg_id
+generate_message '[in-reply-to]="<'$gen_msg_id_1'>"' \
+	    '[references]="<'$gen_msg_id_1'>"' \
+	    '[subject]="Search race test two"'
+test_emacs '(notmuch-search "subject:\"search race test\"")
+	    (notmuch-test-wait)
+	    (notmuch-poll)
+	    (execute-kbd-macro "+search-thread-race-tag")'
+output=$(notmuch search --output=messages 'tag:search-thread-race-tag')
+test_expect_equal "$output" "id:$gen_msg_id_1"
+
+test_begin_subtest "Search global tag operations are race-free"
+generate_message '[in-reply-to]="<'$gen_msg_id_1'>"' \
+	    '[references]="<'$gen_msg_id_1'>"' \
+	    '[subject]="Re: Search race test"'
+test_emacs '(notmuch-search "subject:\"search race test\" -subject:two")
+	    (notmuch-test-wait)
+	    (notmuch-poll)
+	    (execute-kbd-macro "*+search-global-race-tag")'
+output=$(notmuch search --output=messages 'tag:search-global-race-tag')
+test_expect_equal "$output" "id:$gen_msg_id_1"
+
+
+test_done
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 04/12] test/emacs: write *Notmuch errors* buffer from test macro
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (2 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 03/12] test/emacs: split out emacs related tests David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 05/12] perf-test: allow running test_emacs from performance test suite David Bremner
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

---
 test/test-lib.el | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/test/test-lib.el b/test/test-lib.el
index 6831b46f..adabda4a 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -184,7 +184,9 @@ running, quit if it terminated."
        (progn ,@body
 	  (message "COMPLETE"))
        (t (message "%s" err)))
-     (with-current-buffer "*Messages*" (test-output "MESSAGES"))))
+     (with-current-buffer "*Messages*" (test-output "MESSAGES"))
+     (with-current-buffer (get-buffer-create "*Notmuch errors*")
+       (test-output "ERRORS"))))
 
 ;; For historical reasons, we hide deleted tags by default in the test
 ;; suite
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 05/12] perf-test: allow running test_emacs from performance test suite.
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (3 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 04/12] test/emacs: write *Notmuch errors* buffer from test macro David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 06/12] perf-test: emacs tagging David Bremner
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

test_require_external prereq has to move to test-lib-common.sh, and
the new shell functions print_emacs_header and time_emacs are provided.

The somewhat indirect way of printing the output is to avoid the extra
"" present on string values from emacsclient.
---
 performance-test/perf-test-lib.sh |  5 +++++
 test/test-lib-common.sh           | 14 ++++++++++++++
 test/test-lib-emacs.sh            |  8 ++++++++
 test/test-lib.el                  |  5 +++++
 test/test-lib.sh                  | 14 --------------
 5 files changed, 32 insertions(+), 14 deletions(-)

diff --git a/performance-test/perf-test-lib.sh b/performance-test/perf-test-lib.sh
index 0e4915e3..c34f8cd6 100644
--- a/performance-test/perf-test-lib.sh
+++ b/performance-test/perf-test-lib.sh
@@ -210,6 +210,11 @@ print_header ()
     printf "\t\t\tWall(s)\tUsr(s)\tSys(s)\tRes(K)\tIn/Out(512B)\n"
 }
 
+print_emacs_header ()
+{
+    printf "\t\t\tWall(s)\tGCs\tGC time(s)\n"
+}
+
 time_run ()
 {
     printf "  %-22s" "$1"
diff --git a/test/test-lib-common.sh b/test/test-lib-common.sh
index ebbf4cdf..18fa29c0 100644
--- a/test/test-lib-common.sh
+++ b/test/test-lib-common.sh
@@ -29,6 +29,20 @@ if [[ -z "$NOTMUCH_SRCDIR" ]] || [[ -z "$NOTMUCH_BUILDDIR" ]]; then
 	exit 1
 fi
 
+# Explicitly require external prerequisite.  Useful when binary is
+# called indirectly (e.g. from emacs).
+# Returns success if dependency is available, failure otherwise.
+test_require_external_prereq () {
+	local binary
+	binary="$1"
+	if [[ ${test_missing_external_prereq_["${binary}"]} == t ]]; then
+		# dependency is missing, call the replacement function to note it
+		eval "$binary"
+	else
+		true
+	fi
+}
+
 backup_database () {
     test_name=$(basename $0 .sh)
     rm -rf $TMP_DIRECTORY/notmuch-dir-backup."$test_name"
diff --git a/test/test-lib-emacs.sh b/test/test-lib-emacs.sh
index a298526d..ad4c4aeb 100644
--- a/test/test-lib-emacs.sh
+++ b/test/test-lib-emacs.sh
@@ -207,4 +207,12 @@ test_emacs () {
 	${TEST_EMACSCLIENT} --socket-name="$EMACS_SERVER" --eval "(notmuch-test-progn $*)"
 }
 
+time_emacs () {
+    rm -f MESSAGES
+    printf "%s" "$1"
+    shift
+    test_emacs "(test-time $*)" > emacs.out
+    tail -n 1 MESSAGES
+}
+
 emacs_generate_script
diff --git a/test/test-lib.el b/test/test-lib.el
index adabda4a..1b5e8549 100644
--- a/test/test-lib.el
+++ b/test/test-lib.el
@@ -188,6 +188,11 @@ running, quit if it terminated."
      (with-current-buffer (get-buffer-create "*Notmuch errors*")
        (test-output "ERRORS"))))
 
+(defmacro test-time (&rest body)
+  `(let ((results (mapcar (lambda (x) (/ x 5.0)) (benchmark-run 5 ,@body))))
+     (message "\t\t%0.2f\t%0.2f\t%0.2f" (nth 0 results) (nth 1 results) (nth 2 results))
+     (with-current-buffer "*Messages*" (test-output "MESSAGES"))))
+
 ;; For historical reasons, we hide deleted tags by default in the test
 ;; suite
 (setq notmuch-tag-deleted-formats
diff --git a/test/test-lib.sh b/test/test-lib.sh
index 89e5c6d8..59b6079d 100644
--- a/test/test-lib.sh
+++ b/test/test-lib.sh
@@ -603,20 +603,6 @@ $binary () {
 	fi
 }
 
-# Explicitly require external prerequisite.  Useful when binary is
-# called indirectly (e.g. from emacs).
-# Returns success if dependency is available, failure otherwise.
-test_require_external_prereq () {
-	local binary
-	binary="$1"
-	if [[ ${test_missing_external_prereq_["${binary}"]} == t ]]; then
-		# dependency is missing, call the replacement function to note it
-		eval "$binary"
-	else
-		true
-	fi
-}
-
 # You are not expected to call test_ok_ and test_failure_ directly, use
 # the text_expect_* functions instead.
 
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 06/12] perf-test: emacs tagging
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (4 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 05/12] perf-test: allow running test_emacs from performance test suite David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 07/12] emacs: remove non-batch code path from function notmuch-tag David Bremner
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

Time tag operations, to see if it is worthwhile keeping both the
batch and the non-batch calls to notmuch tag.
---
 performance-test/T06-emacs.sh | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100755 performance-test/T06-emacs.sh

diff --git a/performance-test/T06-emacs.sh b/performance-test/T06-emacs.sh
new file mode 100755
index 00000000..66f0be58
--- /dev/null
+++ b/performance-test/T06-emacs.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+
+test_description='emacs operations'
+
+. $(dirname "$0")/perf-test-lib.sh || exit 1
+. $NOTMUCH_SRCDIR/test/test-lib-emacs.sh || exit 1
+
+test_require_emacs
+
+time_start
+
+print_emacs_header
+
+MSGS=$(notmuch search --output=messages "*" | shuf -n 50 | awk '{printf " \"%s\"",$1}')
+
+time_emacs "tag messages" \
+"(dolist (msg (list $MSGS))
+   (notmuch-tag msg (list \"+test\"))
+   (notmuch-tag msg (list \"-test\"))))"
+
+time_done
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 07/12] emacs: remove non-batch code path from function notmuch-tag
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (5 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 06/12] perf-test: emacs tagging David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 08/12] emacs/tag: keep tag history David Bremner
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

It is no slower (according to T06-emacs) to use batch for everything,
and it simplifies the code.
---
 emacs/notmuch-tag.el | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 8af09e68..ad0cb1c1 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -458,7 +458,11 @@ from TAGS if present."
   "Use batch tagging if the tagging query is longer than this.
 
 This limits the length of arguments passed to the notmuch CLI to
-avoid system argument length limits and performance problems.")
+avoid system argument length limits and performance problems.
+
+NOTE: this variable is no longer used.")
+
+(make-obsolete-variable 'notmuch-tag-argument-limit nil "notmuch 0.36")
 
 (defun notmuch-tag (query tag-changes)
   "Add/remove tags in TAG-CHANGES to messages matching QUERY.
@@ -481,16 +485,13 @@ notmuch-after-tag-hook will be run."
     (notmuch-dlet ((tag-changes tag-changes)
 		   (query query))
       (run-hooks 'notmuch-before-tag-hook))
-    (if (<= (length query) notmuch-tag-argument-limit)
-	(apply 'notmuch-call-notmuch-process "tag"
-	       (append tag-changes (list "--" query)))
-      ;; Use batch tag mode to avoid argument length limitations
-      (let ((batch-op (concat (mapconcat #'notmuch-hex-encode tag-changes " ")
-			      " -- " query)))
-	(notmuch-call-notmuch-process :stdin-string batch-op "tag" "--batch")))
-    (notmuch-dlet ((tag-changes tag-changes)
+    ;; Use batch tag mode to avoid argument length limitations
+    (let ((batch-op (concat (mapconcat #'notmuch-hex-encode tag-changes " ")
+			    " -- " query)))
+      (notmuch-call-notmuch-process :stdin-string batch-op "tag" "--batch")))
+  (notmuch-dlet ((tag-changes tag-changes)
 		   (query query))
-      (run-hooks 'notmuch-after-tag-hook))))
+      (run-hooks 'notmuch-after-tag-hook)))
 
 (defun notmuch-tag-change-list (tags &optional reverse)
   "Convert TAGS into a list of tag changes.
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 08/12] emacs/tag: keep tag history
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (6 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 07/12] emacs: remove non-batch code path from function notmuch-tag David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 09/12] emacs: add notmuch-tag-undo David Bremner
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

This buffer local list will be used to provide an undo facility for
tagging operations. The new arguments are for the use of a future undo
function.
---
 emacs/notmuch-tag.el | 27 ++++++++++++++++++---------
 1 file changed, 18 insertions(+), 9 deletions(-)

diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index ad0cb1c1..4c974679 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -275,6 +275,10 @@ This can be used with `notmuch-tag-format-image-data'."
   </g>
 </svg>")
 
+;;; track history of tag operations
+(defvar-local notmuch-tag-history nil
+  "Buffer local history of `notmuch-tag' function.")
+
 ;;; Format Handling
 
 (defvar notmuch-tag--format-cache (make-hash-table :test 'equal)
@@ -464,12 +468,13 @@ NOTE: this variable is no longer used.")
 
 (make-obsolete-variable 'notmuch-tag-argument-limit nil "notmuch 0.36")
 
-(defun notmuch-tag (query tag-changes)
+(defun notmuch-tag (query tag-changes &optional omit-hist)
   "Add/remove tags in TAG-CHANGES to messages matching QUERY.
 
 QUERY should be a string containing the search-terms.
-TAG-CHANGES is a list of strings of the form \"+tag\" or
-\"-tag\" to add or remove tags, respectively.
+TAG-CHANGES is a list of strings of the form \"+tag\" or \"-tag\"
+to add or remove tags, respectively.  OMIT-HIST disables history
+tracking if non-nil.
 
 Note: Other code should always use this function to alter tags of
 messages instead of running (notmuch-call-notmuch-process \"tag\" ..)
@@ -485,13 +490,17 @@ notmuch-after-tag-hook will be run."
     (notmuch-dlet ((tag-changes tag-changes)
 		   (query query))
       (run-hooks 'notmuch-before-tag-hook))
-    ;; Use batch tag mode to avoid argument length limitations
-    (let ((batch-op (concat (mapconcat #'notmuch-hex-encode tag-changes " ")
-			    " -- " query)))
-      (notmuch-call-notmuch-process :stdin-string batch-op "tag" "--batch")))
+    (with-temp-buffer
+      (insert (concat (mapconcat #'notmuch-hex-encode tag-changes " ") " -- " query))
+      (unless (= 0
+		 (notmuch--call-process-region
+		  (point-min) (point-max) notmuch-command t t nil "tag" "--batch"))
+	(notmuch-logged-error "notmuch tag failed" (buffer-string))))
+    (unless omit-hist
+      (push (list :query query :tag-changes tag-changes) notmuch-tag-history)))
   (notmuch-dlet ((tag-changes tag-changes)
-		   (query query))
-      (run-hooks 'notmuch-after-tag-hook)))
+		 (query query))
+    (run-hooks 'notmuch-after-tag-hook)))
 
 (defun notmuch-tag-change-list (tags &optional reverse)
   "Convert TAGS into a list of tag changes.
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 09/12] emacs: add notmuch-tag-undo
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (7 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 08/12] emacs/tag: keep tag history David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 19:09   ` Miguel Bernabeu
  2022-02-03 14:32 ` [RFC PATCH v2 10/12] emacs: redirect undo to notmuch-tag-undo David Bremner
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

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

diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst
index f2667de1..670d2925 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 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..d76b5ab8 100755
--- a/test/T315-emacs-tagging.sh
+++ b/test/T315-emacs-tagging.sh
@@ -103,5 +103,57 @@ 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))"
+    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\")
+      (notmuch-test-wait)
+      (execute-kbd-macro \"+two-$mode\")
+      (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 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\")
+      (notmuch-test-wait)
+      (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

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 10/12] emacs: redirect undo to notmuch-tag-undo
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (8 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 09/12] emacs: add notmuch-tag-undo David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 11/12] emacs: Document undo binding David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 12/12] emacs: whitespace cleanup for keybindings David Bremner
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

The double remap is a bit ugly, but it seems better than adding
another layer of keymaps for those modes where notmuch-tag-undo makes
sense.
---
 emacs/notmuch-hello.el     |  3 +++
 emacs/notmuch-lib.el       |  1 +
 test/T315-emacs-tagging.sh | 10 +++++++++-
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index beb25382..4662e704 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -710,6 +710,9 @@ with `notmuch-hello-query-counts'."
   ;; that when we modify map it does not modify widget-keymap).
   (let ((map (make-composed-keymap (list (make-sparse-keymap) widget-keymap))))
     (set-keymap-parent map notmuch-common-keymap)
+    ;; Currently notmuch-hello-mode supports free text entry, but not
+    ;; tagging operations, so provide standard undo.
+    (define-key map [remap notmuch-tag-undo] #'undo)
     map)
   "Keymap for \"notmuch hello\" buffers.")
 
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 45817e13..6fc71cc7 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -166,6 +166,7 @@ For example, if you wanted to remove an \"inbox\" tag and add an
     (define-key map (kbd "M-=") 'notmuch-refresh-all-buffers)
     (define-key map "G" 'notmuch-poll-and-refresh-this-buffer)
     (define-key map "j" 'notmuch-jump-search)
+    (define-key map [remap undo] 'notmuch-tag-undo)
     map)
   "Keymap shared by all notmuch modes.")
 
diff --git a/test/T315-emacs-tagging.sh b/test/T315-emacs-tagging.sh
index d76b5ab8..c9e3e53a 100755
--- a/test/T315-emacs-tagging.sh
+++ b/test/T315-emacs-tagging.sh
@@ -153,7 +153,15 @@ for mode in search show tree unthreaded; do
     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_begin_subtest "undo tagging in $mode mode (via binding)"
+    test_emacs "(let ((notmuch-tag-history nil))
+      (notmuch-$mode \"$os_x_darwin_thread\")
+      (notmuch-test-wait)
+      (execute-kbd-macro \"+tag-to-be-undone-$mode\")
+      (execute-kbd-macro (kbd \"C-x u\")))"
+    count=$(notmuch count "tag:tag-to-be-undone-$mode")
+    test_expect_equal "$count" "0"
+done
 
 test_done
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 11/12] emacs: Document undo binding.
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (9 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 10/12] emacs: redirect undo to notmuch-tag-undo David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-03 14:32 ` [RFC PATCH v2 12/12] emacs: whitespace cleanup for keybindings David Bremner
  11 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

This messes up whitespace, which will require a global change to fix.
---
 devel/emacs-keybindings.org | 1 +
 doc/notmuch-emacs.rst       | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/devel/emacs-keybindings.org b/devel/emacs-keybindings.org
index 2f73a198..7f0d26bb 100644
--- a/devel/emacs-keybindings.org
+++ b/devel/emacs-keybindings.org
@@ -55,4 +55,5 @@
 | >         | notmuch-search-last-thread             |                                                       |                                         |
 | ?         | notmuch-help                           | notmuch-help                                          | notmuch-help                            |
 | \vert     |                                        | notmuch-show-pipe-message                             | notmuch-show-pipe-message               |
+| [remap undo] | notmuch-tag-undo                       | notmuch-tag-undo                                      | notmuch-tag-undo                        |
 |-----------+----------------------------------------+-------------------------------------------------------+-----------------------------------------|
diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst
index 670d2925..1371c93f 100644
--- a/doc/notmuch-emacs.rst
+++ b/doc/notmuch-emacs.rst
@@ -354,6 +354,8 @@ following key bindings:
 ``k``
     Tagging operations using :ref:`notmuch-tag-jump`
 
+``C-_`` ``C-/`` ``C-x u``: Undo previous tagging operation using :ref:`notmuch-tag-undo`
+
 .. _notmuch-jump:
 
 notmuch-jump
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [RFC PATCH v2 12/12] emacs: whitespace cleanup for keybindings
  2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
                   ` (10 preceding siblings ...)
  2022-02-03 14:32 ` [RFC PATCH v2 11/12] emacs: Document undo binding David Bremner
@ 2022-02-03 14:32 ` David Bremner
  2022-02-04 12:35   ` David Bremner
  11 siblings, 1 reply; 16+ messages in thread
From: David Bremner @ 2022-02-03 14:32 UTC (permalink / raw)
  To: notmuch

Changing the width of a column requires rewriting all the rows.
---
 devel/emacs-keybindings.org | 116 ++++++++++++++++++------------------
 1 file changed, 58 insertions(+), 58 deletions(-)

diff --git a/devel/emacs-keybindings.org b/devel/emacs-keybindings.org
index 7f0d26bb..00977bc3 100644
--- a/devel/emacs-keybindings.org
+++ b/devel/emacs-keybindings.org
@@ -1,59 +1,59 @@
-|-----------+----------------------------------------+-------------------------------------------------------+-----------------------------------------|
-| Key       | Search Mode                            | Show Mode                                             | Tree Mode                               |
-|-----------+----------------------------------------+-------------------------------------------------------+-----------------------------------------|
-| a         | notmuch-search-archive-thread          | notmuch-show-archive-message-then-next-or-next-thread | notmuch-tree-archive-message-then-next  |
-| b         | notmuch-search-scroll-down             | notmuch-show-resend-message                           | notmuch-show-resend-message             |
-| c         | notmuch-search-stash-map               | notmuch-show-stash-map                                | notmuch-show-stash-map                  |
-| d         |                                        |                                                       |                                         |
-| e         |                                        |                                                       | (notmuch-tree-button-activate)          |
-| f         |                                        | notmuch-show-forward-message                          | notmuch-show-forward-message            |
-| g         |                                        |                                                       |                                         |
-| h         |                                        | notmuch-show-toggle-visibility-headers                |                                         |
-| i         |                                        |                                                       |                                         |
-| j         | notmuch-jump-search                    | notmuch-jump-search                                   | notmuch-jump-search                     |
-| k         | notmuch-tag-jump                       | notmuch-tag-jump                                      | notmuch-tag-jump                        |
-| l         | notmuch-search-filter                  | notmuch-show-filter-thread                            | notmuch-tree-filter                     |
-| m         | notmuch-mua-new-mail                   | notmuch-mua-new-mail                                  | notmuch-mua-new-mail                    |
-| n         | notmuch-search-next-thread             | notmuch-show-next-open-message                        | notmuch-tree-next-matching-message      |
-| o         | notmuch-search-toggle-order            |                                                       | notmuch-tree-toggle-order               |
-| p         | notmuch-search-previous-thread         | notmuch-show-previous-open-message                    | notmuch-tree-prev-matching-message      |
-| q         | notmuch-bury-or-kill-this-buffer       | notmuch-bury-or-kill-this-buffer                      | notmuch-bury-or-kill-this-buffer        |
-| r         | notmuch-search-reply-to-thread-sender  | notmuch-show-reply-sender                             | notmuch-show-reply-sender               |
-| s         | notmuch-search                         | notmuch-search                                        | notmuch-search                          |
-| t         | notmuch-search-filter-by-tag           | toggle-truncate-lines                                 | notmuch-tree-filter-by-tag              |
-| u         |                                        |                                                       |                                         |
-| v         |                                        |                                                       | notmuch-show-view-all-mime-parts        |
-| w         |                                        | notmuch-show-save-attachments                         | notmuch-show-save-attachments           |
-| x         | notmuch-bury-or-kill-this-buffer       | notmuch-show-archive-message-then-next-or-exit        | notmuch-tree-quit                       |
-| y         |                                        |                                                       |                                         |
-| z         | notmuch-tree                           | notmuch-tree                                          | notmuch-tree-to-tree                    |
-| A         |                                        | notmuch-show-archive-thread-then-next                 | notmuch-tree-archive-thread             |
-| F         |                                        | notmuch-show-forward-open-messages                    |                                         |
-| G         | notmuch-poll-and-refresh-this-buffer   | notmuch-poll-and-refresh-this-buffer                  | notmuch-poll-and-refresh-this-buffer    |
-| N         |                                        | notmuch-show-next-message                             | notmuch-tree-next-message               |
-| O         |                                        |                                                       |                                         |
-| P         |                                        | notmuch-show-previous-message                         | notmuch-tree-prev-message               |
-| R         | notmuch-search-reply-to-thread         | notmuch-show-reply                                    | notmuch-show-reply                      |
-| S         |                                        |                                                       | notmuch-search-from-tree-current-query  |
-| V         |                                        | notmuch-show-view-raw-message                         | notmuch-show-view-raw-message           |
-| X         |                                        | notmuch-show-archive-thread-then-exit                 |                                         |
-| 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-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                    |
-| -         | notmuch-search-remove-tag              | notmuch-show-remove-tag                               | notmuch-tree-remove-tag                 |
-| .         |                                        | notmuch-show-part-map                                 |                                         |
-| <         | notmuch-search-first-thread            | notmuch-show-toggle-thread-indentation                |                                         |
-| <DEL>     | notmuch-search-scroll-down             | notmuch-show-rewind                                   | notmuch-tree-scroll-message-window-back |
-| <RET>     | notmuch-search-show-thread             | notmuch-show-toggle-message                           | notmuch-tree-show-message               |
-| <SPC>     | notmuch-search-scroll-up               | notmuch-show-advance                                  | notmuch-tree-scroll-or-next             |
-| <TAB>     |                                        | notmuch-show-next-button                              | notmuch-show-next-button                |
-| <backtab> |                                        | notmuch-show-previous-button                          | notmuch-show-previous-button            |
-| =         | notmuch-refresh-this-buffer            | notmuch-refresh-this-buffer                           | notmuch-tree-refresh-view               |
-| >         | notmuch-search-last-thread             |                                                       |                                         |
-| ?         | notmuch-help                           | notmuch-help                                          | notmuch-help                            |
-| \vert     |                                        | notmuch-show-pipe-message                             | notmuch-show-pipe-message               |
+|--------------+----------------------------------------+-------------------------------------------------------+-----------------------------------------|
+| Key          | Search Mode                            | Show Mode                                             | Tree Mode                               |
+|--------------+----------------------------------------+-------------------------------------------------------+-----------------------------------------|
+| a            | notmuch-search-archive-thread          | notmuch-show-archive-message-then-next-or-next-thread | notmuch-tree-archive-message-then-next  |
+| b            | notmuch-search-scroll-down             | notmuch-show-resend-message                           | notmuch-show-resend-message             |
+| c            | notmuch-search-stash-map               | notmuch-show-stash-map                                | notmuch-show-stash-map                  |
+| d            |                                        |                                                       |                                         |
+| e            |                                        |                                                       | (notmuch-tree-button-activate)          |
+| f            |                                        | notmuch-show-forward-message                          | notmuch-show-forward-message            |
+| g            |                                        |                                                       |                                         |
+| h            |                                        | notmuch-show-toggle-visibility-headers                |                                         |
+| i            |                                        |                                                       |                                         |
+| j            | notmuch-jump-search                    | notmuch-jump-search                                   | notmuch-jump-search                     |
+| k            | notmuch-tag-jump                       | notmuch-tag-jump                                      | notmuch-tag-jump                        |
+| l            | notmuch-search-filter                  | notmuch-show-filter-thread                            | notmuch-tree-filter                     |
+| m            | notmuch-mua-new-mail                   | notmuch-mua-new-mail                                  | notmuch-mua-new-mail                    |
+| n            | notmuch-search-next-thread             | notmuch-show-next-open-message                        | notmuch-tree-next-matching-message      |
+| o            | notmuch-search-toggle-order            |                                                       | notmuch-tree-toggle-order               |
+| p            | notmuch-search-previous-thread         | notmuch-show-previous-open-message                    | notmuch-tree-prev-matching-message      |
+| q            | notmuch-bury-or-kill-this-buffer       | notmuch-bury-or-kill-this-buffer                      | notmuch-bury-or-kill-this-buffer        |
+| r            | notmuch-search-reply-to-thread-sender  | notmuch-show-reply-sender                             | notmuch-show-reply-sender               |
+| s            | notmuch-search                         | notmuch-search                                        | notmuch-search                          |
+| t            | notmuch-search-filter-by-tag           | toggle-truncate-lines                                 | notmuch-tree-filter-by-tag              |
+| u            |                                        |                                                       |                                         |
+| v            |                                        |                                                       | notmuch-show-view-all-mime-parts        |
+| w            |                                        | notmuch-show-save-attachments                         | notmuch-show-save-attachments           |
+| x            | notmuch-bury-or-kill-this-buffer       | notmuch-show-archive-message-then-next-or-exit        | notmuch-tree-quit                       |
+| y            |                                        |                                                       |                                         |
+| z            | notmuch-tree                           | notmuch-tree                                          | notmuch-tree-to-tree                    |
+| A            |                                        | notmuch-show-archive-thread-then-next                 | notmuch-tree-archive-thread             |
+| F            |                                        | notmuch-show-forward-open-messages                    |                                         |
+| G            | notmuch-poll-and-refresh-this-buffer   | notmuch-poll-and-refresh-this-buffer                  | notmuch-poll-and-refresh-this-buffer    |
+| N            |                                        | notmuch-show-next-message                             | notmuch-tree-next-message               |
+| O            |                                        |                                                       |                                         |
+| P            |                                        | notmuch-show-previous-message                         | notmuch-tree-prev-message               |
+| R            | notmuch-search-reply-to-thread         | notmuch-show-reply                                    | notmuch-show-reply                      |
+| S            |                                        |                                                       | notmuch-search-from-tree-current-query  |
+| V            |                                        | notmuch-show-view-raw-message                         | notmuch-show-view-raw-message           |
+| X            |                                        | notmuch-show-archive-thread-then-exit                 |                                         |
+| 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-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                    |
+| -            | notmuch-search-remove-tag              | notmuch-show-remove-tag                               | notmuch-tree-remove-tag                 |
+| .            |                                        | notmuch-show-part-map                                 |                                         |
+| <            | notmuch-search-first-thread            | notmuch-show-toggle-thread-indentation                |                                         |
+| <DEL>        | notmuch-search-scroll-down             | notmuch-show-rewind                                   | notmuch-tree-scroll-message-window-back |
+| <RET>        | notmuch-search-show-thread             | notmuch-show-toggle-message                           | notmuch-tree-show-message               |
+| <SPC>        | notmuch-search-scroll-up               | notmuch-show-advance                                  | notmuch-tree-scroll-or-next             |
+| <TAB>        |                                        | notmuch-show-next-button                              | notmuch-show-next-button                |
+| <backtab>    |                                        | notmuch-show-previous-button                          | notmuch-show-previous-button            |
+| =            | notmuch-refresh-this-buffer            | notmuch-refresh-this-buffer                           | notmuch-tree-refresh-view               |
+| >            | notmuch-search-last-thread             |                                                       |                                         |
+| ?            | notmuch-help                           | notmuch-help                                          | notmuch-help                            |
+| \vert        |                                        | notmuch-show-pipe-message                             | notmuch-show-pipe-message               |
 | [remap undo] | notmuch-tag-undo                       | notmuch-tag-undo                                      | notmuch-tag-undo                        |
-|-----------+----------------------------------------+-------------------------------------------------------+-----------------------------------------|
+|--------------+----------------------------------------+-------------------------------------------------------+-----------------------------------------|
-- 
2.34.1

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH v2 09/12] emacs: add notmuch-tag-undo
  2022-02-03 14:32 ` [RFC PATCH v2 09/12] emacs: add notmuch-tag-undo David Bremner
@ 2022-02-03 19:09   ` Miguel Bernabeu
  2022-02-03 21:57     ` David Bremner
  0 siblings, 1 reply; 16+ messages in thread
From: Miguel Bernabeu @ 2022-02-03 19:09 UTC (permalink / raw)
  To: notmuch, David Bremner

Just a typo that jumped to my eye. Sorry, I'm not proficient in elisp to validate the rest.

On February 3, 2022 3:32:51 PM GMT+01:00, David Bremner <david@tethera.net> wrote:
>Keybindings are deferred to a future commit.
>---
> doc/notmuch-emacs.rst      | 15 +++++++++++
> emacs/notmuch-tag.el       | 14 ++++++++++
> test/T315-emacs-tagging.sh | 52 ++++++++++++++++++++++++++++++++++++++
> 3 files changed, 81 insertions(+)
>
>diff --git a/doc/notmuch-emacs.rst b/doc/notmuch-emacs.rst
>index f2667de1..670d2925 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 each notmuch buffer supporting tagging operations (i.e buffers in
Duplicated `each`.

>+: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..d76b5ab8 100755
>--- a/test/T315-emacs-tagging.sh
>+++ b/test/T315-emacs-tagging.sh
>@@ -103,5 +103,57 @@ 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))"
>+    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\")
>+      (notmuch-test-wait)
>+      (execute-kbd-macro \"+two-$mode\")
>+      (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 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\")
>+      (notmuch-test-wait)
>+      (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

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH v2 09/12] emacs: add notmuch-tag-undo
  2022-02-03 19:09   ` Miguel Bernabeu
@ 2022-02-03 21:57     ` David Bremner
  0 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-03 21:57 UTC (permalink / raw)
  To: Miguel Bernabeu, notmuch

Miguel Bernabeu <miguel.bernabeu@lobber.eu> writes:

> Just a typo that jumped to my eye. Sorry, I'm not proficient in elisp to validate the rest.
>
> On February 3, 2022 3:32:51 PM GMT+01:00, David Bremner <david@tethera.net> wrote:
>>Keybindings are deferred to a future commit.
>>---
[snip]
>>+
>>+notmuch-tag-undo
>>+----------------
>>+
>>+Each each notmuch buffer supporting tagging operations (i.e buffers in
> Duplicated `each`.
>

thanks, fixed in git.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [RFC PATCH v2 12/12] emacs: whitespace cleanup for keybindings
  2022-02-03 14:32 ` [RFC PATCH v2 12/12] emacs: whitespace cleanup for keybindings David Bremner
@ 2022-02-04 12:35   ` David Bremner
  0 siblings, 0 replies; 16+ messages in thread
From: David Bremner @ 2022-02-04 12:35 UTC (permalink / raw)
  To: notmuch

[-- Attachment #1: Type: text/plain, Size: 380 bytes --]


I figured out the race condition in the tests. The previous test was
still running when the failing test started, the joys of using a shared
emacs for running all of the tests in one file.

The attached diff is split into the the commits that introduce the tests
in question in my working series, but you should be able to just apply
it on top of the posted series if you want.


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-test-fixups.patch --]
[-- Type: text/x-diff, Size: 1910 bytes --]

From fc88cba7f1f37b9cf3b296eace2422dd0e173502 Mon Sep 17 00:00:00 2001
From: David Bremner <david@tethera.net>
Date: Thu, 3 Feb 2022 21:05:05 -0400
Subject: [PATCH] test fixups

---
 test/T315-emacs-tagging.sh | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/test/T315-emacs-tagging.sh b/test/T315-emacs-tagging.sh
index c9e3e53a..c26413ce 100755
--- a/test/T315-emacs-tagging.sh
+++ b/test/T315-emacs-tagging.sh
@@ -119,7 +119,8 @@ for mode in search show tree unthreaded; do
       (notmuch-$mode \"$os_x_darwin_thread\")
       (notmuch-test-wait)
       (execute-kbd-macro \"+tag-to-be-undone-$mode\")
-      (notmuch-tag-undo))"
+      (notmuch-tag-undo)
+      (notmuch-test-wait))"
     count=$(notmuch count "tag:tag-to-be-undone-$mode")
     test_expect_equal "$count" "0"
 
@@ -128,9 +129,7 @@ for mode in search show tree unthreaded; do
       (notmuch-$mode \"$os_x_darwin_thread\")
       (notmuch-test-wait)
       (execute-kbd-macro \"+one-$mode\")
-      (notmuch-test-wait)
       (execute-kbd-macro \"+two-$mode\")
-      (notmuch-test-wait)
       (notmuch-tag-undo)
       (notmuch-test-wait)
       (execute-kbd-macro \"+three-$mode\"))"
@@ -143,7 +142,6 @@ for mode in search show tree unthreaded; do
       (notmuch-$mode \"$os_x_darwin_thread\")
       (notmuch-test-wait)
       (execute-kbd-macro \"+one-$mode\")
-      (notmuch-test-wait)
       (execute-kbd-macro \"+two-$mode\")
       (notmuch-tag-undo)
       (notmuch-test-wait)
@@ -159,7 +157,8 @@ for mode in search show tree unthreaded; do
       (notmuch-$mode \"$os_x_darwin_thread\")
       (notmuch-test-wait)
       (execute-kbd-macro \"+tag-to-be-undone-$mode\")
-      (execute-kbd-macro (kbd \"C-x u\")))"
+      (execute-kbd-macro (kbd \"C-x u\"))
+      (notmuch-test-wait))"
     count=$(notmuch count "tag:tag-to-be-undone-$mode")
     test_expect_equal "$count" "0"
 done
-- 
2.30.2


[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2022-02-04 12:35 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-03 14:32 v3 support undo in emacs frontend David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 01/12] doc/emacs: add minimal documentation for notmuch-unthreaded mode David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 02/12] test: split variable settings to their own file David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 03/12] test/emacs: split out emacs related tests David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 04/12] test/emacs: write *Notmuch errors* buffer from test macro David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 05/12] perf-test: allow running test_emacs from performance test suite David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 06/12] perf-test: emacs tagging David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 07/12] emacs: remove non-batch code path from function notmuch-tag David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 08/12] emacs/tag: keep tag history David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 09/12] emacs: add notmuch-tag-undo David Bremner
2022-02-03 19:09   ` Miguel Bernabeu
2022-02-03 21:57     ` David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 10/12] emacs: redirect undo to notmuch-tag-undo David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 11/12] emacs: Document undo binding David Bremner
2022-02-03 14:32 ` [RFC PATCH v2 12/12] emacs: whitespace cleanup for keybindings David Bremner
2022-02-04 12:35   ` David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).