For example, to replace a tag with another string, simply use
that string as a formatting expression. To change the foreground
of a tag to red, use the expression
- (propertize tag 'face '(:foreground \"red\"))
+ (propertize tag \\='face \\='(:foreground \"red\"))
See also `notmuch-tag-format-image', which can help replace tags
with images."
unless strike-through is not available (e.g., emacs is running in
a terminal) in which case it uses inverse video. To hide deleted
tags completely set this to
- '((\".*\" nil))
+ \\='((\".*\" nil))
See `notmuch-tag-formats' for full documentation."
:group 'notmuch-show
"Return SVG data representing a star icon.
This can be used with `notmuch-tag-format-image-data'."
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
-<svg version=\"1.1\" width=\"16\" height=\"16\">
+<svg version=\"1.1\" width=\"16\" height=\"16\" xmlns=\"http://www.w3.org/2000/svg\">
<g transform=\"translate(-242.81601,-315.59635)\">
<path
d=\"m 290.25762,334.31206 -17.64143,-11.77975 -19.70508,7.85447 5.75171,-20.41814 -13.55925,-16.31348 21.19618,-0.83936 11.325,-17.93675 7.34825,19.89939 20.55849,5.22795 -16.65471,13.13786 z\"
"Return SVG data representing an empty star icon.
This can be used with `notmuch-tag-format-image-data'."
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
-<svg version=\"1.1\" width=\"16\" height=\"16\">
+<svg version=\"1.1\" width=\"16\" height=\"16\" xmlns=\"http://www.w3.org/2000/svg\">
<g transform=\"translate(-242.81601,-315.59635)\">
<path
d=\"m 290.25762,334.31206 -17.64143,-11.77975 -19.70508,7.85447 5.75171,-20.41814 -13.55925,-16.31348 21.19618,-0.83936 11.325,-17.93675 7.34825,19.89939 20.55849,5.22795 -16.65471,13.13786 z\"
"Return SVG data representing a tag icon.
This can be used with `notmuch-tag-format-image-data'."
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>
-<svg version=\"1.1\" width=\"16\" height=\"16\">
+<svg version=\"1.1\" width=\"16\" height=\"16\" xmlns=\"http://www.w3.org/2000/svg\">
<g transform=\"translate(0,-1036.3622)\">
<path
d=\"m 0.44642857,1040.9336 12.50000043,0 2.700893,3.6161 -2.700893,3.616 -12.50000043,0 z\"
</g>
</svg>")
+;;; 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
(defvar notmuch-tag--format-cache (make-hash-table :test 'equal)
(defcustom notmuch-before-tag-hook nil
"Hooks that are run before tags of a message are modified.
-'tag-changes' will contain the tags that are about to be added or removed as
+`tag-changes' will contain the tags that are about to be added or removed as
a list of strings of the form \"+TAG\" or \"-TAG\".
-'query' will be a string containing the search query that determines
+`query' will be a string containing the search query that determines
the messages that are about to be tagged."
:type 'hook
:options '(notmuch-hl-line-mode)
(defcustom notmuch-after-tag-hook nil
"Hooks that are run after tags of a message are modified.
-'tag-changes' will contain the tags that were added or removed as
+`tag-changes' will contain the tags that were added or removed as
a list of strings of the form \"+TAG\" or \"-TAG\".
-'query' will be a string containing the search query that determines
+`query' will be a string containing the search query that determines
the messages that were tagged."
:type 'hook
:options '(notmuch-hl-line-mode)
(split-string
(with-output-to-string
(with-current-buffer standard-output
- (apply 'call-process notmuch-command nil t
+ (apply 'notmuch--call-process notmuch-command nil t
nil "search" "--output=tags" "--exclude=false" search-terms)))
"\n+" t))
(set-keymap-parent map crm-local-completion-map)
(define-key map " " 'self-insert-command)
map)))
- (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))))
+ (completing-read-multiple prompt tag-list
+ nil nil initial-input
+ 'notmuch-read-tag-changes-history)))
;;; Tagging
"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)
+(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\" ..)
(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)
- (query query))
- (run-hooks 'notmuch-after-tag-hook))))
+ (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)))
+
+(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.