]> git.notmuchmail.org Git - notmuch/blobdiff - emacs/notmuch-wash.el
emacs: Show all multipart/alternative parts by default.
[notmuch] / emacs / notmuch-wash.el
index 6760f3e743c3a578dbba46758d682292a1a55784..92f07c5000751fb394d45c26cb2593902e594e6b 100644 (file)
@@ -124,7 +124,8 @@ collapse the remaining lines into a button.")
   :supertype 'notmuch-wash-button-invisibility-toggle-type)
 
 (defun notmuch-wash-region-isearch-show (overlay)
   :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))
 
 (defun notmuch-wash-button-label (overlay)
   (let* ((type (overlay-get overlay 'type))
@@ -135,7 +136,7 @@ collapse the remaining lines into a button.")
         (lines-count (count-lines (overlay-start overlay) (overlay-end overlay))))
     (format label-format lines-count)))
 
         (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)
+(defun notmuch-wash-region-to-button (msg beg end type prefix)
   "Auxilary function to do the actual making of overlays and buttons
 
 BEG and END are buffer locations. TYPE should a string, either
   "Auxilary function to do the actual making of overlays and buttons
 
 BEG and END are buffer locations. TYPE should a string, either
@@ -148,12 +149,14 @@ insert before the button, probably for indentation."
   ;; since the newly created symbol has no plist.
 
   (let ((overlay (make-overlay beg end))
   ;; 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)
        (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 '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-put overlay 'type type)
     (goto-char (1+ end))
     (save-excursion
@@ -164,7 +167,7 @@ insert before the button, probably for indentation."
                     'overlay overlay
                     :type button-type))))
 
                     '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)
   "Excerpt citations and up to one signature."
   (goto-char (point-min))
   (beginning-of-line)
@@ -174,7 +177,7 @@ insert before the button, probably for indentation."
             (msg-end (point-max))
             (msg-lines (count-lines msg-start msg-end)))
        (notmuch-wash-region-to-button
             (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))
   (while (and (< (point) (point-max))
              (re-search-forward notmuch-wash-citation-regexp nil t))
     (let* ((cite-start (match-beginning 0))
@@ -190,7 +193,7 @@ insert before the button, probably for indentation."
          (goto-char cite-end)
          (forward-line (- notmuch-wash-citation-lines-suffix))
          (notmuch-wash-region-to-button
          (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))
           "citation" "\n")))))
   (if (and (not (eobp))
           (re-search-forward notmuch-wash-signature-regexp nil t))
@@ -204,12 +207,12 @@ insert before the button, probably for indentation."
              (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
              (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"))))))
 
 ;;
 
               "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
   "Elide leading, trailing and successive blank lines."
 
   ;; Algorithm derived from `article-strip-multiple-blank-lines' in
@@ -237,7 +240,7 @@ insert before the button, probably for indentation."
 
 ;;
 
 
 ;;
 
-(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:
   "Improve the display of cited regions of a message.
 
 Perform several transformations on the message body:
@@ -268,7 +271,7 @@ 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."
   "Wrap any long lines in the message to the width of the window.
 
 When doing so, maintaining citation leaders in the wrapped text."
@@ -287,7 +290,7 @@ When doing so, maintaining citation leaders in the wrapped text."
 
 (defvar diff-file-header-re) ; From `diff-mode.el'.
 
 
 (defvar diff-file-header-re) ; From `diff-mode.el'.
 
-(defun notmuch-wash-convert-inline-patch-to-part (depth)
+(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
   "Convert an inline patch into a fake 'text/x-diff' attachment.
 
 Given that this function guesses whether a buffer includes a
@@ -319,4 +322,71 @@ for error."
 
 ;;
 
 
 ;;
 
+;; Temporary workaround for Emacs bug #8721
+;; http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8721
+
+(defun notmuch-isearch-range-invisible (beg end)
+  "Same as `isearch-range-invisible' but with fixed Emacs bug #8721."
+  (when (/= beg end)
+    ;; Check that invisibility runs up to END.
+    (save-excursion
+      (goto-char beg)
+      (let (;; can-be-opened keeps track if we can open some overlays.
+           (can-be-opened (eq search-invisible 'open))
+           ;; the list of overlays that could be opened
+           (crt-overlays nil))
+       (when (and can-be-opened isearch-hide-immediately)
+         (isearch-close-unnecessary-overlays beg end))
+       ;; If the following character is currently invisible,
+       ;; skip all characters with that same `invisible' property value.
+       ;; Do that over and over.
+       (while (and (< (point) end) (invisible-p (point)))
+         (if (invisible-p (get-text-property (point) 'invisible))
+             (progn
+               (goto-char (next-single-property-change (point) 'invisible
+                                                       nil end))
+               ;; if text is hidden by an `invisible' text property
+               ;; we cannot open it at all.
+               (setq can-be-opened nil))
+           (when can-be-opened
+             (let ((overlays (overlays-at (point)))
+                   ov-list
+                   o
+                   invis-prop)
+               (while overlays
+                 (setq o (car overlays)
+                       invis-prop (overlay-get o 'invisible))
+                 (if (invisible-p invis-prop)
+                     (if (overlay-get o 'isearch-open-invisible)
+                         (setq ov-list (cons o ov-list))
+                       ;; We found one overlay that cannot be
+                       ;; opened, that means the whole chunk
+                       ;; cannot be opened.
+                       (setq can-be-opened nil)))
+                 (setq overlays (cdr overlays)))
+               (if can-be-opened
+                   ;; It makes sense to append to the open
+                   ;; overlays list only if we know that this is
+                   ;; t.
+                   (setq crt-overlays (append ov-list crt-overlays)))))
+           (goto-char (next-overlay-change (point)))))
+       ;; See if invisibility reaches up thru END.
+       (if (>= (point) end)
+           (if (and can-be-opened (consp crt-overlays))
+               (progn
+                 (setq isearch-opened-overlays
+                       (append isearch-opened-overlays crt-overlays))
+                 (mapc 'isearch-open-overlay-temporary crt-overlays)
+                 nil)
+             (setq isearch-hidden t)))))))
+
+(defadvice isearch-range-invisible (around notmuch-isearch-range-invisible-advice activate)
+  "Call `notmuch-isearch-range-invisible' instead of the original
+`isearch-range-invisible' when in `notmuch-show-mode' mode."
+  (if (eq major-mode 'notmuch-show-mode)
+      (setq ad-return-value (notmuch-isearch-range-invisible beg end))
+    ad-do-it))
+
+;;
+
 (provide 'notmuch-wash)
 (provide 'notmuch-wash)