(defun notmuch-show-update-tags (tags)
"Update the displayed tags of the current message."
(save-excursion
- (goto-char (notmuch-show-message-top))
- (when (re-search-forward "(\\([^()]*\\))$" (line-end-position) t)
- (let ((inhibit-read-only t))
- (replace-match (concat "("
- (notmuch-tag-format-tags
- tags
- (notmuch-show-get-prop :orig-tags))
- ")"))))))
+ (let ((inhibit-read-only t)
+ (start (notmuch-show-message-top))
+ (depth (notmuch-show-get-prop :depth))
+ (orig-tags (notmuch-show-get-prop :orig-tags))
+ (props (notmuch-show-get-message-properties))
+ (extent (notmuch-show-message-extent)))
+ (goto-char start)
+ (notmuch-show-insert-headerline props depth tags orig-tags)
+ (put-text-property start (1+ start)
+ :notmuch-message-properties props)
+ (put-text-property (car extent) (cdr extent) :notmuch-message-extent extent)
+ ;; delete original headerline, but do not save to kill ring
+ (delete-region (point) (1+ (line-end-position))))))
(defun notmuch-clean-address (address)
"Try to clean a single email ADDRESS for display. Return a cons
(plist-put msg :height height)
height))))
-(defun notmuch-show-insert-headerline (headers date tags depth)
+(defun notmuch-show-insert-headerline (msg-plist depth tags &optional orig-tags)
"Insert a notmuch style headerline based on HEADERS for a
message at DEPTH in the current thread."
- (let ((start (point))
- (from (notmuch-sanitize
+ (let* ((start (point))
+ (headers (plist-get msg-plist :headers))
+ (duplicate (or (plist-get msg-plist :duplicate) 0))
+ (file-count (length (plist-get msg-plist :filename)))
+ (date (or (and notmuch-show-relative-dates
+ (plist-get msg-plist :date_relative))
+ (plist-get headers :Date)))
+ (from (notmuch-sanitize
(notmuch-show-clean-address (plist-get headers :From)))))
(when (string-match "\\cR" from)
;; If the From header has a right-to-left character add
" ("
date
") ("
- (notmuch-tag-format-tags tags tags)
- ")\n")
+ (notmuch-tag-format-tags tags (or orig-tags tags))
+ ")")
+ (insert
+ (if (> file-count 1)
+ (let ((txt (format "%d/%d\n" duplicate file-count)))
+ (concat
+ (notmuch-show-spaces-n (max 0 (- (window-width) (+ (current-column) (length txt)))))
+ txt))
+ "\n"))
(overlay-put (make-overlay start (point))
'face 'notmuch-message-summary-face)))
(make-variable-buffer-local 'notmuch-show-previous-subject)
(defun notmuch-show-choose-duplicate (duplicate)
+ "Display message file with index DUPLICATE in place of the current one.
+
+Message file indices are based on the order the files are
+discovered by `notmuch new' (and hence are somewhat arbitrary),
+and correspond to those passed to the \"\\-\\-duplicate\" arguments
+to the CLI.
+
+When called interactively, the function will prompt for the index
+of the file to display. An error will be signaled if the index
+is out of range."
(interactive "Nduplicate: ")
(let ((count (length (notmuch-show-get-prop :filename))))
(when (or (> duplicate count)
headers-start headers-end
(bare-subject (notmuch-show-strip-re (plist-get headers :Subject))))
(setq message-start (point-marker))
- (notmuch-show-insert-headerline headers
- (or (and notmuch-show-relative-dates
- (plist-get msg :date_relative))
- (plist-get headers :Date))
- (plist-get msg :tags) depth)
+ (notmuch-show-insert-headerline msg depth (plist-get msg :tags))
(setq content-start (point-marker))
;; Set `headers-start' to point after the 'Subject:' header to be
;; compatible with the existing implementation. This just sets it
reset based on the original query."
(interactive "P")
(let ((inhibit-read-only t)
+ (mm-inline-override-types (notmuch--inline-override-types))
(state (unless reset-state
(notmuch-show-capture-state))))
;; `erase-buffer' does not seem to remove overlays, which can lead
;; dme: Would it make sense to use a macro for many of these?
-;; XXX TODO figure out what to do about multiple filenames
(defun notmuch-show-get-filename ()
"Return the filename of the current message."
- (car (notmuch-show-get-prop :filename)))
+ (let ((duplicate (notmuch-show-get-duplicate)))
+ (nth (1- duplicate) (notmuch-show-get-prop :filename))))
(defun notmuch-show-get-header (header &optional props)
"Return the named header of the current message, if any."
(defun notmuch-show-get-date ()
(notmuch-show-get-header :Date))
+(defun notmuch-show-get-duplicate ()
+ ;; if no duplicate property exists, assume first file
+ (or (notmuch-show-get-prop :duplicate) 1))
+
(defun notmuch-show-get-timestamp ()
(notmuch-show-get-prop :timestamp))
(defun notmuch-show-reply (&optional prompt-for-sender)
"Reply to the sender and all recipients of the current message."
(interactive "P")
- (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender t))
+ (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender t
+ (notmuch-show-get-prop :duplicate)))
(put 'notmuch-show-reply-sender 'notmuch-prefix-doc "... and prompt for sender")
(defun notmuch-show-reply-sender (&optional prompt-for-sender)
"Reply to the sender of the current message."
(interactive "P")
- (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender nil))
+ (notmuch-mua-new-reply (notmuch-show-get-message-id) prompt-for-sender nil
+ (notmuch-show-get-prop :duplicate)))
(put 'notmuch-show-forward-message 'notmuch-prefix-doc
"... and prompt for sender")
"View the original source of the current message."
(interactive)
(let* ((id (notmuch-show-get-message-id))
- (buf (get-buffer-create (concat "*notmuch-raw-" id "*")))
+ (duplicate (notmuch-show-get-duplicate))
+ (args (if (> duplicate 1)
+ (list (format "--duplicate=%d" duplicate) id)
+ (list id)))
+ (buf (get-buffer-create (format "*notmuch-raw-%s-%d*" id duplicate)))
(inhibit-read-only t))
(pop-to-buffer-same-window buf)
(erase-buffer)
(let ((coding-system-for-read 'no-conversion))
- (notmuch--call-process notmuch-command nil t nil "show" "--format=raw" id))
+ (apply #'notmuch--call-process notmuch-command nil t nil "show" "--format=raw" args))
(goto-char (point-min))
(set-buffer-modified-p nil)
(setq buffer-read-only t)
(interactive (let ((query-string (if current-prefix-arg
"Pipe all open messages to command: "
"Pipe message to command: ")))
- (list current-prefix-arg (read-string query-string))))
+ (list current-prefix-arg (read-shell-command query-string))))
(let (shell-command)
(if entire-thread
(setq shell-command