[PATCH v2 4b/4] NEWS: added information about new --stderr=FILE top level option

2013-05-27 Thread Tomi Ollila
---
 NEWS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/NEWS b/NEWS
index a7f2ec6..990b038 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,12 @@ Top level option to specify configuration file
   It's now possible to specify the configuration file to use on the
   command line using the `notmuch --config=FILE` option.

+Top level option to redirect writes to stderr
+
+  With `notmuch --stderr=FILE` all writes to stderr are redirected to
+  the specified file. If the file name is a plain '-', stderr is
+  written to stdout.
+
 Deprecated commands "part" and "search-tags" are removed.

 Bash command-line completion
-- 
1.8.1.4



[PATCH 4/5] emacs: Streaming S-expression parser

2013-05-27 Thread Mark Walters

Austin Clements  writes:

> Quoth Mark Walters on May 25 at  9:59 am:
>> 
>> Hi
>> 
>> On Wed, 22 May 2013, Austin Clements  wrote:
>> > On Tue, 21 May 2013, Mark Walters  wrote:
>> >> Hi
>> >>
>> >> This patch looks good to me. Some minor comments below.
>> >
>> > Some minor replies below.
>> >
>> > In building some other code on top of this, I found an interesting (but
>> > easy to fix) interface bug.  Currently, the interface is designed as if
>> > it doesn't matter what buffer these functions are called from, however,
>> > because they move point and expect this point motion to persist, it's
>> > actually not safe to call this interface unless the caller is in the
>> > right buffer anyway.  For example, if the buffer is selected in a
>> > window, the with-current-buffer in the parser functions will actually
>> > move a *temporary* point, meaning that the only way the caller can
>> > discover the new point is to first select the buffer for itself.  I can
>> > think of two solutions: 1) maintain our own mark for the parser's
>> > current position or 2) tweak the doc strings and code so that it reads
>> > from the current buffer.  1 keeps the interface the way it's currently
>> > documented, but complicates the parser implementation and interface and
>> > doesn't simplify the caller.  2 simplifies the parser and it turns out
>> > all callers already satisfy the requirement.
>> 
>> I am confused by this: the docs strings for json/sexp-parse-partial-list
>> both say something like "Parse a partial JSON list from current buffer"?
>> Or do you mean the with-current-buffer in notmuch-search-process-filter?
>
> I was referring to the lower level parser, which effectively has the
> same requirement but isn't documented to and has code that pointlessly
> tries to track the parsing buffer (I consider
> json/sexp-parse-partial-list to be a helper).  In fact, one reason the
> lower level parser didn't choke is because right now we only use it
> through json/sexp-parse-partial-list, which requires that it be called
> from the right buffer.

Right I think I see. I am definitely happy with insisting on being
called from the correct buffer in the low level code.

