[PATCH] fix "shadow build"

2016-11-13 Thread Tomi Ollila
With working tests.
---

Some day we dump `find_notmuch_path()`

configure   | 6 --
 test/test-lib-common.sh | 2 ++
 test/test-lib.sh| 6 +++---
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/configure b/configure
index 2a0ce9e..05b964d 100755
--- a/configure
+++ b/configure
@@ -342,8 +342,8 @@ int main(void) {
 return 0;
 }
 EOF
-if ${CC} ${CFLAGS} _libversion.c -o _libversion > /dev/null 2>&1 && \
-   ./_libversion > _libversion.sh && . ./_libversion.sh
+if ${CC} ${CFLAGS} -I "$srcdir" _libversion.c -o _libversion > /dev/null 2>&1 \
+   && ./_libversion > _libversion.sh && . ./_libversion.sh
 then
 printf "OK.\n"
 else
@@ -1158,6 +1158,8 @@ cat > sh.config < OUTPUT
 }
 
 test_ruby() {
-MAIL_DIR=$MAIL_DIR ruby -I $TEST_DIRECTORY/../bindings/ruby> OUTPUT
+MAIL_DIR=$MAIL_DIR ruby -I $SOURCE_DIRECTORY/bindings/ruby> OUTPUT
 }
 
 test_C () {
 exec_file="test${test_count}"
 test_file="${exec_file}.c"
 cat > ${test_file}
-${TEST_CC} ${TEST_CFLAGS} -I${TEST_DIRECTORY} -I${TEST_DIRECTORY}/../lib 
-o ${exec_file} ${test_file} -L${TEST_DIRECTORY}/../lib/ -lnotmuch -ltalloc
+${TEST_CC} ${TEST_CFLAGS} -I${TEST_DIRECTORY} -I${SOURCE_DIRECTORY}/lib -o 
${exec_file} ${test_file} -L${TEST_DIRECTORY}/../lib/ -lnotmuch -ltalloc
 echo "== stdout ==" > OUTPUT.stdout
 echo "== stderr ==" > OUTPUT.stderr
 ./${exec_file} "$@" 1>>OUTPUT.stdout 2>>OUTPUT.stderr
-- 
2.7.4

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


[Travis CI] Broken: notmuch/notmuch#283 (master - 2dd96d6)

2016-11-13 Thread David Bremner

I'm fairly sure these test failures are emacs 23 specific. In particular
I tested on debian jessie with on old install of emacs23 and I can
replicate them, but not if I switch to emacs24. The tests also fail
under emacs23 with
id:1477191835-17828-1-git-send-email-markwalters1...@gmail.com applied.


1) Wael, what about updating the travis setup so that it uses a more
recent version of emacs?

2) Any emacs23 users care to try to debug this? It looks like none of
the saves involving signing or encryption actually worked, as there are
exactly 3 files in mail/drafts/cur, one with subject draft-test-0001 and
two with subject draft-test-0002


--- Begin Message ---
In-Repl---=-=
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="-=-="

y-To: 
X-Report-Abuse: Please forward a copy of this message, including all headers, 
to ab...@mandrill.com
X-Report-Abuse: You can also report abuse here: 
http://mandrillapp.com/contact/abuse?id=14313403.7254f14bb98a41288940e81b35471ee7
X-Mandrill-User: md_14313403
Date: Sun, 13 Nov 2016 18:04:18 +


---=-=
Content-Type: multipart/alternative; boundary="=-=-="

--=-=-=
Content-Type: text/plain; charset=utf-8
Content-Disposition: inline

Build Update for notmuch/notmuch
-

Build: #283
Status: Broken

Duration: 2 minutes and 36 seconds
Commit: 2dd96d6 (master)
Author: David Bremner
Message: emacs: resume messages

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.

View the changeset: 
https://github.com/notmuch/notmuch/compare/4d486cf94d3f...2dd96d6bd642

View the full build log and details: 
https://travis-ci.org/notmuch/notmuch/builds/175515483

--

You can configure recipients for build notifications in your .travis.yml file. 
See https://docs.travis-ci.com/user/notifications


