+(defvar notmuch-show-id-regexp "ID: \\(.*\\)$")
+(defvar notmuch-show-tags-regexp "(\\([^)]*\\))$")
+
+(defun notmuch-show-get-message-id ()
+ (save-excursion
+ (beginning-of-line)
+ (if (not (looking-at notmuch-show-message-begin-regexp))
+ (re-search-backward notmuch-show-message-begin-regexp))
+ (re-search-forward notmuch-show-id-regexp)
+ (buffer-substring (match-beginning 1) (match-end 1))))
+
+(defun notmuch-show-set-tags (tags)
+ (save-excursion
+ (beginning-of-line)
+ (if (not (looking-at notmuch-show-message-begin-regexp))
+ (re-search-backward notmuch-show-message-begin-regexp))
+ (re-search-forward notmuch-show-tags-regexp)
+ (let ((inhibit-read-only t)
+ (beg (match-beginning 1))
+ (end (match-end 1)))
+ (delete-region beg end)
+ (goto-char beg)
+ (insert (mapconcat 'identity tags " ")))))
+
+(defun notmuch-show-get-tags ()
+ (save-excursion
+ (beginning-of-line)
+ (if (not (looking-at notmuch-show-message-begin-regexp))
+ (re-search-backward notmuch-show-message-begin-regexp))
+ (re-search-forward notmuch-show-tags-regexp)
+ (split-string (buffer-substring (match-beginning 1) (match-end 1)))))
+
+(defun notmuch-show-add-tag (tag)
+ (interactive "sTag to add: ")
+ (notmuch-call-notmuch-process "tag" (concat "+" tag) (concat "id:" (notmuch-show-get-message-id)))
+ (notmuch-show-set-tags (delete-dups (sort (cons tag (notmuch-show-get-tags)) 'string<))))
+
+(defun notmuch-show-remove-tag (tag)
+ (interactive "sTag to remove: ")
+ (let ((tags (notmuch-show-get-tags)))
+ (if (member tag tags)
+ (progn
+ (notmuch-call-notmuch-process "tag" (concat "-" tag) (concat "id:" (notmuch-show-get-message-id)))
+ (notmuch-show-set-tags (delete tag tags))))))
+
+(defun notmuch-show-archive-thread ()
+ "Archive each message in thread, and show next thread from search.
+
+Archive each message currrently shown by removing the \"inbox\"
+tag from each. Then kill this buffer and show the next thread
+from the search from which this thread was originally shown.
+
+Note: This command is safe from any race condition of new messages
+being delivered to the same thread. It does not archive the
+entire thread, but only the messages shown in the current
+buffer."