>> >> On Sat, 18 May 2013, Austin Clements  wrote:
>> >>> This provides the same interface as the streaming JSON parser, but
>> >>> reads S-expressions incrementally.  The only difference is that the
>> >>> `notmuch-sexp-parse-partial-list' helper does not handle interleaved
>> >>> error messages (since we now have the ability to separate these out at
>> >>> the invocation level), so it no longer takes an error function and
>> >>> does not need to do the horrible resynchronization that the JSON
>> >>> parser had to.
>> >>>
>> >>> Some implementation improvements have been made over the JSON parser.
>> >>> This uses a vector instead of a list for the parser data structure,
>> >>> since this allows faster access to elements (and modern versions of
>> >>> Emacs handle storage of small vectors efficiently).  Private functions
>> >>> follow the "prefix--name" convention.  And the implementation is much
>> >>> simpler overall because S-expressions are much easier to parse.
>> >>> ---
>> >>>  emacs/Makefile.local|1 +
>> >>>  emacs/notmuch-parser.el |  212 
>> >>> +++
>> >>>  2 files changed, 213 insertions(+)
>> >>>  create mode 100644 emacs/notmuch-parser.el
>> >>>
>> >>> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
>> >>> index 456700a..a910aff 100644
>> >>> --- a/emacs/Makefile.local
>> >>> +++ b/emacs/Makefile.local
>> >>> @@ -3,6 +3,7 @@
>> >>>  dir := emacs
>> >>>  emacs_sources := \
>> >>>  $(dir)/notmuch-lib.el \
>> >>> +$(dir)/notmuch-parser.el \
>> >>>  $(dir)/notmuch.el \
>> >>>  $(dir)/notmuch-query.el \
>> >>>  $(dir)/notmuch-show.el \
>> >>> diff --git a/emacs/notmuch-parser.el b/emacs/notmuch-parser.el
>> >>> new file mode 100644
>> >>> index 000..1b7cf64
>> >>> --- /dev/null
>> >>> +++ b/emacs/notmuch-parser.el
>> >>> @@ -0,0 +1,212 @@
>> >>> +;; notmuch-parser.el --- streaming S-expression parser
>> >>> +;;
>> >>> +;; Copyright ? Austin Clements
>> >>> +;;
>> >>> +;; This file is part of Notmuch.
>> >>> +;;
>> >>> +;; Notmuch is free software: you can redistribute it and/or modify it
>> >>> +;; under the terms of the GNU General Public License as published by
>> >>> +;; the Free Software Foundation, either version 3 of the License, or
>> >>> +;; (at your option) any later version.
>> >>> +;;
>> >>> +;; Notmuch is distributed in the hope that it will be useful, but
>> >>> +;; WITHOUT ANY WARRANTY; without even the implied warranty of
>> >>> +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> >>> +;; General Public License for more details.
>> >>> +;;
>> >>> +;; You should have received a copy of the GNU General Public License
>> >>> +;; along with Notmuch.  If not, see .
>> >>> +;;
>> >>> +;; 

[PATCH] emacs: Fix trimming regexp in notmuch-check-exit-status

2013-05-27 Thread David Bremner
Austin Clements  writes:

> For such a simple regexp, this was broken in a very complicated way.
>

pushed, for real this time.

d


[PATCH v2 3/4] man: documented --stderr=FILE in notmuch.1 manual page

2013-05-27 Thread Austin Clements
Quoth Tomi Ollila on May 26 at 11:45 am:
> ---
>  man/man1/notmuch.1 | 7 +++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/man/man1/notmuch.1 b/man/man1/notmuch.1
> index 033cc10..fbd575a 100644
> --- a/man/man1/notmuch.1
> +++ b/man/man1/notmuch.1
> @@ -76,7 +76,14 @@ Print the installed version of notmuch, and exit.
>  
>  Specify the configuration file to use. This overrides any
>  configuration file specified by ${NOTMUCH_CONFIG}.
> +.RE
> +
> +.RS 4
> +.TP 4
> +.B \-\-stderr=FILE
>  
> +Redirect all writes to stderr to the specified file.
> +If the file name is a plain '-', stderr is written to stdout.

The second sentence could be just "If FILE is '-', stderr is
redirected to stdout.".  Same goes for the NEWS.

>  .RE
>  
>  .SH COMMANDS

Series LGTM other than my two comments.


[PATCH v2 1/4] cli: add global option --stderr=FILE

2013-05-27 Thread Austin Clements
Quoth Tomi Ollila on May 26 at 11:45 am:
> With this option all writes to stderr are redirected to the spesified
> FILE (or to stdout on case FILE is '-'). This is immediately useful
> in emacs interface as some of its exec intefaces do not provide
> separation of stdout and stderr.
> ---
>  notmuch-client.h |  1 +
>  notmuch.c| 32 
>  2 files changed, 33 insertions(+)
> 
> diff --git a/notmuch-client.h b/notmuch-client.h
> index 45749a6..4a3c7ac 100644
> --- a/notmuch-client.h
> +++ b/notmuch-client.h
> @@ -54,6 +54,7 @@ typedef GMimeCipherContext notmuch_crypto_context_t;
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> diff --git a/notmuch.c b/notmuch.c
> index f51a84f..654a568 100644
> --- a/notmuch.c
> +++ b/notmuch.c
> @@ -251,6 +251,32 @@ notmuch_command (notmuch_config_t *config,
>  return 0;
>  }
>  
> +static int
> +redirect_stderr (const char * stderr_file)
> +{
> +if (strcmp (stderr_file, "-") == 0) {
> + if (dup2 (STDOUT_FILENO, STDERR_FILENO) < 0) {
> + perror ("dup2");
> + return 1;
> + }
> +} else {
> + int fd = open (stderr_file, O_WRONLY|O_CREAT|O_APPEND, 0644);

I think this should include O_TRUNC; otherwise it's too error-prone to
use programmatically.  The permissions should be 0666 (if the user's
umask says things should be group or world writable, it's not our job
to disagree).

> + if (fd < 0) {
> + fprintf (stderr, "Error: Cannot redirect stderr to '%s': %s\n",
> +  stderr_file, strerror (errno));
> + return 1;
> + }
> + if (fd != STDERR_FILENO) {
> + if (dup2 (fd, STDERR_FILENO) < 0) {
> + perror ("dup2");
> + return 1;
> + }
> + close (fd);
> + }
> +}
> +return 0;
> +}
> +
>  int
>  main (int argc, char *argv[])
>  {
> @@ -259,6 +285,7 @@ main (int argc, char *argv[])
>  const char *command_name = NULL;
>  command_t *command;
>  char *config_file_name = NULL;
> +char *stderr_file = NULL;
>  notmuch_config_t *config;
>  notmuch_bool_t print_help=FALSE, print_version=FALSE;
>  int opt_index;
> @@ -268,6 +295,7 @@ main (int argc, char *argv[])
>   { NOTMUCH_OPT_BOOLEAN, _help, "help", 'h', 0 },
>   { NOTMUCH_OPT_BOOLEAN, _version, "version", 'v', 0 },
>   { NOTMUCH_OPT_STRING, _file_name, "config", 'c', 0 },
> + { NOTMUCH_OPT_STRING, _file, "stderr", '\0', 0 },
>   { 0, 0, 0, 0, 0 }
>  };
>  
> @@ -287,6 +315,10 @@ main (int argc, char *argv[])
>   return 1;
>  }
>  
> +if (stderr_file && redirect_stderr (stderr_file) != 0) {
> + /* error already printed */
> + return 1;
> +}
>  if (print_help)
>   return notmuch_help_command (NULL, argc - 1, [1]);
>  


[PATCH 4/4] emacs: Bind MIME part commands to "." submap

2013-05-27 Thread Austin Clements
Since the part commands are no longer tied to a button, but can be
applied with point anywhere within a part, bind the part commands
keymap to "." everywhere in the show buffer.  This lets you save or
view parts without having to navigate to the part button, and is
particularly useful for parts that have no button.  These key bindings
are still available without the prefix when point is over a part
button.
---
 emacs/notmuch-show.el |   27 ---
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index b33d92d..380b144 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -471,17 +471,6 @@ message at DEPTH in the current thread."
   'face 'message-mml
   :supertype 'notmuch-button-type)

-(defvar notmuch-show-part-button-map
-  (let ((map (make-sparse-keymap)))
-(set-keymap-parent map button-map)
-(define-key map "s" 'notmuch-show-save-part)
-(define-key map "v" 'notmuch-show-view-part)
-(define-key map "o" 'notmuch-show-interactively-view-part)
-(define-key map "|" 'notmuch-show-pipe-part)
-map)
-  "Submap for button commands")
-(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
-
 (defun notmuch-show-insert-part-header (nth content-type declared-type 
 name comment)
   (let ((button)
(base-label (concat (when name (concat name ": "))
@@ -1195,6 +1184,21 @@ reset based on the original query."
   "Submap for stash commands")
 (fset 'notmuch-show-stash-map notmuch-show-stash-map)

+(defvar notmuch-show-part-map
+  (let ((map (make-sparse-keymap)))
+(define-key map "s" 'notmuch-show-save-part)
+(define-key map "v" 'notmuch-show-view-part)
+(define-key map "o" 'notmuch-show-interactively-view-part)
+(define-key map "|" 'notmuch-show-pipe-part)
+map)
+  "Submap for part commands")
+(fset 'notmuch-show-part-map notmuch-show-part-map)
+
+(defvar notmuch-show-part-button-map
+  (make-composed-keymap notmuch-show-part-map button-map)
+  "Keymap for part button commands")
+(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
+
 (defvar notmuch-show-mode-map
   (let ((map (make-sparse-keymap)))
(define-key map "?" 'notmuch-help)
@@ -1237,6 +1241,7 @@ reset based on the original query."
(define-key map "$" 'notmuch-show-toggle-process-crypto)
(define-key map "<" 'notmuch-show-toggle-thread-indentation)
(define-key map "t" 'toggle-truncate-lines)
+   (define-key map "." 'notmuch-show-part-map)
map)
   "Keymap for \"notmuch show\" buffers.")
 (fset 'notmuch-show-mode-map notmuch-show-mode-map)
-- 
1.7.10.4



[PATCH 3/4] emacs: Simplify MIME part command implementation

2013-05-27 Thread Austin Clements
This unifies the part button actions and the underlying part action
functions into single interactive command that simply applies to the
part containing point using the just-added part p-list text property
instead of button properties.  Since all part actions can be performed
by applying the appropriate mm function to an mm-handle, this patch
abstracts out the creation of mm handles, making the implementations
of the part commands trivial.  This also eliminates our special
handling for part save in favor of using the appropriate mm function.

This necessarily modifies the way we handle the default part button
action, but in a way that does not change the meaning of the
notmuch-show-part-button-default-action defcustom.

Since these commands are no longer specific to buttons, this patch
eliminates the extra metadata stored with each button.  This also
eliminates one rather special-purpose macro for a collection of
general purpose part handling utilities.
---
 emacs/notmuch-show.el |  133 +
 test/emacs|4 +-
 2 files changed, 61 insertions(+), 76 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index acd0b55..b33d92d 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -474,10 +474,10 @@ message at DEPTH in the current thread."
 (defvar notmuch-show-part-button-map
   (let ((map (make-sparse-keymap)))
 (set-keymap-parent map button-map)
-(define-key map "s" 'notmuch-show-part-button-save)
-(define-key map "v" 'notmuch-show-part-button-view)
-(define-key map "o" 'notmuch-show-part-button-interactively-view)
-(define-key map "|" 'notmuch-show-part-button-pipe)
+(define-key map "s" 'notmuch-show-save-part)
+(define-key map "v" 'notmuch-show-view-part)
+(define-key map "o" 'notmuch-show-interactively-view-part)
+(define-key map "|" 'notmuch-show-pipe-part)
 map)
   "Submap for button commands")
 (fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
@@ -494,61 +494,11 @@ message at DEPTH in the current thread."
  (insert-button
   (concat "[ " base-label " ]")
   :base-label base-label
-  :type 'notmuch-show-part-button-type
-  :notmuch-part nth
-  :notmuch-filename name
-  :notmuch-content-type content-type))
+  :type 'notmuch-show-part-button-type))
 (insert "\n")
 ;; return button
 button))

-;; Functions handling particular MIME parts.
-
-(defmacro notmuch-with-temp-part-buffer (message-id nth  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-get-bodypart-internal ,message-id ,nth 
notmuch-show-process-crypto))
-, at body
-
-(defun notmuch-show-save-part (message-id nth  filename content-type)
-  (notmuch-with-temp-part-buffer message-id nth
-(let ((file (read-file-name
-"Filename to save as: "
-(or mailcap-download-directory "~/")
-nil nil
-filename)))
-  ;; Don't re-compress .gz & al.  Arguably we should make
-  ;; `file-name-handler-alist' nil, but that would chop
-  ;; ange-ftp, which is reasonable to use here.
-  (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion 
t
-
-(defun notmuch-show-view-part (message-id nth  filename content-type )
-  (notmuch-with-temp-part-buffer message-id nth
-(let* ((disposition (if filename `(attachment (filename . ,filename
-  (handle (mm-make-handle (current-buffer) (list content-type)
-  nil nil disposition))
-  ;; Set the default save directory to be consistent with
-  ;; `notmuch-show-save-part'.
-  (mm-default-directory (or mailcap-download-directory "~/"))
-  ;; set mm-inlined-types to nil to force an external viewer
-  (mm-inlined-types nil))
-  (mm-display-part handle
-
-(defun notmuch-show-interactively-view-part (message-id nth  filename 
content-type)
-  (notmuch-with-temp-part-buffer message-id nth
-(let ((handle (mm-make-handle (current-buffer) (list content-type
-  (mm-interactively-view-part handle
-
-(defun notmuch-show-pipe-part (message-id nth  filename content-type)
-  (notmuch-with-temp-part-buffer message-id nth
-(let ((handle (mm-make-handle (current-buffer) (list content-type
-  (mm-pipe-part handle
-
 ;; This is taken from notmuch-wash: maybe it should be unified?
 (defun notmuch-show-toggle-part-invisibility ( button)
   (interactive)
@@ -570,6 +520,8 @@ message at DEPTH in the current thread."
  (delete-region (point) old-end))
(goto-char (min 

[PATCH 2/4] emacs: Record part p-list in a text property

2013-05-27 Thread Austin Clements
This is similar to what we already do with the message p-list, though
we apply the part's text property to the whole part's text, in
contrast with the message p-list, which is (rather obscurely) only
applied to the first character.
---
 emacs/notmuch-lib.el  |   16 
 emacs/notmuch-show.el |   13 -
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 790136e..09ce25e 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -360,6 +360,22 @@ OBJECT."
below
string))

+(defun notmuch-put-text-property-if-nil (start end property value
+   object)
+  "Like `put-text-property', but only set the property where it is nil."
+  (while (< start end)
+(let ((start-nil (text-property-any start end property nil object)))
+  (if (null start-nil)
+ ;; There are no more nil regions; exit the loop
+ (setq start end)
+   ;; Find the end of the nil region
+   (let ((end-nil
+  (or (text-property-not-all start-nil end property nil object)
+  end)))
+ ;; Set the property
+ (put-text-property start-nil end-nil property value object)
+ (setq start end-nil))
+
 (defun notmuch-logged-error (msg  extra)
   "Log MSG and EXTRA to *Notmuch errors* and signal MSG.

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index a080134..acd0b55 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -900,7 +900,10 @@ If HIDE is non-nil then initially hide this part."
 ;; Ensure that the part ends with a carriage return.
 (unless (bolp)
   (insert "\n"))
-(notmuch-show-create-part-overlays msg beg (point) hide)))
+(notmuch-show-create-part-overlays msg beg (point) hide)
+;; Record part information.  Since we already inserted subparts,
+;; don't override exiting :notmuch-part properties.
+(notmuch-put-text-property-if-nil beg (point) :notmuch-part part)))

 (defun notmuch-show-insert-body (msg body depth)
   "Insert the body BODY at depth DEPTH in the current thread."
@@ -1404,6 +1407,14 @@ Some useful entries are:
 (notmuch-show-move-to-message-top)
 (get-text-property (point) :notmuch-message-properties)))

+(defun notmuch-show-get-part-properties ()
+  "Return the properties of the part containing point.
+
+This is the part property list retrieved from the CLI.  Signals
+an error if there is no part containing point."
+  (or (get-text-property (point) :notmuch-part)
+  (error "No message part here")))
+
 (defun notmuch-show-set-prop (prop val  props)
   (let ((inhibit-read-only t)
(props (or props
-- 
1.7.10.4



[PATCH 1/4] emacs: Retain text properties when toggling buttons

2013-05-27 Thread Austin Clements
Previously, we lost any text properties applied to part buttons or
wash buttons when they were toggled because `insert' directly copies
the text properties of the string being inserted.  Fix this by
capturing the properties applied to the button beforehand and
re-applying them after inserting the new text.
---
 emacs/notmuch-show.el |2 ++
 emacs/notmuch-wash.el |2 ++
 2 files changed, 4 insertions(+)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index b0a8d8a..a080134 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -559,10 +559,12 @@ message at DEPTH in the current thread."
 (new-start (button-start button))
 (button-label (button-get button :base-label))
 (old-point (point))
+(properties (text-properties-at (point)))
 (inhibit-read-only t))
(overlay-put overlay 'invisible (not show))
(goto-char new-start)
(insert "[ " button-label (if show " ]" " (hidden) ]"))
+   (set-text-properties new-start (point) properties)
(let ((old-end (button-end button)))
  (move-overlay button new-start (point))
  (delete-region (point) old-end))
diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
index 8a68819..8fe91e1 100644
--- a/emacs/notmuch-wash.el
+++ b/emacs/notmuch-wash.el
@@ -104,9 +104,11 @@ lower).")
 (overlay (button-get cite-button 'overlay))
 (button-label (notmuch-wash-button-label overlay))
 (old-point (point))
+(properties (text-properties-at (point)))
 (inhibit-read-only t))
 (goto-char new-start)
 (insert button-label)
+(set-text-properties new-start (point) properties)
 (let ((old-end (button-end cite-button)))
   (move-overlay cite-button new-start (point))
   (delete-region (point) old-end))
-- 
1.7.10.4



[PATCH 0/4] emacs: Part command improvements

2013-05-27 Thread Austin Clements
This is a follow-up of sorts to id:"8761ycc19t.fsf at qmul.ac.uk", where
Mark suggested that the part handling commands could all use the
correponding mm-* functions.  I ran with the idea and wound up with
this series, which, in addition to standardizing on the mm-* functions
for everything and simplifying the implementation overall, decouples
the part commands from part buttons, which removes an entire layer
from the implementation and adds the ability to invoke part commands
with point anywhere in a part (something I often find myself wanting).



[PATCH 4/5] emacs: Streaming S-expression parser

2013-05-27 Thread Austin Clements
Quoth Mark Walters on May 25 at  9:59 am:
> 
> Hi
> 
> On Wed, 22 May 2013, Austin Clements  wrote:
> > On Tue, 21 May 2013, Mark Walters  wrote:
> >> Hi
> >>
> >> This patch looks good to me. Some minor comments below.
> >
> > Some minor replies below.
> >
> > In building some other code on top of this, I found an interesting (but
> > easy to fix) interface bug.  Currently, the interface is designed as if
> > it doesn't matter what buffer these functions are called from, however,
> > because they move point and expect this point motion to persist, it's
> > actually not safe to call this interface unless the caller is in the
> > right buffer anyway.  For example, if the buffer is selected in a
> > window, the with-current-buffer in the parser functions will actually
> > move a *temporary* point, meaning that the only way the caller can
> > discover the new point is to first select the buffer for itself.  I can
> > think of two solutions: 1) maintain our own mark for the parser's
> > current position or 2) tweak the doc strings and code so that it reads
> > from the current buffer.  1 keeps the interface the way it's currently
> > documented, but complicates the parser implementation and interface and
> > doesn't simplify the caller.  2 simplifies the parser and it turns out
> > all callers already satisfy the requirement.
> 
> I am confused by this: the docs strings for json/sexp-parse-partial-list
> both say something like "Parse a partial JSON list from current buffer"?
> Or do you mean the with-current-buffer in notmuch-search-process-filter?

I was referring to the lower level parser, which effectively has the
same requirement but isn't documented to and has code that pointlessly
tries to track the parsing buffer (I consider
json/sexp-parse-partial-list to be a helper).  In fact, one reason the
lower level parser didn't choke is because right now we only use it
through json/sexp-parse-partial-list, which requires that it be called
from the right buffer.

> >> On Sat, 18 May 2013, Austin Clements  wrote:
> >>> This provides the same interface as the streaming JSON parser, but
> >>> reads S-expressions incrementally.  The only difference is that the
> >>> `notmuch-sexp-parse-partial-list' helper does not handle interleaved
> >>> error messages (since we now have the ability to separate these out at
> >>> the invocation level), so it no longer takes an error function and
> >>> does not need to do the horrible resynchronization that the JSON
> >>> parser had to.
> >>>
> >>> Some implementation improvements have been made over the JSON parser.
> >>> This uses a vector instead of a list for the parser data structure,
> >>> since this allows faster access to elements (and modern versions of
> >>> Emacs handle storage of small vectors efficiently).  Private functions
> >>> follow the "prefix--name" convention.  And the implementation is much
> >>> simpler overall because S-expressions are much easier to parse.
> >>> ---
> >>>  emacs/Makefile.local|1 +
> >>>  emacs/notmuch-parser.el |  212 
> >>> +++
> >>>  2 files changed, 213 insertions(+)
> >>>  create mode 100644 emacs/notmuch-parser.el
> >>>
> >>> diff --git a/emacs/Makefile.local b/emacs/Makefile.local
> >>> index 456700a..a910aff 100644
> >>> --- a/emacs/Makefile.local
> >>> +++ b/emacs/Makefile.local
> >>> @@ -3,6 +3,7 @@
> >>>  dir := emacs
> >>>  emacs_sources := \
> >>>   $(dir)/notmuch-lib.el \
> >>> + $(dir)/notmuch-parser.el \
> >>>   $(dir)/notmuch.el \
> >>>   $(dir)/notmuch-query.el \
> >>>   $(dir)/notmuch-show.el \
> >>> diff --git a/emacs/notmuch-parser.el b/emacs/notmuch-parser.el
> >>> new file mode 100644
> >>> index 000..1b7cf64
> >>> --- /dev/null
> >>> +++ b/emacs/notmuch-parser.el
> >>> @@ -0,0 +1,212 @@
> >>> +;; notmuch-parser.el --- streaming S-expression parser
> >>> +;;
> >>> +;; Copyright ? Austin Clements
> >>> +;;
> >>> +;; This file is part of Notmuch.
> >>> +;;
> >>> +;; Notmuch is free software: you can redistribute it and/or modify it
> >>> +;; under the terms of the GNU General Public License as published by
> >>> +;; the Free Software Foundation, either version 3 of the License, or
> >>> +;; (at your option) any later version.
> >>> +;;
> >>> +;; Notmuch is distributed in the hope that it will be useful, but
> >>> +;; WITHOUT ANY WARRANTY; without even the implied warranty of
> >>> +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> >>> +;; General Public License for more details.
> >>> +;;
> >>> +;; You should have received a copy of the GNU General Public License
> >>> +;; along with Notmuch.  If not, see .
> >>> +;;
> >>> +;; Authors: Austin Clements 
> >>> +
> >>> +(require 'cl)
> >>> +
> >>> +(defun notmuch-sexp-create-parser (buffer)
> >>> +  "Return a streaming S-expression parser that reads from BUFFER.
> >>> +
> >>> +This parser is designed to incrementally read an S-expression
> >>> +whose structure is 

The Python bindings are now back on PyPI

2013-05-27 Thread Julian Berman
Looks like remnants from the first time it was there. I'll update that link
but it may take a bit, PyPI is being upgraded so the upload mechanism is
down currently.

Julian


On Mon, May 27, 2013 at 5:31 AM, Justus Winter <
4winter at informatik.uni-hamburg.de> wrote:

> Hi :)
>
> Quoting Julian Berman (2013-05-26 16:27:31)
> > I've queried gently to find out if anyone was interested in putting the
> Python
> > bindings back on PyPI a few times in IRC before, and didn't really see
> much
> > interest one way or the other. I saw a mailing list post that seemed
> > indifferent, though it brought up that version mismatches would cause
> runtime
> > errors,which I think is OK, it's still useful to be able to install the
> > corresponding version (e.g. homebrew on OSX currently packages notmuch
> 0.14 but
> > does not by default install the bindings, which is good for me, because
> I only
> > want them installed in a virtualenv, so I'd like to be able to `pip
> install
> > notmuch==0.14).
> >
> >
> > So I took the liberty of re-uploading them. They're here: https://
> > pypi.python.org/pypi/notmuch
>
> There are two links to documentation, one in the paragraph above
> "Requirements", one in the list below the download box. The first link
> is correct, http://pythonhosted.org/notmuch/ is severely outdated
> (0.9rc1). Dunno who put the docs there (autogenerated from pypi
> packages?).
>
> Justus
>
-- next part --
An HTML attachment was scrubbed...
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20130527/4c0f2629/attachment-0001.html>


The Python bindings are now back on PyPI

2013-05-27 Thread Justus Winter
Hi :)

Quoting Julian Berman (2013-05-26 16:27:31)
> I've queried gently to find out if anyone was interested in putting the Python
> bindings back on PyPI a few times in IRC before, and didn't really see much
> interest one way or the other. I saw a mailing list post that seemed
> indifferent, though it brought up that version mismatches would cause runtime
> errors,which I think is OK, it's still useful to be able to install the
> corresponding version (e.g. homebrew on OSX currently packages notmuch 0.14 
> but
> does not by default install the bindings, which is good for me, because I only
> want them installed in a virtualenv, so I'd like to be able to `pip install
> notmuch==0.14).
> 
> 
> So I took the liberty of re-uploading them. They're here:?https://
> pypi.python.org/pypi/notmuch

There are two links to documentation, one in the paragraph above
"Requirements", one in the list below the download box. The first link
is correct, http://pythonhosted.org/notmuch/ is severely outdated
(0.9rc1). Dunno who put the docs there (autogenerated from pypi
packages?).

Justus
-- next part --
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: signature
URL: 
<http://notmuchmail.org/pipermail/notmuch/attachments/20130527/963e50ad/attachment.pgp>


[PATCH 1/2] contrib: pick: add thread based utility functions

2013-05-27 Thread Mark Walters

Hi

David Bremner  writes:

> Mark Walters  writes:
>
>> Previously notmuch-pick had no thread based functionality. This adds a
>> macro to iterate through all messages in a thread. To simplify this it
>> adds a text-property marker to the first message of each thread.
>
>
>> +(defun notmuch-pick-get-messages-ids-thread ()
>> +  "Return all id: queries of messages in the current thread."
>> +  (let ((message-ids))
>> +(notmuch-pick-thread-mapc
>> + (lambda () (push (notmuch-pick-get-message-id) message-ids)))
>> +message-ids))
>
> As a style thing, it seems more idiomatic to me to have a map macro
> which returns a sequence, rather than faking it with mapc and push. But
> maybe that's a typical common lisp style, I don't know.

I think I agree: this is very closely copied from notmuch-show
(notmuch-show-mapc and notmuch-show-get-messages-id) so it is probably
worth staying the same.

> More importantly, in emacs 24.3 I get an infinite loop when trying to
> evaluate the update notmuch-pick.el. 

I think this is just stupidity on my part: it should be a defun rather
than a defmacro. Would you be able to test that (or I can send a new
version if you prefer)?

Also, how are you loading notmuch-pick? In my set up the macro and
function work interchangeably.

Best wishes

Mark

>
> The backtrace is below. I'm not a macro expert, but seems like too much
> is happening at compile/eval time.
>
> --
>
> Debugger entered--Lisp error: (quit)
>   (save-excursion (beginning-of-line) (get-text-property (point) 
> :notmuch-message-properties))
>   notmuch-pick-get-message-properties()
>   (or props (notmuch-pick-get-message-properties))
>   (let ((props (or props (notmuch-pick-get-message-properties (plist-get 
> props prop))
>   notmuch-pick-get-prop(:first)
>   (not (notmuch-pick-get-prop :first))
>   (while (not (notmuch-pick-get-prop :first)) (forward-line -1))
>   notmuch-pick-thread-top()
>   (save-excursion (notmuch-pick-thread-top) (progn (while (progn (progn 
> (funcall function) (forward-line)) (and (notmuch-pick-get-message-properties) 
> (not (notmuch-pick-get-prop :first) nil))
>   (lambda (function) "Iterate through all messages in the current thread\n 
> and call FUNCTION for side effects." (save-excursion 
> (notmuch-pick-thread-top) (progn (while (progn (progn (funcall function) 
> (forward-line)) (and (notmuch-pick-get-message-properties) (not 
> (notmuch-pick-get-prop :first) nil)))((lambda nil (push 
> (notmuch-pick-get-message-id) message-ids)))
>   macroexpand((notmuch-pick-thread-mapc (lambda nil (push 
> (notmuch-pick-get-message-id) message-ids))) nil)
>   macroexp--expand-all((notmuch-pick-thread-mapc (lambda nil (push 
> (notmuch-pick-get-message-id) message-ids
>   macroexp--all-forms(((notmuch-pick-thread-mapc (lambda nil (push 
> (notmuch-pick-get-message-id) message-ids))) message-ids))
>   #[1028 "\300.\300\301.\302\"\303.!.@A#..@#\207" [macroexp--cons 
> macroexp--all-clauses 1 macroexp--all-forms] 10 "\n\n(fn FORM BODY BINDINGS 
> FUN)"](((let ((message-ids)) (notmuch-pick-thread-mapc (lambda nil (push 
> (notmuch-pick-get-message-id) message-ids))) message-ids)) 
> ((notmuch-pick-thread-mapc (lambda nil (push (notmuch-pick-get-message-id) 
> message-ids))) message-ids) ((message-ids)) let)
>   macroexp--expand-all((let ((message-ids)) (notmuch-pick-thread-mapc (lambda 
> nil (push (notmuch-pick-get-message-id) message-ids))) message-ids))
>   macroexp--all-forms((lambda nil "Return all id: queries of messages in the 
> current thread." (let ((message-ids)) (notmuch-pick-thread-mapc (lambda nil 
> (push (notmuch-pick-get-message-id) message-ids))) message-ids)) 2)
>   macroexp--expand-all((function (lambda nil "Return all id: queries of 
> messages in the current thread." (let ((message-ids)) 
> (notmuch-pick-thread-mapc (lambda nil (push (notmuch-pick-get-message-id) 
> message-ids))) message-ids
>   macroexp--all-forms((defalias (quote notmuch-pick-get-messages-ids-thread) 
> (function (lambda nil "Return all id: queries of messages in the current 
> thread." (let ((message-ids)) (notmuch-pick-thread-mapc (lambda nil (push 
> (notmuch-pick-get-message-id) message-ids))) message-ids 1)
>   #[514 "\300.\301\"\211\204.
>   macroexp--expand-all((defun notmuch-pick-get-messages-ids-thread nil 
> "Return all id: queries of messages in the current thread." (let 
> ((message-ids)) (notmuch-pick-thread-mapc (lambda nil (push 
> (notmuch-pick-get-message-id) message-ids))) message-ids)))
>   macroexpand-all((defun notmuch-pick-get-messages-ids-thread nil "Return all 
> id: queries of messages in the current thread." (let ((message-ids)) 
> (notmuch-pick-thread-mapc (lambda nil (push (notmuch-pick-get-message-id) 
> message-ids))) message-ids)))
>   #[0 "   \nB.\303\300!)\207" [(defun 
> notmuch-pick-get-messages-ids-thread nil "Return all id: queries of messages 
> in the current 

[PATCH 6/6] man: document notmuch count --output=files

2013-05-27 Thread Mark Walters

David Bremner  writes:

> Other than the bikeshed about starting from zero instead of one, and not
> being completely happy with the option name --duplicate (but not being
> inspired to suggest a better one), this series looks OK to me.
>
> It seems like it would be quite useful to query based on the number of
> duplicates, but that is a much more ambitious task, I think.

This series basically looks good to me too. I agree with all of the
above points though. 

Best wishes

Mark



handle CPPFLAGS in configure and make

2013-05-27 Thread Tomi Ollila
On Sun, May 26 2013, david at tethera.net wrote:

> I wanted to enable hardening flags in the debian build (I guess other
> distros will want to do the same); I realized this is made more
> difficult by the fact that we don't handle CPPFLAGS in our build
> system. Well, if it makes us feel any better, CMake had (has?) the
> same bug.

Series LGTM. I don't know what V=1 does but probably nothing harmful :D

Tomi

>
> ___
> notmuch mailing list
> notmuch at notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch


Re: converting notmuch email to 'TODO' entry in org-mode

2013-05-27 Thread Nicholas Peihl
Hi David,

When you say org-mode template are you referring to Capture templates
for creating TODO items? Does having the %i variable in the Capture
template copy the email text you are looking for?

http://orgmode.org/manual/Template-expansion.html#Template-expansion

Nick Peihl


On 5/24/2013 12:22 AM, David Belohrad wrote:
 Dear All,

 i'm constantly facing a task: someone sends me an email to do
 something, and I'm manually copying contents of email into org-mode
 task using org-mode templates. The template itself only enters the
 'default' todo line and when it was entered, but I'd like to copy the
 contents of the email I'm currently in into that buffer.

 This would allow me to get e.g. exchange meeting request and seamlessly
 copy it into my agenda.

 is there any way how to get 'current email' (not current thread)
 contents into kill ring so I could write a small script to paste it into
 org-mode template?

 thanks

 .d.
 ___
 notmuch mailing list
 notmuch@notmuchmail.org
 http://notmuchmail.org/mailman/listinfo/notmuch



signature.asc
Description: OpenPGP digital signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


The Python bindings are now back on PyPI

2013-05-27 Thread Julian Berman
Hi,

I've queried gently to find out if anyone was interested in putting the
Python bindings back on PyPI a few times in IRC before, and didn't really
see much interest one way or the other. I saw a mailing list post that
seemed indifferent, though it brought up that version mismatches would
cause runtime errors,which I think is OK, it's still useful to be able to
install the corresponding version (e.g. homebrew on OSX currently packages
notmuch 0.14 but does not by default install the bindings, which is good
for me, because I only want them installed in a virtualenv, so I'd like to
be able to `pip install notmuch==0.14).


So I took the liberty of re-uploading them. They're here:
https://pypi.python.org/pypi/notmuch

If anyone strongly objects, or would like to take over ownership of that
package, please feel free to let me know.

Cheers,
Julian
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 1/2] contrib: pick: add thread based utility functions

2013-05-27 Thread Mark Walters

Hi

David Bremner da...@tethera.net writes:

 Mark Walters markwalters1...@gmail.com writes:

 Previously notmuch-pick had no thread based functionality. This adds a
 macro to iterate through all messages in a thread. To simplify this it
 adds a text-property marker to the first message of each thread.


 +(defun notmuch-pick-get-messages-ids-thread ()
 +  Return all id: queries of messages in the current thread.
 +  (let ((message-ids))
 +(notmuch-pick-thread-mapc
 + (lambda () (push (notmuch-pick-get-message-id) message-ids)))
 +message-ids))

 As a style thing, it seems more idiomatic to me to have a map macro
 which returns a sequence, rather than faking it with mapc and push. But
 maybe that's a typical common lisp style, I don't know.

I think I agree: this is very closely copied from notmuch-show
(notmuch-show-mapc and notmuch-show-get-messages-id) so it is probably
worth staying the same.

 More importantly, in emacs 24.3 I get an infinite loop when trying to
 evaluate the update notmuch-pick.el. 

I think this is just stupidity on my part: it should be a defun rather
than a defmacro. Would you be able to test that (or I can send a new
version if you prefer)?

Also, how are you loading notmuch-pick? In my set up the macro and
function work interchangeably.

Best wishes

Mark


 The backtrace is below. I'm not a macro expert, but seems like too much
 is happening at compile/eval time.

 --

 Debugger entered--Lisp error: (quit)
   (save-excursion (beginning-of-line) (get-text-property (point) 
 :notmuch-message-properties))
   notmuch-pick-get-message-properties()
   (or props (notmuch-pick-get-message-properties))
   (let ((props (or props (notmuch-pick-get-message-properties (plist-get 
 props prop))
   notmuch-pick-get-prop(:first)
   (not (notmuch-pick-get-prop :first))
   (while (not (notmuch-pick-get-prop :first)) (forward-line -1))
   notmuch-pick-thread-top()
   (save-excursion (notmuch-pick-thread-top) (progn (while (progn (progn 
 (funcall function) (forward-line)) (and (notmuch-pick-get-message-properties) 
 (not (notmuch-pick-get-prop :first) nil))
   (lambda (function) Iterate through all messages in the current thread\n 
 and call FUNCTION for side effects. (save-excursion 
 (notmuch-pick-thread-top) (progn (while (progn (progn (funcall function) 
 (forward-line)) (and (notmuch-pick-get-message-properties) (not 
 (notmuch-pick-get-prop :first) nil)))((lambda nil (push 
 (notmuch-pick-get-message-id) message-ids)))
   macroexpand((notmuch-pick-thread-mapc (lambda nil (push 
 (notmuch-pick-get-message-id) message-ids))) nil)
   macroexp--expand-all((notmuch-pick-thread-mapc (lambda nil (push 
 (notmuch-pick-get-message-id) message-ids
   macroexp--all-forms(((notmuch-pick-thread-mapc (lambda nil (push 
 (notmuch-pick-get-message-id) message-ids))) message-ids))
   #[1028 \300.\300\301.\302\\303.!.@A#..@#\207 [macroexp--cons 
 macroexp--all-clauses 1 macroexp--all-forms] 10 \n\n(fn FORM BODY BINDINGS 
 FUN)](((let ((message-ids)) (notmuch-pick-thread-mapc (lambda nil (push 
 (notmuch-pick-get-message-id) message-ids))) message-ids)) 
 ((notmuch-pick-thread-mapc (lambda nil (push (notmuch-pick-get-message-id) 
 message-ids))) message-ids) ((message-ids)) let)
   macroexp--expand-all((let ((message-ids)) (notmuch-pick-thread-mapc (lambda 
 nil (push (notmuch-pick-get-message-id) message-ids))) message-ids))
   macroexp--all-forms((lambda nil Return all id: queries of messages in the 
 current thread. (let ((message-ids)) (notmuch-pick-thread-mapc (lambda nil 
 (push (notmuch-pick-get-message-id) message-ids))) message-ids)) 2)
   macroexp--expand-all((function (lambda nil Return all id: queries of 
 messages in the current thread. (let ((message-ids)) 
 (notmuch-pick-thread-mapc (lambda nil (push (notmuch-pick-get-message-id) 
 message-ids))) message-ids
   macroexp--all-forms((defalias (quote notmuch-pick-get-messages-ids-thread) 
 (function (lambda nil Return all id: queries of messages in the current 
 thread. (let ((message-ids)) (notmuch-pick-thread-mapc (lambda nil (push 
 (notmuch-pick-get-message-id) message-ids))) message-ids 1)
   #[514 \300.\301\\211\204.
   macroexp--expand-all((defun notmuch-pick-get-messages-ids-thread nil 
 Return all id: queries of messages in the current thread. (let 
 ((message-ids)) (notmuch-pick-thread-mapc (lambda nil (push 
 (notmuch-pick-get-message-id) message-ids))) message-ids)))
   macroexpand-all((defun notmuch-pick-get-messages-ids-thread nil Return all 
 id: queries of messages in the current thread. (let ((message-ids)) 
 (notmuch-pick-thread-mapc (lambda nil (push (notmuch-pick-get-message-id) 
 message-ids))) message-ids)))
   #[0\nB.\303\300!)\207 [(defun 
 notmuch-pick-get-messages-ids-thread nil Return all id: queries of messages 
 in the current thread. (let ((message-ids)) (notmuch-pick-thread-mapc 
 (lambda nil (push 

Re: The Python bindings are now back on PyPI

2013-05-27 Thread Justus Winter
Hi :)

Quoting Julian Berman (2013-05-26 16:27:31)
 I've queried gently to find out if anyone was interested in putting the Python
 bindings back on PyPI a few times in IRC before, and didn't really see much
 interest one way or the other. I saw a mailing list post that seemed
 indifferent, though it brought up that version mismatches would cause runtime
 errors,which I think is OK, it's still useful to be able to install the
 corresponding version (e.g. homebrew on OSX currently packages notmuch 0.14 
 but
 does not by default install the bindings, which is good for me, because I only
 want them installed in a virtualenv, so I'd like to be able to `pip install
 notmuch==0.14).
 
 
 So I took the liberty of re-uploading them. They're here: https://
 pypi.python.org/pypi/notmuch

There are two links to documentation, one in the paragraph above
Requirements, one in the list below the download box. The first link
is correct, http://pythonhosted.org/notmuch/ is severely outdated
(0.9rc1). Dunno who put the docs there (autogenerated from pypi
packages?).

Justus


signature.asc
Description: signature
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 4/5] emacs: Streaming S-expression parser

2013-05-27 Thread Austin Clements
Quoth Mark Walters on May 25 at  9:59 am:
 
 Hi
 
 On Wed, 22 May 2013, Austin Clements amdra...@mit.edu wrote:
  On Tue, 21 May 2013, Mark Walters markwalters1...@gmail.com wrote:
  Hi
 
  This patch looks good to me. Some minor comments below.
 
  Some minor replies below.
 
  In building some other code on top of this, I found an interesting (but
  easy to fix) interface bug.  Currently, the interface is designed as if
  it doesn't matter what buffer these functions are called from, however,
  because they move point and expect this point motion to persist, it's
  actually not safe to call this interface unless the caller is in the
  right buffer anyway.  For example, if the buffer is selected in a
  window, the with-current-buffer in the parser functions will actually
  move a *temporary* point, meaning that the only way the caller can
  discover the new point is to first select the buffer for itself.  I can
  think of two solutions: 1) maintain our own mark for the parser's
  current position or 2) tweak the doc strings and code so that it reads
  from the current buffer.  1 keeps the interface the way it's currently
  documented, but complicates the parser implementation and interface and
  doesn't simplify the caller.  2 simplifies the parser and it turns out
  all callers already satisfy the requirement.
 
 I am confused by this: the docs strings for json/sexp-parse-partial-list
 both say something like Parse a partial JSON list from current buffer?
 Or do you mean the with-current-buffer in notmuch-search-process-filter?

I was referring to the lower level parser, which effectively has the
same requirement but isn't documented to and has code that pointlessly
tries to track the parsing buffer (I consider
json/sexp-parse-partial-list to be a helper).  In fact, one reason the
lower level parser didn't choke is because right now we only use it
through json/sexp-parse-partial-list, which requires that it be called
from the right buffer.

  On Sat, 18 May 2013, Austin Clements amdra...@mit.edu wrote:
  This provides the same interface as the streaming JSON parser, but
  reads S-expressions incrementally.  The only difference is that the
  `notmuch-sexp-parse-partial-list' helper does not handle interleaved
  error messages (since we now have the ability to separate these out at
  the invocation level), so it no longer takes an error function and
  does not need to do the horrible resynchronization that the JSON
  parser had to.
 
  Some implementation improvements have been made over the JSON parser.
  This uses a vector instead of a list for the parser data structure,
  since this allows faster access to elements (and modern versions of
  Emacs handle storage of small vectors efficiently).  Private functions
  follow the prefix--name convention.  And the implementation is much
  simpler overall because S-expressions are much easier to parse.
  ---
   emacs/Makefile.local|1 +
   emacs/notmuch-parser.el |  212 
  +++
   2 files changed, 213 insertions(+)
   create mode 100644 emacs/notmuch-parser.el
 
  diff --git a/emacs/Makefile.local b/emacs/Makefile.local
  index 456700a..a910aff 100644
  --- a/emacs/Makefile.local
  +++ b/emacs/Makefile.local
  @@ -3,6 +3,7 @@
   dir := emacs
   emacs_sources := \
$(dir)/notmuch-lib.el \
  + $(dir)/notmuch-parser.el \
$(dir)/notmuch.el \
$(dir)/notmuch-query.el \
$(dir)/notmuch-show.el \
  diff --git a/emacs/notmuch-parser.el b/emacs/notmuch-parser.el
  new file mode 100644
  index 000..1b7cf64
  --- /dev/null
  +++ b/emacs/notmuch-parser.el
  @@ -0,0 +1,212 @@
  +;; notmuch-parser.el --- streaming S-expression parser
  +;;
  +;; Copyright © Austin Clements
  +;;
  +;; This file is part of Notmuch.
  +;;
  +;; Notmuch is free software: you can redistribute it and/or modify it
  +;; under the terms of the GNU General Public License as published by
  +;; the Free Software Foundation, either version 3 of the License, or
  +;; (at your option) any later version.
  +;;
  +;; Notmuch is distributed in the hope that it will be useful, but
  +;; WITHOUT ANY WARRANTY; without even the implied warranty of
  +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  +;; General Public License for more details.
  +;;
  +;; You should have received a copy of the GNU General Public License
  +;; along with Notmuch.  If not, see http://www.gnu.org/licenses/.
  +;;
  +;; Authors: Austin Clements acleme...@csail.mit.edu
  +
  +(require 'cl)
  +
  +(defun notmuch-sexp-create-parser (buffer)
  +  Return a streaming S-expression parser that reads from BUFFER.
  +
  +This parser is designed to incrementally read an S-expression
  +whose structure is known to the caller.  Like a typical
  +S-expression parsing interface, it provides a function to read a
  +complete S-expression from the input.  However, it extends this
  +with an additional function that requires the next value in the
  +input to be a 

[PATCH v2 4b/4] NEWS: added information about new --stderr=FILE top level option

2013-05-27 Thread Tomi Ollila
---
 NEWS | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/NEWS b/NEWS
index a7f2ec6..990b038 100644
--- a/NEWS
+++ b/NEWS
@@ -35,6 +35,12 @@ Top level option to specify configuration file
   It's now possible to specify the configuration file to use on the
   command line using the `notmuch --config=FILE` option.
 
+Top level option to redirect writes to stderr
+
+  With `notmuch --stderr=FILE` all writes to stderr are redirected to
+  the specified file. If the file name is a plain '-', stderr is
+  written to stdout.
+
 Deprecated commands part and search-tags are removed.
 
 Bash command-line completion
-- 
1.8.1.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 0/4] emacs: Part command improvements

2013-05-27 Thread Austin Clements
This is a follow-up of sorts to id:8761ycc19t@qmul.ac.uk, where
Mark suggested that the part handling commands could all use the
correponding mm-* functions.  I ran with the idea and wound up with
this series, which, in addition to standardizing on the mm-* functions
for everything and simplifying the implementation overall, decouples
the part commands from part buttons, which removes an entire layer
from the implementation and adds the ability to invoke part commands
with point anywhere in a part (something I often find myself wanting).

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 1/4] emacs: Retain text properties when toggling buttons

2013-05-27 Thread Austin Clements
Previously, we lost any text properties applied to part buttons or
wash buttons when they were toggled because `insert' directly copies
the text properties of the string being inserted.  Fix this by
capturing the properties applied to the button beforehand and
re-applying them after inserting the new text.
---
 emacs/notmuch-show.el |2 ++
 emacs/notmuch-wash.el |2 ++
 2 files changed, 4 insertions(+)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index b0a8d8a..a080134 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -559,10 +559,12 @@ message at DEPTH in the current thread.
 (new-start (button-start button))
 (button-label (button-get button :base-label))
 (old-point (point))
+(properties (text-properties-at (point)))
 (inhibit-read-only t))
(overlay-put overlay 'invisible (not show))
(goto-char new-start)
(insert [  button-label (if show  ]  (hidden) ]))
+   (set-text-properties new-start (point) properties)
(let ((old-end (button-end button)))
  (move-overlay button new-start (point))
  (delete-region (point) old-end))
diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
index 8a68819..8fe91e1 100644
--- a/emacs/notmuch-wash.el
+++ b/emacs/notmuch-wash.el
@@ -104,9 +104,11 @@ lower).)
 (overlay (button-get cite-button 'overlay))
 (button-label (notmuch-wash-button-label overlay))
 (old-point (point))
+(properties (text-properties-at (point)))
 (inhibit-read-only t))
 (goto-char new-start)
 (insert button-label)
+(set-text-properties new-start (point) properties)
 (let ((old-end (button-end cite-button)))
   (move-overlay cite-button new-start (point))
   (delete-region (point) old-end))
-- 
1.7.10.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/4] emacs: Record part p-list in a text property

2013-05-27 Thread Austin Clements
This is similar to what we already do with the message p-list, though
we apply the part's text property to the whole part's text, in
contrast with the message p-list, which is (rather obscurely) only
applied to the first character.
---
 emacs/notmuch-lib.el  |   16 
 emacs/notmuch-show.el |   13 -
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 790136e..09ce25e 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -360,6 +360,22 @@ OBJECT.
below
string))
 
+(defun notmuch-put-text-property-if-nil (start end property value
+  optional object)
+  Like `put-text-property', but only set the property where it is nil.
+  (while ( start end)
+(let ((start-nil (text-property-any start end property nil object)))
+  (if (null start-nil)
+ ;; There are no more nil regions; exit the loop
+ (setq start end)
+   ;; Find the end of the nil region
+   (let ((end-nil
+  (or (text-property-not-all start-nil end property nil object)
+  end)))
+ ;; Set the property
+ (put-text-property start-nil end-nil property value object)
+ (setq start end-nil))
+
 (defun notmuch-logged-error (msg optional extra)
   Log MSG and EXTRA to *Notmuch errors* and signal MSG.
 
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index a080134..acd0b55 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -900,7 +900,10 @@ If HIDE is non-nil then initially hide this part.
 ;; Ensure that the part ends with a carriage return.
 (unless (bolp)
   (insert \n))
-(notmuch-show-create-part-overlays msg beg (point) hide)))
+(notmuch-show-create-part-overlays msg beg (point) hide)
+;; Record part information.  Since we already inserted subparts,
+;; don't override exiting :notmuch-part properties.
+(notmuch-put-text-property-if-nil beg (point) :notmuch-part part)))
 
 (defun notmuch-show-insert-body (msg body depth)
   Insert the body BODY at depth DEPTH in the current thread.
@@ -1404,6 +1407,14 @@ Some useful entries are:
 (notmuch-show-move-to-message-top)
 (get-text-property (point) :notmuch-message-properties)))
 
+(defun notmuch-show-get-part-properties ()
+  Return the properties of the part containing point.
+
+This is the part property list retrieved from the CLI.  Signals
+an error if there is no part containing point.
+  (or (get-text-property (point) :notmuch-part)
+  (error No message part here)))
+
 (defun notmuch-show-set-prop (prop val optional props)
   (let ((inhibit-read-only t)
(props (or props
-- 
1.7.10.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 4/4] emacs: Bind MIME part commands to . submap

2013-05-27 Thread Austin Clements
Since the part commands are no longer tied to a button, but can be
applied with point anywhere within a part, bind the part commands
keymap to . everywhere in the show buffer.  This lets you save or
view parts without having to navigate to the part button, and is
particularly useful for parts that have no button.  These key bindings
are still available without the prefix when point is over a part
button.
---
 emacs/notmuch-show.el |   27 ---
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index b33d92d..380b144 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -471,17 +471,6 @@ message at DEPTH in the current thread.
   'face 'message-mml
   :supertype 'notmuch-button-type)
 
-(defvar notmuch-show-part-button-map
-  (let ((map (make-sparse-keymap)))
-(set-keymap-parent map button-map)
-(define-key map s 'notmuch-show-save-part)
-(define-key map v 'notmuch-show-view-part)
-(define-key map o 'notmuch-show-interactively-view-part)
-(define-key map | 'notmuch-show-pipe-part)
-map)
-  Submap for button commands)
-(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
-
 (defun notmuch-show-insert-part-header (nth content-type declared-type 
optional name comment)
   (let ((button)
(base-label (concat (when name (concat name : ))
@@ -1195,6 +1184,21 @@ reset based on the original query.
   Submap for stash commands)
 (fset 'notmuch-show-stash-map notmuch-show-stash-map)
 
+(defvar notmuch-show-part-map
+  (let ((map (make-sparse-keymap)))
+(define-key map s 'notmuch-show-save-part)
+(define-key map v 'notmuch-show-view-part)
+(define-key map o 'notmuch-show-interactively-view-part)
+(define-key map | 'notmuch-show-pipe-part)
+map)
+  Submap for part commands)
+(fset 'notmuch-show-part-map notmuch-show-part-map)
+
+(defvar notmuch-show-part-button-map
+  (make-composed-keymap notmuch-show-part-map button-map)
+  Keymap for part button commands)
+(fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
+
 (defvar notmuch-show-mode-map
   (let ((map (make-sparse-keymap)))
(define-key map ? 'notmuch-help)
@@ -1237,6 +1241,7 @@ reset based on the original query.
(define-key map $ 'notmuch-show-toggle-process-crypto)
(define-key map  'notmuch-show-toggle-thread-indentation)
(define-key map t 'toggle-truncate-lines)
+   (define-key map . 'notmuch-show-part-map)
map)
   Keymap for \notmuch show\ buffers.)
 (fset 'notmuch-show-mode-map notmuch-show-mode-map)
-- 
1.7.10.4

___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 3/4] emacs: Simplify MIME part command implementation

2013-05-27 Thread Austin Clements
This unifies the part button actions and the underlying part action
functions into single interactive command that simply applies to the
part containing point using the just-added part p-list text property
instead of button properties.  Since all part actions can be performed
by applying the appropriate mm function to an mm-handle, this patch
abstracts out the creation of mm handles, making the implementations
of the part commands trivial.  This also eliminates our special
handling for part save in favor of using the appropriate mm function.

This necessarily modifies the way we handle the default part button
action, but in a way that does not change the meaning of the
notmuch-show-part-button-default-action defcustom.

Since these commands are no longer specific to buttons, this patch
eliminates the extra metadata stored with each button.  This also
eliminates one rather special-purpose macro for a collection of
general purpose part handling utilities.
---
 emacs/notmuch-show.el |  133 +
 test/emacs|4 +-
 2 files changed, 61 insertions(+), 76 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index acd0b55..b33d92d 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -474,10 +474,10 @@ message at DEPTH in the current thread.
 (defvar notmuch-show-part-button-map
   (let ((map (make-sparse-keymap)))
 (set-keymap-parent map button-map)
-(define-key map s 'notmuch-show-part-button-save)
-(define-key map v 'notmuch-show-part-button-view)
-(define-key map o 'notmuch-show-part-button-interactively-view)
-(define-key map | 'notmuch-show-part-button-pipe)
+(define-key map s 'notmuch-show-save-part)
+(define-key map v 'notmuch-show-view-part)
+(define-key map o 'notmuch-show-interactively-view-part)
+(define-key map | 'notmuch-show-pipe-part)
 map)
   Submap for button commands)
 (fset 'notmuch-show-part-button-map notmuch-show-part-button-map)
@@ -494,61 +494,11 @@ message at DEPTH in the current thread.
  (insert-button
   (concat [  base-label  ])
   :base-label base-label
-  :type 'notmuch-show-part-button-type
-  :notmuch-part nth
-  :notmuch-filename name
-  :notmuch-content-type content-type))
+  :type 'notmuch-show-part-button-type))
 (insert \n)
 ;; return button
 button))
 
-;; Functions handling particular MIME parts.
-
-(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-get-bodypart-internal ,message-id ,nth 
notmuch-show-process-crypto))
-,@body
-
-(defun notmuch-show-save-part (message-id nth optional filename content-type)
-  (notmuch-with-temp-part-buffer message-id nth
-(let ((file (read-file-name
-Filename to save as: 
-(or mailcap-download-directory ~/)
-nil nil
-filename)))
-  ;; Don't re-compress .gz  al.  Arguably we should make
-  ;; `file-name-handler-alist' nil, but that would chop
-  ;; ange-ftp, which is reasonable to use here.
-  (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion 
t
-
-(defun notmuch-show-view-part (message-id nth optional filename content-type )
-  (notmuch-with-temp-part-buffer message-id nth
-(let* ((disposition (if filename `(attachment (filename . ,filename
-  (handle (mm-make-handle (current-buffer) (list content-type)
-  nil nil disposition))
-  ;; Set the default save directory to be consistent with
-  ;; `notmuch-show-save-part'.
-  (mm-default-directory (or mailcap-download-directory ~/))
-  ;; set mm-inlined-types to nil to force an external viewer
-  (mm-inlined-types nil))
-  (mm-display-part handle
-
-(defun notmuch-show-interactively-view-part (message-id nth optional filename 
content-type)
-  (notmuch-with-temp-part-buffer message-id nth
-(let ((handle (mm-make-handle (current-buffer) (list content-type
-  (mm-interactively-view-part handle
-
-(defun notmuch-show-pipe-part (message-id nth optional filename content-type)
-  (notmuch-with-temp-part-buffer message-id nth
-(let ((handle (mm-make-handle (current-buffer) (list content-type
-  (mm-pipe-part handle
-
 ;; This is taken from notmuch-wash: maybe it should be unified?
 (defun notmuch-show-toggle-part-invisibility (optional button)
   (interactive)
@@ -570,6 +520,8 @@ message at DEPTH in the current thread.
  (delete-region (point) old-end))
(goto-char 

Re: [PATCH 4/5] emacs: Streaming S-expression parser

2013-05-27 Thread Mark Walters

Austin Clements amdra...@mit.edu writes:

 Quoth Mark Walters on May 25 at  9:59 am:
 
 Hi
 
 On Wed, 22 May 2013, Austin Clements amdra...@mit.edu wrote:
  On Tue, 21 May 2013, Mark Walters markwalters1...@gmail.com wrote:
  Hi
 
  This patch looks good to me. Some minor comments below.
 
  Some minor replies below.
 
  In building some other code on top of this, I found an interesting (but
  easy to fix) interface bug.  Currently, the interface is designed as if
  it doesn't matter what buffer these functions are called from, however,
  because they move point and expect this point motion to persist, it's
  actually not safe to call this interface unless the caller is in the
  right buffer anyway.  For example, if the buffer is selected in a
  window, the with-current-buffer in the parser functions will actually
  move a *temporary* point, meaning that the only way the caller can
  discover the new point is to first select the buffer for itself.  I can
  think of two solutions: 1) maintain our own mark for the parser's
  current position or 2) tweak the doc strings and code so that it reads
  from the current buffer.  1 keeps the interface the way it's currently
  documented, but complicates the parser implementation and interface and
  doesn't simplify the caller.  2 simplifies the parser and it turns out
  all callers already satisfy the requirement.
 
 I am confused by this: the docs strings for json/sexp-parse-partial-list
 both say something like Parse a partial JSON list from current buffer?
 Or do you mean the with-current-buffer in notmuch-search-process-filter?

 I was referring to the lower level parser, which effectively has the
 same requirement but isn't documented to and has code that pointlessly
 tries to track the parsing buffer (I consider
 json/sexp-parse-partial-list to be a helper).  In fact, one reason the
 lower level parser didn't choke is because right now we only use it
 through json/sexp-parse-partial-list, which requires that it be called
 from the right buffer.

Right I think I see. I am definitely happy with insisting on being
called from the correct buffer in the low level code.

  On Sat, 18 May 2013, Austin Clements amdra...@mit.edu wrote:
  This provides the same interface as the streaming JSON parser, but
  reads S-expressions incrementally.  The only difference is that the
  `notmuch-sexp-parse-partial-list' helper does not handle interleaved
  error messages (since we now have the ability to separate these out at
  the invocation level), so it no longer takes an error function and
  does not need to do the horrible resynchronization that the JSON
  parser had to.
 
  Some implementation improvements have been made over the JSON parser.
  This uses a vector instead of a list for the parser data structure,
  since this allows faster access to elements (and modern versions of
  Emacs handle storage of small vectors efficiently).  Private functions
  follow the prefix--name convention.  And the implementation is much
  simpler overall because S-expressions are much easier to parse.
  ---
   emacs/Makefile.local|1 +
   emacs/notmuch-parser.el |  212 
  +++
   2 files changed, 213 insertions(+)
   create mode 100644 emacs/notmuch-parser.el
 
  diff --git a/emacs/Makefile.local b/emacs/Makefile.local
  index 456700a..a910aff 100644
  --- a/emacs/Makefile.local
  +++ b/emacs/Makefile.local
  @@ -3,6 +3,7 @@
   dir := emacs
   emacs_sources := \
   $(dir)/notmuch-lib.el \
  +$(dir)/notmuch-parser.el \
   $(dir)/notmuch.el \
   $(dir)/notmuch-query.el \
   $(dir)/notmuch-show.el \
  diff --git a/emacs/notmuch-parser.el b/emacs/notmuch-parser.el
  new file mode 100644
  index 000..1b7cf64
  --- /dev/null
  +++ b/emacs/notmuch-parser.el
  @@ -0,0 +1,212 @@
  +;; notmuch-parser.el --- streaming S-expression parser
  +;;
  +;; Copyright © Austin Clements
  +;;
  +;; This file is part of Notmuch.
  +;;
  +;; Notmuch is free software: you can redistribute it and/or modify it
  +;; under the terms of the GNU General Public License as published by
  +;; the Free Software Foundation, either version 3 of the License, or
  +;; (at your option) any later version.
  +;;
  +;; Notmuch is distributed in the hope that it will be useful, but
  +;; WITHOUT ANY WARRANTY; without even the implied warranty of
  +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  +;; General Public License for more details.
  +;;
  +;; You should have received a copy of the GNU General Public License
  +;; along with Notmuch.  If not, see http://www.gnu.org/licenses/.
  +;;
  +;; Authors: Austin Clements acleme...@csail.mit.edu
  +
  +(require 'cl)
  +
  +(defun notmuch-sexp-create-parser (buffer)
  +  Return a streaming S-expression parser that reads from BUFFER.
  +
  +This parser is designed to incrementally read an S-expression
  +whose structure is known to the caller.  Like a typical
  

Re: [PATCH] emacs: Fix trimming regexp in notmuch-check-exit-status

2013-05-27 Thread David Bremner
Austin Clements amdra...@mit.edu writes:

 For such a simple regexp, this was broken in a very complicated way.


pushed, for real this time.

d
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2 1/4] cli: add global option --stderr=FILE

2013-05-27 Thread Austin Clements
Quoth Tomi Ollila on May 26 at 11:45 am:
 With this option all writes to stderr are redirected to the spesified
 FILE (or to stdout on case FILE is '-'). This is immediately useful
 in emacs interface as some of its exec intefaces do not provide
 separation of stdout and stderr.
 ---
  notmuch-client.h |  1 +
  notmuch.c| 32 
  2 files changed, 33 insertions(+)
 
 diff --git a/notmuch-client.h b/notmuch-client.h
 index 45749a6..4a3c7ac 100644
 --- a/notmuch-client.h
 +++ b/notmuch-client.h
 @@ -54,6 +54,7 @@ typedef GMimeCipherContext notmuch_crypto_context_t;
  #include sys/stat.h
  #include sys/time.h
  #include unistd.h
 +#include fcntl.h
  #include dirent.h
  #include errno.h
  #include signal.h
 diff --git a/notmuch.c b/notmuch.c
 index f51a84f..654a568 100644
 --- a/notmuch.c
 +++ b/notmuch.c
 @@ -251,6 +251,32 @@ notmuch_command (notmuch_config_t *config,
  return 0;
  }
  
 +static int
 +redirect_stderr (const char * stderr_file)
 +{
 +if (strcmp (stderr_file, -) == 0) {
 + if (dup2 (STDOUT_FILENO, STDERR_FILENO)  0) {
 + perror (dup2);
 + return 1;
 + }
 +} else {
 + int fd = open (stderr_file, O_WRONLY|O_CREAT|O_APPEND, 0644);

I think this should include O_TRUNC; otherwise it's too error-prone to
use programmatically.  The permissions should be 0666 (if the user's
umask says things should be group or world writable, it's not our job
to disagree).

 + if (fd  0) {
 + fprintf (stderr, Error: Cannot redirect stderr to '%s': %s\n,
 +  stderr_file, strerror (errno));
 + return 1;
 + }
 + if (fd != STDERR_FILENO) {
 + if (dup2 (fd, STDERR_FILENO)  0) {
 + perror (dup2);
 + return 1;
 + }
 + close (fd);
 + }
 +}
 +return 0;
 +}
 +
  int
  main (int argc, char *argv[])
  {
 @@ -259,6 +285,7 @@ main (int argc, char *argv[])
  const char *command_name = NULL;
  command_t *command;
  char *config_file_name = NULL;
 +char *stderr_file = NULL;
  notmuch_config_t *config;
  notmuch_bool_t print_help=FALSE, print_version=FALSE;
  int opt_index;
 @@ -268,6 +295,7 @@ main (int argc, char *argv[])
   { NOTMUCH_OPT_BOOLEAN, print_help, help, 'h', 0 },
   { NOTMUCH_OPT_BOOLEAN, print_version, version, 'v', 0 },
   { NOTMUCH_OPT_STRING, config_file_name, config, 'c', 0 },
 + { NOTMUCH_OPT_STRING, stderr_file, stderr, '\0', 0 },
   { 0, 0, 0, 0, 0 }
  };
  
 @@ -287,6 +315,10 @@ main (int argc, char *argv[])
   return 1;
  }
  
 +if (stderr_file  redirect_stderr (stderr_file) != 0) {
 + /* error already printed */
 + return 1;
 +}
  if (print_help)
   return notmuch_help_command (NULL, argc - 1, argv[1]);
  
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2 3/4] man: documented --stderr=FILE in notmuch.1 manual page

2013-05-27 Thread Austin Clements
Quoth Tomi Ollila on May 26 at 11:45 am:
 ---
  man/man1/notmuch.1 | 7 +++
  1 file changed, 7 insertions(+)
 
 diff --git a/man/man1/notmuch.1 b/man/man1/notmuch.1
 index 033cc10..fbd575a 100644
 --- a/man/man1/notmuch.1
 +++ b/man/man1/notmuch.1
 @@ -76,7 +76,14 @@ Print the installed version of notmuch, and exit.
  
  Specify the configuration file to use. This overrides any
  configuration file specified by ${NOTMUCH_CONFIG}.
 +.RE
 +
 +.RS 4
 +.TP 4
 +.B \-\-stderr=FILE
  
 +Redirect all writes to stderr to the specified file.
 +If the file name is a plain '-', stderr is written to stdout.

The second sentence could be just If FILE is '-', stderr is
redirected to stdout..  Same goes for the NEWS.

  .RE
  
  .SH COMMANDS

Series LGTM other than my two comments.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 2/4] emacs: Record part p-list in a text property

2013-05-27 Thread Mark Walters

A couple of small nits:

Austin Clements amdra...@mit.edu writes:

 This is similar to what we already do with the message p-list, though
 we apply the part's text property to the whole part's text, in
 contrast with the message p-list, which is (rather obscurely) only
 applied to the first character.
 ---
  emacs/notmuch-lib.el  |   16 
  emacs/notmuch-show.el |   13 -
  2 files changed, 28 insertions(+), 1 deletion(-)

 diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
 index 790136e..09ce25e 100644
 --- a/emacs/notmuch-lib.el
 +++ b/emacs/notmuch-lib.el
 @@ -360,6 +360,22 @@ OBJECT.
 below
 string))
  
 +(defun notmuch-put-text-property-if-nil (start end property value
 +optional object)
 +  Like `put-text-property', but only set the property where it is nil.
 +  (while ( start end)
 +(let ((start-nil (text-property-any start end property nil object)))
 +  (if (null start-nil)
 +   ;; There are no more nil regions; exit the loop
 +   (setq start end)
 + ;; Find the end of the nil region
 + (let ((end-nil
 +(or (text-property-not-all start-nil end property nil object)
 +end)))
 +   ;; Set the property
 +   (put-text-property start-nil end-nil property value object)
 +   (setq start end-nil))
 +
  (defun notmuch-logged-error (msg optional extra)
Log MSG and EXTRA to *Notmuch errors* and signal MSG.
  
 diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
 index a080134..acd0b55 100644
 --- a/emacs/notmuch-show.el
 +++ b/emacs/notmuch-show.el
 @@ -900,7 +900,10 @@ If HIDE is non-nil then initially hide this part.
  ;; Ensure that the part ends with a carriage return.
  (unless (bolp)
(insert \n))
 -(notmuch-show-create-part-overlays msg beg (point) hide)))
 +(notmuch-show-create-part-overlays msg beg (point) hide)
 +;; Record part information.  Since we already inserted subparts,
 +;; don't override exiting :notmuch-part properties.
 ^^^
existing

 +(notmuch-put-text-property-if-nil beg (point) :notmuch-part part)))
  
  (defun notmuch-show-insert-body (msg body depth)
Insert the body BODY at depth DEPTH in the current thread.
 @@ -1404,6 +1407,14 @@ Some useful entries are:
  (notmuch-show-move-to-message-top)
  (get-text-property (point) :notmuch-message-properties)))
  
 +(defun notmuch-show-get-part-properties ()
 +  Return the properties of the part containing point.
 +
 +This is the part property list retrieved from the CLI.  Signals
 +an error if there is no part containing point.

I think something here should say innermost part or something similar.

Best wishes

Mark


 +  (or (get-text-property (point) :notmuch-part)
 +  (error No message part here)))
 +
  (defun notmuch-show-set-prop (prop val optional props)
(let ((inhibit-read-only t)
   (props (or props
 -- 
 1.7.10.4
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 0/4] emacs: Part command improvements

2013-05-27 Thread Mark Walters
Austin Clements amdra...@mit.edu writes:

 This is a follow-up of sorts to id:8761ycc19t@qmul.ac.uk, where
 Mark suggested that the part handling commands could all use the
 correponding mm-* functions.  I ran with the idea and wound up with
 this series, which, in addition to standardizing on the mm-* functions
 for everything and simplifying the implementation overall, decouples
 the part commands from part buttons, which removes an entire layer
 from the implementation and adds the ability to invoke part commands
 with point anywhere in a part (something I often find myself wanting).

Overall I really like this series. In addition to the clean up etc it
makes it easy to export the text/plain part (which doesn't have a part
button). I have recollection of this being difficult if it is base64
encoded.

I have a few small comments

As mentioned on irc (just included here in case other people are
testing) make-composed-keymap is emacs 24 only.

This does change the default directory for saving: not serious but it's
probably worth deciding do we want to use mailcap-download-directory or
home or where emacs was started or?

I don't know if we want to keep a special keymap for the button or just
always use the . prefix; the advantage is that you don't have 's' on a
button acting differently from 's' in the text (which has annoyed me
several times) otoh it is the extra keystroke which may annoy people
too. Let the bikeshedding begin! (obviously return for the default
action would remain.

Would it be worth having . return in the part body  as the default
action ?

Finally, with message indenting it's the start/end of the part are a
little unclear. I think it's the [ of the part button at the start of
the part to the character before the [ of the next part button. In
particular on the line of a new part but before the button is still the
old part. Since parts are whole lines it would be nice if the region
were line based but I don't know if that is easy.

Best wishes

Mark



___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch