[PATCH] News: add entry for unthreaded mode

2020-09-05 Thread Mark Walters
A belated NEWS entry for the new un-threaded mode introduced in Notmuch
0.30.
---

Sorry I didn't send this for the 0.30 release. I am not sure if the
last sentence is appropriate for a NEWS item, so feel free to delete.

I don't have a development item set up (I am still mainly using emacs
24) so I am not certain the markdown is correct.

Best wishes

Mark


NEWS | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/NEWS b/NEWS
index af903252..a04c0937 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,25 @@ The minimum supported major version of GNU Emacs is now 25.1.
 
 Add support for moving between threads after notmuch-tree-from-search-thread.
 
+New `notmuch-unthreaded` mode (added in Notmuch 0.30)
+
+  Unthreaded view is a mode where each matching message is shown on a
+  separate line.
+
+  The main key entries to unthreaded view are
+
+  'u' enter a query to view in unthreaded mode (works in hello,
+  search, show and tree mode)
+
+  'U' view the current query in unthreaded mode (works from search,
+  show and tree)
+
+  Saved searches can also specify that they should open in unthreaded
+  view.
+
+  Currently it is not possible to specify the sort order: it will
+  always be newest first.
+
 Notmuch-Mutt
 
 
-- 
2.11.0
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: call for NEWS entries for 0.31

2020-09-04 Thread Mark Walters


Hi

> Here's a lightly edited output from git shortlog to jog your collective
> memories. Please send patches for NEWS for any non-trivial user visible
> changes.

I think I should have sent a news patch for the "unthreaded mode" addition 
which went into the 0.30 release (sorry about that). What is the best way to 
add it now?

Best wishes

Mark
___
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-le...@notmuchmail.org


Re: [PATCH] emacs: split-window-sensibly in tree mode with open message

2020-05-22 Thread Mark Walters


Hi

> For some historical context, split-window-sensibly was introduced in 2009 [1] 
> and the (split-window-vertically (/ (window-height) 4)) code in 2012 [2]. The 
> two functions seem pretty interchangeable.

As far as I can see the split-window-sensibly version splits the window into 
two equal parts, whereas the split-window-vertically version (deliberately) 
makes the message pane bigger than the thread pane.

I definitely prefer the current version (unsurprising as I chose the split back 
in 2012), but others may disagree.

Best wishes

Mark


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


[PATCH 1/6] notmuch-show.c: add an option for messages to be returned unthreaded

2020-02-27 Thread Mark Walters
This adds a --unthreaded option to notmuch show to tell it to return
the matching messages in an unthreaded order (so just by date).

To make it easier for users, in particular for notmuch-tree.el, we
output each message with the same "nesting" as if it were an entire
thread in its own right.
---
 notmuch-show.c | 61 --
 1 file changed, 55 insertions(+), 6 deletions(-)

