Re: [PATCH 0/3] reworked crypto toggle, plus a couple of other toggles

2012-01-30 Thread David Edmondson
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

2012-01-30 Thread David Edmondson
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.

2012-01-30 Thread David Edmondson
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

2012-01-30 Thread David Edmondson
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.

2012-01-30 Thread David Edmondson
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
`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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Allan Wind
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

2012-01-30 Thread Allan Wind
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

2012-01-30 Thread Tomi Ollila
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

2012-01-30 Thread Allan Wind
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

2012-01-30 Thread Tomi Ollila
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

2012-01-30 Thread Tomi Ollila
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

2012-01-30 Thread Tomi Ollila
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.

2012-01-30 Thread Austin Clements
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

2012-01-30 Thread Austin Clements
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

2012-01-30 Thread Austin Clements
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

2012-01-30 Thread Tomi Ollila

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

2012-01-30 Thread David Edmondson
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.

2012-01-30 Thread David Edmondson
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.

2012-01-30 Thread David Edmondson
---
 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'.

2012-01-30 Thread David Edmondson
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.

2012-01-30 Thread David Edmondson
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

2012-01-30 Thread Tomi Ollila
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.

2012-01-30 Thread Jani Nikula
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

2012-01-30 Thread Jameson Graef Rollins
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

2012-01-30 Thread Jameson Graef Rollins
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'.

2012-01-30 Thread Mark Walters
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

2012-01-30 Thread Allan Wind
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

2012-01-30 Thread Mark Walters

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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Allan Wind
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

2012-01-30 Thread Mark Walters
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:

2012-01-30 Thread David Bremner
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.

2012-01-30 Thread Austin Clements
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

2012-01-30 Thread Austin Clements
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

2012-01-30 Thread Austin Clements
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

2012-01-30 Thread Dmitry Kurochkin
---
 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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Austin Clements
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Gregor Zattler
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

2012-01-30 Thread Gregor Zattler
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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'

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
---
 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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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'

2012-01-30 Thread Dmitry Kurochkin
`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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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'

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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'

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
---
 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

2012-01-30 Thread Austin Clements
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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'

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
---
 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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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'

2012-01-30 Thread Dmitry Kurochkin
`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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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'

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Dmitry Kurochkin
---
 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 ..."

2012-01-30 Thread Pieter Praet
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

2012-01-30 Thread Pieter Praet
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

2012-01-30 Thread Pieter Praet
* 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}'

2012-01-30 Thread Pieter Praet
* 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}'

2012-01-30 Thread Pieter Praet
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'.

2012-01-30 Thread Pieter Praet
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

2012-01-30 Thread Tomi Ollila
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'

2012-01-30 Thread Pieter Praet
`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

2012-01-30 Thread Tomi Ollila

LGTM. all 3.

Tomi


[PATCH] lib: update notmuch_tags_get examle to reflect api change

2012-01-30 Thread Tomi Ollila
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 ..."

2012-01-30 Thread Tomi Ollila
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'

2012-01-30 Thread Dmitry Kurochkin
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

2012-01-30 Thread Tomi Ollila
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

2012-01-30 Thread David Edmondson
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}'

2012-01-30 Thread David Edmondson
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.

2012-01-30 Thread David Edmondson
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

2012-01-30 Thread David Edmondson
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 ..."

2012-01-30 Thread David Edmondson
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

2012-01-30 Thread David Edmondson
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>


  1   2   >