[PATCH 2/2] insert forest moved
authorMark Walters <markwalters1009@gmail.com>
Wed, 5 Jun 2013 16:23:46 +0000 (17:23 +0100)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:55:26 +0000 (09:55 -0800)
38/66dd400ada0f8da57d25cc55604328e1bd1f1f [new file with mode: 0644]

diff --git a/38/66dd400ada0f8da57d25cc55604328e1bd1f1f b/38/66dd400ada0f8da57d25cc55604328e1bd1f1f
new file mode 100644 (file)
index 0000000..e724ffe
--- /dev/null
@@ -0,0 +1,1566 @@
+Return-Path: <markwalters1009@gmail.com>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+       by olra.theworths.org (Postfix) with ESMTP id 0B1CB431FD8\r
+       for <notmuch@notmuchmail.org>; Wed,  5 Jun 2013 09:24:13 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: 0.224\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=0.224 tagged_above=-999 required=5\r
+       tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1,\r
+       FREEMAIL_ENVFROM_END_DIGIT=1, FREEMAIL_FROM=0.001,\r
+       HS_INDEX_PARAM=0.023, RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+       by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+       with ESMTP id xujJgItUg2nQ for <notmuch@notmuchmail.org>;\r
+       Wed,  5 Jun 2013 09:24:00 -0700 (PDT)\r
+Received: from mail-wi0-f175.google.com (mail-wi0-f175.google.com\r
+       [209.85.212.175]) (using TLSv1 with cipher RC4-SHA (128/128 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id 51A04431FB6\r
+       for <notmuch@notmuchmail.org>; Wed,  5 Jun 2013 09:23:57 -0700 (PDT)\r
+Received: by mail-wi0-f175.google.com with SMTP id hn14so4994170wib.8\r
+       for <notmuch@notmuchmail.org>; Wed, 05 Jun 2013 09:23:56 -0700 (PDT)\r
+DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113;\r
+       h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references;\r
+       bh=hKWwxBUR1hAlUagUlVrOWYvy1g8/CJe4Q7fzDgvJOS0=;\r
+       b=bekF8Pc2Ud/R5lvIhohatvlrgLbwS7yzmMjDt51rUaAsvtu2ZNmqcqvak45dESdJji\r
+       VcRQ3TNKGy9FltXkOjN4ebvG+7vl9Fvs6zyQmzIFVuo2UykuXtF4vhlqTEM0HvXQEDvG\r
+       dVfqezByfjdApWAwfL8z0gol5esui1m1+26J338hecmrtQb8eNXdKvyixVNHtqYFgcPO\r
+       15lTtB6QZCmbbCeCNXSyDLKPr1eS0B8hStohYyvWLN4+n4bn+YAu65bFjAPU0+RY55ir\r
+       jaWb79/KN/6/LGWuujBQ1zZ6HD9dFZzhO4tkrIHxxtJBFP/Y14nwBiwfk5G7br/xC4fr\r
+       u1qA==\r
+X-Received: by 10.180.184.101 with SMTP id et5mr7366942wic.45.1370449436197;\r
+       Wed, 05 Jun 2013 09:23:56 -0700 (PDT)\r
+Received: from localhost (93-97-24-31.zone5.bethere.co.uk. [93.97.24.31])\r
+       by mx.google.com with ESMTPSA id\r
+       fu14sm11487953wic.0.2013.06.05.09.23.54 for <multiple recipients>\r
+       (version=TLSv1.2 cipher=RC4-SHA bits=128/128);\r
+       Wed, 05 Jun 2013 09:23:55 -0700 (PDT)\r
+From: Mark Walters <markwalters1009@gmail.com>\r
+To: notmuch@notmuchmail.org\r
+Subject: [PATCH 2/2] insert forest moved\r
+Date: Wed,  5 Jun 2013 17:23:46 +0100\r
+Message-Id: <1370449426-2325-3-git-send-email-markwalters1009@gmail.com>\r
+X-Mailer: git-send-email 1.7.9.1\r
+In-Reply-To: <1370449426-2325-1-git-send-email-markwalters1009@gmail.com>\r
+References: <1370449426-2325-1-git-send-email-markwalters1009@gmail.com>\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+       <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+       <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Wed, 05 Jun 2013 16:24:13 -0000\r
+\r
+---\r
+ emacs/notmuch-show-display.el |  704 ++++++++++++++++++++++++++++++++++++++++-\r
+ emacs/notmuch-show.el         |  692 ----------------------------------------\r
+ 2 files changed, 703 insertions(+), 693 deletions(-)\r
+\r
+diff --git a/emacs/notmuch-show-display.el b/emacs/notmuch-show-display.el\r
+index 50d83ad..82678c2 100644\r
+--- a/emacs/notmuch-show-display.el\r
++++ b/emacs/notmuch-show-display.el\r
+@@ -21,5 +21,707 @@\r
+ ;; Authors: Carl Worth <cworth@cworth.org>\r
+ ;;          David Edmondson <dme@dme.org>\r
\r
++(require 'mm-view)\r
++(require 'message)\r
++(require 'mm-decode)\r
++(require 'mailcap)\r
\r
+-(provide 'notmuch-show-display)\r
+\ No newline at end of file\r
++(require 'notmuch-lib)\r
++(require 'notmuch-tag)\r
++(require 'notmuch-wash)\r
++(require 'notmuch-crypto)\r
++\r
++(declare-function notmuch-show-get-header "notmuch-show" (header &optional props))\r
++(declare-function notmuch-show-set-message-properties "notmuch-show" (props))\r
++(declare-function notmuch-show-set-prop  "notmuch-show" (prop val &optional props))\r
++\r
++(defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")\r
++  "Headers that should be shown in a message, in this order.\r
++\r
++For an open message, all of these headers will be made visible\r
++according to `notmuch-message-headers-visible' or can be toggled\r
++with `notmuch-show-toggle-visibility-headers'. For a closed message,\r
++only the first header in the list will be visible."\r
++  :type '(repeat string)\r
++  :group 'notmuch-show)\r
++\r
++(defcustom notmuch-message-headers-visible t\r
++  "Should the headers be visible by default?\r
++\r
++If this value is non-nil, then all of the headers defined in\r
++`notmuch-message-headers' will be visible by default in the display\r
++of each message. Otherwise, these headers will be hidden and\r
++`notmuch-show-toggle-visibility-headers' can be used to make them\r
++visible for any given message."\r
++  :type 'boolean\r
++  :group 'notmuch-show)\r
++\r
++(defcustom notmuch-show-relative-dates t\r
++  "Display relative dates in the message summary line."\r
++  :type 'boolean\r
++  :group 'notmuch-show)\r
++\r
++(defvar notmuch-show-markup-headers-hook '(notmuch-show-colour-headers)\r
++  "A list of functions called to decorate the headers listed in\r
++`notmuch-message-headers'.")\r
++\r
++(defcustom notmuch-show-insert-text/plain-hook '(notmuch-wash-wrap-long-lines\r
++                                               notmuch-wash-tidy-citations\r
++                                               notmuch-wash-elide-blank-lines\r
++                                               notmuch-wash-excerpt-citations)\r
++  "Functions used to improve the display of text/plain parts."\r
++  :type 'hook\r
++  :options '(notmuch-wash-convert-inline-patch-to-part\r
++           notmuch-wash-wrap-long-lines\r
++           notmuch-wash-tidy-citations\r
++           notmuch-wash-elide-blank-lines\r
++           notmuch-wash-excerpt-citations)\r
++  :group 'notmuch-show\r
++  :group 'notmuch-hooks)\r
++\r
++;; Mostly useful for debugging.\r
++(defcustom notmuch-show-all-multipart/alternative-parts nil\r
++  "Should all parts of multipart/alternative parts be shown?"\r
++  :type 'boolean\r
++  :group 'notmuch-show)\r
++\r
++(defcustom notmuch-show-indent-messages-width 1\r
++  "Width of message indentation in threads.\r
++\r
++Messages are shown indented according to their depth in a thread.\r
++This variable determines the width of this indentation measured\r
++in number of blanks.  Defaults to `1', choose `0' to disable\r
++indentation."\r
++  :type 'integer\r
++  :group 'notmuch-show)\r
++\r
++(defcustom notmuch-show-indent-multipart nil\r
++  "Should the sub-parts of a multipart/* part be indented?"\r
++  ;; dme: Not sure which is a good default.\r
++  :type 'boolean\r
++  :group 'notmuch-show)\r
++\r
++(defvar notmuch-show-process-crypto nil)\r
++(make-variable-buffer-local 'notmuch-show-process-crypto)\r
++(put 'notmuch-show-process-crypto 'permanent-local t)\r
++\r
++(defvar notmuch-show-indent-content t)\r
++(make-variable-buffer-local 'notmuch-show-indent-content)\r
++(put 'notmuch-show-indent-content 'permanent-local t)\r
++\r
++(defun notmuch-show-fontify-header ()\r
++  (let ((face (cond\r
++             ((looking-at "[Tt]o:")\r
++              'message-header-to)\r
++             ((looking-at "[Bb]?[Cc][Cc]:")\r
++              'message-header-cc)\r
++             ((looking-at "[Ss]ubject:")\r
++              'message-header-subject)\r
++             ((looking-at "[Ff]rom:")\r
++              'message-header-from)\r
++             (t\r
++              'message-header-other))))\r
++\r
++    (overlay-put (make-overlay (point) (re-search-forward ":"))\r
++               'face 'message-header-name)\r
++    (overlay-put (make-overlay (point) (re-search-forward ".*$"))\r
++               'face face)))\r
++\r
++(defun notmuch-show-colour-headers ()\r
++  "Apply some colouring to the current headers."\r
++  (goto-char (point-min))\r
++  (while (looking-at "^[A-Za-z][-A-Za-z0-9]*:")\r
++    (notmuch-show-fontify-header)\r
++    (forward-line)))\r
++\r
++(defun notmuch-show-spaces-n (n)\r
++  "Return a string comprised of `n' spaces."\r
++  (make-string n ? ))\r
++\r
++(defun notmuch-clean-address (address)\r
++  "Try to clean a single email ADDRESS for display. Return a cons\r
++cell of (AUTHOR_EMAIL AUTHOR_NAME). Return (ADDRESS nil) if\r
++parsing fails."\r
++  (condition-case nil\r
++    (let (p-name p-address)\r
++      ;; It would be convenient to use `mail-header-parse-address',\r
++      ;; but that expects un-decoded mailbox parts, whereas our\r
++      ;; mailbox parts are already decoded (and hence may contain\r
++      ;; UTF-8). Given that notmuch should handle most of the awkward\r
++      ;; cases, some simple string deconstruction should be sufficient\r
++      ;; here.\r
++      (cond\r
++       ;; "User <user@dom.ain>" style.\r
++       ((string-match "\\(.*\\) <\\(.*\\)>" address)\r
++      (setq p-name (match-string 1 address)\r
++            p-address (match-string 2 address)))\r
++\r
++       ;; "<user@dom.ain>" style.\r
++       ((string-match "<\\(.*\\)>" address)\r
++      (setq p-address (match-string 1 address)))\r
++\r
++       ;; Everything else.\r
++       (t\r
++      (setq p-address address)))\r
++\r
++      (when p-name\r
++      ;; Remove elements of the mailbox part that are not relevant for\r
++      ;; display, even if they are required during transport:\r
++      ;;\r
++      ;; Backslashes.\r
++      (setq p-name (replace-regexp-in-string "\\\\" "" p-name))\r
++\r
++      ;; Outer single and double quotes, which might be nested.\r
++      (loop\r
++       with start-of-loop\r
++       do (setq start-of-loop p-name)\r
++\r
++       when (string-match "^\"\\(.*\\)\"$" p-name)\r
++       do (setq p-name (match-string 1 p-name))\r
++\r
++       when (string-match "^'\\(.*\\)'$" p-name)\r
++       do (setq p-name (match-string 1 p-name))\r
++\r
++       until (string= start-of-loop p-name)))\r
++\r
++      ;; If the address is 'foo@bar.com <foo@bar.com>' then show just\r
++      ;; 'foo@bar.com'.\r
++      (when (string= p-name p-address)\r
++      (setq p-name nil))\r
++\r
++      (cons p-address p-name))\r
++    (error (cons address nil))))\r
++\r
++(defun notmuch-show-clean-address (address)\r
++  "Try to clean a single email ADDRESS for display.  Return\r
++unchanged ADDRESS if parsing fails."\r
++  (let* ((clean-address (notmuch-clean-address address))\r
++       (p-address (car clean-address))\r
++       (p-name (cdr clean-address)))\r
++    ;; If no name, return just the address.\r
++    (if (not p-name)\r
++      p-address\r
++      ;; Otherwise format the name and address together.\r
++      (concat p-name " <" p-address ">"))))\r
++\r
++(defun notmuch-show-insert-headerline (headers date tags depth)\r
++  "Insert a notmuch style headerline based on HEADERS for a\r
++message at DEPTH in the current thread."\r
++  (let ((start (point)))\r
++    (insert (notmuch-show-spaces-n (* notmuch-show-indent-messages-width depth))\r
++          (notmuch-show-clean-address (plist-get headers :From))\r
++          " ("\r
++          date\r
++          ") ("\r
++          (notmuch-tag-format-tags tags)\r
++          ")\n")\r
++    (overlay-put (make-overlay start (point)) 'face 'notmuch-message-summary-face)))\r
++\r
++(defun notmuch-show-insert-header (header header-value)\r
++  "Insert a single header."\r
++  (insert header ": " header-value "\n"))\r
++\r
++(defun notmuch-show-insert-headers (headers)\r
++  "Insert the headers of the current message."\r
++  (let ((start (point)))\r
++    (mapc (lambda (header)\r
++          (let* ((header-symbol (intern (concat ":" header)))\r
++                 (header-value (plist-get headers header-symbol)))\r
++            (if (and header-value\r
++                     (not (string-equal "" header-value)))\r
++                (notmuch-show-insert-header header header-value))))\r
++        notmuch-message-headers)\r
++    (save-excursion\r
++      (save-restriction\r
++      (narrow-to-region start (point-max))\r
++      (run-hooks 'notmuch-show-markup-headers-hook)))))\r
++\r
++(defun notmuch-show-insert-part-header (nth content-type declared-type &optional name comment)\r
++  (let ((button)\r
++      (base-label (concat (when name (concat name ": "))\r
++                          declared-type\r
++                          (unless (string-equal declared-type content-type)\r
++                            (concat " (as " content-type ")"))\r
++                          comment)))\r
++\r
++    (setq button\r
++        (insert-button\r
++         (concat "[ " base-label " ]")\r
++         :base-label base-label\r
++         :type 'notmuch-show-part-button-type\r
++         :notmuch-part nth\r
++         :notmuch-filename name\r
++         :notmuch-content-type content-type))\r
++    (insert "\n")\r
++    ;; return button\r
++    button))\r
++\r
++;; This is taken from notmuch-wash: maybe it should be unified?\r
++(defun notmuch-show-toggle-part-invisibility (&optional button)\r
++  (interactive)\r
++  (let* ((button (or button (button-at (point))))\r
++       (overlay (button-get button 'overlay)))\r
++    (when overlay\r
++      (let* ((show (overlay-get overlay 'invisible))\r
++           (new-start (button-start button))\r
++           (button-label (button-get button :base-label))\r
++           (old-point (point))\r
++           (inhibit-read-only t))\r
++      (overlay-put overlay 'invisible (not show))\r
++      (goto-char new-start)\r
++      (insert "[ " button-label (if show " ]" " (hidden) ]"))\r
++      (let ((old-end (button-end button)))\r
++        (move-overlay button new-start (point))\r
++        (delete-region (point) old-end))\r
++      (goto-char (min old-point (1- (button-end button))))))))\r
++\r
++(defun notmuch-show-multipart/*-to-list (part)\r
++  (mapcar (lambda (inner-part) (plist-get inner-part :content-type))\r
++        (plist-get part :content)))\r
++\r
++(defun notmuch-show-insert-part-multipart/alternative (msg part content-type nth depth declared-type)\r
++  (notmuch-show-insert-part-header nth declared-type content-type nil)\r
++  (let ((chosen-type (car (notmuch-multipart/alternative-choose (notmuch-show-multipart/*-to-list part))))\r
++      (inner-parts (plist-get part :content))\r
++      (start (point)))\r
++    ;; This inserts all parts of the chosen type rather than just one,\r
++    ;; but it's not clear that this is the wrong thing to do - which\r
++    ;; should be chosen if there are more than one that match?\r
++    (mapc (lambda (inner-part)\r
++          (let* ((inner-type (plist-get inner-part :content-type))\r
++                (hide (not (or notmuch-show-all-multipart/alternative-parts\r
++                         (string= chosen-type inner-type)))))\r
++            (notmuch-show-insert-bodypart msg inner-part depth hide)))\r
++        inner-parts)\r
++\r
++    (when notmuch-show-indent-multipart\r
++      (indent-rigidly start (point) 1)))\r
++  t)\r
++\r
++(defun notmuch-show-setup-w3m ()\r
++  "Instruct w3m how to retrieve content from a \"related\" part of a message."\r
++  (interactive)\r
++  (if (boundp 'w3m-cid-retrieve-function-alist)\r
++    (unless (assq 'notmuch-show-mode w3m-cid-retrieve-function-alist)\r
++      (push (cons 'notmuch-show-mode 'notmuch-show-w3m-cid-retrieve)\r
++          w3m-cid-retrieve-function-alist)))\r
++  (setq mm-inline-text-html-with-images t))\r
++\r
++(defvar w3m-current-buffer) ;; From `w3m.el'.\r
++(defvar notmuch-show-w3m-cid-store nil)\r
++(make-variable-buffer-local 'notmuch-show-w3m-cid-store)\r
++\r
++(defun notmuch-show-w3m-cid-store-internal (content-id\r
++                                          message-id\r
++                                          part-number\r
++                                          content-type\r
++                                          content)\r
++  (push (list content-id\r
++            message-id\r
++            part-number\r
++            content-type\r
++            content)\r
++      notmuch-show-w3m-cid-store))\r
++\r
++(defun notmuch-show-w3m-cid-store (msg part)\r
++  (let ((content-id (plist-get part :content-id)))\r
++    (when content-id\r
++      (notmuch-show-w3m-cid-store-internal (concat "cid:" content-id)\r
++                                         (plist-get msg :id)\r
++                                         (plist-get part :id)\r
++                                         (plist-get part :content-type)\r
++                                         nil))))\r
++\r
++(defun notmuch-show-w3m-cid-retrieve (url &rest args)\r
++  (let ((matching-part (with-current-buffer w3m-current-buffer\r
++                       (assoc url notmuch-show-w3m-cid-store))))\r
++    (if matching-part\r
++      (let ((message-id (nth 1 matching-part))\r
++            (part-number (nth 2 matching-part))\r
++            (content-type (nth 3 matching-part))\r
++            (content (nth 4 matching-part)))\r
++        ;; If we don't already have the content, get it and cache\r
++        ;; it, as some messages reference the same cid: part many\r
++        ;; times (hundreds!), which results in many calls to\r
++        ;; `notmuch part'.\r
++        (unless content\r
++          (setq content (notmuch-get-bodypart-internal (notmuch-id-to-query message-id)\r
++                                                            part-number notmuch-show-process-crypto))\r
++          (with-current-buffer w3m-current-buffer\r
++            (notmuch-show-w3m-cid-store-internal url\r
++                                                 message-id\r
++                                                 part-number\r
++                                                 content-type\r
++                                                 content)))\r
++        (insert content)\r
++        content-type)\r
++      nil)))\r
++\r
++(defun notmuch-show-insert-part-multipart/related (msg part content-type nth depth declared-type)\r
++  (notmuch-show-insert-part-header nth declared-type content-type nil)\r
++  (let ((inner-parts (plist-get part :content))\r
++      (start (point)))\r
++\r
++    ;; We assume that the first part is text/html and the remainder\r
++    ;; things that it references.\r
++\r
++    ;; Stash the non-primary parts.\r
++    (mapc (lambda (part)\r
++          (notmuch-show-w3m-cid-store msg part))\r
++        (cdr inner-parts))\r
++\r
++    ;; Render the primary part.\r
++    (notmuch-show-insert-bodypart msg (car inner-parts) depth)\r
++\r
++    (when notmuch-show-indent-multipart\r
++      (indent-rigidly start (point) 1)))\r
++  t)\r
++\r
++(defun notmuch-show-insert-part-multipart/signed (msg part content-type nth depth declared-type)\r
++  (let ((button (notmuch-show-insert-part-header nth declared-type content-type nil)))\r
++    (button-put button 'face 'notmuch-crypto-part-header)\r
++    ;; add signature status button if sigstatus provided\r
++    (if (plist-member part :sigstatus)\r
++      (let* ((from (notmuch-show-get-header :From msg))\r
++             (sigstatus (car (plist-get part :sigstatus))))\r
++        (notmuch-crypto-insert-sigstatus-button sigstatus from))\r
++      ;; if we're not adding sigstatus, tell the user how they can get it\r
++      (button-put button 'help-echo "Set notmuch-crypto-process-mime to process cryptographic MIME parts.")))\r
++\r
++  (let ((inner-parts (plist-get part :content))\r
++      (start (point)))\r
++    ;; Show all of the parts.\r
++    (mapc (lambda (inner-part)\r
++          (notmuch-show-insert-bodypart msg inner-part depth))\r
++        inner-parts)\r
++\r
++    (when notmuch-show-indent-multipart\r
++      (indent-rigidly start (point) 1)))\r
++  t)\r
++\r
++(defun notmuch-show-insert-part-multipart/encrypted (msg part content-type nth depth declared-type)\r
++  (let ((button (notmuch-show-insert-part-header nth declared-type content-type nil)))\r
++    (button-put button 'face 'notmuch-crypto-part-header)\r
++    ;; add encryption status button if encstatus specified\r
++    (if (plist-member part :encstatus)\r
++      (let ((encstatus (car (plist-get part :encstatus))))\r
++        (notmuch-crypto-insert-encstatus-button encstatus)\r
++        ;; add signature status button if sigstatus specified\r
++        (if (plist-member part :sigstatus)\r
++            (let* ((from (notmuch-show-get-header :From msg))\r
++                   (sigstatus (car (plist-get part :sigstatus))))\r
++              (notmuch-crypto-insert-sigstatus-button sigstatus from))))\r
++      ;; if we're not adding encstatus, tell the user how they can get it\r
++      (button-put button 'help-echo "Set notmuch-crypto-process-mime to process cryptographic MIME parts.")))\r
++\r
++  (let ((inner-parts (plist-get part :content))\r
++      (start (point)))\r
++    ;; Show all of the parts.\r
++    (mapc (lambda (inner-part)\r
++          (notmuch-show-insert-bodypart msg inner-part depth))\r
++        inner-parts)\r
++\r
++    (when notmuch-show-indent-multipart\r
++      (indent-rigidly start (point) 1)))\r
++  t)\r
++\r
++(defun notmuch-show-insert-part-multipart/* (msg part content-type nth depth declared-type)\r
++  (notmuch-show-insert-part-header nth declared-type content-type nil)\r
++  (let ((inner-parts (plist-get part :content))\r
++      (start (point)))\r
++    ;; Show all of the parts.\r
++    (mapc (lambda (inner-part)\r
++          (notmuch-show-insert-bodypart msg inner-part depth))\r
++        inner-parts)\r
++\r
++    (when notmuch-show-indent-multipart\r
++      (indent-rigidly start (point) 1)))\r
++  t)\r
++\r
++(defun notmuch-show-insert-part-message/rfc822 (msg part content-type nth depth declared-type)\r
++  (notmuch-show-insert-part-header nth declared-type content-type nil)\r
++  (let* ((message (car (plist-get part :content)))\r
++       (body (car (plist-get message :body)))\r
++       (start (point)))\r
++\r
++    ;; Override `notmuch-message-headers' to force `From' to be\r
++    ;; displayed.\r
++    (let ((notmuch-message-headers '("From" "Subject" "To" "Cc" "Date")))\r
++      (notmuch-show-insert-headers (plist-get message :headers)))\r
++\r
++    ;; Blank line after headers to be compatible with the normal\r
++    ;; message display.\r
++    (insert "\n")\r
++\r
++    ;; Show the body\r
++    (notmuch-show-insert-bodypart msg body depth)\r
++\r
++    (when notmuch-show-indent-multipart\r
++      (indent-rigidly start (point) 1)))\r
++  t)\r
++\r
++(defun notmuch-show-insert-part-text/plain (msg part content-type nth depth declared-type)\r
++  (let ((start (point)))\r
++    ;; If this text/plain part is not the first part in the message,\r
++    ;; insert a header to make this clear.\r
++    (if (> nth 1)\r
++      (notmuch-show-insert-part-header nth declared-type content-type (plist-get part :filename)))\r
++    (insert (notmuch-get-bodypart-content msg part nth notmuch-show-process-crypto))\r
++    (save-excursion\r
++      (save-restriction\r
++      (narrow-to-region start (point-max))\r
++      (run-hook-with-args 'notmuch-show-insert-text/plain-hook msg depth))))\r
++  t)\r
++\r
++(defun notmuch-show-insert-part-text/calendar (msg part content-type nth depth declared-type)\r
++  (notmuch-show-insert-part-header nth declared-type content-type (plist-get part :filename))\r
++  (insert (with-temp-buffer\r
++          (insert (notmuch-get-bodypart-content msg part nth notmuch-show-process-crypto))\r
++          ;; notmuch-get-bodypart-content provides "raw", non-converted\r
++          ;; data. Replace CRLF with LF before icalendar can use it.\r
++          (goto-char (point-min))\r
++          (while (re-search-forward "\r\n" nil t)\r
++            (replace-match "\n" nil nil))\r
++          (let ((file (make-temp-file "notmuch-ical"))\r
++                result)\r
++            (unwind-protect\r
++                (progn\r
++                  (unless (icalendar-import-buffer file t)\r
++                    (error "Icalendar import error. See *icalendar-errors* for more information"))\r
++                  (set-buffer (get-file-buffer file))\r
++                  (setq result (buffer-substring (point-min) (point-max)))\r
++                  (set-buffer-modified-p nil)\r
++                  (kill-buffer (current-buffer)))\r
++              (delete-file file))\r
++            result)))\r
++  t)\r
++\r
++;; For backwards compatibility.\r
++(defun notmuch-show-insert-part-text/x-vcalendar (msg part content-type nth depth declared-type)\r
++  (notmuch-show-insert-part-text/calendar msg part content-type nth depth declared-type))\r
++\r
++(defun notmuch-show-get-mime-type-of-application/octet-stream (part)\r
++  ;; If we can deduce a MIME type from the filename of the attachment,\r
++  ;; we return that.\r
++  (if (plist-get part :filename)\r
++      (let ((extension (file-name-extension (plist-get part :filename)))\r
++          mime-type)\r
++      (if extension\r
++          (progn\r
++            (mailcap-parse-mimetypes)\r
++            (setq mime-type (mailcap-extension-to-mime extension))\r
++            (if (and mime-type\r
++                     (not (string-equal mime-type "application/octet-stream")))\r
++                mime-type\r
++              nil))\r
++        nil))))\r
++\r
++;; Handler for wash generated inline patch fake parts.\r
++(defun notmuch-show-insert-part-inline-patch-fake-part (msg part content-type nth depth declared-type)\r
++  (notmuch-show-insert-part-*/* msg part content-type nth depth declared-type))\r
++\r
++(defun notmuch-show-insert-part-text/html (msg part content-type nth depth declared-type)\r
++  ;; text/html handler to work around bugs in renderers and our\r
++  ;; invisibile parts code. In particular w3m sets up a keymap which\r
++  ;; "leaks" outside the invisible region and causes strange effects\r
++  ;; in notmuch. We set mm-inline-text-html-with-w3m-keymap to nil to\r
++  ;; tell w3m not to set a keymap (so the normal notmuch-show-mode-map\r
++  ;; remains).\r
++  (let ((mm-inline-text-html-with-w3m-keymap nil))\r
++    (notmuch-show-insert-part-*/* msg part content-type nth depth declared-type)))\r
++\r
++(defun notmuch-show-insert-part-*/* (msg part content-type nth depth declared-type)\r
++  ;; This handler _must_ succeed - it is the handler of last resort.\r
++  (notmuch-show-insert-part-header nth content-type declared-type (plist-get part :filename))\r
++  (notmuch-mm-display-part-inline msg part nth content-type notmuch-show-process-crypto)\r
++  t)\r
++\r
++;; Functions for determining how to handle MIME parts.\r
++\r
++(defun notmuch-show-handlers-for (content-type)\r
++  "Return a list of content handlers for a part of type CONTENT-TYPE."\r
++  (let (result)\r
++    (mapc (lambda (func)\r
++          (if (functionp func)\r
++              (push func result)))\r
++        ;; Reverse order of prefrence.\r
++        (list (intern (concat "notmuch-show-insert-part-*/*"))\r
++              (intern (concat\r
++                       "notmuch-show-insert-part-"\r
++                       (car (notmuch-split-content-type content-type))\r
++                       "/*"))\r
++              (intern (concat "notmuch-show-insert-part-" content-type))))\r
++    result))\r
++\r
++;; \f\r
+\r
++\r
++(defun notmuch-show-insert-bodypart-internal (msg part content-type nth depth declared-type)\r
++  (let ((handlers (notmuch-show-handlers-for content-type)))\r
++    ;; Run the content handlers until one of them returns a non-nil\r
++    ;; value.\r
++    (while (and handlers\r
++              (not (condition-case err\r
++                       (funcall (car handlers) msg part content-type nth depth declared-type)\r
++                     (error (progn\r
++                              (insert "!!! Bodypart insert error: ")\r
++                              (insert (error-message-string err))\r
++                              (insert " !!!\n") nil)))))\r
++      (setq handlers (cdr handlers))))\r
++  t)\r
++\r
++(defun notmuch-show-create-part-overlays (msg beg end hide)\r
++  "Add an overlay to the part between BEG and END"\r
++  (let* ((button (button-at beg))\r
++       (part-beg (and button (1+ (button-end button)))))\r
++\r
++    ;; If the part contains no text we do not make it toggleable. We\r
++    ;; also need to check that the button is a genuine part button not\r
++    ;; a notmuch-wash button.\r
++    (when (and button (/= part-beg end) (button-get button :base-label))\r
++      (button-put button 'overlay (make-overlay part-beg end))\r
++      ;; We toggle the button for hidden parts as that gets the\r
++      ;; button label right.\r
++      (save-excursion\r
++      (when hide\r
++        (notmuch-show-toggle-part-invisibility button))))))\r
++\r
++(defun notmuch-show-insert-bodypart (msg part depth &optional hide)\r
++  "Insert the body part PART at depth DEPTH in the current thread.\r
++\r
++If HIDE is non-nil then initially hide this part."\r
++  (let* ((content-type (downcase (plist-get part :content-type)))\r
++       (mime-type (or (and (string= content-type "application/octet-stream")\r
++                           (notmuch-show-get-mime-type-of-application/octet-stream part))\r
++                      (and (string= content-type "inline patch")\r
++                           "text/x-diff")\r
++                      content-type))\r
++       (nth (plist-get part :id))\r
++       (beg (point)))\r
++\r
++    (notmuch-show-insert-bodypart-internal msg part mime-type nth depth content-type)\r
++    ;; Some of the body part handlers leave point somewhere up in the\r
++    ;; part, so we make sure that we're down at the end.\r
++    (goto-char (point-max))\r
++    ;; Ensure that the part ends with a carriage return.\r
++    (unless (bolp)\r
++      (insert "\n"))\r
++    (notmuch-show-create-part-overlays msg beg (point) hide)))\r
++\r
++(defun notmuch-show-insert-body (msg body depth)\r
++  "Insert the body BODY at depth DEPTH in the current thread."\r
++  (mapc (lambda (part) (notmuch-show-insert-bodypart msg part depth)) body))\r
++\r
++(defun notmuch-show-strip-re (string)\r
++  (replace-regexp-in-string "^\\([Rr]e: *\\)+" "" string))\r
++\r
++(defvar notmuch-show-previous-subject "")\r
++(make-variable-buffer-local 'notmuch-show-previous-subject)\r
++\r
++(defun notmuch-show-insert-msg (msg depth)\r
++  "Insert the message MSG at depth DEPTH in the current thread."\r
++  (let* ((headers (plist-get msg :headers))\r
++       ;; Indentation causes the buffer offset of the start/end\r
++       ;; points to move, so we must use markers.\r
++       message-start message-end\r
++       content-start content-end\r
++       headers-start headers-end\r
++       (bare-subject (notmuch-show-strip-re (plist-get headers :Subject))))\r
++\r
++    (setq message-start (point-marker))\r
++\r
++    (notmuch-show-insert-headerline headers\r
++                                  (or (if notmuch-show-relative-dates\r
++                                          (plist-get msg :date_relative)\r
++                                        nil)\r
++                                      (plist-get headers :Date))\r
++                                  (plist-get msg :tags) depth)\r
++\r
++    (setq content-start (point-marker))\r
++\r
++    ;; Set `headers-start' to point after the 'Subject:' header to be\r
++    ;; compatible with the existing implementation. This just sets it\r
++    ;; to after the first header.\r
++    (notmuch-show-insert-headers headers)\r
++    (save-excursion\r
++      (goto-char content-start)\r
++      ;; If the subject of this message is the same as that of the\r
++      ;; previous message, don't display it when this message is\r
++      ;; collapsed.\r
++      (when (not (string= notmuch-show-previous-subject\r
++                        bare-subject))\r
++      (forward-line 1))\r
++      (setq headers-start (point-marker)))\r
++    (setq headers-end (point-marker))\r
++\r
++    (setq notmuch-show-previous-subject bare-subject)\r
++\r
++    ;; A blank line between the headers and the body.\r
++    (insert "\n")\r
++    (notmuch-show-insert-body msg (plist-get msg :body)\r
++                            (if notmuch-show-indent-content depth 0))\r
++    ;; Ensure that the body ends with a newline.\r
++    (unless (bolp)\r
++      (insert "\n"))\r
++    (setq content-end (point-marker))\r
++\r
++    ;; Indent according to the depth in the thread.\r
++    (if notmuch-show-indent-content\r
++      (indent-rigidly content-start content-end (* notmuch-show-indent-messages-width depth)))\r
++\r
++    (setq message-end (point-max-marker))\r
++\r
++    ;; Save the extents of this message over the whole text of the\r
++    ;; message.\r
++    (put-text-property message-start message-end :notmuch-message-extent (cons message-start message-end))\r
++\r
++    ;; Create overlays used to control visibility\r
++    (plist-put msg :headers-overlay (make-overlay headers-start headers-end))\r
++    (plist-put msg :message-overlay (make-overlay headers-start content-end))\r
++\r
++    (plist-put msg :depth depth)\r
++\r
++    ;; Save the properties for this message. Currently this saves the\r
++    ;; entire message (augmented it with other stuff), which seems\r
++    ;; like overkill. We might save a reduced subset (for example, not\r
++    ;; the content).\r
++    (notmuch-show-set-message-properties msg)\r
++\r
++    ;; Set header visibility.\r
++    (notmuch-show-headers-visible msg notmuch-message-headers-visible)\r
++\r
++    ;; Message visibility depends on whether it matched the search\r
++    ;; criteria.\r
++    (notmuch-show-message-visible msg (and (plist-get msg :match)\r
++                                         (not (plist-get msg :excluded))))))\r
++\r
++(defun notmuch-show-insert-tree (tree depth)\r
++  "Insert the message tree TREE at depth DEPTH in the current thread."\r
++  (let ((msg (car tree))\r
++      (replies (cadr tree)))\r
++    ;; We test whether there is a message or just some replies.\r
++    (when msg\r
++      (notmuch-show-insert-msg msg depth))\r
++    (notmuch-show-insert-thread replies (1+ depth))))\r
++\r
++(defun notmuch-show-insert-thread (thread depth)\r
++  "Insert the thread THREAD at depth DEPTH in the current forest."\r
++  (mapc (lambda (tree) (notmuch-show-insert-tree tree depth)) thread))\r
++\r
++(defun notmuch-show-insert-forest (forest)\r
++  "Insert the forest of threads FOREST."\r
++  (mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest))\r
++\r
++;; Functions relating to the visibility of messages and their\r
++;; components.\r
++\r
++(defun notmuch-show-message-visible (props visible-p)\r
++  (overlay-put (plist-get props :message-overlay) 'invisible (not visible-p))\r
++  (notmuch-show-set-prop :message-visible visible-p props))\r
++\r
++(defun notmuch-show-headers-visible (props visible-p)\r
++  (overlay-put (plist-get props :headers-overlay) 'invisible (not visible-p))\r
++  (notmuch-show-set-prop :headers-visible visible-p props))\r
++\r
++;;\r
++\r
++(provide 'notmuch-show-display)\r
+diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el\r
+index 37ba911..9e3401d 100644\r
+--- a/emacs/notmuch-show.el\r
++++ b/emacs/notmuch-show.el\r
+@@ -22,17 +22,12 @@\r
+ ;;          David Edmondson <dme@dme.org>\r
\r
+ (eval-when-compile (require 'cl))\r
+-(require 'mm-view)\r
+-(require 'message)\r
+-(require 'mm-decode)\r
+-(require 'mailcap)\r
+ (require 'icalendar)\r
+ (require 'goto-addr)\r
\r
+ (require 'notmuch-lib)\r
+ (require 'notmuch-tag)\r
+ (require 'notmuch-query)\r
+-(require 'notmuch-wash)\r
+ (require 'notmuch-mua)\r
+ (require 'notmuch-crypto)\r
+ (require 'notmuch-print)\r
+@@ -43,36 +38,6 @@\r
+ (declare-function notmuch-search-previous-thread "notmuch" nil)\r
+ (declare-function notmuch-search-show-thread "notmuch" nil)\r
\r
+-(defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")\r
+-  "Headers that should be shown in a message, in this order.\r
+-\r
+-For an open message, all of these headers will be made visible\r
+-according to `notmuch-message-headers-visible' or can be toggled\r
+-with `notmuch-show-toggle-visibility-headers'. For a closed message,\r
+-only the first header in the list will be visible."\r
+-  :type '(repeat string)\r
+-  :group 'notmuch-show)\r
+-\r
+-(defcustom notmuch-message-headers-visible t\r
+-  "Should the headers be visible by default?\r
+-\r
+-If this value is non-nil, then all of the headers defined in\r
+-`notmuch-message-headers' will be visible by default in the display\r
+-of each message. Otherwise, these headers will be hidden and\r
+-`notmuch-show-toggle-visibility-headers' can be used to make them\r
+-visible for any given message."\r
+-  :type 'boolean\r
+-  :group 'notmuch-show)\r
+-\r
+-(defcustom notmuch-show-relative-dates t\r
+-  "Display relative dates in the message summary line."\r
+-  :type 'boolean\r
+-  :group 'notmuch-show)\r
+-\r
+-(defvar notmuch-show-markup-headers-hook '(notmuch-show-colour-headers)\r
+-  "A list of functions called to decorate the headers listed in\r
+-`notmuch-message-headers'.")\r
+-\r
+ (defcustom notmuch-show-hook '(notmuch-show-turn-on-visual-line-mode)\r
+   "Functions called after populating a `notmuch-show' buffer."\r
+   :type 'hook\r
+@@ -80,42 +45,6 @@ visible for any given message."\r
+   :group 'notmuch-show\r
+   :group 'notmuch-hooks)\r
\r
+-(defcustom notmuch-show-insert-text/plain-hook '(notmuch-wash-wrap-long-lines\r
+-                                               notmuch-wash-tidy-citations\r
+-                                               notmuch-wash-elide-blank-lines\r
+-                                               notmuch-wash-excerpt-citations)\r
+-  "Functions used to improve the display of text/plain parts."\r
+-  :type 'hook\r
+-  :options '(notmuch-wash-convert-inline-patch-to-part\r
+-           notmuch-wash-wrap-long-lines\r
+-           notmuch-wash-tidy-citations\r
+-           notmuch-wash-elide-blank-lines\r
+-           notmuch-wash-excerpt-citations)\r
+-  :group 'notmuch-show\r
+-  :group 'notmuch-hooks)\r
+-\r
+-;; Mostly useful for debugging.\r
+-(defcustom notmuch-show-all-multipart/alternative-parts nil\r
+-  "Should all parts of multipart/alternative parts be shown?"\r
+-  :type 'boolean\r
+-  :group 'notmuch-show)\r
+-\r
+-(defcustom notmuch-show-indent-messages-width 1\r
+-  "Width of message indentation in threads.\r
+-\r
+-Messages are shown indented according to their depth in a thread.\r
+-This variable determines the width of this indentation measured\r
+-in number of blanks.  Defaults to `1', choose `0' to disable\r
+-indentation."\r
+-  :type 'integer\r
+-  :group 'notmuch-show)\r
+-\r
+-(defcustom notmuch-show-indent-multipart nil\r
+-  "Should the sub-parts of a multipart/* part be indented?"\r
+-  ;; dme: Not sure which is a good default.\r
+-  :type 'boolean\r
+-  :group 'notmuch-show)\r
+-\r
+ (defcustom notmuch-show-part-button-default-action 'notmuch-show-save-part\r
+   "Default part header button action (on ENTER or mouse click)."\r
+   :group 'notmuch-show\r
+@@ -143,18 +72,10 @@ indentation."\r
+ (make-variable-buffer-local 'notmuch-show-query-context)\r
+ (put 'notmuch-show-query-context 'permanent-local t)\r
\r
+-(defvar notmuch-show-process-crypto nil)\r
+-(make-variable-buffer-local 'notmuch-show-process-crypto)\r
+-(put 'notmuch-show-process-crypto 'permanent-local t)\r
+-\r
+ (defvar notmuch-show-elide-non-matching-messages nil)\r
+ (make-variable-buffer-local 'notmuch-show-elide-non-matching-messages)\r
+ (put 'notmuch-show-elide-non-matching-messages 'permanent-local t)\r
\r
+-(defvar notmuch-show-indent-content t)\r
+-(make-variable-buffer-local 'notmuch-show-indent-content)\r
+-(put 'notmuch-show-indent-content 'permanent-local t)\r
+-\r
+ (defcustom notmuch-show-stash-mlarchive-link-alist\r
+   '(("Gmane" . "http://mid.gmane.org/")\r
+     ("MARC" . "http://marc.info/?i=")\r
+@@ -328,35 +249,6 @@ operation on the contents of the current buffer."\r
+   (interactive)\r
+   (notmuch-show-with-message-as-text 'notmuch-print-message))\r
\r
+-(defun notmuch-show-fontify-header ()\r
+-  (let ((face (cond\r
+-             ((looking-at "[Tt]o:")\r
+-              'message-header-to)\r
+-             ((looking-at "[Bb]?[Cc][Cc]:")\r
+-              'message-header-cc)\r
+-             ((looking-at "[Ss]ubject:")\r
+-              'message-header-subject)\r
+-             ((looking-at "[Ff]rom:")\r
+-              'message-header-from)\r
+-             (t\r
+-              'message-header-other))))\r
+-\r
+-    (overlay-put (make-overlay (point) (re-search-forward ":"))\r
+-               'face 'message-header-name)\r
+-    (overlay-put (make-overlay (point) (re-search-forward ".*$"))\r
+-               'face face)))\r
+-\r
+-(defun notmuch-show-colour-headers ()\r
+-  "Apply some colouring to the current headers."\r
+-  (goto-char (point-min))\r
+-  (while (looking-at "^[A-Za-z][-A-Za-z0-9]*:")\r
+-    (notmuch-show-fontify-header)\r
+-    (forward-line)))\r
+-\r
+-(defun notmuch-show-spaces-n (n)\r
+-  "Return a string comprised of `n' spaces."\r
+-  (make-string n ? ))\r
+-\r
+ (defun notmuch-show-update-tags (tags)\r
+   "Update the displayed tags of the current message."\r
+   (save-excursion\r
+@@ -367,104 +259,6 @@ operation on the contents of the current buffer."\r
+                                (notmuch-tag-format-tags tags)\r
+                                ")"))))))\r
\r
+-(defun notmuch-clean-address (address)\r
+-  "Try to clean a single email ADDRESS for display. Return a cons\r
+-cell of (AUTHOR_EMAIL AUTHOR_NAME). Return (ADDRESS nil) if\r
+-parsing fails."\r
+-  (condition-case nil\r
+-    (let (p-name p-address)\r
+-      ;; It would be convenient to use `mail-header-parse-address',\r
+-      ;; but that expects un-decoded mailbox parts, whereas our\r
+-      ;; mailbox parts are already decoded (and hence may contain\r
+-      ;; UTF-8). Given that notmuch should handle most of the awkward\r
+-      ;; cases, some simple string deconstruction should be sufficient\r
+-      ;; here.\r
+-      (cond\r
+-       ;; "User <user@dom.ain>" style.\r
+-       ((string-match "\\(.*\\) <\\(.*\\)>" address)\r
+-      (setq p-name (match-string 1 address)\r
+-            p-address (match-string 2 address)))\r
+-\r
+-       ;; "<user@dom.ain>" style.\r
+-       ((string-match "<\\(.*\\)>" address)\r
+-      (setq p-address (match-string 1 address)))\r
+-\r
+-       ;; Everything else.\r
+-       (t\r
+-      (setq p-address address)))\r
+-\r
+-      (when p-name\r
+-      ;; Remove elements of the mailbox part that are not relevant for\r
+-      ;; display, even if they are required during transport:\r
+-      ;;\r
+-      ;; Backslashes.\r
+-      (setq p-name (replace-regexp-in-string "\\\\" "" p-name))\r
+-\r
+-      ;; Outer single and double quotes, which might be nested.\r
+-      (loop\r
+-       with start-of-loop\r
+-       do (setq start-of-loop p-name)\r
+-\r
+-       when (string-match "^\"\\(.*\\)\"$" p-name)\r
+-       do (setq p-name (match-string 1 p-name))\r
+-\r
+-       when (string-match "^'\\(.*\\)'$" p-name)\r
+-       do (setq p-name (match-string 1 p-name))\r
+-\r
+-       until (string= start-of-loop p-name)))\r
+-\r
+-      ;; If the address is 'foo@bar.com <foo@bar.com>' then show just\r
+-      ;; 'foo@bar.com'.\r
+-      (when (string= p-name p-address)\r
+-      (setq p-name nil))\r
+-\r
+-      (cons p-address p-name))\r
+-    (error (cons address nil))))\r
+-\r
+-(defun notmuch-show-clean-address (address)\r
+-  "Try to clean a single email ADDRESS for display.  Return\r
+-unchanged ADDRESS if parsing fails."\r
+-  (let* ((clean-address (notmuch-clean-address address))\r
+-       (p-address (car clean-address))\r
+-       (p-name (cdr clean-address)))\r
+-    ;; If no name, return just the address.\r
+-    (if (not p-name)\r
+-      p-address\r
+-      ;; Otherwise format the name and address together.\r
+-      (concat p-name " <" p-address ">"))))\r
+-\r
+-(defun notmuch-show-insert-headerline (headers date tags depth)\r
+-  "Insert a notmuch style headerline based on HEADERS for a\r
+-message at DEPTH in the current thread."\r
+-  (let ((start (point)))\r
+-    (insert (notmuch-show-spaces-n (* notmuch-show-indent-messages-width depth))\r
+-          (notmuch-show-clean-address (plist-get headers :From))\r
+-          " ("\r
+-          date\r
+-          ") ("\r
+-          (notmuch-tag-format-tags tags)\r
+-          ")\n")\r
+-    (overlay-put (make-overlay start (point)) 'face 'notmuch-message-summary-face)))\r
+-\r
+-(defun notmuch-show-insert-header (header header-value)\r
+-  "Insert a single header."\r
+-  (insert header ": " header-value "\n"))\r
+-\r
+-(defun notmuch-show-insert-headers (headers)\r
+-  "Insert the headers of the current message."\r
+-  (let ((start (point)))\r
+-    (mapc (lambda (header)\r
+-          (let* ((header-symbol (intern (concat ":" header)))\r
+-                 (header-value (plist-get headers header-symbol)))\r
+-            (if (and header-value\r
+-                     (not (string-equal "" header-value)))\r
+-                (notmuch-show-insert-header header header-value))))\r
+-        notmuch-message-headers)\r
+-    (save-excursion\r
+-      (save-restriction\r
+-      (narrow-to-region start (point-max))\r
+-      (run-hooks 'notmuch-show-markup-headers-hook)))))\r
+-\r
+ (define-button-type 'notmuch-show-part-button-type\r
+   'action 'notmuch-show-part-button-default\r
+   'keymap 'notmuch-show-part-button-map\r
+@@ -483,26 +277,6 @@ message at DEPTH in the current thread."\r
+   "Submap for button commands")\r
+ (fset 'notmuch-show-part-button-map notmuch-show-part-button-map)\r
\r
+-(defun notmuch-show-insert-part-header (nth content-type declared-type &optional name comment)\r
+-  (let ((button)\r
+-      (base-label (concat (when name (concat name ": "))\r
+-                          declared-type\r
+-                          (unless (string-equal declared-type content-type)\r
+-                            (concat " (as " content-type ")"))\r
+-                          comment)))\r
+-\r
+-    (setq button\r
+-        (insert-button\r
+-         (concat "[ " base-label " ]")\r
+-         :base-label base-label\r
+-         :type 'notmuch-show-part-button-type\r
+-         :notmuch-part nth\r
+-         :notmuch-filename name\r
+-         :notmuch-content-type content-type))\r
+-    (insert "\n")\r
+-    ;; return button\r
+-    button))\r
+-\r
+ ;; Functions handling particular MIME parts.\r
\r
+ (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body)\r
+@@ -550,447 +324,9 @@ message at DEPTH in the current thread."\r
+     (let ((handle (mm-make-handle (current-buffer) (list content-type))))\r
+       (mm-pipe-part handle))))\r
\r
+-;; This is taken from notmuch-wash: maybe it should be unified?\r
+-(defun notmuch-show-toggle-part-invisibility (&optional button)\r
+-  (interactive)\r
+-  (let* ((button (or button (button-at (point))))\r
+-       (overlay (button-get button 'overlay)))\r
+-    (when overlay\r
+-      (let* ((show (overlay-get overlay 'invisible))\r
+-           (new-start (button-start button))\r
+-           (button-label (button-get button :base-label))\r
+-           (old-point (point))\r
+-           (inhibit-read-only t))\r
+-      (overlay-put overlay 'invisible (not show))\r
+-      (goto-char new-start)\r
+-      (insert "[ " button-label (if show " ]" " (hidden) ]"))\r
+-      (let ((old-end (button-end button)))\r
+-        (move-overlay button new-start (point))\r
+-        (delete-region (point) old-end))\r
+-      (goto-char (min old-point (1- (button-end button))))))))\r
+-\r
+-(defun notmuch-show-multipart/*-to-list (part)\r
+-  (mapcar (lambda (inner-part) (plist-get inner-part :content-type))\r
+-        (plist-get part :content)))\r
+-\r
+-(defun notmuch-show-insert-part-multipart/alternative (msg part content-type nth depth declared-type)\r
+-  (notmuch-show-insert-part-header nth declared-type content-type nil)\r
+-  (let ((chosen-type (car (notmuch-multipart/alternative-choose (notmuch-show-multipart/*-to-list part))))\r
+-      (inner-parts (plist-get part :content))\r
+-      (start (point)))\r
+-    ;; This inserts all parts of the chosen type rather than just one,\r
+-    ;; but it's not clear that this is the wrong thing to do - which\r
+-    ;; should be chosen if there are more than one that match?\r
+-    (mapc (lambda (inner-part)\r
+-          (let* ((inner-type (plist-get inner-part :content-type))\r
+-                (hide (not (or notmuch-show-all-multipart/alternative-parts\r
+-                         (string= chosen-type inner-type)))))\r
+-            (notmuch-show-insert-bodypart msg inner-part depth hide)))\r
+-        inner-parts)\r
+-\r
+-    (when notmuch-show-indent-multipart\r
+-      (indent-rigidly start (point) 1)))\r
+-  t)\r
+-\r
+-(defun notmuch-show-setup-w3m ()\r
+-  "Instruct w3m how to retrieve content from a \"related\" part of a message."\r
+-  (interactive)\r
+-  (if (boundp 'w3m-cid-retrieve-function-alist)\r
+-    (unless (assq 'notmuch-show-mode w3m-cid-retrieve-function-alist)\r
+-      (push (cons 'notmuch-show-mode 'notmuch-show-w3m-cid-retrieve)\r
+-          w3m-cid-retrieve-function-alist)))\r
+-  (setq mm-inline-text-html-with-images t))\r
+-\r
+-(defvar w3m-current-buffer) ;; From `w3m.el'.\r
+-(defvar notmuch-show-w3m-cid-store nil)\r
+-(make-variable-buffer-local 'notmuch-show-w3m-cid-store)\r
+-\r
+-(defun notmuch-show-w3m-cid-store-internal (content-id\r
+-                                          message-id\r
+-                                          part-number\r
+-                                          content-type\r
+-                                          content)\r
+-  (push (list content-id\r
+-            message-id\r
+-            part-number\r
+-            content-type\r
+-            content)\r
+-      notmuch-show-w3m-cid-store))\r
+-\r
+-(defun notmuch-show-w3m-cid-store (msg part)\r
+-  (let ((content-id (plist-get part :content-id)))\r
+-    (when content-id\r
+-      (notmuch-show-w3m-cid-store-internal (concat "cid:" content-id)\r
+-                                         (plist-get msg :id)\r
+-                                         (plist-get part :id)\r
+-                                         (plist-get part :content-type)\r
+-                                         nil))))\r
+-\r
+-(defun notmuch-show-w3m-cid-retrieve (url &rest args)\r
+-  (let ((matching-part (with-current-buffer w3m-current-buffer\r
+-                       (assoc url notmuch-show-w3m-cid-store))))\r
+-    (if matching-part\r
+-      (let ((message-id (nth 1 matching-part))\r
+-            (part-number (nth 2 matching-part))\r
+-            (content-type (nth 3 matching-part))\r
+-            (content (nth 4 matching-part)))\r
+-        ;; If we don't already have the content, get it and cache\r
+-        ;; it, as some messages reference the same cid: part many\r
+-        ;; times (hundreds!), which results in many calls to\r
+-        ;; `notmuch part'.\r
+-        (unless content\r
+-          (setq content (notmuch-get-bodypart-internal (notmuch-id-to-query message-id)\r
+-                                                            part-number notmuch-show-process-crypto))\r
+-          (with-current-buffer w3m-current-buffer\r
+-            (notmuch-show-w3m-cid-store-internal url\r
+-                                                 message-id\r
+-                                                 part-number\r
+-                                                 content-type\r
+-                                                 content)))\r
+-        (insert content)\r
+-        content-type)\r
+-      nil)))\r
+-\r
+-(defun notmuch-show-insert-part-multipart/related (msg part content-type nth depth declared-type)\r
+-  (notmuch-show-insert-part-header nth declared-type content-type nil)\r
+-  (let ((inner-parts (plist-get part :content))\r
+-      (start (point)))\r
+-\r
+-    ;; We assume that the first part is text/html and the remainder\r
+-    ;; things that it references.\r
+-\r
+-    ;; Stash the non-primary parts.\r
+-    (mapc (lambda (part)\r
+-          (notmuch-show-w3m-cid-store msg part))\r
+-        (cdr inner-parts))\r
+-\r
+-    ;; Render the primary part.\r
+-    (notmuch-show-insert-bodypart msg (car inner-parts) depth)\r
+-\r
+-    (when notmuch-show-indent-multipart\r
+-      (indent-rigidly start (point) 1)))\r
+-  t)\r
+-\r
+-(defun notmuch-show-insert-part-multipart/signed (msg part content-type nth depth declared-type)\r
+-  (let ((button (notmuch-show-insert-part-header nth declared-type content-type nil)))\r
+-    (button-put button 'face 'notmuch-crypto-part-header)\r
+-    ;; add signature status button if sigstatus provided\r
+-    (if (plist-member part :sigstatus)\r
+-      (let* ((from (notmuch-show-get-header :From msg))\r
+-             (sigstatus (car (plist-get part :sigstatus))))\r
+-        (notmuch-crypto-insert-sigstatus-button sigstatus from))\r
+-      ;; if we're not adding sigstatus, tell the user how they can get it\r
+-      (button-put button 'help-echo "Set notmuch-crypto-process-mime to process cryptographic MIME parts.")))\r
+-\r
+-  (let ((inner-parts (plist-get part :content))\r
+-      (start (point)))\r
+-    ;; Show all of the parts.\r
+-    (mapc (lambda (inner-part)\r
+-          (notmuch-show-insert-bodypart msg inner-part depth))\r
+-        inner-parts)\r
+-\r
+-    (when notmuch-show-indent-multipart\r
+-      (indent-rigidly start (point) 1)))\r
+-  t)\r
+-\r
+-(defun notmuch-show-insert-part-multipart/encrypted (msg part content-type nth depth declared-type)\r
+-  (let ((button (notmuch-show-insert-part-header nth declared-type content-type nil)))\r
+-    (button-put button 'face 'notmuch-crypto-part-header)\r
+-    ;; add encryption status button if encstatus specified\r
+-    (if (plist-member part :encstatus)\r
+-      (let ((encstatus (car (plist-get part :encstatus))))\r
+-        (notmuch-crypto-insert-encstatus-button encstatus)\r
+-        ;; add signature status button if sigstatus specified\r
+-        (if (plist-member part :sigstatus)\r
+-            (let* ((from (notmuch-show-get-header :From msg))\r
+-                   (sigstatus (car (plist-get part :sigstatus))))\r
+-              (notmuch-crypto-insert-sigstatus-button sigstatus from))))\r
+-      ;; if we're not adding encstatus, tell the user how they can get it\r
+-      (button-put button 'help-echo "Set notmuch-crypto-process-mime to process cryptographic MIME parts.")))\r
+-\r
+-  (let ((inner-parts (plist-get part :content))\r
+-      (start (point)))\r
+-    ;; Show all of the parts.\r
+-    (mapc (lambda (inner-part)\r
+-          (notmuch-show-insert-bodypart msg inner-part depth))\r
+-        inner-parts)\r
+-\r
+-    (when notmuch-show-indent-multipart\r
+-      (indent-rigidly start (point) 1)))\r
+-  t)\r
+-\r
+-(defun notmuch-show-insert-part-multipart/* (msg part content-type nth depth declared-type)\r
+-  (notmuch-show-insert-part-header nth declared-type content-type nil)\r
+-  (let ((inner-parts (plist-get part :content))\r
+-      (start (point)))\r
+-    ;; Show all of the parts.\r
+-    (mapc (lambda (inner-part)\r
+-          (notmuch-show-insert-bodypart msg inner-part depth))\r
+-        inner-parts)\r
+-\r
+-    (when notmuch-show-indent-multipart\r
+-      (indent-rigidly start (point) 1)))\r
+-  t)\r
+-\r
+-(defun notmuch-show-insert-part-message/rfc822 (msg part content-type nth depth declared-type)\r
+-  (notmuch-show-insert-part-header nth declared-type content-type nil)\r
+-  (let* ((message (car (plist-get part :content)))\r
+-       (body (car (plist-get message :body)))\r
+-       (start (point)))\r
+-\r
+-    ;; Override `notmuch-message-headers' to force `From' to be\r
+-    ;; displayed.\r
+-    (let ((notmuch-message-headers '("From" "Subject" "To" "Cc" "Date")))\r
+-      (notmuch-show-insert-headers (plist-get message :headers)))\r
+-\r
+-    ;; Blank line after headers to be compatible with the normal\r
+-    ;; message display.\r
+-    (insert "\n")\r
+-\r
+-    ;; Show the body\r
+-    (notmuch-show-insert-bodypart msg body depth)\r
+-\r
+-    (when notmuch-show-indent-multipart\r
+-      (indent-rigidly start (point) 1)))\r
+-  t)\r
+-\r
+-(defun notmuch-show-insert-part-text/plain (msg part content-type nth depth declared-type)\r
+-  (let ((start (point)))\r
+-    ;; If this text/plain part is not the first part in the message,\r
+-    ;; insert a header to make this clear.\r
+-    (if (> nth 1)\r
+-      (notmuch-show-insert-part-header nth declared-type content-type (plist-get part :filename)))\r
+-    (insert (notmuch-get-bodypart-content msg part nth notmuch-show-process-crypto))\r
+-    (save-excursion\r
+-      (save-restriction\r
+-      (narrow-to-region start (point-max))\r
+-      (run-hook-with-args 'notmuch-show-insert-text/plain-hook msg depth))))\r
+-  t)\r
+-\r
+-(defun notmuch-show-insert-part-text/calendar (msg part content-type nth depth declared-type)\r
+-  (notmuch-show-insert-part-header nth declared-type content-type (plist-get part :filename))\r
+-  (insert (with-temp-buffer\r
+-          (insert (notmuch-get-bodypart-content msg part nth notmuch-show-process-crypto))\r
+-          ;; notmuch-get-bodypart-content provides "raw", non-converted\r
+-          ;; data. Replace CRLF with LF before icalendar can use it.\r
+-          (goto-char (point-min))\r
+-          (while (re-search-forward "\r\n" nil t)\r
+-            (replace-match "\n" nil nil))\r
+-          (let ((file (make-temp-file "notmuch-ical"))\r
+-                result)\r
+-            (unwind-protect\r
+-                (progn\r
+-                  (unless (icalendar-import-buffer file t)\r
+-                    (error "Icalendar import error. See *icalendar-errors* for more information"))\r
+-                  (set-buffer (get-file-buffer file))\r
+-                  (setq result (buffer-substring (point-min) (point-max)))\r
+-                  (set-buffer-modified-p nil)\r
+-                  (kill-buffer (current-buffer)))\r
+-              (delete-file file))\r
+-            result)))\r
+-  t)\r
+-\r
+-;; For backwards compatibility.\r
+-(defun notmuch-show-insert-part-text/x-vcalendar (msg part content-type nth depth declared-type)\r
+-  (notmuch-show-insert-part-text/calendar msg part content-type nth depth declared-type))\r
+-\r
+-(defun notmuch-show-get-mime-type-of-application/octet-stream (part)\r
+-  ;; If we can deduce a MIME type from the filename of the attachment,\r
+-  ;; we return that.\r
+-  (if (plist-get part :filename)\r
+-      (let ((extension (file-name-extension (plist-get part :filename)))\r
+-          mime-type)\r
+-      (if extension\r
+-          (progn\r
+-            (mailcap-parse-mimetypes)\r
+-            (setq mime-type (mailcap-extension-to-mime extension))\r
+-            (if (and mime-type\r
+-                     (not (string-equal mime-type "application/octet-stream")))\r
+-                mime-type\r
+-              nil))\r
+-        nil))))\r
+-\r
+-;; Handler for wash generated inline patch fake parts.\r
+-(defun notmuch-show-insert-part-inline-patch-fake-part (msg part content-type nth depth declared-type)\r
+-  (notmuch-show-insert-part-*/* msg part content-type nth depth declared-type))\r
+-\r
+-(defun notmuch-show-insert-part-text/html (msg part content-type nth depth declared-type)\r
+-  ;; text/html handler to work around bugs in renderers and our\r
+-  ;; invisibile parts code. In particular w3m sets up a keymap which\r
+-  ;; "leaks" outside the invisible region and causes strange effects\r
+-  ;; in notmuch. We set mm-inline-text-html-with-w3m-keymap to nil to\r
+-  ;; tell w3m not to set a keymap (so the normal notmuch-show-mode-map\r
+-  ;; remains).\r
+-  (let ((mm-inline-text-html-with-w3m-keymap nil))\r
+-    (notmuch-show-insert-part-*/* msg part content-type nth depth declared-type)))\r
+-\r
+-(defun notmuch-show-insert-part-*/* (msg part content-type nth depth declared-type)\r
+-  ;; This handler _must_ succeed - it is the handler of last resort.\r
+-  (notmuch-show-insert-part-header nth content-type declared-type (plist-get part :filename))\r
+-  (notmuch-mm-display-part-inline msg part nth content-type notmuch-show-process-crypto)\r
+-  t)\r
+-\r
+-;; Functions for determining how to handle MIME parts.\r
+-\r
+-(defun notmuch-show-handlers-for (content-type)\r
+-  "Return a list of content handlers for a part of type CONTENT-TYPE."\r
+-  (let (result)\r
+-    (mapc (lambda (func)\r
+-          (if (functionp func)\r
+-              (push func result)))\r
+-        ;; Reverse order of prefrence.\r
+-        (list (intern (concat "notmuch-show-insert-part-*/*"))\r
+-              (intern (concat\r
+-                       "notmuch-show-insert-part-"\r
+-                       (car (notmuch-split-content-type content-type))\r
+-                       "/*"))\r
+-              (intern (concat "notmuch-show-insert-part-" content-type))))\r
+-    result))\r
+-\r
+-;; \f\r
+\r
+-\r
+-(defun notmuch-show-insert-bodypart-internal (msg part content-type nth depth declared-type)\r
+-  (let ((handlers (notmuch-show-handlers-for content-type)))\r
+-    ;; Run the content handlers until one of them returns a non-nil\r
+-    ;; value.\r
+-    (while (and handlers\r
+-              (not (condition-case err\r
+-                       (funcall (car handlers) msg part content-type nth depth declared-type)\r
+-                     (error (progn\r
+-                              (insert "!!! Bodypart insert error: ")\r
+-                              (insert (error-message-string err))\r
+-                              (insert " !!!\n") nil)))))\r
+-      (setq handlers (cdr handlers))))\r
+-  t)\r
+-\r
+-(defun notmuch-show-create-part-overlays (msg beg end hide)\r
+-  "Add an overlay to the part between BEG and END"\r
+-  (let* ((button (button-at beg))\r
+-       (part-beg (and button (1+ (button-end button)))))\r
+-\r
+-    ;; If the part contains no text we do not make it toggleable. We\r
+-    ;; also need to check that the button is a genuine part button not\r
+-    ;; a notmuch-wash button.\r
+-    (when (and button (/= part-beg end) (button-get button :base-label))\r
+-      (button-put button 'overlay (make-overlay part-beg end))\r
+-      ;; We toggle the button for hidden parts as that gets the\r
+-      ;; button label right.\r
+-      (save-excursion\r
+-      (when hide\r
+-        (notmuch-show-toggle-part-invisibility button))))))\r
+-\r
+-(defun notmuch-show-insert-bodypart (msg part depth &optional hide)\r
+-  "Insert the body part PART at depth DEPTH in the current thread.\r
+-\r
+-If HIDE is non-nil then initially hide this part."\r
+-  (let* ((content-type (downcase (plist-get part :content-type)))\r
+-       (mime-type (or (and (string= content-type "application/octet-stream")\r
+-                           (notmuch-show-get-mime-type-of-application/octet-stream part))\r
+-                      (and (string= content-type "inline patch")\r
+-                           "text/x-diff")\r
+-                      content-type))\r
+-       (nth (plist-get part :id))\r
+-       (beg (point)))\r
+-\r
+-    (notmuch-show-insert-bodypart-internal msg part mime-type nth depth content-type)\r
+-    ;; Some of the body part handlers leave point somewhere up in the\r
+-    ;; part, so we make sure that we're down at the end.\r
+-    (goto-char (point-max))\r
+-    ;; Ensure that the part ends with a carriage return.\r
+-    (unless (bolp)\r
+-      (insert "\n"))\r
+-    (notmuch-show-create-part-overlays msg beg (point) hide)))\r
+-\r
+-(defun notmuch-show-insert-body (msg body depth)\r
+-  "Insert the body BODY at depth DEPTH in the current thread."\r
+-  (mapc (lambda (part) (notmuch-show-insert-bodypart msg part depth)) body))\r
+-\r
+ (defun notmuch-show-make-symbol (type)\r
+   (make-symbol (concat "notmuch-show-" type)))\r
\r
+-(defun notmuch-show-strip-re (string)\r
+-  (replace-regexp-in-string "^\\([Rr]e: *\\)+" "" string))\r
+-\r
+-(defvar notmuch-show-previous-subject "")\r
+-(make-variable-buffer-local 'notmuch-show-previous-subject)\r
+-\r
+-(defun notmuch-show-insert-msg (msg depth)\r
+-  "Insert the message MSG at depth DEPTH in the current thread."\r
+-  (let* ((headers (plist-get msg :headers))\r
+-       ;; Indentation causes the buffer offset of the start/end\r
+-       ;; points to move, so we must use markers.\r
+-       message-start message-end\r
+-       content-start content-end\r
+-       headers-start headers-end\r
+-       (bare-subject (notmuch-show-strip-re (plist-get headers :Subject))))\r
+-\r
+-    (setq message-start (point-marker))\r
+-\r
+-    (notmuch-show-insert-headerline headers\r
+-                                  (or (if notmuch-show-relative-dates\r
+-                                          (plist-get msg :date_relative)\r
+-                                        nil)\r
+-                                      (plist-get headers :Date))\r
+-                                  (plist-get msg :tags) depth)\r
+-\r
+-    (setq content-start (point-marker))\r
+-\r
+-    ;; Set `headers-start' to point after the 'Subject:' header to be\r
+-    ;; compatible with the existing implementation. This just sets it\r
+-    ;; to after the first header.\r
+-    (notmuch-show-insert-headers headers)\r
+-    (save-excursion\r
+-      (goto-char content-start)\r
+-      ;; If the subject of this message is the same as that of the\r
+-      ;; previous message, don't display it when this message is\r
+-      ;; collapsed.\r
+-      (when (not (string= notmuch-show-previous-subject\r
+-                        bare-subject))\r
+-      (forward-line 1))\r
+-      (setq headers-start (point-marker)))\r
+-    (setq headers-end (point-marker))\r
+-\r
+-    (setq notmuch-show-previous-subject bare-subject)\r
+-\r
+-    ;; A blank line between the headers and the body.\r
+-    (insert "\n")\r
+-    (notmuch-show-insert-body msg (plist-get msg :body)\r
+-                            (if notmuch-show-indent-content depth 0))\r
+-    ;; Ensure that the body ends with a newline.\r
+-    (unless (bolp)\r
+-      (insert "\n"))\r
+-    (setq content-end (point-marker))\r
+-\r
+-    ;; Indent according to the depth in the thread.\r
+-    (if notmuch-show-indent-content\r
+-      (indent-rigidly content-start content-end (* notmuch-show-indent-messages-width depth)))\r
+-\r
+-    (setq message-end (point-max-marker))\r
+-\r
+-    ;; Save the extents of this message over the whole text of the\r
+-    ;; message.\r
+-    (put-text-property message-start message-end :notmuch-message-extent (cons message-start message-end))\r
+-\r
+-    ;; Create overlays used to control visibility\r
+-    (plist-put msg :headers-overlay (make-overlay headers-start headers-end))\r
+-    (plist-put msg :message-overlay (make-overlay headers-start content-end))\r
+-\r
+-    (plist-put msg :depth depth)\r
+-\r
+-    ;; Save the properties for this message. Currently this saves the\r
+-    ;; entire message (augmented it with other stuff), which seems\r
+-    ;; like overkill. We might save a reduced subset (for example, not\r
+-    ;; the content).\r
+-    (notmuch-show-set-message-properties msg)\r
+-\r
+-    ;; Set header visibility.\r
+-    (notmuch-show-headers-visible msg notmuch-message-headers-visible)\r
+-\r
+-    ;; Message visibility depends on whether it matched the search\r
+-    ;; criteria.\r
+-    (notmuch-show-message-visible msg (and (plist-get msg :match)\r
+-                                         (not (plist-get msg :excluded))))))\r
+-\r
+ (defun notmuch-show-toggle-process-crypto ()\r
+   "Toggle the processing of cryptographic MIME parts."\r
+   (interactive)\r
+@@ -1018,23 +354,6 @@ If HIDE is non-nil then initially hide this part."\r
+            "Content is not indented."))\r
+   (notmuch-show-refresh-view))\r
\r
+-(defun notmuch-show-insert-tree (tree depth)\r
+-  "Insert the message tree TREE at depth DEPTH in the current thread."\r
+-  (let ((msg (car tree))\r
+-      (replies (cadr tree)))\r
+-    ;; We test whether there is a message or just some replies.\r
+-    (when msg\r
+-      (notmuch-show-insert-msg msg depth))\r
+-    (notmuch-show-insert-thread replies (1+ depth))))\r
+-\r
+-(defun notmuch-show-insert-thread (thread depth)\r
+-  "Insert the thread THREAD at depth DEPTH in the current forest."\r
+-  (mapc (lambda (tree) (notmuch-show-insert-tree tree depth)) thread))\r
+-\r
+-(defun notmuch-show-insert-forest (forest)\r
+-  "Insert the forest of threads FOREST."\r
+-  (mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest))\r
+-\r
+ (defvar notmuch-id-regexp\r
+   (concat\r
+    ;; Match the id: prefix only if it begins a word (to disallow, for\r
+@@ -1373,17 +692,6 @@ effects."\r
+     (loop do (funcall function)\r
+         while (notmuch-show-goto-message-next))))\r
\r
+-;; Functions relating to the visibility of messages and their\r
+-;; components.\r
+-\r
+-(defun notmuch-show-message-visible (props visible-p)\r
+-  (overlay-put (plist-get props :message-overlay) 'invisible (not visible-p))\r
+-  (notmuch-show-set-prop :message-visible visible-p props))\r
+-\r
+-(defun notmuch-show-headers-visible (props visible-p)\r
+-  (overlay-put (plist-get props :headers-overlay) 'invisible (not visible-p))\r
+-  (notmuch-show-set-prop :headers-visible visible-p props))\r
+-\r
+ ;; Functions for setting and getting attributes of the current\r
+ ;; message.\r
\r
+-- \r
+1.7.9.1\r
+\r