aboutsummaryrefslogtreecommitdiffhomepage
path: root/emacs
diff options
context:
space:
mode:
authorGravatar Austin Clements <amdragon@MIT.EDU>2013-10-24 11:19:07 -0400
committerGravatar David Bremner <david@tethera.net>2013-11-08 20:35:13 -0400
commit730b8f61e0cf4b2e8c0f123c0914d472d6df38fc (patch)
tree8ac4fa0d20d221b7b2c94eb86d42007017af0796 /emacs
parent662e097984780165e57c7fa1f0ddf450dfeab83d (diff)
emacs: Use notmuch tag --batch for large tag queries
(Unfortunately, it's difficult to first demonstrate this problem with a known-broken test because modern Linux kernels have argument length limits in the megabytes, which makes Emacs really slow!)
Diffstat (limited to 'emacs')
-rw-r--r--emacs/notmuch-lib.el8
-rw-r--r--emacs/notmuch-tag.el15
2 files changed, 21 insertions, 2 deletions
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 17040ed8..08a86fd3 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -355,6 +355,14 @@ user-friendly queries."
"Return a query that matches the message with id ID."
(concat "id:" (notmuch-escape-boolean-term id)))
+(defun notmuch-hex-encode (str)
+ "Hex-encode STR (e.g., as used by batch tagging).
+
+This replaces spaces, percents, and double quotes in STR with
+%NN where NN is the hexadecimal value of the character."
+ (replace-regexp-in-string
+ "[ %\"]" (lambda (match) (format "%%%02x" (aref match 0))) str))
+
;;
(defun notmuch-common-do-stash (text)
diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index f705ac5d..b60f46c7 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -261,6 +261,12 @@ from TAGS if present."
(error "Changed tag must be of the form `+this_tag' or `-that_tag'")))))
(sort result-tags 'string<)))
+(defconst notmuch-tag-argument-limit 1000
+ "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.")
+
(defun notmuch-tag (query tag-changes)
"Add/remove tags in TAG-CHANGES to messages matching QUERY.
@@ -279,8 +285,13 @@ notmuch-after-tag-hook will be run."
tag-changes)
(unless (null tag-changes)
(run-hooks 'notmuch-before-tag-hook)
- (apply 'notmuch-call-notmuch-process "tag"
- (append tag-changes (list "--" query)))
+ (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")))
(run-hooks 'notmuch-after-tag-hook)))
(defun notmuch-tag-change-list (tags &optional reverse)