--=-=-=
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable



  
=20=20=20=20
  

  

  

  
https://avatars.githubusercontent.com/u/7518979?s=3D40d=3D=
https%3A%2F%2Ftravis-ci.org%2Fimages%2Fmailer%2Fmascot-avatar-40px.png" sty=
le=3D"vertical-align:middle;width:40px;height:40px"> https://travis-ci.org/no=
tmuch/notmuch" style=3D"text-decoration:underline;color:#606060">notmuch / =
notmuch (https://github.com/notmuch/notmuch/tree/ma=
ster" style=3D"text-decoration:underline;color:#606060">master)


  
  

  

  
https://travis-ci.org/images/mailer/fai=
led.png" width=3D"25" height=3D"25">

=
https://travis-ci.org/notmuch/notmuch/builds/175515483; style=3D=
"text-decoration:none;font-weight:bold;color:#57769d;text-decoration:underl=
ine;color:#df192a">Build #283 was broken.https://tra=
vis-ci.org/images/mailer/arrow-failed.png" style=3D"float: right;" height=
=3D"45">


 2 minutes and 36 secon=
ds

  


  

David Bremner

https://github.com/notmuch/notmuch/commit/2dd96d6bd642c3b32ce199=
7528f69665019b7497" style=3D"text-decoration:underline;text-decoration:none=
;font-weight:bold;color:#57769d">2dd96d6 https://github.com/=
notmuch/notmuch/compare/4d486cf94d3f...2dd96d6bd642" style=3D"text-decorati=
on:underline;text-decoration:none;font-weight:bold;color:#57769d">Changeset=
 =E2=86=92

  
  
=C2=A0
emacs: resume messagesProvi=
de functionality to resume editing a message previously saved withnotmu=
ch-draft-save, including decoding the X-Notmuch-Emacs-Secureheader.=
Resume gets the raw file from notmuch and using the emacs functionm=
ime-to-mml reconstructs the message (including attachments).'e' is =
bound to resume a draft from show or tree mode.
  
  
  

  


  

  
Want to know about upcoming bu=
ild environment updates?
Would you like to stay up-to-date with the upcoming Travis CI b=
uild environment updates?
  We set up a mailing list for you!
  Sign up http://eepurl.com/9OCsP; style=3D"text-dec=
oration:underline;color:#606060">here.

  

  

  

  
https://travis-ci.org/images/mailer/email-footer-tr=
avis-logo.png" style=3D"width: 50px; height: 50px;">
  
  
https://docs.travis-ci.com; style=3D"text-decoration=
:underline;color:#606060">Documentation about Travis CI
Need help? Mail mailto:supp...@travis-ci.com; style=
=3D"text-decoration:underline;color:#606060">support!
Choose who receives these build notification 

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

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

> 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).

Pushed to master with the following edits:

