]> git.notmuchmail.org Git - notmuch/blobdiff - emacs/notmuch-show.el
emacs: Access raw messages via cat subcommand
[notmuch] / emacs / notmuch-show.el
index 3fc3787c13496ed6c5b1f6a00077cf9496388b68..9b3841fffbbbf21233190950b9c11104d762e28a 100644 (file)
@@ -21,7 +21,7 @@
 ;; Authors: Carl Worth <cworth@cworth.org>
 ;;          David Edmondson <dme@dme.org>
 
-(require 'cl)
+(eval-when-compile (require 'cl))
 (require 'mm-view)
 (require 'message)
 (require 'mm-decode)
@@ -85,10 +85,10 @@ any given message."
 (defmacro with-current-notmuch-show-message (&rest body)
   "Evaluate body with current buffer set to the text of current message"
   `(save-excursion
-     (let ((filename (notmuch-show-get-filename)))
-       (let ((buf (generate-new-buffer (concat "*notmuch-msg-" filename "*"))))
+     (let ((id (notmuch-show-get-message-id)))
+       (let ((buf (generate-new-buffer (concat "*notmuch-msg-" id "*"))))
          (with-current-buffer buf
-           (insert-file-contents filename nil nil nil t)
+           (call-process notmuch-command nil t nil "cat" id)
            ,@body)
         (kill-buffer buf)))))
 
@@ -586,7 +586,6 @@ function is used. "
       "Keymap for \"notmuch show\" buffers.")
 (fset 'notmuch-show-mode-map notmuch-show-mode-map)
 
-;;;###autoload
 (defun notmuch-show-mode ()
   "Major mode for viewing a thread with notmuch.
 
@@ -918,7 +917,11 @@ any effects from previous calls to
 (defun notmuch-show-view-raw-message ()
   "View the file holding the current message."
   (interactive)
-  (view-file (notmuch-show-get-filename)))
+  (let ((id (notmuch-show-get-message-id)))
+    (let ((buf (get-buffer-create (concat "*notmuch-raw-" id "*"))))
+      (switch-to-buffer buf)
+      (save-excursion
+       (call-process notmuch-command nil t nil "cat" id)))))
 
 (defun notmuch-show-pipe-message (entire-thread command)
   "Pipe the contents of the current message (or thread) to the given command.
@@ -939,32 +942,58 @@ than only the current message."
                       (mapconcat 'identity (notmuch-show-get-message-ids-for-open-messages) " OR "))
                      " | " command))
       (setq shell-command
-           (concat command " < " (shell-quote-argument (notmuch-show-get-filename)))))
+           (concat "notmuch cat " (shell-quote-argument (notmuch-show-get-message-id)) " | " command)))
     (start-process-shell-command "notmuch-pipe-command" "*notmuch-pipe*" shell-command)))
 
+(defun notmuch-show-add-tags-worker (current-tags add-tags)
+  "Add to `current-tags' with any tags from `add-tags' not
+currently present and return the result."
+  (let ((result-tags (copy-sequence current-tags)))
+    (mapc (lambda (add-tag)
+           (unless (member add-tag current-tags)
+             (setq result-tags (push add-tag result-tags))))
+           add-tags)
+    (sort result-tags 'string<)))
+
+(defun notmuch-show-del-tags-worker (current-tags del-tags)
+  "Remove any tags in `del-tags' from `current-tags' and return
+the result."
+  (let ((result-tags (copy-sequence current-tags)))
+    (mapc (lambda (del-tag)
+           (setq result-tags (delete del-tag result-tags)))
+         del-tags)
+    result-tags))
+
 (defun notmuch-show-add-tag (&rest toadd)
   "Add a tag to the current message."
   (interactive
    (list (notmuch-select-tag-with-completion "Tag to add: ")))
-  (apply 'notmuch-call-notmuch-process
-        (append (cons "tag"
-                      (mapcar (lambda (s) (concat "+" s)) toadd))
-                (cons (notmuch-show-get-message-id) nil)))
-  (notmuch-show-set-tags (sort (union toadd (notmuch-show-get-tags) :test 'string=) 'string<)))
+
+  (let* ((current-tags (notmuch-show-get-tags))
+        (new-tags (notmuch-show-add-tags-worker current-tags toadd)))
+
+    (unless (equal current-tags new-tags)
+      (apply 'notmuch-call-notmuch-process
+            (append (cons "tag"
+                          (mapcar (lambda (s) (concat "+" s)) toadd))
+                    (cons (notmuch-show-get-message-id) nil)))
+      (notmuch-show-set-tags new-tags))))
 
 (defun notmuch-show-remove-tag (&rest toremove)
   "Remove a tag from the current message."
   (interactive
    (list (notmuch-select-tag-with-completion
          "Tag to remove: " (notmuch-show-get-message-id))))
-  (let ((tags (notmuch-show-get-tags)))
-    (if (intersection tags toremove :test 'string=)
-       (progn
-         (apply 'notmuch-call-notmuch-process
-                (append (cons "tag"
-                              (mapcar (lambda (s) (concat "-" s)) toremove))
-                        (cons (notmuch-show-get-message-id) nil)))
-         (notmuch-show-set-tags (sort (set-difference tags toremove :test 'string=) 'string<))))))
+
+  (let* ((current-tags (notmuch-show-get-tags))
+        (new-tags (notmuch-show-del-tags-worker current-tags toremove)))
+
+    (unless (equal current-tags new-tags)
+      (apply 'notmuch-call-notmuch-process
+            (append (cons "tag"
+                          (mapcar (lambda (s) (concat "-" s)) toremove))
+                    (cons (notmuch-show-get-message-id) nil)))
+      (notmuch-show-set-tags new-tags))))
 
 (defun notmuch-show-toggle-headers ()
   "Toggle the visibility of the current message headers."