Re: [PATCH 0/3] reworked crypto toggle, plus a couple of other toggles
On Sun, 29 Jan 2012 12:06:57 -0800, Jameson Graef Rollins jroll...@finestructure.net wrote: My inclination is to remove `notmuch-crypto-process-mime' altogether (declared it an obsolete variable) and allow users to set a default for `notmuch-show-process-crypto' directly, but that is not done in this patchset while awaiting feedback. I'm not sure I understand this. `notmuch-show-process-crypto' *is* what sets the default for the `notmuch-show-process-crypto' buffer-local variable. How would you change the current behavior or settings (beyond just a variable rename)? The problem with the code as I posted can be seen if you imagine the following ~/.emacs.el sequence: bin6NS6r8HTtY.bin Description: application/emacs-lisp I'm sure that I can figure out either some `defcustom' goop or worse to sort it out so that the initialisation happens correctly. `notmuch-crypto-process-mime' is used only in notmuch-show.el, so the setting really belongs there with an appropriate name. I intentionally put this in a separate section in case there were eventually other needs for this setting beyond just show mode. I personally think we should just leave it where it is, particularly since it's been there for a while. Okay. pgptcBnLBlO8m.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: Bug: emacs 23.2 doesn't like ido-completing-read
On Sun, 29 Jan 2012 23:17:55 +, Mark Walters markwalters1...@gmail.com wrote: I have been experimenting with notmuch-always-prompt-for-sender on my debian stable setup (emacs 23.2.1) and it doesn't like ido-completing-read. It goes to the minibuffer and then it seems to be impossible to exit the minibuffer. I can find an emacs bug report #3274 and some discussion http://comments.gmane.org/gmane.emacs.bugs/27856 which indicates that it is a problem with ido initialisation. Unfortunately I can't get from there to a solution (except upgrade emacs). I'm not sure that notmuch-mua.el should be using `ido-completing-read', and certainly not without `require'ing it. Is there a particular thing required that `completing-read' doesn't do? pgpFXUt2TfqoT.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/2 v2] emacs: Stop the `truncate-string-to-width' madness.
There's no need to call `truncate-string-to-width' twice in this code path. --- emacs/notmuch.el | 22 ++ 1 files changed, 10 insertions(+), 12 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 72f78ed..d4d6904 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -469,18 +469,16 @@ Complete list of currently available key bindings: (let ((thread-id (notmuch-search-find-thread-id)) (subject (notmuch-search-find-subject))) (if ( (length thread-id) 0) - (notmuch-show thread-id - (current-buffer) - notmuch-search-query-string - ;; name the buffer based on notmuch-search-find-subject - (if (string-match ^[ \t]*$ subject) - [No Subject] - (truncate-string-to-width -(concat * -(truncate-string-to-width subject 32 nil nil t) -*) -32 nil nil t)) - crypto-switch) + (progn + (if (string-match ^[ \t]*$ subject) + (setq subject [No Subject])) + + (notmuch-show thread-id + (current-buffer) + notmuch-search-query-string + ;; Name the buffer based on the subject. + (concat * (truncate-string-to-width subject 30 nil nil t) *) + crypto-switch)) (message End of search results. (defun notmuch-search-reply-to-thread (optional prompt-for-sender) -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 0/2 v2] minor cleanup and improvements
Oops. That should be 'v3'. I need a bunch of automation to make posting patches simpler. pgpkwFC77M8DY.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/3 v2] emacs: Rework crypto switch toggle.
Re-work the existing crypto switch toggle to be based on a persistant buffer-local variable. To allow this, modify `notmuch-show-refresh-view' to erase and re-draw in the current buffer rather than killing the current buffer and creating a new one. (This will also allow more per-buffer behaviour in future patches.) Add a binding ('$') to toggle crypto processing of the current buffer and remove the prefix argument approach that achieves a similar result. --- emacs/notmuch-show.el | 105 +++- emacs/notmuch.el |7 +-- 2 files changed, 53 insertions(+), 59 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 84ac624..53f6ae4 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -124,6 +124,17 @@ indentation. (const :tag View interactively notmuch-show-interactively-view-part))) +(defvar notmuch-show-thread-id nil) +(make-variable-buffer-local 'notmuch-show-thread-id) +(defvar notmuch-show-parent-buffer nil) +(make-variable-buffer-local 'notmuch-show-parent-buffer) +(defvar notmuch-show-query-context nil) +(make-variable-buffer-local 'notmuch-show-query-context) + +(defvar notmuch-show-process-crypto nil) +(make-variable-buffer-local 'notmuch-show-process-crypto) +(put 'notmuch-show-process-crypto 'permanent-local t) + (defmacro with-current-notmuch-show-message (rest body) Evaluate body with current buffer set to the text of current message `(save-excursion @@ -410,14 +421,11 @@ message at DEPTH in the current thread. (defmacro notmuch-with-temp-part-buffer (message-id nth rest body) (declare (indent 2)) - (let ((process-crypto (make-symbol process-crypto))) -`(let ((,process-crypto notmuch-show-process-crypto)) - (with-temp-buffer -(setq notmuch-show-process-crypto ,process-crypto) -;; Always acquires the part via `notmuch part', even if it is -;; available in the JSON output. -(insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) -,@body + `(with-temp-buffer + ;; Always acquires the part via `notmuch part', even if it is + ;; available in the JSON output. + (insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) + ,@body)) (defun notmuch-show-save-part (message-id nth optional filename content-type) (notmuch-with-temp-part-buffer message-id nth @@ -599,7 +607,7 @@ current buffer, if possible. (sigstatus (car (plist-get part :sigstatus (notmuch-crypto-insert-sigstatus-button sigstatus from)) ;; if we're not adding sigstatus, tell the user how they can get it - (button-put button 'help-echo Set notmuch-crypto-process-mime to process cryptographic mime parts.))) + (button-put button 'help-echo Set notmuch-crypto-process-mime to process cryptographic MIME parts.))) (let ((inner-parts (plist-get part :content)) (start (point))) @@ -625,7 +633,7 @@ current buffer, if possible. (sigstatus (car (plist-get part :sigstatus (notmuch-crypto-insert-sigstatus-button sigstatus from ;; if we're not adding encstatus, tell the user how they can get it - (button-put button 'help-echo Set notmuch-crypto-process-mime to process cryptographic mime parts.))) + (button-put button 'help-echo Set notmuch-crypto-process-mime to process cryptographic MIME parts.))) (let ((inner-parts (plist-get part :content)) (start (point))) @@ -752,8 +760,6 @@ current buffer, if possible. ;; Helper for parts which are generally not included in the default ;; JSON output. -;; Uses the buffer-local variable notmuch-show-process-crypto to -;; determine if parts should be decrypted first. (defun notmuch-show-get-bodypart-internal (message-id part-number) (let ((args '(show --format=raw)) (part-arg (format --part=%s part-number))) @@ -907,6 +913,15 @@ current buffer, if possible. ;; criteria. (notmuch-show-message-visible msg (plist-get msg :match +(defun notmuch-show-toggle-process-crypto () + Toggle the processing of cryptographic MIME parts. + (interactive) + (setq notmuch-show-process-crypto (not notmuch-show-process-crypto)) + (message (if notmuch-show-process-crypto + Processing cryptographic MIME parts. +Not processing cryptographic MIME parts.)) + (notmuch-show-refresh-view)) + (defun notmuch-show-insert-tree (tree depth) Insert the message tree TREE at depth DEPTH in the current thread. (let ((msg (car tree)) @@ -922,15 +937,6 @@ current buffer, if possible. Insert the forest of threads FOREST. (mapc (lambda (thread) (notmuch-show-insert-thread thread 0)) forest)) -(defvar notmuch-show-thread-id nil) -(make-variable-buffer-local 'notmuch-show-thread-id) -(defvar notmuch-show-parent-buffer nil) -(make-variable-buffer-local 'notmuch-show-parent-buffer) -(defvar notmuch-show-query-context nil)
[PATCH 1/2] test: add test for hiding Original Message region at beginning of a message
The test is currently broken and will be fixed by a subsequent patch. The patch adds a new file for tests of Emacs notmuch-show view. Based on patch by David Edmondson [1]. [1] id:1327562380-12894-4-git-send-email-...@dme.org --- test/emacs-show | 28 test/notmuch-test |1 + 2 files changed, 29 insertions(+), 0 deletions(-) create mode 100755 test/emacs-show diff --git a/test/emacs-show b/test/emacs-show new file mode 100755 index 000..9800575 --- /dev/null +++ b/test/emacs-show @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +test_description=Testing emacs notmuch-show view +. test-lib.sh + +test_begin_subtest Hiding Original Message region at beginning of a message +test_subtest_known_broken +message_id='originalmessagehidin...@notmuchmail.org' +add_message \ +[id]=$message_id \ +'[subject]=Hiding Original Message region at beginning of a message' \ +'[body]=-Original Message- +Text here.' + +cat EOF EXPECTED +Notmuch Test Suite test_su...@notmuchmail.org (2001-01-05) (inbox) +Subject: Hiding Original Message region at beginning of a message +To: Notmuch Test Suite test_su...@notmuchmail.org +Date: Fri, 05 Jan 2001 15:43:57 + + +[ 2-line hidden original message. Click/Enter to show. ] +EOF + +test_emacs (notmuch-show \id:$message_id\) + (test-visible-output) +test_expect_equal_file OUTPUT EXPECTED + +test_done diff --git a/test/notmuch-test b/test/notmuch-test index 3f1740c..c814be9 100755 --- a/test/notmuch-test +++ b/test/notmuch-test @@ -54,6 +54,7 @@ TESTS= argument-parsing emacs-test-functions.sh emacs-address-cleaning.sh + emacs-show TESTS=${NOTMUCH_TESTS:=$TESTS} -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/2] emacs: fix `notmuch-wash-region-to-button' to work at beginning of buffer
`Notmuch-wash-region-to-button' is the function that creates hidden regions with buttons for signatures, citations and original messages. Before the change, it did not work correctly if the to-be-hidden region started at the beginning of a message: the visibility toggle button was hidden as well. The patch fixes this. There are two parts in the fix: * Use `insert-before-markers' instead of `insert' for creating the button, so that it does not get added to the hidden overlay. * Stop using PREFIX argument for adding a newline before the button. The newline should not be added before a button at the beginning of buffer. The corresponding test is fixed now. --- emacs/notmuch-wash.el | 24 ++-- test/emacs-show |1 - 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el index 5c1e830..9d3d13f 100644 --- a/emacs/notmuch-wash.el +++ b/emacs/notmuch-wash.el @@ -136,12 +136,13 @@ collapse the remaining lines into a button.) (lines-count (count-lines (overlay-start overlay) (overlay-end overlay (format label-format lines-count))) -(defun notmuch-wash-region-to-button (msg beg end type prefix) +(defun notmuch-wash-region-to-button (msg beg end type optional prefix) Auxiliary function to do the actual making of overlays and buttons BEG and END are buffer locations. TYPE should a string, either -\citation\ or \signature\. PREFIX is some arbitrary text to -insert before the button, probably for indentation. +\citation\ or \signature\. Optional PREFIX is some arbitrary +text to insert before the button, probably for indentation. Note +that PREFIX should not include a newline. ;; This uses some slightly tricky conversions between strings and ;; symbols because of the way the button code works. Note that @@ -160,12 +161,15 @@ insert before the button, probably for indentation. (overlay-put overlay 'type type) (goto-char (1+ end)) (save-excursion - (goto-char (1- beg)) - (insert prefix) - (insert-button (notmuch-wash-button-label overlay) + (goto-char beg) + (if prefix + (insert-before-markers prefix)) + (let ((button-beg (point))) + (insert-before-markers (notmuch-wash-button-label overlay) \n) + (make-button button-beg (1- (point)) 'invisibility-spec invis-spec 'overlay overlay -:type button-type +:type button-type) (defun notmuch-wash-excerpt-citations (msg depth) Excerpt citations and up to one signature. @@ -177,7 +181,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 msg-start msg-end original \n))) +msg msg-start msg-end original))) (while (and ( (point) (point-max)) (re-search-forward notmuch-wash-citation-regexp nil t)) (let* ((cite-start (match-beginning 0)) @@ -194,7 +198,7 @@ insert before the button, probably for indentation. (forward-line (- notmuch-wash-citation-lines-suffix)) (notmuch-wash-region-to-button msg hidden-start (point-marker) - citation \n) + citation) (if (and (not (eobp)) (re-search-forward notmuch-wash-signature-regexp nil t)) (let* ((sig-start (match-beginning 0)) @@ -208,7 +212,7 @@ insert before the button, probably for indentation. (overlay-put (make-overlay sig-start-marker sig-end-marker) 'face 'message-cited-text) (notmuch-wash-region-to-button msg sig-start-marker sig-end-marker - signature \n)) + signature)) ;; diff --git a/test/emacs-show b/test/emacs-show index 9800575..5700d2e 100755 --- a/test/emacs-show +++ b/test/emacs-show @@ -4,7 +4,6 @@ test_description=Testing emacs notmuch-show view . test-lib.sh test_begin_subtest Hiding Original Message region at beginning of a message -test_subtest_known_broken message_id='originalmessagehidin...@notmuchmail.org' add_message \ [id]=$message_id \ -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 0/4 v3] more care when hiding regions with buttons
Hi David. Here is my attempt to fix the issue in a cleaner way: id:1327926286-16680-1-git-send-email-dmitry.kuroch...@gmail.com Regards, Dmitry ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] lib: update notmuch_tags_get examle to reflect api change
The function notmuch_database_find_message_by_filename now requires a notmuch_message_t and returns a notmuch_status_t. This change was introduced with 02a3076711, LIBNOTMUCH_VERSION_MAJOR = 2, version 0.9. --- lib/notmuch.h | 21 +++-- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index 7929fe7..5e6e449 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -941,21 +941,22 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header); * Typical usage might be: * * notmuch_message_t *message; + * notmuch_status_t status; * notmuch_tags_t *tags; * const char *tag; * - * message = notmuch_database_find_message (database, message_id); - * - * for (tags = notmuch_message_get_tags (message); - * notmuch_tags_valid (tags); - * notmuch_result_move_to_next (tags)) - * { - * tag = notmuch_tags_get (tags); - * + * status = notmuch_database_find_message (database, message_id, message); + * if(!status message) { + * for (tags = notmuch_message_get_tags (message); + * notmuch_tags_valid (tags); + * notmuch_result_move_to_next (tags)) + * { + * tag = notmuch_tags_get (tags); + * + * } + * notmuch_message_destroy (message); * } * - * notmuch_message_destroy (message); - * * Note that there's no explicit destructor needed for the * notmuch_tags_t object. (For consistency, we do provide a * notmuch_tags_destroy function, but there's no good reason to call -- 1.7.2.5 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] lib: update notmuch_tags_get examle to reflect api change
Ignore this one. /Allan -- Allan Wind Life Integrity, LLC http://lifeintegrity.com ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] lib: update notmuch_tags_get examle to reflect api change
On Mon, 30 Jan 2012 09:02:33 -0500, Allan Wind allan_w...@lifeintegrity.com wrote: The function notmuch_database_find_message_by_filename now requires a notmuch_message_t and returns a notmuch_status_t. This change was introduced with 02a3076711, LIBNOTMUCH_VERSION_MAJOR = 2, version 0.9. --- + * status = notmuch_database_find_message (database, message_id, message); + * if(!status message) { + * for (tags = notmuch_message_get_tags (message); Space betweem 'if' and '(' missing. Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] lib: update notmuch_tags_get examle to reflect api change
The function notmuch_database_find_message_by_filename now requires a notmuch_message_t and returns a notmuch_status_t. This change was introduced with 02a3076711, LIBNOTMUCH_VERSION_MAJOR = 2, version 0.9. --- lib/notmuch.h | 21 +++-- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index 7929fe7..5e6e449 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -941,21 +941,22 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header); * Typical usage might be: * * notmuch_message_t *message; + * notmuch_status_t status; * notmuch_tags_t *tags; * const char *tag; * - * message = notmuch_database_find_message (database, message_id); - * - * for (tags = notmuch_message_get_tags (message); - * notmuch_tags_valid (tags); - * notmuch_result_move_to_next (tags)) - * { - * tag = notmuch_tags_get (tags); - * + * status = notmuch_database_find_message (database, message_id, message); + * if (!status message) { + * for (tags = notmuch_message_get_tags (message); + * notmuch_tags_valid (tags); + * notmuch_result_move_to_next (tags)) + * { + * tag = notmuch_tags_get (tags); + * + * } + * notmuch_message_destroy (message); * } * - * notmuch_message_destroy (message); - * * Note that there's no explicit destructor needed for the * notmuch_tags_t object. (For consistency, we do provide a * notmuch_tags_destroy function, but there's no good reason to call -- 1.7.2.5 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/2] emacs: fix `notmuch-wash-region-to-button' to work at beginning of buffer
On Mon, 30 Jan 2012 16:24:46 +0400, Dmitry Kurochkin dmitry.kuroch...@gmail.com wrote: `Notmuch-wash-region-to-button' is the function that creates hidden regions with buttons for signatures, citations and original messages. Before the change, it did not work correctly if the to-be-hidden region started at the beginning of a message: the visibility toggle button was hidden as well. The patch fixes this. There are two parts in the fix: * Use `insert-before-markers' instead of `insert' for creating the button, so that it does not get added to the hidden overlay. * Stop using PREFIX argument for adding a newline before the button. The newline should not be added before a button at the beginning of buffer. The corresponding test is fixed now. --- +1 -- for test and fix. Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] STYLE: Initial draft of coding style document
On Fri, 27 Jan 2012 19:46:58 -0400, David Bremner da...@tethera.net wrote: From: David Bremner brem...@debian.org [ ... ] + +* Indent is 4 spaces with mixed tabs/spaces and a tab width of 8. + Tabs should be only at the beginning of the line. So, after initial indentation (with tabs) there should not be further tabs? We'll be using the former instead of the latter in these 2 below? /* excerpt from command-line-arguments.h -- indentation without tabs */ enum notmuch_opt_type { NOTMUCH_OPT_END = 0, NOTMUCH_OPT_BOOLEAN,/* --verbose */ NOTMUCH_OPT_INT,/* --frob=8 */ NOTMUCH_OPT_KEYWORD,/* --format=raw|json|text */ NOTMUCH_OPT_STRING, /* --file=/tmp/gnarf.txt */ NOTMUCH_OPT_POSITION/* notmuch dump pos_arg */ }; /* excerpt from command-line-arguments.h -- indentation with tabs */ enum notmuch_opt_type { NOTMUCH_OPT_END = 0, NOTMUCH_OPT_BOOLEAN,/* --verbose */ NOTMUCH_OPT_INT,/* --frob=8 */ NOTMUCH_OPT_KEYWORD,/* --format=raw|json|text */ NOTMUCH_OPT_STRING, /* --file=/tmp/gnarf.txt */ NOTMUCH_OPT_POSITION/* notmuch dump pos_arg */ }; [ ... ] Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/2] show: Simplify new text formatter code
On Thu, 26 Jan 2012 01:55:26 -0500, Austin Clements amdra...@mit.edu wrote: This makes the text formatter take advantage of the new code structure. The previously duplicated header logic is now unified, several things that we used to compute repeatedly across different callbacks are now computed once, and the code is simpler overall and 32% shorter. Unifying the header logic causes this to format some dates slightly differently, so the two affected test cases are updated. --- Looks good, works fine. Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] emacs: More address cleaning.
loop freaks me out a little, but LGTM. Quoth David Edmondson on Jan 30 at 2:59 pm: Remove outer single-quotes from the mailbox part. Allow for multiple sets of nested single and double quotes. Add more tests. --- emacs/notmuch-show.el | 24 +--- test/emacs-address-cleaning.el |8 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 84ac624..7bfbda9 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -315,15 +315,25 @@ unchanged ADDRESS if parsing fails. (t (setq p-address address))) - ;; Remove elements of the mailbox part that are not relevant for - ;; display, even if they are required during transport. (when p-name - ;; Outer double quotes. - (when (string-match ^\\\(.*\\)\$ p-name) - (setq p-name (match-string 1 p-name))) - + ;; Remove elements of the mailbox part that are not relevant for + ;; display, even if they are required during transport: + ;; ;; Backslashes. - (setq p-name (replace-regexp-in-string p-name))) + (setq p-name (replace-regexp-in-string p-name)) + + ;; Outer single and double quotes, which might be nested. + (loop + with start-of-loop + do (setq start-of-loop p-name) + + when (string-match ^\\\(.*\\)\$ p-name) + do (setq p-name (match-string 1 p-name)) + + when (string-match ^'\\(.*\\)'$ p-name) + do (setq p-name (match-string 1 p-name)) + + until (string= start-of-loop p-name))) ;; If the address is 'f...@bar.com f...@bar.com' then show just ;; 'f...@bar.com'. diff --git a/test/emacs-address-cleaning.el b/test/emacs-address-cleaning.el index 3b0b109..8423245 100644 --- a/test/emacs-address-cleaning.el +++ b/test/emacs-address-cleaning.el @@ -21,11 +21,19 @@ foo (at home) f...@bar.com foo [at home] f...@bar.com Foo Bar + 'Foo Bar' f...@bar.com + \'Foo Bar'\ f...@bar.com + '\Foo Bar\' f...@bar.com + '\'Foo Bar'\' f...@bar.com Fred Dibna \\[extraordinaire\\] f...@dibna.com)) (expected '(ДБ db-uk...@stop.me.uk foo (at home) f...@bar.com foo [at home] f...@bar.com Foo Bar + Foo Bar f...@bar.com + Foo Bar f...@bar.com + Foo Bar f...@bar.com + Foo Bar f...@bar.com Fred Dibna [extraordinaire] f...@dibna.com)) (output (mapcar #'notmuch-show-clean-address input))) (notmuch-test-expect-equal output expected))) ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] moved _config_(get|set)_list () functions earlyer in the file
s/earlyer/earlier/, but unless someone feels strongly about that, I don't think we need another version of this trivial patch. Quoth Tomi Ollila on Jan 30 at 12:31 pm: Moved static functions _config_get_list () and _config_set_list () closer to the beginning of file so that their definition is known (without adding forward declarations) in upcoming changes. --- This addresses Ethan's comments. Thanks. s/_notmuch_/_config_/ and changed 'in further work' to 'in upcoming changes' -- 'changes' being more generic that 'patches'. notmuch-config.c | 84 +++--- 1 files changed, 42 insertions(+), 42 deletions(-) diff --git a/notmuch-config.c b/notmuch-config.c index 0ded6d7..a124e34 100644 --- a/notmuch-config.c +++ b/notmuch-config.c @@ -467,6 +467,48 @@ notmuch_config_save (notmuch_config_t *config) return 0; } +static const char ** +_config_get_list (notmuch_config_t *config, + const char *section, const char *key, + const char ***outlist, size_t *list_length, size_t *ret_length) +{ +assert(outlist); + +if (*outlist == NULL) { + + char **inlist = g_key_file_get_string_list (config-key_file, + section, key, list_length, NULL); + if (inlist) { + unsigned int i; + + *outlist = talloc_size (config, sizeof (char *) * (*list_length + 1)); + + for (i = 0; i *list_length; i++) + (*outlist)[i] = talloc_strdup (*outlist, inlist[i]); + + (*outlist)[i] = NULL; + + g_strfreev (inlist); + } +} + +if (ret_length) + *ret_length = *list_length; + +return *outlist; +} + +static void +_config_set_list (notmuch_config_t *config, + const char *group, const char *name, + const char *list[], + size_t length, const char ***config_var ) +{ +g_key_file_set_string_list (config-key_file, group, name, list, length); +talloc_free (*config_var); +*config_var = NULL; +} + const char * notmuch_config_get_database_path (notmuch_config_t *config) { @@ -551,37 +593,6 @@ notmuch_config_set_user_primary_email (notmuch_config_t *config, config-user_primary_email = NULL; } -static const char ** -_config_get_list (notmuch_config_t *config, - const char *section, const char *key, - const char ***outlist, size_t *list_length, size_t *ret_length) -{ -assert(outlist); - -if (*outlist == NULL) { - - char **inlist = g_key_file_get_string_list (config-key_file, - section, key, list_length, NULL); - if (inlist) { - unsigned int i; - - *outlist = talloc_size (config, sizeof (char *) * (*list_length + 1)); - - for (i = 0; i *list_length; i++) - (*outlist)[i] = talloc_strdup (*outlist, inlist[i]); - - (*outlist)[i] = NULL; - - g_strfreev (inlist); - } -} - -if (ret_length) - *ret_length = *list_length; - -return *outlist; -} - const char ** notmuch_config_get_user_other_email (notmuch_config_t *config, size_t *length) { @@ -598,17 +609,6 @@ notmuch_config_get_new_tags (notmuch_config_t *config, size_t *length) (config-new_tags_length), length); } -static void -_config_set_list (notmuch_config_t *config, - const char *group, const char *name, - const char *list[], - size_t length, const char ***config_var ) -{ -g_key_file_set_string_list (config-key_file, group, name, list, length); -talloc_free (*config_var); -*config_var = NULL; -} - void notmuch_config_set_user_other_email (notmuch_config_t *config, const char *list[], ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: emacs: more flexible and consistent tagging operations
The whole series LGTM. Quoth Dmitry Kurochkin on Jan 30 at 9:33 am: Changes: v3: * merged 3 `notmuch-show-tag-all'-related patches into one * add patch to clean up tagging function argument names * fix other comments from Austin's reviews [5,6] v2: * add patch to remove No tags given error from `notmuch-tag' as suggested by Austin in [1] * split patch 3 in two (search and show) for easier review * add patch with NEWS entry * rename `notmuch-{search,show}-operate-all' to `notmuch-{search,show}-tag-all' * fix other comments from Austin's reviews [2,3,4] Regards, Dmitry [1] id:20120129231650.gk17...@mit.edu [2] id:20120129225710.gg17...@mit.edu [3] id:20120129230229.gi17...@mit.edu [4] id:20120129231120.gj17...@mit.edu [5] id:20120130044806.gm17...@mit.edu [6] id:20120130050402.gp17...@mit.edu ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: emacs: more flexible and consistent tagging operations
Works fine. +1 Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 0/5 v3] reworked crypto toggle, plus a few other toggles
v3: - Add a toggle for line truncation (). - Retain the state of a show buffer across a call to refresh (which includes the various toggles here). David Edmondson (5): emacs: Rework crypto switch toggle. emacs: Allow `notmuch-show-mode' to display only matching messages. emacs: Allow the indentation of content to be toggled. emacs: Add a binding () to toggle the truncation of long lines. emacs: Retain the state of the buffer during `notmuch-show-refresh-view'. emacs/notmuch-show.el | 183 + emacs/notmuch.el |7 +- 2 files changed, 126 insertions(+), 64 deletions(-) -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/5] emacs: Allow `notmuch-show-mode' to display only matching messages.
The current behaviour (all messages shown, non-matching collapsed) is retained as the default. Type '!' to switch to showing only the matching messages - non-matching messages are not available. '!' will switch back to showing everything. --- emacs/notmuch-show.el | 18 +- 1 files changed, 17 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 53f6ae4..99478a4 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -135,6 +135,10 @@ indentation. (make-variable-buffer-local 'notmuch-show-process-crypto) (put 'notmuch-show-process-crypto 'permanent-local t) +(defvar notmuch-show-elide-non-matching-messages nil) +(make-variable-buffer-local 'notmuch-show-elide-non-matching-messages) +(put 'notmuch-show-elide-non-matching-messages 'permanent-local t) + (defmacro with-current-notmuch-show-message (rest body) Evaluate body with current buffer set to the text of current message `(save-excursion @@ -922,11 +926,22 @@ current buffer, if possible. Not processing cryptographic MIME parts.)) (notmuch-show-refresh-view)) +(defun notmuch-show-toggle-elide-non-matching () + Toggle the display of non-matching messages. + (interactive) + (setq notmuch-show-elide-non-matching-messages (not notmuch-show-elide-non-matching-messages)) + (message (if notmuch-show-elide-non-matching-messages + Showing matching messages only. +Showing all messages.)) + (notmuch-show-refresh-view)) + (defun notmuch-show-insert-tree (tree depth) Insert the message tree TREE at depth DEPTH in the current thread. (let ((msg (car tree)) (replies (cadr tree))) -(notmuch-show-insert-msg msg depth) +(if (or (not notmuch-show-elide-non-matching-messages) + (plist-get msg :match)) + (notmuch-show-insert-msg msg depth)) (notmuch-show-insert-thread replies (1+ depth (defun notmuch-show-insert-thread (thread depth) @@ -1079,6 +1094,7 @@ Refreshes the current view, observing changes in cryptographic preferences. (define-key map (kbd M-RET) 'notmuch-show-open-or-close-all) (define-key map (kbd RET) 'notmuch-show-toggle-message) (define-key map # 'notmuch-show-print-message) + (define-key map ! 'notmuch-show-toggle-elide-non-matching) (define-key map $ 'notmuch-show-toggle-process-crypto) map) Keymap for \notmuch show\ buffers.) -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 4/5] emacs: Add a binding () to toggle the truncation of long lines.
--- emacs/notmuch-show.el |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index a2c4daf..8b07adf 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1114,6 +1114,7 @@ Refreshes the current view, observing changes in cryptographic preferences. (define-key map ! 'notmuch-show-toggle-elide-non-matching) (define-key map $ 'notmuch-show-toggle-process-crypto) (define-key map 'notmuch-show-toggle-thread-indentation) + (define-key map 'toggle-truncate-lines) map) Keymap for \notmuch show\ buffers.) (fset 'notmuch-show-mode-map notmuch-show-mode-map) -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 5/5] emacs: Retain the state of the buffer during `notmuch-show-refresh-view'.
Record the state of the buffer during `notmuch-show-refresh-view'. In this context, state is defined as: - the open/closed state of each message, - the current message. --- emacs/notmuch-show.el | 41 + 1 files changed, 37 insertions(+), 4 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 8b07adf..a77cd52 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1053,15 +1053,48 @@ function is used. (notmuch-show-mark-read))) +(defun notmuch-show-capture-state () + Capture the state of the current buffer. + +This includes: + - the list of open messages, + - the current message. + (list (notmuch-show-get-message-id) (notmuch-show-get-message-ids-for-open-messages))) + +(defun notmuch-show-apply-state (state) + Apply STATE to the current buffer. + +This includes: + - opening the messages previously opened, + - closing all other messages, + - moving to the correct current message. + (let ((current (car state)) + (open (cadr state))) + +;; Open those that were open. +(goto-char (point-min)) +(loop do (notmuch-show-message-visible (notmuch-show-get-message-properties) + (member (notmuch-show-get-message-id) open)) + until (not (notmuch-show-goto-message-next))) + +;; Go to the previously open message. +(goto-char (point-min)) +(unless (loop if (string= current (notmuch-show-get-message-id)) + return t + until (not (notmuch-show-goto-message-next))) + (message Previously current message not found. + (defun notmuch-show-refresh-view () Refresh the current view. Refreshes the current view, observing changes in cryptographic preferences. (interactive) - (let ((inhibit-read-only t)) -(erase-buffer)) - (notmuch-show-worker notmuch-show-thread-id notmuch-show-parent-buffer - notmuch-show-query-context)) + (let ((inhibit-read-only t) + (state (notmuch-show-capture-state))) +(erase-buffer) +(notmuch-show-worker notmuch-show-thread-id notmuch-show-parent-buffer +notmuch-show-query-context) +(notmuch-show-apply-state state))) (defvar notmuch-show-stash-map (let ((map (make-sparse-keymap))) -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] emacs: Move the blank line from the bottom of the headers to the top of the body.
The blank line doesn't really change position, but is now considered to be part of the body rather than part of the headers. This means that it is visible when the body is visible rather than when the headers are visible. --- I'm interested in getting feedback on this. Unless you run with `notmuch-message-headers-visible' set to `nil' or regularly toggle header visibility, you probably don't care. emacs/notmuch-show.el |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 84ac624..73f73d4 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -854,8 +854,6 @@ current buffer, if possible. ;; compatible with the existing implementation. This just sets it ;; to after the first header. (notmuch-show-insert-headers headers) -;; Headers should include a blank line (backwards compatibility). -(insert \n) (save-excursion (goto-char content-start) ;; If the subject of this message is the same as that of the @@ -870,6 +868,8 @@ current buffer, if possible. (setq notmuch-show-previous-subject bare-subject) (setq body-start (point-marker)) +;; A blank line between the headers and the body. +(insert \n) (notmuch-show-insert-body msg (plist-get msg :body) depth) ;; Ensure that the body ends with a newline. (unless (bolp) -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 0/5 v3] reworked crypto toggle, plus a few other toggles
On Mon, 30 Jan 2012 16:30:59 +, David Edmondson d...@dme.org wrote: v3: - Add a toggle for line truncation (). - Retain the state of a show buffer across a call to refresh (which includes the various toggles here). Applied and tested -- patches 2-5 works fine -- I currently don't have any messages to test 1. David Edmondson (5): emacs: Rework crypto switch toggle. emacs: Allow `notmuch-show-mode' to display only matching messages. emacs: Allow the indentation of content to be toggled. emacs: Add a binding () to toggle the truncation of long lines. emacs: Retain the state of the buffer during `notmuch-show-refresh-view'. So +1 Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 4/5] emacs: Add a binding () to toggle the truncation of long lines.
On Jan 30, 2012 6:31 PM, David Edmondson d...@dme.org wrote: --- emacs/notmuch-show.el |1 + 1 files changed, 1 insertions(+), 0 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index a2c4daf..8b07adf 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1114,6 +1114,7 @@ Refreshes the current view, observing changes in cryptographic preferences. (define-key map ! 'notmuch-show-toggle-elide-non-matching) (define-key map $ 'notmuch-show-toggle-process-crypto) (define-key map 'notmuch-show-toggle-thread-indentation) + (define-key map 'toggle-truncate-lines) Okay, this is bikeshedding, but we have ¦ to pipe a message - wouldn't it be appropriate to reserve for saving a message to file? map) Keymap for \notmuch show\ buffers.) (fset 'notmuch-show-mode-map notmuch-show-mode-map) -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 2/2] emacs: new mua mailto: URI handler
On Mon, 30 Jan 2012 15:43:10 +, David Edmondson d...@dme.org wrote: On Sun, 29 Jan 2012 11:33:44 -0800, Jameson Graef Rollins jroll...@finestructure.net wrote: The new function 'notmuch-mua-mailto' provides an interactive handler for rfc6068 mailto:; URIs. It attempts to implement the rfc6068 specification: http://tools.ietf.org/html/rfc6068 How is this expected to be used? I know generally about how mailto: URIs are used, but not how they are currently plumbed in with an Emacs MUA. I use a variant of the following as my browser mailto url handler: #!/bin/sh emacsclient --eval (notmuch-mua-mailto \$@\) jamie. pgpzrbKGAs8Ri.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 0/3] reworked crypto toggle, plus a couple of other toggles
On Mon, 30 Jan 2012 11:26:32 +, David Edmondson d...@dme.org wrote: The simplest approach is to have `notmuch-show-process-crypto' inherit the value of `notmuch-crypto-process-mime' when any `notmuch-show-mode' buffers are first created. Currently that happens in only one place (`notmuch-show'), which makes things straightforward. Updated patches soon. Nice. That's the right solution. Thanks. jamie. pgppSB2uDzcu2.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 5/5] emacs: Retain the state of the buffer during `notmuch-show-refresh-view'.
On Mon, 30 Jan 2012 16:31:04 +, David Edmondson d...@dme.org wrote: Record the state of the buffer during `notmuch-show-refresh-view'. In this context, state is defined as: - the open/closed state of each message, - the current message. This looks great! I have two very minor queries one of which may class as bikeshedding. The first is that I currently sometimes use = (that is notmuch-show-refresh-view) as a way to go back to the original state (ie which messages are open and back to the first message) so I am not sure the keep state version should completely replace the old one. (Maybe there is an alternative way to achieve the same effect that I don't know!) Secondly in (defun notmuch-show-refresh-view () Refresh the current view. Refreshes the current view, observing changes in cryptographic preferences. (interactive) - (let ((inhibit-read-only t)) -(erase-buffer)) - (notmuch-show-worker notmuch-show-thread-id notmuch-show-parent-buffer -notmuch-show-query-context)) + (let ((inhibit-read-only t) + (state (notmuch-show-capture-state))) +(erase-buffer) +(notmuch-show-worker notmuch-show-thread-id notmuch-show-parent-buffer + notmuch-show-query-context) +(notmuch-show-apply-state state))) how would you feel about a (notmuch-show-message-adjust) at the end? Other than that this is excellent. Best wishes Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] lib: update notmuch_tags_get example to reflect api change
The function notmuch_database_find_message_by_filename now requires a notmuch_message_t and returns a notmuch_status_t. This change was introduced with 02a3076711, LIBNOTMUCH_VERSION_MAJOR = 2, version 0.9. --- lib/notmuch.h | 21 +++-- 1 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/notmuch.h b/lib/notmuch.h index 7929fe7..5e6e449 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -941,21 +941,22 @@ notmuch_message_get_header (notmuch_message_t *message, const char *header); * Typical usage might be: * * notmuch_message_t *message; + * notmuch_status_t status; * notmuch_tags_t *tags; * const char *tag; * - * message = notmuch_database_find_message (database, message_id); - * - * for (tags = notmuch_message_get_tags (message); - * notmuch_tags_valid (tags); - * notmuch_result_move_to_next (tags)) - * { - * tag = notmuch_tags_get (tags); - * + * status = notmuch_database_find_message (database, message_id, message); + * if (!status message) { + * for (tags = notmuch_message_get_tags (message); + * notmuch_tags_valid (tags); + * notmuch_result_move_to_next (tags)) + * { + * tag = notmuch_tags_get (tags); + * + * } + * notmuch_message_destroy (message); * } * - * notmuch_message_destroy (message); - * * Note that there's no explicit destructor needed for the * notmuch_tags_t object. (For consistency, we do provide a * notmuch_tags_destroy function, but there's no good reason to call -- 1.7.2.5 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: Bug?: notmuch-search-show-thread shows several threads; only one containing matching messages
On Mon, 30 Jan 2012 20:04:25 +0100, Gregor Zattler telegr...@gmx.net wrote: Hi Pieter, * Pieter Praet pie...@praet.org [30. Jan. 2012]: On Mon, 30 Jan 2012 00:42:14 +0100, Gregor Zattler telegr...@gmx.net wrote: * Pieter Praet pie...@praet.org [26. Jan. 2012]: On Thu, 26 Jan 2012 13:44:50 +0100, Gregor Zattler telegr...@gmx.net wrote: | [2] grep -I ^Message-Id: /tmp/thread-I-m-interested-in.mbox |sed -e s/Message-Id: //I -e s/$// really.mid | grep -I -F really.mid rest.mbox | -- no match [...] Also, the '-F' option expects input on stdin, not a filename. No, this is -F instead of -f and means --fixed-strings. And as I said, `-F' requires input on stdin, like this: `grep -F $(cat really.mid) rest.mbox' Otherwise [1] you're grepping for the pattern 'really.mid' instead of for the patterns specified *in* 'really.mid', so naturally, you aren't getting any results. *blush* you're right and I'm wrong. I re-re-did the greps with with the same results (no hits at all). [...] Here's another couple of threads squashed into a single one: - [O] [Use Question] Capture and long lines - id:banlktikof4txunllufrznsd6k2zys7s...@mail.gmail.com - [O] Worg update - id:m1wrfiz3ch@tsdye.com - [O] Table formula to convert hex to dec - id:20110724080054.GB16388@x201 - [O] ICS import? - id:20120125173421.GQ3747@x201 AFAICT, none of them share Message-Id's... Do you consider this a bug? I do. No idea what causes it or how to fix it though... :) First I thougt it' not a severe bug since one see's more not less messages in notmuch show buffer. But later I realised one also sees less not more threads in notmuch search buffer and might not read certain notmuch threads because of wrong $Subject: in notmuch search buffer. Hi I think notmuch links two messages into the same thread if they have an in-reply-to or reference header in common: i.e the messages reference a common parent message. (See comment in lib/database.cc Even before a message is added, it's pre-allocated thread ID is useful so that all descendant messages that reference this common parent can be recognized as belonging to the same thread.) As far as I can see your grep tests haven't checked for that. Also, could you email me the mbox you had (I think you said that it was a mailing list so all public) and I will take a look? Thanks Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/2] test: remove Generate some messages test from raw
Before the change, the first subtest in raw format tests just generated messages and checked that they are added successfully. This is not really a raw format test, it is creating of environment required for other subtests to run. The patch removes the first subtest from raw and replaces it with bare add_message calls, similar to how it is done in other tests. TODO: we should check that test environment was created successfully. Currently, many tests do add_message(), notmuch new and other calls without checking the results. We should come up with a general solution for this, i.e. if any command during test initialization fails, all tests should be skipped with appropriate error message. --- test/raw |7 ++- 1 files changed, 2 insertions(+), 5 deletions(-) diff --git a/test/raw b/test/raw index 0171e64..de0b867 100755 --- a/test/raw +++ b/test/raw @@ -3,11 +3,8 @@ test_description='notmuch show --format=raw' . ./test-lib.sh -test_begin_subtest Generate some messages -generate_message -generate_message -output=$(NOTMUCH_NEW) -test_expect_equal $output Added 2 new messages to the database. +add_message +add_message test_begin_subtest Attempt to show multiple raw messages output=$(notmuch show --format=raw * 21) -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 2/2] test: use subtest name for generated message subject by default
Before the change, messages generated by generate_message() used Test message #N for default subject where N is the generated messages counter. Since message subject is commonly present in expected results, there is a chance of breaking other tests when a new generate_message() call is added. The patch changes default subject value for generated messages to subtest name if it is available. If subtest name is not available (i.e. message is generated during test initialization), the old default value is used (in this case it is fine to have the counter in the subject). Another benefit of this change is a sane default value for subject in generated messages, which would allow to simplify code like: test_begin_subtest test for a cool feature add_message [subject]=message for test for a cool feature --- test/encoding|2 +- test/search-folder-coherence |2 +- test/test-lib.sh |6 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/test/encoding b/test/encoding index 33259c1..dbaceb0 100755 --- a/test/encoding +++ b/test/encoding @@ -9,7 +9,7 @@ output=$(notmuch show id:${gen_msg_id} 21 | notmuch_show_sanitize) test_expect_equal $output message{ id:msg-001@notmuch-test-suite depth:0 match:1 filename:/XXX/mail/msg-001 header{ Notmuch Test Suite test_su...@notmuchmail.org (2001-01-05) (inbox unread) -Subject: Test message #1 +Subject: Message with text of unknown charset From: Notmuch Test Suite test_su...@notmuchmail.org To: Notmuch Test Suite test_su...@notmuchmail.org Date: Fri, 05 Jan 2001 15:43:57 + diff --git a/test/search-folder-coherence b/test/search-folder-coherence index f8119cb..3f6ec76 100755 --- a/test/search-folder-coherence +++ b/test/search-folder-coherence @@ -32,7 +32,7 @@ test_expect_equal_file OUTPUT EXPECTED test_begin_subtest Test matches folder:spam output=$(notmuch search folder:spam) -test_expect_equal $output thread:0001 2001-01-05 [1/1] Notmuch Test Suite; Test message #1 (inbox unread) +test_expect_equal $output thread:0001 2001-01-05 [1/1] Notmuch Test Suite; Single new message (inbox unread) test_begin_subtest Remove folder:spam copy of email rm $dir/spam/$(basename $file_x) diff --git a/test/test-lib.sh b/test/test-lib.sh index 8158328..94efdc1 100644 --- a/test/test-lib.sh +++ b/test/test-lib.sh @@ -318,7 +318,11 @@ generate_message () fi if [ -z ${template[subject]} ]; then - template[subject]=Test message #${gen_msg_cnt} + if [ -n $test_subtest_name ]; then + template[subject]=$test_subtest_name + else + template[subject]=Test message #${gen_msg_cnt} + fi fi if [ -z ${template[date]} ]; then -- 1.7.8.3 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] lib: update notmuch_tags_get example to reflect api change
On 2012-01-30 17:42:01, Austin Clements wrote: Sorry, I replied to the wrong one. This one LGTM. (BTW, for future reference, it's helpful if you send later versions in reply to the first version so that they're grouped in threads. Sorry that the documentation on notmuch's coding conventions is so scattered and lacking. We're working on it.) Will do. I deleted the first message by mistake, and did not see Message-Ids in the archives. Does git send-email hang on to the message-ids for replies? /Allan -- Allan Wind Life Integrity, LLC http://lifeintegrity.com ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: Bug?: notmuch-search-show-thread shows several threads; only one containing matching messages
On Mon, 30 Jan 2012 23:34:16 +0100, Gregor Zattler telegr...@gmx.net wrote: Hi Mark, * Mark Walters markwalters1...@gmail.com [30. Jan. 2012]: On Mon, 30 Jan 2012 20:04:25 +0100, Gregor Zattler telegr...@gmx.net wrote: * Pieter Praet pie...@praet.org [30. Jan. 2012]: On Mon, 30 Jan 2012 00:42:14 +0100, Gregor Zattler telegr...@gmx.net wrote: * Pieter Praet pie...@praet.org [26. Jan. 2012]: Here's another couple of threads squashed into a single one: - [O] [Use Question] Capture and long lines - id:banlktikof4txunllufrznsd6k2zys7s...@mail.gmail.com - [O] Worg update - id:m1wrfiz3ch@tsdye.com - [O] Table formula to convert hex to dec - id:20110724080054.GB16388@x201 - [O] ICS import? - id:20120125173421.GQ3747@x201 AFAICT, none of them share Message-Id's... Do you consider this a bug? I do. No idea what causes it or how to fix it though... :) First I thougt it' not a severe bug since one see's more not less messages in notmuch show buffer. But later I realised one also sees less not more threads in notmuch search buffer and might not read certain notmuch threads because of wrong $Subject: in notmuch search buffer. I think notmuch links two messages into the same thread if they have an in-reply-to or reference header in common: i.e the messages reference a common parent message. (See comment in lib/database.cc Even before a message is added, it's pre-allocated thread ID is useful so that all descendant messages that reference this common parent can be recognized as belonging to the same thread.) So in case message a from thread A and message b from B would name the same Message c in their In-Reoply-To:/References: headers, while c is not (for some reason) in A or B, notmuch would assume both threads linked? Makes sense. As far as I can see your grep tests haven't checked for that. True. Also, could you email me the mbox you had (I think you said that it was a mailing list so all public) and I will take a look? Sure, I do so off-list because of the size of the attachment. Hi I have looked at this and I think this is not notmuch's fault: I think it is a mua doing strange things: One of the mails has an in-reply-to header which looks like In-reply-to: Message from Carsten Dominik carsten.domi...@gmail.com of Tue, 15 Mar 2011 12:18:51 BST. 17242340-a14f-495a-b144-20c96d52b...@gmail.com and I think notmuch is taking the carsten.domi...@gmail.com as message id. A similar in-reply-to header appears in the other thread so notmuch pairs them up. According to http://www.jwz.org/doc/threading.html this form of header is not allowed under RFC2822 but was allowed under the earlier RFC822. You can see several such messages on the gnu-mailing list site eg ftp://lists.gnu.org/emacs-orgmode/2011-11 search for in-reply-to: M but they all appear to be from the same person (running mh-e 8.3 nmh under emacs 24) In my collection from the linux kernel mailing list I get some examples of in-reply-to not just being : msg-id but it was only about 200 from 100,000 messages in the second half of 2010 (the most recent archives I have). Best wishes Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re:
On Tue, 24 Jan 2012 16:06:15 -0800, Jameson Graef Rollins jroll...@finestructure.net wrote: Final v3 rework of this patch series: pushed. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 1/7] cli: add --do-not-exclude option to count and search.
Quoth Mark Walters on Jan 29 at 6:39 pm: This option turns off the exclusion so all matching messages are returned. We do not need to add this to show as notmuch-show does not (yet) exclude. --- notmuch-count.c | 12 notmuch-search.c | 12 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/notmuch-count.c b/notmuch-count.c index 63459fb..c88975e 100644 --- a/notmuch-count.c +++ b/notmuch-count.c @@ -37,6 +37,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) int output = OUTPUT_MESSAGES; const char **search_exclude_tags; size_t search_exclude_tags_length; +notmuch_bool_t do_not_exclude = FALSE; unsigned int i; notmuch_opt_desc_t options[] = { @@ -44,6 +45,7 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) (notmuch_keyword_t []){ { threads, OUTPUT_THREADS }, { messages, OUTPUT_MESSAGES }, { 0, 0 } } }, + { NOTMUCH_OPT_BOOLEAN, do_not_exclude, do-not-exclude, 'd', 0 }, Maybe just no-exclude? do-not-exclude seems needlessly verbose. Also, you have an extra space after the first comma. { 0, 0, 0, 0, 0 } }; @@ -78,10 +80,12 @@ notmuch_count_command (void *ctx, int argc, char *argv[]) return 1; } -search_exclude_tags = notmuch_config_get_search_exclude_tags - (config, search_exclude_tags_length); -for (i = 0; i search_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); +if (!do_not_exclude) { You could move search_exclude_tags and search_exclude_tags_length in here now that it's a block (but you don't have to). + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, search_exclude_tags_length); + for (i = 0; i search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); +} switch (output) { case OUTPUT_MESSAGES: diff --git a/notmuch-search.c b/notmuch-search.c index d504051..084dd05 100644 --- a/notmuch-search.c +++ b/notmuch-search.c @@ -425,6 +425,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) int limit = -1; /* unlimited */ const char **search_exclude_tags; size_t search_exclude_tags_length; +notmuch_bool_t do_not_exclude = FALSE; unsigned int i; enum { NOTMUCH_FORMAT_JSON, NOTMUCH_FORMAT_TEXT } @@ -446,6 +447,7 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) { files, OUTPUT_FILES }, { tags, OUTPUT_TAGS }, { 0, 0 } } }, +{ NOTMUCH_OPT_BOOLEAN, do_not_exclude, do-not-exclude, 'd', 0 }, Same. { NOTMUCH_OPT_INT, offset, offset, 'O', 0 }, { NOTMUCH_OPT_INT, limit, limit, 'L', 0 }, { 0, 0, 0, 0, 0 } @@ -493,10 +495,12 @@ notmuch_search_command (void *ctx, int argc, char *argv[]) notmuch_query_set_sort (query, sort); -search_exclude_tags = notmuch_config_get_search_exclude_tags - (config, search_exclude_tags_length); -for (i = 0; i search_exclude_tags_length; i++) - notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); +if (!do_not_exclude) { + search_exclude_tags = notmuch_config_get_search_exclude_tags + (config, search_exclude_tags_length); + for (i = 0; i search_exclude_tags_length; i++) + notmuch_query_add_tag_exclude (query, search_exclude_tags[i]); +} switch (output) { default: ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 3/7] lib: Make notmuch_query_search_messages set the exclude flag
Quoth Mark Walters on Jan 29 at 6:39 pm: Add a flag NOTMUCH_MESSAGE_FLAG_EXCLUDED which is set by notmuch_query_search_messages for excluded messages. Also add an option omit_excluded_messages to the search that we do not want the excludes at all. This exclude flag will be added to notmuch_query_search threads in the next patch. --- lib/notmuch-private.h |1 + lib/notmuch.h |8 ++- lib/query.cc | 52 +--- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index 7bf153e..e791bb0 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -401,6 +401,7 @@ typedef struct _notmuch_message_list { */ struct visible _notmuch_messages { notmuch_bool_t is_of_list_type; +notmuch_doc_id_set_t *excluded_doc_ids; I might be following the diff wrong, but shouldn't this be a field of notmuch_mset_messages_t? (Then it also doesn't have to be a pointer, which is really how notmuch_doc_id_set_t was designed to be used.) notmuch_message_node_t *iterator; }; diff --git a/lib/notmuch.h b/lib/notmuch.h index 7929fe7..740d005 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -449,6 +449,11 @@ typedef enum { const char * notmuch_query_get_query_string (notmuch_query_t *query); +/* specify whether to results should omit the excluded results rather + * than just marking them excluded */ +void +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit); + I don't think we should add this API. The library behavior will not change for library users that don't use excludes and library users that do use excludes should by aware of the excluded flag and do the appropriate thing. I can see why this is handy in some cases, but I don't think it provides enough utility to warrant becoming part of the permanent and minimal library interface. /* Specify the sorting desired for this query. */ void notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort); @@ -895,7 +900,8 @@ notmuch_message_get_filenames (notmuch_message_t *message); /* Message flags */ typedef enum _notmuch_message_flag { -NOTMUCH_MESSAGE_FLAG_MATCH +NOTMUCH_MESSAGE_FLAG_MATCH, +NOTMUCH_MESSAGE_FLAG_EXCLUDED } notmuch_message_flag_t; /* Get a value of a flag for the email corresponding to 'message'. */ diff --git a/lib/query.cc b/lib/query.cc index c25b301..7d165d2 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -28,6 +28,7 @@ struct _notmuch_query { const char *query_string; notmuch_sort_t sort; notmuch_string_list_t *exclude_terms; +notmuch_bool_t omit_excluded_messages; }; typedef struct _notmuch_mset_messages { @@ -57,6 +58,12 @@ struct visible _notmuch_threads { notmuch_doc_id_set_t match_set; }; +/* we need this in the message functions so forward declare */ Comments should start with a capital letter and end with a period. (The code isn't completely consistent about this, but it is something we're codifying in the upcoming style guide.) +static notmuch_bool_t +_notmuch_doc_id_set_init (void *ctx, + notmuch_doc_id_set_t *doc_ids, + GArray *arr); + notmuch_query_t * notmuch_query_create (notmuch_database_t *notmuch, const char *query_string) @@ -79,6 +86,8 @@ notmuch_query_create (notmuch_database_t *notmuch, query-exclude_terms = _notmuch_string_list_create (query); +query-omit_excluded_messages = FALSE; + return query; } @@ -89,6 +98,12 @@ notmuch_query_get_query_string (notmuch_query_t *query) } void +notmuch_query_set_omit_excluded_messages (notmuch_query_t *query, notmuch_bool_t omit) +{ +query-omit_excluded_messages = omit; +} + +void notmuch_query_set_sort (notmuch_query_t *query, notmuch_sort_t sort) { query-sort = sort; @@ -173,6 +188,7 @@ notmuch_query_search_messages (notmuch_query_t *query) mail)); Xapian::Query string_query, final_query, exclude_query; Xapian::MSet mset; + Xapian::MSetIterator iterator; unsigned int flags = (Xapian::QueryParser::FLAG_BOOLEAN | Xapian::QueryParser::FLAG_PHRASE | Xapian::QueryParser::FLAG_LOVEHATE | @@ -190,11 +206,35 @@ notmuch_query_search_messages (notmuch_query_t *query) final_query = Xapian::Query (Xapian::Query::OP_AND, mail_query, string_query); } + messages-base.excluded_doc_ids = NULL; + + if (query-exclude_terms) { + exclude_query = _notmuch_exclude_tags (query, final_query); + exclude_query = Xapian::Query (Xapian::Query::OP_AND, +exclude_query, final_query); + + if
Re: [PATCH 4/7] lib: Add the exclude flag to notmuch_query_search_threads
Quoth Mark Walters on Jan 29 at 6:39 pm: Add the NOTMUCH_MESSAGE_FLAG_EXCLUDED flag to notmuch_query_search_threads. Implemented by inspecting the tags directly in _notmuch_thread_create/_thread_add_message rather than as a Xapian query for speed reasons. --- lib/notmuch-private.h | 16 ++-- lib/query.cc |1 + lib/thread.cc | 18 +++--- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/notmuch-private.h b/lib/notmuch-private.h index e791bb0..56b87c6 100644 --- a/lib/notmuch-private.h +++ b/lib/notmuch-private.h @@ -211,12 +211,8 @@ _notmuch_directory_get_document_id (notmuch_directory_t *directory); /* thread.cc */ -notmuch_thread_t * -_notmuch_thread_create (void *ctx, - notmuch_database_t *notmuch, - unsigned int seed_doc_id, - notmuch_doc_id_set_t *match_set, - notmuch_sort_t sort); +/* Definition of _notmuch_thread_create moved later since now uses + * string_list_t */ Naw, leave the definition here along with the other things from thread.cc and just add a typedef struct _notmuch_string_list notmuch_string_list_t; along with the typedef for notmuch_doc_id_set_t near the top. (You might also have to tweak the typedef of notmuch_string_list_t later so it's just the struct definition.) /* message.cc */ @@ -492,6 +488,14 @@ notmuch_filenames_t * _notmuch_filenames_create (const void *ctx, notmuch_string_list_t *list); +notmuch_thread_t * +_notmuch_thread_create (void *ctx, + notmuch_database_t *notmuch, + unsigned int seed_doc_id, + notmuch_doc_id_set_t *match_set, + notmuch_string_list_t *excluded_terms, + notmuch_sort_t sort); + #pragma GCC visibility pop NOTMUCH_END_DECLS diff --git a/lib/query.cc b/lib/query.cc index 7d165d2..dee7ec0 100644 --- a/lib/query.cc +++ b/lib/query.cc @@ -472,6 +472,7 @@ notmuch_threads_get (notmuch_threads_t *threads) threads-query-notmuch, doc_id, threads-match_set, +threads-query-exclude_terms, threads-query-sort); } diff --git a/lib/thread.cc b/lib/thread.cc index 0435ee6..6d65d52 100644 --- a/lib/thread.cc +++ b/lib/thread.cc @@ -214,7 +214,8 @@ _thread_cleanup_author (notmuch_thread_t *thread, */ static void _thread_add_message (notmuch_thread_t *thread, - notmuch_message_t *message) + notmuch_message_t *message, + notmuch_string_list_t *exclude_terms) { notmuch_tags_t *tags; const char *tag; @@ -262,6 +263,15 @@ _thread_add_message (notmuch_thread_t *thread, notmuch_tags_move_to_next (tags)) { tag = notmuch_tags_get (tags); + /* mark excluded messages */ Capital and period. + for (notmuch_string_node_t *term = exclude_terms-head; term; + term = term-next) { + /* we ignore initial 'K' */ Same. + if (strcmp(tag, (term-string + 1)) == 0) { + notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED, TRUE); + break; + } + } g_hash_table_insert (thread-tags, xstrdup (tag), NULL); } } @@ -321,7 +331,8 @@ _thread_add_matched_message (notmuch_thread_t *thread, _thread_set_subject_from_message (thread, message); } -thread-matched_messages++; +if (!notmuch_message_get_flag (message, NOTMUCH_MESSAGE_FLAG_EXCLUDED)) + thread-matched_messages++; I'd still say this warrants a better API. if (g_hash_table_lookup_extended (thread-message_hash, notmuch_message_get_message_id (message), NULL, @@ -392,6 +403,7 @@ _notmuch_thread_create (void *ctx, notmuch_database_t *notmuch, unsigned int seed_doc_id, notmuch_doc_id_set_t *match_set, + notmuch_string_list_t *exclude_terms, notmuch_sort_t sort) { notmuch_thread_t *thread; @@ -467,7 +479,7 @@ _notmuch_thread_create (void *ctx, if (doc_id == seed_doc_id) message = seed_message; - _thread_add_message (thread, message); + _thread_add_message (thread, message, exclude_terms); if ( _notmuch_doc_id_set_contains (match_set, doc_id)) { _notmuch_doc_id_set_remove (match_set, doc_id); ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v4 02/12] emacs: remove text properties from `notmuch-search-get-tags' result
--- emacs/notmuch.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 84d7d0a..ff46617 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -577,7 +577,7 @@ the messages that were tagged (let ((beg (+ (point) 1))) (re-search-forward )) (let ((end (- (point) 1))) - (split-string (buffer-substring beg end)) + (split-string (buffer-substring-no-properties beg end)) (defun notmuch-search-get-tags-region (beg end) (save-excursion -- 1.7.9 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v4 07/12] emacs: add * binding for notmuch-show view
The patch adds `notmuch-show-tag-all' function bound to * in notmuch-show view. The function is similar to the `notmuch-search-tag-all' function for the notmuch-search view: it changes tags for all messages in the current thread. --- emacs/notmuch-show.el | 35 +++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index a0efae7..1cdd23e 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1074,6 +1074,7 @@ thread id. If a prefix is given, crypto processing is toggled. (define-key map c 'notmuch-show-stash-map) (define-key map = 'notmuch-show-refresh-view) (define-key map h 'notmuch-show-toggle-headers) + (define-key map * 'notmuch-show-tag-all) (define-key map - 'notmuch-show-remove-tag) (define-key map + 'notmuch-show-add-tag) (define-key map x 'notmuch-show-archive-thread-then-exit) @@ -1171,6 +1172,15 @@ All currently available key bindings: (notmuch-show-move-to-message-top) t)) +(defun notmuch-show-mapc (function) + Iterate through all messages in the current thread with +`notmuch-show-goto-message-next' and call FUNCTION for side +effects. + (save-excursion +(goto-char (point-min)) +(loop do (funcall function) + while (notmuch-show-goto-message-next + ;; Functions relating to the visibility of messages and their ;; components. @@ -1223,6 +1233,18 @@ Some useful entries are: Return the message id of the current message. (concat id:\ (notmuch-show-get-prop :id) \)) +(defun notmuch-show-get-messages-ids () + Return all message ids of messages in the current thread. + (let ((message-ids)) +(notmuch-show-mapc + (lambda () (push (notmuch-show-get-message-id) message-ids))) +message-ids)) + +(defun notmuch-show-get-messages-ids-search () + Return a search string for all message ids of messages in the +current thread. + (mapconcat 'identity (notmuch-show-get-messages-ids) or )) + ;; dme: Would it make sense to use a macro for many of these? (defun notmuch-show-get-filename () @@ -1501,6 +1523,19 @@ TAG-CHANGES is a list of tag operations for `notmuch-tag'. initial-input (notmuch-show-get-message-id (apply 'notmuch-show-tag-message tag-changes))) +(defun notmuch-show-tag-all (rest tag-changes) + Change tags for all messages in the current thread. + +TAG-CHANGES is a list of tag operations for `notmuch-tag'. + (interactive (notmuch-read-tag-changes nil notmuch-show-thread-id)) + (apply 'notmuch-tag (notmuch-show-get-messages-ids-search) tag-changes) + (notmuch-show-mapc + (lambda () + (let* ((current-tags (notmuch-show-get-tags)) + (new-tags (notmuch-update-tags current-tags tag-changes))) + (unless (equal current-tags new-tags) +(notmuch-show-set-tags new-tags)) + (defun notmuch-show-add-tag () Same as `notmuch-show-tag' but sets initial input to '+'. (interactive) -- 1.7.9 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [RFC PATCH 2/4] Add NOTMUCH_MESSAGE_FLAG_EXCLUDED flag
This is looking really good. I think this overall approach is significantly better than the initial exclude support and the UI aspects look like they should be much more pleasant. Quoth Mark Walters on Jan 29 at 6:36 pm: Ok I now have a patch set which might be complete enough to be worth reviewing. It is essentially complete and appears to work. Things that still need doing: updating the test suite. The series changes notmuch-show to output the exclude flag so several tests need updating. Of course, the new functionality needs some tests too. emacs/notmuch.el I think it would be nice to hide (make invisible) threads with no matching non-excluded messages (with a toggle for visibility) but that is definitely beyond my elisp skills. I'm happy to do that once this goes in. The first patch of the series is not really part of the series: it adds a --do-not-exclude option to tell the command not to exclude. I think this is useful anyway, but it also simplifies behaviour decisions with the excludes. For example notmuch count will only count matching non-excluded messages but notmuch count --do-not-exclude will count all matching messages excluded or not. One outstanding issue is that raised in id:20120124025331.gz16...@mit.edu. I will need to think about that. Best wishes Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/6] emacs: move tag format validation to `notmuch-tag' function
Hi Austin. On Sun, 29 Jan 2012 16:34:27 -0500, Austin Clements wrote: > One philosophical nit below, but not enough to hold this up. > > Quoth Dmitry Kurochkin on Jan 28 at 8:41 am: > > Before the change, tag format validation was done in > > `notmuch-search-operate-all' function only. The patch moves it down > > to `notmuch-tag', so that all users of that function get input > > validation. > > --- > > emacs/notmuch.el | 12 ++-- > > 1 files changed, 6 insertions(+), 6 deletions(-) > > > > diff --git a/emacs/notmuch.el b/emacs/notmuch.el > > index 72f78ed..84d7d0a 100644 > > --- a/emacs/notmuch.el > > +++ b/emacs/notmuch.el > > @@ -522,6 +522,12 @@ Note: Other code should always use this function alter > > tags of > > messages instead of running (notmuch-call-notmuch-process \"tag\" ..) > > directly, so that hooks specified in notmuch-before-tag-hook and > > notmuch-after-tag-hook will be run." > > + ;; Perform some validation > > + (when (null tags) (error "No tags given")) > > Since this is a non-interactive function and hence is meant to be > invoked programmatically, I would expect it to accept zero tags. > Unlike the following check, this is a UI-level check and thus, I > believe, belongs in interactive functions (even if that requires a > little duplication). > Agreed. Though I would hate to add the same check to each tag operation. Perhaps this check can go to `notmuch-select-tags-with-completion'? This is not the main patch in the series. So I think I would prefer not to make v2 because of this issue. If we come up with a good (i.e. no duplication) solution, I will prepare a separate patch for it. Regards, Dmitry > > + (mapc (lambda (tag) > > + (unless (string-match-p "^[-+][-+_.[:word:]]+$" tag) > > + (error "Tag must be of the form `+this_tag' or `-that_tag'"))) > > + tags) > >(run-hooks 'notmuch-before-tag-hook) > >(apply 'notmuch-call-notmuch-process > > (append (list "tag") tags (list "--" query))) > > @@ -890,12 +896,6 @@ characters as well as `_.+-'. > >(interactive (notmuch-select-tags-with-completion > > "Operations (+add -drop): notmuch tag " > > '("+" "-"))) > > - ;; Perform some validation > > - (when (null actions) (error "No operations given")) > > - (mapc (lambda (action) > > - (unless (string-match-p "^[-+][-+_.[:word:]]+$" action) > > - (error "Action must be of the form `+this_tag' or `-that_tag'"))) > > - actions) > >(apply 'notmuch-tag notmuch-search-query-string actions)) > > > > (defun notmuch-search-buffer-title (query)
[PATCH 4/6] test: fix emacs tests after tagging operations changes
On Sun, 29 Jan 2012 17:58:41 -0500, Austin Clements wrote: > Quoth Dmitry Kurochkin on Jan 28 at 8:41 am: > > After the recent tagging operations changes, functions bound to "+" > > and "-" in notmuch-search and notmuch-show views always read input > > from the minibuffer. Use kbd macros instead of calling them directly. > > Should this be folded into the previous patch so these tests aren't > temporarily broken? I think it is a common approach for notmuch. IIRC I sent patches which changes both code and tests, and I was asked to move the tests to a separate patch. So I will leave it as is for now. Though if you point me to a relevant discussion or policy, which says that the tests should be merged, I would be happy to do it. Regards, Dmitry
[PATCH 1/6] emacs: move tag format validation to `notmuch-tag' function
On Sun, 29 Jan 2012 18:16:50 -0500, Austin Clements wrote: > Quoth Dmitry Kurochkin on Jan 30 at 2:54 am: > > Hi Austin. > > > > On Sun, 29 Jan 2012 16:34:27 -0500, Austin Clements > > wrote: > > > One philosophical nit below, but not enough to hold this up. > > > > > > Quoth Dmitry Kurochkin on Jan 28 at 8:41 am: > > > > Before the change, tag format validation was done in > > > > `notmuch-search-operate-all' function only. The patch moves it down > > > > to `notmuch-tag', so that all users of that function get input > > > > validation. > > > > --- > > > > emacs/notmuch.el | 12 ++-- > > > > 1 files changed, 6 insertions(+), 6 deletions(-) > > > > > > > > diff --git a/emacs/notmuch.el b/emacs/notmuch.el > > > > index 72f78ed..84d7d0a 100644 > > > > --- a/emacs/notmuch.el > > > > +++ b/emacs/notmuch.el > > > > @@ -522,6 +522,12 @@ Note: Other code should always use this function > > > > alter tags of > > > > messages instead of running (notmuch-call-notmuch-process \"tag\" ..) > > > > directly, so that hooks specified in notmuch-before-tag-hook and > > > > notmuch-after-tag-hook will be run." > > > > + ;; Perform some validation > > > > + (when (null tags) (error "No tags given")) > > > > > > Since this is a non-interactive function and hence is meant to be > > > invoked programmatically, I would expect it to accept zero tags. > > > Unlike the following check, this is a UI-level check and thus, I > > > believe, belongs in interactive functions (even if that requires a > > > little duplication). > > > > > > > Agreed. Though I would hate to add the same check to each tag > > operation. Perhaps this check can go to > > `notmuch-select-tags-with-completion'? > > > > This is not the main patch in the series. So I think I would prefer not > > to make v2 because of this issue. If we come up with a good (i.e. no > > duplication) solution, I will prepare a separate patch for it. > > What about not giving any error for no tags? As a user, if I delete > the whole tags prompt including the +/- operator, that's a very > explicit action and it's very clear what it should do (nothing). I > don't need Emacs wagging its finger at me for doing something with a > clear meaning. Sure, let's try it. I am always hesitant to do changes like this to avoid boring discussions on what is better. I hope nobody would argue with this change :) Regards, Dmitry
Bug?: notmuch-search-show-thread shows several threads; only one containing matching messages
Hi Jani, notmuch developers, executive summary: notmuch almangamates several e-mail threads into one notmuch-thread, I consider this a bug: * Jani Nikula [26. Jan. 2012]: > On Thu, 26 Jan 2012 13:44:50 +0100, Gregor Zattler > wrote: >> * Jameson Graef Rollins [25. Jan. 2012]: >>> On Wed, 25 Jan 2012 20:19:03 -0500, Austin Clements >>> wrote: One very common cause of this is someone using "reply" to get an initial set of recipients, but then replacing the entire message and subject (presumably without realizing that the mail is still tracking what it was a reply to). This can also happen if someone intentionally replies to multiple messages (though few mail clients support this), or if there was a message ID collision. >>> >>> This is a very common occurrence for me as well. I would put money down >>> that this is what you're seeing. >> >> I thought about this too and this is why I checked for any >> occurrence of Message-IDs in the other emails: >> >>|> I isolated the thread I was interested in, >>|> extracted the message ids of its messages and greped the rest of >>|> the messages for this message ids: no matches.[2] Therefore no of >>|> the rests messages are part of the thread I was interested in >> >> perhaps there was a logic error in how I did this: >> >>|> [2] grep -I "^Message-Id:" /tmp/thread-I-m-interested-in.mbox |sed -e >> "s/Message-Id: $//" >really.mid >>|> grep -I -F really.mid rest.mbox >>|> --> no match >> /tmp/thread-I-m-interested-in.mbox is a mbox with messages >> I'minterested in, the "real" ones. really.mid is a list of >> Message-IDs of these "real" emails. rest.mbox is a mbox with the >> other emails, Emacs showed in his notmuch show buffer but are >> other threads. >> >> Since there is no match I concluded, the threads are not linked. >> Perhaps I made a mistake. I'l retest it and report again. But >> right now I don't have the time to do this. I re-did it. This time I used the Emacs interface, searched for folder:orgmode date 64 bit 32 and in the notmuch-search -buffer I used notmuch-search-stash-thread-id to get the internal thread-number. I then did a notmuch show --format=mbox thread:000108e0 >thread.mbox opened this mbox with mutt, saved the one thread about dates before 1970 in one maildir `date64bit32-I-am-interested-in.mailbox' and the rest in a maildir `other-e-mails.mailbox'. I produced a list of all Message-Ids of the interesting thread by doing rgrep -E -i "^Message-Id:[[:space:]]" date64bit32-I-am-interested-in.mailbox|egrep -o "[^<]+@[^>]+" >date64bit32-I-am-interested-in.mid and searched for this strings in the other e-mails: rgrep -F date64bit32-I-am-interested-in.mid other-e-mails.mailbox No hits. I also did it the other way around: rgrep -E -i "^Message-Id:[[:space:]]" other-e-mails.mailbox|egrep -o "[^<]+@[^>]+" >other-e-mails.mid rgrep -F other-e-mails.mid date64bit32-I-am-interested-in.mailbox No hits. (I spared me the hassle to search for the Message-Ids in correct headers only, there are simply no hits anywhere in this other e-mails. Thus I conclude that notmuch amalgamates different e-mail-threads into one as represented by one thread-id. I consider this a bug. If anybody is interested I can email her/him the mbox file with the relevant thread (minus privacy relevant headers / 300 KiB gzipped). > Do you have an mbox file in the maildir indexed by notmuch? That seems > like the issue. I don't think so: I rgreped for files with more than 1 line beginning with "Message-Id". I got 38 hits. I looked at all of them, they are no mbox files (at least no valid ones) but e-mails with other e-mails attached, or cited or in one case a multipart/mixed message with plain text part and html part. Nonetheless I isolated all Message-Ids from these 38 files, eliminated some html artefacts and greped for this in date64bit32-I-am-interested-in.mailbox and other-e-mails.mailbox: No hits with either file. I also did it the other way around: Searching for the Message-ids of the two sets in the 38 potential mbox files: No hit. Ciao, Gregor -- -... --- .-. . -.. ..--.. ...-.-
Bug?: notmuch-search-show-thread shows several threads; only one containing matching messages
Hi Pieter, notmuch developers * Pieter Praet [26. Jan. 2012]: > On Thu, 26 Jan 2012 13:44:50 +0100, Gregor Zattler > wrote: >>|> [2] grep -I "^Message-Id:" /tmp/thread-I-m-interested-in.mbox |sed -e >> "s/Message-Id: $//" >really.mid >>|> grep -I -F really.mid rest.mbox >>|> --> no match >> > > Did you mean to do case-insensitive grep? ('-i' instead of '-I'). Yes I did mean case-insensitive search and the `-I' is the result of a misguided abbrev... Sorry about this. > Also, the '-F' option expects input on stdin, not a filename. No, this is -F instead of -f and means --fixed-strings. > Try this (with all individual threads split into separate mboxes): > > #+begin_src sh > for i in $(ls *.mbox) ; do > grep -i '^Message-Id:' "${i}" | \ > sed -e 's/^.\{13\}//' -e 's/>$//' \ > > "${i}.mids" > done > for i in $(ls *.mids) ; do > echo "## Grepping for ${i}'s Message-Ids" > grep -i -F "$(cat ${i})" *.mbox > done > #+end_src Thanks I did it "manual". > Here's another couple of threads squashed into a single one: > - [O] [Use Question] Capture and long lines > - id:"BANLkTikoF4tXuNLLufRzNSD6k2ZYs7sUcg at mail.gmail.com" > - [O] Worg update > - id:"m1wrfiz3ch.fsf at tsdye.com" > - [O] Table formula to convert hex to dec > - id:"20110724080054.GB16388 at x201" > - [O] ICS import? > - id:"20120125173421.GQ3747 at x201" > > > AFAICT, none of them share Message-Id's... Do you consider this a bug? Ciao, Gregor -- -... --- .-. . -.. ..--.. ...-.-
[PATCH 3/6] emacs: make "+" and "-" tagging operations more robust
Hi Austin. The below changes will be send as v2 soon. On Sun, 29 Jan 2012 17:57:10 -0500, Austin Clements wrote: > I'm looking forward to having this. I think it'll streamline tagging > operations. > > Quoth Dmitry Kurochkin on Jan 28 at 8:41 am: > > Before the change, "+" and "-" tagging operations in notmuch-search > > and notmuch-show views accepted only a single tag. The patch makes > > them use the recently added `notmuch-select-tags-with-completion' > > function, which allows to enter multiple tags with "+" and "-" > > prefixes. So after the change, "+" and "-" bindings allow to both add > > and remove multiple tags. The only difference between "+" and "-" is > > the minibuffer initial input ("+" and "-" respectively). > > This patch was a little difficult to review because it was largish and > the diff happened to contain a bunch of forward references. If it's > convenient (don't bother if it's not), could you divide up the next > version a little? Something simple like sending the show changes as a > separate patch would probably make it a lot easier. > done > > --- > > emacs/notmuch-show.el | 65 +++ > > emacs/notmuch.el | 165 > > + > > 2 files changed, 107 insertions(+), 123 deletions(-) > > > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > > index 84ac624..03eadfb 100644 > > --- a/emacs/notmuch-show.el > > +++ b/emacs/notmuch-show.el > > @@ -38,8 +38,9 @@ > > > > (declare-function notmuch-call-notmuch-process "notmuch" ( args)) > > (declare-function notmuch-fontify-headers "notmuch" nil) > > -(declare-function notmuch-select-tag-with-completion "notmuch" (prompt > > search-terms)) > > +(declare-function notmuch-select-tags-with-completion "notmuch" ( > > initial-input search-terms)) > > (declare-function notmuch-search-show-thread "notmuch" nil) > > +(declare-function notmuch-update-tags "notmuch" (current-tags > > changed-tags)) > > > > (defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date") > >"Headers that should be shown in a message, in this order. > > @@ -1267,7 +1268,7 @@ Some useful entries are: > > > > (defun notmuch-show-mark-read () > >"Mark the current message as read." > > - (notmuch-show-remove-tag "unread")) > > + (notmuch-show-tag-message "-unread")) > > > > ;; Functions for getting attributes of several messages in the current > > ;; thread. > > @@ -1470,51 +1471,33 @@ than only the current message." > > (message (format "Command '%s' exited abnormally with code %d" > > shell-command exit-code > > > > -(defun notmuch-show-add-tags-worker (current-tags add-tags) > > - "Add to `current-tags' with any tags from `add-tags' not > > -currently present and return the result." > > - (let ((result-tags (copy-sequence current-tags))) > > -(mapc (lambda (add-tag) > > - (unless (member add-tag current-tags) > > - (setq result-tags (push add-tag result-tags > > - add-tags) > > -(sort result-tags 'string<))) > > - > > -(defun notmuch-show-del-tags-worker (current-tags del-tags) > > - "Remove any tags in `del-tags' from `current-tags' and return > > -the result." > > - (let ((result-tags (copy-sequence current-tags))) > > -(mapc (lambda (del-tag) > > - (setq result-tags (delete del-tag result-tags))) > > - del-tags) > > -result-tags)) > > - > > -(defun notmuch-show-add-tag ( toadd) > > - "Add a tag to the current message." > > - (interactive > > - (list (notmuch-select-tag-with-completion "Tag to add: "))) > > +(defun notmuch-show-tag-message ( changed-tags) > > + "Change tags for the current message. > > > > +`Changed-tags' is a list of tag operations for \"notmuch tag\", > > +i.e. a list of tags to change with '+' and '-' prefixes." > > Ticks in a docstring indicate functions (and will be hyperlinked as > such by describe-function). Typically, argument names are indicated > by writing them in all caps. > Thanks for the explanation. Fixed. > Also, it probably makes more sense to reference `notmuch-tag' than > "notmuch tag", since this is Lisp land (and, since that will be > helpfully hyperlinked, you probably don't need to explain changed-tags > here). > Makes sense, done. > >(let* ((current-tags (notmuch-show-get-tags)) > > -(new-tags (notmuch-show-add-tags-worker current-tags toadd))) > > - > > +(new-tags (notmuch-update-tags current-tags changed-tags))) > > (unless (equal current-tags new-tags) > > - (apply 'notmuch-tag (notmuch-show-get-message-id) > > -(mapcar (lambda (s) (concat "+" s)) toadd)) > > + (apply 'notmuch-tag (notmuch-show-get-message-id) changed-tags) > >(notmuch-show-set-tags new-tags > > > > -(defun notmuch-show-remove-tag ( toremove) > > - "Remove a tag from the current message." > > - (interactive > > - (list (notmuch-select-tag-with-completion > > - "Tag to
[PATCH 6/6] emacs: separate history for operations which accept single and multiple tags
On Sun, 29 Jan 2012 18:02:29 -0500, Austin Clements wrote: > Quoth Dmitry Kurochkin on Jan 28 at 8:41 am: > > Some tag-related operations accept a single tag without prefix > > (`notmuch-select-tag-with-completion'), others accept multiple tags > > prefixed with '+' or '-' (`notmuch-select-tags-with-completion'). > > Before the change, both functions used a single default minibuffer > > history. This is inconvenient because you have to skip options with > > incompatible format when going through the history. The patch adds > > separate history lists for the two functions. Note that functions > > that accept the same input format (e.g. "+", "-", "*") share the > > history list as before. > > --- > > emacs/notmuch.el | 12 ++-- > > 1 files changed, 10 insertions(+), 2 deletions(-) > > > > diff --git a/emacs/notmuch.el b/emacs/notmuch.el > > index 24b0ea3..9813e0a 100644 > > --- a/emacs/notmuch.el > > +++ b/emacs/notmuch.el > > @@ -76,6 +76,14 @@ For example: > > (defvar notmuch-query-history nil > >"Variable to store minibuffer history for notmuch queries") > > > > +(defvar notmuch-select-tag-history nil > > + "Variable to store notmuch tag history for > > + `notmuch-select-tag-with-completion'.") > > + > > +(defvar notmuch-select-tags-history nil > > + "Variable to store notmuch tags history for > > + `notmuch-select-tags-with-completion'.") > > + > > Really these are minibuffer or input histories, not "notmuch tag > history". Also, the second line shouldn't be indented. (Definitely > nits, but if you roll a new version, you might as well fix these.) > fixed Regards, Dmitry > > (defun notmuch-tag-completions ( search-terms) > >(split-string > > (with-output-to-string > > @@ -86,7 +94,7 @@ For example: > > > > (defun notmuch-select-tag-with-completion (prompt search-terms) > >(let ((tag-list (notmuch-tag-completions search-terms))) > > -(completing-read prompt tag-list))) > > +(completing-read prompt tag-list nil nil nil > > 'notmuch-select-tag-history))) > > > > (defun notmuch-select-tags-with-completion ( initial-input > > search-terms) > >(let* ((add-tag-list (mapcar (apply-partially 'concat "+") > > @@ -105,7 +113,7 @@ For example: > > map))) > > (delete "" (completing-read-multiple > > "Operations (+add -drop): notmuch tag " tag-list nil > > - nil initial-input > > + nil initial-input 'notmuch-select-tags-history > > > > (defun notmuch-update-tags (current-tags changed-tags) > >"Update `current-tags' with `changed-tags' and return the result.
[PATCH 8/6] emacs: use message ids instead of thread id in `notmuch-show-operate-all'
EOn Sun, 29 Jan 2012 18:11:20 -0500, Austin Clements wrote: > Eighth in the increasingly inaccurately named six patch series... > > Quoth Dmitry Kurochkin on Jan 28 at 9:59 am: > > Before the change, `notmuch-show-operate-all' used thread id for > > "notmuch tag" search. This could result in tagging unexpected > > messages that were added to the thread after the notmuch-show buffer > > was created. The patch changes `notmuch-show-operate-all' to use ids > > of shown messages to fix this. > > Are you planning to roll this into your earlier patch? > I would prefer to leave it separate. > > --- > > emacs/notmuch-show.el | 23 ++- > > 1 files changed, 22 insertions(+), 1 deletions(-) > > > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > > index 2ca4d92..e606224 100644 > > --- a/emacs/notmuch-show.el > > +++ b/emacs/notmuch-show.el > > @@ -1170,6 +1170,15 @@ All currently available key bindings: > > (notmuch-show-move-to-message-top) > > t)) > > > > +(defun notmuch-show-mapc (function) > > + "Iterate through all messages with > > +`notmuch-show-goto-message-next' and call `function' for side > > +effects." > > `function' should be FUNCTION. > done > > + (save-excursion > > +(goto-char (point-min)) > > +(loop do (funcall function) > > + while (notmuch-show-goto-message-next > > + > > ;; Functions relating to the visibility of messages and their > > ;; components. > > > > @@ -1222,6 +1231,18 @@ Some useful entries are: > >"Return the message id of the current message." > >(concat "id:\"" (notmuch-show-get-prop :id) "\"")) > > > > +(defun notmuch-show-get-messages-ids () > > + "Return all message ids of currently shown messages." > > "currently shown" could mean visible on the screen, which is not what > you mean. You also don't mean "open messages". Maybe "Return all > message ids of messages in this show buffer"? > Changed to "messages in the current thread". That is consistent with other docstrings in notmuch-show.el. > > + (let ((message-ids)) > > +(notmuch-show-mapc > > + (lambda () (push (notmuch-show-get-message-id) message-ids))) > > +message-ids)) > > + > > +(defun notmuch-show-get-messages-ids-search () > > + "Return a search string for all message ids of currently shown > > +messages." > > Same. > fixed Regards, Dmitry > > + (mapconcat 'identity (notmuch-show-get-messages-ids) " or ")) > > + > > ;; dme: Would it make sense to use a macro for many of these? > > > > (defun notmuch-show-get-filename () > > @@ -1496,7 +1517,7 @@ i.e. a list of tags to change with '+' and '-' > > prefixes." > > `Changed-tags' is a list of tag operations for \"notmuch tag\", > > i.e. a list of tags to change with '+' and '-' prefixes." > >(interactive (notmuch-select-tags-with-completion nil > > notmuch-show-thread-id)) > > - (apply 'notmuch-tag notmuch-show-thread-id changed-tags) > > + (apply 'notmuch-tag (notmuch-show-get-messages-ids-search) changed-tags) > >(save-excursion > > (goto-char (point-min)) > > (loop do (let* ((current-tags (notmuch-show-get-tags))
[PATCH v2 00/13] emacs: more robust and consistent tagging operations
Changes in v2: * add patch to remove "No tags given" error from `notmuch-tag' as suggested by Austin in [1] * split patch 3 in two (search and show) for easier review * add patch with NEWS entry * rename `notmuch-{search,show}-operate-all' to `notmuch-{search,show}-tag-all' * fix other comments from Austin's reviews [2,3,4] Regards, Dmitry [1] id:"20120129231650.GK17991 at mit.edu" [2] id:"20120129225710.GG17991 at mit.edu" [3] id:"20120129230229.GI17991 at mit.edu" [4] id:"20120129231120.GJ17991 at mit.edu"
[PATCH v2 01/13] emacs: move tag format validation to `notmuch-tag' function
Before the change, tag format validation was done in `notmuch-search-operate-all' function only. The patch moves it down to `notmuch-tag', so that all users of that function get input validation. --- emacs/notmuch.el | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 72f78ed..84d7d0a 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -522,6 +522,12 @@ Note: Other code should always use this function alter tags of messages instead of running (notmuch-call-notmuch-process \"tag\" ..) directly, so that hooks specified in notmuch-before-tag-hook and notmuch-after-tag-hook will be run." + ;; Perform some validation + (when (null tags) (error "No tags given")) + (mapc (lambda (tag) + (unless (string-match-p "^[-+][-+_.[:word:]]+$" tag) + (error "Tag must be of the form `+this_tag' or `-that_tag'"))) + tags) (run-hooks 'notmuch-before-tag-hook) (apply 'notmuch-call-notmuch-process (append (list "tag") tags (list "--" query))) @@ -890,12 +896,6 @@ characters as well as `_.+-'. (interactive (notmuch-select-tags-with-completion "Operations (+add -drop): notmuch tag " '("+" "-"))) - ;; Perform some validation - (when (null actions) (error "No operations given")) - (mapc (lambda (action) - (unless (string-match-p "^[-+][-+_.[:word:]]+$" action) - (error "Action must be of the form `+this_tag' or `-that_tag'"))) - actions) (apply 'notmuch-tag notmuch-search-query-string actions)) (defun notmuch-search-buffer-title (query) -- 1.7.8.3
[PATCH v2 02/13] emacs: remove text properties from `notmuch-search-get-tags' result
--- emacs/notmuch.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 84d7d0a..ff46617 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -577,7 +577,7 @@ the messages that were tagged" (let ((beg (+ (point) 1))) (re-search-forward ")") (let ((end (- (point) 1))) - (split-string (buffer-substring beg end)) + (split-string (buffer-substring-no-properties beg end)) (defun notmuch-search-get-tags-region (beg end) (save-excursion -- 1.7.8.3
[PATCH v2 04/13] emacs: make "+" and "-" tagging operations in notmuch-show more robust
Before the change, "+" and "-" tagging operations in notmuch-show view accepted only a single tag. The patch makes them use the recently added `notmuch-read-tag-changes' function, which allows to enter multiple tags with "+" and "-" prefixes. So after the change, "+" and "-" bindings in notmuch-show view allow to both add and remove multiple tags. The only difference between "+" and "-" is the minibuffer initial input ("+" and "-" respectively). --- emacs/notmuch-show.el | 64 +--- 1 files changed, 23 insertions(+), 41 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 84ac624..11dab2d 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -38,8 +38,9 @@ (declare-function notmuch-call-notmuch-process "notmuch" ( args)) (declare-function notmuch-fontify-headers "notmuch" nil) -(declare-function notmuch-select-tag-with-completion "notmuch" (prompt search-terms)) +(declare-function notmuch-read-tag-changes "notmuch" ( initial-input search-terms)) (declare-function notmuch-search-show-thread "notmuch" nil) +(declare-function notmuch-update-tags "notmuch" (current-tags tag-changes)) (defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date") "Headers that should be shown in a message, in this order. @@ -1267,7 +1268,7 @@ Some useful entries are: (defun notmuch-show-mark-read () "Mark the current message as read." - (notmuch-show-remove-tag "unread")) + (notmuch-show-tag-message "-unread")) ;; Functions for getting attributes of several messages in the current ;; thread. @@ -1470,51 +1471,32 @@ than only the current message." (message (format "Command '%s' exited abnormally with code %d" shell-command exit-code -(defun notmuch-show-add-tags-worker (current-tags add-tags) - "Add to `current-tags' with any tags from `add-tags' not -currently present and return the result." - (let ((result-tags (copy-sequence current-tags))) -(mapc (lambda (add-tag) - (unless (member add-tag current-tags) - (setq result-tags (push add-tag result-tags - add-tags) -(sort result-tags 'string<))) - -(defun notmuch-show-del-tags-worker (current-tags del-tags) - "Remove any tags in `del-tags' from `current-tags' and return -the result." - (let ((result-tags (copy-sequence current-tags))) -(mapc (lambda (del-tag) - (setq result-tags (delete del-tag result-tags))) - del-tags) -result-tags)) - -(defun notmuch-show-add-tag ( toadd) - "Add a tag to the current message." - (interactive - (list (notmuch-select-tag-with-completion "Tag to add: "))) +(defun notmuch-show-tag-message ( tag-changes) + "Change tags for the current message. +TAG-CHANGES is a list of tag operations for `notmuch-tag'." (let* ((current-tags (notmuch-show-get-tags)) -(new-tags (notmuch-show-add-tags-worker current-tags toadd))) - +(new-tags (notmuch-update-tags current-tags tag-changes))) (unless (equal current-tags new-tags) - (apply 'notmuch-tag (notmuch-show-get-message-id) -(mapcar (lambda (s) (concat "+" s)) toadd)) + (apply 'notmuch-tag (notmuch-show-get-message-id) tag-changes) (notmuch-show-set-tags new-tags -(defun notmuch-show-remove-tag ( toremove) - "Remove a tag from the current message." - (interactive - (list (notmuch-select-tag-with-completion - "Tag to remove: " (notmuch-show-get-message-id +(defun notmuch-show-tag ( initial-input) + "Change tags for the current message, read input from the minibuffer." + (interactive) + (let ((tag-changes (notmuch-read-tag-changes + initial-input (notmuch-show-get-message-id +(apply 'notmuch-show-tag-message tag-changes))) - (let* ((current-tags (notmuch-show-get-tags)) -(new-tags (notmuch-show-del-tags-worker current-tags toremove))) +(defun notmuch-show-add-tag () + "Same as `notmuch-show-tag' but sets initial input to '+'." + (interactive) + (notmuch-show-tag "+")) -(unless (equal current-tags new-tags) - (apply 'notmuch-tag (notmuch-show-get-message-id) -(mapcar (lambda (s) (concat "-" s)) toremove)) - (notmuch-show-set-tags new-tags +(defun notmuch-show-remove-tag () + "Same as `notmuch-show-tag' but sets initial input to '-'." + (interactive) + (notmuch-show-tag "-")) (defun notmuch-show-toggle-headers () "Toggle the visibility of the current message headers." @@ -1559,7 +1541,7 @@ argument, hide all of the messages." (defun notmuch-show-archive-thread-internal (show-next) ;; Remove the tag from the current set of messages. (goto-char (point-min)) - (loop do (notmuch-show-remove-tag "inbox") + (loop do (notmuch-show-tag-message "-inbox") until (not (notmuch-show-goto-message-next))) ;; Move to the next item in the search results, if any. (let ((parent-buffer notmuch-show-parent-buffer)) --
[PATCH v2 03/13] emacs: make "+" and "-" tagging operations in notmuch-search more robust
Before the change, "+" and "-" tagging operations in notmuch-search view accepted only a single tag. The patch makes them use the recently added `notmuch-read-tag-changes' function (renamed `notmuch-select-tags-with-completion'), which allows to enter multiple tags with "+" and "-" prefixes. So after the change, "+" and "-" bindings in notmuch-search view allow to both add and remove multiple tags. The only difference between "+" and "-" is the minibuffer initial input ("+" and "-" respectively). --- emacs/notmuch.el | 164 +++--- 1 files changed, 82 insertions(+), 82 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index ff46617..90b594c 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -76,38 +76,57 @@ For example: (defvar notmuch-query-history nil "Variable to store minibuffer history for notmuch queries") -(defun notmuch-tag-completions ( prefixes search-terms) - (let ((tag-list -(split-string - (with-output-to-string - (with-current-buffer standard-output - (apply 'call-process notmuch-command nil t -nil "search-tags" search-terms))) - "\n+" t))) -(if (null prefixes) - tag-list - (apply #'append -(mapcar (lambda (tag) - (mapcar (lambda (prefix) -(concat prefix tag)) prefixes)) -tag-list) +(defun notmuch-tag-completions ( search-terms) + (split-string + (with-output-to-string + (with-current-buffer standard-output + (apply 'call-process notmuch-command nil t + nil "search-tags" search-terms))) + "\n+" t)) (defun notmuch-select-tag-with-completion (prompt search-terms) - (let ((tag-list (notmuch-tag-completions nil search-terms))) + (let ((tag-list (notmuch-tag-completions search-terms))) (completing-read prompt tag-list))) -(defun notmuch-select-tags-with-completion (prompt prefixes search-terms) - (let ((tag-list (notmuch-tag-completions prefixes search-terms)) - (crm-separator " ") - ;; By default, space is bound to "complete word" function. - ;; Re-bind it to insert a space instead. Note that - ;; still does the completion. - (crm-local-completion-map -(let ((map (make-sparse-keymap))) - (set-keymap-parent map crm-local-completion-map) - (define-key map " " 'self-insert-command) - map))) -(delete "" (completing-read-multiple prompt tag-list +(defun notmuch-read-tag-changes ( initial-input search-terms) + (let* ((all-tag-list (notmuch-tag-completions)) +(add-tag-list (mapcar (apply-partially 'concat "+") all-tag-list)) +(remove-tag-list (mapcar (apply-partially 'concat "-") + (if (null search-terms) + all-tag-list + (notmuch-tag-completions search-terms +(tag-list (append add-tag-list remove-tag-list)) +(crm-separator " ") +;; By default, space is bound to "complete word" function. +;; Re-bind it to insert a space instead. Note that +;; still does the completion. +(crm-local-completion-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map crm-local-completion-map) + (define-key map " " 'self-insert-command) + map))) +(delete "" (completing-read-multiple "Tags (+add -drop): " + tag-list nil nil initial-input + +(defun notmuch-update-tags (tags tag-changes) + "Return a copy of TAGS with additions and removals from TAG-CHANGES. + +TAG-CHANGES must be a list of tags names, each prefixed with +either a \"+\" to indicate the tag should be added to TAGS if not +present or a \"-\" to indicate that the tag should be removed +from TAGS if present." + (let ((result-tags (copy-sequence tags))) +(dolist (tag-change tag-changes) + (unless (string= tag-change "") + (let ((op (string-to-char tag-change)) + (tag (substring tag-change 1))) + (case op + (?+ (unless (member tag result-tags) + (push tag result-tags))) + (?- (setq result-tags (delete tag result-tags))) + (otherwise +(error "Changed tag must be of the form `+this_tag' or `-that_tag'")) +(sort result-tags 'string<))) (defun notmuch-foreach-mime-part (function mm-handle) (cond ((stringp (car mm-handle)) @@ -447,6 +466,10 @@ Complete list of currently available key bindings: "Return a list of threads for the current region" (notmuch-search-properties-in-region 'notmuch-search-thread-id beg end)) +(defun notmuch-search-find-thread-id-region-search (beg end) + "Return a search string for threads for the current region" + (mapconcat 'identity (notmuch-search-find-thread-id-region beg end) " or ")) + (defun notmuch-search-find-authors ()
[PATCH v2 05/13] test: fix emacs tests after tagging operations changes
After the recent tagging operations changes, functions bound to "+" and "-" in notmuch-search and notmuch-show views always read input from the minibuffer. Use kbd macros instead of calling them directly. --- test/emacs | 20 ++-- 1 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/emacs b/test/emacs index 8ca4c8a..b9c0e02 100755 --- a/test/emacs +++ b/test/emacs @@ -101,26 +101,26 @@ test_begin_subtest "Add tag from search view" os_x_darwin_thread=$(notmuch search --output=threads id:ddd65cda0911171950o4eea4389v86de9525e46052d3 at mail.gmail.com) test_emacs "(notmuch-search \"$os_x_darwin_thread\") (notmuch-test-wait) - (notmuch-search-add-tag \"tag-from-search-view\")" + (execute-kbd-macro \"+tag-from-search-view\")" output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-search-view unread)" test_begin_subtest "Remove tag from search view" test_emacs "(notmuch-search \"$os_x_darwin_thread\") (notmuch-test-wait) - (notmuch-search-remove-tag \"tag-from-search-view\")" + (execute-kbd-macro \"-tag-from-search-view\")" output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)" test_begin_subtest "Add tag from notmuch-show view" test_emacs "(notmuch-show \"$os_x_darwin_thread\") - (notmuch-show-add-tag \"tag-from-show-view\")" + (execute-kbd-macro \"+tag-from-show-view\")" output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-show-view unread)" test_begin_subtest "Remove tag from notmuch-show view" test_emacs "(notmuch-show \"$os_x_darwin_thread\") - (notmuch-show-remove-tag \"tag-from-show-view\")" + (execute-kbd-macro \"-tag-from-show-view\")" output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)" @@ -128,14 +128,14 @@ test_begin_subtest "Message with .. in Message-Id:" add_message [id]=123..456 at example '[subject]="Message with .. in Message-Id"' test_emacs '(notmuch-search "id:\"123..456 at example\"") (notmuch-test-wait) - (notmuch-search-add-tag "search-add") - (notmuch-search-add-tag "search-remove") - (notmuch-search-remove-tag "search-remove") + (execute-kbd-macro "+search-add") + (execute-kbd-macro "+search-remove") + (execute-kbd-macro "-search-remove") (notmuch-show "id:\"123..456 at example\"") (notmuch-test-wait) - (notmuch-show-add-tag "show-add") - (notmuch-show-add-tag "show-remove") - (notmuch-show-remove-tag "show-remove")' + (execute-kbd-macro "+show-add") + (execute-kbd-macro "+show-remove") + (execute-kbd-macro "-show-remove")' output=$(notmuch search 'id:"123..456 at example"' | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Message with .. in Message-Id (inbox search-add show-add)" -- 1.7.8.3
[PATCH v2 06/13] emacs: rename `notmuch-search-operate-all' to `notmuch-search-tag-all'
`Notmuch-search-tag-all' is more clear and consistent with other tagging function names. --- emacs/notmuch.el |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 90b594c..90627dc 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -271,7 +271,7 @@ For a mouse binding, return nil." (define-key map "t" 'notmuch-search-filter-by-tag) (define-key map "f" 'notmuch-search-filter) (define-key map [mouse-1] 'notmuch-search-show-thread) -(define-key map "*" 'notmuch-search-operate-all) +(define-key map "*" 'notmuch-search-tag-all) (define-key map "a" 'notmuch-search-archive-thread) (define-key map "-" 'notmuch-search-remove-tag) (define-key map "+" 'notmuch-search-add-tag) @@ -420,7 +420,7 @@ any tags). Pressing \\[notmuch-search-show-thread] on any line displays that thread. The '\\[notmuch-search-add-tag]' and '\\[notmuch-search-remove-tag]' keys can be used to add or remove tags from a thread. The '\\[notmuch-search-archive-thread]' key is a convenience for archiving a thread (removing the \"inbox\" -tag). The '\\[notmuch-search-operate-all]' key can be used to add or remove a tag from all +tag). The '\\[notmuch-search-tag-all]' key can be used to add or remove a tag from all threads in the current buffer. Other useful commands are '\\[notmuch-search-filter]' for filtering the current search @@ -884,7 +884,7 @@ non-authors is found, assume that all of the authors match." (goto-char found-target))) (delete-process proc -(defun notmuch-search-operate-all ( actions) +(defun notmuch-search-tag-all ( actions) "Add/remove tags from all matching messages. This command adds or removes tags from all messages matching the -- 1.7.8.3
[PATCH v2 07/13] emacs: add "*" binding for notmuch-show view
The patch adds `notmuch-show-tag-all' function bound to "*" in notmuch-show view. The function is similar to the `notmuch-search-tag-all' function for the notmuch-search view: it changes tags for all messages in the current thread. --- emacs/notmuch-show.el | 15 +++ 1 files changed, 15 insertions(+), 0 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 11dab2d..0d90c1e 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1073,6 +1073,7 @@ thread id. If a prefix is given, crypto processing is toggled." (define-key map "c" 'notmuch-show-stash-map) (define-key map "=" 'notmuch-show-refresh-view) (define-key map "h" 'notmuch-show-toggle-headers) + (define-key map "*" 'notmuch-show-tag-all) (define-key map "-" 'notmuch-show-remove-tag) (define-key map "+" 'notmuch-show-add-tag) (define-key map "x" 'notmuch-show-archive-thread-then-exit) @@ -1488,6 +1489,20 @@ TAG-CHANGES is a list of tag operations for `notmuch-tag'." initial-input (notmuch-show-get-message-id (apply 'notmuch-show-tag-message tag-changes))) +(defun notmuch-show-tag-all ( tag-changes) + "Change tags for all messages in the current thread. + +TAG-CHANGES is a list of tag operations for `notmuch-tag'." + (interactive (notmuch-read-tag-changes nil notmuch-show-thread-id)) + (apply 'notmuch-tag notmuch-show-thread-id tag-changes) + (save-excursion +(goto-char (point-min)) +(loop do (let* ((current-tags (notmuch-show-get-tags)) + (new-tags (notmuch-update-tags current-tags tag-changes))) + (unless (equal current-tags new-tags) +(notmuch-show-set-tags new-tags))) + while (notmuch-show-goto-message-next + (defun notmuch-show-add-tag () "Same as `notmuch-show-tag' but sets initial input to '+'." (interactive) -- 1.7.8.3
[PATCH v2 08/13] emacs: separate history for operations which accept single and multiple tags
Some tag-related operations accept a single tag without prefix (`notmuch-select-tag-with-completion'), others accept multiple tags prefixed with '+' or '-' (`notmuch-read-tag-changes'). Before the change, both functions used a single default minibuffer history. This is inconvenient because you have to skip options with incompatible format when going through the history. The patch adds separate history lists for the two functions. Note that functions that accept the same input format (e.g. "+", "-", "*") share the history list as before. --- emacs/notmuch.el | 13 +++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 90627dc..5adcac5 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -76,6 +76,14 @@ For example: (defvar notmuch-query-history nil "Variable to store minibuffer history for notmuch queries") +(defvar notmuch-select-tag-history nil + "Variable to store minibuffer history for +`notmuch-select-tag-with-completion' function.") + +(defvar notmuch-read-tag-changes-history nil + "Variable to store minibuffer history for +`notmuch-read-tag-changes' function.") + (defun notmuch-tag-completions ( search-terms) (split-string (with-output-to-string @@ -86,7 +94,7 @@ For example: (defun notmuch-select-tag-with-completion (prompt search-terms) (let ((tag-list (notmuch-tag-completions search-terms))) -(completing-read prompt tag-list))) +(completing-read prompt tag-list nil nil nil 'notmuch-select-tag-history))) (defun notmuch-read-tag-changes ( initial-input search-terms) (let* ((all-tag-list (notmuch-tag-completions)) @@ -106,7 +114,8 @@ For example: (define-key map " " 'self-insert-command) map))) (delete "" (completing-read-multiple "Tags (+add -drop): " - tag-list nil nil initial-input + tag-list nil nil initial-input + 'notmuch-read-tag-changes-history (defun notmuch-update-tags (tags tag-changes) "Return a copy of TAGS with additions and removals from TAG-CHANGES. -- 1.7.8.3
[PATCH v2 09/13] emacs: relax tag syntax check in `notmuch-tag' function
The tag syntax check in `notmuch-tag' function was too strict and did not allow nmbug tags with "::". Since the check is done for all tagging operations in Emacs UI, this basically means that no nmbug tags can be changed. The patch relaxes the tag syntax check to allow any tag names that do not include whitespace characters. --- emacs/notmuch.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 5adcac5..7e8f185 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -557,7 +557,7 @@ notmuch-after-tag-hook will be run." ;; Perform some validation (when (null tags) (error "No tags given")) (mapc (lambda (tag) - (unless (string-match-p "^[-+][-+_.[:word:]]+$" tag) + (unless (string-match-p "^[-+]\\S-+$" tag) (error "Tag must be of the form `+this_tag' or `-that_tag'"))) tags) (run-hooks 'notmuch-before-tag-hook) -- 1.7.8.3
[PATCH v2 10/13] emacs: use message ids instead of thread id in `notmuch-show-operate-all'
Before the change, `notmuch-show-operate-all' used thread id for "notmuch tag" search. This could result in tagging unexpected messages that were added to the thread after the notmuch-show buffer was created. The patch changes `notmuch-show-operate-all' to use ids of shown messages to fix this. --- emacs/notmuch-show.el | 23 ++- 1 files changed, 22 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 0d90c1e..b115a8f 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1170,6 +1170,15 @@ All currently available key bindings: (notmuch-show-move-to-message-top) t)) +(defun notmuch-show-mapc (function) + "Iterate through all messages in the current thread with +`notmuch-show-goto-message-next' and call FUNCTION for side +effects." + (save-excursion +(goto-char (point-min)) +(loop do (funcall function) + while (notmuch-show-goto-message-next + ;; Functions relating to the visibility of messages and their ;; components. @@ -1222,6 +1231,18 @@ Some useful entries are: "Return the message id of the current message." (concat "id:\"" (notmuch-show-get-prop :id) "\"")) +(defun notmuch-show-get-messages-ids () + "Return all message ids of messages in the current thread." + (let ((message-ids)) +(notmuch-show-mapc + (lambda () (push (notmuch-show-get-message-id) message-ids))) +message-ids)) + +(defun notmuch-show-get-messages-ids-search () + "Return a search string for all message ids of messages in the +current thread." + (mapconcat 'identity (notmuch-show-get-messages-ids) " or ")) + ;; dme: Would it make sense to use a macro for many of these? (defun notmuch-show-get-filename () @@ -1494,7 +1515,7 @@ TAG-CHANGES is a list of tag operations for `notmuch-tag'." TAG-CHANGES is a list of tag operations for `notmuch-tag'." (interactive (notmuch-read-tag-changes nil notmuch-show-thread-id)) - (apply 'notmuch-tag notmuch-show-thread-id tag-changes) + (apply 'notmuch-tag (notmuch-show-get-messages-ids-search) tag-changes) (save-excursion (goto-char (point-min)) (loop do (let* ((current-tags (notmuch-show-get-tags)) -- 1.7.8.3
[PATCH v2 11/13] emacs: code cleanup in `notmuch-show-operate-all', no functional changes
Use `notmuch-show-mapc' function instead of a custom `loop'. --- emacs/notmuch-show.el | 13 ++--- 1 files changed, 6 insertions(+), 7 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index b115a8f..69381ac 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1516,13 +1516,12 @@ TAG-CHANGES is a list of tag operations for `notmuch-tag'." TAG-CHANGES is a list of tag operations for `notmuch-tag'." (interactive (notmuch-read-tag-changes nil notmuch-show-thread-id)) (apply 'notmuch-tag (notmuch-show-get-messages-ids-search) tag-changes) - (save-excursion -(goto-char (point-min)) -(loop do (let* ((current-tags (notmuch-show-get-tags)) - (new-tags (notmuch-update-tags current-tags tag-changes))) - (unless (equal current-tags new-tags) -(notmuch-show-set-tags new-tags))) - while (notmuch-show-goto-message-next + (notmuch-show-mapc + (lambda () + (let* ((current-tags (notmuch-show-get-tags)) + (new-tags (notmuch-update-tags current-tags tag-changes))) + (unless (equal current-tags new-tags) +(notmuch-show-set-tags new-tags)) (defun notmuch-show-add-tag () "Same as `notmuch-show-tag' but sets initial input to '+'." -- 1.7.8.3
[PATCH v2 12/13] emacs: accept empty tag list in `notmuch-tag'
Since `notmuch-tag' is a non-interactive function and hence is meant to be invoked programmatically, it should accept zero tags. Also, the tagging operations (bound to "*", "+", "-") would accept empty input without an error. --- emacs/notmuch.el | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 7e8f185..1b7a835 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -555,15 +555,15 @@ messages instead of running (notmuch-call-notmuch-process \"tag\" ..) directly, so that hooks specified in notmuch-before-tag-hook and notmuch-after-tag-hook will be run." ;; Perform some validation - (when (null tags) (error "No tags given")) (mapc (lambda (tag) (unless (string-match-p "^[-+]\\S-+$" tag) (error "Tag must be of the form `+this_tag' or `-that_tag'"))) tags) - (run-hooks 'notmuch-before-tag-hook) - (apply 'notmuch-call-notmuch-process -(append (list "tag") tags (list "--" query))) - (run-hooks 'notmuch-after-tag-hook)) + (unless (null tags) +(run-hooks 'notmuch-before-tag-hook) +(apply 'notmuch-call-notmuch-process "tag" + (append tags (list "--" query))) +(run-hooks 'notmuch-after-tag-hook))) (defcustom notmuch-before-tag-hook nil "Hooks that are run before tags of a message are modified. -- 1.7.8.3
[PATCH v2 13/13] NEWS: document Emacs UI tagging operations changes
--- NEWS | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/NEWS b/NEWS index 2acdce5..dc3acc4 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,24 @@ Reply to sender and search modes, 'r' has been bound to reply to sender, replacing reply to all, which now has key binding 'R'. +More robust and consistent tagging operations + + All tagging operations ("+", "-", "*") now accept multiple tags with + "+" or "-" prefix, like "*" operation in notmuch-search view before. + + "*" operation (`notmuch-show-tag-all`) is now available in + notmuch-show view. + + `Notmuch-show-{add,remove}-tag' functions no longer accept tag + argument, `notmuch-show-tag-message' should be used instead. Custom + bindings using these functions should be updated, e.g.: + +(notmuch-show-remove-tag "unread") + + should be changed to: + +(notmuch-show-tag-message "-unread") + Library changes --- -- 1.7.8.3
[PATCH v2 13/13] NEWS: document Emacs UI tagging operations changes
Quoth Dmitry Kurochkin on Jan 30 at 6:26 am: > --- > NEWS | 18 ++ > 1 files changed, 18 insertions(+), 0 deletions(-) > > diff --git a/NEWS b/NEWS > index 2acdce5..dc3acc4 100644 > --- a/NEWS > +++ b/NEWS > @@ -39,6 +39,24 @@ Reply to sender >and search modes, 'r' has been bound to reply to sender, replacing >reply to all, which now has key binding 'R'. > > +More robust and consistent tagging operations I don't think "robust" is the word you're looking for (same thing with some of the commit messages). In this context, I interpret "robust" as meaning "the tagging operations could do incorrect things and have been fixed". Maybe "flexible" or "capable"? > + > + All tagging operations ("+", "-", "*") now accept multiple tags with > + "+" or "-" prefix, like "*" operation in notmuch-search view before. Isn't this functionality of * also new in 0.12? > + > + "*" operation (`notmuch-show-tag-all`) is now available in Did you mean ' instead of ` at the end? > + notmuch-show view. > + > + `Notmuch-show-{add,remove}-tag' functions no longer accept tag > + argument, `notmuch-show-tag-message' should be used instead. Custom > + bindings using these functions should be updated, e.g.: > + > +(notmuch-show-remove-tag "unread") > + > + should be changed to: > + > +(notmuch-show-tag-message "-unread") > + > Library changes > --- >
[PATCH v2 03/13] emacs: make "+" and "-" tagging operations in notmuch-search more robust
On Sun, 29 Jan 2012 23:48:06 -0500, Austin Clements wrote: > Looking good. Just a few small points below. > > Quoth Dmitry Kurochkin on Jan 30 at 6:26 am: > > Before the change, "+" and "-" tagging operations in notmuch-search > > view accepted only a single tag. The patch makes them use the > > recently added `notmuch-read-tag-changes' function (renamed > > `notmuch-select-tags-with-completion'), which allows to enter multiple > > tags with "+" and "-" prefixes. So after the change, "+" and "-" > > bindings in notmuch-search view allow to both add and remove multiple > > tags. The only difference between "+" and "-" is the minibuffer > > initial input ("+" and "-" respectively). > > --- > > emacs/notmuch.el | 164 > > +++--- > > 1 files changed, 82 insertions(+), 82 deletions(-) > > > > diff --git a/emacs/notmuch.el b/emacs/notmuch.el > > index ff46617..90b594c 100644 > > --- a/emacs/notmuch.el > > +++ b/emacs/notmuch.el > > @@ -76,38 +76,57 @@ For example: > > (defvar notmuch-query-history nil > >"Variable to store minibuffer history for notmuch queries") > > > > -(defun notmuch-tag-completions ( prefixes search-terms) > > - (let ((tag-list > > -(split-string > > - (with-output-to-string > > - (with-current-buffer standard-output > > - (apply 'call-process notmuch-command nil t > > -nil "search-tags" search-terms))) > > - "\n+" t))) > > -(if (null prefixes) > > - tag-list > > - (apply #'append > > -(mapcar (lambda (tag) > > - (mapcar (lambda (prefix) > > -(concat prefix tag)) prefixes)) > > -tag-list) > > +(defun notmuch-tag-completions ( search-terms) > > + (split-string > > + (with-output-to-string > > + (with-current-buffer standard-output > > + (apply 'call-process notmuch-command nil t > > + nil "search-tags" search-terms))) > > + "\n+" t)) > > > > (defun notmuch-select-tag-with-completion (prompt search-terms) > > - (let ((tag-list (notmuch-tag-completions nil search-terms))) > > + (let ((tag-list (notmuch-tag-completions search-terms))) > > (completing-read prompt tag-list))) > > > > -(defun notmuch-select-tags-with-completion (prompt prefixes > > search-terms) > > - (let ((tag-list (notmuch-tag-completions prefixes search-terms)) > > - (crm-separator " ") > > - ;; By default, space is bound to "complete word" function. > > - ;; Re-bind it to insert a space instead. Note that > > - ;; still does the completion. > > - (crm-local-completion-map > > -(let ((map (make-sparse-keymap))) > > - (set-keymap-parent map crm-local-completion-map) > > - (define-key map " " 'self-insert-command) > > - map))) > > -(delete "" (completing-read-multiple prompt tag-list > > +(defun notmuch-read-tag-changes ( initial-input > > search-terms) > > + (let* ((all-tag-list (notmuch-tag-completions)) > > +(add-tag-list (mapcar (apply-partially 'concat "+") all-tag-list)) > > +(remove-tag-list (mapcar (apply-partially 'concat "-") > > + (if (null search-terms) > > + all-tag-list > > + (notmuch-tag-completions search-terms > > +(tag-list (append add-tag-list remove-tag-list)) > > +(crm-separator " ") > > +;; By default, space is bound to "complete word" function. > > +;; Re-bind it to insert a space instead. Note that > > +;; still does the completion. > > +(crm-local-completion-map > > + (let ((map (make-sparse-keymap))) > > + (set-keymap-parent map crm-local-completion-map) > > + (define-key map " " 'self-insert-command) > > + map))) > > +(delete "" (completing-read-multiple "Tags (+add -drop): " > > + tag-list nil nil initial-input > > + > > +(defun notmuch-update-tags (tags tag-changes) > > + "Return a copy of TAGS with additions and removals from TAG-CHANGES. > > + > > +TAG-CHANGES must be a list of tags names, each prefixed with > > +either a \"+\" to indicate the tag should be added to TAGS if not > > +present or a \"-\" to indicate that the tag should be removed > > +from TAGS if present." > > + (let ((result-tags (copy-sequence tags))) > > +(dolist (tag-change tag-changes) > > + (unless (string= tag-change "") > > This function should give the "must be of the form" error for empty > strings, rather than silently ignoring them. It turns out > `string-to-char' on an empty string is fine (it returns 0, which will > trigger the error), but `substring' isn't. Perhaps move the unless > into the let before, like > (let ((op (string-to-char tag-change)) >(tag (unless (string= tag-change "") (substring tag-change 1 > done > > + (let ((op (string-to-char tag-change)) > > + (tag (substring tag-change 1))) > > + (case op > > + (?+ (unless
[PATCH v2 13/13] NEWS: document Emacs UI tagging operations changes
On Mon, 30 Jan 2012 00:04:02 -0500, Austin Clements wrote: > Quoth Dmitry Kurochkin on Jan 30 at 6:26 am: > > --- > > NEWS | 18 ++ > > 1 files changed, 18 insertions(+), 0 deletions(-) > > > > diff --git a/NEWS b/NEWS > > index 2acdce5..dc3acc4 100644 > > --- a/NEWS > > +++ b/NEWS > > @@ -39,6 +39,24 @@ Reply to sender > >and search modes, 'r' has been bound to reply to sender, replacing > >reply to all, which now has key binding 'R'. > > > > +More robust and consistent tagging operations > > I don't think "robust" is the word you're looking for (same thing with > some of the commit messages). In this context, I interpret "robust" > as meaning "the tagging operations could do incorrect things and have > been fixed". Maybe "flexible" or "capable"? > Changed to "flexible". > > + > > + All tagging operations ("+", "-", "*") now accept multiple tags with > > + "+" or "-" prefix, like "*" operation in notmuch-search view before. > > Isn't this functionality of * also new in 0.12? > No, "*" in notmuch-search was always working this way. > > + > > + "*" operation (`notmuch-show-tag-all`) is now available in > > Did you mean ' instead of ` at the end? > No. Regards, Dmitry > > + notmuch-show view. > > + > > + `Notmuch-show-{add,remove}-tag' functions no longer accept tag > > + argument, `notmuch-show-tag-message' should be used instead. Custom > > + bindings using these functions should be updated, e.g.: > > + > > +(notmuch-show-remove-tag "unread") > > + > > + should be changed to: > > + > > +(notmuch-show-tag-message "-unread") > > + > > Library changes > > --- > >
[PATCH v2 10/13] emacs: use message ids instead of thread id in `notmuch-show-operate-all'
On Sun, 29 Jan 2012 23:57:09 -0500, Austin Clements wrote: > Quoth Dmitry Kurochkin on Jan 30 at 6:26 am: > > Before the change, `notmuch-show-operate-all' used thread id for > > notmuch-show-tag-all? > ouch > > "notmuch tag" search. This could result in tagging unexpected > > messages that were added to the thread after the notmuch-show buffer > > was created. The patch changes `notmuch-show-operate-all' to use ids > > of shown messages to fix this. > > --- > > If you move this patch before the one that introduces > notmuch-show-tag-all, you could do it this way from the beginning. > This patch can not be moved before the one that introduces `notmuch-show-tag-all', because it changes `notmuch-show-tag-all'. Perhaps you meant to factor out `notmuch-show-mapc' and `notmuch-show-get-messages-ids-search' into a separate patch(es), but I am too lazy. I merged this patch into the one which introduces `notmuch-show-tag-all'. Regards, Dmitry > > emacs/notmuch-show.el | 23 ++- > > 1 files changed, 22 insertions(+), 1 deletions(-) > > > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > > index 0d90c1e..b115a8f 100644 > > --- a/emacs/notmuch-show.el > > +++ b/emacs/notmuch-show.el > > @@ -1170,6 +1170,15 @@ All currently available key bindings: > > (notmuch-show-move-to-message-top) > > t)) > > > > +(defun notmuch-show-mapc (function) > > + "Iterate through all messages in the current thread with > > +`notmuch-show-goto-message-next' and call FUNCTION for side > > +effects." > > + (save-excursion > > +(goto-char (point-min)) > > +(loop do (funcall function) > > + while (notmuch-show-goto-message-next > > + > > ;; Functions relating to the visibility of messages and their > > ;; components. > > > > @@ -1222,6 +1231,18 @@ Some useful entries are: > >"Return the message id of the current message." > >(concat "id:\"" (notmuch-show-get-prop :id) "\"")) > > > > +(defun notmuch-show-get-messages-ids () > > + "Return all message ids of messages in the current thread." > > + (let ((message-ids)) > > +(notmuch-show-mapc > > + (lambda () (push (notmuch-show-get-message-id) message-ids))) > > +message-ids)) > > + > > +(defun notmuch-show-get-messages-ids-search () > > + "Return a search string for all message ids of messages in the > > +current thread." > > + (mapconcat 'identity (notmuch-show-get-messages-ids) " or ")) > > + > > ;; dme: Would it make sense to use a macro for many of these? > > > > (defun notmuch-show-get-filename () > > @@ -1494,7 +1515,7 @@ TAG-CHANGES is a list of tag operations for > > `notmuch-tag'." > > > > TAG-CHANGES is a list of tag operations for `notmuch-tag'." > >(interactive (notmuch-read-tag-changes nil notmuch-show-thread-id)) > > - (apply 'notmuch-tag notmuch-show-thread-id tag-changes) > > + (apply 'notmuch-tag (notmuch-show-get-messages-ids-search) tag-changes) > >(save-excursion > > (goto-char (point-min)) > > (loop do (let* ((current-tags (notmuch-show-get-tags))
emacs: more flexible and consistent tagging operations
Changes: v3: * merged 3 `notmuch-show-tag-all'-related patches into one * add patch to clean up tagging function argument names * fix other comments from Austin's reviews [5,6] v2: * add patch to remove "No tags given" error from `notmuch-tag' as suggested by Austin in [1] * split patch 3 in two (search and show) for easier review * add patch with NEWS entry * rename `notmuch-{search,show}-operate-all' to `notmuch-{search,show}-tag-all' * fix other comments from Austin's reviews [2,3,4] Regards, Dmitry [1] id:"20120129231650.GK17991 at mit.edu" [2] id:"20120129225710.GG17991 at mit.edu" [3] id:"20120129230229.GI17991 at mit.edu" [4] id:"20120129231120.GJ17991 at mit.edu" [5] id:"20120130044806.GM17991 at mit.edu" [6] id:"20120130050402.GP17991 at mit.edu"
[PATCH v3 01/12] emacs: move tag format validation to `notmuch-tag' function
Before the change, tag format validation was done in `notmuch-search-operate-all' function only. The patch moves it down to `notmuch-tag', so that all users of that function get input validation. --- emacs/notmuch.el | 12 ++-- 1 files changed, 6 insertions(+), 6 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 72f78ed..84d7d0a 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -522,6 +522,12 @@ Note: Other code should always use this function alter tags of messages instead of running (notmuch-call-notmuch-process \"tag\" ..) directly, so that hooks specified in notmuch-before-tag-hook and notmuch-after-tag-hook will be run." + ;; Perform some validation + (when (null tags) (error "No tags given")) + (mapc (lambda (tag) + (unless (string-match-p "^[-+][-+_.[:word:]]+$" tag) + (error "Tag must be of the form `+this_tag' or `-that_tag'"))) + tags) (run-hooks 'notmuch-before-tag-hook) (apply 'notmuch-call-notmuch-process (append (list "tag") tags (list "--" query))) @@ -890,12 +896,6 @@ characters as well as `_.+-'. (interactive (notmuch-select-tags-with-completion "Operations (+add -drop): notmuch tag " '("+" "-"))) - ;; Perform some validation - (when (null actions) (error "No operations given")) - (mapc (lambda (action) - (unless (string-match-p "^[-+][-+_.[:word:]]+$" action) - (error "Action must be of the form `+this_tag' or `-that_tag'"))) - actions) (apply 'notmuch-tag notmuch-search-query-string actions)) (defun notmuch-search-buffer-title (query) -- 1.7.8.3
[PATCH v3 02/12] emacs: remove text properties from `notmuch-search-get-tags' result
--- emacs/notmuch.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 84d7d0a..ff46617 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -577,7 +577,7 @@ the messages that were tagged" (let ((beg (+ (point) 1))) (re-search-forward ")") (let ((end (- (point) 1))) - (split-string (buffer-substring beg end)) + (split-string (buffer-substring-no-properties beg end)) (defun notmuch-search-get-tags-region (beg end) (save-excursion -- 1.7.8.3
[PATCH v3 04/12] emacs: make "+" and "-" tagging operations in notmuch-show more flexible
Before the change, "+" and "-" tagging operations in notmuch-show view accepted only a single tag. The patch makes them use the recently added `notmuch-read-tag-changes' function, which allows to enter multiple tags with "+" and "-" prefixes. So after the change, "+" and "-" bindings in notmuch-show view allow to both add and remove multiple tags. The only difference between "+" and "-" is the minibuffer initial input ("+" and "-" respectively). --- emacs/notmuch-show.el | 64 +--- 1 files changed, 23 insertions(+), 41 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 84ac624..11dab2d 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -38,8 +38,9 @@ (declare-function notmuch-call-notmuch-process "notmuch" ( args)) (declare-function notmuch-fontify-headers "notmuch" nil) -(declare-function notmuch-select-tag-with-completion "notmuch" (prompt search-terms)) +(declare-function notmuch-read-tag-changes "notmuch" ( initial-input search-terms)) (declare-function notmuch-search-show-thread "notmuch" nil) +(declare-function notmuch-update-tags "notmuch" (current-tags tag-changes)) (defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date") "Headers that should be shown in a message, in this order. @@ -1267,7 +1268,7 @@ Some useful entries are: (defun notmuch-show-mark-read () "Mark the current message as read." - (notmuch-show-remove-tag "unread")) + (notmuch-show-tag-message "-unread")) ;; Functions for getting attributes of several messages in the current ;; thread. @@ -1470,51 +1471,32 @@ than only the current message." (message (format "Command '%s' exited abnormally with code %d" shell-command exit-code -(defun notmuch-show-add-tags-worker (current-tags add-tags) - "Add to `current-tags' with any tags from `add-tags' not -currently present and return the result." - (let ((result-tags (copy-sequence current-tags))) -(mapc (lambda (add-tag) - (unless (member add-tag current-tags) - (setq result-tags (push add-tag result-tags - add-tags) -(sort result-tags 'string<))) - -(defun notmuch-show-del-tags-worker (current-tags del-tags) - "Remove any tags in `del-tags' from `current-tags' and return -the result." - (let ((result-tags (copy-sequence current-tags))) -(mapc (lambda (del-tag) - (setq result-tags (delete del-tag result-tags))) - del-tags) -result-tags)) - -(defun notmuch-show-add-tag ( toadd) - "Add a tag to the current message." - (interactive - (list (notmuch-select-tag-with-completion "Tag to add: "))) +(defun notmuch-show-tag-message ( tag-changes) + "Change tags for the current message. +TAG-CHANGES is a list of tag operations for `notmuch-tag'." (let* ((current-tags (notmuch-show-get-tags)) -(new-tags (notmuch-show-add-tags-worker current-tags toadd))) - +(new-tags (notmuch-update-tags current-tags tag-changes))) (unless (equal current-tags new-tags) - (apply 'notmuch-tag (notmuch-show-get-message-id) -(mapcar (lambda (s) (concat "+" s)) toadd)) + (apply 'notmuch-tag (notmuch-show-get-message-id) tag-changes) (notmuch-show-set-tags new-tags -(defun notmuch-show-remove-tag ( toremove) - "Remove a tag from the current message." - (interactive - (list (notmuch-select-tag-with-completion - "Tag to remove: " (notmuch-show-get-message-id +(defun notmuch-show-tag ( initial-input) + "Change tags for the current message, read input from the minibuffer." + (interactive) + (let ((tag-changes (notmuch-read-tag-changes + initial-input (notmuch-show-get-message-id +(apply 'notmuch-show-tag-message tag-changes))) - (let* ((current-tags (notmuch-show-get-tags)) -(new-tags (notmuch-show-del-tags-worker current-tags toremove))) +(defun notmuch-show-add-tag () + "Same as `notmuch-show-tag' but sets initial input to '+'." + (interactive) + (notmuch-show-tag "+")) -(unless (equal current-tags new-tags) - (apply 'notmuch-tag (notmuch-show-get-message-id) -(mapcar (lambda (s) (concat "-" s)) toremove)) - (notmuch-show-set-tags new-tags +(defun notmuch-show-remove-tag () + "Same as `notmuch-show-tag' but sets initial input to '-'." + (interactive) + (notmuch-show-tag "-")) (defun notmuch-show-toggle-headers () "Toggle the visibility of the current message headers." @@ -1559,7 +1541,7 @@ argument, hide all of the messages." (defun notmuch-show-archive-thread-internal (show-next) ;; Remove the tag from the current set of messages. (goto-char (point-min)) - (loop do (notmuch-show-remove-tag "inbox") + (loop do (notmuch-show-tag-message "-inbox") until (not (notmuch-show-goto-message-next))) ;; Move to the next item in the search results, if any. (let ((parent-buffer notmuch-show-parent-buffer)) --
[PATCH v3 03/12] emacs: make "+" and "-" tagging operations in notmuch-search more flexible
Before the change, "+" and "-" tagging operations in notmuch-search view accepted only a single tag. The patch makes them use the recently added `notmuch-read-tag-changes' function (renamed `notmuch-select-tags-with-completion'), which allows to enter multiple tags with "+" and "-" prefixes. So after the change, "+" and "-" bindings in notmuch-search view allow to both add and remove multiple tags. The only difference between "+" and "-" is the minibuffer initial input ("+" and "-" respectively). --- emacs/notmuch.el | 163 +++--- 1 files changed, 81 insertions(+), 82 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index ff46617..ce8bef6 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -76,38 +76,56 @@ For example: (defvar notmuch-query-history nil "Variable to store minibuffer history for notmuch queries") -(defun notmuch-tag-completions ( prefixes search-terms) - (let ((tag-list -(split-string - (with-output-to-string - (with-current-buffer standard-output - (apply 'call-process notmuch-command nil t -nil "search-tags" search-terms))) - "\n+" t))) -(if (null prefixes) - tag-list - (apply #'append -(mapcar (lambda (tag) - (mapcar (lambda (prefix) -(concat prefix tag)) prefixes)) -tag-list) +(defun notmuch-tag-completions ( search-terms) + (split-string + (with-output-to-string + (with-current-buffer standard-output + (apply 'call-process notmuch-command nil t + nil "search-tags" search-terms))) + "\n+" t)) (defun notmuch-select-tag-with-completion (prompt search-terms) - (let ((tag-list (notmuch-tag-completions nil search-terms))) + (let ((tag-list (notmuch-tag-completions search-terms))) (completing-read prompt tag-list))) -(defun notmuch-select-tags-with-completion (prompt prefixes search-terms) - (let ((tag-list (notmuch-tag-completions prefixes search-terms)) - (crm-separator " ") - ;; By default, space is bound to "complete word" function. - ;; Re-bind it to insert a space instead. Note that - ;; still does the completion. - (crm-local-completion-map -(let ((map (make-sparse-keymap))) - (set-keymap-parent map crm-local-completion-map) - (define-key map " " 'self-insert-command) - map))) -(delete "" (completing-read-multiple prompt tag-list +(defun notmuch-read-tag-changes ( initial-input search-terms) + (let* ((all-tag-list (notmuch-tag-completions)) +(add-tag-list (mapcar (apply-partially 'concat "+") all-tag-list)) +(remove-tag-list (mapcar (apply-partially 'concat "-") + (if (null search-terms) + all-tag-list + (notmuch-tag-completions search-terms +(tag-list (append add-tag-list remove-tag-list)) +(crm-separator " ") +;; By default, space is bound to "complete word" function. +;; Re-bind it to insert a space instead. Note that +;; still does the completion. +(crm-local-completion-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map crm-local-completion-map) + (define-key map " " 'self-insert-command) + map))) +(delete "" (completing-read-multiple "Tags (+add -drop): " + tag-list nil nil initial-input + +(defun notmuch-update-tags (tags tag-changes) + "Return a copy of TAGS with additions and removals from TAG-CHANGES. + +TAG-CHANGES must be a list of tags names, each prefixed with +either a \"+\" to indicate the tag should be added to TAGS if not +present or a \"-\" to indicate that the tag should be removed +from TAGS if present." + (let ((result-tags (copy-sequence tags))) +(dolist (tag-change tag-changes) + (let ((op (string-to-char tag-change)) + (tag (unless (string= tag-change "") (substring tag-change 1 + (case op + (?+ (unless (member tag result-tags) + (push tag result-tags))) + (?- (setq result-tags (delete tag result-tags))) + (otherwise + (error "Changed tag must be of the form `+this_tag' or `-that_tag'") +(sort result-tags 'string<))) (defun notmuch-foreach-mime-part (function mm-handle) (cond ((stringp (car mm-handle)) @@ -447,6 +465,10 @@ Complete list of currently available key bindings: "Return a list of threads for the current region" (notmuch-search-properties-in-region 'notmuch-search-thread-id beg end)) +(defun notmuch-search-find-thread-id-region-search (beg end) + "Return a search string for threads for the current region" + (mapconcat 'identity (notmuch-search-find-thread-id-region beg end) " or ")) + (defun notmuch-search-find-authors () "Return the authors for the
[PATCH v3 05/12] test: fix emacs tests after tagging operations changes
After the recent tagging operations changes, functions bound to "+" and "-" in notmuch-search and notmuch-show views always read input from the minibuffer. Use kbd macros instead of calling them directly. --- test/emacs | 20 ++-- 1 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/emacs b/test/emacs index 8ca4c8a..b9c0e02 100755 --- a/test/emacs +++ b/test/emacs @@ -101,26 +101,26 @@ test_begin_subtest "Add tag from search view" os_x_darwin_thread=$(notmuch search --output=threads id:ddd65cda0911171950o4eea4389v86de9525e46052d3 at mail.gmail.com) test_emacs "(notmuch-search \"$os_x_darwin_thread\") (notmuch-test-wait) - (notmuch-search-add-tag \"tag-from-search-view\")" + (execute-kbd-macro \"+tag-from-search-view\")" output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-search-view unread)" test_begin_subtest "Remove tag from search view" test_emacs "(notmuch-search \"$os_x_darwin_thread\") (notmuch-test-wait) - (notmuch-search-remove-tag \"tag-from-search-view\")" + (execute-kbd-macro \"-tag-from-search-view\")" output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)" test_begin_subtest "Add tag from notmuch-show view" test_emacs "(notmuch-show \"$os_x_darwin_thread\") - (notmuch-show-add-tag \"tag-from-show-view\")" + (execute-kbd-macro \"+tag-from-show-view\")" output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox tag-from-show-view unread)" test_begin_subtest "Remove tag from notmuch-show view" test_emacs "(notmuch-show \"$os_x_darwin_thread\") - (notmuch-show-remove-tag \"tag-from-show-view\")" + (execute-kbd-macro \"-tag-from-show-view\")" output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)" @@ -128,14 +128,14 @@ test_begin_subtest "Message with .. in Message-Id:" add_message [id]=123..456 at example '[subject]="Message with .. in Message-Id"' test_emacs '(notmuch-search "id:\"123..456 at example\"") (notmuch-test-wait) - (notmuch-search-add-tag "search-add") - (notmuch-search-add-tag "search-remove") - (notmuch-search-remove-tag "search-remove") + (execute-kbd-macro "+search-add") + (execute-kbd-macro "+search-remove") + (execute-kbd-macro "-search-remove") (notmuch-show "id:\"123..456 at example\"") (notmuch-test-wait) - (notmuch-show-add-tag "show-add") - (notmuch-show-add-tag "show-remove") - (notmuch-show-remove-tag "show-remove")' + (execute-kbd-macro "+show-add") + (execute-kbd-macro "+show-remove") + (execute-kbd-macro "-show-remove")' output=$(notmuch search 'id:"123..456 at example"' | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2001-01-05 [1/1] Notmuch Test Suite; Message with .. in Message-Id (inbox search-add show-add)" -- 1.7.8.3
[PATCH v3 06/12] emacs: rename `notmuch-search-operate-all' to `notmuch-search-tag-all'
`Notmuch-search-tag-all' is more clear and consistent with other tagging function names. --- emacs/notmuch.el |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index ce8bef6..7d06109 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -270,7 +270,7 @@ For a mouse binding, return nil." (define-key map "t" 'notmuch-search-filter-by-tag) (define-key map "f" 'notmuch-search-filter) (define-key map [mouse-1] 'notmuch-search-show-thread) -(define-key map "*" 'notmuch-search-operate-all) +(define-key map "*" 'notmuch-search-tag-all) (define-key map "a" 'notmuch-search-archive-thread) (define-key map "-" 'notmuch-search-remove-tag) (define-key map "+" 'notmuch-search-add-tag) @@ -419,7 +419,7 @@ any tags). Pressing \\[notmuch-search-show-thread] on any line displays that thread. The '\\[notmuch-search-add-tag]' and '\\[notmuch-search-remove-tag]' keys can be used to add or remove tags from a thread. The '\\[notmuch-search-archive-thread]' key is a convenience for archiving a thread (removing the \"inbox\" -tag). The '\\[notmuch-search-operate-all]' key can be used to add or remove a tag from all +tag). The '\\[notmuch-search-tag-all]' key can be used to add or remove a tag from all threads in the current buffer. Other useful commands are '\\[notmuch-search-filter]' for filtering the current search @@ -883,7 +883,7 @@ non-authors is found, assume that all of the authors match." (goto-char found-target))) (delete-process proc -(defun notmuch-search-operate-all ( actions) +(defun notmuch-search-tag-all ( actions) "Add/remove tags from all matching messages. This command adds or removes tags from all messages matching the -- 1.7.8.3
[PATCH v3 07/12] emacs: add "*" binding for notmuch-show view
The patch adds `notmuch-show-tag-all' function bound to "*" in notmuch-show view. The function is similar to the `notmuch-search-tag-all' function for the notmuch-search view: it changes tags for all messages in the current thread. --- emacs/notmuch-show.el | 35 +++ 1 files changed, 35 insertions(+), 0 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 11dab2d..69381ac 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1073,6 +1073,7 @@ thread id. If a prefix is given, crypto processing is toggled." (define-key map "c" 'notmuch-show-stash-map) (define-key map "=" 'notmuch-show-refresh-view) (define-key map "h" 'notmuch-show-toggle-headers) + (define-key map "*" 'notmuch-show-tag-all) (define-key map "-" 'notmuch-show-remove-tag) (define-key map "+" 'notmuch-show-add-tag) (define-key map "x" 'notmuch-show-archive-thread-then-exit) @@ -1169,6 +1170,15 @@ All currently available key bindings: (notmuch-show-move-to-message-top) t)) +(defun notmuch-show-mapc (function) + "Iterate through all messages in the current thread with +`notmuch-show-goto-message-next' and call FUNCTION for side +effects." + (save-excursion +(goto-char (point-min)) +(loop do (funcall function) + while (notmuch-show-goto-message-next + ;; Functions relating to the visibility of messages and their ;; components. @@ -1221,6 +1231,18 @@ Some useful entries are: "Return the message id of the current message." (concat "id:\"" (notmuch-show-get-prop :id) "\"")) +(defun notmuch-show-get-messages-ids () + "Return all message ids of messages in the current thread." + (let ((message-ids)) +(notmuch-show-mapc + (lambda () (push (notmuch-show-get-message-id) message-ids))) +message-ids)) + +(defun notmuch-show-get-messages-ids-search () + "Return a search string for all message ids of messages in the +current thread." + (mapconcat 'identity (notmuch-show-get-messages-ids) " or ")) + ;; dme: Would it make sense to use a macro for many of these? (defun notmuch-show-get-filename () @@ -1488,6 +1510,19 @@ TAG-CHANGES is a list of tag operations for `notmuch-tag'." initial-input (notmuch-show-get-message-id (apply 'notmuch-show-tag-message tag-changes))) +(defun notmuch-show-tag-all ( tag-changes) + "Change tags for all messages in the current thread. + +TAG-CHANGES is a list of tag operations for `notmuch-tag'." + (interactive (notmuch-read-tag-changes nil notmuch-show-thread-id)) + (apply 'notmuch-tag (notmuch-show-get-messages-ids-search) tag-changes) + (notmuch-show-mapc + (lambda () + (let* ((current-tags (notmuch-show-get-tags)) + (new-tags (notmuch-update-tags current-tags tag-changes))) + (unless (equal current-tags new-tags) +(notmuch-show-set-tags new-tags)) + (defun notmuch-show-add-tag () "Same as `notmuch-show-tag' but sets initial input to '+'." (interactive) -- 1.7.8.3
[PATCH v3 08/12] emacs: separate history for operations which accept single and multiple tags
Some tag-related operations accept a single tag without prefix (`notmuch-select-tag-with-completion'), others accept multiple tags prefixed with '+' or '-' (`notmuch-read-tag-changes'). Before the change, both functions used a single default minibuffer history. This is inconvenient because you have to skip options with incompatible format when going through the history. The patch adds separate history lists for the two functions. Note that functions that accept the same input format (e.g. "+", "-", "*") share the history list as before. --- emacs/notmuch.el | 13 +++-- 1 files changed, 11 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 7d06109..0a3bd17 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -76,6 +76,14 @@ For example: (defvar notmuch-query-history nil "Variable to store minibuffer history for notmuch queries") +(defvar notmuch-select-tag-history nil + "Variable to store minibuffer history for +`notmuch-select-tag-with-completion' function.") + +(defvar notmuch-read-tag-changes-history nil + "Variable to store minibuffer history for +`notmuch-read-tag-changes' function.") + (defun notmuch-tag-completions ( search-terms) (split-string (with-output-to-string @@ -86,7 +94,7 @@ For example: (defun notmuch-select-tag-with-completion (prompt search-terms) (let ((tag-list (notmuch-tag-completions search-terms))) -(completing-read prompt tag-list))) +(completing-read prompt tag-list nil nil nil 'notmuch-select-tag-history))) (defun notmuch-read-tag-changes ( initial-input search-terms) (let* ((all-tag-list (notmuch-tag-completions)) @@ -106,7 +114,8 @@ For example: (define-key map " " 'self-insert-command) map))) (delete "" (completing-read-multiple "Tags (+add -drop): " - tag-list nil nil initial-input + tag-list nil nil initial-input + 'notmuch-read-tag-changes-history (defun notmuch-update-tags (tags tag-changes) "Return a copy of TAGS with additions and removals from TAG-CHANGES. -- 1.7.8.3
[PATCH v3 09/12] emacs: relax tag syntax check in `notmuch-tag' function
The tag syntax check in `notmuch-tag' function was too strict and did not allow nmbug tags with "::". Since the check is done for all tagging operations in Emacs UI, this basically means that no nmbug tags can be changed. The patch relaxes the tag syntax check to allow any tag names that do not include whitespace characters. --- emacs/notmuch.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 0a3bd17..2332c42 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -556,7 +556,7 @@ notmuch-after-tag-hook will be run." ;; Perform some validation (when (null tags) (error "No tags given")) (mapc (lambda (tag) - (unless (string-match-p "^[-+][-+_.[:word:]]+$" tag) + (unless (string-match-p "^[-+]\\S-+$" tag) (error "Tag must be of the form `+this_tag' or `-that_tag'"))) tags) (run-hooks 'notmuch-before-tag-hook) -- 1.7.8.3
[PATCH v3 10/12] emacs: accept empty tag list in `notmuch-tag'
Since `notmuch-tag' is a non-interactive function and hence is meant to be invoked programmatically, it should accept zero tags. Also, the tagging operations (bound to "*", "+", "-") would accept empty input without an error. --- emacs/notmuch.el | 10 +- 1 files changed, 5 insertions(+), 5 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index 2332c42..c464c3c 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -554,15 +554,15 @@ messages instead of running (notmuch-call-notmuch-process \"tag\" ..) directly, so that hooks specified in notmuch-before-tag-hook and notmuch-after-tag-hook will be run." ;; Perform some validation - (when (null tags) (error "No tags given")) (mapc (lambda (tag) (unless (string-match-p "^[-+]\\S-+$" tag) (error "Tag must be of the form `+this_tag' or `-that_tag'"))) tags) - (run-hooks 'notmuch-before-tag-hook) - (apply 'notmuch-call-notmuch-process -(append (list "tag") tags (list "--" query))) - (run-hooks 'notmuch-after-tag-hook)) + (unless (null tags) +(run-hooks 'notmuch-before-tag-hook) +(apply 'notmuch-call-notmuch-process "tag" + (append tags (list "--" query))) +(run-hooks 'notmuch-after-tag-hook))) (defcustom notmuch-before-tag-hook nil "Hooks that are run before tags of a message are modified. -- 1.7.8.3
[PATCH v3 11/12] emacs: s/tags/tag-changes/ for arguments of tagging functions
This makes the argument names more consistent and clear. The following functions changed: `notmuch-tag', `notmuch-search-tag-thread', `notmuch-search-tag-region' and `notmuch-search-tag-all'. --- emacs/notmuch.el | 33 + 1 files changed, 17 insertions(+), 16 deletions(-) diff --git a/emacs/notmuch.el b/emacs/notmuch.el index c464c3c..fa62019 100644 --- a/emacs/notmuch.el +++ b/emacs/notmuch.el @@ -543,25 +543,26 @@ and will also appear in a buffer named \"*Notmuch errors*\"." (error (buffer-substring beg end)) )) -(defun notmuch-tag (query tags) - "Add/remove tags in TAGS to messages matching QUERY. +(defun notmuch-tag (query tag-changes) + "Add/remove tags in TAG-CHANGES to messages matching QUERY. -TAGS should be a list of strings of the form \"+TAG\" or \"-TAG\" and -QUERY should be a string containing the search-query. +TAG-CHANGES should be a list of strings of the form \"+tag\" or +\"-tag\" and QUERY should be a string containing the +search-query. Note: Other code should always use this function alter tags of messages instead of running (notmuch-call-notmuch-process \"tag\" ..) directly, so that hooks specified in notmuch-before-tag-hook and notmuch-after-tag-hook will be run." ;; Perform some validation - (mapc (lambda (tag) - (unless (string-match-p "^[-+]\\S-+$" tag) + (mapc (lambda (tag-change) + (unless (string-match-p "^[-+]\\S-+$" tag-change) (error "Tag must be of the form `+this_tag' or `-that_tag'"))) - tags) - (unless (null tags) + tag-changes) + (unless (null tag-changes) (run-hooks 'notmuch-before-tag-hook) (apply 'notmuch-call-notmuch-process "tag" - (append tags (list "--" query))) + (append tag-changes (list "--" query))) (run-hooks 'notmuch-after-tag-hook))) (defcustom notmuch-before-tag-hook nil @@ -621,26 +622,26 @@ the messages that were tagged" (forward-line 1)) output))) -(defun notmuch-search-tag-thread ( tags) +(defun notmuch-search-tag-thread ( tag-changes) "Change tags for the currently selected thread. See `notmuch-search-tag-region' for details." - (apply 'notmuch-search-tag-region (point) (point) tags)) + (apply 'notmuch-search-tag-region (point) (point) tag-changes)) -(defun notmuch-search-tag-region (beg end tags) +(defun notmuch-search-tag-region (beg end tag-changes) "Change tags for threads in the given region. TAGS is a list of tag operations for `notmuch-tag'. The tags are added or removed for all threads in the region from BEG to END." (let ((search-string (notmuch-search-find-thread-id-region-search beg end))) -(apply 'notmuch-tag search-string tags) +(apply 'notmuch-tag search-string tag-changes) (save-excursion (let ((last-line (line-number-at-pos end)) (max-line (- (line-number-at-pos (point-max)) 2))) (goto-char beg) (while (<= (line-number-at-pos) (min last-line max-line)) (notmuch-search-set-tags - (notmuch-update-tags (notmuch-search-get-tags) tags)) + (notmuch-update-tags (notmuch-search-get-tags) tag-changes)) (forward-line)) (defun notmuch-search-tag ( initial-input) @@ -892,7 +893,7 @@ non-authors is found, assume that all of the authors match." (goto-char found-target))) (delete-process proc -(defun notmuch-search-tag-all ( actions) +(defun notmuch-search-tag-all ( tag-changes) "Add/remove tags from all matching messages. This command adds or removes tags from all messages matching the @@ -904,7 +905,7 @@ Each character of the tag name may consist of alphanumeric characters as well as `_.+-'. " (interactive (notmuch-read-tag-changes)) - (apply 'notmuch-tag notmuch-search-query-string actions)) + (apply 'notmuch-tag notmuch-search-query-string tag-changes)) (defun notmuch-search-buffer-title (query) "Returns the title for a buffer with notmuch search results." -- 1.7.8.3
[PATCH v3 12/12] NEWS: document Emacs UI tagging operations changes
--- NEWS | 18 ++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/NEWS b/NEWS index 2acdce5..7506d68 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,24 @@ Reply to sender and search modes, 'r' has been bound to reply to sender, replacing reply to all, which now has key binding 'R'. +More flexible and consistent tagging operations + + All tagging operations ("+", "-", "*") now accept multiple tags with + "+" or "-" prefix, like "*" operation in notmuch-search view before. + + "*" operation (`notmuch-show-tag-all') is now available in + notmuch-show view. + + `Notmuch-show-{add,remove}-tag' functions no longer accept tag + argument, `notmuch-show-tag-message' should be used instead. Custom + bindings using these functions should be updated, e.g.: + +(notmuch-show-remove-tag "unread") + + should be changed to: + +(notmuch-show-tag-message "-unread") + Library changes --- -- 1.7.8.3
[PATCH] emacs: globally replace non-branching "(if COND (progn ..." with "(when ..."
On Sat, 28 Jan 2012 08:41:36 -0400, David Bremner wrote: > On Sat, 14 Jan 2012 10:17:18 +0100, Pieter Praet wrote: > > Less code, same results, without sacrificing readability. > > > > This looks OK, although the re-indenting makes these kind of changes > painful to review (not that I'm suggesting we should re-indent, just > some random complaining). > You can use `diff-refine-hunk' to see what the actual changes are. Try this: #+begin_src emacs-lisp (global-set-key (kbd "C-c /") (lambda() "Refine display of unified diff hunks" (interactive) (save-excursion (goto-char (point-min)) (while (re-search-forward diff-hunk-header-re-unified nil t) (diff-refine-hunk) #+end_src Work pretty much *anywhere*. Note: it does NOT work in `notmuch-show-mode' (not even with `notmuch-wash-convert-inline-patch-to-part' disabled), but this is easily solved by first running `notmuch-show-view-raw-message' ("V") and `diff-mode' (to fontify the buffer)... > d > > Peace -- Pieter
Bug?: notmuch-search-show-thread shows several threads; only one containing matching messages
On Mon, 30 Jan 2012 00:42:14 +0100, Gregor Zattler wrote: > Hi Pieter, notmuch developers > * Pieter Praet [26. Jan. 2012]: > > On Thu, 26 Jan 2012 13:44:50 +0100, Gregor Zattler > > wrote: > >>|> [2] grep -I "^Message-Id:" /tmp/thread-I-m-interested-in.mbox |sed > >> -e "s/Message-Id: $//" >really.mid > >>|> grep -I -F really.mid rest.mbox > >>|> --> no match > >> > > > > Did you mean to do case-insensitive grep? ('-i' instead of '-I'). > > Yes I did mean case-insensitive search and the `-I' is the result > of a misguided abbrev... Sorry about this. > > > Also, the '-F' option expects input on stdin, not a filename. > > No, this is -F instead of -f and means --fixed-strings. > And as I said, `-F' requires input on stdin, like this: `grep -F "$(cat really.mid)" rest.mbox' Otherwise [1] you're grepping for the pattern 'really.mid' instead of for the patterns specified *in* 'really.mid', so naturally, you aren't getting any results. > > Try this (with all individual threads split into separate mboxes): > > > > #+begin_src sh > > for i in $(ls *.mbox) ; do > > grep -i '^Message-Id:' "${i}" | \ > > sed -e 's/^.\{13\}//' -e 's/>$//' \ > > > "${i}.mids" > > done > > for i in $(ls *.mids) ; do > > echo "## Grepping for ${i}'s Message-Ids" > > grep -i -F "$(cat ${i})" *.mbox > > done > > #+end_src > > Thanks I did it "manual". > > > Here's another couple of threads squashed into a single one: > > - [O] [Use Question] Capture and long lines > > - id:"BANLkTikoF4tXuNLLufRzNSD6k2ZYs7sUcg at mail.gmail.com" > > - [O] Worg update > > - id:"m1wrfiz3ch.fsf at tsdye.com" > > - [O] Table formula to convert hex to dec > > - id:"20110724080054.GB16388 at x201" > > - [O] ICS import? > > - id:"20120125173421.GQ3747 at x201" > > > > > > AFAICT, none of them share Message-Id's... > > Do you consider this a bug? > I do. No idea what causes it or how to fix it though... :) > Ciao, Gregor > -- > -... --- .-. . -.. ..--.. ...-.- > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch Peace -- Pieter [1] id:"20120126124450.GB30209 at shi.workgroup"
[PATCH v2 1/2] emacs: `notmuch-show-get-message-id': optionally return Message-Id sans prefix
* emacs/notmuch-show.el (notmuch-show-get-message-id): Add optional arg BARE. When non-nil, return a Message-Id without quotes and prefix, thus obviating the need to strip them off again in various places. (notmuch-show-stash-message-id-stripped): Update wrt changes in `notmuch-show-get-message-id'. --- emacs/notmuch-show.el | 13 + 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 84ac624..b13d088 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -1216,9 +1216,14 @@ Some useful entries are: (notmuch-show-get-message-properties (plist-get props prop))) -(defun notmuch-show-get-message-id () - "Return the message id of the current message." - (concat "id:\"" (notmuch-show-get-prop :id) "\"")) +(defun notmuch-show-get-message-id ( bare) + "Return the Message-Id of the current message. + +If optional argument BARE is non-nil, return +the Message-Id without prefix and quotes." + (if bare + (notmuch-show-get-prop :id) +(concat "id:\"" (notmuch-show-get-prop :id) "\""))) ;; dme: Would it make sense to use a macro for many of these? @@ -1618,7 +1623,7 @@ buffer." (defun notmuch-show-stash-message-id-stripped () "Copy message ID of current message (sans `id:' prefix) to kill-ring." (interactive) - (notmuch-common-do-stash (substring (notmuch-show-get-message-id) 4 -1))) + (notmuch-common-do-stash (notmuch-show-get-message-id t))) (defun notmuch-show-stash-subject () "Copy Subject field of current message to kill-ring." -- 1.7.8.1
[PATCH v2 2/2] emacs: add `notmuch-show-stash-mlarchive-link{, -and-go}'
* emacs/notmuch-show.el (notmuch-show-stash-mlarchive-link-alist): New defcustom of type `alist' (key = name, value = URI), containing Mailing List Archive URI's for searching by Message-Id. (notmuch-show-stash-mlarchive-link-default): New defcustom, default MLA to use when `notmuch-show-stash-mlarchive-link' received no user input whatsoever. Available choices are generated using the contents of `notmuch-show-stash-mlarchive-link-alist'. (notmuch-show-stash-map): Added keybinds "l" and "L" for `notmuch-show-stash-mlarchive-link' respectively `notmuch-show-stash-mlarchive-link-and-go'. (notmuch-show-stash-mlarchive-link): New function, stashes a URI pointing to the current message at one of the MLAs configured in `notmuch-show-stash-mlarchive-link-alist'. Prompts user with `completing-read' if not provided with an MLA key. (notmuch-show-stash-mlarchive-link-and-go): New function, uses `notmuch-show-stash-mlarchive-link' to stash a URI, and then visits it using the browser configured in `browse-url-browser-function'. * test/emacs Expanded subtest "Stashing in notmuch-show" wrt new functions `notmuch-show-stash-mlarchive-link{,-and-go}'. Based on original work [1] by David Edmondson . [1] id:"1327397873-20596-1-git-send-email-dme at dme.org" --- Addressed comments by David Edmondson [2] and Dmitry Kurochkin [3]. [2] id:"cunsjj1jyfj.fsf at hotblack-desiato.hh.sledj.net" [3] id:"87zkd9je5j.fsf at gmail.com" emacs/notmuch-show.el | 61 + test/emacs|8 +- 2 files changed, 68 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index b13d088..3d1312c 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -124,6 +124,35 @@ indentation." (const :tag "View interactively" notmuch-show-interactively-view-part))) +(defcustom notmuch-show-stash-mlarchive-link-alist + '(("Gmane" . "http://mid.gmane.org/;) +("MARC" . "http://marc.info/?i=;) +("Mail Archive, The" . "http://mail-archive.com/search?l=mid=;) +;; FIXME: can these services be searched by `Message-Id' ? +;; ("MarkMail" . "http://markmail.org/;) +;; ("Nabble" . "http://nabble.com/;) +;; ("opensubscriber" . "http://opensubscriber.com/;) +) + "List of Mailing List Archives to use when stashing links. + +These URIs are concatenated with the current message's +Message-Id in `notmuch-show-stash-mlarchive-link'." + :type '(alist :key-type (string :tag "Name") + :value-type (string :tag "URL")) + :group 'notmuch-show) + +(defcustom notmuch-show-stash-mlarchive-link-default "Gmane" + "Default Mailing List Archive to use when stashing links. + +This is used when `notmuch-show-stash-mlarchive-link' isn't +provided with an MLA argument nor `completing-read' input." + :type `(choice + ,@(mapcar +(lambda (mla) + (list 'const :tag (car mla) :value (car mla))) +notmuch-show-stash-mlarchive-link-alist)) + :group 'notmuch-show) + (defmacro with-current-notmuch-show-message ( body) "Evaluate body with current buffer set to the text of current message" `(save-excursion @@ -1048,6 +1077,8 @@ thread id. If a prefix is given, crypto processing is toggled." (define-key map "s" 'notmuch-show-stash-subject) (define-key map "T" 'notmuch-show-stash-tags) (define-key map "t" 'notmuch-show-stash-to) +(define-key map "l" 'notmuch-show-stash-mlarchive-link) +(define-key map "L" 'notmuch-show-stash-mlarchive-link-and-go) map) "Submap for stash commands") (fset 'notmuch-show-stash-map notmuch-show-stash-map) @@ -1640,6 +1671,36 @@ buffer." (interactive) (notmuch-common-do-stash (notmuch-show-get-to))) +(defun notmuch-show-stash-mlarchive-link ( mla) + "Copy an ML Archive URI for the current message to the kill-ring. + +This presumes that the message is available at the selected Mailing List Archive. + +If optional argument MLA is non-nil, use the provided key instead of prompting +the user (see `notmuch-show-stash-mlarchive-link-alist')." + (interactive) + (notmuch-common-do-stash + (concat (cdr (assoc +(or mla +(let ((completion-ignore-case t)) + (completing-read + "Mailing List Archive: " + notmuch-show-stash-mlarchive-link-alist + nil t nil nil notmuch-show-stash-mlarchive-link-default))) +notmuch-show-stash-mlarchive-link-alist)) + (notmuch-show-get-message-id t + +(defun notmuch-show-stash-mlarchive-link-and-go ( mla) + "Copy an ML Archive URI for the current message to the kill-ring and visit it. + +This presumes that the message is available at the selected Mailing List Archive. + +If optional argument MLA is non-nil, use the provided key instead of
[PATCH v4?] emacs: add `notmuch-show-stash-mlarchive-link{, -and-go}'
On Fri, 27 Jan 2012 09:18:40 +, David Edmondson wrote: > Much nicer :-) > > On Fri, 27 Jan 2012 09:44:26 +0100, Pieter Praet wrote: > > +(defcustom notmuch-show-stash-mlarchive-link-alist > > + '(("Gmane" . "http://mid.gmane.org/;) > > +("MARC" . "http://marc.info/?i=;) > > +("Mail Archive, The" . "http://mail-archive.com/search?l=mid=;) > > +;; FIXME: can these services be searched by `Message-Id' ? > > +;; ("MarkMail" . "http://markmail.org/;) > > +;; ("Nabble" . "http://nabble.com/;) > > +;; ("opensubscriber" . "http://opensubscriber.com/;) > > +) > > + "List of Mailing List Archives to use when stashing links." > > + :type '(alist :key-type (string :tag "Name") > > + :value-type (string :tag "URL")) > > + :group 'notmuch-show) > > Add a comment saying that the URI is the result of concatenating this > with the message id. > Done. > If someone wants to do something more complicated they can submit > another patch (maybe it should be an option to have the `cdr' be a > function that is called with the message id as an argument?). > > > + (substring (notmuch-show-get-message-id) 4 -1 > > We should put this logic in one place and re-use it. Done. New patches here: id:"1327907574-12760-1-git-send-email-pieter at praet.org" id:"1327907574-12760-2-git-send-email-pieter at praet.org" For some reason, I've marked them as "v2". :/ Note to self: don't send patches while you're still half asleep... Peace -- Pieter
[RFC] Re: [PATCH] emacs: Add `notmuch-show-stash-gmane' and `notmuch-show-stash-gmane-and-go'.
On Fri, 27 Jan 2012 20:36:40 +0400, Dmitry Kurochkin wrote: > On Fri, 27 Jan 2012 09:42:23 +0100, Pieter Praet wrote: > > On Thu, 26 Jan 2012 14:40:26 +, David Edmondson wrote: > > > In general, I like this. > > > > > > - I think that the stash function(s) should take an optional argument > > > specifying the archive to use. That will make testing simpler and also > > > allow people to produce preferred bindings more easily. > > > > > > > Agreed. In fact, apparently that last patch [1] of mine made the test > > suite hang @ emacs:"Stashing in notmuch-show" due to it waiting for > > `completing-read' to finish... Sorry for that. > > > > > - "Message archive: " feels better than "ML Archive: ", but I don't > > > really care. > > > > > > > Agreed. > > > > FWIW I believe "Mailing list archive" would be better. > Agreed. > Regards, > Dmitry > > > > - Don't base the patch on the thing that I posted, just on master from > > > the repository - no need to make David's life harder. > > > > Seeing as how it was only a minor improvement to your idea (and further > > discussion/correction was probably appropriate), I intended for you to > > squash it into your original patch. > > > > Anyways, patch (relative to master) follows... > > > > > > Peace > > > > -- > > Pieter > > > > [1] id:"1327583610-30085-1-git-send-email-pieter at praet.org" > > ___ > > notmuch mailing list > > notmuch at notmuchmail.org > > http://notmuchmail.org/mailman/listinfo/notmuch Peace -- Pieter
NEWS: add entries for the changes in the python bindings
On Sun, 29 Jan 2012 18:08:50 +0100, Justus Winter <4winter at informatik.uni-hamburg.de> wrote: > This patch series adds a section for the python binding changes to the > NEWS file. LGTM -- although knowing which python 2.x versions works would be nice to know. At least tests pass using python 2.5 but how complete are those tests... > > Cheers, > Justus Tomi
[PATCH v4] test: emacs: add test for `notmuch-search-operate-all'
`notmuch-search-operate-all' (bound to "*") adds and removes tags to/from all messages which match the query used to populate the current search buffer. --- Rebased to current master. Previous versions (chronologically): - id:"1309450108-2793-1-git-send-email-pieter at praet.org" - id:"1309762318-4530-5-git-send-email-pieter at praet.org" - id:"1310313335-4159-5-git-send-email-pieter at praet.org" test/emacs | 19 +++ 1 files changed, 19 insertions(+), 0 deletions(-) diff --git a/test/emacs b/test/emacs index 8ca4c8a..e94ad94 100755 --- a/test/emacs +++ b/test/emacs @@ -124,6 +124,25 @@ test_emacs "(notmuch-show \"$os_x_darwin_thread\") output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox unread)" +test_begin_subtest "Add/remove tags to/from all matching messages." +test_emacs '(notmuch-search "tag:inbox AND tags") + (notmuch-test-wait) + (notmuch-search-operate-all "+matching" "-inbox") + (notmuch-search "tag:matching AND NOT tag:inbox") + (notmuch-test-wait) + (test-output)' +cat
[PATCH 3/3] lib: Use talloc to simplify cleanup in notmuch_database_open
LGTM. all 3. Tomi
[PATCH] lib: update notmuch_tags_get examle to reflect api change
On Sun, 29 Jan 2012 10:29:01 -0500, Allan Wind wrote: > The function notmuch_database_find_message_by_filename now requires a > notmuch_message_t and returns a notmuch_status_t. This > change was introduced with 02a3076711, LIBNOTMUCH_VERSION_MAJOR = 2, > version 0.9. > --- Good, but [ ... ] > - * > + * status = notmuch_database_find_message (database, message_id, > ); > + * if(!status && message) { > + * for (tags = notmuch_message_get_tags (message); space missing between 'if' and '(' Tomi
[PATCH] emacs: globally replace non-branching "(if COND (progn ..." with "(when ..."
On Mon, 30 Jan 2012 08:03:59 +0100, Pieter Praet wrote: > On Sat, 28 Jan 2012 08:41:36 -0400, David Bremner > wrote: > > On Sat, 14 Jan 2012 10:17:18 +0100, Pieter Praet > > wrote: > > > Less code, same results, without sacrificing readability. > > > > > > > This looks OK, although the re-indenting makes these kind of changes > > painful to review (not that I'm suggesting we should re-indent, just > > some random complaining). > > > > You can use `diff-refine-hunk' to see what the actual changes are. > > Try this: > > #+begin_src emacs-lisp > (global-set-key (kbd "C-c /") > (lambda() > "Refine display of unified diff hunks" > (interactive) > (save-excursion > (goto-char (point-min)) > (while (re-search-forward > diff-hunk-header-re-unified > nil t) > (diff-refine-hunk) > #+end_src > > Work pretty much *anywhere*. > > Note: it does NOT work in `notmuch-show-mode' (not even with > `notmuch-wash-convert-inline-patch-to-part' disabled), but this is > easily solved by first running `notmuch-show-view-raw-message' ("V") > and `diff-mode' (to fontify the buffer)... What we need is 'notmuch-devel' minor mode which can do this, dme's notmuch patching tool, nmbug tag changes and everything... > > > d > > > Peace > > -- > Pieter Tomi
[PATCH v4] test: emacs: add test for `notmuch-search-operate-all'
Hi Pieter. On Mon, 30 Jan 2012 08:45:50 +0100, Pieter Praet wrote: > `notmuch-search-operate-all' (bound to "*") adds and removes tags > to/from all messages which match the query used to populate the > current search buffer. > > --- > > Rebased to current master. > > Previous versions (chronologically): > - id:"1309450108-2793-1-git-send-email-pieter at praet.org" > - id:"1309762318-4530-5-git-send-email-pieter at praet.org" > - id:"1310313335-4159-5-git-send-email-pieter at praet.org" > This looks like a useful patch series. We definitely need more tests for tagging operations in the Emacs UI. Do you plan to revive it? Note that not so long ago I posted a bunch of tagging-related patches [1] that would conflict with this patch at least because of `notmuch-search-operate-all' being renamed to `notmuch-search-tag-all'. > > test/emacs | 19 +++ > 1 files changed, 19 insertions(+), 0 deletions(-) > > diff --git a/test/emacs b/test/emacs > index 8ca4c8a..e94ad94 100755 > --- a/test/emacs > +++ b/test/emacs > @@ -124,6 +124,25 @@ test_emacs "(notmuch-show \"$os_x_darwin_thread\") > output=$(notmuch search $os_x_darwin_thread | notmuch_search_sanitize) > test_expect_equal "$output" "thread:XXX 2009-11-18 [4/4] Jjgod Jiang, > Alexander Botero-Lowry; [notmuch] Mac OS X/Darwin compatibility issues (inbox > unread)" > > +test_begin_subtest "Add/remove tags to/from all matching messages." > +test_emacs '(notmuch-search "tag:inbox AND tags") > + (notmuch-test-wait) > + (notmuch-search-operate-all "+matching" "-inbox") > + (notmuch-search "tag:matching AND NOT tag:inbox") > + (notmuch-test-wait) > + (test-output)' > +cat+ 2009-11-18 [3/3] Adrian Perez de Castro, Keith Packard, Carl Worth > [notmuch] Introducing myself (matching signed unread) > + 2009-11-18 [1/3] Carl Worth, Israel Herraiz, Keith Packard > [notmuch] New to the list (inbox matching unread) > + 2009-11-18 [2/2] Keith Packard, Carl Worth[notmuch] [PATCH] Make > notmuch-show 'X' (and 'x') commands remove inbox (and unread) tags (matching > unread) > + 2009-11-18 [1/2] Keith Packard, Alexander Botero-Lowry[notmuch] > [PATCH] Create a default notmuch-show-hook that highlights URLs and uses > word-wrap (inbox matching unread) > + 2009-11-18 [1/1] Jan Janak[notmuch] [PATCH] notmuch new: > Support for conversion of spool subdirectories into tags (matching unread) > + 2009-11-18 [1/1] Stewart Smith[notmuch] [PATCH] Fix linking with > gcc to use g++ to link in C++ libs. (matching unread) > + 2009-11-17 [1/2] Ingmar Vanhassel, Carl Worth [notmuch] [PATCH] Typsos > (inbox matching unread) > +End of search results. > +EOF > +test_expect_equal_file OUTPUT EXPECTED I am worried that this test would break because of changes in other tests. E.g. if a new test adds a new message which matches "tag:inbox AND tags", this test would have to be updated. I think we should avoid this. I see the following options here: * Search for messages which are less likely to change, e.g. "from:carl". * Rework the test to avoid using any fixed expected results, e.g.: - count all messages with tag:inbox - remove inbox tag, add some other distinct tag for all messages with tag:inbox - count all messages with tag:inbox again, check that it is 0 - add the inbox tag back, remove the previously added tag, check the message count I like the latter approach because it does not compare Emacs UI output and hence would not break when that output changes. What do you think? Also, we should leave notmuch db in the same state as it was before the test if possible. Regards, Dmitry [1] id:"1327901644-15799-1-git-send-email-dmitry.kurochkin at gmail.com" > + > test_begin_subtest "Message with .. in Message-Id:" > add_message [id]=123..456 at example '[subject]="Message with .. in > Message-Id"' > test_emacs '(notmuch-search "id:\"123..456 at example\"") > -- > 1.7.8.1 >
[PATCH 2/2] emacs: Quote MML tags in replies
On Sun, 29 Jan 2012 01:07:08 -0500, Aaron Ecay wrote: > Emacs message-mode uses certain text strings to indicate how to attach > files to outgoing mail. If these are present in the text of an email, > and a user is tricked into replying to the message, the user?s files > could be exposed. > --- [ ... ] > > - (message-goto-body)) > + (message-goto-body) > + (mml-quote-region (point) (mark))) As asked before, comment why mmm-quote-region is needed and why (mark) is used instead of (point-max) is there. We know the reasons but future viewers of the code will wonder a while... Tomi
[PATCH v2 1/2] emacs: `notmuch-show-get-message-id': optionally return Message-Id sans prefix
Looks good. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120130/692e7b4e/attachment.pgp>
[PATCH v2 2/2] emacs: add `notmuch-show-stash-mlarchive-link{, -and-go}'
Looks good. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120130/02522874/attachment.pgp>
[PATCH 1/3] emacs: Stop the `truncate-string-to-width' madness.
On Sat, 28 Jan 2012 00:09:58 -0500, Austin Clements wrote: > Quoth David Edmondson on Jan 25 at 1:48 pm: > > There's no need to call `truncate-string-to-width' twice in this code > > path. > > LGTM if what I point out below is okay. Technically this changes the > behavior of this code, but what it did before was obviously wrong (if > you do roll a new version, I'd mention this in the commit message; but > no need to do that just for this). > > > --- > > emacs/notmuch.el | 14 ++ > > 1 files changed, 6 insertions(+), 8 deletions(-) > > > > diff --git a/emacs/notmuch.el b/emacs/notmuch.el > > index 3ec0816..3f6b977 100644 > > --- a/emacs/notmuch.el > > +++ b/emacs/notmuch.el > > @@ -441,18 +441,16 @@ Complete list of currently available key bindings: > >(interactive "P") > >(let ((thread-id (notmuch-search-find-thread-id)) > > (subject (notmuch-search-find-subject))) > > + > > +(if (string-match "^[ \t]*$" subject) > > + (setq subject "[No Subject]")) > > + > > Is subject necessarily a string at this point? Previously this only > ran if the code determined there was a thread at point. No, it's a bug. It's fixed in the third patch, but should be fixed here as well. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120130/96898fb4/attachment.pgp>
[PATCH 0/2] Add a fake 'Tags' header
On Sat, 28 Jan 2012 08:16:04 -0400, David Bremner wrote: > On Thu, 26 Jan 2012 18:16:27 +, David Edmondson wrote: > > From a discussion in #notmuch, add a fake 'Tags' header when > > displaying messages and ensure that it's kept up to date. > > Indeed this seems useful when tags are too long for the display width, > but it also seems a bit redundant to display the tags twice, once in the > first line, and then repeated later. I usually have `notmuch-message-headers-visible' set to `t', so I only see the tags once. (Though I would like to have the blank line even when the headers are not shown, just haven't got around to it.) > Is there some customization of the first line (author date (tags) ) that > I missed? No, there's no way to configure the contents of the header line. I'll have a think about it. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120130/e072261c/attachment.pgp>
[PATCH] emacs: globally replace non-branching "(if COND (progn ..." with "(when ..."
On Sat, 28 Jan 2012 13:14:45 -0400, David Bremner wrote: > On Sat, 28 Jan 2012 14:55:22 +0200, Jani Nikula wrote: > > On Jan 28, 2012 2:41 PM, "David Bremner" wrote: > > > > Sometimes someone (Dmitry?) sent patches that separated a small functional > > change, and the big non-functional indentation change it caused, > > separately. Would you prefer (or tolerate ;) that style? > > Hmm, that might be nicer, I'm not 100% sure. > > I wouldn't say it's mandatory for a patch like this (and I'd say other > peoples views on what's easy to review are at least as important as mine > here). Each patch should be valid in the repository without any following patches (preceding are obviously okay). Incorrect indentation would disqualify a patch from being 'valid', so it shouldn't be accepted. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120130/272614fb/attachment.pgp>
[PATCH 1/2] test: auto load elisp tests file in test_emacs if available
Nice idea, +1. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120130/fff78d13/attachment-0001.pgp>