:supertype 'notmuch-wash-button-invisibility-toggle-type)
(defun notmuch-wash-region-isearch-show (overlay)
- (remove-from-invisibility-spec (overlay-get overlay 'invisible)))
+ (dolist (invis-spec (overlay-get overlay 'invisible))
+ (remove-from-invisibility-spec invis-spec)))
(defun notmuch-wash-button-label (overlay)
(let* ((type (overlay-get overlay 'type))
(lines-count (count-lines (overlay-start overlay) (overlay-end overlay))))
(format label-format lines-count)))
-(defun notmuch-wash-region-to-button (beg end type prefix)
- "Auxilary function to do the actual making of overlays and buttons
+(defun notmuch-wash-region-to-button (msg beg end type prefix)
+ "Auxiliary function to do the actual making of overlays and buttons
BEG and END are buffer locations. TYPE should a string, either
\"citation\" or \"signature\". PREFIX is some arbitrary text to
;; since the newly created symbol has no plist.
(let ((overlay (make-overlay beg end))
+ (message-invis-spec (plist-get msg :message-invis-spec))
(invis-spec (make-symbol (concat "notmuch-" type "-region")))
(button-type (intern-soft (concat "notmuch-wash-button-"
type "-toggle-type"))))
(add-to-invisibility-spec invis-spec)
- (overlay-put overlay 'invisible invis-spec)
+ (overlay-put overlay 'invisible (list invis-spec message-invis-spec))
(overlay-put overlay 'isearch-open-invisible #'notmuch-wash-region-isearch-show)
+ (overlay-put overlay 'priority 10)
(overlay-put overlay 'type type)
(goto-char (1+ end))
(save-excursion
'overlay overlay
:type button-type))))
-(defun notmuch-wash-excerpt-citations (depth)
+(defun notmuch-wash-excerpt-citations (msg depth)
"Excerpt citations and up to one signature."
(goto-char (point-min))
(beginning-of-line)
(msg-end (point-max))
(msg-lines (count-lines msg-start msg-end)))
(notmuch-wash-region-to-button
- msg-start msg-end "original" "\n")))
+ msg msg-start msg-end "original" "\n")))
(while (and (< (point) (point-max))
(re-search-forward notmuch-wash-citation-regexp nil t))
(let* ((cite-start (match-beginning 0))
(goto-char cite-end)
(forward-line (- notmuch-wash-citation-lines-suffix))
(notmuch-wash-region-to-button
- hidden-start (point-marker)
+ msg hidden-start (point-marker)
"citation" "\n")))))
(if (and (not (eobp))
(re-search-forward notmuch-wash-signature-regexp nil t))
(set-marker sig-end-marker (point-max))
(overlay-put (make-overlay sig-start-marker sig-end-marker) 'face 'message-cited-text)
(notmuch-wash-region-to-button
- sig-start-marker sig-end-marker
+ msg sig-start-marker sig-end-marker
"signature" "\n"))))))
;;
-(defun notmuch-wash-elide-blank-lines (depth)
+(defun notmuch-wash-elide-blank-lines (msg depth)
"Elide leading, trailing and successive blank lines."
;; Algorithm derived from `article-strip-multiple-blank-lines' in
;;
-(defun notmuch-wash-tidy-citations (depth)
+(defun notmuch-wash-tidy-citations (msg depth)
"Improve the display of cited regions of a message.
Perform several transformations on the message body:
;;
-(defun notmuch-wash-wrap-long-lines (depth)
+(defun notmuch-wash-wrap-long-lines (msg depth)
"Wrap any long lines in the message to the width of the window.
When doing so, maintaining citation leaders in the wrapped text."
(defvar diff-file-header-re) ; From `diff-mode.el'.
-(defun notmuch-wash-convert-inline-patch-to-part (depth)
+(defun notmuch-wash-subject-to-filename (subject &optional maxlen)
+ "Convert a mail SUBJECT into a filename.
+
+The resulting filename is similar to the names generated by \"git
+format-patch\", without the leading patch sequence number
+\"0001-\" and \".patch\" extension. Any leading \"[PREFIX]\"
+style strings are removed prior to conversion.
+
+Optional argument MAXLEN is the maximum length of the resulting
+filename, before trimming any trailing . and - characters."
+ (let* ((s (replace-regexp-in-string "^ *\\(\\[[^]]*\\] *\\)*" "" subject))
+ (s (replace-regexp-in-string "[^A-Za-z0-9._]+" "-" s))
+ (s (replace-regexp-in-string "\\.+" "." s))
+ (s (if maxlen (substring s 0 (min (length s) maxlen)) s))
+ (s (replace-regexp-in-string "[.-]*$" "" s)))
+ s))
+
+(defun notmuch-wash-subject-to-patch-sequence-number (subject)
+ "Convert a patch mail SUBJECT into a patch sequence number.
+
+Return the patch sequence number N from the last \"[PATCH N/M]\"
+style prefix in SUBJECT, or nil if such a prefix can't be found."
+ (when (string-match
+ "^ *\\(\\[[^]]*\\] *\\)*\\[[^]]*?\\([0-9]+\\)/[0-9]+[^]]*\\].*"
+ subject)
+ (string-to-number (substring subject (match-beginning 2) (match-end 2)))))
+
+(defun notmuch-wash-subject-to-patch-filename (subject)
+ "Convert a patch mail SUBJECT into a filename.
+
+The resulting filename is similar to the names generated by \"git
+format-patch\". If the patch mail was generated and sent using
+\"git format-patch/send-email\", this should re-create the
+original filename the sender had."
+ (format "%04d-%s.patch"
+ (or (notmuch-wash-subject-to-patch-sequence-number subject) 1)
+ (notmuch-wash-subject-to-filename subject 52)))
+
+(defun notmuch-wash-convert-inline-patch-to-part (msg depth)
"Convert an inline patch into a fake 'text/x-diff' attachment.
Given that this function guesses whether a buffer includes a
(setq patch-end (match-beginning 0)))
(save-restriction
(narrow-to-region patch-start patch-end)
- (setq part (plist-put part :content-type "text/x-diff"))
+ (setq part (plist-put part :content-type "inline-patch-fake-part"))
(setq part (plist-put part :content (buffer-string)))
(setq part (plist-put part :id -1))
- (setq part (plist-put part :filename "inline patch"))
+ (setq part (plist-put part :filename
+ (notmuch-wash-subject-to-patch-filename
+ (plist-get
+ (plist-get msg :headers) :Subject))))
(delete-region (point-min) (point-max))
(notmuch-show-insert-bodypart nil part depth))))))