X-Git-Url: https://git.notmuchmail.org/git?a=blobdiff_plain;f=emacs%2Fnotmuch-tag.el;h=908e7ade6270bccce7fb6afbbb3e63eccc261465;hb=12621980ee19aa36c76ad16500c4f5a43ca6c6ca;hp=22a603fcf04ab279a38acba548f0bf26a4de5bc4;hpb=45444eebe5c618d08ab168c49201bcd3cc235506;p=notmuch diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el index 22a603fc..908e7ade 100644 --- a/emacs/notmuch-tag.el +++ b/emacs/notmuch-tag.el @@ -148,15 +148,16 @@ This can be used with `notmuch-tag-format-image-data'." (dolist (format (cdr formats) tag) (setq tag (eval format)))))))) -(defun notmuch-tag-format-tags (tags) +(defun notmuch-tag-format-tags (tags &optional face) "Return a string representing formatted TAGS." - (notmuch-combine-face-text-property-string - (mapconcat #'identity - ;; nil indicated that the tag was deliberately hidden - (delq nil (mapcar #'notmuch-tag-format-tag tags)) - " ") - 'notmuch-tag-face - t)) + (let ((face (or face 'notmuch-tag-face))) + (notmuch-combine-face-text-property-string + (mapconcat #'identity + ;; nil indicated that the tag was deliberately hidden + (delq nil (mapcar #'notmuch-tag-format-tag tags)) + " ") + face + t))) (defcustom notmuch-before-tag-hook nil "Hooks that are run before tags of a message are modified. @@ -230,8 +231,16 @@ initial input in the minibuffer." (set-keymap-parent map crm-local-completion-map) (define-key map " " 'self-insert-command) map))) - (delete "" (completing-read-multiple prompt - tag-list nil nil initial-input + (delete "" (completing-read-multiple + prompt + ;; Append the separator to each completion so when the + ;; user completes a tag they can immediately begin + ;; entering another. `completing-read-multiple' + ;; ultimately splits the input on crm-separator, so we + ;; don't need to strip this back off (we just need to + ;; delete "empty" entries caused by trailing spaces). + (mapcar (lambda (tag-op) (concat tag-op crm-separator)) tag-list) + nil nil initial-input 'notmuch-read-tag-changes-history)))) (defun notmuch-update-tags (tags tag-changes) @@ -253,6 +262,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. @@ -271,8 +286,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)