diff --git a/notmuch-show.c b/notmuch-show.c
index 21792a57..cf543ed9 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1066,11 +1066,11 @@ do_show_single (void *ctx,
 
 /* Formatted output of threads */
 static int
-do_show (void *ctx,
-notmuch_query_t *query,
-const notmuch_show_format_t *format,
-sprinter_t *sp,
-notmuch_show_params_t *params)
+do_show_threaded (void *ctx,
+ notmuch_query_t *query,
+ const notmuch_show_format_t *format,
+ sprinter_t *sp,
+ notmuch_show_params_t *params)
 {
 notmuch_threads_t *threads;
 notmuch_thread_t *thread;
@@ -1107,6 +1107,50 @@ do_show (void *ctx,
 return res != NOTMUCH_STATUS_SUCCESS;
 }
 
+static int
+do_show_unthreaded (void *ctx,
+   notmuch_query_t *query,
+   const notmuch_show_format_t *format,
+   sprinter_t *sp,
+   notmuch_show_params_t *params)
+{
+notmuch_messages_t *messages;
+notmuch_message_t *message;
+notmuch_status_t status, res = NOTMUCH_STATUS_SUCCESS;
+notmuch_bool_t excluded;
+
+status= notmuch_query_search_messages (query, );
+if (print_status_query ("notmuch show", query, status))
+   return 1;
+
+sp->begin_list (sp);
+
+for (;
+notmuch_messages_valid (messages);
+notmuch_messages_move_to_next (messages)) {
+   sp->begin_list (sp);
+   sp->begin_list (sp);
+
+   message = notmuch_messages_get (messages);
+
+   notmuch_message_set_flag (message, NOTMUCH_MESSAGE_FLAG_MATCH, TRUE);
+   excluded = notmuch_message_get_flag (message, 
NOTMUCH_MESSAGE_FLAG_EXCLUDED);
+
+   if (!excluded || !params->omit_excluded) {
+   status = show_message (ctx, format, sp, message, 0, params);
+   if (status && !res)
+   res = status;
+   } else {
+   sp->null (sp);
+   }
+   notmuch_message_destroy (message);
+   sp->end (sp);
+   sp->end (sp);
+}
+sp->end (sp);
+return res;
+}
+
 enum {
 NOTMUCH_FORMAT_NOT_SPECIFIED,
 NOTMUCH_FORMAT_JSON,
@@ -1168,6 +1212,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, 
char *argv[])
 bool exclude = true;
 bool entire_thread_set = false;
 bool single_message;
+bool unthreaded = FALSE;
 
 notmuch_opt_desc_t options[] = {
{ .opt_keyword = , .name = "format", .keywords =
@@ -1181,6 +1226,7 @@ notmuch_show_command (notmuch_config_t *config, int argc, 
char *argv[])
{ .opt_bool = , .name = "exclude" },
{ .opt_bool = _thread, .name = "entire-thread",
  .present = _thread_set },
+   { .opt_bool = , .name = "unthreaded" },
{ .opt_int = , .name = "part" },
{ .opt_keyword = (int *) (), .name = "decrypt",
  .keyword_no_arg_value = "true", .keywords =
@@ -1317,7 +1363,10 @@ notmuch_show_command (notmuch_config_t *config, int 
argc, char *argv[])
params.omit_excluded = false;
}
 
-   ret = do_show (config, query, formatter, sprinter, );
+   if (unthreaded)
+   ret = do_show_unthreaded (config, query, formatter, sprinter, 
);
+   else
+   ret = do_show_threaded (config, query, formatter, sprinter, 
);
 }
 
   DONE:
-- 
2.11.0

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


[PATCH 2/6] Introduce unthreaded mode

2020-02-27 Thread Mark Walters
This commit introduces a new 'unthreaded' search mode where each
matching message is shown on a separate line. It shares almost all of
its code with tree view. Subsequent commits will allow it to diverge
slightly in appearance.
---
 emacs/notmuch-hello.el |  2 +-
 emacs/notmuch-lib.el   |  1 +
 emacs/notmuch-show.el  |  2 +-
 emacs/notmuch-tree.el  | 28 +---
 4 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index aff8beb5..858446df 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -31,7 +31,7 @@
 (declare-function notmuch-search "notmuch" ( query oldest-first 
target-thread target-line continuation))
 (declare-function notmuch-poll "notmuch" ())
 (declare-function notmuch-tree "notmuch-tree"
-  ( query query-context target buffer-name 
open-target))
+ ( query query-context target buffer-name open-target 
unthreaded))
 
 (defun notmuch-saved-search-get (saved-search field)
   "Get FIELD from SAVED-SEARCH.
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 8acad267..73b165e4 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -154,6 +154,7 @@ For example, if you wanted to remove an \"inbox\" tag and 
add an
 (define-key map "q" 'notmuch-bury-or-kill-this-buffer)
 (define-key map "s" 'notmuch-search)
 (define-key map "z" 'notmuch-tree)
+(define-key map "u" 'notmuch-unthreaded)
 (define-key map "m" 'notmuch-mua-new-mail)
 (define-key map "g" 'notmuch-refresh-this-buffer)
 (define-key map "=" 'notmuch-refresh-this-buffer)
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index ef2bf1e0..d4a1389b 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -48,7 +48,7 @@
 (declare-function notmuch-count-attachments "notmuch" (mm-handle))
 (declare-function notmuch-save-attachments "notmuch" (mm-handle  
queryp))
 (declare-function notmuch-tree "notmuch-tree"
- ( query query-context target buffer-name 
open-target))
+ ( query query-context target buffer-name open-target 
unthreaded))
 (declare-function notmuch-tree-get-message-properties "notmuch-tree" nil)
 (declare-function notmuch-read-query "notmuch" (prompt))
 (declare-function notmuch-draft-resume "notmuch-draft" (id))
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index c00315e8..80b830dd 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -42,6 +42,11 @@
 ;; the following variable is defined in notmuch.el
 (defvar notmuch-search-query-string)
 
+;; this variable distinguishes the unthreaded display from the normal tree 
display
+(defvar notmuch-tree-unthreaded nil
+  "A buffer local copy of argument unthreaded to the function notmuch-tree")
+(make-variable-buffer-local 'notmuch-tree-unthreaded)
+
 (defgroup notmuch-tree nil
   "Showing message and thread structure."
   :group 'notmuch)
@@ -890,7 +895,7 @@ Complete list of currently available key bindings:
(notmuch-sexp-parse-partial-list 'notmuch-tree-insert-forest-thread
 results-buf)
 
-(defun notmuch-tree-worker (basic-query  query-context target 
open-target)
+(defun notmuch-tree-worker (basic-query  query-context target 
open-target unthreaded)
   "Insert the tree view of the search in the current buffer.
 
 This is is a helper function for notmuch-tree. The arguments are
@@ -898,6 +903,7 @@ the same as for the function notmuch-tree."
   (interactive)
   (notmuch-tree-mode)
   (add-hook 'post-command-hook #'notmuch-tree-command-hook t t)
+  (setq notmuch-tree-unthreaded unthreaded)
   (setq notmuch-tree-basic-query basic-query)
   (setq notmuch-tree-query-context (if (or (string= query-context "")
   (string= query-context "*"))
@@ -915,7 +921,7 @@ the same as for the function notmuch-tree."
   (let* ((search-args (concat basic-query
   (if query-context (concat " and (" query-context ")"))
   ))
-(message-arg "--entire-thread"))
+(message-arg (if unthreaded "--unthreaded" "--entire-thread")))
 (if (equal (car (process-lines notmuch-command "count" search-args)) "0")
(setq search-args basic-query))
 (notmuch-tag-clear-cache)
@@ -940,7 +946,7 @@ the same as for the function notmuch-tree."
  ")")
 notmuch-tree-basic-query))
 
-(defun notmuch-tree ( query query-context target buffer-name 
open-target)
+(defun notmuch-tree ( query query-context target buffer-name 
open-target unthreaded)
   "Display threads matching QUERY in Tree View.
 
 The arguments are:
@@ -953,23 +959,31 @@ The arguments are:
   current if it appears in the tree view results.
   BUFFER-NAME: the name of the buffer to display the tree view. If
   it is nil \"*notmuch-tree\" followed by QUERY is used.
-  OPEN-TARGET: If TRUE open the target message in the message pane."
+  OPEN-TARGET: If TRUE 

[PATCH 4/6] Unthreaded mode: allow user to choose different `show out' than tree

2020-02-27 Thread Mark Walters
Tree mode allows the user to choose whether to use the split screen
displaying just the current message or a full screen displaying the
entire thread. As unthreaded mode is quite different in use the user
may want a different customisation for this mode.
---
 emacs/notmuch-tree.el | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 760eaaec..895c05f4 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -56,6 +56,16 @@
   :type 'boolean
   :group 'notmuch-tree)
 
+(defcustom notmuch-unthreaded-show-out t
+  "View selected messages in new window rather than split-pane."
+  :type 'boolean
+  :group 'notmuch-tree)
+
+(defun notmuch-tree-show-out ()
+  (if notmuch-tree-unthreaded
+  notmuch-unthreaded-show-out
+notmuch-tree-show-out))
+
 (defcustom notmuch-tree-result-format
   `(("date" . "%12s  ")
 ("authors" . "%-20s")
@@ -531,8 +541,8 @@ NOT change the database."
 Shows in split pane or whole window according to value of
 `notmuch-tree-show-out'. A prefix argument reverses the choice."
   (interactive "P")
-  (if (or (and notmuch-tree-show-out  (not arg))
- (and (not notmuch-tree-show-out) arg))
+  (if (or (and (notmuch-tree-show-out) (not arg))
+ (and (not (notmuch-tree-show-out)) arg))
   (notmuch-tree-show-message-out)
 (notmuch-tree-show-message-in)))
 
-- 
2.11.0

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


[PATCH 3/6] Unthreaded mode: allow different result format

2020-02-27 Thread Mark Walters
It is likely that the user will want a different line format for
unthreaded mode from tree mode; in particular the thread structure
graphics are unnecessary in unthreaded mode.

Add a new customisable variable and set it to something sensible.
---
 emacs/notmuch-tree.el | 27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 80b830dd..760eaaec 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -76,6 +76,31 @@ Note the author string should not contain
   :type '(alist :key-type (string) :value-type (string))
   :group 'notmuch-tree)
 
+(defcustom notmuch-unthreaded-result-format
+  `(("date" . "%12s  ")
+("authors" . "%-20s")
+((("subject" . "%s")) ." %-54s ")
+("tags" . "(%s)"))
+  "Result formatting for unthreaded Tree view. Supported fields are: date,
+authors, subject, tree, tags.  Tree means the thread tree
+box graphics. The field may also be a list in which case
+the formatting rules are applied recursively and then the
+output of all the fields in the list is inserted
+according to format-string.
+
+Note the author string should not contain
+whitespace (put it in the neighbouring fields instead).
+For example:
+(setq notmuch-tree-result-format \(\(\"authors\" . \"%-40s\"\)
+ \(\"subject\" . \"%s\"\)\)\)"
+  :type '(alist :key-type (string) :value-type (string))
+  :group 'notmuch-tree)
+
+(defun notmuch-tree-result-format ()
+  (if notmuch-tree-unthreaded
+  notmuch-unthreaded-result-format
+notmuch-tree-result-format))
+
 ;; Faces for messages that match the query.
 (defface notmuch-tree-match-face
   '((t :inherit default))
@@ -759,7 +784,7 @@ unchanged ADDRESS if parsing fails."
   ;; We need to save the previous subject as it will get overwritten
   ;; by the insert-field calls.
   (let ((previous-subject notmuch-tree-previous-subject))
-(insert (notmuch-tree-format-field-list notmuch-tree-result-format msg))
+(insert (notmuch-tree-format-field-list (notmuch-tree-result-format) msg))
 (notmuch-tree-set-message-properties msg)
 (notmuch-tree-set-prop :previous-subject previous-subject)
 (insert "\n")))
-- 
2.11.0

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


[PATCH 6/6] notmuch-hello/jump: allow saved searches to specify unthreaded mode

2020-02-27 Thread Mark Walters
Saved searches in notmuch-hello and notmuch-jump can specify whether
to use search mode or tree mode. This adds an option for them to
specify unthreaded mode.
---
 emacs/notmuch-hello.el | 29 +++--
 emacs/notmuch-jump.el  | 10 +++---
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el
index 858446df..ab6ee798 100644
--- a/emacs/notmuch-hello.el
+++ b/emacs/notmuch-hello.el
@@ -32,6 +32,9 @@
 (declare-function notmuch-poll "notmuch" ())
 (declare-function notmuch-tree "notmuch-tree"
  ( query query-context target buffer-name open-target 
unthreaded))
+(declare-function notmuch-unthreaded
+ ( query query-context target buffer-name 
open-target))
+
 
 (defun notmuch-saved-search-get (saved-search field)
   "Get FIELD from SAVED-SEARCH.
@@ -99,7 +102,8 @@ searches so they still work in customize."
 (group :format "%v" :inline t (const :format "" 
:search-type)
(choice :tag " Search Type"
(const :tag "Search mode" nil)
-   (const :tag "Tree mode" tree))
+   (const :tag "Tree mode" tree)
+   (const :tag "Unthreaded mode" 
unthreaded))
 
 (defcustom notmuch-saved-searches
   `((:name "inbox" :query "tag:inbox" :key ,(kbd "i"))
@@ -122,10 +126,10 @@ a plist. Supported properties are
   :sort-order  Specify the sort order to be used for the search.
Possible values are 'oldest-first 'newest-first or
nil. Nil means use the default sort order.
-  :search-type Specify whether to run the search in search-mode
-   or tree mode. Set to 'tree to specify tree
-   mode, set to nil (or anything except tree) to
-   specify search mode.
+  :search-type Specify whether to run the search in search-mode,
+   tree mode or unthreaded mode. Set to 'tree to specify tree
+   mode, 'unthreaded to specify unthreaded mode, and set to nil
+   (or anything except tree and unthreaded) to specify search 
mode.
 
 Other accepted forms are a cons cell of the form (NAME . QUERY)
 or a list of the form (NAME QUERY COUNT-QUERY)."
@@ -437,13 +441,18 @@ diagonal."
  append (notmuch-hello-reflect-generate-row ncols nrows row list
 
 (defun notmuch-hello-widget-search (widget  ignore)
-  (if (widget-get widget :notmuch-search-type)
-  (notmuch-tree (widget-get widget
-   :notmuch-search-terms))
+  (cond
+   ((eq (widget-get widget :notmuch-search-type) 'tree)
+(notmuch-tree (widget-get widget
+ :notmuch-search-terms)))
+   ((eq (widget-get widget :notmuch-search-type) 'unthreaded)
+(notmuch-unthreaded (widget-get widget
+   :notmuch-search-terms)))
+   (t
 (notmuch-search (widget-get widget
:notmuch-search-terms)
(widget-get widget
-   :notmuch-search-oldest-first
+   :notmuch-search-oldest-first)
 
 (defun notmuch-saved-search-count (search)
   (car (process-lines notmuch-command "count" search)))
@@ -579,7 +588,7 @@ with `notmuch-hello-query-counts'."
 (newest-first nil)
 (oldest-first t)
 (otherwise notmuch-search-oldest-first)))
-(search-type (eq (plist-get elem :search-type) 'tree))
+(search-type (plist-get elem :search-type))
 (msg-count (plist-get elem :count)))
(widget-insert (format "%8s "
   (notmuch-hello-nice-number msg-count)))
diff --git a/emacs/notmuch-jump.el b/emacs/notmuch-jump.el
index 3e20b8c7..1cdf5b50 100644
--- a/emacs/notmuch-jump.el
+++ b/emacs/notmuch-jump.el
@@ -56,9 +56,13 @@ fast way to jump to a saved search from anywhere in Notmuch."
   (oldest-first t)
   (otherwise (default-value 'notmuch-search-oldest-first)
(push (list key name
-   (if (eq (plist-get saved-search :search-type) 'tree)
-   `(lambda () (notmuch-tree ',query))
- `(lambda () (notmuch-search ',query ',oldest-first
+   (cond
+((eq (plist-get saved-search :search-type) 'tree)
+ `(lambda () (notmuch-tree ',query)))
+((eq (plist-get saved-search :search-type) 'unthreaded)
+ `(lambda () (notmuch-unthreaded ',query)))
+(t
+ `(lambda () (notmuch-search ',query 
',oldest-first)
   

[PATCH 5/6] Add a U binding to switch to unthreaded from other views

2020-02-27 Thread Mark Walters
We have shortcuts S and Z to let the user switch to Search view and
Tree view with the current search. Add U to let the user switch to
unthreaded view from the current search, and ensure that S and Z
switch from unthreaded to search and tree veiew respectively.
---
 emacs/notmuch-show.el | 10 ++
 emacs/notmuch-tree.el | 23 +--
 emacs/notmuch.el  |  6 ++
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index d4a1389b..214e279f 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -50,6 +50,8 @@
 (declare-function notmuch-tree "notmuch-tree"
  ( query query-context target buffer-name open-target 
unthreaded))
 (declare-function notmuch-tree-get-message-properties "notmuch-tree" nil)
+(declare-function notmuch-unthreaded
+ ( query query-context target buffer-name 
open-target))
 (declare-function notmuch-read-query "notmuch" (prompt))
 (declare-function notmuch-draft-resume "notmuch-draft" (id))
 
@@ -1471,6 +1473,7 @@ reset based on the original query."
   (let ((map (make-sparse-keymap)))
 (set-keymap-parent map notmuch-common-keymap)
 (define-key map "Z" 'notmuch-tree-from-show-current-query)
+(define-key map "U" 'notmuch-unthreaded-from-show-current-query)
 (define-key map (kbd "") 'widget-backward)
 (define-key map (kbd "M-TAB") 'notmuch-show-previous-button)
 (define-key map (kbd "") 'notmuch-show-previous-button)
@@ -1559,6 +1562,13 @@ All currently available key bindings:
notmuch-show-query-context
(notmuch-show-get-message-id)))
 
+(defun notmuch-unthreaded-from-show-current-query ()
+  "Call notmuch unthreaded with the current query"
+  (interactive)
+  (notmuch-unthreaded notmuch-show-thread-id
+ notmuch-show-query-context
+ (notmuch-show-get-message-id)))
+
 (defun notmuch-show-move-to-message-top ()
   (goto-char (notmuch-show-message-top)))
 
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 895c05f4..9a83292c 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -294,6 +294,8 @@ FUNC."
 (define-key map [remap notmuch-jump-search] 
(notmuch-tree-close-message-pane-and #'notmuch-jump-search))
 
 (define-key map "S" 'notmuch-search-from-tree-current-query)
+(define-key map "U" 'notmuch-unthreaded-from-tree-current-query)
+(define-key map "Z" 'notmuch-tree-from-unthreaded-current-query)
 
 ;; these use notmuch-show functions directly
 (define-key map "|" 'notmuch-show-pipe-message)
@@ -474,6 +476,18 @@ NOT change the database."
 (notmuch-tree-close-message-window)
 (notmuch-tree query)))
 
+(defun notmuch-unthreaded-from-tree-current-query ()
+  "Switch from tree view to unthreaded view"
+  (interactive)
+  (unless notmuch-tree-unthreaded
+(notmuch-tree-refresh-view 'unthreaded)))
+
+(defun notmuch-tree-from-unthreaded-current-query ()
+  "Switch from unthreaded view to tree view"
+  (interactive)
+  (when notmuch-tree-unthreaded
+(notmuch-tree-refresh-view 'tree)))
+
 (defun notmuch-search-from-tree-current-query ()
   "Call notmuch search with the current query"
   (interactive)
@@ -635,19 +649,24 @@ message will be \"unarchived\", i.e. the tag changes in
   (when (window-live-p notmuch-tree-message-window)
 (notmuch-tree-show-message-in)))
 
-(defun notmuch-tree-refresh-view ()
+(defun notmuch-tree-refresh-view ( view)
   "Refresh view."
   (interactive)
   (when (get-buffer-process (current-buffer))
 (error "notmuch tree process already running for current buffer"))
   (let ((inhibit-read-only t)
(basic-query notmuch-tree-basic-query)
+   (unthreaded (cond ((eq view 'unthreaded) t)
+ ((eq view 'tree) nil)
+ (t notmuch-tree-unthreaded)))
(query-context notmuch-tree-query-context)
(target (notmuch-tree-get-message-id)))
 (erase-buffer)
 (notmuch-tree-worker basic-query
 query-context
-target)))
+target
+nil
+unthreaded)))
 
 (defun notmuch-tree-thread-top ()
   (when (notmuch-tree-get-message-properties)
diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index 0d68d123..f4789b4f 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -190,6 +190,7 @@ there will be called at other points of notmuch execution."
 (define-key map (kbd "RET") 'notmuch-search-show-thread)
 (define-key map (kbd "M-RET") 'notmuch-tree-from-search-thread)
 (define-key map "Z" 'notmuch-tree-from-search-current-query)
+(define-key map "U" 'notmuch-unthreaded-from-search-current-query)
 map)
   "Keymap for \"notmuch search\" buffers.")
 (fset 'notmuch-search-mode-map notmuch-search-mode-map)
@@ -523,6 +524,11 @@ thread."
   (interactive)
   (notmuch-tree notmuch-search-query-string))
 
+(defun 

[PATCH 0/6] Add an unthreaded mode

2020-02-27 Thread Mark Walters
This series adds an unthreaded mode. In this mode all messages
matching the query are shown, one per line, in unthreaded (reverse)
date order. For some discussion of such a mode see
id:87mupcay3s@tethera.net and subsequent thread.

The main key bindings are u to run an unthreaded search, and U to
rerun the current query in unthreaded view.

Most of the functionality comes from the existing notmuch-tree code so
it is relatively simple.

I have been running some very similar code for just over a year and
finally found time to tidy and submit it.

One note: --entire-thread=false outputs just the matching messages
(not the entire threads) but still in threaded order, and this option
can be used by pre-existing emacs functionality (depending on user
settings); this is why I added a new --unthreaded option.

Best wishes

Mark


Mark Walters (6):
  notmuch-show.c: add an option for messages to be returned unthreaded
  Introduce unthreaded mode
  Unthreaded mode: allow different result format
  Unthreaded mode: allow user to choose different `show out' than tree
  Add a U binding to switch to unthreaded from other views
  notmuch-hello/jump: allow saved searches to specify unthreaded mode

 emacs/notmuch-hello.el | 31 +++--
 emacs/notmuch-jump.el  | 10 --
 emacs/notmuch-lib.el   |  1 +
 emacs/notmuch-show.el  | 12 ++-
 emacs/notmuch-tree.el  | 92 +++---
 emacs/notmuch.el   |  6 
 notmuch-show.c | 61 +
 7 files changed, 180 insertions(+), 33 deletions(-)

-- 
2.11.0

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


Re: [PATCH] emacs: tree: support fold/unfold thread

2019-03-23 Thread Mark Walters


Hello

> This patch allow the user to fold/unfold a thread in the current tree
> buffer by pressing "t" key.

This looks like a really nice feature! I will try and review the code
properly soon, but have some preliminary comments.

> By default a string is displayed at the beginning of the overlay to
> indicate that this thread is folded.

I wonder if it would make sense to make the [] replace the "tree
symbol" (-> etc)? This would mean that it was always on the screen and the
tree symbol looks a little odd with a collapsed thread.

Secondly, I wonder whether making it collapse just the subthread below
the current message (ie a subtree) would be nice? To me that feels more
generic, but might be more effort than it's worth as the code would need
to deal with nested folds. Then C-u t could do exactly the current
folding (ie the whole thread). But this is just a thought.

Finally a comment on the code

> +The overlay found is located between START and END position in BUFFER."
> +  (seq-find (lambda (ov)

> +(defun notmuch-tree-clean-up-overlays ()
> +  "Remove overlays not referenced to any buffer"
> +  (setq notmuch-tree-overlays (seq-filter #'overlay-buffer 
> notmuch-tree-overlays)))

seq-find and seq-filter are emacs 25+ only I think; at least they don't
seem to be in emacs24 which I think we still support. Perhaps some cl
functions can be used (eg remove-if-not) instead?

Best wishes

Mark

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


Re: [emacs] message list view

2018-12-12 Thread Mark Walters


Dear All

I think this could be very useful -- indeed I currently have been running some 
scruffy patches implementing this for the last couple of months.

What I have done is modify notmuch-show.c so that you can pass a --unthreaded 
option and it returns each message as if it were a thread on its own. Then 
notmuch-tree basically "just works" with this output.

The reason I like it was I found I was sometimes missing messages when multiple 
messages arrived in the same thread.

I haven't tried Bremner's suggestion of just not passing entire-thread; it 
would give a slightly odd ordering of the messages (all matching messages by 
thread, and in thread order) rather than just date order.

My patches are against a rather outdated version of notmuch but I can probably 
update and post relatively easily if people would like to try it.

Best wishes

Mark


On Tue, 11 Dec 2018, Jeff Templon  wrote:
> Hi,
>
> David Bremner  writes:
>
>> David Edmondson  writes:
>>
>>> On Tuesday, 2018-12-11 at 11:20:55 -04, David Bremner wrote:
>>>
 Discussion on #notmuch the other day led me to wonder how useful a
 "message list" view would be. Essentially this would display a single
 line summary for individual messages matching a query and allow
 e.g. tagging operations or "opening" the message to get a more complete
 view.
>
>
> I think it'd be useful.  I'll give you an example that always bugs me:
> if I look in "unread" (the standard startup screen search) and see some
> new message in a long thread of which I've deleted a bunch of messages,
> and I type 'd' to delete, it actually first undeletes (or to be precise,
> it toggles the already-present deleted tag on) all the already-deleted
> messages in the thread, then I have to hit 'd' again to delete all of
> them.
>
> If it were a message view instead of a thread view, I could just delete
> the dang message ;-)
>
> JT
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> https://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] lib: add support for thread: queries

2017-10-20 Thread Mark Walters

Hi

On Mon, 16 Oct 2017, Jani Nikula  wrote:
> Add support for querying threads using message-ids in addition to
> thread-ids. The main benefit is that thread queries via message-ids
> are portable across databases, re-indexing, and thread joining, while
> thread ids can be somewhat transient. A thread: query can
> be shared between notmuch users, while a thread: query may
> cease to work after the regular delivery of a message that joins
> threads.

I like the idea.

Just one thought -- is any form of recursion allowed in this sort of
operator so could we have thread:'some query' which would expand to all
threads matching the query? I am guessing this may not be possible now
but would it be worth requiring the thread form to be
thread:id: rather than thread:?

Best wishes

Mark


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


Re: notmuch-emacs: Fcc to top-level directory given by database.path

2017-10-02 Thread Mark Walters

Hi

On Sun, 01 Oct 2017, Arun Isaac <arunis...@systemreboot.net> wrote:
> Mark Walters <markwalters1...@gmail.com> writes:
>
>> Incidentally, I think "/" is an alternative for the fcc line which
>> already works, which is "\"/\" in notmuch-fcc-dirs.
>
> Perhaps, notmuch should be made to tolerate a "/" at the beginning of the
> Fcc folder argument. That is, notmuch should not complain about absolute
> paths, and it should interpret these as relative to the root. To
> maintain backward compatibility, we could add a "/" at the beginning if
> it is not already there.
>
> So,
>
> "/" => database.path
> "/sent" => database.path/sent
> "sent" => database.path/sent
>
> etc.
>
> Is this a better idea?

The reason for the warning is that this behaviour is completely
different from what you would get with normal file fcc. Given that, I am
a little reluctant to drop the warning.

Best wishes

Mark

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


Re: [PATCH 0/6] Sort by from and subject

2017-09-30 Thread Mark Walters

Hi

On Sat, 30 Sep 2017, Jani Nikula  wrote:
> On Sat, 30 Sep 2017, William Casarin  wrote:
>> Jani Nikula  writes:
>>
>>> I think there are two considerations here:
>>>
>>> First, is this something we want to have? Is this generally useful?
>>
>> Sorting by from and subject are in most mail clients (mutt, gnus, outlook...)
>
> Which of those display results as threads, and of those that do, how do
> they sort the threads? In the notmuch case, the threads would be sorted
> based on one of the matching messages. Which one should it be? For
> current date based searches, the message used for sorting is also
> selected based on date.

I agree with Jani that for thread based views sorting by from is a
little odd -- sorting by subject less so as that is mostly constant in a
thread.

But allowing sorting by from in message based views could be useful. If
we are looking at the notmuch-emacs frontend then that would be in tree
view. This calls notmuch-show.c from the CLI, so that is the place I
would suggest we do this. If notmuch-show.c returns each message as "if
it were in its own thread" in the sense of the sexp output (see
devel/schemata) I think notmuch-tree would just work.

>>> There's still the issue of From: and Subject: needing more heuristic for
>>> useful sorting that I mentioned in id:87efrm70ai@nikula.org.
>>
>> I think I understand what you mean in id:87efrm70ai@nikula.org but I
>> don't have enough knowledge of notmuch to implement what you're asking
>> :(. I believe these are rare cases because I haven't ran into the issue
>> you described?
>
> Look at the subject line of this message. Should it be sorted starting
> at "Re:", "[PATCH", or "Sort"? You could argue for and against any one
> of them. Contrast that with the thread sorting above: If the matching
> message in this thread changes from one with vs. without "Re:", the sort
> placement of the thread could change considerably.
>
> It's common for some corporate mail systems to switch "Firstname
> Lastname" in messages to "Lastname, Firstname". Should we do something
> about that?
>
> Arguably we could do the sorting first, and think of ways to improve it
> afterwards.

These are concerns, but I agree that we try some form of sorting first
and then think about improving it. I think the above as an interface to
notmuch-tree should work -- I had something similar in the very early
days of notmuch-tree (when it was notmuch-pick) but dropped it when
trying to keep the patch set small enough to be even vaguely manageable.

Best wishes

Mark

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


Re: Guess 'From:' when doing notmuch reply

2017-09-30 Thread Mark Walters

> One option would be for you to customize the output of notmuch-reply in
> Emacs. I think the package message-templ (unfortunately only in
> marmalade, debian, and my git repo) provides tools that could help with
> that. If you want to investigate it's at:
>
> http://pivot.cs.unb.ca/git?p=message-templ.git;a=summary

Just a thought: would it be worth including this in contrib?

Best wishes

Mark


>
> There may well be better tools for message-mode.
>
> d
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> https://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: notmuch.el: "wash" date in message display

2017-09-30 Thread Mark Walters

On Thu, 21 Sep 2017, Tomi Ollila  wrote:
> On Wed, Sep 20 2017, Matt Armstrong wrote:
>
>> I miss some of the Gnus "wash" functions available for message display.
>> There was one that either reformatted the Date: header into my time
>> zone, or displayed the Date in terms of elapsed time from now (e.g. 1
>> hour ago, 1 day ago, etc.).  I don't remember which, but I'd be happy
>> with either.
>
> I personally use 
>
> http://mid.mail-archive.com/1427132722-20346-1-git-send-email-tomi.ollila@iki.fi
>
> -- this shows (date) in local time in addition to the default Date:
> in case time zones differ...

Hi

I agree that something like this would be useful. I made some
suggestions further down in the thread Tomi linked to above: in
particular I think there should be three possibilities -- show original
date, date in my timezone, or both.

As three of us seem to be thinking of patching/writing our snippets to
do this, I think it could well be worth including in notmuch. I am happy
to review a patch.

Best wishes

Mark

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


Re: notmuch-emacs: Fcc to top-level directory given by database.path

2017-09-30 Thread Mark Walters
On Sun, 24 Sep 2017, David Bremner  wrote:
> Arun Isaac  writes:
>
>>> In any case I've noted your feature request/bug-report. It doesn't sound
>>> terribly difficult to change, but it will need someone motivated to
>>> think about all of the related details like updating the test suite and
>>> changing docstrings.
>>
>> I can contribute this patch. Shall I make it such that if the folder
>> part of `notmuch-fcc-dirs' is an empty string, then `notmuch insert' is
>> called without a `--folder=' argument?
>
> Sounds reasonable to me. Any objections Mark?

I am not sure: do we want an empty Fcc header to save the message to the
root folder? (At the moment the insert fails for an empty Fcc header
which isn't good either) In general though are suggesting Fcc header
lines of the form

""

or

"" +sent

save to the root folder?

Apart from the empty header case that sounds fine. I am not sure about
the documentation for it -- the variable is already a little
complicated, so I wouldn't want to clutter it further.

Incidentally, I think "/" is an alternative for the fcc line which
already works, which is "\"/\" in notmuch-fcc-dirs.

Best wishes

Mark



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


Re: notmuch-emacs: Fcc to top-level directory given by database.path

2017-09-23 Thread Mark Walters

On Sat, 23 Sep 2017, David Bremner  wrote:
> Arun Isaac  writes:
>
>> I am using notmuch-emacs, and I would like to Fcc my sent mail to the
>> top-level directory given by database.path, instead of using a folder
>> like "sent" relative to the top-level directory.
>>
>> The function `notmuch-maildir-notmuch-insert-current-buffer' in
>> notmuch-maildir-fcc.el calls `notmuch insert' with the `--folder='
>> argument. I would like it to not do this.
>
> Do you happen to know if it calls with an empty string as the folder
> name? It would be consistent with searching for that to insert at the
> top level.
>
> In any case I've noted your feature request/bug-report. It doesn't sound
> terribly difficult to change, but it will need someone motivated to
> think about all of the related details like updating the test suite and
> changing docstrings.

Alternatively, does just using / as the folder work?

Best wishes

Mark

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


Re: [PATCH 2/2] emacs: show: allow user to insert rfc822 parts as messages

2017-08-28 Thread Mark Walters
>
>> +  (let* ((folder
>> +  (read-from-minibuffer "Folder/tags to insert part to: "
>> +notmuch-show-part-notmuch-insert-folder)))
>> +(mm-with-unibyte-buffer
>> + (mm-insert-part handle)
>> + (notmuch-maildir-fcc-with-notmuch-insert folder nil "Folder/tags to 
>> insert part to")
>> + (message nil
>
> Why this? It would be nice to have a comment explaining it.

Assuming you mean the message nil bit, This is actually me being dim. I
want to remove things like the retry message. But it would be much better
to make the insert-part function return something saying whether it
succeeded or not, and then give a useful message.

Best wishes

Mark

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


Re: [PATCH 1/2] emacs: maildir fcc make insert more flexible

2017-08-28 Thread Mark Walters

Hi

Thanks for the review.

On Mon, 28 Aug 2017, David Edmondson <d...@dme.org> wrote:
> On Monday, 2017-08-28 at 08:32:21 +0100, Mark Walters wrote:
>
>> This changeset makes the function
>> notmuch-maildir-fcc-with-notmuch-insert slightly more flexible by
>> allowing some of the prompts to be controlled by the caller.
>> ---
>>  emacs/notmuch-maildir-fcc.el | 16 ++--
>>  1 file changed, 10 insertions(+), 6 deletions(-)
>>
>> diff --git a/emacs/notmuch-maildir-fcc.el b/emacs/notmuch-maildir-fcc.el
>> index 1551e8b..acff24d 100644
>> --- a/emacs/notmuch-maildir-fcc.el
>> +++ b/emacs/notmuch-maildir-fcc.el
>> @@ -227,7 +227,7 @@ should be a list of tag changes to apply to the inserted 
>> message."
>>  (apply 'notmuch-call-notmuch-process
>> :stdin-string (buffer-string) "insert" args)))
>>  
>> -(defun notmuch-maildir-fcc-with-notmuch-insert (fcc-header  create)
>> +(defun notmuch-maildir-fcc-with-notmuch-insert (fcc-header  create 
>> header-name)
>
> Given that this is not FCC specific, perhaps rename it?

Yes that might make sense.

>
>>"Store message with notmuch insert.
>>  
>>  The fcc-header should be of the form \"folder +tag1 -tag2\" where
>
> I realise that this patch set didn't add this string, but it is mildly
> ridiculous. There's no reason that we couldn't use a list, where a
> leading “+” or “-” indicates a tag and anything else is a folder.
>
> Even two variables (one for folder and another for tags) would be an
> improvement

The reason for this choice is that, when writing the postpone code, I
wanted to keep within the message mode compose world, which has the fcc
header as a string.

I think I would also only like to be queried once when inserting. Or are
you suggesting that the user types in a lisp list?

Best wishes

Mark




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


[PATCH 0/2] emacs: allow message/rfc822 to be inserted in the mailstore

2017-08-28 Thread Mark Walters
Several people including id:87bmnlko2o.fsf@len have asked to be able
to reply directly to message/rfc822 messages from the emacs
frontend. Doing that in emacs would be likely to be a little fragile
as all other replies are generated by the cli code.

This pair of patches provide an alternative approach: let the user
insert the attached message directly into the mailstore. Once it is
there, the user can reply as normal.

I have been running something like this for a long time (see
id:1463744295-12533-1-git-send-email-markwalters1...@gmail.com for my
earlier version) with no problems.

This new version includes some better error checking, and allows the
user to specify tags for the inserted message. The new version is not
heavily tested but seems to work.

Best wishes

Mark




Mark Walters (2):
  emacs: maildir fcc make insert more flexible
  emacs: show: allow user to insert rfc822 parts as messages

 emacs/notmuch-maildir-fcc.el | 16 ++--
 emacs/notmuch-show.el| 35 +++
 2 files changed, 45 insertions(+), 6 deletions(-)

-- 
2.1.4

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


[PATCH 1/2] emacs: maildir fcc make insert more flexible

2017-08-28 Thread Mark Walters
This changeset makes the function
notmuch-maildir-fcc-with-notmuch-insert slightly more flexible by
allowing some of the prompts to be controlled by the caller.
---
 emacs/notmuch-maildir-fcc.el | 16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/emacs/notmuch-maildir-fcc.el b/emacs/notmuch-maildir-fcc.el
index 1551e8b..acff24d 100644
--- a/emacs/notmuch-maildir-fcc.el
+++ b/emacs/notmuch-maildir-fcc.el
@@ -227,7 +227,7 @@ should be a list of tag changes to apply to the inserted 
message."
 (apply 'notmuch-call-notmuch-process
   :stdin-string (buffer-string) "insert" args)))
 
-(defun notmuch-maildir-fcc-with-notmuch-insert (fcc-header  create)
+(defun notmuch-maildir-fcc-with-notmuch-insert (fcc-header  create 
header-name)
   "Store message with notmuch insert.
 
 The fcc-header should be of the form \"folder +tag1 -tag2\" where
@@ -239,7 +239,8 @@ quoting each space with an immediately preceding backslash
 or surrounding the entire folder name in double quotes.
 
 If CREATE is non-nil then create the folder if necessary."
-  (let* ((args (split-string-and-unquote fcc-header))
+  (let* ((header-name (or header-name "Fcc header"))
+(args (split-string-and-unquote fcc-header))
 (folder (car args))
 (tags (cdr args)))
 (condition-case nil
@@ -250,14 +251,17 @@ If CREATE is non-nil then create the folder if necessary."
   ;; how to deal with it.
   (error
(let ((response (notmuch-read-char-choice
-   "Insert failed: (r)etry, (c)reate folder, (i)gnore, or 
(e)dit the header? "
+   (concat
+"Insert failed: (r)etry, (c)reate folder, (i)gnore, or 
(e)dit the "
+header-name "? ")
'(?r ?c ?i ?e
 (case response
-  (?r (notmuch-maildir-fcc-with-notmuch-insert fcc-header))
-  (?c (notmuch-maildir-fcc-with-notmuch-insert fcc-header 't))
+  (?r (notmuch-maildir-fcc-with-notmuch-insert fcc-header nil 
header-name))
+  (?c (notmuch-maildir-fcc-with-notmuch-insert fcc-header 't 
header-name))
   (?i 't)
   (?e (notmuch-maildir-fcc-with-notmuch-insert
-   (read-from-minibuffer "Fcc header: " fcc-header)
+   (read-from-minibuffer (concat header-name ": ") fcc-header)
+   nil header-name
 
 
 ;
-- 
2.1.4

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


[PATCH 2/2] emacs: show: allow user to insert rfc822 parts as messages

2017-08-28 Thread Mark Walters
This adds a part-handler function that uses notmuch-insert to insert
an rfc822 part as a message in its own right. This allows the user to
reply directly to that message.

We use notmuch-maildir-fcc-with-notmuch-insert as that has builtin
error handling/retry functionality, and it allows the user to specify
tags to identify the inserted message.

The format of the folder/tags line is the same as for Fcc: headers
when using notmuch insert.
---
 emacs/notmuch-show.el | 35 +++
 1 file changed, 35 insertions(+)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index cd901e4..b3717d0 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -143,6 +143,20 @@ indentation."
 (const :tag "View interactively"
notmuch-show-interactively-view-part)))
 
+(defcustom notmuch-show-part-notmuch-insert-folder ""
+  "Default folder/tags to use when inserting rfc822 parts into the database.
+
+It should be of the form \"folder +tag1 -tag2\" where folder is
+the folder (relative to the notmuch mailstore) to store the
+message in, and tag1 and tag2 are tag changes to apply to the
+stored message. This string is split using
+`split-string-and-unquote', so a folder name containing spaces
+can be specified by quoting each space with an immediately
+preceding backslash or surrounding the entire folder name in
+double quotes."
+  :group 'notmuch-show
+  :type 'string)
+
 (defcustom notmuch-show-only-matching-messages nil
   "Only matching messages are shown by default."
   :type 'boolean
@@ -1448,6 +1462,7 @@ reset based on the original query."
 (define-key map "o" 'notmuch-show-interactively-view-part)
 (define-key map "|" 'notmuch-show-pipe-part)
 (define-key map "m" 'notmuch-show-choose-mime-of-part)
+(define-key map "i" 'notmuch-show-notmuch-insert-part)
 (define-key map "?" 'notmuch-subkeymap-help)
 map)
   "Submap for part commands")
@@ -2463,6 +2478,26 @@ part to be treated as if it had that mime-type."
   (interactive)
   (notmuch-show-apply-to-current-part-handle #'mm-pipe-part))
 
+(defun notmuch-show--notmuch-insert-handle (handle)
+  "Notmuch insert the part associated with HANDLE."
+  ;; This is based on mm-pipe-part
+  (let* ((folder
+ (read-from-minibuffer "Folder/tags to insert part to: "
+   notmuch-show-part-notmuch-insert-folder)))
+(mm-with-unibyte-buffer
+ (mm-insert-part handle)
+ (notmuch-maildir-fcc-with-notmuch-insert folder nil "Folder/tags to 
insert part to")
+ (message nil
+
+(defun notmuch-show-notmuch-insert-part ()
+  "If the current part is rfc822 then insert into the mailstore"
+  (interactive)
+  (let* ((part (notmuch-show-get-part-properties))
+(computed-type (plist-get part :computed-type)))
+(if (notmuch-match-content-type computed-type "message/rfc822")
+   (notmuch-show-apply-to-current-part-handle
+#'notmuch-show--notmuch-insert-handle)
+  (message "Not a message/rfc822 part."
 
 (defun notmuch-show--mm-display-part (handle)
   "Use mm-display-part to display HANDLE in a new buffer.
-- 
2.1.4

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


[PATCH] test: duplicate mids: add an extra broken search test

2017-08-27 Thread Mark Walters
---

Hi

Many thanks to bremner for the parent patch. I thought it might be
worth adding a search test after the broken show test demonstrating
the distinction between show and search. When I added it I found it
actually gives the other file as the answer!

This applies on top of the parent patch.

Best wishes

Mark


test/T670-duplicate-mid.sh | 8 
 1 file changed, 8 insertions(+)

diff --git a/test/T670-duplicate-mid.sh b/test/T670-duplicate-mid.sh
index 55ebde3..0de2bc0 100755
--- a/test/T670-duplicate-mid.sh
+++ b/test/T670-duplicate-mid.sh
@@ -86,6 +86,14 @@ expected='[[[{
 ['
 test_expect_equal_json "$output" "$expected"
 
+test_begin_subtest 'First subject preserved in notmuch-search file order'
+test_subtest_known_broken
+notmuch search id:duplicate | notmuch_search_sanitize > OUTPUT
+cat < EXPECTED
+thread:XXX   2001-01-05 [1/1(3)] Notmuch Test Suite; message 1 (inbox unread)
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 rm ${MAIL_DIR}/00-copy4
 test_begin_subtest 'Deleted first duplicate file does not stop notmuch show 
from working'
 output=$(notmuch show --body=false --format=json id:duplicate | 
notmuch_json_show_sanitize)
-- 
2.1.4

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


Duplicate message ids

2017-08-27 Thread Mark Walters

Hi

A concern for notmuch is some form of attack via someone sending a
message with a duplicate message id. I think I have seen it asserted
that it is not so much of a problem as the first message received by
notmuch will have priority.

However, I believe that this is not the case. The script below gives a
demonstration (on my system at least). I have written it as a "test" so
(I hope) it doesn't mess up the system. It should work if you put it in
the test directory and execute it.

It adds a message, runs notmuch new, adds a message with the same id,
runs notmuch new, and then runs notmuch search  and notmuch show
. The former shows the subject of the first message, and the latter
the subject of the second message.

Best wishes

Mark

#!/usr/bin/env bash
test_description='Do duplicate message ids get shown in arrival order'
. ./test-lib.sh || exit 1


find ${MAIL_DIR}
generate_message [id]=duplicate-id [subject]=first [body]=first
mkdir "${MAIL_DIR}"/b
mv "$gen_msg_filename" "${MAIL_DIR}"/b
notmuch new
generate_message [id]=duplicate-id [subject]=second [body]=second
mv "$gen_msg_filename" "${MAIL_DIR}"/a
notmuch new
find ${MAIL_DIR}

echo
echo SEARCH: observe \"first\" is the subject
notmuch search id:duplicate-id

echo
echo SHOW: observe \"second\" is the subject and body
notmuch show --format=json id:duplicate-id |json_pp
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2] emacs: Add notmuch-update-search-tags

2017-08-27 Thread Mark Walters

Hi

OK I have now actually tested it, and I have read the patch more
carefully, but I am afraid I still have concerns.

The key problem is the patch assumes that the display of a thread in a
search buffer depends only on the thread. And this is not true as the
number of matching messages is displayed eg [10/19], and the author list
is split into matching authors | unmatching authors.

However, when the tags in a thread are changed the patch makes all
search buffers containing that thread update to look the same. Indeed,
if you change a tag on a single message I think the count will always
update to be [1/??] as there is only one message matching the tag-change
query.

I think you could get round this by modifying your code only slightly --
rather than calling notmuch-search-update-result in
notmuch-search-update-results, *just* update the tags, using something
like notmuch-search-set-tags. (I have just tried this and it seems to work.)

This is not perfect, as this will show tags of newly arrived messages in
the thread, but that might well be acceptable.

And this still keeps it to one call to the database, which avoids your
(completely correct) performance concerns.


> It may be possible to optimize this down to one batch search query per 
> notmuch-search buffer - however, this results in a large search query. 
> Not only would one take a while to execute, but the resulting query can 
> become too large to be passed as a command-line parameter, and "notmuch 
> search" does not seem to have a --batch switch to read queries from 
> standard input.

This points to my next concern -- this is already a problem in the
current patch. If you go into a moderately large search buffer, and do
something like * +foo (to tag all the messages with foo), the tag step
works because is uses the --batch switch to tag, but your search query
doesn't.

The options here are to:  add --batch to search handling, or  just
decide not to do display the tag updates for large queries.

Incidentally there also seems to a bug in the current that the first
thread in a search buffer doesn't seem to get updated. I think you are
using too low level functions -- things like
notmuch-search-foreach-result might do exactly what you need.

Finally, in the longer term, do you wanting to do this for tree and show
buffers too?

[An alternative approach, which I don't think I like but I mention in
case others do -- we could only propagate tag changes to parent
buffers. So updating a tag in a show buffer only updates the single
search buffer that called it. This might avoid the large query problem
as show buffers probably don't have large queries.]

Best wishes

Mark









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


Re: [PATCH v2] emacs: Add notmuch-update-search-tags

2017-08-26 Thread Mark Walters

Hi

On Sat, 26 Aug 2017, Vladimir Panteleev  wrote:
> From: Vladimir Panteleev 
>
> Implement an option which, when enabled, causes any tag changes done
> from within notmuch-emacs to instantly update matching threads in open
> search buffers.

I like the idea, and provided it only marks the tags as changed in the
normal way, I think we could even default to on.

However, I am concerned that this version does other things as
well. Note these comments are from reading the patch not from testing,
so please point out if I am wrong.

1) Suppose a new message arrives in the thread. Then triggering a tag
change in the show buffer, (eg notmuch automatically removing an unread
tag) pulls that message into original search buffer.

2) If that new message has some tags that aren't in the thread they will
get marked as "added tags"

3) At least in theory I think the thread may no longer exist -- it could
have merged with another thread and taken the other threads id.

I think 3 is probably rare enough not to be real concern (though we
should make sure we don't actually give an error). But 1 and 2 seem
undesirable.

Rather than refreshing the result it might make sense to fetch the tags
for the actual messages in that thread (as it was when the search buffer
was loaded) by using notmuch-search-find-stable-query.

So something like the following,

- in each notmuch-search buffer

- see if thread-id thread is in that buffer (or perhaps even if there is a 
thread
  which contains message id in that buffer?)

- If yes, fetch a new list of tags for the messages that buffer thinks are
  in that thread (using notmuch-search-find-stable-query).

- Update tags appropriately.

If we do that then I think the only change in these buffers is the tag
updates, and exactly as if you changed those tags in the search buffer
itself, the threads shown etc don't change.

What do you think?

Best wishes

Mark


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


Re: High CPU usage on Tree View with many emails

2017-06-25 Thread Mark Walters

Hi

> When I make a query that gives many results (e.g. "review", which hits
> ~2200 emails with my Gerrit reviews) and want to display them in Tree
> View, the CPU usage stays high for several seconds.
>
> While this happens, the Emacs window flickers, like it was busy with
> redisplaying the buffer.

Yes I see this but I don't quite know why it happens. I think it is to
do with the special tree graphics characters. Two things you could try
are running emacs in a terminal, and changing the font. If you are happy
compiling from source, then you could also try changing the characters
used for the tree graphics (in emacs/notmuch-tree.el)

If you are feeling more adventurous I think the flicker is fixed in
emacs master, so emacs 26 should be OK. (*)

Best wishes

Mark

(*) For an entertaining description of quite what was needed to make
emacs double buffer its output see
https://www.facebook.com/notes/daniel-colascione/buttery-smooth-emacs/10155313440066102/




> If I pull the horizontal scroll of the Emacs
> buffer down, I can see that the buffer grows (like messages being
> inserted there). The Emacs profiler says that more than 50% of CPU
> time is spend in notmuch-tree-insert-forest-thread.
>
> Interestingly, the in the non-tree view the same query is processed in no 
> time.
>
> Any idea?
>
> -- 
> Piotr Trojanek
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> https://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] emacs: tree: bugfix: specify --format-version

2017-05-13 Thread Mark Walters
Previously notmuch tree did not specify the format-version when
calling notmuch. This meant that when the structured output was
slightly changed (in commit 14c60cf168ac3b0f277188c16e6012b7ebdadde7)
stash filename broke. This fixes this breakage by specifying the
format-version.
---

Bremner pointed out this bug today on irc. In due course we may want
to use format-version=3 and update the helper functions but as none of
notmuch-emacs uses the new format version yet this seem the right fix for now.

Best wishes

Mark



emacs/notmuch-tree.el | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 7bebdba..d4d4076 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -917,7 +917,7 @@ the same as for the function notmuch-tree."
 (notmuch-tag-clear-cache)
 (let ((proc (notmuch-start-notmuch
 "notmuch-tree" (current-buffer) #'notmuch-tree-process-sentinel
-"show" "--body=false" "--format=sexp"
+"show" "--body=false" "--format=sexp" "--format-version=2"
 message-arg search-args))
  ;; Use a scratch buffer to accumulate partial output.
  ;; This buffer will be killed by the sentinel, which
-- 
2.1.4

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


Re: [RFC patch 2/2] lib: index message files with duplicate message-ids

2017-03-16 Thread Mark Walters

Hi

Just a comment on your last point:

> It also occurs to me that one of the things i'd love to have is
> well-indexed notes about any given e-mail.  So if this was adopted, i
> could presumably just write a file that has the same Message-Id as the
> message, put my notes in it, and index it.  that's a little weird,
> though.  would there be a better way to do such a thing?

A different way which might get pretty close to what you would be to
start a reply and then postpone it.

Ideally we would wrap this in a "note" function would delete the
to/cc/bcc headers to make sure it doesn't accidentally get sent and add a
+note tag when saving.

Best wishes

Mark



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


Re: [PATCH] emacs: remove use of message-send-hook

2017-03-10 Thread Mark Walters

On Fri, 10 Mar 2017, David Bremner <da...@tethera.net> wrote:
> Mark Walters <markwalters1...@gmail.com> writes:
>
>> +(let (tag-change
>> +  post-send-tag-changes)
>> +  ;; post-send-tag-changes are tag-changes to apply after sending,
>> +  ;; but we need to store them now as the compose buffer is
>> +  ;; typically killed before message-send-and-exit returns.
>> +  (push (notmuch-message-mark-replied t) post-send-tag-changes)
>> +  (push (notmuch-draft--mark-deleted t) post-send-tag-changes)
>> +  (letf (((symbol-function 'message-do-fcc) 
>> #'notmuch-maildir-message-do-fcc))
>> +(if exit
>> +(message-send-and-exit arg)
>> +  (message-send arg)))
>> +  (dolist (tag-change post-send-tag-changes)
>> +(when tag-change
>> +  (apply #'notmuch-tag tag-change))

Hi

> Would it be possible to concatenate the two lists and only call
> notmuch-tag once? It seems like that should be notably faster.

I think that it's not possible as they are tagging different
messages. We could probably do something with --batch but that would
mean some change in notmuch-tag itself.

Best wishes

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


[PATCH] NEWS for emacs

2017-03-06 Thread Mark Walters
---

This is the NEWS updates for most of my changes. I am not quite sure
whether any of my other changes warranted news items -- prod me if you
think they do.

Note I changed the heading to Emacs not Emacs Interface to match
previous releases but obviously that can be changed back if you
prefer.

Best wishes

Mark



NEWS | 65 ++---
 1 file changed, 62 insertions(+), 3 deletions(-)

diff --git a/NEWS b/NEWS
index 652affa..bfd5255 100644
--- a/NEWS
+++ b/NEWS
@@ -9,10 +9,69 @@ Regular expression searches supported for `from:` and 
`subject:`.
   This requires recent Xapian (1.4+) See notmuch-search-terms(7) for
   details.
 
-Emacs Interface

+Emacs
+-
+
+Postpone and resume messages in `notmuch-message-mode` (composition)
+
+  Notmuch now has built in support for postponing, saving and resuming
+  messages. The default bindings are C-x C-s to save a draft, C-c C-p
+  to postpone a draft (save and exit compose buffer), and "e" in show
+  or tree view to resume.
+
+  Draft messages are tagged with `notmuch-draft-tags` (draft by
+  default) so you may wish to add that to the excluded tags list. When
+  saving a previously saved draft message the earlier draft gets
+  tagged deleted.
+
+  Note that attachments added before postponing will be included as
+  they were when you postponed in the final message.
+
+Address Completion
+
+  It is now possible to save the list of address completions for
+  notmuch's internal completion between runs of emacs. This makes the
+  first calls to address completion much better and faster. For
+  privacy reasons it is disabled by default, to enable set or
+  customize `notmuch-address-save-filename`.
+
+Tag jump menu
+
+  It is now possible to configure tagging shortcuts (with an interface
+  like notmuch jump). For example (by default) k u will remove the
+  unread tag, and k s will add a tag "spam" and remove the inbox
+  tag. Pressing k twice will do the reverse operation so, for example,
+  k k s removes the spam tag and adds the inbox tag. See the customize
+  variable `notmuch-tagging-keys` for more information.
+
+Refresh all buffers
+
+  It is now possible to refresh all notmuch buffers to reflect the
+  current state of the database with a single command, `M-=`.
+
+Stop display of application/* parts
+
+  By default gnus displays all application/* parts such as
+  application/zip in the message buffer. This has several undesirable
+  effects for notmuch (security, triggering errors etc). Notmuch now
+  overrides this and does not display them by default. If you have
+  customized `mm-inline-override-types` then we assume you know what
+  you want and do not interfere; if you do want to stop the display of
+  application/* add application/* to your customization. If you want
+  to allow application/* then set `mm-inline-override-types` to
+  "non/existent".
+
+Small change in the api for notmuch-search-tag
+
+  When `notmuch-search-tag` is called non-interactively and the region
+  is set, then it only tags the threads in the region. (Previously it
+  only tagged the current thread.)
+
+Bugfix for sending messages with very long headers.
 
-  Save and resume messages in `notmuch-message-mode` (composition).
+  Previously emacs didn't fold very long headers when sending which
+  could cause the MTA to refuse to send the message. This makes sure
+  it does fold any long headers so the message is RFC compliant.
 
 Library changes
 ---
-- 
2.1.4

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


[PATCH v3 1/2] Test: emacs: test for folding long headers.

2017-03-04 Thread Mark Walters
Headers of more than 998 characters should be folded when sending.
However, until recently, emacs did not do this.

This adds a (known broken) test for this when sending messages in
emacs. We will backport the fix to notmuch-emacs in the next
changeset.
---
 test/T310-emacs.sh | 78 ++
 1 file changed, 78 insertions(+)

diff --git a/test/T310-emacs.sh b/test/T310-emacs.sh
index 01385ae..f626d9a 100755
--- a/test/T310-emacs.sh
+++ b/test/T310-emacs.sh
@@ -208,6 +208,84 @@ This is a test that messages are sent via SMTP
 EOF
 test_expect_equal_file OUTPUT EXPECTED
 
+test_begin_subtest "Folding a long header when sending via (fake) SMTP"
+long_subject="This is a long subject `echo {1..1000}`"
+emacs_deliver_message \
+"${long_subject}" \
+'This is a test that long headers are folded when messages are sent via 
SMTP' \
+'(message-goto-to)
+ (kill-whole-line)
+ (insert "To: u...@example.com\n")'
+sed \
+-e s',^Message-ID: <.*>$,Message-ID: ,' \
+-e s',^\(Content-Type: text/plain\); charset=us-ascii$,\1,' < sent_message 
>OUTPUT
+cat 
+To: u...@example.com
+Subject: This is a long subject 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
+ 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
+ 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
+ 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
+ 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
+ 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
+ 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
+ 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
+ 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
+ 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
+ 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
+ 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
+ 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
+ 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
+ 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
+ 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
+ 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
+ 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
+ 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
+ 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
+ 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
+ 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
+ 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
+ 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
+ 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
+ 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
+ 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
+ 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
+ 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
+ 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
+ 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
+ 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
+ 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
+ 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
+ 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
+ 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
+ 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
+ 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
+ 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
+ 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
+ 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
+ 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779
+ 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
+ 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
+ 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833
+ 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
+ 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
+ 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
+ 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
+ 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
+ 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941

[PATCH v3 0/2] emacs: fold long headers when sending

2017-03-04 Thread Mark Walters
Version 2 of this series is at
id:1488649637-19006-1-git-send-email-markwalters1...@gmail.com

The change here is to split the folding headers function into an
explicit function as this makes managing the hook simpler.

Best wishes

Mark


Mark Walters (2):
  Test: emacs: test for folding long headers.
  emacs: compat: backport fix for folding long headers when sending

 emacs/notmuch-compat.el | 28 +++---
 test/T310-emacs.sh  | 78 +
 2 files changed, 102 insertions(+), 4 deletions(-)

-- 
2.1.4

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


[PATCH v3 2/2] emacs: compat: backport fix for folding long headers when sending

2017-03-04 Thread Mark Walters
This backports the fix from emacs master (commit
77bbca8c82f6e553c42abbfafca28f55fc995d00) to notmuch-emacs to wrap
long headers.

This fixes the test introduced in the previous changeset.
---
 emacs/notmuch-compat.el | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index c3d827a..2cedd39 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -1,8 +1,28 @@
-;; Compatibility functions for emacs 23 and 24 pre 24.4
+;; Compatibility functions for earlier versions of emacs
 
-;; The functions in this file are copied from eamcs 24.4 and are
-;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2014 Free Software
-;; Foundation, Inc.
+;; The functions in this file are copied from more modern versions of
+;; emacs and are Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2017
+;; Free Software Foundation, Inc.
+
+
+;; emacs master has a bugfix for folding long headers when sending
+;; messages. Include the fix for earlier versions of emacs. To avoid
+;; interfering with gnus we only run the hook when called from
+;; notmuch-message-mode.
+
+(declare-function mail-header-fold-field "mail-parse" nil)
+
+(defun notmuch-message--fold-long-headers ()
+  (when (eq major-mode 'notmuch-message-mode)
+(goto-char (point-min))
+(while (not (eobp))
+  (when (and (looking-at "[^:]+:")
+(> (- (line-end-position) (point)) 998))
+   (mail-header-fold-field))
+  (forward-line 1
+
+(unless (fboundp 'message--fold-long-headers)
+  (add-hook 'message-header-hook 'notmuch-message--fold-long-headers))
 
 (if (fboundp 'setq-local)
 (defalias 'notmuch-setq-local 'setq-local)
-- 
2.1.4

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


[PATCH v2 0/2] emacs: fold long headers when sending

2017-03-04 Thread Mark Walters
The only change from v1 (at
id:1485684281-2760-1-git-send-email-markwalters1...@gmail.com ) is an
updated test as suggested by Domo using echo {1..1000} instead of seq.

Best wishes

Mark


Mark Walters (2):
  Test: emacs: test for folding long headers.
  emacs: compat: backport fix for folding long headers when sending

 emacs/notmuch-compat.el | 28 +++---
 test/T310-emacs.sh  | 78 +
 2 files changed, 102 insertions(+), 4 deletions(-)

-- 
2.1.4

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


[PATCH v2 2/2] emacs: compat: backport fix for folding long headers when sending

2017-03-04 Thread Mark Walters
This backports the fix from emacs master (commit
77bbca8c82f6e553c42abbfafca28f55fc995d00) to notmuch-emacs to wrap
long headers.

This fixes the test introduced in the previous changeset.
---
 emacs/notmuch-compat.el | 28 
 1 file changed, 24 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index c3d827a..e71e861 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -1,8 +1,28 @@
-;; Compatibility functions for emacs 23 and 24 pre 24.4
+;; Compatibility functions for earlier versions of emacs
 
-;; The functions in this file are copied from eamcs 24.4 and are
-;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2014 Free Software
-;; Foundation, Inc.
+;; The functions in this file are copied from more modern versions of
+;; emacs and are Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2017
+;; Free Software Foundation, Inc.
+
+
+
+;; emacs master has a bugfix for folding long headers when sending
+;; messages. Include the fix for earlier versions of emacs. To avoid
+;; interfering with gnus we only run the hook when called from
+;; notmuch-message-mode.
+
+(declare-function mail-header-fold-field "mail-parse" nil)
+
+(unless (fboundp 'message--fold-long-headers)
+  (add-hook 'message-header-hook
+   (lambda ()
+ (when (eq major-mode 'notmuch-message-mode)
+   (goto-char (point-min))
+   (while (not (eobp))
+ (when (and (looking-at "[^:]+:")
+(> (- (line-end-position) (point)) 998))
+   (mail-header-fold-field))
+ (forward-line 1))
 
 (if (fboundp 'setq-local)
 (defalias 'notmuch-setq-local 'setq-local)
-- 
2.1.4

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


[PATCH v2 1/2] Test: emacs: test for folding long headers.

2017-03-04 Thread Mark Walters
Headers of more than 998 characters should be folded when sending.
However, until recently, emacs did not do this.

This adds a (known broken) test for this when sending messages in
emacs. We will backport the fix to notmuch-emacs in the next
changeset.
---
 test/T310-emacs.sh | 78 ++
 1 file changed, 78 insertions(+)

diff --git a/test/T310-emacs.sh b/test/T310-emacs.sh
index 01385ae..f626d9a 100755
--- a/test/T310-emacs.sh
+++ b/test/T310-emacs.sh
@@ -208,6 +208,84 @@ This is a test that messages are sent via SMTP
 EOF
 test_expect_equal_file OUTPUT EXPECTED
 
+test_begin_subtest "Folding a long header when sending via (fake) SMTP"
+long_subject="This is a long subject `echo {1..1000}`"
+emacs_deliver_message \
+"${long_subject}" \
+'This is a test that long headers are folded when messages are sent via 
SMTP' \
+'(message-goto-to)
+ (kill-whole-line)
+ (insert "To: u...@example.com\n")'
+sed \
+-e s',^Message-ID: <.*>$,Message-ID: ,' \
+-e s',^\(Content-Type: text/plain\); charset=us-ascii$,\1,' < sent_message 
>OUTPUT
+cat 
+To: u...@example.com
+Subject: This is a long subject 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
+ 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
+ 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
+ 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
+ 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
+ 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
+ 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
+ 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
+ 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
+ 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
+ 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
+ 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
+ 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
+ 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
+ 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
+ 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
+ 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
+ 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
+ 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
+ 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
+ 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
+ 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
+ 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
+ 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
+ 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
+ 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
+ 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
+ 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
+ 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
+ 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
+ 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
+ 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
+ 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
+ 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
+ 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
+ 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
+ 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
+ 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
+ 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
+ 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
+ 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
+ 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779
+ 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
+ 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
+ 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833
+ 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
+ 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
+ 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
+ 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
+ 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
+ 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941

Re: Github an licensing

2017-03-04 Thread Mark Walters

> On irc rlb pointed me to
> https://joeyh.name/blog/entry/removing_everything_from_github/
>
> IANAL so I don't know whether it is a real problem, a hypothetical
> problem or not a problem.

I got a couple of links sent to me privately which look relevant:

 * https://news.ycombinator.com/item?id=13767373
 * https://news.ycombinator.com/item?id=13766933

(hacker threads, but from people claiming to be lawyers)

Best wishes

Mark


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


Github an licensing

2017-03-04 Thread Mark Walters

Dear All

On irc rlb pointed me to
https://joeyh.name/blog/entry/removing_everything_from_github/

IANAL so I don't know whether it is a real problem, a hypothetical
problem or not a problem.

My guess is that it can't affect the main notmuch license as the bulk of
notmuch's copyright is owned by people not responsible for the github
mirror (*), but it might mean that those of us responsible for the mirror are
illegally posting notmuch's code.

Does anyone have any views on this, and whether we should carry on
maintaining the github mirror?

Best wishes

Mark

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


Re: [PATCH v2] emacs: show: stop display of application/* parts

2017-02-27 Thread Mark Walters

Hi

>> But what will we do if the user has not customized it because she
>> /wants/ to display all possible things inline. I have not seen that this
>> patch is merged into master, and probably, when I have learned about
>> this variable, I think maybe it's better not to do it in the notmuch
>> code.

Well they can set mm-inline-override-types to
"non-existent/type". Rather a kludge I agree.

> The problem is that the gnus default is somehow unsafe, and causes bad
> behaviour for people receiving large attachments.

I agree with this and do think we should block this by default. In
particular, gnus/mm stuff doesn't even check for the existence of unzip
before running it on zip attachments so on my machines which don't have
unzip I get a bodypart insertion error.

One alternative would be to add a variable
notmuch-mm-inline-override-types which would combine or replace
mm-inline-override-types for notmuch's use. A defcustom would be
clutter, but a variable would mean anyone with unusual requirements
could just setq it.

What does anyone think?

Best wishes

Mark



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


Re: [Patch v4] lib: regexp matching in 'subject' and 'from'

2017-02-10 Thread Mark Walters
On Thu, 09 Feb 2017, David Bremner  wrote:
> Jani Nikula  writes:
>
>>
>> Theoretically "/" is an acceptable character in message-ids [1]. Rare,
>> unlikely, but acceptable. Searching for message-id's beginning with "/"
>> would have to use regexps, which would break in all sorts of ways
>> throughout the stack. I don't think there are handy alternatives to
>> "//", given the characters that are acceptable in message-ids,
>> but this is something to think about.
>
> Would telling the user to \ escape ( or double /) the initial / be good
> enough there? This would disable regex processing.  I guess this goes
> back to someone's earlier suggestion.  A third option would be to use
> single quotes there ("id:'/foo'"), but that isn't really consistent with 
> either Xapian
> or usual regex conventions.
>
> So I guess my favourite idea ATM is to use id:\/some/crazy/message-id
> FWIW, I don't have any such message ids.
>
>> For example, could the regexp matcher for message-ids first check if the
>> "regexp" is a strict match with "/" and all, and accept those? This
>> might be a reasonable workaround if it can be made to work.
>
> We're building a query, so I think the equivalent is to make an OR, with
> the exact match and the regex posting source. That could be done,
> although I'm a bit uneasy about how this makes the syntax for id:
> different, so id:/foo would be legit, but from:/foo would be an error.
> Maybe the dwim-factor is worth it.

Hi

Broadly I like the backslash escaping option. Two thoughts: can any
fields (from/subject/message-id) start with a "\" anyway? I think not
but thought it worth checking.

Secondly, message-id is often round-tripped, that is output from notmuch
and then fed back to notmuch. Do we want to escape the output as above
before printing in any cases? My view is that if we output the
message-id prefixed with "id:" then we should escape it (which applies
with --output=messages --format=text), but if we don't print the "id:"
part then we shouldn't (eg with --format=json). A similar thing would
apply to emacs: if it is a normal stash then escape the id, but if it is
a "bare stash" then do not.

Actually, one more thing: it would be a shame to block or significantly
delay the series for such a corner case.

Best wishes

Mark



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


[PATCH] test: fix tests for content-disposition

2017-01-29 Thread Mark Walters
This fixes all tests for the recent addition of content-disposition to
the structured format outputs of notmuch-show.
---

Since Jani added the content-disposition as I wanted to use it from emacs 
(thanks Jani!)
I thought I should fix the tests.

I don't know if it should be folded in to the main patch or applied
separately. Either is fine with me.

Best wishes

Mark



test/T160-json.sh  |  2 +-
 test/T170-sexp.sh  |  2 +-
 test/T190-multipart.sh | 22 ++
 test/T350-crypto.sh|  1 +
 4 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/test/T160-json.sh b/test/T160-json.sh
index b346f37..74e0d8f 100755
--- a/test/T160-json.sh
+++ b/test/T160-json.sh
@@ -48,7 +48,7 @@ output=$(notmuch show --format=json "id:$id")
 filename=$(notmuch search --output=files "id:$id")
 # Get length of README after base64-encoding, minus additional newline.
 attachment_length=$(( $(base64 $TEST_DIRECTORY/README | wc -c) - 1 ))
-test_expect_equal_json "$output" "[[[{\"id\": \"$id\", \"match\": true, 
\"excluded\": false, \"filename\": \"$filename\", \"timestamp\": 946728000, 
\"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\"], \"headers\": 
{\"Subject\": \"$subject\", \"From\": \"Notmuch Test Suite 
\", \"To\": \"test_su...@notmuchmail.org\", 
\"Date\": \"Sat, 01 Jan 2000 12:00:00 +\"}, \"body\": [{\"id\": 1, 
\"content-type\": \"multipart/mixed\", \"content\": [{\"id\": 2, 
\"content-type\": \"text/plain\", \"content\": \"This is a test message with 
inline attachment with a filename\"}, {\"id\": 3, \"content-type\": 
\"application/octet-stream\", \"content-length\": $attachment_length, 
\"content-transfer-encoding\": \"base64\", \"filename\": \"README\"}]}]}, ["
+test_expect_equal_json "$output" "[[[{\"id\": \"$id\", \"match\": true, 
\"excluded\": false, \"filename\": \"$filename\", \"timestamp\": 946728000, 
\"date_relative\": \"2000-01-01\", \"tags\": [\"inbox\"], \"headers\": 
{\"Subject\": \"$subject\", \"From\": \"Notmuch Test Suite 
\", \"To\": \"test_su...@notmuchmail.org\", 
\"Date\": \"Sat, 01 Jan 2000 12:00:00 +\"}, \"body\": [{\"id\": 1, 
\"content-type\": \"multipart/mixed\", \"content\": [{\"id\": 2, 
\"content-type\": \"text/plain\", \"content\": \"This is a test message with 
inline attachment with a filename\"}, {\"id\": 3, \"content-type\": 
\"application/octet-stream\", \"content-length\": $attachment_length, 
\"content-transfer-encoding\": \"base64\", \"content-disposition\": \"inline\", 
\"filename\": \"README\"}]}]}, ["
 
 test_begin_subtest "Search message: json, utf-8"
 add_message "[subject]=\"json-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 
Jan 2000 12:00:00 -\"" "[body]=\"jsön-search-méssage\""
diff --git a/test/T170-sexp.sh b/test/T170-sexp.sh
index 800ebc6..2088972 100755
--- a/test/T170-sexp.sh
+++ b/test/T170-sexp.sh
@@ -39,7 +39,7 @@ output=$(notmuch show --format=sexp "id:$id")
 filename=$(notmuch search --output=files "id:$id")
 # Get length of README after base64-encoding, minus additional newline.
 attachment_length=$(( $(base64 $TEST_DIRECTORY/README | wc -c) - 1 ))
-test_expect_equal "$output" ":id \"$id\" :match t :excluded nil :filename 
\"$filename\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags 
(\"inbox\") :headers (:Subject \"sexp-show-inline-attachment-filename\" :From 
\"Notmuch Test Suite \" :To 
\"test_su...@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +\") :body 
((:id 1 :content-type \"multipart/mixed\" :content ((:id 2 :content-type 
\"text/plain\" :content \"This is a test message with inline attachment with a 
filename\") (:id 3 :content-type \"application/octet-stream\" :filename 
\"README\" :content-transfer-encoding \"base64\" :content-length 
$attachment_length) ("
+test_expect_equal "$output" ":id \"$id\" :match t :excluded nil :filename 
\"$filename\" :timestamp 946728000 :date_relative \"2000-01-01\" :tags 
(\"inbox\") :headers (:Subject \"sexp-show-inline-attachment-filename\" :From 
\"Notmuch Test Suite \" :To 
\"test_su...@notmuchmail.org\" :Date \"Sat, 01 Jan 2000 12:00:00 +\") :body 
((:id 1 :content-type \"multipart/mixed\" :content ((:id 2 :content-type 
\"text/plain\" :content \"This is a test message with inline attachment with a 
filename\") (:id 3 :content-type \"application/octet-stream\" 
:content-disposition \"inline\" :filename \"README\" :content-transfer-encoding 
\"base64\" :content-length $attachment_length) ("
 
 test_begin_subtest "Search message: sexp, utf-8"
 add_message "[subject]=\"sexp-search-utf8-body-sübjéct\"" "[date]=\"Sat, 01 
Jan 2000 12:00:00 -\"" "[body]=\"jsön-search-méssage\""
diff --git a/test/T190-multipart.sh b/test/T190-multipart.sh
index 3567890..b631c5e 100755
--- a/test/T190-multipart.sh
+++ b/test/T190-multipart.sh
@@ -348,11 +348,11 @@ cat 

Re: [PATCH 2/2] cli/show: add content-disposition to structured output message parts

2017-01-29 Thread Mark Walters

On Sat, 28 Jan 2017, Jani Nikula  wrote:
> Help the clients decide how to display parts.

This series looks good to me. I would say +1, but I am not sure my
knowledge of C is really up to that.

There are a bunch of tests to update; I will send a patch to do that in
shortly.

> I'm not sure if this should bump the version in schemata, because the
> comment in notmuch-client.h says new map fields can be added without
> increasing NOTMUCH_FORMAT_CUR. Yet the schemata version history says
> thread_summary.query was added in v2... which looks like a change that
> shouldn't need a version bump. Confused.

I think the reason for the bump before was that the client needed to
know it had got the new format, so it could either bail out, or at least
work around it, if it got the old format.

In this case though, I think any sane program has to treat
content-disposition nil as being "do whatever the default is" (since I
don't think all parts have a content-disposition).

Thus, I don't think we need a schemata bump, as the client can just use
the extra information if present, and otherwise do what it normally would.

Best wishes

Mark

>
> The problem could be avoided by conflating both this change and
> id:20170110201929.21875-1-j...@nikula.org into v3... ;)
> ---
>  devel/schemata | 1 +
>  notmuch-show.c | 6 ++
>  2 files changed, 7 insertions(+)
>
> diff --git a/devel/schemata b/devel/schemata
> index 41dc4a60fff3..c94459eb783a 100644
> --- a/devel/schemata
> +++ b/devel/schemata
> @@ -76,6 +76,7 @@ part = {
>  sigstatus?: sigstatus,
>  
>  content-type:   string,
> +content-disposition?:   string,
>  content-id?:string,
>  # if content-type starts with "multipart/":
>  content:[part*],
> diff --git a/notmuch-show.c b/notmuch-show.c
> index 8b38fe6db136..8e69b3465886 100644
> --- a/notmuch-show.c
> +++ b/notmuch-show.c
> @@ -582,6 +582,7 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, 
> mime_node_t *node,
>  GMimeObject *meta = node->envelope_part ?
>   GMIME_OBJECT (node->envelope_part) : node->part;
>  GMimeContentType *content_type = g_mime_object_get_content_type (meta);
> +const char *disposition = _get_disposition (meta);
>  const char *cid = g_mime_object_get_content_id (meta);
>  const char *filename = GMIME_IS_PART (node->part) ?
>   g_mime_part_get_filename (GMIME_PART (node->part)) : NULL;
> @@ -611,6 +612,11 @@ format_part_sprinter (const void *ctx, sprinter_t *sp, 
> mime_node_t *node,
>  sp->map_key (sp, "content-type");
>  sp->string (sp, g_mime_content_type_to_string (content_type));
>  
> +if (disposition) {
> + sp->map_key (sp, "content-disposition");
> + sp->string (sp, disposition);
> +}
> +
>  if (cid) {
>   sp->map_key (sp, "content-id");
>   sp->string (sp, cid);
> -- 
> 2.11.0
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 0/2] emacs: Fold long headers when sending

2017-01-29 Thread Mark Walters
This pair of patches add a test for folding long headers, and backport
the bugfix from emacs master. This fixes the bug reported in
id:87612qwh04@viking.dsc.soic.indiana.edu

The fix in emacs master (77bbca8c82f6e553c42abbfafca28f55fc995d00)
runs the folding function just before message-header-hook, so this fix
should give almost exactly the same behaviour.

Since message--fold-long-headers was introduced in the same commit
this should mean we do not apply the fix for any version of emacs
which it already has it.

I don't know whether my bash in the test suite is sufficiently
portable, so if anyone who knows about that could check I would be
grateful. (For example, is seq -s " " 1 1000 standard?)

Best wishes

Mark



Mark Walters (2):
  Test: emacs: test for folding long headers.
  emacs: compat: backport fix for folding long headers when sending

 emacs/notmuch-compat.el | 28 +++---
 test/T310-emacs.sh  | 78 +
 2 files changed, 102 insertions(+), 4 deletions(-)

-- 
2.1.4

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


[PATCH 1/2] Test: emacs: test for folding long headers.

2017-01-29 Thread Mark Walters
Headers of more than 998 characters should be folded when sending.
However, until recently, emacs did not do this.

This adds a (known broken) test for this when sending messages in
emacs. We will backport the fix to notmuch-emacs in the next
changeset.
---
 test/T310-emacs.sh | 79 ++
 1 file changed, 79 insertions(+)

diff --git a/test/T310-emacs.sh b/test/T310-emacs.sh
index 01385ae..5331514 100755
--- a/test/T310-emacs.sh
+++ b/test/T310-emacs.sh
@@ -208,6 +208,85 @@ This is a test that messages are sent via SMTP
 EOF
 test_expect_equal_file OUTPUT EXPECTED
 
+test_begin_subtest "Folding a long header when sending via (fake) SMTP"
+test_subtest_known_broken
+long_subject="This is a long subject `seq -s ' ' 1 1000`"
+emacs_deliver_message \
+"${long_subject}" \
+'This is a test that long headers are folded when messages are sent via 
SMTP' \
+'(message-goto-to)
+ (kill-whole-line)
+ (insert "To: u...@example.com\n")' 
+sed \
+-e s',^Message-ID: <.*>$,Message-ID: ,' \
+-e s',^\(Content-Type: text/plain\); charset=us-ascii$,\1,' < sent_message 
>OUTPUT
+cat 
+To: u...@example.com
+Subject: This is a long subject 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
+ 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
+ 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
+ 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
+ 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
+ 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
+ 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
+ 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
+ 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
+ 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
+ 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
+ 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
+ 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
+ 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275
+ 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
+ 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311
+ 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
+ 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
+ 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
+ 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
+ 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
+ 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419
+ 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
+ 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
+ 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473
+ 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
+ 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509
+ 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527
+ 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545
+ 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563
+ 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581
+ 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
+ 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
+ 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
+ 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
+ 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671
+ 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
+ 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707
+ 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725
+ 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743
+ 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761
+ 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779
+ 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
+ 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
+ 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833
+ 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851
+ 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
+ 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
+ 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905
+ 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
+ 924 925 926 927 928 929 930 931 932 933 

[PATCH 2/2] emacs: compat: backport fix for folding long headers when sending

2017-01-29 Thread Mark Walters
This backports the fix from emacs master (commit
77bbca8c82f6e553c42abbfafca28f55fc995d00) to notmuch-emacs to wrap
long headers.

This fixes the test introduced in the previous changeset.
---
 emacs/notmuch-compat.el | 28 
 test/T310-emacs.sh  |  1 -
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
index c3d827a..e71e861 100644
--- a/emacs/notmuch-compat.el
+++ b/emacs/notmuch-compat.el
@@ -1,8 +1,28 @@
-;; Compatibility functions for emacs 23 and 24 pre 24.4
+;; Compatibility functions for earlier versions of emacs
 
-;; The functions in this file are copied from eamcs 24.4 and are
-;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2014 Free Software
-;; Foundation, Inc.
+;; The functions in this file are copied from more modern versions of
+;; emacs and are Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2017
+;; Free Software Foundation, Inc.
+
+
+
+;; emacs master has a bugfix for folding long headers when sending
+;; messages. Include the fix for earlier versions of emacs. To avoid
+;; interfering with gnus we only run the hook when called from
+;; notmuch-message-mode.
+
+(declare-function mail-header-fold-field "mail-parse" nil)
+
+(unless (fboundp 'message--fold-long-headers)
+  (add-hook 'message-header-hook
+   (lambda ()
+ (when (eq major-mode 'notmuch-message-mode)
+   (goto-char (point-min))
+   (while (not (eobp))
+ (when (and (looking-at "[^:]+:")
+(> (- (line-end-position) (point)) 998))
+   (mail-header-fold-field))
+ (forward-line 1))
 
 (if (fboundp 'setq-local)
 (defalias 'notmuch-setq-local 'setq-local)
diff --git a/test/T310-emacs.sh b/test/T310-emacs.sh
index 5331514..a486df8 100755
--- a/test/T310-emacs.sh
+++ b/test/T310-emacs.sh
@@ -209,7 +209,6 @@ EOF
 test_expect_equal_file OUTPUT EXPECTED
 
 test_begin_subtest "Folding a long header when sending via (fake) SMTP"
-test_subtest_known_broken
 long_subject="This is a long subject `seq -s ' ' 1 1000`"
 emacs_deliver_message \
 "${long_subject}" \
-- 
2.1.4

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


[PATCH] emacs: fully add the notmuch-address customize group

2017-01-28 Thread Mark Walters
We now have several customizable options for address completion. There
is a customize group notmuch-address but it only contains one of these
options. Add all the others, and make it part of the notmuch customize
group.
---

Bremner pointed out that many of these were not in the notmuch-addres
customize group, so we add them all.

Best wishes

Mark



 emacs/notmuch-address.el | 7 ++-
 emacs/notmuch-lib.el | 4 
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 15c709d..d504ff2 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -66,6 +66,7 @@ disabled."
  (const :tag "Disable address completion" nil)
  (string :tag "Use external completion command"))
   :group 'notmuch-send
+  :group 'notmuch-address
   :group 'notmuch-external)
 
 (defcustom notmuch-address-internal-completion '(sent nil)
@@ -93,6 +94,7 @@ This should be a list of the form '(DIRECTION FILTER), where
 (setq notmuch-address-completions (clrhash 
notmuch-address-completions))
 (setq notmuch-address-full-harvest-finished nil))
   :group 'notmuch-send
+  :group 'notmuch-address
   :group 'notmuch-external)
 
 (defcustom notmuch-address-save-filename nil
@@ -104,6 +106,7 @@ should make sure it is not somewhere publicly readable."
   :type '(choice (const :tag "Off" nil)
 (file :tag "Filename"))
   :group 'notmuch-send
+  :group 'notmuch-address
   :group 'notmuch-external)
 
 (defcustom notmuch-address-selection-function 
'notmuch-address-selection-function
@@ -115,6 +118,7 @@ See documentation of function 
`notmuch-address-selection-function'
 to know how address selection is made by default."
   :type 'function
   :group 'notmuch-send
+  :group 'notmuch-address
   :group 'notmuch-external)
 
 (defcustom notmuch-address-post-completion-functions nil
@@ -145,7 +149,8 @@ matching `notmuch-address-completion-headers-regexp'.
 (defcustom notmuch-address-use-company t
   "If available, use company mode for address completion"
   :type 'boolean
-  :group 'notmuch-send)
+  :group 'notmuch-send
+  :group 'notmuch-address)
 
 (defun notmuch-address-setup ()
   (let* ((setup-company (and notmuch-address-use-company
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 5dc6797..337b20a 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -74,6 +74,10 @@
   "Running external commands from within Notmuch."
   :group 'notmuch)
 
+(defgroup notmuch-address nil
+  "Address completion."
+  :group 'notmuch)
+
 (defgroup notmuch-faces nil
   "Graphical attributes for displaying text"
   :group 'notmuch)
-- 
2.1.4

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


[PATCH] emacs: company: remove two build warnings

2017-01-28 Thread Mark Walters
This adds two defvars to avoid two build warnings in the notmuch emacs
code. These were both introduced (by me) in commit 827c28a0.
---

The defvar for notmuch-address-command is clearly correct as that is
defined in notmuch-address so will definitely be defined when this
code is run.

The other, for company-idle-timeout, is slightly less clear, as the
user may not use company. It feels a little unpleasant to be defining
variables outside our namespace but we do the same with
company-backends.

[Incidentally I don't think emacs compiler should complain as the
actual use (line 59) is a macro which does bind the variable in any
case.]

Best wishes

Mark




emacs/notmuch-company.el | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
index dca6471..3e12e7a 100644
--- a/emacs/notmuch-company.el
+++ b/emacs/notmuch-company.el
@@ -37,12 +37,14 @@
 (declare-function company-mode "company")
 (declare-function company-manual-begin "company")
 (defvar company-backends)
+(defvar company-idle-delay)
 
 (declare-function notmuch-address-harvest "notmuch-address")
 (declare-function notmuch-address-harvest-trigger "notmuch-address")
 (declare-function notmuch-address-matching "notmuch-address")
 (declare-function notmuch-address--harvest-ready "notmuch-address")
 (defvar notmuch-address-completion-headers-regexp)
+(defvar notmuch-address-command)
 
 ;;;###autoload
 (defun notmuch-company-setup ()
-- 
2.1.4

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


[PATCH v2] emacs: show: stop display of application/* parts

2017-01-28 Thread Mark Walters
Gnus seems to display application/zip and application/tar by
default. This doesn't seem desirable so we override it.

We only override if the user has not customized
mm-inline-override-types themselves.
---

I think this fixes all the bugs (and typos). Thanks to Tomas and Tomi
for finding and verifying the correct way to get the default value of
a defcustom variable.

It's only lightly tested but seems to work.

Best wishes

Mark



emacs/notmuch-show.el | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 364004b..c670160 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1227,7 +1227,15 @@ matched."
   (interactive "sNotmuch show: \nP")
   (let ((buffer-name (generate-new-buffer-name
  (or buffer-name
- (concat "*notmuch-" thread-id "*")
+ (concat "*notmuch-" thread-id "*"
+   ;; We override mm-inline-override-types to stop application/*
+   ;; parts from being displayed unless the user has customized
+   ;; it themselves.
+   (mm-inline-override-types
+(if (equal mm-inline-override-types
+   (eval (car (get 'mm-inline-override-types 
'standard-value
+(cons "application/*" mm-inline-override-types)
+  mm-inline-override-types)))
 (switch-to-buffer (get-buffer-create buffer-name))
 ;; No need to track undo information for this buffer.
 (setq buffer-undo-list t)
-- 
2.1.4

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


Re: Q: notmuch emacs, fcc, maildir, notmuch insert and message-kill-buffer-on-exit

2017-01-25 Thread Mark Walters

Hi

I am not sure what the full problem is (I will try and have a better
look later), but I think the main problem is that the sending mail part
is returning an error. The "Sending...failed to" is coming from emacs,
and I think the  "mail for [ -oi -t > ] : send was successful; " from
msmtp/msmptq.

The insert is done after the send, so since this returns an error the
insert is never attempted.

Best wishes

Mark


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


[PATCH] emacs: show: stop display of appliaction/* parts

2017-01-07 Thread Mark Walters
Gnus seems to display application/zip and application/tar by
default. This doesn't seem desirable so we override it.

We only override ifthe user has not customized
mm-inline-override-types themselves.
---

This was mentioned on irc today and this might be a reasonable way of
doing this.

It does mean that if a user adds, for example, image/* to
mm-inline-override-types then application/* will be displayed again.

It also makes it slightly awkward to allow all types (eg setting
mm-inline-override-types to non/existent would do).

Also I feel there ought to be a better way to tell if a variable has
been customized (or otherwise set), but I didn't find one.

Best wishes

Mark


emacs/notmuch-show.el | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 364004b..42734ac 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1227,7 +1227,15 @@ matched."
   (interactive "sNotmuch show: \nP")
   (let ((buffer-name (generate-new-buffer-name
  (or buffer-name
- (concat "*notmuch-" thread-id "*")
+ (concat "*notmuch-" thread-id "*"
+   ;; We override mm-inline-override-types to stop appliacation/*
+   ;; parts from being displayed unless the user has customized
+   ;; it themselves.
+   (mm-inline-override-types
+(if (equal (list mm-inline-override-types)
+   (get 'mm-inline-override-types 'standard-value))
+(cons "application/*" mm-inline-override-types)
+  mm-inline-override-types)))
 (switch-to-buffer (get-buffer-create buffer-name))
 ;; No need to track undo information for this buffer.
 (setq buffer-undo-list t)
-- 
2.1.4

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


[WIP PATCH] emacs: tag-jump allow post tag functions

2016-12-15 Thread Mark Walters
This adds an option to the tag-jump defcustom to apply a post-tagging
function. One natural option is to go to the next thread/message.
---

This is a first attempt at this. The main change needed is to update
the docstrings.

The structure is a little weird (a list with a plist as an
element). However this has two advantage, it is backward compatible,
and it is possible to hide the more complicated options.

Best wishes

Mark




 emacs/notmuch-tag.el | 33 ++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
index 09d182d..a6506dc 100644
--- a/emacs/notmuch-tag.el
+++ b/emacs/notmuch-tag.el
@@ -42,7 +42,25 @@
(key-sequence :tag "Key")
(radio :tag "Tag operations" (repeat :tag "Tag list" (string 
:format "%v" :tag "change"))
   (variable :tag "Tag variable"))
-   (string :tag "Name"
+   (string :tag "Name")
+   (choice :tag "Advanced Options"
+   (const :tag "None" nil)
+   (list :tag "Choose"
+ (const :format "" :post-search)
+ (choice :tag "Post tag in search view: "
+ (const :tag "None" ignore)
+ (const :tag "Next" 
notmuch-search-next-thread)
+ (function :tag "Custom function" :format 
"%v"))
+ (const :format "" :post-tree)
+ (choice :tag "Post tag in tree view: "
+ (const :tag "None" ignore)
+ (const :tag "Next" 
notmuch-tree-next-message)
+ (function :tag "Custom function" :format 
"%v"))
+ (const :format "" :post-show)
+ (choice :tag "Post tag in show view: "
+ (const :tag "None" ignore)
+ (const :tag "Next" 
notmuch-show-next-message)
+ (function :tag "Custom function" :format 
"%v")))
 
 (defcustom notmuch-tagging-keys
   `((,(kbd "a") notmuch-archive-tags "Archive")
@@ -530,9 +548,18 @@ and vice versa."
 (name-string (if name
  (if reverse (concat "Reverse " name)
name)
-   (mapconcat #'identity tag-change " "
+   (mapconcat #'identity tag-change " ")))
+(adv-opts (fourth binding))
+(post-tag-function
+ (case major-mode
+   (notmuch-search-mode (plist-get adv-opts :post-search))
+   (notmuch-show-mode (plist-get adv-opts :post-show))
+   (notmuch-tree-mode (plist-get adv-opts :post-tree)
(push (list key name-string
-`(lambda () (,tag-function ',tag-change)))
+   `(lambda () (,tag-function ',tag-change)
+  ,(if post-tag-function
+   `(,post-tag-function)
+ '(ignore
  action-map)))
 (push (list notmuch-tag-jump-reverse-key
(if reverse
-- 
2.1.4

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


Re: anyone uses notmuch-web?

2016-12-14 Thread Mark Walters

> i'm an user of notmuch already for some years (in fact from the beginning).
> great product! i want to replace my roundcube installation on web server by
> notmuch-web, which - at least in testing on local computer - looks great and
> does exactly the job.
>
> my concerns are in the domain of the internet security. apparently the haskell
> stuff (sorry, not a haskell guy) cannot go over https, but only http, and for
> this one has to do some proxying between http and https done on http 
> server
> level.

I can't say much about notmuch-web but as a shameless plug rlb and I are
working on noservice https://gitlab.com/noservice/noservice

This is intended as pure https (ideally you use a firewall to block its
http port), and by default uses client certificate verification so is
probably reasonably secure. Note neither rlb nor I are security experts.

A rough guide is that noservice is intended to look and feel like the
emacs frontend. I use it every day and it meets most of my requirements.

> is anyone using such modus operandi? could you share your thoughts about using
> notmuch-web?

If you do decide to use notmuch-web then possibly try nginx as the https
frontend, and you can configure that to require client certificates.

Best wishes

Mark




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


Re: [emacs] thread view is showing all messages

2016-11-20 Thread Mark Walters

Hi

>> --
>> By default, various components of email messages, (citations,
>> signatures, already-read messages),  are hidden.
>> --

I wonder if this text should be changed -- I am not sure what is meant
by already-read messages (maybe completely cited messages?) but it does
seem misleading. Having said that, I don't have a good suggestion -- the
best I can come up with is "quoted messages"

Interestingly the wording above dates back to 2009 so maybe it isn't
that big a problem.

Best wishes

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


Re: Filtering completions

2016-11-20 Thread Mark Walters

Hi

On Mon, 21 Nov 2016, Sebastian Fischmeister  wrote:
> Hi,
>
> Is there a variable defining a regex to filter harvested completions before 
> showing them? My completions include some outdated or invalid email addresses 
> for people and I would like to automatically remove them from the list.
>
> I didn't find something for that in notmuch-address.el, and for instance 
> notmuch-address-matching.

There is no regex or similar, but you can filter the search used to
harvest the addresses -- see notmuch-address-internal-completion
(customisable under notmuch-send). 

You might find that putting a date limit would work; alternatively you
could tag messages from the dead addresses (eg tag:dead-address) and put
a "not tag:dead-address" in the filter field.

Best wishes

Mark


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


[PATCH 2/2] emacs: address: save hash

2016-11-20 Thread Mark Walters
This allows the user to save the address hash so that it is much
faster for the first completion after a restart. This defaults to off
as there are privacy implications to saving this information.

The code tries hard to avoid overwriting the wrong file. It also notes
if changes have been made to any of the relevant user settings, so
that the user does not get surprising results (i.e., outdated options
being used). Finally it stores some version information so that is
easy for us to update the format of the save file.
---
 emacs/notmuch-address.el | 83 +---
 1 file changed, 79 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 2eaca79..15c709d 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -37,11 +37,15 @@
 
 (defvar notmuch-address-full-harvest-finished nil
   "t indicates that full completion address harvesting has been
-finished. Use notmuch-address--harvest-ready to access.")
+finished. Use notmuch-address--harvest-ready to access as that
+will load a saved hash if necessary (and available).")
 
 (defun notmuch-address--harvest-ready ()
-  "Return t if there is a full address hash available."
-  notmuch-address-full-harvest-finished)
+  "Return t if there is a full address hash available.
+
+If the hash is not present it attempts to load a saved hash."
+  (or notmuch-address-full-harvest-finished
+  (notmuch-address--load-address-hash)))
 
 (defcustom notmuch-address-command 'internal
   "Determines how address completion candidates are generated.
@@ -91,6 +95,17 @@ This should be a list of the form '(DIRECTION FILTER), where
   :group 'notmuch-send
   :group 'notmuch-external)
 
+(defcustom notmuch-address-save-filename nil
+  "Filename to save the cached completion addresses.
+
+All the addresses notmuch uses for address completion will be
+cached in this file. This has obvious privacy implications so you
+should make sure it is not somewhere publicly readable."
+  :type '(choice (const :tag "Off" nil)
+(file :tag "Filename"))
+  :group 'notmuch-send
+  :group 'notmuch-external)
+
 (defcustom notmuch-address-selection-function 
'notmuch-address-selection-function
   "The function to select address from given list. The function is
 called with PROMPT, COLLECTION, and INITIAL-INPUT as arguments
@@ -327,6 +342,64 @@ execution, CALLBACK is called when harvesting finishes."
   ;; return value
   nil)
 
+(defvar notmuch-address--save-hash-version 1
+  "Version format of the save hash.")
+
+(defun notmuch-address--get-address-hash ()
+  "Returns the saved address hash as a plist.
+
+Returns nil if the save file does not exist, or it does not seem
+to be a saved address hash."
+  (when notmuch-address-save-filename
+(condition-case nil
+   (with-temp-buffer
+ (insert-file-contents notmuch-address-save-filename)
+ (let ((name (read (current-buffer)))
+   (plist (read (current-buffer
+   ;; We do two simple sanity checks on the loaded file. We just
+   ;; check a version is specified, not that it is the current
+   ;; version, as we are allowed to over-write and a save-file with
+   ;; an older version.
+   (when (and (string= name "notmuch-address-hash")
+  (plist-get plist :version))
+ plist)))
+  ;; The error case catches any of the reads failing.
+  (error nil
+
+(defun notmuch-address--load-address-hash ()
+  "Read the saved address hash and set the corresponding variables."
+  (let ((load-plist (notmuch-address--get-address-hash)))
+(when (and load-plist
+  ;; If the user's setting have changed, or the version
+  ;; has changed, return nil to make sure the new settings
+  ;; take effect.
+  (equal (plist-get load-plist :completion-settings)
+ notmuch-address-internal-completion)
+  (equal (plist-get load-plist :version)
+ notmuch-address--save-hash-version))
+  (setq notmuch-address-last-harvest (plist-get load-plist :last-harvest)
+   notmuch-address-completions (plist-get load-plist :completions)
+   notmuch-address-full-harvest-finished t)
+  ;; Return t to say load was successful.
+  t)))
+
+(defun notmuch-address--save-address-hash ()
+  (when notmuch-address-save-filename
+(if (or (not (file-exists-p notmuch-address-save-filename))
+ ;; The file exists, check it is a file we saved
+   (notmuch-address--get-address-hash))
+   (with-temp-file notmuch-address-save-filename
+ (let ((save-plist (list :version notmuch-address--save-hash-version
+ :completion-settings 
notmuch-address-internal-completion
+ :last-harvest notmuch-address-last-harvest
+ :completions 

[PATCH 0/2] emacs allow save and load of the address-completions

2016-11-20 Thread Mark Walters
This series adds a load/save functionality for the address
completions. This avoids the slow and poor completion provided until
the full address-hash has been generated -- this can take some time,
(over a minute on my machine), and is annoying if you frequently
restart emacs (e.g. when debugging things).

Although the patch is quite large it is relatively simple: essentially
a "print" to save, and a "read" to load. I have tried quite hard to
stop over-writing existing files, and to make sure the user does not
get surprising results if they change settings or the address
completion is upgraded in some way (e.g., we store the frequency of
each match in the map).

By default the save/load is switched off: this avoids accidental
privacy leaks, but does make it harder for users to discover.

Best wishes

Mark



Mark Walters (2):
  emacs: address: move address-full-harvest-finished to a function
  emacs: address: save hash

 emacs/notmuch-address.el | 85 ++--
 emacs/notmuch-company.el |  4 +--
 2 files changed, 84 insertions(+), 5 deletions(-)

-- 
2.1.4

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


[PATCH 1/2] emacs: address: move address-full-harvest-finished to a function

2016-11-20 Thread Mark Walters
This makes the code access notmuch-address-full-harvest-finished via a
helper function, notmuch-address--harvest-ready. Later we will use
this to check whether we can load the harvest instead of regenerating
it.
---
 emacs/notmuch-address.el | 8 ++--
 emacs/notmuch-company.el | 4 ++--
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index b3c56cf..2eaca79 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -37,7 +37,11 @@
 
 (defvar notmuch-address-full-harvest-finished nil
   "t indicates that full completion address harvesting has been
-finished")
+finished. Use notmuch-address--harvest-ready to access.")
+
+(defun notmuch-address--harvest-ready ()
+  "Return t if there is a full address hash available."
+  notmuch-address-full-harvest-finished)
 
 (defcustom notmuch-address-command 'internal
   "Determines how address completion candidates are generated.
@@ -170,7 +174,7 @@ elisp-based implementation or older implementation requiring
 external commands."
   (cond
((eq notmuch-address-command 'internal)
-(when (not notmuch-address-full-harvest-finished)
+(unless (notmuch-address--harvest-ready)
   ;; First, run quick synchronous harvest based on what the user
   ;; entered so far
   (notmuch-address-harvest original t))
diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
index ebe2c08..dca6471 100644
--- a/emacs/notmuch-company.el
+++ b/emacs/notmuch-company.el
@@ -41,7 +41,7 @@
 (declare-function notmuch-address-harvest "notmuch-address")
 (declare-function notmuch-address-harvest-trigger "notmuch-address")
 (declare-function notmuch-address-matching "notmuch-address")
-(defvar notmuch-address-full-harvest-finished)
+(declare-function notmuch-address--harvest-ready "notmuch-address")
 (defvar notmuch-address-completion-headers-regexp)
 
 ;;;###autoload
@@ -70,7 +70,7 @@
 (line-beginning-position))
   (setq notmuch-company-last-prefix (company-grab "[:,][ 
\t]*\\(.*\\)" 1 (point-at-bol)
   (candidates (cond
-  (notmuch-address-full-harvest-finished
+  ((notmuch-address--harvest-ready)
;; Update harvested addressed from time to time
(notmuch-address-harvest-trigger)
(notmuch-address-matching arg))
-- 
2.1.4

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


[PATCH] NEWS for notmuch-cycle-notmuch-buffers

2016-11-18 Thread Mark Walters
---

A first attempt at NEWS for 09caa0f. I am not fully happy with it, so
any suggestions very welcome. It applies on top of
id:20161117121820.23393-1-da...@tethera.net

Best wishes

Mark



NEWS | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/NEWS b/NEWS
index e693da7..3413a9c 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,13 @@ Notmuch 0.23.2 (UNRELEASED)
 Emacs
 -
 
+Fix notmuch-interesting-buffer and notmuch-cycle-notmuch-buffers.
+
+  The functions `notmuch-interesting-buffer` which detects notmuch
+  buffers, and `notmuch-cycle-notmuch-buffers` which cycles between
+  notmuch buffers, now additionally detect notmuch-tree-mode and
+  notmuch-message-mode buffers.
+
 Restore compatibility with Emacs 23.
 
   Notmuch support for Emacs 23 is now deprecated.
-- 
2.1.4

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


[PATCH] emacs: remove use of message-send-hook

2016-11-17 Thread Mark Walters
We use message-send-hook for two things -- tagging drafts deleted, and
tagging replied the parent message of a reply. We should not use
message-send-hook as that will affect gnus etc too. Moreover,
message-send-hook is run before the message is sent, even before the
user confirms they want to send it (if message-confirm-send is
set). This means the user can do C-c C-c to send, then cancel, and the
parent is still tagged replied.

Now we have our own send function it is natural to put these functions
there rather than in the hook. We also fix the bug mentioned
above. This is slightly tricky as message-send-and-exit kills the
compose buffer, so we need to store the tagging commands ready to be
run after the send is successful.
---

As mentioned in the commit message, we need to remove our use of
message-send-hook and fix the bug of erroneously tagging messages
"replied" or "deleted". This approach might be a little overkill (a
dolist for a list of two elements), but it avoids breaking the api
(for notmuch-message-mark-replied) and is easily extendable if we need
to add more post send tagging operations later.

Also, it seemed easiest to tweak the require orders, but maybe we
should just move the two things in notmuch-message into notmuch-mua.

Best wishes

Mark


emacs/notmuch-draft.el   | 12 ++--
 emacs/notmuch-message.el | 12 +++-
 emacs/notmuch-mua.el | 19 +++
 3 files changed, 28 insertions(+), 15 deletions(-)

diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
index fb7f4f5..738628b 100644
--- a/emacs/notmuch-draft.el
+++ b/emacs/notmuch-draft.el
@@ -91,12 +91,15 @@ postponing and resuming a message."
   "Message-id of the most recent saved draft of this message")
 (make-variable-buffer-local 'notmuch-draft-id)
 
-(defun notmuch-draft--mark-deleted ()
+(defun notmuch-draft--mark-deleted ( dry-run)
   "Tag the last saved draft deleted.
 
-Used when a new version is saved, or the message is sent."
+Used when a new version is saved, or the message is sent.  If
+DRY-RUN is set, then just return a list of the arguments for
+`notmuch-tag' rather than doing the tagging."
   (when notmuch-draft-id
-(notmuch-tag notmuch-draft-id '("+deleted"
+(funcall (if dry-run #'list #'notmuch-tag)
+notmuch-draft-id '("+deleted"
 
 (defun notmuch-draft-quote-some-mml ()
   "Quote the mml tags in `notmuch-draft-quoted-tags`."
@@ -259,9 +262,6 @@ applied to newly inserted messages)."
   (setq notmuch-draft-id (when draft id)
 
 
-(add-hook 'message-send-hook 'notmuch-draft--mark-deleted)
-
-
 (provide 'notmuch-draft)
 
 ;;; notmuch-draft.el ends here
diff --git a/emacs/notmuch-message.el b/emacs/notmuch-message.el
index 55e4cfe..373d38c 100644
--- a/emacs/notmuch-message.el
+++ b/emacs/notmuch-message.el
@@ -23,7 +23,6 @@
 
 (require 'message)
 (require 'notmuch-tag)
-(require 'notmuch-mua)
 
 (defcustom notmuch-message-replied-tags '("+replied")
   "List of tag changes to apply to a message when it has been replied to.
@@ -38,15 +37,18 @@ the \"inbox\" and \"todo\" tags, you would set:
   :type '(repeat string)
   :group 'notmuch-send)
 
-(defun notmuch-message-mark-replied ()
+(defun notmuch-message-mark-replied ( dry-run)
+  "Tag the parent message replied.
+
+If DRY-RUN is set, then just return a list of the arguments for
+`notmuch-tag' rather than doing the tagging."
   ;; get the in-reply-to header and parse it for the message id.
   (let ((rep (mail-header-parse-addresses (message-field-value 
"In-Reply-To"
 (when (and notmuch-message-replied-tags rep)
-  (notmuch-tag (notmuch-id-to-query (car (car rep)))
+  (funcall (if dry-run #'list #'notmuch-tag)
+  (notmuch-id-to-query (car (car rep)))
   (notmuch-tag-change-list notmuch-message-replied-tags)
 
-(add-hook 'message-send-hook 'notmuch-message-mark-replied)
-
 (provide 'notmuch-message)
 
 ;;; notmuch-message.el ends here
diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index 93747b1..07be69a 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -28,6 +28,7 @@
 (require 'notmuch-lib)
 (require 'notmuch-address)
 (require 'notmuch-draft)
+(require 'notmuch-message)
 
 (eval-when-compile (require 'cl))
 
@@ -545,10 +546,20 @@ unencrypted.  Really send? "
   (interactive "P")
   (when (and (notmuch-mua-check-no-misplaced-secure-tag)
 (notmuch-mua-check-secure-tag-has-newline))
-(letf (((symbol-function 'message-do-fcc) 
#'notmuch-maildir-message-do-fcc))
- (if exit
- (message-send-and-exit arg)
-   (message-send arg)
+(let (tag-change
+ post-send-tag-changes)
+  ;; post-send-tag-changes are tag-changes to apply after sending,
+  ;; but we need to store them now as the compose buffer is
+  ;; typically killed before message-send-and-exit returns.
+  (push (notmuch-message-mark-replied t) post-send-tag-changes)
+  (push (notmuch-draft--mark-deleted 

[PATCH v3] emacs: add compatibility functions for emacs 23

2016-11-15 Thread Mark Walters
Some of the recent changes to the emacs code have used functions
introduced in emacs 24. The functions used are read-char-choice and
setq-local. This changeset adds a file notmuch-compat.el which
contains compatibility functions so that it should work on emacs
23.

Note, since these functions are taken almost unchanged from the emacs
source they are copyright the Free Software Foundation, and the header
in the file reflects that.
---

Hi

This is another version of this patch. The previous version is at
id:1477736487-31319-1-git-send-email-markwalters1...@gmail.com

The main change is to split out the compatibility functions into a
separate file.

I haven't moved the defadvice code mentioned in
id:87mvh4rigu@tethera.net into this file as that confuses the
copyright situation (I think that it is all Tomi's code)

Best wishes

Mark




emacs/Makefile.local |  1 +
 emacs/notmuch-address.el |  4 +--
 emacs/notmuch-company.el |  3 +-
 emacs/notmuch-compat.el  | 73 
 emacs/notmuch-lib.el |  1 +
 emacs/notmuch-maildir-fcc.el |  4 +--
 6 files changed, 81 insertions(+), 5 deletions(-)
 create mode 100644 emacs/notmuch-compat.el

diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 6896ff9..442a5e4 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -3,6 +3,7 @@
 dir := emacs
 emacs_sources := \
$(dir)/notmuch-lib.el \
+   $(dir)/notmuch-compat.el \
$(dir)/notmuch-parser.el \
$(dir)/notmuch.el \
$(dir)/notmuch-query.el \
diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 5b2beef..b3c56cf 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -147,11 +147,11 @@ toggles the setting in this buffer."
   (interactive)
   (if (local-variable-p 'notmuch-address-command)
   (kill-local-variable 'notmuch-address-command)
-(setq-local notmuch-address-command 'internal))
+(notmuch-setq-local notmuch-address-command 'internal))
   (if (boundp 'company-idle-delay)
   (if (local-variable-p 'company-idle-delay)
  (kill-local-variable 'company-idle-delay)
-   (setq-local company-idle-delay nil
+   (notmuch-setq-local company-idle-delay nil
 
 (defun notmuch-address-matching (substring)
   "Returns a list of completion candidates matching SUBSTRING.
diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
index b0f9782..ebe2c08 100644
--- a/emacs/notmuch-company.el
+++ b/emacs/notmuch-company.el
@@ -28,6 +28,7 @@
 ;;; Code:
 
 (eval-when-compile (require 'cl))
+(require 'notmuch-lib)
 
 (defvar notmuch-company-last-prefix nil)
 (make-variable-buffer-local 'notmuch-company-last-prefix)
@@ -53,7 +54,7 @@
   ;; internal completion) can still be accessed via standard company
   ;; functions, e.g., company-complete.
   (unless (eq notmuch-address-command 'internal)
-(setq-local company-idle-delay nil)))
+(notmuch-setq-local company-idle-delay nil)))
 
 ;;;###autoload
 (defun notmuch-company (command  arg  _ignore)
diff --git a/emacs/notmuch-compat.el b/emacs/notmuch-compat.el
new file mode 100644
index 000..c3d827a
--- /dev/null
+++ b/emacs/notmuch-compat.el
@@ -0,0 +1,73 @@
+;; Compatibility functions for emacs 23 and 24 pre 24.4
+
+;; The functions in this file are copied from eamcs 24.4 and are
+;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2014 Free Software
+;; Foundation, Inc.
+
+(if (fboundp 'setq-local)
+(defalias 'notmuch-setq-local 'setq-local)
+  (defmacro notmuch-setq-local (var val)
+"Set variable VAR to value VAL in current buffer.
+
+Backport of setq-local for emacs without setq-local (pre 24.3)."
+`(set (make-local-variable ',var) ,val)))
+
+(if (fboundp 'read-char-choice)
+(defalias 'notmuch-read-char-choice 'read-char-choice)
+  (defun notmuch-read-char-choice (prompt chars  
inhibit-keyboard-quit)
+  "Read and return one of CHARS, prompting for PROMPT.
+Any input that is not one of CHARS is ignored.
+
+If optional argument INHIBIT-KEYBOARD-QUIT is non-nil, ignore
+keyboard-quit events while waiting for a valid input.
+
+This is an exact copy of this function from emacs 24 for use on
+emacs 23, except with the one emacs 24 only function it calls
+inlined."
+  (unless (consp chars)
+(error "Called `read-char-choice' without valid char choices"))
+  (let (char done show-help (helpbuf " *Char Help*"))
+(let ((cursor-in-echo-area t)
+  (executing-kbd-macro executing-kbd-macro)
+ (esc-flag nil))
+  (save-window-excursion ; in case we call help-form-show
+   (while (not done)
+ (unless (get-text-property 0 'face prompt)
+   (setq prompt (propertize prompt 'face 'minibuffer-prompt)))
+ (setq char (let ((inhibit-quit inhibit-keyboard-quit))
+  (read-key prompt)))
+ (and show-help (buffer-live-p (get-buffer helpbuf))
+  (kill-buffer helpbuf))
+ (cond
+  ((not 

[PATCH] Test: fix draft test for emacs23

2016-11-14 Thread Mark Walters
emacs24 and emacs23 have different secure tag defaults: in particular,
mml-secure-message-sign only signs the part on emacs23 but the whole
message on emacs24. This difference makes one of the draft tests fail
(which causes a cascade of later failures) on emacs23. It seems that
travis uses emacs23 so it is useful to fix this.

We do this by forcing the whole message to be signed in either case --
the code snippet is extracted from mml-secure-message-sign on emacs24.
---

The main thing to note with this is that the motivation for fixing is
that travis seems to use emacs23.

Best wishes

Mark



test/T630-emacs-draft.sh | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/test/T630-emacs-draft.sh b/test/T630-emacs-draft.sh
index 46fc356..cd9e33a 100755
--- a/test/T630-emacs-draft.sh
+++ b/test/T630-emacs-draft.sh
@@ -32,7 +32,9 @@ test_begin_subtest "Saving a signed draft adds header"
 test_emacs '(notmuch-mua-mail)
(message-goto-subject)
(insert "draft-test-0003")
-   (mml-secure-message-sign)
+;; We would use (mml-secure-message-sign) but on emacs23
+;; that only signs the part, not the whole message.
+(mml-secure-message mml-secure-method '\''sign)
(notmuch-draft-save)
(test-output)'
 header_count=$(notmuch show --format=raw subject:draft-test-0003 | grep -c 
^X-Notmuch-Emacs-Secure)
-- 
2.1.4

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


[PATCH v7 3/4] emacs: check drafts for encryption tags before saving

2016-11-13 Thread Mark Walters
From: David Bremner 

In general the user may not want to save plaintext copies of messages
that they are sending encrypted, so give them a chance to abort.
---
 emacs/notmuch-draft.el   | 39 +++
 test/T630-emacs-draft.sh | 13 +
 2 files changed, 52 insertions(+)

diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
index b8a5e67..1fb049a 100644
--- a/emacs/notmuch-draft.el
+++ b/emacs/notmuch-draft.el
@@ -71,6 +71,21 @@ postponing and resuming a message."
   :type '(repeat string)
   :group 'notmuch-send)
 
+(defcustom notmuch-draft-save-plaintext 'ask
+  "Should notmuch save/postpone in plaintext messages that seem
+  like they are intended to be sent encrypted
+(i.e with an mml encryption tag in it)."
+  :type '(radio
+ (const :tag "Never" nil)
+ (const :tag "Ask every time" ask)
+ (const :tag "Always" t))
+  :group 'notmuch-draft
+  :group 'notmuch-crypto)
+
+(defvar notmuch-draft-encryption-tag-regex
+  "<#\\(part encrypt\\|secure.*mode=.*encrypt>\\)"
+  "Regular expression matching mml tags indicating encryption of part or 
message")
+
 (defvar notmuch-draft-id nil
   "Message-id of the most recent saved draft of this message")
 (make-variable-buffer-local 'notmuch-draft-id)
@@ -103,6 +118,28 @@ Used when a new version is saved, or the message is sent."
  (goto-char (+ (match-beginning 0) 2))
  (insert "!"))
 
+(defun notmuch-draft--has-encryption-tag ()
+  "Returns t if there is an mml secure tag."
+  (save-excursion
+(message-goto-body)
+(re-search-forward notmuch-draft-encryption-tag-regex nil 't)))
+
+(defun notmuch-draft--query-encryption ()
+  "Checks if we should save a message that should be encrypted.
+
+`notmuch-draft-save-plaintext' controls the behaviour."
+  (case notmuch-draft-save-plaintext
+   ((ask)
+(notmuch-draft--query-encryption)
+(unless (yes-or-no-p "(Customize `notmuch-draft-save-plaintext' to 
avoid this warning)
+This message contains mml tags that suggest it is intended to be encrypted.
+Really save and index an unencrypted copy? ")
+  (error "Save aborted")))
+   ((nil)
+(error "Refusing to save draft with encryption tags (see 
`notmuch-draft-save-plaintext')"))
+   ((t)
+(ignore
+
 (defun notmuch-draft--make-message-id ()
   ;; message-make-message-id gives the id inside a "<" ">" pair,
   ;; but notmuch doesn't want that form, so remove them.
@@ -115,6 +152,8 @@ This saves the current message in the database with tags
 `notmuch-draft-tags` (in addition to any default tags
 applied to newly inserted messages)."
   (interactive)
+  (when (notmuch-draft--has-encryption-tag)
+(notmuch-draft--query-encryption))
   (let ((id (notmuch-draft--make-message-id)))
 (with-temporary-notmuch-message-buffer
  ;; We insert a Date header and a Message-ID header, the former
diff --git a/test/T630-emacs-draft.sh b/test/T630-emacs-draft.sh
index e39690c..689ccfb 100755
--- a/test/T630-emacs-draft.sh
+++ b/test/T630-emacs-draft.sh
@@ -39,4 +39,17 @@ header_count=$(notmuch show --format=raw 
subject:draft-test-0003 | grep -c ^X-No
 body_count=$(notmuch notmuch show --format=raw subject:draft-test-0003 | grep 
-c '^\<#secure')
 test_expect_equal "$header_count,$body_count" "1,0"
 
+test_begin_subtest "Refusing to save an encrypted draft"
+test_emacs '(notmuch-mua-mail)
+   (message-goto-subject)
+   (insert "draft-test-0004")
+   (mml-secure-message-sign-encrypt)
+   (let ((notmuch-draft-save-plaintext nil))
+(notmuch-draft-save))
+   (test-output)'
+count1=$(notmuch count tag:draft)
+count2=$(notmuch count subject:draft-test-0004)
+
+test_expect_equal "$count1,$count2" "3,0"
+
 test_done
-- 
2.1.4

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


[PATCH v7 4/4] emacs: resume messages

2016-11-13 Thread Mark Walters
From: David Bremner 

Provide functionality to resume editing a message previously saved with
notmuch-draft-save, including decoding the X-Notmuch-Emacs-Secure
header.

Resume gets the raw file from notmuch and using the emacs function
mime-to-mml reconstructs the message (including attachments).

'e' is bound to resume a draft from show or tree mode.
---
 emacs/notmuch-draft.el   | 62 
 emacs/notmuch-show.el|  8 +++
 emacs/notmuch-tree.el| 10 
 test/T630-emacs-draft.sh | 15 
 4 files changed, 95 insertions(+)

diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
index 1fb049a..496e11f 100644
--- a/emacs/notmuch-draft.el
+++ b/emacs/notmuch-draft.el
@@ -25,6 +25,7 @@
 
 (require 'notmuch-maildir-fcc)
 (require 'notmuch-tag)
+(require 'notmuch-mua)
 
 (declare-function notmuch-show-get-message-id "notmuch-show" ( bare))
 
@@ -118,6 +119,27 @@ Used when a new version is saved, or the message is sent."
  (goto-char (+ (match-beginning 0) 2))
  (insert "!"))
 
+(defun notmuch-draft-unquote-some-mml ()
+  "Unquote the mml tags in `notmuch-draft-quoted-tags`."
+  (save-excursion
+(when notmuch-draft-quoted-tags
+  (let ((re (concat "<#!+/?\\("
+   (mapconcat 'regexp-quote notmuch-draft-quoted-tags 
"\\|")
+   "\\)")))
+   (message-goto-body)
+   (while (re-search-forward re nil t)
+ ;; Remove one ! from after the #.
+ (goto-char (+ (match-beginning 0) 2))
+ (delete-char 1
+(let (secure-tag)
+  (save-restriction
+   (message-narrow-to-headers)
+   (setq secure-tag (message-fetch-field "X-Notmuch-Emacs-Secure" 't))
+   (message-remove-header "X-Notmuch-Emacs-Secure"))
+  (message-goto-body)
+  (when secure-tag
+   (insert secure-tag "\n")
+
 (defun notmuch-draft--has-encryption-tag ()
   "Returns t if there is an mml secure tag."
   (save-excursion
@@ -198,6 +220,46 @@ applied to newly inserted messages)."
   (notmuch-draft-save)
   (kill-buffer))
 
+(defun notmuch-draft-resume (id)
+  "Resume editing of message with id ID."
+  (let* ((tags (process-lines notmuch-command "search" "--output=tags"
+ "--exclude=false" id))
+(draft (equal tags (notmuch-update-tags tags notmuch-draft-tags
+(when (or draft
+ (yes-or-no-p "Message does not appear to be a draft: really 
resume? "))
+  (switch-to-buffer (get-buffer-create (concat "*notmuch-draft-" id "*")))
+  (setq buffer-read-only nil)
+  (erase-buffer)
+  (let ((coding-system-for-read 'no-conversion))
+   (call-process notmuch-command nil t nil "show" "--format=raw" id))
+  (mime-to-mml)
+  (goto-char (point-min))
+  (when (re-search-forward "^$" nil t)
+   (replace-match mail-header-separator t t))
+  ;; Remove the Date and Message-ID headers (unless the user has
+  ;; explicitly customized emacs to tell us not to) as they will
+  ;; be replaced when the message is sent.
+  (save-restriction
+   (message-narrow-to-headers)
+   (when (member 'Message-ID message-deletable-headers)
+ (message-remove-header "Message-ID"))
+   (when (member 'Date message-deletable-headers)
+ (message-remove-header "Date"))
+   ;; The X-Notmuch-Emacs-Draft header is a more reliable
+   ;; indication of whether the message really is a draft.
+   (setq draft (> (message-remove-header "X-Notmuch-Emacs-Draft") 0)))
+  ;; If the message is not a draft we should not unquote any mml.
+  (when draft
+   (notmuch-draft-unquote-some-mml))
+  (notmuch-message-mode)
+  (message-goto-body)
+  (set-buffer-modified-p nil)
+  ;; If the resumed message was a draft then set the draft
+  ;; message-id so that we can delete the current saved draft if the
+  ;; message is resaved or sent.
+  (setq notmuch-draft-id (when draft id)
+
+
 (add-hook 'message-send-hook 'notmuch-draft--mark-deleted)
 
 
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index fcf7e6e..364004b 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -38,6 +38,7 @@
 (require 'notmuch-mua)
 (require 'notmuch-crypto)
 (require 'notmuch-print)
+(require 'notmuch-draft)
 
 (declare-function notmuch-call-notmuch-process "notmuch" ( args))
 (declare-function notmuch-search-next-thread "notmuch" nil)
@@ -50,6 +51,7 @@
  ( query query-context target buffer-name 
open-target))
 (declare-function notmuch-tree-get-message-properties "notmuch-tree" nil)
 (declare-function notmuch-read-query "notmuch" (prompt))
+(declare-function notmuch-draft-resume "notmuch-draft" (id))
 
 (defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")
   "Headers that should be shown in a message, in this order.
@@ -1445,6 +1447,7 @@ reset based on the original query."
 (define-key map "|" 

[PATCH v7 0/4] emacs postpone/resume patches

2016-11-13 Thread Mark Walters
The previous version of this series is at
id:1479036106-32453-1-git-send-email-markwalters1...@gmail.com

The only change is for the error handling for resume. In show mode is
is actually simpler than before -- notmuch-show-get-message-id will
always return an id, so we don't need to check for non-nil
there. Indeed, if this were not the case then the tag commands would
all need to check too.

However, in tree-mode the corresponding command can fail if point is
after the end of the last message. Thus there we do check for non-nil
(as do the tagging commands).

The diff from v6 is below.

Best wishes

Mark




David Bremner (2):
  emacs: check drafts for encryption tags before saving
  emacs: resume messages

Mark Walters (2):
  emacs: tree: remove binding for pressing button in message pane
  emacs: postpone a message

 emacs/Makefile.local |   3 +-
 emacs/notmuch-draft.el   | 268 +++
 emacs/notmuch-mua.el |   4 +
 emacs/notmuch-show.el|   8 ++
 emacs/notmuch-tree.el|  11 +-
 test/T630-emacs-draft.sh |  70 +
 6 files changed, 362 insertions(+), 2 deletions(-)
 create mode 100644 emacs/notmuch-draft.el
 create mode 100755 test/T630-emacs-draft.sh

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 79e4435..364004b 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1988,9 +1988,7 @@ to show, nil otherwise."
 (defun notmuch-show-resume-message ()
   "Resume EDITING the current draft message."
   (interactive)
-  (let ((id (notmuch-show-get-message-id)))
-(when id
-  (notmuch-draft-resume id
+  (notmuch-draft-resume (notmuch-show-get-message-id)))
 
 (put 'notmuch-show-pipe-message 'notmuch-doc
  "Pipe the contents of the current message to a command.")
diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 4abcf60..7bebdba 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -273,7 +273,6 @@ FUNC."
 (define-key map "r" (notmuch-tree-close-message-pane-and 
#'notmuch-show-reply-sender))
 (define-key map "R" (notmuch-tree-close-message-pane-and 
#'notmuch-show-reply))
 (define-key map "V" (notmuch-tree-close-message-pane-and 
#'notmuch-show-view-raw-message))
-(define-key map "e" (notmuch-tree-close-message-pane-and 
#'notmuch-show-resume-message))
 
 ;; The main tree view bindings
 (define-key map (kbd "RET") 'notmuch-tree-show-message)
@@ -294,6 +293,7 @@ FUNC."
 (define-key map "*" 'notmuch-tree-tag-thread)
 (define-key map " " 'notmuch-tree-scroll-or-next)
 (define-key map (kbd "DEL") 'notmuch-tree-scroll-message-window-back)
+(define-key map "e" 'notmuch-tree-resume-message)
 map))
 (fset 'notmuch-tree-mode-map notmuch-tree-mode-map)
 
@@ -406,6 +406,15 @@ NOT change the database."
(list (notmuch-read-tag-changes (notmuch-tree-get-tags) "Tag message" "-")))
   (notmuch-tree-tag tag-changes))
 
+(defun notmuch-tree-resume-message ()
+  "Resume EDITING the current draft message."
+  (interactive)
+  (notmuch-tree-close-message-window)
+  (let ((id (notmuch-tree-get-message-id)))
+(if id
+   (notmuch-draft-resume id)
+  (message "No message to resume!"
+
 ;; The next two functions close the message window before calling
 ;; notmuch-search or notmuch-tree but they do so after the user has
 ;; entered the query (in case the user was basing the query on


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


[PATCH v7 2/4] emacs: postpone a message

2016-11-13 Thread Mark Walters
This provides initial support for postponing in the emacs frontend;
resuming will follow in a later commit. On saving/postponing it uses
notmuch insert to put the message in the notmuch database

Current bindings are C-x C-s to save a draft, C-c C-p to postpone a
draft (save and exit compose buffer).

Previous drafts get tagged deleted on subsequent saves, or on the
message being sent.

Each draft gets its own message-id, and we use the namespace
draft- for draft message ids (so, at least for most people, drafts
are easily distinguisable).
---
 emacs/Makefile.local |   3 +-
 emacs/notmuch-draft.el   | 167 +++
 emacs/notmuch-mua.el |   4 ++
 test/T630-emacs-draft.sh |  42 
 4 files changed, 215 insertions(+), 1 deletion(-)
 create mode 100644 emacs/notmuch-draft.el
 create mode 100755 test/T630-emacs-draft.sh

diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 2d6aedb..6896ff9 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -20,7 +20,8 @@ emacs_sources := \
$(dir)/notmuch-print.el \
$(dir)/notmuch-version.el \
$(dir)/notmuch-jump.el \
-   $(dir)/notmuch-company.el
+   $(dir)/notmuch-company.el \
+   $(dir)/notmuch-draft.el
 
 $(dir)/notmuch-version.el: $(dir)/Makefile.local version.stamp
 $(dir)/notmuch-version.el: $(srcdir)/$(dir)/notmuch-version.el.tmpl
diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
new file mode 100644
index 000..b8a5e67
--- /dev/null
+++ b/emacs/notmuch-draft.el
@@ -0,0 +1,167 @@
+;;; notmuch-draft.el --- functions for postponing and editing drafts
+;;
+;; Copyright © Mark Walters
+;; Copyright © David Bremner
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;; Authors: Mark Walters <markwalters1...@gmail.com>
+;; David Bremner <da...@tethera.net>
+
+;;; Code:
+
+(require 'notmuch-maildir-fcc)
+(require 'notmuch-tag)
+
+(declare-function notmuch-show-get-message-id "notmuch-show" ( bare))
+
+(defgroup notmuch-draft nil
+  "Saving and editing drafts in Notmuch."
+  :group 'notmuch)
+
+(defcustom notmuch-draft-tags '("+draft")
+  "List of tags changes to apply to a draft message when it is saved in the 
database.
+
+Tags starting with \"+\" (or not starting with either \"+\" or
+\"-\") in the list will be added, and tags starting with \"-\"
+will be removed from the message being stored.
+
+For example, if you wanted to give the message a \"draft\" tag
+but not the (normally added by default) \"inbox\" tag, you would
+set:
+(\"+draft\" \"-inbox\")"
+  :type '(repeat string)
+  :group 'notmuch-draft)
+
+(defcustom notmuch-draft-folder "drafts"
+  "Folder to save draft messages in.
+
+This should be specified relative to the root of the notmuch
+database. It will be created if necessary."
+  :type 'string
+  :group 'notmuch-draft)
+
+(defcustom notmuch-draft-quoted-tags '()
+  "Mml tags to quote.
+
+This should be a list of mml tags to quote before saving. You do
+not need to include \"secure\" as that is handled separately.
+
+If you include \"part\" then attachments will not be saved with
+the draft -- if not then they will be saved with the draft. The
+former means the attachments may not still exist when you resume
+the message, the latter means that the attachments as they were
+when you postponed will be sent with the resumed message.
+
+Note you may get strange results if you change this between
+postponing and resuming a message."
+  :type '(repeat string)
+  :group 'notmuch-send)
+
+(defvar notmuch-draft-id nil
+  "Message-id of the most recent saved draft of this message")
+(make-variable-buffer-local 'notmuch-draft-id)
+
+(defun notmuch-draft--mark-deleted ()
+  "Tag the last saved draft deleted.
+
+Used when a new version is saved, or the message is sent."
+  (when notmuch-draft-id
+(notmuch-tag notmuch-draft-id '("+deleted"
+
+(defun notmuch-draft-quote-some-mml ()
+  "Quote the mml tags in `notmuch-draft-quoted-tags`."
+  (save-excursion
+;; First we deal with any secure tag separately.
+(message-goto-body)
+(when (looking-at "<#secure

[PATCH v7 1/4] emacs: tree: remove binding for pressing button in message pane

2016-11-13 Thread Mark Walters
We want to use "e" for editting postponed messages in show, and in
tree view, so remove the binding for the function which does

 (In message pane) Activate BUTTON or button at point
---
 emacs/notmuch-tree.el | 1 -
 1 file changed, 1 deletion(-)

diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 62064ce..8398eb1 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -266,7 +266,6 @@ FUNC."
 (define-key map (kbd "M-TAB") (notmuch-tree-to-message-pane 
#'notmuch-show-previous-button))
 (define-key map (kbd "")  (notmuch-tree-to-message-pane 
#'notmuch-show-previous-button))
 (define-key map (kbd "TAB") (notmuch-tree-to-message-pane 
#'notmuch-show-next-button))
-(define-key map "e" (notmuch-tree-to-message-pane 
#'notmuch-tree-button-activate))
 (define-key map "$" (notmuch-tree-to-message-pane 
#'notmuch-show-toggle-process-crypto))
 
 ;; bindings from show (or elsewhere) but we close the message pane first.
-- 
2.1.4

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


[PATCH v6 4/4] emacs: resume messages

2016-11-13 Thread Mark Walters
From: David Bremner 

Provide functionality to resume editing a message previously saved with
notmuch-draft-save, including decoding the X-Notmuch-Emacs-Secure
header.

Resume gets the raw file from notmuch and using the emacs function
mime-to-mml reconstructs the message (including attachments).

'e' is bound to resume a draft from show or tree mode.
---
 emacs/notmuch-draft.el   | 62 
 emacs/notmuch-show.el| 10 
 emacs/notmuch-tree.el|  1 +
 test/T630-emacs-draft.sh | 15 
 4 files changed, 88 insertions(+)

diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
index 1fb049a..496e11f 100644
--- a/emacs/notmuch-draft.el
+++ b/emacs/notmuch-draft.el
@@ -25,6 +25,7 @@
 
 (require 'notmuch-maildir-fcc)
 (require 'notmuch-tag)
+(require 'notmuch-mua)
 
 (declare-function notmuch-show-get-message-id "notmuch-show" ( bare))
 
@@ -118,6 +119,27 @@ Used when a new version is saved, or the message is sent."
  (goto-char (+ (match-beginning 0) 2))
  (insert "!"))
 
+(defun notmuch-draft-unquote-some-mml ()
+  "Unquote the mml tags in `notmuch-draft-quoted-tags`."
+  (save-excursion
+(when notmuch-draft-quoted-tags
+  (let ((re (concat "<#!+/?\\("
+   (mapconcat 'regexp-quote notmuch-draft-quoted-tags 
"\\|")
+   "\\)")))
+   (message-goto-body)
+   (while (re-search-forward re nil t)
+ ;; Remove one ! from after the #.
+ (goto-char (+ (match-beginning 0) 2))
+ (delete-char 1
+(let (secure-tag)
+  (save-restriction
+   (message-narrow-to-headers)
+   (setq secure-tag (message-fetch-field "X-Notmuch-Emacs-Secure" 't))
+   (message-remove-header "X-Notmuch-Emacs-Secure"))
+  (message-goto-body)
+  (when secure-tag
+   (insert secure-tag "\n")
+
 (defun notmuch-draft--has-encryption-tag ()
   "Returns t if there is an mml secure tag."
   (save-excursion
@@ -198,6 +220,46 @@ applied to newly inserted messages)."
   (notmuch-draft-save)
   (kill-buffer))
 
+(defun notmuch-draft-resume (id)
+  "Resume editing of message with id ID."
+  (let* ((tags (process-lines notmuch-command "search" "--output=tags"
+ "--exclude=false" id))
+(draft (equal tags (notmuch-update-tags tags notmuch-draft-tags
+(when (or draft
+ (yes-or-no-p "Message does not appear to be a draft: really 
resume? "))
+  (switch-to-buffer (get-buffer-create (concat "*notmuch-draft-" id "*")))
+  (setq buffer-read-only nil)
+  (erase-buffer)
+  (let ((coding-system-for-read 'no-conversion))
+   (call-process notmuch-command nil t nil "show" "--format=raw" id))
+  (mime-to-mml)
+  (goto-char (point-min))
+  (when (re-search-forward "^$" nil t)
+   (replace-match mail-header-separator t t))
+  ;; Remove the Date and Message-ID headers (unless the user has
+  ;; explicitly customized emacs to tell us not to) as they will
+  ;; be replaced when the message is sent.
+  (save-restriction
+   (message-narrow-to-headers)
+   (when (member 'Message-ID message-deletable-headers)
+ (message-remove-header "Message-ID"))
+   (when (member 'Date message-deletable-headers)
+ (message-remove-header "Date"))
+   ;; The X-Notmuch-Emacs-Draft header is a more reliable
+   ;; indication of whether the message really is a draft.
+   (setq draft (> (message-remove-header "X-Notmuch-Emacs-Draft") 0)))
+  ;; If the message is not a draft we should not unquote any mml.
+  (when draft
+   (notmuch-draft-unquote-some-mml))
+  (notmuch-message-mode)
+  (message-goto-body)
+  (set-buffer-modified-p nil)
+  ;; If the resumed message was a draft then set the draft
+  ;; message-id so that we can delete the current saved draft if the
+  ;; message is resaved or sent.
+  (setq notmuch-draft-id (when draft id)
+
+
 (add-hook 'message-send-hook 'notmuch-draft--mark-deleted)
 
 
diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index fcf7e6e..79e4435 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -38,6 +38,7 @@
 (require 'notmuch-mua)
 (require 'notmuch-crypto)
 (require 'notmuch-print)
+(require 'notmuch-draft)
 
 (declare-function notmuch-call-notmuch-process "notmuch" ( args))
 (declare-function notmuch-search-next-thread "notmuch" nil)
@@ -50,6 +51,7 @@
  ( query query-context target buffer-name 
open-target))
 (declare-function notmuch-tree-get-message-properties "notmuch-tree" nil)
 (declare-function notmuch-read-query "notmuch" (prompt))
+(declare-function notmuch-draft-resume "notmuch-draft" (id))
 
 (defcustom notmuch-message-headers '("Subject" "To" "Cc" "Date")
   "Headers that should be shown in a message, in this order.
@@ -1445,6 +1447,7 @@ reset based on the original query."
 (define-key map "|" 

[PATCH v6 3/4] emacs: check drafts for encryption tags before saving

2016-11-13 Thread Mark Walters
From: David Bremner 

In general the user may not want to save plaintext copies of messages
that they are sending encrypted, so give them a chance to abort.
---
 emacs/notmuch-draft.el   | 39 +++
 test/T630-emacs-draft.sh | 13 +
 2 files changed, 52 insertions(+)

diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
index b8a5e67..1fb049a 100644
--- a/emacs/notmuch-draft.el
+++ b/emacs/notmuch-draft.el
@@ -71,6 +71,21 @@ postponing and resuming a message."
   :type '(repeat string)
   :group 'notmuch-send)
 
+(defcustom notmuch-draft-save-plaintext 'ask
+  "Should notmuch save/postpone in plaintext messages that seem
+  like they are intended to be sent encrypted
+(i.e with an mml encryption tag in it)."
+  :type '(radio
+ (const :tag "Never" nil)
+ (const :tag "Ask every time" ask)
+ (const :tag "Always" t))
+  :group 'notmuch-draft
+  :group 'notmuch-crypto)
+
+(defvar notmuch-draft-encryption-tag-regex
+  "<#\\(part encrypt\\|secure.*mode=.*encrypt>\\)"
+  "Regular expression matching mml tags indicating encryption of part or 
message")
+
 (defvar notmuch-draft-id nil
   "Message-id of the most recent saved draft of this message")
 (make-variable-buffer-local 'notmuch-draft-id)
@@ -103,6 +118,28 @@ Used when a new version is saved, or the message is sent."
  (goto-char (+ (match-beginning 0) 2))
  (insert "!"))
 
+(defun notmuch-draft--has-encryption-tag ()
+  "Returns t if there is an mml secure tag."
+  (save-excursion
+(message-goto-body)
+(re-search-forward notmuch-draft-encryption-tag-regex nil 't)))
+
+(defun notmuch-draft--query-encryption ()
+  "Checks if we should save a message that should be encrypted.
+
+`notmuch-draft-save-plaintext' controls the behaviour."
+  (case notmuch-draft-save-plaintext
+   ((ask)
+(notmuch-draft--query-encryption)
+(unless (yes-or-no-p "(Customize `notmuch-draft-save-plaintext' to 
avoid this warning)
+This message contains mml tags that suggest it is intended to be encrypted.
+Really save and index an unencrypted copy? ")
+  (error "Save aborted")))
+   ((nil)
+(error "Refusing to save draft with encryption tags (see 
`notmuch-draft-save-plaintext')"))
+   ((t)
+(ignore
+
 (defun notmuch-draft--make-message-id ()
   ;; message-make-message-id gives the id inside a "<" ">" pair,
   ;; but notmuch doesn't want that form, so remove them.
@@ -115,6 +152,8 @@ This saves the current message in the database with tags
 `notmuch-draft-tags` (in addition to any default tags
 applied to newly inserted messages)."
   (interactive)
+  (when (notmuch-draft--has-encryption-tag)
+(notmuch-draft--query-encryption))
   (let ((id (notmuch-draft--make-message-id)))
 (with-temporary-notmuch-message-buffer
  ;; We insert a Date header and a Message-ID header, the former
diff --git a/test/T630-emacs-draft.sh b/test/T630-emacs-draft.sh
index e39690c..689ccfb 100755
--- a/test/T630-emacs-draft.sh
+++ b/test/T630-emacs-draft.sh
@@ -39,4 +39,17 @@ header_count=$(notmuch show --format=raw 
subject:draft-test-0003 | grep -c ^X-No
 body_count=$(notmuch notmuch show --format=raw subject:draft-test-0003 | grep 
-c '^\<#secure')
 test_expect_equal "$header_count,$body_count" "1,0"
 
+test_begin_subtest "Refusing to save an encrypted draft"
+test_emacs '(notmuch-mua-mail)
+   (message-goto-subject)
+   (insert "draft-test-0004")
+   (mml-secure-message-sign-encrypt)
+   (let ((notmuch-draft-save-plaintext nil))
+(notmuch-draft-save))
+   (test-output)'
+count1=$(notmuch count tag:draft)
+count2=$(notmuch count subject:draft-test-0004)
+
+test_expect_equal "$count1,$count2" "3,0"
+
 test_done
-- 
2.1.4

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


[PATCH v6 0/4] emacs postpone/resume patches

2016-11-13 Thread Mark Walters
This version 6 of this series. The previous version is at
id:20161107125211.23405-1-da...@tethera.net

This addresses the review comments on the previous version, adds a
couple of "requires" to fix some compile warnings, and1 updates on
function name which was missed previously.

I also rejigged Patch 3 (the secure tag checks). I think I like this
version but i am happy to revert to the previous one if preferred.

The diff from the previous version is below.

Best wishes

Mark

David Bremner (2):
  emacs: check drafts for encryption tags before saving
  emacs: resume messages

Mark Walters (2):
  emacs: tree: remove binding for pressing button in message pane
  emacs: postpone a message

 emacs/Makefile.local |   3 +-
 emacs/notmuch-draft.el   | 268 +++
 emacs/notmuch-mua.el |   4 +
 emacs/notmuch-show.el|  10 ++
 emacs/notmuch-tree.el|   2 +-
 test/T630-emacs-draft.sh |  70 +
 6 files changed, 355 insertions(+), 2 deletions(-)
 create mode 100644 emacs/notmuch-draft.el
 create mode 100755 test/T630-emacs-draft.sh

diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
index 1528d79..496e11f 100644
--- a/emacs/notmuch-draft.el
+++ b/emacs/notmuch-draft.el
@@ -24,6 +24,8 @@
 ;;; Code:
 
 (require 'notmuch-maildir-fcc)
+(require 'notmuch-tag)
+(require 'notmuch-mua)
 
 (declare-function notmuch-show-get-message-id "notmuch-show" ( bare))
 
@@ -109,7 +111,7 @@ Used when a new version is saved, or the message is sent."
 ;; specified tags.
 (when notmuch-draft-quoted-tags
   (let ((re (concat "<#!*/?\\("
-   (mapconcat 'identity notmuch-draft-quoted-tags "\\|")
+   (mapconcat 'regexp-quote notmuch-draft-quoted-tags 
"\\|")
"\\)")))
(message-goto-body)
(while (re-search-forward re nil t)
@@ -122,7 +124,7 @@ Used when a new version is saved, or the message is sent."
   (save-excursion
 (when notmuch-draft-quoted-tags
   (let ((re (concat "<#!+/?\\("
-   (mapconcat 'identity notmuch-draft-quoted-tags "\\|")
+   (mapconcat 'regexp-quote notmuch-draft-quoted-tags 
"\\|")
"\\)")))
(message-goto-body)
(while (re-search-forward re nil t)
@@ -138,21 +140,32 @@ Used when a new version is saved, or the message is sent."
   (when secure-tag
(insert secure-tag "\n")
 
-(defun notmuch-draft--check-encryption-tag ( ask)
-  "Query user if there an mml tag that looks like it might indicate encryption.
-
-Returns t if there is no such tag, or the user confirms they mean
-it."
+(defun notmuch-draft--has-encryption-tag ()
+  "Returns t if there is an mml secure tag."
   (save-excursion
 (message-goto-body)
-  (or
-   ;; We are fine if no relevant tag is found, or
-   (not (re-search-forward notmuch-draft-encryption-tag-regex nil 't))
-   ;; The user confirms they means it.
-   (and ask
-   (yes-or-no-p "(Customize `notmuch-draft-save-plaintext' to avoid 
this warning)
+(re-search-forward notmuch-draft-encryption-tag-regex nil 't)))
+
+(defun notmuch-draft--query-encryption ()
+  "Checks if we should save a message that should be encrypted.
+
+`notmuch-draft-save-plaintext' controls the behaviour."
+  (case notmuch-draft-save-plaintext
+   ((ask)
+(notmuch-draft--query-encryption)
+(unless (yes-or-no-p "(Customize `notmuch-draft-save-plaintext' to 
avoid this warning)
 This message contains mml tags that suggest it is intended to be encrypted.
-Really save and index an unencrypted copy? ")
+Really save and index an unencrypted copy? ")
+  (error "Save aborted")))
+   ((nil)
+(error "Refusing to save draft with encryption tags (see 
`notmuch-draft-save-plaintext')"))
+   ((t)
+(ignore
+
+(defun notmuch-draft--make-message-id ()
+  ;; message-make-message-id gives the id inside a "<" ">" pair,
+  ;; but notmuch doesn't want that form, so remove them.
+  (concat "draft-" (substring (message-make-message-id) 1 -1)))
 
 (defun notmuch-draft-save ()
   "Save the current draft message in the notmuch database.
@@ -161,19 +174,9 @@ This saves the current message in the database with tags
 `notmuch-draft-tags` (in addition to any default tags
 applied to newly inserted messages)."
   (interactive)
-  (case notmuch-draft-save-plaintext
-((ask)
- (unless (notmuch-draft--check-encryption-tag t)
-   (error "Save aborted")))
-((t)
- (ignore))
-((nil)
- (unless (notmuch-draft--check-encryption-tag nil)
-   (error "Refusing to save draft with encryption tags (see 
`notmuch-draft-save-plaintext

[PATCH v6 2/4] emacs: postpone a message

2016-11-13 Thread Mark Walters
This provides initial support for postponing in the emacs frontend;
resuming will follow in a later commit. On saving/postponing it uses
notmuch insert to put the message in the notmuch database

Current bindings are C-x C-s to save a draft, C-c C-p to postpone a
draft (save and exit compose buffer).

Previous drafts get tagged deleted on subsequent saves, or on the
message being sent.

Each draft gets its own message-id, and we use the namespace
draft- for draft message ids (so, at least for most people, drafts
are easily distinguisable).
---
 emacs/Makefile.local |   3 +-
 emacs/notmuch-draft.el   | 167 +++
 emacs/notmuch-mua.el |   4 ++
 test/T630-emacs-draft.sh |  42 
 4 files changed, 215 insertions(+), 1 deletion(-)
 create mode 100644 emacs/notmuch-draft.el
 create mode 100755 test/T630-emacs-draft.sh

diff --git a/emacs/Makefile.local b/emacs/Makefile.local
index 2d6aedb..6896ff9 100644
--- a/emacs/Makefile.local
+++ b/emacs/Makefile.local
@@ -20,7 +20,8 @@ emacs_sources := \
$(dir)/notmuch-print.el \
$(dir)/notmuch-version.el \
$(dir)/notmuch-jump.el \
-   $(dir)/notmuch-company.el
+   $(dir)/notmuch-company.el \
+   $(dir)/notmuch-draft.el
 
 $(dir)/notmuch-version.el: $(dir)/Makefile.local version.stamp
 $(dir)/notmuch-version.el: $(srcdir)/$(dir)/notmuch-version.el.tmpl
diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
new file mode 100644
index 000..b8a5e67
--- /dev/null
+++ b/emacs/notmuch-draft.el
@@ -0,0 +1,167 @@
+;;; notmuch-draft.el --- functions for postponing and editing drafts
+;;
+;; Copyright © Mark Walters
+;; Copyright © David Bremner
+;;
+;; 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 <https://www.gnu.org/licenses/>.
+;;
+;; Authors: Mark Walters <markwalters1...@gmail.com>
+;; David Bremner <da...@tethera.net>
+
+;;; Code:
+
+(require 'notmuch-maildir-fcc)
+(require 'notmuch-tag)
+
+(declare-function notmuch-show-get-message-id "notmuch-show" ( bare))
+
+(defgroup notmuch-draft nil
+  "Saving and editing drafts in Notmuch."
+  :group 'notmuch)
+
+(defcustom notmuch-draft-tags '("+draft")
+  "List of tags changes to apply to a draft message when it is saved in the 
database.
+
+Tags starting with \"+\" (or not starting with either \"+\" or
+\"-\") in the list will be added, and tags starting with \"-\"
+will be removed from the message being stored.
+
+For example, if you wanted to give the message a \"draft\" tag
+but not the (normally added by default) \"inbox\" tag, you would
+set:
+(\"+draft\" \"-inbox\")"
+  :type '(repeat string)
+  :group 'notmuch-draft)
+
+(defcustom notmuch-draft-folder "drafts"
+  "Folder to save draft messages in.
+
+This should be specified relative to the root of the notmuch
+database. It will be created if necessary."
+  :type 'string
+  :group 'notmuch-draft)
+
+(defcustom notmuch-draft-quoted-tags '()
+  "Mml tags to quote.
+
+This should be a list of mml tags to quote before saving. You do
+not need to include \"secure\" as that is handled separately.
+
+If you include \"part\" then attachments will not be saved with
+the draft -- if not then they will be saved with the draft. The
+former means the attachments may not still exist when you resume
+the message, the latter means that the attachments as they were
+when you postponed will be sent with the resumed message.
+
+Note you may get strange results if you change this between
+postponing and resuming a message."
+  :type '(repeat string)
+  :group 'notmuch-send)
+
+(defvar notmuch-draft-id nil
+  "Message-id of the most recent saved draft of this message")
+(make-variable-buffer-local 'notmuch-draft-id)
+
+(defun notmuch-draft--mark-deleted ()
+  "Tag the last saved draft deleted.
+
+Used when a new version is saved, or the message is sent."
+  (when notmuch-draft-id
+(notmuch-tag notmuch-draft-id '("+deleted"
+
+(defun notmuch-draft-quote-some-mml ()
+  "Quote the mml tags in `notmuch-draft-quoted-tags`."
+  (save-excursion
+;; First we deal with any secure tag separately.
+(message-goto-body)
+(when (looking-at "<#secure

[PATCH v6 1/4] emacs: tree: remove binding for pressing button in message pane

2016-11-13 Thread Mark Walters
We want to use "e" for editting postponed messages in show, and in
tree view, so remove the binding for the function which does

 (In message pane) Activate BUTTON or button at point
---
 emacs/notmuch-tree.el | 1 -
 1 file changed, 1 deletion(-)

diff --git a/emacs/notmuch-tree.el b/emacs/notmuch-tree.el
index 62064ce..8398eb1 100644
--- a/emacs/notmuch-tree.el
+++ b/emacs/notmuch-tree.el
@@ -266,7 +266,6 @@ FUNC."
 (define-key map (kbd "M-TAB") (notmuch-tree-to-message-pane 
#'notmuch-show-previous-button))
 (define-key map (kbd "")  (notmuch-tree-to-message-pane 
#'notmuch-show-previous-button))
 (define-key map (kbd "TAB") (notmuch-tree-to-message-pane 
#'notmuch-show-next-button))
-(define-key map "e" (notmuch-tree-to-message-pane 
#'notmuch-tree-button-activate))
 (define-key map "$" (notmuch-tree-to-message-pane 
#'notmuch-show-toggle-process-crypto))
 
 ;; bindings from show (or elsewhere) but we close the message pane first.
-- 
2.1.4

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


Re: [Patch v5 4/4] emacs: resume messages

2016-11-13 Thread Mark Walters
On Sat, 12 Nov 2016, David Bremner  wrote:
> David Bremner  writes:
>
>> Provide functionality to resume editing a mesage previously saved with
>> notmuch-draft-save, including decoding the X-Notmuch-Emacs-Secure
>> header.
>
> s/mesage/message/
>
>> +(defun notmuch-draft-unquote-some-mml ()
>> +  "Unquote the mml tags in `notmuch-draft-quoted-tags`."
>> +  (save-excursion
>> +(when notmuch-draft-quoted-tags
>> +  (let ((re (concat "<#!+/?\\("
>> +(mapconcat 'identity notmuch-draft-quoted-tags "\\|")
>> +
> Same issue here with regex quoting, I think.

Yes I will change this.

>> +(let (secure-tag)
>> +  (save-restriction
>> +(message-narrow-to-headers)
>> +(setq secure-tag (message-fetch-field "X-Notmuch-Emacs-Secure" 't))
>> +(message-remove-header "X-Notmuch-Emacs-Secure"))
>> +  (message-goto-body)
>> +  (when secure-tag
>> +(insert secure-tag "\n")
>
> Can the setq inside the let be replaced with
>
> (let ((secure-tag (message-fetch-field "X-Notmuch-Emacs-Secure" 't)))
>  ...
>
> Perhaps by pushing the let inside the save-restriction?

We need to insert the secure-tag in the body, so outside of the
save-restriction. However, message-fetch-field requires the message to
be narrowed to the headers. So I don't see an easy way to avoid the setq.

>
>>  (require 'notmuch-mua)
>>  (require 'notmuch-crypto)
>>  (require 'notmuch-print)
>> +(require 'notmuch-draft)
>
> This line I added.
>
>> +(defun notmuch-show-resume-message ()
>> +  "Resume EDITING the current draft message."
>> +  (interactive)
>> +  (let ((id (notmuch-show-get-message-id)))
>> +(when id
>> +  (notmuch-draft-resume id

Do you mean if we are not on a message? I think this may not be needed:
I think all I intended to check was that we are on a message, but that
seems to always be true in the show buffer (unlike threads in the search
buffer).

Best wishes

Mark


>
> The error handling is not very clear to me
> here. notmuch-show-get-message-id is not documented to return nil on
> error. Should some docstring be changed here?
>
>> +<#secure method=pgpmime mode=sign>
>> +EOF
>> +test_expect_equal_file EXPECTED OUTPUT.clean
>>  test_done
>
> The quoting of the secure tag here is not present in the original test,
> but sure confused me for a few minutes.
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> https://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [Patch v5 2/4] emacs: postpone a message

2016-11-13 Thread Mark Walters
On Sat, 12 Nov 2016, David Bremner <da...@tethera.net> wrote:
> David Bremner <da...@tethera.net> writes:
>
>> From: Mark Walters <markwalters1...@gmail.com>
>
> This really Mark's work, that I have split out into a separate file.
>
>> +(defcustom notmuch-draft-tags '("+draft")
>> +  "List of tags changes to apply to a draft message when it is saved in the 
>> database.
>
> Here and a few other places the documentation uses "the database" to
> mean the directory hierachy containing mail messages + the xapian
> database.  At some point I would like to be able to distinguish between
> the database and the maildir root (which doesn't need to be maildirs)
> when talking about configuration. I don't really know better terminology
> here, but I thought I would mention it in case someone else is inspired.

I think we could use "mailstore" for the maildir root, "database" makes
sense for the xapian database. However, I don't have a good term for the
combined whole -- so I am  not sure what would make sense in this
particular case.

>
>> +(defun notmuch-draft--mark-deleted ()
>
> This -- naming convention is my contribution. Perhaps eventually we
> could mark all private functions not intended to be called by users this
> way. Since it is essentially cosmetic, I didn't want to do that
> now. Indeed, one could quibble about the correctness of calling a
> function private and then putting it in a public hook.

I like it, and I agree. I do intend to remove it from the public hook
later (see below).

>> +(defun notmuch-draft-quote-some-mml ()
>> +  "Quote the mml tags in `notmuch-draft-quoted-tags`."
>> +  (save-excursion
>> +;; First we deal with any secure tag separately.
>> +(message-goto-body)
>> +(when (looking-at "<#secure[^\n]*>\n")
>> +  (let ((secure-tag (match-string 0)))
>> +(delete-region (match-beginning 0) (match-end 0))
>> +(message-add-header (concat "X-Notmuch-Emacs-Secure: " secure-tag
>> +;; This is copied from mml-quote-region but only quotes the
>> +;; specified tags.
>> +(when notmuch-draft-quoted-tags
>> +  (let ((re (concat "<#!*/?\\("
>> +(mapconcat 'identity notmuch-draft-quoted-tags "\\|")
>> +"\\)")))
> One "hidden feature" is that regex characters in the quoted tags will be
> interpreted. Possibly calling regexp-quote instead of identity would be
> extra cautious here?

Good catch: I have made it regexp-quote as you suggest.

>> +(defun notmuch-draft-save ()
>> +  "Save the current draft message in the notmuch database.
>> +
>> +This saves the current message in the database with tags
>> +`notmuch-draft-tags` (in addition to any default tags
>> +applied to newly inserted messages)."
>> +  (interactive)
>> +  (let (;; We need the message id as we need it for tagging. Note
>> +;; message-make-message-id gives the id inside a "<" ">" pair,
>> +;; but notmuch doesn't want that form, so remove them.
>> +(id (concat "draft-" (substring (message-make-message-id) 1
>> -1
>
> what do you think of isolating this code and commentary in a private
> function?

I have done this.

>> + (if (member 'Message-ID message-deletable-headers)
>> + (progn
>> +   (message-remove-header "Message-ID")
>> +   (message-add-header (concat "Message-ID: <" id ">")))
>> +   (message "You have customized emacs so Message-ID is not a deletable 
>> header, so not changing it")
>> +   (setq id nil))
>
> I'm not sure if it's just me, but I find the (if (progn ...)
> else-clauses) a bit off-putting. An alternative would be to use cond
>  
> (cond
>  ((member 'Message-ID message-deletable-headers)
>   (message-remove-header "Message-id")
>   (message-add-header (concat "Message-ID: <" id ">")))
>  (t
>   (message "You have customized emacs so Message-ID is not a deletable 
> header, so not changing it")
>   (setq id nil)))

I am happy either way, so I have made the change

>> +(add-hook 'message-send-hook 'notmuch-draft--mark-deleted)
>
> Can we avoid this by adding some code notmuch-mua-send-common?

Yes. We should do the same for notmuch-message-mark-replied. However
getting it right looks slightly non-trivial. In particular, the user can
abort sending for various reasons (eg charset things, or they have
message-confirm-send set) and we should not do the marking if they do
a

Re: [PATCH] emacs: mua: add a pre-send-check-hook

2016-11-12 Thread Mark Walters

> For consistency with Emacs' own elisp, perhaps rename
> notmuch-mua-pre-send-check-hooks to
> notmuch-mua-pre-send-check-functions?

Hi

Yes you are correct.  (Annoyingly I had thought about this and thought
it was OK since I didn't need to pass an argument. I had missed the
return value case).

Best wishes

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


Re: [PATCH v4] emacs: add notmuch-address-post-completion-hook

2016-11-12 Thread Mark Walters
On Sat, 12 Nov 2016, David Bremner  wrote:
> Tomi Ollila  writes:
>
>> Like someone (whose message I cannot find just now) mentioned in another
>> thread, just now it is right time to mention here too...
>>
>> https://www.gnu.org/software/emacs/manual/html_node/elisp/Hooks.html
>>
>> ... that when hook name ends with `-hook` it is supposed to be "normal hook"
>> -- a function which does not take arguments nor return values.
>>
>> So, I'd like to suggest that this variable is renamed to 
>> notmuch-address-completion-functions
>>
>
> Well, I guess the -functions convention should be followed, but
> notmuch-address-completion-functions seems a bit vague.

Maybe notmuch-address-post-completion-functions ?

Alternatively maybe we can end in -hook-functions to indicate it is a
function which is like a hook?

Best wishes

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


Re: [Patch v5 3/4] emacs: check drafts for encryption tags before saving

2016-11-07 Thread Mark Walters

On Mon, 07 Nov 2016, David Bremner  wrote:
> In general the user may not want to save plaintext copies of messages
> that they are sending encrypted, so give them a chance to abort.
> ---
>  emacs/notmuch-draft.el   | 40 
>  test/T630-emacs-draft.sh | 13 +
>  2 files changed, 53 insertions(+)
>
> diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
> index 11d906b..5a230e8 100644
> --- a/emacs/notmuch-draft.el
> +++ b/emacs/notmuch-draft.el
> @@ -70,6 +70,21 @@ postponing and resuming a message."
>:type '(repeat string)
>:group 'notmuch-send)
>  
> +(defcustom notmuch-draft-save-plaintext 'ask
> +  "Should notmuch save/postpone in plaintext messages that seem
> +  like they are intended to be sent encrypted
> +(i.e with an mml encryption tag in it)."
> +  :type '(radio
> +   (const :tag "Never" nil)
> +   (const :tag "Ask every time" ask)
> +   (const :tag "Always" t))
> +  :group 'notmuch-draft
> +  :group 'notmuch-crypto)
> +
> +(defvar notmuch-draft-encryption-tag-regex
> +  "<#\\(part encrypt\\|secure.*mode=.*encrypt>\\)"
> +  "Regular expression matching mml tags indicating encryption of part or 
> message")
> +
>  (defvar notmuch-draft-id nil
>"Message-id of the most recent saved draft of this message")
>  (make-variable-buffer-local 'notmuch-draft-id)
> @@ -102,6 +117,22 @@ Used when a new version is saved, or the message is 
> sent."
> (goto-char (+ (match-beginning 0) 2))
> (insert "!"))
>  
> +(defun notmuch-draft--check-encryption-tag ( ask)
> +  "Query user if there an mml tag that looks like it might indicate 
> encryption.
> +
> +Returns t if there is no such tag, or the user confirms they mean
> +it."
> +  (save-excursion
> +(message-goto-body)
> +  (or
> +   ;; We are fine if no relevant tag is found, or
> +   (not (re-search-forward notmuch-draft-encryption-tag-regex nil 't))
> +   ;; The user confirms they means it.
> +   (and ask
> + (yes-or-no-p "(Customize `notmuch-draft-save-plaintext' to avoid 
> this warning)
> +This message contains mml tags that suggest it is intended to be encrypted.
> +Really save and index an unencrypted copy? ")
> +
>  (defun notmuch-draft-save ()
>"Save the current draft message in the notmuch database.
>  
> @@ -109,6 +140,15 @@ This saves the current message in the database with tags
>  `notmuch-draft-tags` (in addition to any default tags
>  applied to newly inserted messages)."
>(interactive)
> +  (case notmuch-draft-save-plaintext
> +((ask)
> + (unless (notmuch-draft--check-encryption-tag t)
> +   (error "Save aborted")))
> +((t)
> + (ignore))
> +((nil)
> + (unless (notmuch-draft--check-encryption-tag nil)
> +   (error "Refusing to save draft with encryption tags (see 
> `notmuch-draft-save-plaintext')"

What would you think of rejigging the logic here? I would prefer that
the first check was "is there an encryption tag" and then if there is
such a tag decide what to do. The reason I prefer that is that it makes
the common case clear.

I realise there are downsides too -- eg in your code you don't even
check for secure tags if they are going to  be ignored anyway.

If you prefer your way then lets leave it as is.

Best wishes

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


Re: [Patch v3 2/2] emacs: postpone/resume support

2016-11-06 Thread Mark Walters

> +(defun notmuch-draft--check-encryption-tag ()
> +  "Query user if there an mml tag that looks like it might indicate 
> encryption.
> +
> +Returns t if there is no such tag, or the user confirms they mean
> +it."
> +  (save-excursion
> +(message-goto-body)
> +  (or
> +   ;; We are fine if no relevant tag is found, or
> +   (not (re-search-forward notmuch-draft-encryption-tag-regex nil 't))
> +   ;; The user confirms they means it.
> +   (yes-or-no-p "(Customize `notmuch-draft-save-plaintext' to avoid this 
> warning)
> +This message contains mml tags that suggest it is intended to be encrypted.
> +Really save and index an unencrypted copy? "
> +
> +(defun notmuch-draft-save ()
> +  "Save the current draft message in the notmuch database.
> +
> +This saves the current message in the database with tags
> +`notmuch-draft-draft-tags` (in addition to any default tags
> +applied to newly inserted messages)."
> +  (interactive)
> +  (case notmuch-draft-save-plaintext
> +((ask)
> + (unless (notmuch-draft--check-encryption-tag)
> +   (error "Save aborted")))
> +((t)
> + (ignore))
> +((nil)
> + (error "Refusing to save draft with encryption tags (see 
> `notmuch-draft-save-plaintext')")))

Hi

Did you mean for the case when notmuch-draft-save-plaintext is nil to
abort in all cases, not just when there is an mml secure tag? (I haven't
tested but it looks like that is what happens above)

Best wishes

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


Re: [Patch v3 2/2] emacs: postpone/resume support

2016-11-06 Thread Mark Walters

On Sun, 06 Nov 2016, David Bremner <da...@tethera.net> wrote:
> From: Mark Walters <markwalters1...@gmail.com>
>
> This provides preliminary support for postponing and resuming in the
> emacs frontend. On postponing it uses notmuch insert to put the
> message in the notmuch database; resume gets the raw file from notmuch
> and using the emacs function mime-to-mml reconstructs the message
> (including attachments).
>
> Current bindings are C-x C-s to save a draft, C-c C-p to postpone a
> draft (save and exit compose buffer), and e to resume a draft from
> show or tree mode.
>
> Previous drafts get tagged deleted on subsequent saves, or on the
> message being sent.
>
> Each draft gets its own message-id, and we use the namespace
> draft- for draft message ids (so, at least for most people, drafts
> are easily distinguisable).

Hi

Many thanks for doing this; I definitely like the move to a
notmuch-draft file. I haven't checked it completely yet, or tested it,
but I think the move itself looks fine except for two documentation bits
which aren't quite right -- see below.

Best wishes

Mark



> ---
>  emacs/notmuch-draft.el | 261 
> +
>  emacs/notmuch-mua.el   |   4 +
>  emacs/notmuch-show.el  |  10 ++
>  emacs/notmuch-tree.el  |   1 +
>  4 files changed, 276 insertions(+)
>  create mode 100644 emacs/notmuch-draft.el
>
> diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
> new file mode 100644
> index 000..806c1a7
> --- /dev/null
> +++ b/emacs/notmuch-draft.el
> @@ -0,0 +1,261 @@
> +;;; notmuch-draft.el --- functions for postponing and editing drafts
> +;;
> +;; Copyright © Mark Walters
> +;; Copyright © David Bremner
> +;;
> +;; 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 <https://www.gnu.org/licenses/>.
> +;;
> +;; Authors: Mark Walters <markwalters1...@gmail.com>
> +;;   David Bremner <da...@tethera.net>
> +
> +;;; Code:
> +
> +(require 'notmuch-maildir-fcc)
> +
> +(declare-function notmuch-show-get-message-id "notmuch-show" ( 
> bare))
> +
> +(defgroup notmuch-draft nil
> +  "Saving and editing drafts in Notmuch."
> +  :group 'notmuch)
> +
> +(defcustom notmuch-draft-tags '("+draft")
> +  "List of tags changes to apply to a draft message when it is saved in the 
> database.
> +
> +Tags starting with \"+\" (or not starting with either \"+\" or
> +\"-\") in the list will be added, and tags starting with \"-\"
> +will be removed from the message being stored.
> +
> +For example, if you wanted to give the message a \"draft\" tag
> +but not the (normally added by default) \"inbox\" tag, you would
> +set:
> +(\"+draft\" \"-inbox\")"
> +  :type '(repeat string)
> +  :group 'notmuch-draft)
> +
> +(defcustom notmuch-draft-folder "drafts"
> +  "Folder to save draft messages in.
> +
> +This should be specified relative to the root of the notmuch
> +database. It will be created if necessary."
> +  :type 'string
> +  :group 'notmuch-draft)
> +
> +(defcustom notmuch-draft-quoted-tags '()
> +  "Mml tags to quote.
> +
> +This should be a list of mml tags to quote before saving. You do
> +not need to include \"secure\" as that is handled separately.
> +
> +If you include \"part\" then attachments will not be saved with
> +the draft -- if not then they will be saved with the draft. The
> +former means the attachments may not still exist when you resume
> +the message, the latter means that the attachments as they were
> +when you postponed will be sent with the resumed message.
> +
> +Note you may get strange results if you change this between
> +postponing and resuming a message."
> +  :type '(repeat string)
> +  :group 'notmuch-send)
> +
> +(defcustom notmuch-draft-save-plaintext 'ask
> +  "Should notmuch save/postpone in plaintext messages that seem
> +  like they are intended to be sent encrypted
&

Re: [PATCH] emacs: add check for encryption before saving.

2016-11-05 Thread Mark Walters
On Sat, 05 Nov 2016, David Bremner <da...@tethera.net> wrote:
> Mark Walters <markwalters1...@gmail.com> writes:
>
>>
>> I think this is an excellent thing to add. I agree that false positives
>> aren't much of a worry. If someone bumps into them a lot then they can
>> complain or come up with a better regex.
>>
>
> Should the regex also be a defcustom?

I think not a defcustom, but perhaps a defvar (the difference being that
defvar's are hidden from most users -- anyone who can write a better
regex can use setq in their init file). I think even if we don't expect
users to change it making it a defvar is quite clean so that might be
best.

Best wishes

Mark





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


Re: [PATCH] emacs: add check for encryption before saving.

2016-11-05 Thread Mark Walters

On Sat, 05 Nov 2016, David Bremner  wrote:
> This is intended to decrease the chance of people ending up with a bunch
> of plaintext drafts of encrypted messages without knowing it.
>
> The check is intentionally overcautious; I think the false positive of
> misplaced #secure tag is probably OK here.
> ---
>
> This is somewhat RFC. The regex needs to be double checked, and the
> variable name is not ideal. However it does solve reduce a worry I
> have about this code saving drafts of sensitive messages in plaintext
> that are effectively invisible because they are tagged deleted.

Hi

I think this is an excellent thing to add. I agree that false positives
aren't much of a worry. If someone bumps into them a lot then they can
complain or come up with a better regex.

>  emacs/notmuch-message.el | 25 +
>  1 file changed, 25 insertions(+)
>
> diff --git a/emacs/notmuch-message.el b/emacs/notmuch-message.el
> index a503296..a2b079d 100644
> --- a/emacs/notmuch-message.el
> +++ b/emacs/notmuch-message.el
> @@ -80,6 +80,12 @@ postponing and resuming a message."
>:type '(repeat string)
>:group 'notmuch-send)
>  
> +(defcustom notmuch-message-warn-encryption t
> +  "Warn if the user postpones or saves a message with an mml encryption tag 
> in it"
> +  :type 'boolean
> +  :group 'notmuch-send
> +  :group 'notmuch-crypto)

I think it would be good if the variable name contained postpone or save
in it as it is not part of the normal send message route. Perhaps
notmuch-message-warn-unencrypted-save ? (not perfect I know)

Maybe change the docstring to something like "Warn if the user postpones
or saves a message that would be encrypted if sent (i.e., has an mml
encryption tag)."

> +(defun notmuch-message-check-encryption ()
> +  "Query user if there an mml tag that looks like it might indicate 
> encryption.

Maybe a name like notmuch-message-check-has-encrypt-tag (or omit "check")?

But this is probably excessive bikeshedding on my part. In any case the
only one I care about above is the name of the defcustom variable

(and there is one trivial typo below)

Best wishes

Mark

> +Returns t if there is no such tag, or the user confirms they mean
> +it."
> +  (save-excursion
> +(message-goto-body)
> +  (or
> +   ;; We fine if there is no secure tag, and no #part encryption
 ^^^
 are
  

> +   (not (re-search-forward "<#\\(part 
> encrypt\\|secure.*mode=.*encrypt>\\)" nil 't))
> +   ;; The user confirms they means it.
> +   (yes-or-no-p "\
> +This message contains mml tags that suggest it is intended to be encrypted.
> +Really save and index an unencrypted copy?
> +(Customize `notmuch-message-warn-encrypted' to avoid this warning)"
> +
>  (defun notmuch-message-save-draft ()
>"Save the current draft message in the notmuch database.
>  
> @@ -147,6 +169,9 @@ This saves the current message in the database with tags
>  `notmuch-message-draft-tags` (in addition to any default tags
>  applied to newly inserted messages)."
>(interactive)
> +  (when (and notmuch-message-warn-encryption
> +  (not (notmuch-message-check-encryption))
> +  (error "Save aborted")))
>(let (;; We need the message id as we need it for tagging. Note
>   ;; message-make-message-id gives the id inside a "<" ">" pair,
>   ;; but notmuch doesn't want that form, so remove them.
> -- 
> 2.10.1
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] emacs: mua: add a pre-send-check-hook

2016-11-04 Thread Mark Walters
This add a pre-send hook for any checks the user wants to run before
sending the message. If any function in the hook returns nil then the
send will abort.

One use would be to check that the from address is appropriate for the
recipients (i.e., test From: based on To: and Cc:), but many other
uses are possible: checking spelling, checking that the message is set
to be encrypted etc.
---

bremner and I were discussing the address-completion-hook on irc, and
before he implemented that I suggested an alternative of adding a
pre-send-check-hook. The idea is that functions in this hook can force
abort sending (or at least get confirmation from the user) based on
the message.

For example I would be quite likely to use something like the
following in the hook.

(lambda ()
  (save-excursion
(save-restriction
  (let ((to (message-fetch-field "To"))
(from (message-fetch-field "From"))
(case-fold-search t))
(or (not (string-match "work-domain-address" to))
(string= from "my-work-address")
(yes-or-no-p "Message to work but not from work address. Really 
send? "))

I think this is reasonably orthogonal to the
notmuch-address-completion-hook. Setting the from address based on the
to addresses makes a lot of sense, but checking on send also does --
if the from is correct then the check is silent, and if the user types
in the To: without using completion then the check will catch it.


Best wishes

Mark


emacs/notmuch-mua.el | 12 +++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index f333655..78130e6 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -36,6 +36,15 @@
 
 ;;
 
+(defcustom notmuch-mua-pre-send-check-hook nil
+  "Hook of checks run before sending messages.
+
+If any of the functions in the hook return nil then the send will
+be aborted."
+  :type 'hook
+  :group 'notmuch-send
+  :group 'notmuch-hooks)
+
 (defcustom notmuch-mua-send-hook '(notmuch-mua-message-send-hook)
   "Hook run before sending messages."
   :type 'hook
@@ -538,7 +547,8 @@ unencrypted.  Really send? "
 
 (defun notmuch-mua-send-common (arg  exit)
   (interactive "P")
-  (when (and (notmuch-mua-check-no-misplaced-secure-tag)
+  (when (and (run-hook-with-args-until-failure 
'notmuch-mua-pre-send-check-hook)
+(notmuch-mua-check-no-misplaced-secure-tag)
 (notmuch-mua-check-secure-tag-has-newline))
 (letf (((symbol-function 'message-do-fcc) 
#'notmuch-maildir-message-do-fcc))
  (if exit
-- 
2.1.4

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


Re: [PATCH v4] emacs: add notmuch-address-post-completion-hook

2016-11-04 Thread Mark Walters

This version looks good to me +1

Best wishes

Mark

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


[PATCH v2 0/2] add postpone support

2016-11-03 Thread Mark Walters
This is version 2 of this set. The previous version is at
id:1473004582-19396-1-git-send-email-markwalters1...@gmail.com

The diff between v1 and v2 is below. The main change is that we store
the secure tag in a temporary header and restore it afterwards. This
avoids a bug in the way emacs deals with secure tags not at the top of
the message. 

Other comments:

I haven't tested this version heavily: I have been running something
similar in my tree but I just don't postpone enough messages to test
it thoroughly.

It unbinds rather than rebinds the press button in message pane option
in tree-view (currently bound to "e"). I have some thoughts on how to
deal better with attachment handling in tree-view but that can follow later.

It uses message-send-hook -- we really shouldn't do that, but as we
already do for tagging replies "replied" it is probably OK to do so
for now. (Fixing this properly is a little tricky -- avoiding the use
of message-send-hook is easy but we currently mark a message replied
even if the user aborts sending the message.)

Best wishes

Mark








Mark Walters (2):
  emacs: tree: move binding for pressing button in message pane to u
  emacs:  postpone/resume support

 emacs/notmuch-message.el | 187 +++
 emacs/notmuch-mua.el |   4 +
 emacs/notmuch-show.el|   9 +++
 emacs/notmuch-tree.el|   2 +-
 4 files changed, 201 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch-message.el b/emacs/notmuch-message.el
index b8d6d07..a503296 100644
--- a/emacs/notmuch-message.el
+++ b/emacs/notmuch-message.el
@@ -63,11 +63,11 @@ database. It will be created if necessary."
   :type 'string
   :group 'notmuch-send)
 
-(defcustom notmuch-message-quoted-tags '("secure")
+(defcustom notmuch-message-quoted-tags '()
   "Mml tags to quote.
 
-This should be a list of mml tags to quote before saving. It is
-recommended that the list includes \"secure\".
+This should be a list of mml tags to quote before saving. You do
+not need to include \"secure\" as that is handled separately.
 
 If you include \"part\" then attachments will not be saved with
 the draft -- if not then they will be saved with the draft. The
@@ -100,10 +100,16 @@ Used when a new version is saved, or the message is sent."
 
 (defun notmuch-message-quote-some-mml ()
   "Quote the mml tags in `notmuch-message-quoted-tags`."
+  (save-excursion
+;; First we deal with any secure tag separately.
+(message-goto-body)
+(when (looking-at "<#secure[^\n]*>\n")
+  (let ((secure-tag (match-string 0)))
+   (delete-region (match-beginning 0) (match-end 0))
+   (message-add-header (concat "X-Notmuch-Emacs-Secure: " secure-tag
 ;; This is copied from mml-quote-region but only quotes the
 ;; specified tags.
 (when notmuch-message-quoted-tags
-(save-excursion
   (let ((re (concat "<#!*/?\\("
(mapconcat 'identity notmuch-message-quoted-tags "\\|")
"\\)")))
@@ -115,8 +121,8 @@ Used when a new version is saved, or the message is sent."
 
 (defun notmuch-message-unquote-some-mml ()
   "Unquote the mml tags in `notmuch-message-quoted-tags`."
-  (when notmuch-message-quoted-tags
   (save-excursion
+(when notmuch-message-quoted-tags
   (let ((re (concat "<#!+/?\\("
(mapconcat 'identity notmuch-message-quoted-tags "\\|")
"\\)")))
@@ -124,7 +130,15 @@ Used when a new version is saved, or the message is sent."
(while (re-search-forward re nil t)
  ;; Remove one ! from after the #.
  (goto-char (+ (match-beginning 0) 2))
- (delete-char 1))
+ (delete-char 1
+(let (secure-tag)
+  (save-restriction
+   (message-narrow-to-headers)
+   (setq secure-tag (message-fetch-field "X-Notmuch-Emacs-Secure" 't))
+   (message-remove-header "X-Notmuch-Emacs-Secure"))
+  (message-goto-body)
+  (when secure-tag
+   (insert secure-tag "\n")
 
 (defun notmuch-message-save-draft ()
   "Save the current draft message in the notmuch database.
@@ -157,6 +171,7 @@ applied to newly inserted messages)."
   (message-remove-header "Date")
   (message-add-header (concat "Date: " (message-make-date
(message "You have customized emacs so Date is not a deletable header, 
so not changing it"))
+ (message-add-header "X-Notmuch-Emacs-Draft: True")
  (notmuch-message-quote-some-mml)
  (notmuch-maildir-setup-message-for-saving)
  (notmuch-maildir-notmuch-insert-current-buffer
@@ -201,10 +216,11 @@ applied to newly inserted messages)."
(when (member 'Message-ID message-deletable-headers)
  

Re: [PATCH v3] emacs: add notmuch-address-post-completion-hook

2016-11-03 Thread Mark Walters

On Thu, 03 Nov 2016, David Bremner  wrote:
> This hook can be used to update the message based on the results of
> address completion. For example using message-templ or gnus-alias to set
> the From address based on the To address just completed.
>
> The post-completion command is added to the notmuch-company backend to
> ensure that the hook is also called company completion is started
> without going through notmuch-address-expand-name. See the docstring of
> `company-backends' for more information.
> ---
>
> Sorry for the false send. My fingers somehow mix up Debian's
> "reportbug" and git-send-email.
>
> Here is a simplified version. As far as I could tell during testing
> with company-mode the hook is only called via the post-completion
> command, and always with a single argument. This might indicate a
> separate bug, since I noticed in one fairly long running emacs session
> (11 days), notmuch-address-history is nil.
>
> I guess the docstring for notmuch-address-completion-hook should have
> a '.' at the end, or probably ' function.'
>
>
>  emacs/notmuch-address.el | 7 +++
>  emacs/notmuch-company.el | 1 +
>  2 files changed, 8 insertions(+)
>
> diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
> index b2e1fba..d1abb21 100644
> --- a/emacs/notmuch-address.el
> +++ b/emacs/notmuch-address.el
> @@ -98,6 +98,12 @@ to know how address selection is made by default."
>:group 'notmuch-send
>:group 'notmuch-external)
>  
> +(defcustom notmuch-address-completion-hook nil
> +  "Functions called after completing address. The completed address is 
> passed as an argument to each"
> +  :type 'hook
> +  :group 'notmuch-address
> +  :group 'notmuch-hooks)
> +
>  (defun notmuch-address-selection-function (prompt collection initial-input)
>"Call (`completing-read'
>PROMPT COLLECTION nil nil INITIAL-INPUT 'notmuch-address-history)"
> @@ -205,6 +211,7 @@ external commands."
>(if chosen
> (progn
>   (push chosen notmuch-address-history)
> + (run-hook-with-args 'notmuch-address-completion-hook chosen)
>   (delete-region beg end)
>   (insert chosen))

Hi

Would it be worth putting the run-hook after the (insert chosen) rather
than before? That would mean that the hook had access to the full new
header. It would also mean that it wouldn't matter if the hook changed
the buffer -- as it is I think the replace might go wrong as we replace
beg to end and those seem to be integer-points not markers

One final query -- this function will be called when completing any of
To: Cc: Bcc: From: and some other less common headers. We could pass an
argument which says which header we are on but that is probably more
complexity than necessary. However, it is probably worth documenting
that it may be called from these headers in the defcustom for the hook.

But otherwise it looks good to me.

Best wishes

Mark



>   (message "No matches.")
> diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
> index 168315f..91c4804 100644
> --- a/emacs/notmuch-company.el
> +++ b/emacs/notmuch-company.el
> @@ -86,6 +86,7 @@
>(match (if (string-match notmuch-company-last-prefix arg)
>(match-end 0)
>  0))
> +  (post-completion (run-hook-with-args 'notmuch-address-completion-hook 
> arg))
>(no-cache t
>  
>  
> -- 
> 2.10.1
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH] emacs: add notmuch-address-post-completion-hook

2016-11-03 Thread Mark Walters

On Thu, 03 Nov 2016, David Bremner  wrote:
> This hook can be used to update the message based on the results of
> address completion. For example I use it to set the From address based
> on the To address just completed.
>
> The post-completion command is added to the notmuch-company backend to
> ensure that the hook is also called company completion is started
> without going through notmuch-address-expand-name. See the docstring of
> `company-backends' for more information.
> ---
>  emacs/notmuch-address.el | 10 ++
>  emacs/notmuch-company.el |  1 +
>  2 files changed, 11 insertions(+)
>
> diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
> index b2e1fba..17960bf 100644
> --- a/emacs/notmuch-address.el
> +++ b/emacs/notmuch-address.el
> @@ -98,6 +98,12 @@ to know how address selection is made by default."
>:group 'notmuch-send
>:group 'notmuch-external)
>  
> +(defcustom notmuch-address-completion-hook nil
> +  "Functions called after completing address. The completed address is 
> passed as an argument to each"

Hi when testing this with company I think the following happens: if you
trigger it manually with tab then I think the hook gets passed a list of
possible addresses, not just one.

> +  :type 'hook
> +  :group 'notmuch-address
> +  :group 'notmuch-hooks)
> +
>  (defun notmuch-address-selection-function (prompt collection initial-input)
>"Call (`completing-read'
>PROMPT COLLECTION nil nil INITIAL-INPUT 'notmuch-address-history)"
> @@ -170,6 +176,10 @@ external commands."
>  (process-lines notmuch-address-command original
>  
>  (defun notmuch-address-expand-name ()
> +  (let ((return-value (notmuch-address-real-expand-name)))
> +(run-hook-with-args 'notmuch-address-completion-hook)))

I think you need to return return-value here? But you also need to
modify notmuch-address-real-expand-name to return chosen. Around line
217 of notmuch-address.el

  (if chosen
  (progn
(push chosen notmuch-address-history)
(delete-region beg end)
(insert chosen))

should become 

  (if chosen
  (progn
(push chosen notmuch-address-history)
(delete-region beg end)
(insert chosen)
;; Return completed address 
chosen)

I guess an alternative would to just run the hook there, and then you
wouldn't need to the notmuch-address-real-expand-name function at
all. (Sorry for misleading you about this on irc yesterday.)


> +
> +(defun notmuch-address-real-expand-name ()
>(cond
> ((and (eq notmuch-address-command 'internal)
>notmuch-address-use-company
> diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
> index 168315f..91c4804 100644
> --- a/emacs/notmuch-company.el
> +++ b/emacs/notmuch-company.el
> @@ -86,6 +86,7 @@
>(match (if (string-match notmuch-company-last-prefix arg)
>(match-end 0)
>  0))
> +  (post-completion (run-hook-with-args 'notmuch-address-completion-hook 
> arg))
>(no-cache t

To fix the list of addresses case you might be able to just put a
(unless (listp arg) or something round the run-hook-with-args

Best wishes

Mark

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


Re: rfc for notmuch remote access script

2016-10-30 Thread Mark Walters
On Sun, 30 Oct 2016, David Bremner  wrote:
> Jani Nikula  writes:
>
>>
>> Personally, I prefer a simple script that assumes a certain type of ssh
>> client configuration. We can typically reference documentation written
>> by others how to do that, and just say "put that stuff under a Host
>> notmuch section in ~/.ssh/config".

Hi

The only possible downside I can see with this is if the address for the
notmuch-server varies. For example my router does NAT the address from
inside and outside my home network is different. I don't know if that is
a common setup, and quite plausibly I could configure things better. I
only mention it as it might be easier to change an environment variable,
than change the .ssh/config file.

Quite plausibly though the simpler common case outweighs that. If we did
want to support my use case above, maybe we could have an environment
variable to say which .ssh/config section to use, which most people
could completely ignore?

> OK, I misunderstood, and thought you wanted to edit the script after
> installation. Hence my question about installing into $HOME.
>
> I'm not using remote access, and I don't really have opinions about the
> best way to do it. I do have 2 concerns about the overall idea
>
> 1. I worry about the maintenance burden of extra code ./configure
> 2. I worry about promoting remote-notmuch for non-experts when the
>situation with gpg seems quite broken, at least for people not
>willing to store private key material on the server.

I wonder if we could do the following --

1) have 2 separate config targets for notmuch-cli and notmuch-emacs so
you can install one without the other.

2) Have things under contrib which config/make can install. Then this
script could go in contrib, which would be a clear signal that it is not
fully supported.

Moreover, point 2 would go very nicely with Jani's other patch
id:1477140605-3011-1-git-send-email-j...@nikula.org for notmuch prefixed
commands. It would mean we could have various notmuch extensions in
contrib and the user could install any they wanted.

Best wishes

Mark

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


[PATCH v2] emacs: add compatability functions for emacs 23

2016-10-29 Thread Mark Walters
Some of the recent changes to the emacs code have used functions
introduced in emacs 24. The functions used are read-char-choice and
setq-local. This changeset adds compatability functions to
notmuch-lib so that it should work on emacs 23.
---

Version 1 of this patch (with some discussion) is at
id:1477191835-17828-1-git-send-email-markwalters1...@gmail.com

The general consensus is that we should not define functions outside
our namespace, even when they are just backports of functions from
later emacs.

rlb on irc gave one additional reason not mentioned earlier in the
thread -- it could be that some other package choses to test for the
setq-local say and perhaps draws incorrect conclusions about the
environment. In particular this would be a case where we were breaking
otherwise working packages.

I think it makes sense to included the whole of read-char-choice, not
some cutdown version, as we may use other functionality from it later
(eg help-forms etc), and it would be confusing if the change only
worked on emacs 24.

Finally, I have two questions

1) please could someone with emacs 23 see if the testsuite passes? My
system with emacs 23 is so outdated the test suite doesn't run (wrong
python versions I think).

2) Is the copyright notice I have included above the two functions
sufficient, and suitably placed?

Best wishes

Mark








 emacs/notmuch-address.el |  4 +--
 emacs/notmuch-company.el |  3 +-
 emacs/notmuch-lib.el | 72 
 emacs/notmuch-maildir-fcc.el |  4 +--
 4 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index b2e1fba..1af3263 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -136,11 +136,11 @@ toggles the setting in this buffer."
   (interactive)
   (if (local-variable-p 'notmuch-address-command)
   (kill-local-variable 'notmuch-address-command)
-(setq-local notmuch-address-command 'internal))
+(notmuch-setq-local notmuch-address-command 'internal))
   (if (boundp 'company-idle-delay)
   (if (local-variable-p 'company-idle-delay)
  (kill-local-variable 'company-idle-delay)
-   (setq-local company-idle-delay nil
+   (notmuch-setq-local company-idle-delay nil
 
 (defun notmuch-address-matching (substring)
   "Returns a list of completion candidates matching SUBSTRING.
diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
index 168315f..5d75c14 100644
--- a/emacs/notmuch-company.el
+++ b/emacs/notmuch-company.el
@@ -28,6 +28,7 @@
 ;;; Code:
 
 (eval-when-compile (require 'cl))
+(require 'notmuch-lib)
 
 (defvar notmuch-company-last-prefix nil)
 (make-variable-buffer-local 'notmuch-company-last-prefix)
@@ -53,7 +54,7 @@
   ;; internal completion) can still be accessed via standard company
   ;; functions, e.g., company-complete.
   (unless (eq notmuch-address-command 'internal)
-(setq-local company-idle-delay nil)))
+(notmuch-setq-local company-idle-delay nil)))
 
 ;;;###autoload
 (defun notmuch-company (command  arg  _ignore)
diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 1f0d167..bb53170 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -966,6 +966,78 @@ status."
 (defvar notmuch-show-process-crypto nil)
 (make-variable-buffer-local 'notmuch-show-process-crypto)
 
+;; Compatibility functions for emacs 23.
+
+;; The functions in this section are copied from eamcs 24.4 and are
+;; Copyright (C) 1985-1986, 1992, 1994-1995, 1999-2014 Free Software
+;; Foundation, Inc.
+
+(if (fboundp 'setq-local)
+(defalias 'notmuch-setq-local 'setq-local)
+  (defmacro notmuch-setq-local (var val)
+"Set variable VAR to value VAL in current buffer.
+
+Backport of setq-local for emacs without setq-local (pre 24.3)."
+`(set (make-local-variable ',var) ,val)))
+
+(if (fboundp 'read-char-choice)
+(defalias 'notmuch-read-char-choice 'read-char-choice)
+  (defun notmuch-read-char-choice (prompt chars  
inhibit-keyboard-quit)
+  "Read and return one of CHARS, prompting for PROMPT.
+Any input that is not one of CHARS is ignored.
+
+If optional argument INHIBIT-KEYBOARD-QUIT is non-nil, ignore
+keyboard-quit events while waiting for a valid input.
+
+This is an exact copy of this function from emacs 24 for use on
+emacs 23, except with the one emacs 24 only function it calls
+inlined."
+  (unless (consp chars)
+(error "Called `read-char-choice' without valid char choices"))
+  (let (char done show-help (helpbuf " *Char Help*"))
+(let ((cursor-in-echo-area t)
+  (executing-kbd-macro executing-kbd-macro)
+ (esc-flag nil))
+  (save-window-excursion ; in case we call help-form-show
+   (while (not done)
+ (unless (get-text-property 0 'face prompt)
+   (setq prompt (propertize prompt 'face 'minibuffer-prompt)))
+ (setq char (let ((inhibit-quit inhibit-keyboard-quit))
+  (read-key prompt)))

Re: [PATCH] emacs: add compatability functions for emacs 23

2016-10-27 Thread Mark Walters

On Thu, 27 Oct 2016, Matt Armstrong <marmstr...@google.com> wrote:
> Mark Walters <markwalters1...@gmail.com> writes:
>
>> +;; Compatability functions for emacs 23.
>> +
>> +(unless (fboundp 'setq-local)
>> +  (defmacro setq-local (var val)
>> +`(set (make-local-variable ',var) ,val)))
>
> A concern I have with this approach is that it modifies symbols outside
> the notmuch namespace.  Could people on old Emacsen come to rely on the
> newer Emacs interfaces inadvertently, and wonder how they came to be,
> etc?

This is a good point. I think I don't mind too much if they do -- they
should see it is provided by notmuch-lib if they do describe-function
etc. But maybe bremner would like to comment?

However, maybe other packages are doing the same. Thus I think we should
not put in a cut down version of read-char-choice but just include the
whole command from the emacs24 source. That way if any other package is
doing the same load order doesn't matter -- we don't stomp on them and
they don't stomp on us.

(As an aside if we do that do we need to include any copyright notice or
similar? -- maybe notmuch-lib.el could include notmuch-compat.el which
would contain all the compatability functions?)

> The only other package I have non-trivial experience working with is
> Gnus, and the practice there was to place portability interfaces in the
> gnus- namespace, and refrain from calling the "native" interfaces
> directly.

I think this would introduce a lot of clutter, so I would prefer not to
go that route.

Best wishes

Mark

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


Re: [PATCH] emacs: add compatability functions for emacs 23

2016-10-25 Thread Mark Walters

On Tue, 25 Oct 2016, David Bremner <da...@tethera.net> wrote:
> Mark Walters <markwalters1...@gmail.com> writes:
>
>> Some of the recent changes to the emacs code have used functions
>> introduced in emacs 24. The functions used are read-char-choice and
>> setq-local. This changeset adds compatability functions to
>> notmuch-lib so that it should work on emacs 23.
>>
>> ---
>>
>> Hi
>>
>> I tried compiling under emacs 23 recently and noticed that some recent
>> changes have used some features introuduced in emacs 24. I think we
>> still support emacs 23 so this changeset adds two compatability
>> functions.
>
> Hi Mark;
>
> Can you give me a recipe to reproduce the failures in emacs23? I only
> get warnings when building. Of course I believe that things will go
> wrong at some point calling non-existent functions.

Hi

You can make the read-char-choice fail by setting the fcc header to use
insert (the default), locking the database (eg doing notmuch tag
--batch), composing and sending a message. The Fcc will fail, which will
trigger the error.

For the setq-local start to compose a message, and then run
M-x notmuch-address-toggle-internal-completion
This will give the error.

Best wishes

Mark


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


[PATCH v2] devel: Document emacs keybindings

2016-10-23 Thread Mark Walters
This adds a file under devel listing all the keybindings sorted by key
in the main three modes (search, show and tree).

To reduce clutter it only lists the single key "unmodified"
keybindings: I think all our uses of prefixes and modifiers are
natural variants of the unmodified binding (eg M-n compared to n in
show mode)

This should make easier to see what keybindings are available when
adding new features.
---

Hi

This is an updated version of

id:1474377391-17960-1-git-send-email-markwalters1...@gmail.com

It is almost unchanged, but I have changed the commit message to make
it clear that I only intend it to contain unmodified (no C- M- etc)
bindings.

Otherwise the only change is that I updated the table to reflect
9966720453c72286b5f36a56323244d70202cb26 which moved "b" in tree-mode
to bounce, and DEL to backscroll.

Best wishes

Mark



devel/emacs-keybindings.org | 59 +
 1 file changed, 59 insertions(+)
 create mode 100644 devel/emacs-keybindings.org

diff --git a/devel/emacs-keybindings.org b/devel/emacs-keybindings.org
new file mode 100644
index 000..0f13b36
--- /dev/null
+++ b/devel/emacs-keybindings.org
@@ -0,0 +1,59 @@
+|---++---+-|
+| Key   | Search Mode| Show Mode   
  | Tree Mode   |
+|---++---+-|
+| a | notmuch-search-archive-thread  | 
notmuch-show-archive-message-then-next-or-next-thread | 
notmuch-tree-archive-message-then-next  |
+| b | notmuch-search-scroll-down | 
notmuch-show-resend-message   | 
notmuch-show-resend-message |
+| c | notmuch-search-stash-map   | notmuch-show-stash-map  
  | notmuch-show-stash-map  |
+| d || 
  | |
+| e || 
  | (notmuch-tree-button-activate)  |
+| f || 
notmuch-show-forward-message  | 
notmuch-show-forward-message|
+| g || 
  | |
+| h || 
notmuch-show-toggle-visibility-headers| 
|
+| i || 
  | |
+| j | notmuch-jump-search| notmuch-jump-search 
  | notmuch-jump-search |
+| k | notmuch-tag-jump   | notmuch-tag-jump
  | notmuch-tag-jump|
+| l | notmuch-search-filter  | 
notmuch-show-filter-thread| 
|
+| m | notmuch-mua-new-mail   | notmuch-mua-new-mail
  | notmuch-mua-new-mail|
+| n | notmuch-search-next-thread | 
notmuch-show-next-open-message| 
notmuch-tree-next-matching-message  |
+| o | notmuch-search-toggle-order| 
  | |
+| p | notmuch-search-previous-thread | 
notmuch-show-previous-open-message| 
notmuch-tree-prev-matching-message  |
+| q | notmuch-bury-or-kill-this-buffer   | 
notmuch-bury-or-kill-this-buffer  | 
notmuch-bury-or-kill-this-buffer|
+| r | notmuch-search-reply-to-thread-sender  | 
notmuch-show-reply-sender | 
notmuch-show-reply-sender   |
+| s | notmuch-search | notmuch-search  
  | notmuch-search  |
+| t | notmuch-search-filter-by-tag   | toggle-truncate-lines   
  | |
+| u || 
  | |
+| v ||  

Re: [PATCH] cli: try to run external notmuch- prefixed commands as subcommands

2016-10-22 Thread Mark Walters

On Sat, 22 Oct 2016, Jani Nikula  wrote:
> If the given subcommand is not known to notmuch, try to execute
> external notmuch- instead. This allows users to have their
> own notmuch related tools be run via the notmuch command, not unlike
> git does. Also notmuch-emacs-mua will be executable via 'notmuch
> emacs-mua'.
>
> By design, this does not allow notmuch's own subcommands to be
> overriden using external commands.
>
> ---
>
> Whether internal subcommands can be overridden or not is up to debate,
> can be consider either a bug or a feature depending on how you look at
> it.

This looks good to me +1 (note my C is not great, and I haven't tested
yet). It took me a while to realise that a nice feature of this was that
we can have some commands in languages other than C, like the emacs-mua
command in the next patch.

My only query is whether we are setting ourselves up to annoy people if
we add official commands later. For example if we add a notmuch delete
command then it could break a user's setup if they have a notmuch-delete
command. Would it be worth saying that we guarantee some namespace such
as local-* (so commands called notmuch-local-*) won't be touched?

Best wishes

Mark




> ---
>  notmuch.c | 39 +--
>  1 file changed, 37 insertions(+), 2 deletions(-)
>
> diff --git a/notmuch.c b/notmuch.c
> index 38b73c1d2acc..b9c320329dd5 100644
> --- a/notmuch.c
> +++ b/notmuch.c
> @@ -363,6 +363,39 @@ notmuch_command (notmuch_config_t *config,
>  return EXIT_SUCCESS;
>  }
>  
> +/*
> + * Try to run subcommand in argv[0] as notmuch- prefixed external
> + * command. argv must be NULL terminated (argv passed to main always
> + * is).
> + *
> + * Does not return if the external command is found and
> + * executed. Return TRUE if external command is not found. Return
> + * FALSE on errors.
> + */
> +static notmuch_bool_t try_external_command(char *argv[])
> +{
> +char *old_argv0 = argv[0];
> +notmuch_bool_t ret = TRUE;
> +
> +argv[0] = talloc_asprintf (NULL, "notmuch-%s", old_argv0);
> +
> +/*
> + * This will only return on errors. Not finding an external
> + * command (ENOENT) is not an error from our perspective.
> + */
> +execvp (argv[0], argv);
> +if (errno != ENOENT) {
> + fprintf (stderr, "Error: Running external command '%s' failed: %s\n",
> +  argv[0], strerror(errno));
> + ret = FALSE;
> +}
> +
> +talloc_free (argv[0]);
> +argv[0] = old_argv0;
> +
> +return ret;
> +}
> +
>  int
>  main (int argc, char *argv[])
>  {
> @@ -406,8 +439,10 @@ main (int argc, char *argv[])
>  
>  command = find_command (command_name);
>  if (!command) {
> - fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n",
> -  command_name);
> + /* This won't return if the external command is found. */
> + if (try_external_command(argv + opt_index))
> + fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch 
> help\")\n",
> +  command_name);
>   ret = EXIT_FAILURE;
>   goto DONE;
>  }
> -- 
> 2.1.4
>
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> https://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] emacs: add compatability functions for emacs 23

2016-10-22 Thread Mark Walters
Some of the recent changes to the emacs code have used functions
introduced in emacs 24. The functions used are read-char-choice and
setq-local. This changeset adds compatability functions to
notmuch-lib so that it should work on emacs 23.

---

Hi

I tried compiling under emacs 23 recently and noticed that some recent
changes have used some features introuduced in emacs 24. I think we
still support emacs 23 so this changeset adds two compatability
functions.

They are setq-local, which is esentially trivial, and
read-char-choice. I have written a minimal version of read-char-choice
for the functionality we need -- an alternative would be to just copy
and paste the function from emacs 24 source.

I have tested (lightly) on emacs 23 and it seems to work (and didn't
before). It should not change anything on more recent emacs (i.e. in
cases where we weren't already broken).

Finally, it does leave a compiler warning when compiling under emacs
23: notmuch-company.el does not require notmuch-lib.el but I think
that is probably OK.

Best wishes

Mark



emacs/notmuch-lib.el | 18 ++
1 file changed, 18 insertions(+)

diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el
index 1f0d167..1459f83 100644
--- a/emacs/notmuch-lib.el
+++ b/emacs/notmuch-lib.el
@@ -966,6 +966,24 @@ status."
 (defvar notmuch-show-process-crypto nil)
 (make-variable-buffer-local 'notmuch-show-process-crypto)
 
+;; Compatability functions for emacs 23.
+
+(unless (fboundp 'setq-local)
+  (defmacro setq-local (var val)
+`(set (make-local-variable ',var) ,val)))
+
+(unless (fboundp 'read-char-choice)
+  (defun read-char-choice (prompt chars)
+(let (char done)
+  (while (not done)
+   (setq char (read-key prompt))
+   (cond
+((memq char chars)
+ (setq done t))
+((memq char '(?\C-g ?\e))
+ (keyboard-quit
+  char)))
+
 (provide 'notmuch-lib)
 
 ;; Local Variables:
-- 
2.1.4

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


[PATCH] emacs: interesting-buffer bugfixes/updates

2016-10-22 Thread Mark Walters
The command notmuch-interesting-buffer has got out of date -- it
doesn't mention notmuch-tree, and it still refers to message-mode not
notmuch-message-mode. Update both of these.

This fixes the bug that notmuch-cycle-notmuch-buffers does not include
notmuch-tree or notmuch-message-mode buffers in its cycling.

---

Jani pointed notmuch-cycle-notmuch-buffers out to me on irc (I hadn't
known it existed). It seems like it could be very useful.

However, it call notmuch-interesting-buffer which has not been updated
since 2011, so doesn't know about notmuch-tree or
notmuch-message-mode. notmuch-tree came into mainline in 2013, and we
switched to notmuch-message-mode (from message-mode) in August last
year, so both bugs have been present for quite some time.

Best wishes

Mark






emacs/notmuch.el | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/emacs/notmuch.el b/emacs/notmuch.el
index bd08aa0..2fc72b7 100644
--- a/emacs/notmuch.el
+++ b/emacs/notmuch.el
@@ -1066,8 +1066,9 @@ current search results AND that are tagged with the given 
tag."
   (with-current-buffer b
 (memq major-mode '(notmuch-show-mode
   notmuch-search-mode
+  notmuch-tree-mode
   notmuch-hello-mode
-  message-mode
+  notmuch-message-mode
 
 ;;;###autoload
 (defun notmuch-cycle-notmuch-buffers ()
-- 
2.1.4

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


[PATCH] nmbug: allow excluded messages

2016-10-22 Thread Mark Walters
This makes nmbug work even if the notmuch mailing list messages are
excluded (i.e., have a tag in the excluded tags list).
---

I keep all my mailing list emails under an excluded tag (initially
this was to test the exclude code thoroughly, but I find it convenient
to keep day to day email and mailing list email separate). However,
this confuses nmbug -- would the following patch be acceptable?

(I think this is the only place it is needed, but I don't use nmbug
much so I haven't tested thoroughly.)

Best wishes

Mark

devel/nmbug/nmbug | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/devel/nmbug/nmbug b/devel/nmbug/nmbug
index 6febf16..dc565c4 100755
--- a/devel/nmbug/nmbug
+++ b/devel/nmbug/nmbug
@@ -580,7 +580,7 @@ def get_status():
 maybe_deleted = _diff_index(index=index, filter='D')
 for id, tags in maybe_deleted.items():
 (_, stdout, stderr) = _spawn(
-args=['notmuch', 'search', '--output=files', 'id:{0}'.format(id)],
+args=['notmuch', 'search', '--output=files', '--exclude=false', 
'id:{0}'.format(id)],
 stdout=_subprocess.PIPE,
 wait=True)
 if stdout:
-- 
2.1.4

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


[PATCH] NEWS for two bugfixes

2016-10-22 Thread Mark Walters
This adds news items for the two bugs

emacs: search face bugfix
and
emacs: fix notmuch-search-line-faces defcustom
---

Hi here is a NEWS update as requested.

Best wishes

Mark


NEWS | 9 +
 1 file changed, 9 insertions(+)

diff --git a/NEWS b/NEWS
index ac3ceb1..547b961 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,15 @@ Require Xapian >= 1.2.6
 Emacs
 -
 
+Fix default colours for unread and flagged messages
+
+  In 0.23 the default colours for unread and flagged messages in
+  search view were accidentally swapped. This release returns them to
+  the original colours.
+
+  A related change in 0.23 broke the customize widget for
+  notmuch-search-line-faces. This is now fixed.
+
 Fix test failure with Emacs 25.1
 
   A previously undiscovered jit-lock related bug was exposed by Emacs
-- 
2.1.4

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


Re: [PATCH v4] Add notmuch-show--build-queries.

2016-10-20 Thread Mark Walters

On Wed, 19 Oct 2016, Matt Armstrong  wrote:
> notmuch-show--build-buffer now queries a list of queries built by the
> former.  This simplifies the logic.  It also provides an easy place to
> experiment with alternate sets of queries for given notmuch-show-*
> variables (e.g. users can use advice-add to do so in a surgical way).
> ---

This version looks good to me +1

Best wishes

Mark


>  emacs/notmuch-show.el | 35 +--
>  1 file changed, 21 insertions(+), 14 deletions(-)
>
> diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
> index 16ff45a..fcf7e6e 100644
> --- a/emacs/notmuch-show.el
> +++ b/emacs/notmuch-show.el
> @@ -1263,6 +1263,18 @@ matched."
>   (message "No messages matched the query!")
>   nil
>  
> +(defun notmuch-show--build-queries (thread context)
> +  "Return a list of queries to try for this search.
> +
> +THREAD and CONTEXT are both strings, though CONTEXT may be nil.
> +When CONTEXT is not nil, the first query is the conjunction of it
> +and THREAD.  The next query is THREAD alone, and serves as a
> +fallback if the prior matches no messages."
> +  (let (queries)
> +(push (list thread) queries)
> +(if context (push (list thread "and (" context ")") queries))
> +queries))
> +
>  (defun notmuch-show--build-buffer ( state)
>"Display messages matching the current buffer context.
>  
> @@ -1270,25 +1282,20 @@ Apply the previously saved STATE if supplied, 
> otherwise show the
>  first relevant message.
>  
>  If no messages match the query return NIL."
> -  (let* ((basic-args (list notmuch-show-thread-id))
> -  (args (if notmuch-show-query-context
> -(append (list "\'") basic-args
> -(list "and (" notmuch-show-query-context ")\'"))
> -  (append (list "\'") basic-args (list "\'"
> -  (cli-args (cons "--exclude=false"
> +  (let* ((cli-args (cons "--exclude=false"
>(when notmuch-show-elide-non-matching-messages
>  (list "--entire-thread=false"
> -
> -  (forest (or (notmuch-query-get-threads (append cli-args args))
> -  ;; If a query context reduced the number of
> -  ;; results to zero, try again without it.
> -  (and notmuch-show-query-context
> -   (notmuch-query-get-threads (append cli-args 
> basic-args)
> -
> +  (queries (notmuch-show--build-queries
> +notmuch-show-thread-id notmuch-show-query-context))
> +  (forest nil)
>;; Must be reset every time we are going to start inserting
>;; messages into the buffer.
>(notmuch-show-previous-subject ""))
> -
> +;; Use results from the first query that returns some.
> +(while (and (not forest) queries)
> +  (setq forest (notmuch-query-get-threads
> + (append cli-args (list "'") (car queries) (list "'"
> +  (setq queries (cdr queries)))
>  (when forest
>(notmuch-show-insert-forest forest)
>  
> -- 
> 2.8.0.rc3.226.g39d4020
>
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> https://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2] emacs: make faces clear on dark backgrounds.

2016-10-20 Thread Mark Walters
On Thu, 20 Oct 2016, Matt Armstrong  wrote:
> The notmuch-tag-flagged, notmuch-search-flagged-face and
> notmuch-crypto-part-header faces defaulted to "blue", which is nearly
> unreadable when a dark background is in use.  This is addressed by using
> "gold" for dark backgrounds.

Hi

Broadly this looks good to me -- though I think blue is OK on some dark
backgrounds so it would be good to have confirmation from some people
who do use a dark background normally as to whether they had to
customise these faces.

One small point: I think I would prefer a ((class color) (background
light)) test for the "light" face so that it is consistent with the other 
deffaces
which already distinguish between light and dark background.

Best wishes

Mark


> ---
>  emacs/notmuch-crypto.el | 5 -
>  emacs/notmuch-tag.el| 5 -
>  emacs/notmuch.el| 5 -
>  3 files changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/emacs/notmuch-crypto.el b/emacs/notmuch-crypto.el
> index e376aa8..3f4b3f6 100644
> --- a/emacs/notmuch-crypto.el
> +++ b/emacs/notmuch-crypto.el
> @@ -42,7 +42,10 @@ mode."
>:group 'notmuch-crypto)
>  
>  (defface notmuch-crypto-part-header
> -  '((t (:foreground "blue")))
> +  'class color)
> +  (background dark))
> + (:foreground "gold"))
> +(t (:foreground "blue")))
>"Face used for crypto parts headers."
>:group 'notmuch-crypto
>:group 'notmuch-faces)
> diff --git a/emacs/notmuch-tag.el b/emacs/notmuch-tag.el
> index 1b2ce5c..199582b 100644
> --- a/emacs/notmuch-tag.el
> +++ b/emacs/notmuch-tag.el
> @@ -115,7 +115,10 @@ Used in the default value of `notmuch-tag-formats`."
>:group 'notmuch-faces)
>  
>  (defface notmuch-tag-flagged
> -  '((t :foreground "blue"))
> +  'class color)
> +  (background dark))
> + (:foreground "gold"))
> +(t :foreground "blue"))
>"Face used for the flagged tag.
>  
>  Used in the default value of `notmuch-tag-formats`."
> diff --git a/emacs/notmuch.el b/emacs/notmuch.el
> index bd08aa0..9246344 100644
> --- a/emacs/notmuch.el
> +++ b/emacs/notmuch.el
> @@ -313,7 +313,10 @@ there will be called at other points of notmuch 
> execution."
>:group 'notmuch-faces)
>  
>  (defface notmuch-search-flagged-face
> -  '((t
> +  'class color)
> +  (background dark))
> + (:foreground "gold"))
> +(t
>   (:foreground "blue")))
>"Face used in search mode face for flagged threads.
>  
> -- 
> 2.8.0.rc3.226.g39d4020
>
> ___
> notmuch mailing list
> notmuch@notmuchmail.org
> https://notmuchmail.org/mailman/listinfo/notmuch
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


  1   2   3   4   5   6   7   8   9   10   >