From ed1005482916c73de23a958db00c71b6e21d2b8c Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Mon, 7 Dec 2009 09:34:06 -0800 Subject: [PATCH 01/13] Revert "Add some very rudimentary support for handling html parts" This reverts commit ed16edc94d6a50ca86ff1575d9ea6fb9168b2e81. The performance hit is just far too severe, (threads with many HTML messages make emacs stop and pause for seconds before displaying the thread even if most of the HTML messages are entirely hidden). --- notmuch.el | 41 +++++++++-------------------------------- 1 file changed, 9 insertions(+), 32 deletions(-) diff --git a/notmuch.el b/notmuch.el index c504f46d..81035311 100644 --- a/notmuch.el +++ b/notmuch.el @@ -637,52 +637,29 @@ which this thread was originally shown." (goto-char end)))))) (forward-line)))) -(defun notmuch-show-markup-part (beg end depth mime-message) +(defun notmuch-show-markup-part (beg end depth) (if (re-search-forward notmuch-show-part-begin-regexp nil t) (progn - (if (eq mime-message nil) - (let ((filename (notmuch-show-get-filename))) - (with-temp-buffer - (insert-file-contents filename nil nil nil t) - (setq mime-message (mm-dissect-buffer))))) (forward-line) - (let ((part-beg (point-marker))) + (let ((beg (point-marker))) (re-search-forward notmuch-show-part-end-regexp) - - (let ((part-end (copy-marker (match-beginning 0)))) - (goto-char part-end) + (let ((end (copy-marker (match-beginning 0)))) + (goto-char end) (if (not (bolp)) (insert "\n")) - (indent-rigidly part-beg part-end depth) - (save-excursion - (goto-char part-beg) - (forward-line -1) - (beginning-of-line) - (let ((handle-type (mm-handle-type mime-message)) - mime-type) - (if (sequencep (car handle-type)) - (setq mime-type (car handle-type)) - (setq mime-type (car (car (cdr handle-type)))) - ) - (if (equal mime-type "text/html") - (mm-display-part mime-message)))) - - (notmuch-show-markup-citations-region part-beg part-end depth) + (indent-rigidly beg end depth) + (notmuch-show-markup-citations-region beg end depth) ; Advance to the next part (if any) (so the outer loop can ; determine whether we've left the current message. (if (re-search-forward notmuch-show-part-begin-regexp nil t) (beginning-of-line))))) - (goto-char end)) - mime-message) + (goto-char end))) (defun notmuch-show-markup-parts-region (beg end depth) (save-excursion (goto-char beg) - (let (mime-message) - (while (< (point) end) - (setq mime-message - (notmuch-show-markup-part - beg end depth mime-message)))))) + (while (< (point) end) + (notmuch-show-markup-part beg end depth)))) (defun notmuch-show-markup-body (depth match btn) "Markup a message body, (indenting, buttonizing citations, From cface5fda7c98b1a2272d2ecf41fe9c8b6edb816 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Tue, 8 Dec 2009 22:12:43 -0800 Subject: [PATCH 02/13] TODO: Note that we should report when two "copies" of a message differ. Marten Veldthuis pointed out on the mailing list that intentional spoofing is something that the user should be told about. --- TODO | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/TODO b/TODO index d6c303ee..12d7c4ff 100644 --- a/TODO +++ b/TODO @@ -130,6 +130,12 @@ Add support for configuring "virtual tags" which are a tuple of (tag-name, search-specification). The database is responsible for ensuring that the virtual tag is always consistent. +Indicate to the user if two files with the same message ID have +content that is actually different in some interesting way. Perhaps +notmuch initially sees all changes as interesting, and quickly learns +from the user which changes are not interesting (such as the very +common mailing-list footer). + General ------- Audit everything for dealing with out-of-memory (and drop xutil.c). From db68eea0134bf0ea97aa6a887a7c302a610484a1 Mon Sep 17 00:00:00 2001 From: Fernando Carrijo Date: Wed, 9 Dec 2009 17:09:01 -0200 Subject: [PATCH 03/13] Nuke the remainings of _notmuch_message_add_thread_id. The function _notmuch_message_add_thread_id has been removed from the private interface of notmuch. There's no reason for one to keep a declaration of its prototype in the code base. Also, lets update a commentary that referenced that function and escaped from previous scrutiny. Signed-off-by: Fernando Carrijo --- lib/database.cc | 9 ++++----- lib/notmuch-private.h | 4 ---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/lib/database.cc b/lib/database.cc index 23ddd4ae..b6c4d07b 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -855,12 +855,11 @@ _notmuch_database_link_message_to_children (notmuch_database_t *notmuch, * * We first look at 'message_file' and its link-relevant headers * (References and In-Reply-To) for message IDs. We also look in the - * database for existing message that reference 'message'.p + * database for existing message that reference 'message'. * - * The end result is to call _notmuch_message_add_thread_id with one - * or more thread IDs to which this message belongs, (including - * generating a new thread ID if necessary if the message doesn't - * connect to any existing threads). + * The end result is to call _notmuch_message_ensure_thread_id which + * generates a new thread ID if the message doesn't connect to any + * existing threads. */ static notmuch_status_t _notmuch_database_link_message (notmuch_database_t *notmuch, diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 0c340a76..116f63d6 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -193,10 +193,6 @@ void _notmuch_message_set_filename (notmuch_message_t *message, const char *filename); -void -_notmuch_message_add_thread_id (notmuch_message_t *message, - const char *thread_id); - void _notmuch_message_ensure_thread_id (notmuch_message_t *message); From 6f1173c0e46526cc70592659ab6c1c4a740d3e64 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Wed, 9 Dec 2009 14:03:03 -0800 Subject: [PATCH 04/13] TODO: Add idea for an --exclude-threads options to "notmuch search". This would provide support for "muted" threads, as well as allowing for negative filtering based on messages not matched by the original search, (but present in threads that do have at least one matched message). --- TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/TODO b/TODO index 12d7c4ff..d2a1aa41 100644 --- a/TODO +++ b/TODO @@ -44,6 +44,10 @@ and *then* --max-threads), and also complete value for --sort= notmuch command-line tool ------------------------- +Implement "notmuch search --exclude-threads=" to allow +for excluding muted threads, (and any other negative, thread-based +filtering that the user wants to do). + Fix "notmuch show" so that the UI doesn't fail to show a thread that is visible in a search buffer, but happens to no longer match the current search. (Perhaps add a --matching= From 764e686f8fb685f7da2e797db39cb0184827e0d8 Mon Sep 17 00:00:00 2001 From: David Bremner Date: Fri, 4 Dec 2009 22:26:36 -0400 Subject: [PATCH 05/13] notmuch-search-process-filter: add text properties for authors and subject to each line Add functions notmuch-search-find-authors and notmuch-find-subject to match notmuch-find-thread-id. These functions are just a wrapper around get-text-property, but in principle that could change. --- notmuch.el | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/notmuch.el b/notmuch.el index 81035311..1c3f1f40 100644 --- a/notmuch.el +++ b/notmuch.el @@ -1110,6 +1110,14 @@ Complete list of currently available key bindings: "Return the thread for the current thread" (get-text-property (point) 'notmuch-search-thread-id)) +(defun notmuch-search-find-authors () + "Return the authors for the current thread" + (get-text-property (point) 'notmuch-search-authors)) + +(defun notmuch-search-find-subject () + "Return the subject for the current thread" + (get-text-property (point) 'notmuch-search-subject)) + (defun notmuch-search-show-thread () "Display the currently selected thread." (interactive) @@ -1234,7 +1242,9 @@ This function advances the next thread when finished." (goto-char (point-max)) (let ((beg (point-marker))) (insert (format "%s %-7s %-40s %s (%s)\n" date count authors subject tags)) - (put-text-property beg (point-marker) 'notmuch-search-thread-id thread-id)) + (put-text-property beg (point-marker) 'notmuch-search-thread-id thread-id) + (put-text-property beg (point-marker) 'notmuch-search-authors authors) + (put-text-property beg (point-marker) 'notmuch-search-subject subject)) (set 'line (match-end 0))) (set 'more nil)))))) (delete-process proc)))) From 5e8ce15bfb4e836ca3ecd961903230b42830c06e Mon Sep 17 00:00:00 2001 From: David Bremner Date: Fri, 4 Dec 2009 22:26:37 -0400 Subject: [PATCH 06/13] notmuch-show: add optional argument for query context instead of using global binding notmuch-search-query-string Also modify the one call to notmuch-show in notmuch.el. This makes the call (notmuch-show thread-id) will work when there is no binding for notmuch-search-query-string; e.g. when called from user code outside notmuch. --- notmuch.el | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/notmuch.el b/notmuch.el index 1c3f1f40..d180fa4e 100644 --- a/notmuch.el +++ b/notmuch.el @@ -926,15 +926,17 @@ All currently available key bindings: (lambda() (hl-line-mode 1) )) -(defun notmuch-show (thread-id &optional parent-buffer) +(defun notmuch-show (thread-id &optional parent-buffer query-context) "Run \"notmuch show\" with the given thread ID and display results. The optional PARENT-BUFFER is the notmuch-search buffer from which this notmuch-show command was executed, (so that the next -thread from that buffer can be show when done with this one)." +thread from that buffer can be show when done with this one). + +The optional QUERY-CONTEXT is a notmuch search term. Only messages from the thread +matching this search term are shown if non-nil. " (interactive "sNotmuch show: ") - (let ((query notmuch-search-query-string) - (buffer (get-buffer-create (concat "*notmuch-show-" thread-id "*")))) + (let ((buffer (get-buffer-create (concat "*notmuch-show-" thread-id "*")))) (switch-to-buffer buffer) (notmuch-show-mode) (set (make-local-variable 'notmuch-show-parent-buffer) parent-buffer) @@ -946,7 +948,9 @@ thread from that buffer can be show when done with this one)." (erase-buffer) (goto-char (point-min)) (save-excursion - (call-process notmuch-command nil t nil "show" "--entire-thread" thread-id "and (" query ")") + (let* ((basic-args (list notmuch-command nil t nil "show" "--entire-thread" thread-id)) + (args (if query-context (append basic-args (list "and (" query-context ")")) basic-args))) + (apply 'call-process args)) (notmuch-show-markup-messages) ) (run-hooks 'notmuch-show-hook) @@ -1123,7 +1127,7 @@ Complete list of currently available key bindings: (interactive) (let ((thread-id (notmuch-search-find-thread-id))) (if (> (length thread-id) 0) - (notmuch-show thread-id (current-buffer)) + (notmuch-show thread-id (current-buffer) notmuch-search-query-string) (error "End of search results")))) (defun notmuch-search-reply-to-thread () From 0a53a1d1d7ca3732e9711a718dabca56425df2d4 Mon Sep 17 00:00:00 2001 From: David Bremner Date: Thu, 10 Dec 2009 11:14:35 -0400 Subject: [PATCH 07/13] notmuch.el: patch notmuch-show to call notmuch show without query-context (i.e. without tag:inbox) if the first query returns nothing. This fixes the annoying bug of archiving a thread, and then going back to open it and getting an error. It needs the notmuch-show API changing patch of 1259979997-31544-3-git-send-email-david@tethera.net. --- notmuch.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/notmuch.el b/notmuch.el index d180fa4e..fa83d406 100644 --- a/notmuch.el +++ b/notmuch.el @@ -950,7 +950,9 @@ matching this search term are shown if non-nil. " (save-excursion (let* ((basic-args (list notmuch-command nil t nil "show" "--entire-thread" thread-id)) (args (if query-context (append basic-args (list "and (" query-context ")")) basic-args))) - (apply 'call-process args)) + (apply 'call-process args) + (when (and (eq (buffer-size) 0) query-context) + (apply 'call-process basic-args))) (notmuch-show-markup-messages) ) (run-hooks 'notmuch-show-hook) From 4aff2ca55bfe285ced36e9fe02c907d8b4120672 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Thu, 10 Dec 2009 10:35:18 -0800 Subject: [PATCH 08/13] emacs: Fix '+' and '-' in case of thread no longer matching current search. Similar to the way thread-viewing was broken after a thread was archived, (and recently fixed), tag manipulation has also been broken when the thread no longer matches the current search. This also means that the behavior of '+' and '-' are now different than that of '*'. The '+' and '-' bindings now return to the previous behavior old affecting all messages in the thread, (and not simply those matching the search). I actually prefer this behavior, since otherwise a '-' operation on a thread might not actually remove the tag from the thread, (since it could operate on a subset of the thread and not hit all messages with the given tag). So I'd now like to fix '*' to be consistent with '+' and '-', for which we add an item to TODO. --- TODO | 6 ++++++ notmuch.el | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index d2a1aa41..43956691 100644 --- a/TODO +++ b/TODO @@ -8,6 +8,12 @@ Fix the things that are causing the most pain to new users Emacs interface (notmuch.el) ---------------------------- +Enhance '+' and '-' in the search view to operate on an entire region +if set. + +Fix '*' to work by simply calling '+' or '-' on a region consisting of +the entire buffer. + Add a global keybinding table for notmuch, and then view-specific tables that add to it. diff --git a/notmuch.el b/notmuch.el index fa83d406..fb112f97 100644 --- a/notmuch.el +++ b/notmuch.el @@ -1184,7 +1184,7 @@ The tag is added to messages in the currently selected thread which match the current search terms." (interactive (list (notmuch-select-tag-with-completion "Tag to add: "))) - (notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id) " and " notmuch-search-query-string) + (notmuch-call-notmuch-process "tag" (concat "+" tag) (notmuch-search-find-thread-id)) (notmuch-search-set-tags (delete-dups (sort (cons tag (notmuch-search-get-tags)) 'string<)))) (defun notmuch-search-remove-tag (tag) @@ -1194,7 +1194,7 @@ The tag is removed from messages in the currently selected thread which match the current search terms." (interactive (list (notmuch-select-tag-with-completion "Tag to remove: " (notmuch-search-find-thread-id)))) - (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id) " and " notmuch-search-query-string) + (notmuch-call-notmuch-process "tag" (concat "-" tag) (notmuch-search-find-thread-id)) (notmuch-search-set-tags (delete tag (notmuch-search-get-tags)))) (defun notmuch-search-archive-thread () From 0d340415c942a87cb29f6507979266751020109a Mon Sep 17 00:00:00 2001 From: Keith Amidon Date: Sat, 5 Dec 2009 14:53:59 -0800 Subject: [PATCH 09/13] Expand scope of items considered when saving attachments Previously only mime parts that indicated specified a "disposition" of "attachment" were saved. However there are time when it is important to be able to save inline content as well. After this commit any mime part that specifies a filename will be considered when saving attachments. --- notmuch.el | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index fb112f97..31e9d585 100644 --- a/notmuch.el +++ b/notmuch.el @@ -322,7 +322,9 @@ buffer." (lambda (p) (let ((disposition (mm-handle-disposition p))) (and (listp disposition) - (equal (car disposition) "attachment") + (or (equal (car disposition) "attachment") + (and (equal (car disposition) "inline") + (assq 'filename disposition))) (incf count)))) mm-handle) count)) @@ -332,7 +334,9 @@ buffer." (lambda (p) (let ((disposition (mm-handle-disposition p))) (and (listp disposition) - (equal (car disposition) "attachment") + (or (equal (car disposition) "attachment") + (and (equal (car disposition) "inline") + (assq 'filename disposition))) (or (not queryp) (y-or-n-p (concat "Save '" (cdr (assq 'filename disposition)) "' "))) From 8d2f19b896af55d256f970d71727e621255a58cb Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 11 Dec 2009 15:25:55 -0800 Subject: [PATCH 10/13] emacs: Avoid infinite loop when marking up citations. Thanks to Dirk Hohndel for reporting the bug. The infinite loop was first noticed in the following message (available from the Linux kernel mailing list): alpine.LFD.2.00.0912081304070.3560@localhost.localdomain Note that the bug does not show up when viewing the message in isolation---the bug was triggered only when viewing this file indented to a depth of at least 13. The fix is simply to use a marker rather than an integer position when recording a point we plan to move back to later, (since inserting the indented button causes the buffer position of the desired marker to change). --- notmuch.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index 31e9d585..9ec89ca0 100644 --- a/notmuch.el +++ b/notmuch.el @@ -608,7 +608,7 @@ which this thread was originally shown." (invis-spec (make-symbol "notmuch-citation-region"))) (add-to-invisibility-spec invis-spec) (overlay-put overlay 'invisible invis-spec) - (let ((p (point)) + (let ((p (point-marker)) (cite-button-text (concat "[" (number-to-string (count-lines beg-sub (point))) "-line citation.]"))) @@ -633,7 +633,7 @@ which this thread was originally shown." (goto-char (- beg-sub 1)) (insert (concat "\n" indent)) (let ((sig-button-text (concat "[" (number-to-string sig-lines) - "-line signature.]"))) + "-line signature. Click/Enter to show.]"))) (insert-button sig-button-text 'invisibility-spec invis-spec :type 'notmuch-button-signature-toggle-type) ) From 2e3d07b8d50ecbc48cf2c40e0557201d42081ab9 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 11 Dec 2009 15:31:10 -0800 Subject: [PATCH 11/13] emacs: Don't regard a manually indented '>' as introducing a citation. In the message mentioned in the previous commit, an ASCII diagram was included in which '>' was used as the first non-whitespace character in a line. Notmuch previously (and mistakenly) regarded this as a citation. We fix this by only regarding a '>' in the first column of an email as introducing a citation. --- notmuch.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index 9ec89ca0..33e434f3 100644 --- a/notmuch.el +++ b/notmuch.el @@ -599,11 +599,13 @@ which this thread was originally shown." (while (< (point) end) (let ((beg-sub (point-marker)) (indent (make-string depth ? )) - (citation "[[:space:]]*>")) + (citation ">")) + (move-to-column depth) (if (looking-at citation) (progn (while (looking-at citation) - (forward-line)) + (forward-line) + (move-to-column depth)) (let ((overlay (make-overlay beg-sub (point))) (invis-spec (make-symbol "notmuch-citation-region"))) (add-to-invisibility-spec invis-spec) From 19e8ad63934428c0d0f4a091ccebdcc9b0b9ffa5 Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 11 Dec 2009 15:36:41 -0800 Subject: [PATCH 12/13] emacs: Don't insert extra line after citations. This extra line had been annoying me for a while, so I'm glad to see it go away. --- notmuch.el | 1 - 1 file changed, 1 deletion(-) diff --git a/notmuch.el b/notmuch.el index 33e434f3..492b5d66 100644 --- a/notmuch.el +++ b/notmuch.el @@ -619,7 +619,6 @@ which this thread was originally shown." (insert-button cite-button-text 'invisibility-spec invis-spec :type 'notmuch-button-citation-toggle-type) - (insert "\n") (goto-char (+ (length cite-button-text) p)) )))) (move-to-column depth) From dac01ec52036e0320f66211be3dc5e5126eb218f Mon Sep 17 00:00:00 2001 From: Carl Worth Date: Fri, 11 Dec 2009 15:52:40 -0800 Subject: [PATCH 13/13] emacs: Add instructions to the hidden citations/signatures. We've received a user report that the hidden citations were annoying since the user couldn't tell what was being referred to by subsequent text. Apparently it wasn't obvious enough that the hidden citation could be revealed by clicking or by pressing Enter. So make the button text say as much. --- notmuch.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notmuch.el b/notmuch.el index 492b5d66..97914f2c 100644 --- a/notmuch.el +++ b/notmuch.el @@ -613,13 +613,13 @@ which this thread was originally shown." (let ((p (point-marker)) (cite-button-text (concat "[" (number-to-string (count-lines beg-sub (point))) - "-line citation.]"))) + "-line citation. Click/Enter to show.]"))) (goto-char (- beg-sub 1)) (insert (concat "\n" indent)) (insert-button cite-button-text 'invisibility-spec invis-spec :type 'notmuch-button-citation-toggle-type) - (goto-char (+ (length cite-button-text) p)) + (forward-line) )))) (move-to-column depth) (if (looking-at notmuch-show-signature-regexp)