diff --git a/emacs/notmuch-draft.el b/emacs/notmuch-draft.el
index 496e11f..fb7f4f5 100644
--- a/emacs/notmuch-draft.el
+++ b/emacs/notmuch-draft.el
@@ -25,9 +25,9 @@
 
 (require 'notmuch-maildir-fcc)
 (require 'notmuch-tag)
-(require 'notmuch-mua)
 
 (declare-function notmuch-show-get-message-id "notmuch-show" ( bare))
+(declare-function notmuch-message-mode "notmuch-mua")

switch require to declare function to avoid circular require


 (defgroup notmuch-draft nil
   "Saving and editing drafts in Notmuch."
@@ -152,7 +152,6 @@ Used when a new version is saved, or the message is sent."
 `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? ")

remove recursive call.

diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el
index b68cdf2..93747b1 100644
--- a/emacs/notmuch-mua.el
+++ b/emacs/notmuch-mua.el
@@ -27,6 +27,7 @@
 
 (require 'notmuch-lib)
 (require 'notmuch-address)
+(require 'notmuch-draft)
 
 (eval-when-compile (require 'cl))
 
Added a require so that saving worked after applying 3 of 4 patches


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


Re: [PATCH] emacs: rename notmuch-address-completion-hook to notmuch-address-post-completion-functions

2016-11-13 Thread David Bremner
David Bremner  writes:

> Apparently it is a (not completely adhered to) emacs convention [1] that
> only hooks that don't take arguments end in 'hook'
>
> [1]: https://www.gnu.org/software/emacs/manual/html_node/elisp/Hooks.html
> ---

pushed to master
___
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 .
+;;
+;; Authors: Mark Walters 
+;; David Bremner 
+
+;;; 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[^\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 

[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


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

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

> 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.
>

I'm fine with the changes, and with leaving the "remove things from
hooks" step for later. I think the only remaining question is this
rather nitpicky discussion about the error handling of
notmuch-show-resume-message.
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


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

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

> On Sat, 12 Nov 2016, David Bremner  wrote:
>>> +(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
>
>>
>> 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?
>
> 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).

Well, two issues:

1) it's not clear that notmuch-show-returns nil on an error. When I
tested it in a random buffer it errored because it passed nill to
notmuch-id-to-query.

2) If we're not going to resume, we'd hope some error message would be
   printed, and it might be the job of this function to print it.
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] emacs: rename notmuch-address-completion-hook to notmuch-address-post-completion-functions

2016-11-13 Thread David Bremner
Apparently it is a (not completely adhered to) emacs convention [1] that
only hooks that don't take arguments end in 'hook'

[1]: https://www.gnu.org/software/emacs/manual/html_node/elisp/Hooks.html
---
 emacs/notmuch-address.el | 4 ++--
 emacs/notmuch-company.el | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-address.el b/emacs/notmuch-address.el
index 36c796f..5b2beef 100644
--- a/emacs/notmuch-address.el
+++ b/emacs/notmuch-address.el
@@ -98,7 +98,7 @@ to know how address selection is made by default."
   :group 'notmuch-send
   :group 'notmuch-external)
 
-(defcustom notmuch-address-completion-hook nil
+(defcustom notmuch-address-post-completion-functions nil
   "Functions called after completing address.
 
 The completed address is passed as an argument to each function.
@@ -218,7 +218,7 @@ external commands."
(push chosen notmuch-address-history)
(delete-region beg end)
(insert chosen)
-   (run-hook-with-args 'notmuch-address-completion-hook chosen))
+   (run-hook-with-args 'notmuch-address-post-completion-functions 
chosen))
(message "No matches.")
(ding
(t nil)))
diff --git a/emacs/notmuch-company.el b/emacs/notmuch-company.el
index 91c4804..b0f9782 100644
--- a/emacs/notmuch-company.el
+++ b/emacs/notmuch-company.el
@@ -86,7 +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))
+  (post-completion (run-hook-with-args 
'notmuch-address-post-completion-functions arg))
   (no-cache t
 
 
-- 
2.10.2

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


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

2016-11-13 Thread Tomi Ollila

(Trying to send this w/o Mark in To: -- in the hope also Mark receive this
email to his gmail account...)

On Sun, Nov 13 2016, Mark Walters  wrote:

> 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?

I found *-hook-functions format mystically familiar but could not found any
references in emacs 24.5 (nor now latest git) elisp source; there has been
loadhist-hook-functions and vc-backend-hook-functions in the source but
those have been removed/replaced later (w/o explanation why). otoh there
are plenty of *-hook-function references (which value seem to be expected to
be symbol to function). Then I recognized I have had such definitions in
my *own* elisp configuration files something like 25 years... ;) (copied
from someone in my early emacs days).

So, after more grepping it looks to me that this 
notmuch-address-post-completion-functions
is pretty good suggestion.

(Grepping through elisp source distributed with emacs there are quite
a few lines like (run-hook-with-args '...-hook args..). it is easy to
end up being incompliant with the emacs convention. But other code
not being compliant is not good reason to do the same (and thanks to
Matt (in id:qf537j3hu4p@marmstrong-linux.kir.corp.google.com) for
rest of us to recognize this early enough))

BTW: I just noticed that the message subject said: 
emacs: add notmuch-address-post-completion-hook
but the currently used variable name lacked this -post- part
-- caused a bit of confusion of what/why am I suggesting here ;)

Tomi

>
> Best wishes
>
> Mark
___
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')"
-  (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 

[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 .
+;;
+;; Authors: Mark Walters 
+;; David Bremner 
+
+;;; 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[^\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 

[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  wrote:
> David Bremner  writes:
>
>> From: Mark Walters 
>
> 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
abort. However, message-send-and-exit will have killed the buffer so we
need to store the relevant local variables before we run that command.

Having said that, I think that message-send-hook is run before the send
anyway, so putting both of the above in notmuch-mua-send-common would
not make the situation any worse.

My inclination was to fix it properly afterwards -- but we could do the
above now as a "no worse than now" change.

Best wishes

Mark






>
>> --- /dev/null
>> +++ b/test/T630-emacs-draft.sh
>> @@ -0,0 +1,42 @@
>> +#!/usr/bin/env bash
>> +test_description="Emacs Draft Handling"
>> +. ./test-lib.sh || exit 1
>
> Ok,