[PATCH v3] Make buttons for attachments allow viewing as well as saving
Define a keymap for attachment buttons to allow multiple actions. Define 3 possible actions: save attachment: exactly as currently, view attachment: uses mailcap entry, view attachment with user chosen program Keymap on a button is: s for save, v for view and o for view with other program. Default (i.e. enter or mouse button) is save but this is configurable in notmuch customize. One implementation detail: the view attachment function forces all attachments to be "displayed" using mailcap even if emacs could display them itself. Thus, for example, text/html appears in a browser and text/plain asks whether to save (on a standard debian setup) --- emacs/notmuch-show.el | 106 ++--- 1 files changed, 82 insertions(+), 24 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 03c1f6b..0aaaf79 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -281,10 +281,21 @@ message at DEPTH in the current thread." (run-hooks 'notmuch-show-markup-headers-hook) (define-button-type 'notmuch-show-part-button-type - 'action 'notmuch-show-part-button-action + 'action 'notmuch-show-part-button-default + 'keymap 'notmuch-show-part-button-map 'follow-link t 'face 'message-mml) +(defvar notmuch-show-part-button-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map button-map) + (define-key map "s" 'notmuch-show-part-button-save) + (define-key map "v" 'notmuch-show-part-button-view) + (define-key map "o" 'notmuch-show-part-button-interactively-view) +map) + "Submap for button commands") +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) + (defun notmuch-show-insert-part-header (nth content-type declared-type &optional name comment) (let ((button)) (setq button @@ -299,29 +310,48 @@ message at DEPTH in the current thread." " ]") :type 'notmuch-show-part-button-type :notmuch-part nth - :notmuch-filename name)) + :notmuch-filename name + :notmuch-content-type content-type)) (insert "\n") ;; return button button)) ;; Functions handling particular MIME parts. -(defun notmuch-show-save-part (message-id nth &optional filename) - (let ((process-crypto notmuch-show-process-crypto)) -(with-temp-buffer - (setq notmuch-show-process-crypto process-crypto) - ;; Always acquires the part via `notmuch part', even if it is - ;; available in the JSON output. - (insert (notmuch-show-get-bodypart-internal message-id nth)) - (let ((file (read-file-name - "Filename to save as: " - (or mailcap-download-directory "~/") - nil nil - filename))) - ;; Don't re-compress .gz & al. Arguably we should make - ;; `file-name-handler-alist' nil, but that would chop - ;; ange-ftp, which is reasonable to use here. - (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion t) +(defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) + (declare (indent 2)) + (let ((process-crypto (make-symbol "process-crypto"))) +`(let ((,process-crypto notmuch-show-process-crypto)) + (with-temp-buffer +(setq notmuch-show-process-crypto ,process-crypto) +;; Always acquires the part via `notmuch part', even if it is +;; available in the JSON output. +(insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) +, at body + +(defun notmuch-show-save-part (message-id nth &optional filename content-type) + (notmuch-with-temp-part-buffer message-id nth +(let ((file (read-file-name +"Filename to save as: " +(or mailcap-download-directory "~/") +nil nil +filename))) + ;; Don't re-compress .gz & al. Arguably we should make + ;; `file-name-handler-alist' nil, but that would chop + ;; ange-ftp, which is reasonable to use here. + (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion t + +(defun notmuch-show-view-part (message-id nth &optional filename content-type ) + (notmuch-with-temp-part-buffer message-id nth +;; set mm-inlined-types to nil to force an external viewer +(let ((handle (mm-make-handle (current-buffer) (list content-type))) + (mm-inlined-types nil)) + (mm-display-part handle t + +(defun notmuch-show-interactively-view-part (message-id nth &optional filename content-type) + (notmuch-with-temp-part-buffer message-id nth +(let ((handle (mm-make-handle (current-buffer) (list content-type + (mm-interactively-view-part handle (defun notmuch-show-mm-display-part-inline (msg part nth content-type) "Use the mm-decode/mm-view functions to display a part in the @@ -1502,12 +1532,40 @@ buffer." ;; Commands typically bound to buttons. -(defun notmuch-show
Infinite loop in emacs interface
Hi, Actually, this is starting to look like a problem with gnus in the latest emacs-snapshot. I didn't notice before, but when I view the thread, I get this error: Debugger entered--Lisp error: (void-variable gnus-inhibit-images) mm-shr((# ("text/html") nil nil nil nil nil nil)) mm-inline-text-html((# ("text/html") nil nil nil nil nil nil)) mm-display-inline((# ("text/html") nil nil nil nil nil nil)) mm-display-part((# ("text/html") nil nil nil nil nil nil)) notmuch-show-mm-display-part-inline(...snipped...) notmuch-search-show-thread(nil) call-interactively(notmuch-search-show-thread nil nil) Someone seems to have come across it quite a while ago. http://lists.gnu.org/archive/html/emacs-devel/2010-11/msg00625.html This is quite strange because the previous emacs snapshot (20120105) was working OK. Running this code before viewing the thread seems to remove the error and stop the infinite loop: (defvar gnus-inhibit-images nil "*testing") (set-variable 'gnus-inhibit-images nil) But that's about the extent of my elisp knowledge. I'm not sure how to actually fix the bug. Cheers, Rodney
[PATCH 1/1] Make buttons for attachments allow viewing as well as saving
> > Oops, actually there was a bug in that macro. It should have been > > (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) > (declare (indent 2)) > (let ((process-crypto (make-symbol "process-crypto"))) > `(let ((,process-crypto notmuch-show-process-crypto)) >(with-temp-buffer > (setq notmuch-show-process-crypto ,process-crypto) > ;; Always acquires the part via `notmuch part', even if it is > ;; available in the JSON output. > (insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) > , at body > > The only difference is on the "insert" line. Sorry about that. Fixed. [Snip excellent explanation of defmacro] Thanks for the excellent explanation! > > Finally, I have discovered one bug/misfeature. If you try to "view" an > > attachment then it will offer to save it but will not offer a > > filename. If you try and save it (or use the default action) it will > > offer a filename as now. As far as I can see this is not fixable if I > > use mm-display-part: however, I could include a slight tweaked version, > > notmuch-show-mm-display-part say, which would fix this corner > > case. (Essentially, it would call notmuch-show-save-part if it failed to > > find a handler rather than mailcap-save-binary-file.) However, this is > > about 50 lines of lisp so I am not sure it is worth it. > > Hmm. This is probably worth fixing, but probably in a separate patch. > Duplicating mm-display-part is probably not the way to go. It think > it will work to pass t as the no-default argument to mm-display-part > and check the return value, which should be 'inline if it was able to > handle it internally or 'external if it found an external helper. I'm > pretty sure it will never fall in to mailcap-save-binary-file in that > case. If that doesn't work, you could flet mailcap-save-binary-file > around the call to mm-display-part. I had tried passing t to mm-display-part and that didn't work as I expected. I will experiment some more and try your flet suggestion but I think that will be a separate patch. I will send a potential final version of this patch as a reply to this email. Many thanks for all the guidance and help! Best wishes Mark
[PATCH 1/4] emacs: unify search mechanisms
Hello. On Mon, 16 Jan 2012 12:21:20 +, Jani Nikula wrote: > On Mon, 16 Jan 2012 15:39:14 +0400, Dmitry Kurochkin gmail.com> wrote: > > On Mon, 16 Jan 2012 11:35:37 +, David Edmondson wrote: > > > On Sun, 25 Dec 2011 08:14:52 +0400, Dmitry Kurochkin > > gmail.com> wrote: > > > > Before the change, there were two ways to do search in Emacs UI: > > > > search widget in notmuch-hello buffer and `notmuch-search' > > > > function bound to "s". Internally, notmuch-hello search widget > > > > uses `notmuch-search' function. But it uses widget field input > > > > instead of minibuffer. Such duplication is a major issue for > > > > notmuch-hello usability: search interface is inconsistent and > > > > lacks features that are available in minibuffer (e.g. history and > > > > auto completion). Some of these features may be relatively easy > > > > to implement for notmuch-hello search, others would be much more > > > > tricky. So to avoid duplication, make UI more consistent, bring > > > > notmuch-hello search to feature parity with the minibuffer > > > > search, the patch replaces notmuch-hello search widget and with a > > > > button that works the same way as "s" key binding. > > > > > > Dmitry, if Daniel re-submits his patches to allow the construction of > > > `notmuch-hello' buffers to be configured, it seems that this patchset > > > would become unnecessary. Is that correct? > > > > Right. We will just need to fix the 's' key binding. Looking forward > > for that. > > Isn't (something like) this still needed to merge the search histories: > > id:"1324698436-8532-1-git-send-email-dmitry.kurochkin at gmail.com" > I have sent a new patch series implementing the changes [1]. Regards, Dmitry [1] id:1326828850-8519-1-git-send-email-dmitry.kurochkin at gmail.com > > Jani.
[PATCH 3/3] emacs: bind "s" to `notmuch-hello-search' in notmuch-hello buffer
`notmuch-hello-search' uses `notmuch-search' function but refreshes notmuch-hello buffer when the search buffer is closed. --- emacs/notmuch-hello.el |5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index cb36977..e908659 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -163,7 +163,8 @@ International Bureau of Weights and Measures." (format "%s%03d" notmuch-hello-thousands-separator elem)) (cdr result) -(defun notmuch-hello-search (search) +(defun notmuch-hello-search (&optional search) + (interactive) (notmuch-search search notmuch-search-oldest-first nil nil #'notmuch-hello-search-continuation)) @@ -330,7 +331,7 @@ should be. Returns a cons cell `(tags-per-line width)'." (define-key map "G" 'notmuch-hello-poll-and-update) (define-key map (kbd "") 'widget-backward) (define-key map "m" 'notmuch-mua-new-mail) -(define-key map "s" 'notmuch-search) +(define-key map "s" 'notmuch-hello-search) map) "Keymap for \"notmuch hello\" buffers.") (fset 'notmuch-hello-mode-map notmuch-hello-mode-map) -- 1.7.8.3
[PATCH 2/3] emacs: use a single history for all searches
There are two ways to do search in Emacs UI: search widget in notmuch-hello buffer and `notmuch-search' function bound to "s". Before the change, these search mechanisms used different history lists. The patch makes notmuch-hello search use the same history list as `notmuch-search' function. --- emacs/notmuch-hello.el | 49 ++-- emacs/notmuch-lib.el |9 emacs/notmuch.el | 19 +-- test/emacs.expected-output/notmuch-hello |2 +- .../notmuch-hello-no-saved-searches|2 +- .../emacs.expected-output/notmuch-hello-with-empty |2 +- 6 files changed, 40 insertions(+), 43 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 08fcd22..cb36977 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -29,8 +29,8 @@ (declare-function notmuch-search "notmuch" (query &optional oldest-first target-thread target-line continuation)) (declare-function notmuch-poll "notmuch" ()) -(defcustom notmuch-recent-searches-max 10 - "The number of recent searches to store and display." +(defcustom notmuch-hello-recent-searches-max 10 + "The number of recent searches to display." :type 'integer :group 'notmuch) @@ -151,16 +151,6 @@ International Bureau of Weights and Measures." (defvar notmuch-hello-url "http://notmuchmail.org"; "The `notmuch' web site.") -(defvar notmuch-hello-recent-searches nil) - -(defun notmuch-hello-remember-search (search) - (setq notmuch-hello-recent-searches - (delete search notmuch-hello-recent-searches)) - (push search notmuch-hello-recent-searches) - (if (> (length notmuch-hello-recent-searches) -notmuch-recent-searches-max) - (setq notmuch-hello-recent-searches (butlast notmuch-hello-recent-searches - (defun notmuch-hello-nice-number (n) (let (result) (while (> n 0) @@ -173,16 +163,9 @@ International Bureau of Weights and Measures." (format "%s%03d" notmuch-hello-thousands-separator elem)) (cdr result) -(defun notmuch-hello-trim (search) - "Trim whitespace." - (if (string-match "^[[:space:]]*\\(.*[^[:space:]]\\)[[:space:]]*$" search) - (match-string 1 search) -search)) - (defun notmuch-hello-search (search) - (let ((search (notmuch-hello-trim search))) -(notmuch-hello-remember-search search) -(notmuch-search search notmuch-search-oldest-first nil nil #'notmuch-hello-search-continuation))) + (notmuch-search search notmuch-search-oldest-first nil nil + #'notmuch-hello-search-continuation)) (defun notmuch-hello-add-saved-search (widget) (interactive) @@ -461,7 +444,7 @@ Complete list of currently available key bindings: (let ((found-target-pos nil) (final-target-pos nil) - (search-bar-pos)) + (default-pos)) (let* ((saved-alist ;; Filter out empty saved searches if required. (if notmuch-show-empty-saved-searches @@ -493,7 +476,7 @@ Complete list of currently available key bindings: (indent-rigidly start (point) notmuch-hello-indent))) (widget-insert "\nSearch: ") - (setq search-bar-pos (point-marker)) + (setq default-pos (point-marker)) (widget-create 'editable-field ;; Leave some space at the start and end of the ;; search boxes. @@ -507,18 +490,18 @@ Complete list of currently available key bindings: (put-text-property (1- (point)) (point) 'invisible t) (widget-insert "\n") - (when notmuch-hello-recent-searches + (when notmuch-search-history (widget-insert "\nRecent searches: ") (widget-create 'push-button :notify (lambda (&rest ignore) - (setq notmuch-hello-recent-searches nil) + (setq notmuch-search-history nil) (notmuch-hello-update)) "clear") (widget-insert "\n\n") - (let ((start (point)) - (nth 0)) - (mapc (lambda (search) - (let ((widget-symbol (intern (format "notmuch-hello-search-%d" nth + (let ((start (point))) + (loop for i from 1 to notmuch-hello-recent-searches-max + for search in notmuch-search-history do + (let ((widget-symbol (intern (format "notmuch-hello-search-%d" i (set widget-symbol (widget-create 'editable-field ;; Don't let the search boxes be @@ -545,9 +528,7 @@ Complete list of currently available key bindings: (notmuch-hello-add-saved-search widget)) :notmuch-saved-search-widget widget-symbol
[PATCH 1/3] emacs: bind "s" to `notmuch-search' in notmuch-hello buffer
Before the change, "s" in notmuch-hello buffer would jump to the search box. The patch changes the binding to `notmuch-search' which is consistent with all other notmuch buffers. --- emacs/notmuch-hello.el | 19 ++- 1 files changed, 6 insertions(+), 13 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 02017ce..08fcd22 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -29,9 +29,6 @@ (declare-function notmuch-search "notmuch" (query &optional oldest-first target-thread target-line continuation)) (declare-function notmuch-poll "notmuch" ()) -(defvar notmuch-hello-search-bar-marker nil - "The position of the search bar within the notmuch-hello buffer.") - (defcustom notmuch-recent-searches-max 10 "The number of recent searches to store and display." :type 'integer @@ -321,11 +318,6 @@ should be. Returns a cons cell `(tags-per-line width)'." (widget-insert "\n")) found-target-pos)) -(defun notmuch-hello-goto-search () - "Put point inside the `search' widget." - (interactive) - (goto-char notmuch-hello-search-bar-marker)) - (defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png"))) (defun notmuch-hello-search-continuation() @@ -355,7 +347,7 @@ should be. Returns a cons cell `(tags-per-line width)'." (define-key map "G" 'notmuch-hello-poll-and-update) (define-key map (kbd "") 'widget-backward) (define-key map "m" 'notmuch-mua-new-mail) -(define-key map "s" 'notmuch-hello-goto-search) +(define-key map "s" 'notmuch-search) map) "Keymap for \"notmuch hello\" buffers.") (fset 'notmuch-hello-mode-map notmuch-hello-mode-map) @@ -468,7 +460,8 @@ Complete list of currently available key bindings: (widget-insert " messages.\n")) (let ((found-target-pos nil) - (final-target-pos nil)) + (final-target-pos nil) + (search-bar-pos)) (let* ((saved-alist ;; Filter out empty saved searches if required. (if notmuch-show-empty-saved-searches @@ -500,7 +493,7 @@ Complete list of currently available key bindings: (indent-rigidly start (point) notmuch-hello-indent))) (widget-insert "\nSearch: ") - (setq notmuch-hello-search-bar-marker (point-marker)) + (setq search-bar-pos (point-marker)) (widget-create 'editable-field ;; Leave some space at the start and end of the ;; search boxes. @@ -589,7 +582,7 @@ Complete list of currently available key bindings: (when notmuch-saved-searches (widget-insert "Edit saved searches with the `edit' button.\n")) (widget-insert "Hit RET or click on a saved search or tag name to view matching threads.\n") - (widget-insert "`=' refreshes this screen. `s' jumps to the search box. `q' to quit.\n") + (widget-insert "`=' refreshes this screen. `s' to search messages. `q' to quit.\n") (let ((fill-column (- (window-width) notmuch-hello-indent))) (center-region start (point @@ -601,7 +594,7 @@ Complete list of currently available key bindings: (widget-forward 1))) (unless (widget-at) - (notmuch-hello-goto-search + (goto-char search-bar-pos (run-hooks 'notmuch-hello-refresh-hook)) -- 1.7.8.3
on deleting messages
Hi, On Tue, 17 Jan 2012 11:01:45 -0800, Jameson Graef Rollins wrote: [ ... ] > Based on the show-mode improvements I recently sent [1], the following > patch set implements thread and message delete keys. > > This is the last I'm going to comment on this issue. If we don't want > to support this, we should put together something on the wiki that > states we don't want to support it and that users should just bind it > themselves (with a nice explanation how), so that we can try to reduce > the number of future patches on the issue. I think this is something every (new) users are expecting to have: a simple and sensible way "to list the trashed messages". So I'd go for it. /Xavier
Re: on deleting messages
On Tue, 17 Jan 2012 22:21:18 +0200, Jani Nikula wrote: > Looking at the source and history, I have to admit there has been > intent, and code, to have support for "deleted" tag. See for example > TODO or [1]. > > And I agree there has been demand for this. > > I say let's have this. +1 > But make it clear that "deleted" is just a tag; that the messages aren't > going away, not by notmuch anyway. Indeed; notmuch does not touch the content of files nor touch the existence of files. Emacs tips wiki page may contain a section user can shoot thems^H^H^H^H^H^H^H^H^H^H^H configure the actual file deleting functionality for themselves. > BR, > Jani. Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/3] emacs: bind "s" to `notmuch-search' in notmuch-hello buffer
On Tue, 17 Jan 2012 23:34:08 +0400, Dmitry Kurochkin wrote: > Before the change, "s" in notmuch-hello buffer would jump to the > search box. The patch changes the binding to `notmuch-search' which > is consistent with all other notmuch buffers. > --- > emacs/notmuch-hello.el | 19 ++- > 1 files changed, 6 insertions(+), 13 deletions(-) > > diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el > index 02017ce..08fcd22 100644 > --- a/emacs/notmuch-hello.el > +++ b/emacs/notmuch-hello.el > @@ -29,9 +29,6 @@ > (declare-function notmuch-search "notmuch" (query &optional oldest-first > target-thread target-line continuation)) > (declare-function notmuch-poll "notmuch" ()) > > -(defvar notmuch-hello-search-bar-marker nil > - "The position of the search bar within the notmuch-hello buffer.") > - > (defcustom notmuch-recent-searches-max 10 >"The number of recent searches to store and display." >:type 'integer > @@ -321,11 +318,6 @@ should be. Returns a cons cell `(tags-per-line width)'." > (widget-insert "\n")) > found-target-pos)) > > -(defun notmuch-hello-goto-search () > - "Put point inside the `search' widget." > - (interactive) > - (goto-char notmuch-hello-search-bar-marker)) After this, what would the user have to do to bind some key to put the point in the search box? If someone wants to restore old behaviour for themselves. Also, it's perhaps out of scope for this patch, but it will become more evident now that notmuch-search does not respect notmuch-search-oldest-first when called without parameters like the new 's' keybinding does. This is the same in search view. BR, Jani. > - > (defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png"))) > > (defun notmuch-hello-search-continuation() > @@ -355,7 +347,7 @@ should be. Returns a cons cell `(tags-per-line width)'." > (define-key map "G" 'notmuch-hello-poll-and-update) > (define-key map (kbd "") 'widget-backward) > (define-key map "m" 'notmuch-mua-new-mail) > -(define-key map "s" 'notmuch-hello-goto-search) > +(define-key map "s" 'notmuch-search) > map) >"Keymap for \"notmuch hello\" buffers.") > (fset 'notmuch-hello-mode-map notmuch-hello-mode-map) > @@ -468,7 +460,8 @@ Complete list of currently available key bindings: >(widget-insert " messages.\n")) > > (let ((found-target-pos nil) > - (final-target-pos nil)) > + (final-target-pos nil) > + (search-bar-pos)) >(let* ((saved-alist > ;; Filter out empty saved searches if required. > (if notmuch-show-empty-saved-searches > @@ -500,7 +493,7 @@ Complete list of currently available key bindings: > (indent-rigidly start (point) notmuch-hello-indent))) > > (widget-insert "\nSearch: ") > - (setq notmuch-hello-search-bar-marker (point-marker)) > + (setq search-bar-pos (point-marker)) > (widget-create 'editable-field > ;; Leave some space at the start and end of the > ;; search boxes. > @@ -589,7 +582,7 @@ Complete list of currently available key bindings: > (when notmuch-saved-searches > (widget-insert "Edit saved searches with the `edit' button.\n")) > (widget-insert "Hit RET or click on a saved search or tag name to view > matching threads.\n") > - (widget-insert "`=' refreshes this screen. `s' jumps to the search box. > `q' to quit.\n") > + (widget-insert "`=' refreshes this screen. `s' to search messages. `q' > to quit.\n") > (let ((fill-column (- (window-width) notmuch-hello-indent))) > (center-region start (point > > @@ -601,7 +594,7 @@ Complete list of currently available key bindings: > (widget-forward 1))) > >(unless (widget-at) > - (notmuch-hello-goto-search > + (goto-char search-bar-pos > >(run-hooks 'notmuch-hello-refresh-hook)) > > -- > 1.7.8.3 > > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch
ANNOUNCE: nottoomuch-addresses.sh 2.0
nottoomuch-addresses.sh -- email address substring matcher -- completion helper version 2.0 is available. Note to 1.92 prerelease tester(s): ignore regexp "indicator" has changed from ^re:... to ^/.../[i]. This allows this 'i' flag and trailing whitespace in re. Changes: * Added regexp-based ignores using /regexp/[i] syntax in ignore file. * Addresses 'cache' now contains all addresses and filreted (by ignore) are now in separate file. This way changes in ignore filters can be propagated to active address list. * Encoded address content is now recursively decoded. Header version was changed but this version supports "importing" data from older versions. In case you had ignore filters defined (or recursively encoded mailbox/comment names) it is recommended to rebuils address cache with /path/to/nottoomuch-addresses.sh --update --rebuild Location: http://www.iki.fi/too/nottoomuch/nottoomuch-addresses.sh Sha1sum (not md5sum): 343833fce0a30ddae859eff4a31d6153fa9c81f9 Web page: http://www.iki.fi/too/nottoomuch/nottoomuch-addresses/ Enjoy! Tomi ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v2 4/5] emacs: Use the new JSON reply format.
On Tue, 17 Jan 2012 15:53:37 -0700, Adam Wolfe Gordon wrote: > +(defun notmuch-parts-filter-by-type (parts type) > + "Return a list of message parts with the given type" > + (let (result) > +(dolist (part (append parts nil) result) > + (if (string= (cdr (assq 'content-type part)) type) > + (setq result (append result (list (cdr (assq 'content part))) > +result)) I still think that `loop' is easier to read :-) But no objection to this code. > +(defun notmuch-mua-insert-part-quoted (part) > + (let ((start (point)) > + limit) > +(insert part) > +(setq limit (point)) > +(goto-char start) > +(while (re-search-forward "\\(^\\)[^$]" limit 0) > + (replace-match "> " nil nil nil 1) > + ;; We have added two characters to the quotable region > + (setq limit (+ limit 2))) > +(set-buffer-modified-p nil))) You could use a marker for the limit, as it would then move along automagically (sorry for not noticing this last time). pgp23zzdGKFsn.pgp Description: PGP signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] Start devel directory for developer tools and documentation.
On Tue, 17 Jan 2012 08:47:51 -0400, David Bremner wrote: > From: David Bremner > pushed. I need to find time to look at the uncrustify config again before I push that. d
[PATCH 1/1] Make buttons for attachments allow viewing as well as saving
> In general, yes, I think so. A few comments on your draft below. Ok I include a newer version which I am fairly happy with but I do have some queries. > > +(defvar notmuch-show-part-button-map > > + (let ((map (make-sparse-keymap))) > > + (set-keymap-parent map button-map) > > + (define-key map "s" 'notmuch-show-part-button-save) > > + (define-key map "v" 'notmuch-show-part-button-view) > > + (define-key map "o" 'notmuch-show-part-button-interactively-view) > > +map) > > + "Submap for button commands") > > +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) > > I don't think this fset is necessary. Actually, I've never seen this > outside of the notmuch code. It looks like it does appear in code > shipped with Emacs, but only in a handful of places. All of those > places look like very old code, so maybe this was necessary once upon > a time? I have no idea on this: at the moment I have left it in as fset for keymaps seems to occur throughout notmuch (I have the fset because I copied it from somewhere). > (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) > (declare (indent 2)) > (let ((process-crypto (make-symbol "process-crypto"))) > `(let ((,process-crypto notmuch-show-process-crypto)) >(with-temp-buffer > (setq notmuch-show-process-crypto ,process-crypto) > ;; Always acquires the part via `notmuch part', even if it is > ;; available in the JSON output. > (insert (notmuch-show-get-bodypart-internal message-id nth)) > , at body I have followed the macro approach: since notmuch-show-save-part also uses it (which doesn't appear in the diff as it was unchanged). I have made all three functions use notmuch-with-temp-part-buffer. However, I used the macro exactly as you wrote it (and it seems to work) but I moderately understand why but could not justify it to someone! > (defun notmuch-show-interactively-view-part (message-id nth content-type) > (notmuch-with-temp-part-buffer message-id nth > (let ((handle (mm-make-handle (current-buffer) (list content-type > (mm-interactively-view-part handle) Emacs wants to indent the (let line level with message-id in the line above which looks odd (and makes the lines too long). Do I overrule emacs, or put message-id and nth onto a separate line or is there something better? Also note that, because of the unification with notmuch-show-save-part all three functions have to have the four arguments message-id, nth, filename and content-type (even though currently each individual function only uses three of them). However see below for another comment on this. > > +(defcustom notmuch-show-part-button-default-action > > 'notmuch-show-part-button-save > > + "Default part header button action (on ENTER or mouse click)." > > + :group 'notmuch > > + :type '(choice (const :tag "Save part" > > + notmuch-show-part-button-save) > > +(const :tag "View part" > > + notmuch-show-part-button-view) > > +(const :tag "View interactively" > > + notmuch-show-part-button-interactively-view))) > > You probably want this to be the handler function, rather than the > button function, since the interface to the button function is rather > awkward. That is, if someone wanted to plug in their own action, they > would want to define it in terms of the high-level handler interface > that you use above, rather than the low-level > button-with-magic-properties interface that Emacs forces you to use > below. I have done this. > This duplication is much worse, but also less necessary. > > (defun notmuch-show-part-button-interactively-view (&optional button) > (interactive) > (notmuch-show-part-button-internal button > #'notmuch-show-interactively-view-part)) > > (defun notmuch-show-part-button-internal (button handler) > (let ((button (or button (button-at (point) > (if button > (let ((nth (button-get button :notmuch-part))) > (if nth > (funcall handler (notmuch-show-get-message-id) nth > (button-get button :notmuch-content-type)) > (message "Not a valid part (is it a fake part?).")) Yes this is much nicer and I have done this too (modulo the extra argument mentioned above). Finally, I have discovered one bug/misfeature. If you try to "view" an attachment then it will offer to save it but will not offer a filename. If you try and save it (or use the default action) it will offer a filename as now. As far as I can see this is not fixable if I use mm-display-part: however, I could include a slight tweaked version, notmuch-show-mm-display-part say, which would fix this corner case. (Essentially, it would call notmuch-show-save-part if it failed to find a handler rather than mailcap-save-binary-file.) However, this is about 50 lines of lisp so I am not sure it is worth it. Best
on deleting messages
On Tue, 17 Jan 2012 11:01:45 -0800, Jameson Graef Rollins wrote: > Now that Austin's excellent tag exclusion patch set [0] has been pushed, > the question remains if we want to support any delete-handling key > bindings in emacs. > > Based on the show-mode improvements I recently sent [1], the following > patch set implements thread and message delete keys. > > This is the last I'm going to comment on this issue. If we don't want > to support this, we should put together something on the wiki that > states we don't want to support it and that users should just bind it > themselves (with a nice explanation how), so that we can try to reduce > the number of future patches on the issue. > > Given the number of patches we've had on this issue, though, it's clear > that a lot of people expect this functionality, so we may want to > seriously consider supporting it. Given Austin's tag exclusion stuff, > and the fact that "deleted" tags are excluded by default, we now have > the functionality that Carl originally wanted to see, so it's not so > unreasonable to support this functionality anymore. I think it's reasonable to consider having key bindings (or other special handling) for pretty much *any* tags that are special to notmuch: inbox, unread, draft, flagged, etc. (An exhaustive list should be documented somewhere.) Looking at the source and history, I have to admit there has been intent, and code, to have support for "deleted" tag. See for example TODO or [1]. And I agree there has been demand for this. I say let's have this. But make it clear that "deleted" is just a tag; that the messages aren't going away, not by notmuch anyway. BR, Jani. [1] commit 2c262042ac174d7bc96d6035ab9c88bd0abe7f35
[PATCH 1/1] Make buttons for attachments allow viewing as well as saving
> > I am happy to make that change. My original patch in the summer was more > > like that: > > id:"CALUdzSWAto+4mCUOOMk+8vFs+Pog-xUma6u-Aqx2M6-sbyQROg at mail.gmail.com" > > Is this the right id? I couldn't find it in the list archive. Sorry I messed up: it should be id:"87mxehqhbl.fsf at r102.config" However I have included my current draft along these lines. I think it is working but I am not submitting yet: just asking if this is the right idea. Best wishes Mark >From 9e52414b9871369c1cbb5c3e72d833b56bb236d4 Mon Sep 17 00:00:00 2001 From: Mark Walters Date: Sat, 14 Jan 2012 18:04:22 + Subject: [PATCH] Make buttons for attachments allow viewing as well as saving Define a keymap for attachment buttons to allow multiple actions. Define 3 possible actions: save attachment: exactly as currently, view attachment: uses mailcap entry, view attachment with user chosen program Keymap on a button is: s for save, v for view and o for view with other program. Default (i.e. enter or mouse button) is save but this is configurable in notmuch customize. One implementation detail: the view attachment function forces all attachments to be "displayed" using mailcap even if emacs could display them itself. Thus, for example, text/html appears in a browser and text/plain asks whether to save (on a standard debian setup) --- emacs/notmuch-show.el | 87 1 files changed, 79 insertions(+), 8 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 03c1f6b..2413caa 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -281,10 +281,21 @@ message at DEPTH in the current thread." (run-hooks 'notmuch-show-markup-headers-hook) (define-button-type 'notmuch-show-part-button-type - 'action 'notmuch-show-part-button-action + 'action 'notmuch-show-part-button-default + 'keymap 'notmuch-show-part-button-map 'follow-link t 'face 'message-mml) +(defvar notmuch-show-part-button-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map button-map) + (define-key map "s" 'notmuch-show-part-button-save) + (define-key map "v" 'notmuch-show-part-button-view) + (define-key map "o" 'notmuch-show-part-button-interactively-view) +map) + "Submap for button commands") +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) + (defun notmuch-show-insert-part-header (nth content-type declared-type &optional name comment) (let ((button)) (setq button @@ -299,7 +310,8 @@ message at DEPTH in the current thread." " ]") :type 'notmuch-show-part-button-type :notmuch-part nth - :notmuch-filename name)) + :notmuch-filename name + :notmuch-content-type content-type)) (insert "\n") ;; return button button)) @@ -323,6 +335,28 @@ message at DEPTH in the current thread." ;; ange-ftp, which is reasonable to use here. (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion t) +(defun notmuch-show-view-part (message-id nth content-type) + (let ((process-crypto notmuch-show-process-crypto)) +(with-temp-buffer + (setq notmuch-show-process-crypto process-crypto) + ;; Always acquires the part via `notmuch part', even if it is + ;; available in the JSON output. + (insert (notmuch-show-get-bodypart-internal message-id nth)) + ;; set mm-inlined-types to nil to force an external viewer + (let ((handle (mm-make-handle (current-buffer) (list content-type))) + (mm-inlined-types nil)) + (mm-display-part handle t) + +(defun notmuch-show-interactively-view-part (message-id nth content-type) + (let ((process-crypto notmuch-show-process-crypto)) +(with-temp-buffer + (setq notmuch-show-process-crypto process-crypto) + ;; Always acquires the part via `notmuch part', even if it is + ;; available in the JSON output. + (insert (notmuch-show-get-bodypart-internal message-id nth)) + (let ((handle (mm-make-handle (current-buffer) (list content-type + (mm-interactively-view-part handle) + (defun notmuch-show-mm-display-part-inline (msg part nth content-type) "Use the mm-decode/mm-view functions to display a part in the current buffer, if possible." @@ -1502,12 +1536,49 @@ buffer." ;; Commands typically bound to buttons. -(defun notmuch-show-part-button-action (button) - (let ((nth (button-get button :notmuch-part))) -(if nth - (notmuch-show-save-part (notmuch-show-get-message-id) nth - (button-get button :notmuch-filename)) - (message "Not a valid part (is it a fake part?)." +(defcustom notmuch-show-part-button-default-action 'notmuch-show-part-button-save + "Default part header button action (on ENTER or mouse click)." + :group 'notmuch + :type '(choice (const :tag "Save part" + notmuch-show-part-button-s
[PATCH v3] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 18 at 12:40 am: > > > Oof, sorry. Two more tweaks that I really should have caught in the > > previous version. After that this gets my automatic +1. > > Both fixed. I have also fixed the bug I mentioned (missing filename when > "view" falls back on save); I couldn't make it work with the > "no-default" option. However overriding mm-save-part with flet seems to > do the trick. Oh, indeed. I'd foolishly assumed that when mm-display-part passed the function mailcap-save-binary-file as the method to mm-display-external that it would actually *use* that function, but you're right that it uses mm-save-part. > +(defun notmuch-show-view-part (message-id nth &optional filename > content-type ) > + (notmuch-with-temp-part-buffer message-id nth > +;; set mm-inlined-types to nil to force an external viewer > +(let ((handle (mm-make-handle (current-buffer) (list content-type))) > + (mm-inlined-types nil)) > + ;; We override mm-save-part as notmuch-show-save-part is better > + ;; since it offers the filename > + (flet ((mm-save-part (&rest args) (ignore))) > + (or (mm-display-part handle) > + (notmuch-show-save-part message-id nth filename > content-type)) > > Is that a reasonable solution? It's *probably* safe to depend on the result of mm-display-part, but you can avoid the question altogether by simply calling notmuch-show-save-part from your flet mm-save-part. E.g., (flet ((mm-save-part (&rest args) (notmuch-show-save-part message-id nth filename content-type))) (mm-display-part handle)) (Yeah, flet indentation is lame.) > Best wishes > > Mark
[PATCH] fix .gitignore for gzipped man pages
--- .gitignore |1 - man/.gitignore |2 ++ 2 files changed, 2 insertions(+), 1 deletions(-) create mode 100644 man/.gitignore diff --git a/.gitignore b/.gitignore index d64ec9f..d428290 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ tags /notmuch notmuch.sym notmuch-shared -notmuch.1.gz libnotmuch.so* libnotmuch*.dylib *.[ao] diff --git a/man/.gitignore b/man/.gitignore new file mode 100644 index 000..26ead20 --- /dev/null +++ b/man/.gitignore @@ -0,0 +1,2 @@ +# ignore gzipped man pages +*.[0-9].gz -- 1.7.5.4
[PATCH v2] emacs: add invisible dot instead of space at the end of notmuch-hello search box
This makes `show-trailing-whitespace' happy, i.e. it does not mark the whole search box line as trailing spaces. Since the dot is invisible, this change makes no visible difference for `notmuch-hello'. --- emacs/notmuch-hello.el |9 ++--- 1 files changed, 6 insertions(+), 3 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 02017ce..38846ef 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -508,9 +508,12 @@ Complete list of currently available key bindings: (length "Search: "))) :action (lambda (widget &rest ignore) (notmuch-hello-search (widget-value widget - ;; add an invisible space to make `widget-end-of-line' ignore - ;; trailine spaces in the search widget field - (widget-insert " ") + ;; Add an invisible dot to make `widget-end-of-line' ignore + ;; trailing spaces in the search widget field. A dot is used + ;; instead of a space to make `show-trailing-whitespace' + ;; happy, i.e. avoid it marking the whole line as trailing + ;; spaces. + (widget-insert ".") (put-text-property (1- (point)) (point) 'invisible t) (widget-insert "\n") -- 1.7.8.3
Partial words on notmuch search?
On Mon, 16 Jan 2012 21:34:31 -0500, Austin Clements wrote: > Quoth Andrei Popescu on Jan 16 at 10:21 pm: > > This is also interesting: > > $ notmuch count 'debian' > > 65888 > > $ notmuch count 'dEbian' > > 65888 > > $ notmuch count 'Debian' > > 65887 > > The first two will match stemmed versions of "debian" such as > "debian's" and "debianed". However, starting a term with a capital > letter suppresses stemming (because it suggests that it's a name, > which you wouldn't want to modify), so your last query matches only > the term "debian". This is probably documented somewhere, though I > don't know where. Interesting. Is this done when adding the terms to the database, or when searching? I presume the latter. How much control does notmuch have over this? The assumption that one wouldn't want to have stemming for names is very much language dependent. [1] BR, Jani. [1] http://en.wikipedia.org/wiki/Finnish_noun_cases (the same works for names as well as nouns)
Infinite loop in emacs interface
On Tue, 17 Jan 2012 12:37:52 -0500, Aaron Ecay wrote: > After converting the mbox file to Maildir and adding it to my mailstore, > I cannot reproduce the loop. (The versions of notmuch and emacs I used > are close to the ones you have, but not an exact match, so it may be > something subtle about those versions. I can investigate > more carefully if it seems like this is the case.) Hi Aaron, That's a pity. I am using Julien Danjou's emacs-snapshot package for debian and actually I only noticed the infinite loop on this thread after restarting emacs some unknown time after the package was upgraded. The package was upgraded from 20120105 to 20120111. I haven't been using this snapshot of emacs for very long, so possibly the problem might occur with other threads. To test this thread, I copied it out of my maildirs with mutt, deleted the original messages, ran "notmuch new", copied the mbox thread back into my maildirs, then ran "notmuch new" again, and the problem was still there. > If you do: > M-x set-variable RET debug-on-quit RET t RET > then trigger the loop and press C-g, you should get a buffer showing a > backtrace of the lisp stack. What does that say? I copied 4 backtraces which appear below. I pressed the 'a' key when viewing the thread, then C-g. They were run with notmuch git commit efa5d6cb32. Since then I went back to 0.11 because it seems like the reply function stopped working. Cheers, Rodney Debugger entered--Lisp error: (quit) mapc((lambda (del-tag) (setq result-tags (delete del-tag result-tags))) ("inbox")) (let ((result-tags (copy-sequence current-tags))) (mapc (lambda (del-tag) (setq result-tags (delete del-tag result-tags))) del-tags) result-tags) notmuch-show-del-tags-worker(nil ("inbox")) (let* ((current-tags (notmuch-show-get-tags)) (new-tags (notmuch-show-del-tags-worker current-tags toremove))) (unless (equal current-tags new-tags) (apply (quote notmuch-tag) (notmuch-show-get-message-id) (mapcar (lambda (s) (concat "-" s)) toremove)) (notmuch-show-set-tags new-tags))) notmuch-show-remove-tag("inbox") (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next (while (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next) (catch (quote --cl-block-nil--) (while (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next) nil) (cl-block-wrapper (catch (quote --cl-block-nil--) (while (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next) nil)) (block nil (while (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next) nil) (loop do (notmuch-show-remove-tag "inbox") until (not (notmuch-show-goto-message-next))) notmuch-show-archive-thread-internal(t) notmuch-show-archive-thread() call-interactively(notmuch-show-archive-thread nil nil) Debugger entered--Lisp error: (quit) notmuch-show-move-to-message-top() (save-excursion (notmuch-show-move-to-message-top) (get-text-property (point) :notmuch-message-properties)) notmuch-show-get-message-properties() (or props (notmuch-show-get-message-properties)) (let ((props (or props (notmuch-show-get-message-properties (plist-get props prop)) notmuch-show-get-prop(:tags) notmuch-show-get-tags() (let* ((current-tags (notmuch-show-get-tags)) (new-tags (notmuch-show-del-tags-worker current-tags toremove))) (unless (equal current-tags new-tags) (apply (quote notmuch-tag) (notmuch-show-get-message-id) (mapcar (lambda (s) (concat "-" s)) toremove)) (notmuch-show-set-tags new-tags))) notmuch-show-remove-tag("inbox") (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next (while (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next) (catch (quote --cl-block-nil--) (while (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next) nil) (cl-block-wrapper (catch (quote --cl-block-nil--) (while (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next) nil)) (block nil (while (progn (notmuch-show-remove-tag "inbox") (not (not (notmuch-show-goto-message-next) nil) (loop do (notmuch-show-remove-tag "inbox") until (not (notmuch-show-goto-message-next))) notmuch-show-archive-thread-internal(t) notmuch-show-archive-thread() call-interactively(notmuch-show-archive-thread nil nil) Debugger entered--Lisp error: (quit) notmuch-show-move-to-message-top() (save-excursion (notmuch-show-move-to-message-top) (get-text-property (point) :notmuch-message-properties)) notmuch-show-get-message-properties() (or props (notmuch-show-get-message-properties)) (let ((props (or props (notmuch-show-get-message-properties (plist-get props prop)) notmuch-show-get-prop(:tags) notmuch-show-get-tags() (let* ((current-tags (notmuch-show-get-tags)) (new-tags (notmuch-show-del-tags-worker curre
Re: [PATCH] Start devel directory for developer tools and documentation.
On Tue, 17 Jan 2012 08:47:51 -0400, David Bremner wrote: > From: David Bremner > pushed. I need to find time to look at the uncrustify config again before I push that. d ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v3] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 17 at 11:44 pm: > Define a keymap for attachment buttons to allow multiple actions. > Define 3 possible actions: > save attachment: exactly as currently, > view attachment: uses mailcap entry, > view attachment with user chosen program > > Keymap on a button is: s for save, v for view and o for view with > other program. Default (i.e. enter or mouse button) is save but this > is configurable in notmuch customize. > > One implementation detail: the view attachment function forces all > attachments to be "displayed" using mailcap even if emacs could > display them itself. Thus, for example, text/html appears in a browser > and text/plain asks whether to save (on a standard debian setup) Oof, sorry. Two more tweaks that I really should have caught in the previous version. After that this gets my automatic +1. > --- > emacs/notmuch-show.el | 106 > ++--- > 1 files changed, 82 insertions(+), 24 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 03c1f6b..0aaaf79 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -281,10 +281,21 @@ message at DEPTH in the current thread." > (run-hooks 'notmuch-show-markup-headers-hook) > > (define-button-type 'notmuch-show-part-button-type > - 'action 'notmuch-show-part-button-action > + 'action 'notmuch-show-part-button-default > + 'keymap 'notmuch-show-part-button-map >'follow-link t >'face 'message-mml) > > +(defvar notmuch-show-part-button-map > + (let ((map (make-sparse-keymap))) > + (set-keymap-parent map button-map) > + (define-key map "s" 'notmuch-show-part-button-save) > + (define-key map "v" 'notmuch-show-part-button-view) > + (define-key map "o" 'notmuch-show-part-button-interactively-view) Indentation. > +map) > + "Submap for button commands") > +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) > + > (defun notmuch-show-insert-part-header (nth content-type declared-type > &optional name comment) >(let ((button)) > (setq button > @@ -299,29 +310,48 @@ message at DEPTH in the current thread." > " ]") > :type 'notmuch-show-part-button-type > :notmuch-part nth > -:notmuch-filename name)) > +:notmuch-filename name > +:notmuch-content-type content-type)) > (insert "\n") > ;; return button > button)) > > ;; Functions handling particular MIME parts. > > -(defun notmuch-show-save-part (message-id nth &optional filename) > - (let ((process-crypto notmuch-show-process-crypto)) > -(with-temp-buffer > - (setq notmuch-show-process-crypto process-crypto) > - ;; Always acquires the part via `notmuch part', even if it is > - ;; available in the JSON output. > - (insert (notmuch-show-get-bodypart-internal message-id nth)) > - (let ((file (read-file-name > -"Filename to save as: " > -(or mailcap-download-directory "~/") > -nil nil > -filename))) > - ;; Don't re-compress .gz & al. Arguably we should make > - ;; `file-name-handler-alist' nil, but that would chop > - ;; ange-ftp, which is reasonable to use here. > - (mm-write-region (point-min) (point-max) file nil nil nil > 'no-conversion t) > +(defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) > + (declare (indent 2)) > + (let ((process-crypto (make-symbol "process-crypto"))) > +`(let ((,process-crypto notmuch-show-process-crypto)) > + (with-temp-buffer > + (setq notmuch-show-process-crypto ,process-crypto) > + ;; Always acquires the part via `notmuch part', even if it is > + ;; available in the JSON output. > + (insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) > + , at body > + > +(defun notmuch-show-save-part (message-id nth &optional filename > content-type) > + (notmuch-with-temp-part-buffer message-id nth > +(let ((file (read-file-name > + "Filename to save as: " > + (or mailcap-download-directory "~/") > + nil nil > + filename))) > + ;; Don't re-compress .gz & al. Arguably we should make > + ;; `file-name-handler-alist' nil, but that would chop > + ;; ange-ftp, which is reasonable to use here. > + (mm-write-region (point-min) (point-max) file nil nil nil > 'no-conversion t > + > +(defun notmuch-show-view-part (message-id nth &optional filename > content-type ) > + (notmuch-with-temp-part-buffer message-id nth > +;; set mm-inlined-types to nil to force an external viewer > +(let ((handle (mm-make-handle (current-buffer) (list content-type))) > + (mm-inlined-types nil)) > + (mm-display-part handle t > + > +(defun notmuch-show-interactively-view-part (message-id nth &optional > filename content-type) > + (notmuch-with-temp-part-buffer me
[PATCH 1/3] test: Don't return the result of checking for running emacs to the tester.
On Tue, 17 Jan 2012 14:37:52 +, David Edmondson wrote: > (And for the list...) > > On Tue, 17 Jan 2012 18:20:04 +0400, Dmitry Kurochkin gmail.com> wrote: > > Can you please elaborate why this is needed? > > This code: > > # wait until the emacs server is up > until test_emacs '()' 2>/dev/null; do > sleep 1 > done > > outputs 'nil', so the first caller to test_emacs has 'nil\n' prepended > to their expected output. Thanks. Would be nice to have this explained in the commit message. No need to resend just because of this though. Regards, Dmitry
[PATCH 2/3] test: Add `test_emacs_expect_t'.
On Tue, 17 Jan 2012 14:35:07 +, David Edmondson wrote: > On Tue, 17 Jan 2012 18:26:41 +0400, Dmitry Kurochkin gmail.com> wrote: > > Sorry, I still do not understand why we can not implement > > test_emacs_expect_t() like: > > > > result=${test_emacs $@} > > test_expect_equal $result t > > > > Can you please explain? > > In the failure case test_expect_equal does: > > test_failure_ "$test_subtest_name" "$(diff -u $testname.expected > $testname.output)" > > that diff output is not useful here, because the test harness doesn't > have any expected output other than `t' with which to diff the actual > output. > > The emacs-address-cleaning test shows how we will provide expected > vs. actual output directly from within emacs, making it easier for the > developer to figure out what went wrong. Thanks for the explanation. Regards, Dmitry
[PATCH 2/3] test: Add `test_emacs_expect_t'.
On Tue, 17 Jan 2012 14:07:03 +, David Edmondson wrote: > Add a new test function to allow simpler testing of emacs > functionality. > > `test_emacs_expect_t' takes one argument - a list expression to > evaluate. The test passes if the expression returns `t', otherwise it > fails and the output is reported to the tester. > --- > > Re-worked as Dmitry suggested. > > test/README |8 > test/emacs-test-functions.sh |9 + > test/notmuch-test|1 + > test/test-lib.sh | 33 + > 4 files changed, 51 insertions(+), 0 deletions(-) > create mode 100755 test/emacs-test-functions.sh > > diff --git a/test/README b/test/README > index bde6db0..9dbe2ee 100644 > --- a/test/README > +++ b/test/README > @@ -189,6 +189,14 @@ library for your script to use. > tests that may run in the same Emacs instance. Use `let' instead > so the scope of the changed variables is limited to a single test. > > + test_emacs_expect_t > + > + This function executes the provided emacs lisp script within > + emacs in a manner similar to 'test_emacs'. The expressions should > + return the value `t' to indicate that the test has passed. If the > + test does not return `t' then it is considered failed and all data > + returned by the test is reported to the tester. > + > test_done > > Your test script must have test_done at the end. Its purpose > diff --git a/test/emacs-test-functions.sh b/test/emacs-test-functions.sh > new file mode 100755 > index 000..0e1f9fc > --- /dev/null > +++ b/test/emacs-test-functions.sh > @@ -0,0 +1,9 @@ > +#!/usr/bin/env bash > + > +test_description="emacs test function sanity" > +. test-lib.sh > + > +test_begin_subtest "emacs test function sanity" > +test_emacs_expect_t 't' > + > +test_done > diff --git a/test/notmuch-test b/test/notmuch-test > index 6a99ae3..d034f99 100755 > --- a/test/notmuch-test > +++ b/test/notmuch-test > @@ -52,6 +52,7 @@ TESTS=" >python >hooks >argument-parsing > + emacs-test-functions.sh > " > TESTS=${NOTMUCH_TESTS:=$TESTS} > > diff --git a/test/test-lib.sh b/test/test-lib.sh > index 7c9ce24..4b05760 100644 > --- a/test/test-lib.sh > +++ b/test/test-lib.sh > @@ -503,6 +503,39 @@ test_expect_equal_file () > fi > } > > +test_emacs_expect_t () { > + test "$#" = 1 || error "bug in the test script: not 1 parameter to > test_emacs_expect_t" > + > + # Run the test. > + if ! test_skip "$test_subtest_name" > + then > + # We cannot call 'test_emacs' in a subshell, because > + # the setting of EMACS_SERVER would not persist > + # throughout a sequence of tests, so we use a > + # temporary file. > + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi > + output="$tmp/test_emacs_output.$$" > + test_emacs "$1" > "${output}" > + result=$(cat "${output}") > + rm -f "${output}" > + fi > + > + # Restore state after the test. > + exec 1>&6 2>&7 # Restore stdout and stderr > + inside_subtest= > + > + # Report success/failure. > + if ! test_skip "$test_subtest_name" > + then > + if [ "$result" == t ] > + then > + test_ok_ "$test_subtest_name" > + else > + test_failure_ "$test_subtest_name" "$(eval printf > ${result})" > + fi > + fi > +} > + Sorry, I still do not understand why we can not implement test_emacs_expect_t() like: result=${test_emacs $@} test_expect_equal $result t Can you please explain? Regards, Dmitry > NOTMUCH_NEW () > { > notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found > [0-9]* total file' > -- > 1.7.7.3 > > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] Start devel directory for developer tools and documentation.
Quoth David Bremner on Jan 17 at 8:47 am: > From: David Bremner > > We had a lot of back and forth about the name of this directory, but > nothing very conclusive. In the end, I just chose "devel" just to move > on. LGTM.
[PATCH 1/3] test: Don't return the result of checking for running emacs to the tester.
Can you please elaborate why this is needed? Regards, Dmitry
Infinite loop in emacs interface
Hi, Emacs notmuch is a really excellent mail program. But today I got an infinite loop in emacs 24.0.92.1 with notmuch (0.11 and master). It only happens when viewing a certain thread. There seem to be 2 problems: 1. the n and p keys (notmuch-show-{next,previous}-open-message) can't get past the second message in the thread. 2. when using the 'a' key (notmuch-show-archive-thread), it will loop, probably because it can't get past the second message. The thread is attached. Cheers, Rodney -- next part -- A non-text attachment was scrubbed... Name: loop-thread.gz Type: application/octet-stream Size: 6912 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/a28ae422/attachment.obj>
[PATCH 1/2] emacs: add invisible dot instead of space at the end of notmuch-hello search box
On Tue, 17 Jan 2012 14:08:58 +, David Edmondson wrote: > On Tue, 17 Jan 2012 17:24:45 +0400, Dmitry Kurochkin gmail.com> wrote: > > This makes `show-trailing-whitespace' happy, i.e. it does not mark the > > whole search box line as trailing spaces. > > Why should `whitespace-mode' be active in `notmuch-hello' buffers? I do not say that it should be active in notmuch-hello. For me `show-trailing-whitespace' is activated everywhere with some exceptions. Notmuch-hello is one of these exceptions. This change make it one step closer to removing the exception. Regards, Dmitry
[PATCH 1/1] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 17 at 10:27 pm: > > (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) > > (declare (indent 2)) > > (let ((process-crypto (make-symbol "process-crypto"))) > > `(let ((,process-crypto notmuch-show-process-crypto)) > >(with-temp-buffer > > (setq notmuch-show-process-crypto ,process-crypto) > > ;; Always acquires the part via `notmuch part', even if it is > > ;; available in the JSON output. > > (insert (notmuch-show-get-bodypart-internal message-id nth)) > > , at body > > I have followed the macro approach: since notmuch-show-save-part also > uses it (which doesn't appear in the diff as it was unchanged). I have > made all three functions use notmuch-with-temp-part-buffer. However, I > used the macro exactly as you wrote it (and it seems to work) but I > moderately understand why but could not justify it to someone! Oops, actually there was a bug in that macro. It should have been (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) (declare (indent 2)) (let ((process-crypto (make-symbol "process-crypto"))) `(let ((,process-crypto notmuch-show-process-crypto)) (with-temp-buffer (setq notmuch-show-process-crypto ,process-crypto) ;; Always acquires the part via `notmuch part', even if it is ;; available in the JSON output. (insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) , at body The only difference is on the "insert" line. Sorry about that. I don't know how familiar you are with syntactic abstraction, so here's a top-down explanation. A macro is like the compile-time equivalent of a function: rather than the arguments and return being values that result from evaluation, they are pieces of code, the body of the macro executes at compile time instead of at run time, and the compiler replaces the invocation of the macro with the code that the macro returns. This is not unlike a C/C++ macro, but the implementation of the macro is regular Lisp code that runs at compile time and the code is represented as S-expressions rather than strings (one beauty of Lisp is that the representation of code and data is the same). The above macro returns the code starting after the "`" (pronounced quasiquote), so that's what invocations of the macro get replaced with. Quasiquote (like quote) inhibits the evaluation of what follows it and results in the code as data, rather than the result of evaluating the code. Unlike quote, quasiquote lets you jump back into the evaluator using "," and ",@", so it's great for piecing together code from a template, which is what macros spend most of their time doing. The "declare" is simply a specification to emacs-lisp-mode about how to indent uses of this macro. The "make-symbol" is necessary to avoid conflicting with variable names that may appear in the code that uses this macro (since the invoking code and the code returned by the macro will be interleaved, you have to worry about variable conflicts). > > (defun notmuch-show-interactively-view-part (message-id nth content-type) > > (notmuch-with-temp-part-buffer message-id nth > > (let ((handle (mm-make-handle (current-buffer) (list content-type > > (mm-interactively-view-part handle) > > Emacs wants to indent the (let line level with message-id in the line > above which looks odd (and makes the lines too long). Do I overrule > emacs, or put message-id and nth onto a separate line or is there > something better? If you evaluate the defmacro, it'll pick up on that declare line at the beginning of it and indent this correctly. > Also note that, because of the unification with notmuch-show-save-part > all three functions have to have the four arguments message-id, nth, > filename and content-type (even though currently each individual > function only uses three of them). However see below for another comment > on this. That makes sense. > > > +(defcustom notmuch-show-part-button-default-action > > > 'notmuch-show-part-button-save > > > + "Default part header button action (on ENTER or mouse click)." > > > + :group 'notmuch > > > + :type '(choice (const :tag "Save part" > > > + notmuch-show-part-button-save) > > > + (const :tag "View part" > > > + notmuch-show-part-button-view) > > > + (const :tag "View interactively" > > > + notmuch-show-part-button-interactively-view))) > > > > You probably want this to be the handler function, rather than the > > button function, since the interface to the button function is rather > > awkward. That is, if someone wanted to plug in their own action, they > > would want to define it in terms of the high-level handler interface > > that you use above, rather than the low-level > > button-with-magic-properties interface that Emacs forces you to use > > below. > > I have done this. > > > This duplicati
[PATCH 1/2] uncrustify.cfg: initial support for notmuch coding style
On Tue, 10 Jan 2012 08:07:07 -0400, David Bremner wrote: > From: David Bremner > > Uncrustify is a free (as in GPL2+) tool that indents and beautifies > C/C++ code. It is similar to GNU indent in functionality although > probably more configurable (in fairness, indent has better > documentation). Uncrustify does not have the indent mis-feature of > needing to have every typedef'ed type defined in the > configuration (even standard types like size_t). > > This configuration starts with the linux-kernel style from the > uncrustify config, disables aggressive re-indenting of structs, > and fine tunes the handling 'else' and braces. > > In an ideal situation, running uncrustify on notmuch code would be > NOP; currently this is not true for all files because 1) the > configuration is not perfect 2) the coding style of notmuch is not > completely consistent; in particular the treatment of braces after > e.g. for (_) is not consistent. > --- > uncrustify.cfg | 99 > Good stuff: while testing I did these changes: --- uncrustify.cfg0 2012-01-17 16:20:18.686489325 +0200 +++ uncrustify.cfg 2012-01-17 17:02:39.664512588 +0200 @@ -21 +20,0 @@ - @@ -60,0 +60,4 @@ +sp_before_ptr_star = force +sp_between_ptr_star= remove +sp_after_ptr_star = remove + @@ -62 +65 @@ -sp_sizeof_paren= remove# "sizeof (int)" vs "sizeof(int)" +sp_sizeof_paren= force # "sizeof (int)" vs "sizeof(int)" @@ -93 +96 @@ -align_right_cmt_span = 0 +align_right_cmt_span = 1 # 0 -> 1 -- just to fix some alignments The first three: +sp_before_ptr_star = force +sp_between_ptr_star= remove +sp_after_ptr_star = remove are important and pretty uncontroversial; fixes more than breaks (if anything) +sp_sizeof_paren= force # "sizeof (int)" vs "sizeof(int)" adds space after sizeof; do 'grep sizeof *.c' and you see this is prevalent in the code. I think this is the right way (especially) as sizeof is an operator... +align_right_cmt_span = 1 # 0 -> 1 -- just to fix some alignments This fixes, for example, comment alignment in g_mime_filter_headers_get_type() (in gmime-filter-headers.c). I also tested using this change: @@ -66 +69 @@ -sp_after_cast = force # "(int) a" vs "(int)a" +sp_after_cast = remove# "(int) a" vs "(int)a" But this changes basically all the casts in code not to have space after cast. I'd prefer this but it is not the prevalent style. Note that just running uncrustify --replace -c uncrustify.cfg notmuch-show.c does this: format_part_start_json (unused (GMimeObject * part), I.e. there is space after '*' and 'part'. This is probably the old known problem: uncrustify thinks unused is function which takes int parameter and there is multiplication to be done. If there is way to tell uncrustify that GMimeObject is type then this change would not take place. I run for f in *.c; do uncrustify --replace -c uncrustify.cfg $f; done in notmuch source root directory and the output is pretty good, in addition to the above problem there are these format_* structure initialization changes: Quoting Austin: "The good news is that that structure is on its way out." So, it would be good to get devel/uncrustify.cfg in place so developers can start playing with it... Tomi
Notmuch fails to build with gmime 2.6.4
Quoth hollunder at lavabit.com on Jan 17 at 4:24 pm: > Hi there. I've seen gmime related discussion but it's hard to follow using > a web interface, so here's my bug report. There's a GMime 2.6 support patch that will probably make it into the master branch in the next day or two. Sorry for the inconvenience.
Improving notmuch query documentation [was: Re: Partial words on notmuch search?]
Quoth Andrei Popescu on Jan 18 at 12:14 am: > On Lu, 16 ian 12, 21:34:31, Austin Clements wrote: > > Quoth Andrei Popescu on Jan 16 at 10:21 pm: > > > Where can I read more about this? (except the source :) > > > > Most of this is in the Xapian query syntax document you found. Really > > we ought to beef-up Notmuch's query syntax documentation. > > If I get around to write something myself where do you suggest I should > start, the wiki or the manpage? Probably expanding man/man7/notmuch-search-terms.7 would be the way to go.
Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 18 at 12:40 am: > > > Oof, sorry. Two more tweaks that I really should have caught in the > > previous version. After that this gets my automatic +1. > > Both fixed. I have also fixed the bug I mentioned (missing filename when > "view" falls back on save); I couldn't make it work with the > "no-default" option. However overriding mm-save-part with flet seems to > do the trick. Oh, indeed. I'd foolishly assumed that when mm-display-part passed the function mailcap-save-binary-file as the method to mm-display-external that it would actually *use* that function, but you're right that it uses mm-save-part. > +(defun notmuch-show-view-part (message-id nth &optional filename > content-type ) > + (notmuch-with-temp-part-buffer message-id nth > +;; set mm-inlined-types to nil to force an external viewer > +(let ((handle (mm-make-handle (current-buffer) (list content-type))) > + (mm-inlined-types nil)) > + ;; We override mm-save-part as notmuch-show-save-part is better > + ;; since it offers the filename > + (flet ((mm-save-part (&rest args) (ignore))) > + (or (mm-display-part handle) > + (notmuch-show-save-part message-id nth filename > content-type)) > > Is that a reasonable solution? It's *probably* safe to depend on the result of mm-display-part, but you can avoid the question altogether by simply calling notmuch-show-save-part from your flet mm-save-part. E.g., (flet ((mm-save-part (&rest args) (notmuch-show-save-part message-id nth filename content-type))) (mm-display-part handle)) (Yeah, flet indentation is lame.) > Best wishes > > Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6
Quoth Thomas Jost on Jan 17 at 11:50 am: > There are lots of API changes in gmime 2.6 crypto handling. By adding > preprocessor directives, it is however possible to add gmime 2.6 compatibility > while preserving compatibility with gmime 2.4 too. > > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info". > > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test > fails (signature verification with signer key unavailable) but this will be > hard > to fix since the new API does not report the reason why a signature > verification > fails (other than the human-readable error message). > --- > mime-node.c | 56 ++-- > notmuch-client.h | 28 +++- > notmuch-reply.c |7 > notmuch-show.c | 95 > ++ > show-message.c |4 ++ > 5 files changed, 185 insertions(+), 5 deletions(-) > > diff --git a/mime-node.c b/mime-node.c > index d26bb44..e575e1c 100644 > --- a/mime-node.c > +++ b/mime-node.c > @@ -33,7 +33,11 @@ typedef struct mime_node_context { > GMimeMessage *mime_message; > > /* Context provided by the caller. */ > +#ifdef GMIME_26 > +GMimeCryptoContext *cryptoctx; > +#else > GMimeCipherContext *cryptoctx; > +#endif > notmuch_bool_t decrypt; > } mime_node_context_t; > > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res) > > notmuch_status_t > mime_node_open (const void *ctx, notmuch_message_t *message, > - GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt, > - mime_node_t **root_out) > +#ifdef GMIME_26 > + GMimeCryptoContext *cryptoctx, > +#else > + GMimeCipherContext *cryptoctx, > +#endif > + notmuch_bool_t decrypt, mime_node_t **root_out) > { > const char *filename = notmuch_message_get_filename (message); > mime_node_context_t *mctx; > @@ -112,12 +120,21 @@ DONE: > return status; > } > > +#ifdef GMIME_26 > +static int > +_signature_list_free (GMimeSignatureList **proxy) > +{ > +g_object_unref (*proxy); > +return 0; > +} > +#else > static int > _signature_validity_free (GMimeSignatureValidity **proxy) > { > g_mime_signature_validity_free (*proxy); > return 0; > } > +#endif > > static mime_node_t * > _mime_node_create (const mime_node_t *parent, GMimeObject *part) > @@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, > GMimeObject *part) > GMimeMultipartEncrypted *encrypteddata = > GMIME_MULTIPART_ENCRYPTED (part); > node->decrypt_attempted = TRUE; > +#ifdef GMIME_26 > + GMimeDecryptResult *decrypt_result = NULL; Reading through the GMime code, it looks like we do have to unref decrypt_result. I think this is easy, though. Right after you call g_mime_decrypt_result_get_signatures below, do: g_object_ref (node->sig_list); g_object_unref (decrypt_result); > + node->decrypted_child = g_mime_multipart_encrypted_decrypt > + (encrypteddata, node->ctx->cryptoctx, &decrypt_result, &err); > +#else > node->decrypted_child = g_mime_multipart_encrypted_decrypt > (encrypteddata, node->ctx->cryptoctx, &err); > +#endif > if (node->decrypted_child) { > - node->decrypt_success = node->verify_attempted = TRUE; > + node->decrypt_success = node->verify_attempted =TRUE; Whitespace. (There should be no diff on the above line) > +#ifdef GMIME_26 > + /* This may be NULL if the part is not signed. */ > + node->sig_list = g_mime_decrypt_result_get_signatures > (decrypt_result); > +#else > node->sig_validity = > g_mime_multipart_encrypted_get_signature_validity (encrypteddata); > +#endif > } else { > fprintf (stderr, "Failed to decrypt part: %s\n", >(err ? err->message : "no error explanation given")); > @@ -182,6 +210,16 @@ _mime_node_create (const mime_node_t *parent, > GMimeObject *part) >"(must be exactly 2)\n", >node->nchildren); > } else { > +#ifdef GMIME_26 > + GMimeSignatureList *sig_list = g_mime_multipart_signed_verify > + (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, &err); > + node->verify_attempted = TRUE; > + node->sig_list = sig_list; Just a nit. This could be node->sig_list = g_mime_multipart_signed_verify ( ... ) To me, the local variable just makes this code more verbose without adding anything. Up to you. > + > + if (!sig_list) > + fprintf (stderr, "Failed to verify signed part: %s\n", > + (err ? err->message : "no error explanation given")); > +#else > /* For some reason the GMimeSignatureValidity returned >* here is not a const (in
[PATCH 2/2] emacs: fix typo in notmuch-hello
--- emacs/notmuch-hello.el |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index a71f3ce..aed1fb3 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -509,7 +509,7 @@ Complete list of currently available key bindings: :action (lambda (widget &rest ignore) (notmuch-hello-search (widget-value widget ;; add an invisible dot to make `widget-end-of-line' ignore - ;; trailine spaces in the search widget field + ;; trailing spaces in the search widget field (widget-insert ".") (put-text-property (1- (point)) (point) 'invisible t) (widget-insert "\n") -- 1.7.8.3
[PATCH 1/2] emacs: add invisible dot instead of space at the end of notmuch-hello search box
This makes `show-trailing-whitespace' happy, i.e. it does not mark the whole search box line as trailing spaces. Since the dot is invisible, this change makes no visible difference for `notmuch-hello'. --- emacs/notmuch-hello.el |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el index 02017ce..a71f3ce 100644 --- a/emacs/notmuch-hello.el +++ b/emacs/notmuch-hello.el @@ -508,9 +508,9 @@ Complete list of currently available key bindings: (length "Search: "))) :action (lambda (widget &rest ignore) (notmuch-hello-search (widget-value widget - ;; add an invisible space to make `widget-end-of-line' ignore + ;; add an invisible dot to make `widget-end-of-line' ignore ;; trailine spaces in the search widget field - (widget-insert " ") + (widget-insert ".") (put-text-property (1- (point)) (point) 'invisible t) (widget-insert "\n") -- 1.7.8.3
[PATCH 2/4] test: Add address cleaning tests.
On Tue, 17 Jan 2012 12:52:26 +, David Edmondson wrote: > Including some more test framework in test-lib.el. > --- > test/address-cleaning.el | 29 + > test/address-cleaning.sh | 11 +++ > test/notmuch-test|1 + > test/test-lib.el | 29 + > 4 files changed, 70 insertions(+), 0 deletions(-) > create mode 100644 test/address-cleaning.el > create mode 100755 test/address-cleaning.sh > Since test/ directory is used for all kind of tests not just Emacs UI-specific, so I think address-cleaning.* files should be emacs-address-cleaning. Regards, Dmitry > diff --git a/test/address-cleaning.el b/test/address-cleaning.el > new file mode 100644 > index 000..59e8d92 > --- /dev/null > +++ b/test/address-cleaning.el > @@ -0,0 +1,29 @@ > +(defun notmuch-test-address-cleaning-1 () > + (notmuch-test-compare (notmuch-show-clean-address "dme at dme.org") > + "dme at dme.org")) > + > +(defun notmuch-test-address-cleaning-2 () > + (let* ((input '("foo at bar.com" > + "" > + "Foo Bar " > + "foo at bar.com " > + "\"Foo Bar\" ")) > + (expected '("foo at bar.com" > + "foo at bar.com" > + "Foo Bar " > + "foo at bar.com" > + "Foo Bar ")) > + (output (mapcar #'notmuch-show-clean-address input))) > +(notmuch-test-compare output expected))) > + > +(defun notmuch-test-address-cleaning-3 () > + (let* ((input '("?? " > + "foo (at home) " > + "foo [at home] " > + "Foo Bar")) > + (expected '("?? " > + "foo (at home) " > + "foo [at home] " > + "Foo Bar")) > + (output (mapcar #'notmuch-show-clean-address input))) > +(notmuch-test-compare output expected))) > diff --git a/test/address-cleaning.sh b/test/address-cleaning.sh > new file mode 100755 > index 000..7ec011a > --- /dev/null > +++ b/test/address-cleaning.sh > @@ -0,0 +1,11 @@ > +#!/usr/bin/env bash > + > +test_description="emacs address cleaning" > +. test-lib.sh > + > +for i in 1 2 3; do > +test_emacs_expect_t "notmuch-test-address-clean-$i" \ > +'(load "address-cleaning.el") (notmuch-test-address-cleaning-'$i')' > +done > + > +test_done > diff --git a/test/notmuch-test b/test/notmuch-test > index d034f99..7768c32 100755 > --- a/test/notmuch-test > +++ b/test/notmuch-test > @@ -53,6 +53,7 @@ TESTS=" >hooks >argument-parsing >emacs-test-functions.sh > + address-cleaning.sh > " > TESTS=${NOTMUCH_TESTS:=$TESTS} > > diff --git a/test/test-lib.el b/test/test-lib.el > index 3b817c3..cf8a46d 100644 > --- a/test/test-lib.el > +++ b/test/test-lib.el > @@ -20,6 +20,8 @@ > ;; > ;; Authors: Dmitry Kurochkin > > +(require 'cl);; This code is generally used uncompiled. > + > ;; `read-file-name' by default uses `completing-read' function to read > ;; user input. It does not respect `standard-input' variable which we > ;; use in tests to provide user input. So replace it with a plain > @@ -76,3 +78,30 @@ nothing." > > (add-hook-counter 'notmuch-hello-mode-hook) > (add-hook-counter 'notmuch-hello-refresh-hook) > + > +;; Functions to help when writing tests: > + > +(defun notmuch-test-reporter (output expected) > + "Report that the `output' does not match the `expected' result." > + (concat "Expect:\t" (prin1-to-string expected) "\n" > + "Output:\t" (prin1-to-string output) "\n")) > + > +(defun notmuch-test-unsimilar (output expected) > + "`output' and `expected' are dissimilar. Show a summary of > +the differences, ignoring similarities." > + (cond ((and (listp output) > + (listp expected)) > + (apply #'concat (loop for o in output > +for e in expected > +if (not (equal o e)) > +collect (notmuch-test-reporter o e > + > + (t > + ;; Catch all case. > + (notmuch-test-reporter output expected > + > +(defun notmuch-test-compare (output expected) > + "Compare `output' with `expected'. Report any discrepencies." > + (if (equal output expected) > + t > +(notmuch-test-unsimilar output expected))) > -- > 1.7.7.3 > > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/4] test: Add `test_emacs_expect_t'.
On Tue, 17 Jan 2012 12:52:25 +, David Edmondson wrote: > Add a new test function to allow simpler testing of emacs > functionality. > > `test_emacs_expect_t' takes two arguments: > - the name of the test, > - some lisp to evaluate. > > The test passes if the lisp returns `t', otherwise it fails and the > output is reported to the tester. -1 This is not what I suggested. I do not like the approach when a single function is used to both declare a subtest and test for result (as opposed to test_begin_subtest). The fact that it is possible to write tests in two different ways makes it hard to maintain and improve the test framework (one example would be known broken test support). I consider the proper way to write tests to be using the test_begin_subtest function. Other functions are not currently deprecated, but I am against adding new code that make the situation worse. Also, please consider documenting new functions in README. Regards, Dmitry > --- > test/emacs-test-functions.sh |8 > test/notmuch-test|1 + > test/test-lib.sh | 24 > 3 files changed, 33 insertions(+), 0 deletions(-) > create mode 100755 test/emacs-test-functions.sh > > diff --git a/test/emacs-test-functions.sh b/test/emacs-test-functions.sh > new file mode 100755 > index 000..969cc78 > --- /dev/null > +++ b/test/emacs-test-functions.sh > @@ -0,0 +1,8 @@ > +#!/usr/bin/env bash > + > +test_description="emacs test function sanity" > +. test-lib.sh > + > +test_emacs_expect_t "emacs test function sanity" 't' > + > +test_done > diff --git a/test/notmuch-test b/test/notmuch-test > index 6a99ae3..d034f99 100755 > --- a/test/notmuch-test > +++ b/test/notmuch-test > @@ -52,6 +52,7 @@ TESTS=" >python >hooks >argument-parsing > + emacs-test-functions.sh > " > TESTS=${NOTMUCH_TESTS:=$TESTS} > > diff --git a/test/test-lib.sh b/test/test-lib.sh > index 7c9ce24..15da973 100644 > --- a/test/test-lib.sh > +++ b/test/test-lib.sh > @@ -503,6 +503,30 @@ test_expect_equal_file () > fi > } > > +test_emacs_expect_t () { > + test "$#" = 2 || error "bug in the test script: not 2 parameters to > test_emacs_expect_t" > + test_reset_state_ > + if ! test_skip "$1" > + then > + # We cannot call 'test_emacs' in a subshell, because > + # the setting of EMACS_SERVER would not persist > + # throughout a sequence of tests, so we use a > + # temporary file. > + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi > + output="$tmp/test_emacs_output.$$" > + test_emacs "$2" >"${output}" > + result=$(cat "${output}") > + rm -f "${output}" > + > + if [ "$result" == t ] > + then > + test_ok_ "$1" > + else > + test_failure_ "$1" "$(eval printf ${result})" > + fi > + fi > +} > + > NOTMUCH_NEW () > { > notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found > [0-9]* total file' > -- > 1.7.7.3 > > ___ > notmuch mailing list > notmuch at notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving
> Oof, sorry. Two more tweaks that I really should have caught in the > previous version. After that this gets my automatic +1. Both fixed. I have also fixed the bug I mentioned (missing filename when "view" falls back on save); I couldn't make it work with the "no-default" option. However overriding mm-save-part with flet seems to do the trick. +(defun notmuch-show-view-part (message-id nth &optional filename content-type ) + (notmuch-with-temp-part-buffer message-id nth +;; set mm-inlined-types to nil to force an external viewer +(let ((handle (mm-make-handle (current-buffer) (list content-type))) + (mm-inlined-types nil)) + ;; We override mm-save-part as notmuch-show-save-part is better + ;; since it offers the filename + (flet ((mm-save-part (&rest args) (ignore))) + (or (mm-display-part handle) + (notmuch-show-save-part message-id nth filename content-type)) Is that a reasonable solution? Best wishes Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Notmuch fails to build with gmime 2.6.4
Hi there. I've seen gmime related discussion but it's hard to follow using a web interface, so here's my bug report. Arch Linux x86_64 gmime 2.6.4 notmuch git, last commit: 8ea82928b91e847298e4586f9db9734e727a418a Build error: CC -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 command-line-arguments.o CC -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 debugger.o In file included from debugger.c:21:0: notmuch-client.h:72:5: error: unknown type name ?GMimeSignatureValidity? notmuch-client.h:86:5: error: unknown type name ?GMimeCipherContext? notmuch-client.h:297:5: error: unknown type name ?GMimeSignatureValidity? notmuch-client.h:322:3: error: unknown type name ?GMimeCipherContext? make: *** [debugger.o] Error 1 Regards, Philipp
Emacs: Crypto: How to get automatic encryption?
On Tue, 17 Jan 2012 09:19:51 +, David Edmondson wrote: > On Mon, 16 Jan 2012 23:48:30 -0500, Antoine Beaupr? anarcat.ath.cx> wrote: > > Jumping in here, I have modified the previously posted code here to > > provide me with a more complete solution. > > This looks good. I'll switch over to using it. Awesome! > > Code is attached. Obviously, those function names would change if they > > would be to integrate into notmuch. ;) > > I wondered about pushing to have notmuch do this by default. In general > I like the idea, but it suffers if a recipient occasionally uses a mail > client that does not support decryption (phone, PDA, webmail, ...). Well, it your call: you can disable encryption on the fly by setting the message to just signing... I have also found out (to great pains) that it is kind of difficult to *completely* disable signing or encrypting, as the send-hook will happily add back the #secure line even if you remove it. A workaround is to set "mode=none" in the #secure line manually. Maybe C-c RET C-n could do that instead of just removing the line? On Tue, 17 Jan 2012 15:39:52 +, David Edmondson wrote: > >(if (and force (re-search-forward "<#secure [> >]*>\n" nil t)) > >(replace-match "" nil nil)) > >;; If we can encrypt, do so, else just sign. > >(if (or force (not (re-search-forward "<#secure [> >]*>\n" nil t))) > > Is this second test for `force' necessary? If `force' is set then you'll > remove the <#secure..> just above, so it will not be found here. Yes, it is. If force is true, the search-forward will not be ran at all. The idea here is that if we do not force (ie. if we're running in the hook), we do not want to override the existing #secure tags, to respect the users' choices. Cheers, A. -- Antoine Beaupr? +++ R?seau Koumbit Networks +++ +1.514.387.6262 #208
[PATCH v2] emacs: add invisible dot instead of space at the end of notmuch-hello search box
+1. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/8d44c5e1/attachment.pgp>
[PATCH 1/1] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 17 at 8:39 pm: > > > I am happy to make that change. My original patch in the summer was more > > > like that: > > > id:"CALUdzSWAto+4mCUOOMk+8vFs+Pog-xUma6u-Aqx2M6-sbyQROg at mail.gmail.com" > > > > Is this the right id? I couldn't find it in the list archive. > > Sorry I messed up: it should be id:"87mxehqhbl.fsf at r102.config" However > I have included my current draft along these lines. I think it is > working but I am not submitting yet: just asking if this is the right > idea. In general, yes, I think so. A few comments on your draft below. > Best wishes > > Mark > > From 9e52414b9871369c1cbb5c3e72d833b56bb236d4 Mon Sep 17 00:00:00 2001 > From: Mark Walters > Date: Sat, 14 Jan 2012 18:04:22 + > Subject: [PATCH] Make buttons for attachments allow viewing as well as saving > > Define a keymap for attachment buttons to allow multiple actions. > Define 3 possible actions: > save attachment: exactly as currently, > view attachment: uses mailcap entry, > view attachment with user chosen program > > Keymap on a button is: s for save, v for view and o for view with > other program. Default (i.e. enter or mouse button) is save but this > is configurable in notmuch customize. > > One implementation detail: the view attachment function forces all > attachments to be "displayed" using mailcap even if emacs could > display them itself. Thus, for example, text/html appears in a browser > and text/plain asks whether to save (on a standard debian setup) > --- > emacs/notmuch-show.el | 87 > 1 files changed, 79 insertions(+), 8 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 03c1f6b..2413caa 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -281,10 +281,21 @@ message at DEPTH in the current thread." > (run-hooks 'notmuch-show-markup-headers-hook) > > (define-button-type 'notmuch-show-part-button-type > - 'action 'notmuch-show-part-button-action > + 'action 'notmuch-show-part-button-default > + 'keymap 'notmuch-show-part-button-map >'follow-link t >'face 'message-mml) > > +(defvar notmuch-show-part-button-map > + (let ((map (make-sparse-keymap))) > + (set-keymap-parent map button-map) > + (define-key map "s" 'notmuch-show-part-button-save) > + (define-key map "v" 'notmuch-show-part-button-view) > + (define-key map "o" 'notmuch-show-part-button-interactively-view) > +map) > + "Submap for button commands") > +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) I don't think this fset is necessary. Actually, I've never seen this outside of the notmuch code. It looks like it does appear in code shipped with Emacs, but only in a handful of places. All of those places look like very old code, so maybe this was necessary once upon a time? > + > (defun notmuch-show-insert-part-header (nth content-type declared-type > &optional name comment) >(let ((button)) > (setq button > @@ -299,7 +310,8 @@ message at DEPTH in the current thread." > " ]") > :type 'notmuch-show-part-button-type > :notmuch-part nth > -:notmuch-filename name)) > +:notmuch-filename name > +:notmuch-content-type content-type)) > (insert "\n") > ;; return button > button)) > @@ -323,6 +335,28 @@ message at DEPTH in the current thread." > ;; ange-ftp, which is reasonable to use here. > (mm-write-region (point-min) (point-max) file nil nil nil > 'no-conversion t) > > +(defun notmuch-show-view-part (message-id nth content-type) > + (let ((process-crypto notmuch-show-process-crypto)) > +(with-temp-buffer > + (setq notmuch-show-process-crypto process-crypto) > + ;; Always acquires the part via `notmuch part', even if it is > + ;; available in the JSON output. > + (insert (notmuch-show-get-bodypart-internal message-id nth)) > + ;; set mm-inlined-types to nil to force an external viewer > + (let ((handle (mm-make-handle (current-buffer) (list content-type))) > + (mm-inlined-types nil)) > + (mm-display-part handle t) > + > +(defun notmuch-show-interactively-view-part (message-id nth content-type) > + (let ((process-crypto notmuch-show-process-crypto)) > +(with-temp-buffer > + (setq notmuch-show-process-crypto process-crypto) > + ;; Always acquires the part via `notmuch part', even if it is > + ;; available in the JSON output. > + (insert (notmuch-show-get-bodypart-internal message-id nth)) > + (let ((handle (mm-make-handle (current-buffer) (list content-type > + (mm-interactively-view-part handle) > + Yeah. Though you're right that the duplication is a little annoying. With the snippet I sent earlier, these could change to, e.g., (defun notmuch-show-interactively-view-part (message-id nth content-type) (notmuch-with-part-temp-buffer
[PATCH 1/6] emacs: break up notmuch-show-archive-thread-internal into two generally useful functions
On Tue, 17 Jan 2012 12:17:54 -0800, Jameson Graef Rollins wrote: > > We're not currently in the habit of adding doc strings for > non-interactive programs. Do we need to go down that route? It is handy for developers, since the usual documentation facilities (describe-function, apropos, ...) will then work for that function too. Emacs documentation recommends(-ish) this: ,[ Elisp manual Section D.6 ] | An internal variable or subroutine of a Lisp program might as well | have a documentation string. In earlier Emacs versions, you could | save space by using a comment instead of a documentation string, | but that is no longer the case--documentation strings now take up | very little space in a running Emacs. ` -- Aaron Ecay
Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 17 at 11:44 pm: > Define a keymap for attachment buttons to allow multiple actions. > Define 3 possible actions: > save attachment: exactly as currently, > view attachment: uses mailcap entry, > view attachment with user chosen program > > Keymap on a button is: s for save, v for view and o for view with > other program. Default (i.e. enter or mouse button) is save but this > is configurable in notmuch customize. > > One implementation detail: the view attachment function forces all > attachments to be "displayed" using mailcap even if emacs could > display them itself. Thus, for example, text/html appears in a browser > and text/plain asks whether to save (on a standard debian setup) Oof, sorry. Two more tweaks that I really should have caught in the previous version. After that this gets my automatic +1. > --- > emacs/notmuch-show.el | 106 > ++--- > 1 files changed, 82 insertions(+), 24 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 03c1f6b..0aaaf79 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -281,10 +281,21 @@ message at DEPTH in the current thread." > (run-hooks 'notmuch-show-markup-headers-hook) > > (define-button-type 'notmuch-show-part-button-type > - 'action 'notmuch-show-part-button-action > + 'action 'notmuch-show-part-button-default > + 'keymap 'notmuch-show-part-button-map >'follow-link t >'face 'message-mml) > > +(defvar notmuch-show-part-button-map > + (let ((map (make-sparse-keymap))) > + (set-keymap-parent map button-map) > + (define-key map "s" 'notmuch-show-part-button-save) > + (define-key map "v" 'notmuch-show-part-button-view) > + (define-key map "o" 'notmuch-show-part-button-interactively-view) Indentation. > +map) > + "Submap for button commands") > +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) > + > (defun notmuch-show-insert-part-header (nth content-type declared-type > &optional name comment) >(let ((button)) > (setq button > @@ -299,29 +310,48 @@ message at DEPTH in the current thread." > " ]") > :type 'notmuch-show-part-button-type > :notmuch-part nth > -:notmuch-filename name)) > +:notmuch-filename name > +:notmuch-content-type content-type)) > (insert "\n") > ;; return button > button)) > > ;; Functions handling particular MIME parts. > > -(defun notmuch-show-save-part (message-id nth &optional filename) > - (let ((process-crypto notmuch-show-process-crypto)) > -(with-temp-buffer > - (setq notmuch-show-process-crypto process-crypto) > - ;; Always acquires the part via `notmuch part', even if it is > - ;; available in the JSON output. > - (insert (notmuch-show-get-bodypart-internal message-id nth)) > - (let ((file (read-file-name > -"Filename to save as: " > -(or mailcap-download-directory "~/") > -nil nil > -filename))) > - ;; Don't re-compress .gz & al. Arguably we should make > - ;; `file-name-handler-alist' nil, but that would chop > - ;; ange-ftp, which is reasonable to use here. > - (mm-write-region (point-min) (point-max) file nil nil nil > 'no-conversion t) > +(defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) > + (declare (indent 2)) > + (let ((process-crypto (make-symbol "process-crypto"))) > +`(let ((,process-crypto notmuch-show-process-crypto)) > + (with-temp-buffer > + (setq notmuch-show-process-crypto ,process-crypto) > + ;; Always acquires the part via `notmuch part', even if it is > + ;; available in the JSON output. > + (insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) > + ,@body > + > +(defun notmuch-show-save-part (message-id nth &optional filename > content-type) > + (notmuch-with-temp-part-buffer message-id nth > +(let ((file (read-file-name > + "Filename to save as: " > + (or mailcap-download-directory "~/") > + nil nil > + filename))) > + ;; Don't re-compress .gz & al. Arguably we should make > + ;; `file-name-handler-alist' nil, but that would chop > + ;; ange-ftp, which is reasonable to use here. > + (mm-write-region (point-min) (point-max) file nil nil nil > 'no-conversion t > + > +(defun notmuch-show-view-part (message-id nth &optional filename > content-type ) > + (notmuch-with-temp-part-buffer message-id nth > +;; set mm-inlined-types to nil to force an external viewer > +(let ((handle (mm-make-handle (current-buffer) (list content-type))) > + (mm-inlined-types nil)) > + (mm-display-part handle t > + > +(defun notmuch-show-interactively-view-part (message-id nth &optional > filename content-type) > + (notmuch-with-temp-part-buffer messa
[PATCH v2 5/5] emacs: Use message-citation-line-format in reply
Instead of using a static citation line for the first line of the reply message, use the customizable one defined by message-mode. This makes it easy for users to customize the reply style, and retains consistency for users with existing message-mode customizations. The test has been updated to reflect how the message will be formatted with the default value of message-citation-line-format. --- emacs/notmuch-mua.el | 19 --- test/emacs |2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index 64e160a..b58f919 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -135,9 +135,22 @@ list." (forward-line -1) (goto-char (point-max))) - (insert (format "On %s, %s wrote:\n" - (cdr (assq 'date original-headers)) - (cdr (assq 'from original-headers + (let* ((quoth message-citation-line-format) +(case-fold-search nil) +(full-from (cdr (assq 'from original-headers))) +(from-addr (car (mail-header-parse-address full-from))) +(from-name (cdr (mail-header-parse-address full-from))) +(first-name (car (split-string from-name))) +(last-name (append (cdr (split-string from-name +(time (date-to-time (cdr (assq 'date original-headers) + + (setq quoth (replace-regexp-in-string "%f" full-from quoth t t)) + (setq quoth (replace-regexp-in-string "%n" from-addr quoth t t)) + (setq quoth (replace-regexp-in-string "%N" from-name quoth t t)) + (setq quoth (replace-regexp-in-string "%F" first-name quoth t t)) + (setq quoth (replace-regexp-in-string "%L" last-name quoth t t)) + (setq quoth (format-time-string quoth time)) + (insert quoth)) (if plain-parts (mapc (lambda (part) (notmuch-mua-insert-part-quoted part)) plain-parts) diff --git a/test/emacs b/test/emacs index ac47b16..3f59b23 100755 --- a/test/emacs +++ b/test/emacs @@ -268,7 +268,7 @@ Subject: Re: Testing message sent via SMTP In-Reply-To: Fcc: $(pwd)/mail/sent --text follows this line-- -On 01 Jan 2000 12:00:00 -, Notmuch Test Suite wrote: +On Sat, Jan 01 2000, Notmuch Test Suite wrote: > This is a test that messages are sent via SMTP EOF test_expect_equal_file OUTPUT EXPECTED -- 1.7.5.4
[PATCH v2 4/5] emacs: Use the new JSON reply format.
Using the new JSON reply format allows emacs to quote HTML parts nicely by using mm-display-part to turn them into displayable text, then quoting them. This is very useful for users who regularly receive HTML-only email. The behavior for messages that contain plain text parts should be unchanged. --- Here is an updated patch that addresses David's concerns. A separate patch implementing use of the message-citation-line-format variable will follow. emacs/notmuch-lib.el |8 emacs/notmuch-mua.el | 97 + 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el index 0f856bf..2681634 100644 --- a/emacs/notmuch-lib.el +++ b/emacs/notmuch-lib.el @@ -127,6 +127,14 @@ the user hasn't set this variable with the old or new value." (list 'when (< emacs-major-version 23) form)) +(defun notmuch-parts-filter-by-type (parts type) + "Return a list of message parts with the given type" + (let (result) +(dolist (part (append parts nil) result) + (if (string= (cdr (assq 'content-type part)) type) + (setq result (append result (list (cdr (assq 'content part))) +result)) + ;; Compatibility functions for versions of emacs before emacs 23. ;; ;; Both functions here were copied from emacs 23 with the following copyright: diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index d8ab822..64e160a 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -19,6 +19,7 @@ ;; ;; Authors: David Edmondson +(require 'json) (require 'message) (require 'notmuch-lib) @@ -71,49 +72,81 @@ list." (push header message-hidden-headers))) notmuch-mua-hidden-headers)) +(defun notmuch-mua-insert-part-quoted (part) + (let ((start (point)) + limit) +(insert part) +(setq limit (point)) +(goto-char start) +(while (re-search-forward "\\(^\\)[^$]" limit 0) + (replace-match "> " nil nil nil 1) + ;; We have added two characters to the quotable region + (setq limit (+ limit 2))) +(set-buffer-modified-p nil))) + +(defun notmuch-mua-parse-html-part (part) + (with-temp-buffer +(insert part) +(let ((handle (mm-make-handle (current-buffer) (list "text/html"))) + (end-of-orig (point-max))) + (mm-display-part handle) + (delete-region (point-min) end-of-orig) + (fill-region (point-min) (point-max)) + (buffer-substring (point-min) (point-max) + (defun notmuch-mua-reply (query-string &optional sender reply-all) - (let (headers - body - (args '("reply"))) + (let ((args '("reply" "--format=json")) + reply + body) (if notmuch-show-process-crypto (setq args (append args '("--decrypt" (if reply-all (setq args (append args '("--reply-to=all"))) (setq args (append args '("--reply-to=sender" (setq args (append args (list query-string))) -;; This make assumptions about the output of `notmuch reply', but -;; really only that the headers come first followed by a blank -;; line and then the body. +;; Get the reply object as JSON, and parse it into an elisp object. (with-temp-buffer (apply 'call-process (append (list notmuch-command nil (list t t) nil) args)) (goto-char (point-min)) - (if (re-search-forward "^$" nil t) - (save-excursion - (save-restriction - (narrow-to-region (point-min) (point)) - (goto-char (point-min)) - (setq headers (mail-header-extract) - (forward-line 1) - (setq body (buffer-substring (point) (point-max -;; If sender is non-nil, set the From: header to its value. -(when sender - (mail-header-set 'from sender headers)) -(let - ;; Overlay the composition window on that being used to read - ;; the original message. - ((same-window-regexps '("\\*mail .*"))) - (notmuch-mua-mail (mail-header 'to headers) - (mail-header 'subject headers) - (message-headers-to-generate headers t '(to subject -;; insert the message body - but put it in front of the signature -;; if one is present -(goto-char (point-max)) -(if (re-search-backward message-signature-separator nil t) + (setq reply (aref (json-read) 0))) + +;; Start with the prelude, based on the headers of the original message. +(let* ((original (cdr (assq 'original reply))) + (headers (cdr (assq 'headers (assq 'reply reply + (original-headers (cdr (assq 'headers original))) + (body-parts (cdr (assq 'body original))) + (plain-parts (notmuch-parts-filter-by-type body-parts "text/plain")) + (html-parts (notmuch-parts-filter-by-type body-parts "text/html"))) + + ;; If sender is non-nil, set the From: header to its value. + (when sender + (mail-header-set 'from sender headers)) + (let +
[PATCH v3] Make buttons for attachments allow viewing as well as saving
Define a keymap for attachment buttons to allow multiple actions. Define 3 possible actions: save attachment: exactly as currently, view attachment: uses mailcap entry, view attachment with user chosen program Keymap on a button is: s for save, v for view and o for view with other program. Default (i.e. enter or mouse button) is save but this is configurable in notmuch customize. One implementation detail: the view attachment function forces all attachments to be "displayed" using mailcap even if emacs could display them itself. Thus, for example, text/html appears in a browser and text/plain asks whether to save (on a standard debian setup) --- emacs/notmuch-show.el | 106 ++--- 1 files changed, 82 insertions(+), 24 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 03c1f6b..0aaaf79 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -281,10 +281,21 @@ message at DEPTH in the current thread." (run-hooks 'notmuch-show-markup-headers-hook) (define-button-type 'notmuch-show-part-button-type - 'action 'notmuch-show-part-button-action + 'action 'notmuch-show-part-button-default + 'keymap 'notmuch-show-part-button-map 'follow-link t 'face 'message-mml) +(defvar notmuch-show-part-button-map + (let ((map (make-sparse-keymap))) + (set-keymap-parent map button-map) + (define-key map "s" 'notmuch-show-part-button-save) + (define-key map "v" 'notmuch-show-part-button-view) + (define-key map "o" 'notmuch-show-part-button-interactively-view) +map) + "Submap for button commands") +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) + (defun notmuch-show-insert-part-header (nth content-type declared-type &optional name comment) (let ((button)) (setq button @@ -299,29 +310,48 @@ message at DEPTH in the current thread." " ]") :type 'notmuch-show-part-button-type :notmuch-part nth - :notmuch-filename name)) + :notmuch-filename name + :notmuch-content-type content-type)) (insert "\n") ;; return button button)) ;; Functions handling particular MIME parts. -(defun notmuch-show-save-part (message-id nth &optional filename) - (let ((process-crypto notmuch-show-process-crypto)) -(with-temp-buffer - (setq notmuch-show-process-crypto process-crypto) - ;; Always acquires the part via `notmuch part', even if it is - ;; available in the JSON output. - (insert (notmuch-show-get-bodypart-internal message-id nth)) - (let ((file (read-file-name - "Filename to save as: " - (or mailcap-download-directory "~/") - nil nil - filename))) - ;; Don't re-compress .gz & al. Arguably we should make - ;; `file-name-handler-alist' nil, but that would chop - ;; ange-ftp, which is reasonable to use here. - (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion t) +(defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) + (declare (indent 2)) + (let ((process-crypto (make-symbol "process-crypto"))) +`(let ((,process-crypto notmuch-show-process-crypto)) + (with-temp-buffer +(setq notmuch-show-process-crypto ,process-crypto) +;; Always acquires the part via `notmuch part', even if it is +;; available in the JSON output. +(insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) +,@body + +(defun notmuch-show-save-part (message-id nth &optional filename content-type) + (notmuch-with-temp-part-buffer message-id nth +(let ((file (read-file-name +"Filename to save as: " +(or mailcap-download-directory "~/") +nil nil +filename))) + ;; Don't re-compress .gz & al. Arguably we should make + ;; `file-name-handler-alist' nil, but that would chop + ;; ange-ftp, which is reasonable to use here. + (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion t + +(defun notmuch-show-view-part (message-id nth &optional filename content-type ) + (notmuch-with-temp-part-buffer message-id nth +;; set mm-inlined-types to nil to force an external viewer +(let ((handle (mm-make-handle (current-buffer) (list content-type))) + (mm-inlined-types nil)) + (mm-display-part handle t + +(defun notmuch-show-interactively-view-part (message-id nth &optional filename content-type) + (notmuch-with-temp-part-buffer message-id nth +(let ((handle (mm-make-handle (current-buffer) (list content-type + (mm-interactively-view-part handle (defun notmuch-show-mm-display-part-inline (msg part nth content-type) "Use the mm-decode/mm-view functions to display a part in the @@ -1502,12 +1532,40 @@ buffer." ;; Commands typically bound to buttons. -(defun notmuch-
[PATCH 1/1] Make buttons for attachments allow viewing as well as saving
On Tue, 17 Jan 2012 15:26:03 -0500, Austin Clements wrote: > Quoth Mark Walters on Jan 17 at 9:06 am: > > > > > > I wonder if the "problem" comes from me doing things in a non-lispy > > > > fashion (I am completely new to lisp). Thus > > > > notmuch-show-part-button-default-action is a variable that gets passed > > > > around rather than a function. > > > > > > Sorry, I should have looked at the bigger context in this patch. I > > > think Jameson was implying that notmuch-show-part-button-default > > > should change to > > > > > > (defun notmuch-show-part-button-default (&optional button) > > > (interactive) > > > (funcall notmuch-show-part-button-default-action button)) > > > > > > I would go one step further and say that each action should probably > > > be a separate function. That is, break notmuch-show-part-action into > > > separate functions and simply invoke the appropriate function, rather > > > than performing a fixed data dispatch. This would be more flexible > > > and Lispy. It may be that your approach works out better, but I'd at > > > least give this a shot. > > > > I am happy to make that change. My original patch in the summer was more > > like that: > > id:"CALUdzSWAto+4mCUOOMk+8vFs+Pog-xUma6u-Aqx2M6-sbyQROg at mail.gmail.com" > > Is this the right id? I couldn't find it in the list archive. > > > Is that more what you had in mind? (Only in broad terms: Obviously I > > would need to add in the customization and default function etc). I > > decided that I didn't like the code duplication (but I am completely new > > to lisp) which is why I changed it for this submission. > > Yes, I wondered about this, too. It seems like at worst the > notmuch-show-process-crypto stuff would be duplicated. This might be > little enough that it's not worth worrying about, or it might be worth > introducing something like > > (defun notmuch-with-temp-part-buffer (message-id nth action) > (let ((process-crypto notmuch-show-process-crypto)) > (with-temp-buffer > (setq notmuch-show-process-crypto process-crypto) > ;; Always acquires the part via `notmuch part', even if it is > ;; available in the JSON output. > (insert (notmuch-show-get-bodypart-internal message-id nth)) > (funcall action > > You could also do this as a macro, but that definitely seems like > overkill. It seems to me that a macro is in fact the best solution. If you do it with a function, you need two defuns per action: one to do the actual work: (defun notmuch-show-part-button-whatever-worker () ;; do stuff... ) and one that says: (defun notmuch-show-part-button-whatever () (notmuch-with-temp-part-buffer id part-number #'notmuch-show-part-button-whatever-worker)) It would be the latter function that the key would be bound to. If a macro is used, the split between the worker and glue fns can be abandoned, and only one function is needed: (defun notmuch-show-part-button-whatever () (notmuch-with-temp-part-buffer ;; do stuff... )) A further advantage is if interactive arguments (e.g. C-u prefix) are needed for the function, there is no need to thread them through as arguments of notmuch-with-temp-part-buffer. -- Aaron Ecay
Re: [PATCH 1/1] Make buttons for attachments allow viewing as well as saving
> > Oops, actually there was a bug in that macro. It should have been > > (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) > (declare (indent 2)) > (let ((process-crypto (make-symbol "process-crypto"))) > `(let ((,process-crypto notmuch-show-process-crypto)) >(with-temp-buffer > (setq notmuch-show-process-crypto ,process-crypto) > ;; Always acquires the part via `notmuch part', even if it is > ;; available in the JSON output. > (insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) > ,@body > > The only difference is on the "insert" line. Sorry about that. Fixed. [Snip excellent explanation of defmacro] Thanks for the excellent explanation! > > Finally, I have discovered one bug/misfeature. If you try to "view" an > > attachment then it will offer to save it but will not offer a > > filename. If you try and save it (or use the default action) it will > > offer a filename as now. As far as I can see this is not fixable if I > > use mm-display-part: however, I could include a slight tweaked version, > > notmuch-show-mm-display-part say, which would fix this corner > > case. (Essentially, it would call notmuch-show-save-part if it failed to > > find a handler rather than mailcap-save-binary-file.) However, this is > > about 50 lines of lisp so I am not sure it is worth it. > > Hmm. This is probably worth fixing, but probably in a separate patch. > Duplicating mm-display-part is probably not the way to go. It think > it will work to pass t as the no-default argument to mm-display-part > and check the return value, which should be 'inline if it was able to > handle it internally or 'external if it found an external helper. I'm > pretty sure it will never fall in to mailcap-save-binary-file in that > case. If that doesn't work, you could flet mailcap-save-binary-file > around the call to mm-display-part. I had tried passing t to mm-display-part and that didn't work as I expected. I will experiment some more and try your flet suggestion but I think that will be a separate patch. I will send a potential final version of this patch as a reply to this email. Many thanks for all the guidance and help! Best wishes Mark ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Emacs: Crypto: How to get automatic encryption?
>(if (and force (re-search-forward "<#secure [> >]*>\n" nil t)) > (replace-match "" nil nil)) >;; If we can encrypt, do so, else just sign. >(if (or force (not (re-search-forward "<#secure [> >]*>\n" nil t))) Is this second test for `force' necessary? If `force' is set then you'll remove the <#secure..> just above, so it will not be found here. > (if (anarcat/message-guess-encryption) > (insert "<#secure method=pgpmime mode=signencrypt>\n") >(insert "<#secure method=pgpmime mode=sign>\n")) >) -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/90e8e822/attachment.pgp>
[PATCH] Add pseudo-compatibility with gmime 2.6
Quoth Thomas Jost on Jan 17 at 11:48 am: > On Mon, 16 Jan 2012 22:47:14 -0500, Austin Clements > wrote: > > Quoth Thomas Jost on Jan 17 at 12:56 am: > > > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info". > > > > > > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, > > > the > > > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto > > > test > > > fails (signature verification with signer key unavailable) but this will > > > be hard > > > to fix since the new API does not report the reason why a signature > > > verification > > > fails (other than the human-readable error message). > > > > What is the result of this failing test? > > The test looks like that: > > FAIL signature verification with signer key unavailable >--- crypto.4.expected 2012-01-16 23:05:06.765651183 + >+++ crypto.4.output 2012-01-16 23:05:06.765651183 + >@@ -12,9 +12,7 @@ > "Bcc": "", > "Date": "01 Jan 2000 12:00:00 -"}, > "body": [{"id": 1, >- "sigstatus": [{"status": "error", >- "keyid": "6D92612D94E46381", >- "errors": 2}], >+ "sigstatus": [], > "content-type": "multipart/signed", > "content": [{"id": 2, > "content-type": "text/plain", >Failed to verify signed part: gpg: keyblock resource > `/home/schnouki/dev/notmuch/test/tmp.crypto/gnupg/pubring.gpg': file open > error >gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux) >gpg: Signature made Mon Jan 16 23:05:06 2012 UTC using RSA key ID > 94E46381 >gpg: Can't check signature: public key not found > > So basically if a signer public key is missing, we can't get the status > signature: empty "sigstatus" field in the JSON output, "Unknown > signature status" in Emacs. > > IMHO this is a bug in gmime 2.6, and I think I know what causes it. I'll > file a bug in gmime and hopefully they'll find a cleaner way to fix it > than the one I came up with :) Oh, okay. That does seem like a bug in GMime. Do you think it would be possible to mark this test as "broken" if notmuch is using GMime 2.6? Off the top of my head, I can't think of an easy way to plumb that information through to the test suite. I don't think we should push any patches that knowingly break a test, even if it's in just one configuration. > > > > > --- > > > mime-node.c | 50 ++- > > > notmuch-client.h | 27 ++- > > > notmuch-reply.c |7 > > > notmuch-show.c | 97 > > > ++ > > > show-message.c |4 ++ > > > 5 files changed, 181 insertions(+), 4 deletions(-) > > > > > > diff --git a/mime-node.c b/mime-node.c > > > index d26bb44..ae2473d 100644 > > > --- a/mime-node.c > > > +++ b/mime-node.c > > > @@ -33,7 +33,11 @@ typedef struct mime_node_context { > > > GMimeMessage *mime_message; > > > > > > /* Context provided by the caller. */ > > > +#ifdef GMIME_26 > > > +GMimeCryptoContext *cryptoctx; > > > +#else > > > GMimeCipherContext *cryptoctx; > > > +#endif > > > notmuch_bool_t decrypt; > > > } mime_node_context_t; > > > > > > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res) > > > > > > notmuch_status_t > > > mime_node_open (const void *ctx, notmuch_message_t *message, > > > - GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt, > > > - mime_node_t **root_out) > > > +#ifdef GMIME_26 > > > + GMimeCryptoContext *cryptoctx, > > > +#else > > > + GMimeCipherContext *cryptoctx, > > > +#endif > > > + notmuch_bool_t decrypt, mime_node_t **root_out) > > > { > > > const char *filename = notmuch_message_get_filename (message); > > > mime_node_context_t *mctx; > > > @@ -112,12 +120,21 @@ DONE: > > > return status; > > > } > > > > > > +#ifdef GMIME_26 > > > +static int > > > +_signature_list_free (GMimeSignatureList **proxy) > > > +{ > > > +g_object_unref (*proxy); > > > +return 0; > > > +} > > > +#else > > > static int > > > _signature_validity_free (GMimeSignatureValidity **proxy) > > > { > > > g_mime_signature_validity_free (*proxy); > > > return 0; > > > } > > > +#endif > > > > > > static mime_node_t * > > > _mime_node_create (const mime_node_t *parent, GMimeObject *part) > > > @@ -165,11 +182,23 @@ _mime_node_create (const mime_node_t *parent, > > > GMimeObject *part) > > > GMimeMultipartEncrypted *encrypteddata = > > > GMIME_MULTIPART_ENCRYPTED (part); > > > node->decrypt_attempted = TRUE; > > > +#ifdef GMIME_26 > > > + GMimeDecryptResult *decrypt_result = g_mime_decrypt_result_new (); > > > > I think g_mime_multipart_encrypted_decrypt allocates the > > GMimeDecryptResult for you, so this will just leak memory. > > You're right, fixed. Will it be
[PATCH v2 3/3] search: Support automatic tag exclusions
Quoth David Edmondson on Jan 17 at 9:08 am: > On Mon, 16 Jan 2012 15:16:24 -0700, Jeremy Nickurak > wrote: > > On Mon, Jan 16, 2012 at 12:28, Austin Clements wrote: > > >> Having "deleted" and "spam" as default settings in the configuration > > >> file might be more reasonable. > > > > If I read correctly: > > > > 1) If no exclude options are in the config file, none should be used. > > Yes. > > > 2) On notmuch setup, "deleted" and "spam" should be added to .notmuch-config > > I might argue between 'should' and 'could', but the sense is correct. Oh, I think I see. I don't know if I can do precisely that, since the config code doesn't know if it's being called from setup, but is something like this essentially what you're suggesting? if (notmuch_config_get_auto_exclude_tags (config, &tmp) == NULL) { if (is_new) { const char *tags[] = { "deleted", "spam" }; notmuch_config_set_auto_exclude_tags (config, tags, 2); } else { notmuch_config_set_auto_exclude_tags (config, NULL, 0); } } (where is_new is TRUE if this is a brand-new config file)
[PATCH 1/1] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 17 at 9:06 am: > > > > I wonder if the "problem" comes from me doing things in a non-lispy > > > fashion (I am completely new to lisp). Thus > > > notmuch-show-part-button-default-action is a variable that gets passed > > > around rather than a function. > > > > Sorry, I should have looked at the bigger context in this patch. I > > think Jameson was implying that notmuch-show-part-button-default > > should change to > > > > (defun notmuch-show-part-button-default (&optional button) > > (interactive) > > (funcall notmuch-show-part-button-default-action button)) > > > > I would go one step further and say that each action should probably > > be a separate function. That is, break notmuch-show-part-action into > > separate functions and simply invoke the appropriate function, rather > > than performing a fixed data dispatch. This would be more flexible > > and Lispy. It may be that your approach works out better, but I'd at > > least give this a shot. > > I am happy to make that change. My original patch in the summer was more > like that: > id:"CALUdzSWAto+4mCUOOMk+8vFs+Pog-xUma6u-Aqx2M6-sbyQROg at mail.gmail.com" Is this the right id? I couldn't find it in the list archive. > Is that more what you had in mind? (Only in broad terms: Obviously I > would need to add in the customization and default function etc). I > decided that I didn't like the code duplication (but I am completely new > to lisp) which is why I changed it for this submission. Yes, I wondered about this, too. It seems like at worst the notmuch-show-process-crypto stuff would be duplicated. This might be little enough that it's not worth worrying about, or it might be worth introducing something like (defun notmuch-with-temp-part-buffer (message-id nth action) (let ((process-crypto notmuch-show-process-crypto)) (with-temp-buffer (setq notmuch-show-process-crypto process-crypto) ;; Always acquires the part via `notmuch part', even if it is ;; available in the JSON output. (insert (notmuch-show-get-bodypart-internal message-id nth)) (funcall action You could also do this as a macro, but that definitely seems like overkill.
Re: [PATCH] Start devel directory for developer tools and documentation.
Quoth David Bremner on Jan 17 at 8:47 am: > From: David Bremner > > We had a lot of back and forth about the name of this directory, but > nothing very conclusive. In the end, I just chose "devel" just to move > on. LGTM. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH] emacs: have notmuch-search-archive-thread use -next-thread function
+1 -- Aaron Ecay
[PATCH 3/6] emacs: add message archiving functions
On Tue, 17 Jan 2012 10:05:28 -0800, Jameson Graef Rollins wrote: > This adds two new message archiving functions that parallel the thread > archiving functions: notmuch-show-archive-message{,-then-next}. The > former also takes a prefix argument to unarchive the message (ie. put > back in inbox). > --- > emacs/notmuch-show.el | 17 + > 1 files changed, 17 insertions(+), 0 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index ee9ef62..207949c 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -1485,6 +1485,23 @@ buffer." >(notmuch-show-archive-thread) >(notmuch-show-next-thread)) > > +(defun notmuch-show-archive-message (&optional unarchive) > + "Archive the current message. > + > +If a prefix argument is given, the message will be > +\"unarchived\" (ie. the \"inbox\" tag will be added instead of > +removed)." > + (interactive) If this function uses the prefix arg, its interactive call should be ?(interactive "P")?. This applies equally to the -thread variant in patch 2/6, but I made the comment here because that diff doesn?t show the function contiguously. -- Aaron Ecay
[PATCH 1/6] emacs: break up notmuch-show-archive-thread-internal into two generally useful functions
On Tue, 17 Jan 2012 10:05:26 -0800, Jameson Graef Rollins wrote: > Brake up notmuch-show-archive-thread-internal into two new functions: > > notmuch-show-tag-thread-internal: applies a tag to all messages in > thread. If option remove flag is t, tags will be removed instead of > added. > > notmuch-show-next-thread: moves to the next thread in the search > result. If given a prefix, will show the next result, otherwise will > just move to it in the search view. > > Two new interactive functions, notmuch-show-{add,remove}-tag-thread, > are also added. Together, these provide a better suit of thread > tagging and navigation tools. > > The higher level thread archiving functions are modified to use these > new functions. > --- > emacs/notmuch-show.el | 33 ++--- > 1 files changed, 26 insertions(+), 7 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 03c1f6b..3625afd 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -1421,12 +1421,29 @@ argument, hide all of the messages." >(interactive) >(backward-button 1)) > > -(defun notmuch-show-archive-thread-internal (show-next) > - ;; Remove the tag from the current set of messages. > +(defun notmuch-show-tag-thread-internal (tag &optional remove) > + ;; Add tag to the current set of messages. If the remove switch is > + ;; given, tags will be removed instead of added. This should be a docstring instead of a comment. (This applies equally to the old version) -- Aaron Ecay
[PATCH 2/3] test: Add `test_emacs_expect_t'.
On Tue, 17 Jan 2012 18:49:36 +0400, Dmitry Kurochkin wrote: > > + # We cannot call 'test_emacs' in a subshell, because > > + # the setting of EMACS_SERVER would not persist > > + # throughout a sequence of tests, so we use a > > + # temporary file. > > + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi > > + output="$tmp/test_emacs_output.$$" > > + test_emacs "$1" > "${output}" > > + result=$(cat "${output}") > > + rm -f "${output}" > > I wonder if there is any bash trick which can help here? I'm not aware of one, but I'm not a bash expert. > Another option is to start emacs server before using test_emacs in > subshell. See emacs-subject-to-filename for an example. I think this > is a better option than using a temporary file. I think that's a very poor option. Forcing knowledge the breakage into all of the users may make applying any future fix more difficult. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/3df8fb09/attachment.pgp>
show-mode message/thread archiving improvements
+1 on this series from me. (Minor comments on a couple of the patches to follow.) -- Aaron Ecay
Re: [PATCH 1/1] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 17 at 10:27 pm: > > (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) > > (declare (indent 2)) > > (let ((process-crypto (make-symbol "process-crypto"))) > > `(let ((,process-crypto notmuch-show-process-crypto)) > >(with-temp-buffer > > (setq notmuch-show-process-crypto ,process-crypto) > > ;; Always acquires the part via `notmuch part', even if it is > > ;; available in the JSON output. > > (insert (notmuch-show-get-bodypart-internal message-id nth)) > > ,@body > > I have followed the macro approach: since notmuch-show-save-part also > uses it (which doesn't appear in the diff as it was unchanged). I have > made all three functions use notmuch-with-temp-part-buffer. However, I > used the macro exactly as you wrote it (and it seems to work) but I > moderately understand why but could not justify it to someone! Oops, actually there was a bug in that macro. It should have been (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) (declare (indent 2)) (let ((process-crypto (make-symbol "process-crypto"))) `(let ((,process-crypto notmuch-show-process-crypto)) (with-temp-buffer (setq notmuch-show-process-crypto ,process-crypto) ;; Always acquires the part via `notmuch part', even if it is ;; available in the JSON output. (insert (notmuch-show-get-bodypart-internal ,message-id ,nth)) ,@body The only difference is on the "insert" line. Sorry about that. I don't know how familiar you are with syntactic abstraction, so here's a top-down explanation. A macro is like the compile-time equivalent of a function: rather than the arguments and return being values that result from evaluation, they are pieces of code, the body of the macro executes at compile time instead of at run time, and the compiler replaces the invocation of the macro with the code that the macro returns. This is not unlike a C/C++ macro, but the implementation of the macro is regular Lisp code that runs at compile time and the code is represented as S-expressions rather than strings (one beauty of Lisp is that the representation of code and data is the same). The above macro returns the code starting after the "`" (pronounced quasiquote), so that's what invocations of the macro get replaced with. Quasiquote (like quote) inhibits the evaluation of what follows it and results in the code as data, rather than the result of evaluating the code. Unlike quote, quasiquote lets you jump back into the evaluator using "," and ",@", so it's great for piecing together code from a template, which is what macros spend most of their time doing. The "declare" is simply a specification to emacs-lisp-mode about how to indent uses of this macro. The "make-symbol" is necessary to avoid conflicting with variable names that may appear in the code that uses this macro (since the invoking code and the code returned by the macro will be interleaved, you have to worry about variable conflicts). > > (defun notmuch-show-interactively-view-part (message-id nth content-type) > > (notmuch-with-temp-part-buffer message-id nth > > (let ((handle (mm-make-handle (current-buffer) (list content-type > > (mm-interactively-view-part handle) > > Emacs wants to indent the (let line level with message-id in the line > above which looks odd (and makes the lines too long). Do I overrule > emacs, or put message-id and nth onto a separate line or is there > something better? If you evaluate the defmacro, it'll pick up on that declare line at the beginning of it and indent this correctly. > Also note that, because of the unification with notmuch-show-save-part > all three functions have to have the four arguments message-id, nth, > filename and content-type (even though currently each individual > function only uses three of them). However see below for another comment > on this. That makes sense. > > > +(defcustom notmuch-show-part-button-default-action > > > 'notmuch-show-part-button-save > > > + "Default part header button action (on ENTER or mouse click)." > > > + :group 'notmuch > > > + :type '(choice (const :tag "Save part" > > > + notmuch-show-part-button-save) > > > + (const :tag "View part" > > > + notmuch-show-part-button-view) > > > + (const :tag "View interactively" > > > + notmuch-show-part-button-interactively-view))) > > > > You probably want this to be the handler function, rather than the > > button function, since the interface to the button function is rather > > awkward. That is, if someone wanted to plug in their own action, they > > would want to define it in terms of the high-level handler interface > > that you use above, rather than the low-level > > button-with-magic-properties interface that Emacs forces you to use > > below. > > I have done this. > > > This duplication is
[PATCH] fix .gitignore for gzipped man pages
On Tue, 17 Jan 2012 20:16:03 +0200, Jani Nikula wrote: > --- > .gitignore |1 - > man/.gitignore |2 ++ pushed, d
[PATCH v2 5/5] emacs: Use message-citation-line-format in reply
Instead of using a static citation line for the first line of the reply message, use the customizable one defined by message-mode. This makes it easy for users to customize the reply style, and retains consistency for users with existing message-mode customizations. The test has been updated to reflect how the message will be formatted with the default value of message-citation-line-format. --- emacs/notmuch-mua.el | 19 --- test/emacs |2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index 64e160a..b58f919 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -135,9 +135,22 @@ list." (forward-line -1) (goto-char (point-max))) - (insert (format "On %s, %s wrote:\n" - (cdr (assq 'date original-headers)) - (cdr (assq 'from original-headers + (let* ((quoth message-citation-line-format) +(case-fold-search nil) +(full-from (cdr (assq 'from original-headers))) +(from-addr (car (mail-header-parse-address full-from))) +(from-name (cdr (mail-header-parse-address full-from))) +(first-name (car (split-string from-name))) +(last-name (append (cdr (split-string from-name +(time (date-to-time (cdr (assq 'date original-headers) + + (setq quoth (replace-regexp-in-string "%f" full-from quoth t t)) + (setq quoth (replace-regexp-in-string "%n" from-addr quoth t t)) + (setq quoth (replace-regexp-in-string "%N" from-name quoth t t)) + (setq quoth (replace-regexp-in-string "%F" first-name quoth t t)) + (setq quoth (replace-regexp-in-string "%L" last-name quoth t t)) + (setq quoth (format-time-string quoth time)) + (insert quoth)) (if plain-parts (mapc (lambda (part) (notmuch-mua-insert-part-quoted part)) plain-parts) diff --git a/test/emacs b/test/emacs index ac47b16..3f59b23 100755 --- a/test/emacs +++ b/test/emacs @@ -268,7 +268,7 @@ Subject: Re: Testing message sent via SMTP In-Reply-To: Fcc: $(pwd)/mail/sent --text follows this line-- -On 01 Jan 2000 12:00:00 -, Notmuch Test Suite wrote: +On Sat, Jan 01 2000, Notmuch Test Suite wrote: > This is a test that messages are sent via SMTP EOF test_expect_equal_file OUTPUT EXPECTED -- 1.7.5.4 ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH v2 4/5] emacs: Use the new JSON reply format.
Using the new JSON reply format allows emacs to quote HTML parts nicely by using mm-display-part to turn them into displayable text, then quoting them. This is very useful for users who regularly receive HTML-only email. The behavior for messages that contain plain text parts should be unchanged. --- Here is an updated patch that addresses David's concerns. A separate patch implementing use of the message-citation-line-format variable will follow. emacs/notmuch-lib.el |8 emacs/notmuch-mua.el | 97 + 2 files changed, 73 insertions(+), 32 deletions(-) diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el index 0f856bf..2681634 100644 --- a/emacs/notmuch-lib.el +++ b/emacs/notmuch-lib.el @@ -127,6 +127,14 @@ the user hasn't set this variable with the old or new value." (list 'when (< emacs-major-version 23) form)) +(defun notmuch-parts-filter-by-type (parts type) + "Return a list of message parts with the given type" + (let (result) +(dolist (part (append parts nil) result) + (if (string= (cdr (assq 'content-type part)) type) + (setq result (append result (list (cdr (assq 'content part))) +result)) + ;; Compatibility functions for versions of emacs before emacs 23. ;; ;; Both functions here were copied from emacs 23 with the following copyright: diff --git a/emacs/notmuch-mua.el b/emacs/notmuch-mua.el index d8ab822..64e160a 100644 --- a/emacs/notmuch-mua.el +++ b/emacs/notmuch-mua.el @@ -19,6 +19,7 @@ ;; ;; Authors: David Edmondson +(require 'json) (require 'message) (require 'notmuch-lib) @@ -71,49 +72,81 @@ list." (push header message-hidden-headers))) notmuch-mua-hidden-headers)) +(defun notmuch-mua-insert-part-quoted (part) + (let ((start (point)) + limit) +(insert part) +(setq limit (point)) +(goto-char start) +(while (re-search-forward "\\(^\\)[^$]" limit 0) + (replace-match "> " nil nil nil 1) + ;; We have added two characters to the quotable region + (setq limit (+ limit 2))) +(set-buffer-modified-p nil))) + +(defun notmuch-mua-parse-html-part (part) + (with-temp-buffer +(insert part) +(let ((handle (mm-make-handle (current-buffer) (list "text/html"))) + (end-of-orig (point-max))) + (mm-display-part handle) + (delete-region (point-min) end-of-orig) + (fill-region (point-min) (point-max)) + (buffer-substring (point-min) (point-max) + (defun notmuch-mua-reply (query-string &optional sender reply-all) - (let (headers - body - (args '("reply"))) + (let ((args '("reply" "--format=json")) + reply + body) (if notmuch-show-process-crypto (setq args (append args '("--decrypt" (if reply-all (setq args (append args '("--reply-to=all"))) (setq args (append args '("--reply-to=sender" (setq args (append args (list query-string))) -;; This make assumptions about the output of `notmuch reply', but -;; really only that the headers come first followed by a blank -;; line and then the body. +;; Get the reply object as JSON, and parse it into an elisp object. (with-temp-buffer (apply 'call-process (append (list notmuch-command nil (list t t) nil) args)) (goto-char (point-min)) - (if (re-search-forward "^$" nil t) - (save-excursion - (save-restriction - (narrow-to-region (point-min) (point)) - (goto-char (point-min)) - (setq headers (mail-header-extract) - (forward-line 1) - (setq body (buffer-substring (point) (point-max -;; If sender is non-nil, set the From: header to its value. -(when sender - (mail-header-set 'from sender headers)) -(let - ;; Overlay the composition window on that being used to read - ;; the original message. - ((same-window-regexps '("\\*mail .*"))) - (notmuch-mua-mail (mail-header 'to headers) - (mail-header 'subject headers) - (message-headers-to-generate headers t '(to subject -;; insert the message body - but put it in front of the signature -;; if one is present -(goto-char (point-max)) -(if (re-search-backward message-signature-separator nil t) + (setq reply (aref (json-read) 0))) + +;; Start with the prelude, based on the headers of the original message. +(let* ((original (cdr (assq 'original reply))) + (headers (cdr (assq 'headers (assq 'reply reply + (original-headers (cdr (assq 'headers original))) + (body-parts (cdr (assq 'body original))) + (plain-parts (notmuch-parts-filter-by-type body-parts "text/plain")) + (html-parts (notmuch-parts-filter-by-type body-parts "text/html"))) + + ;; If sender is non-nil, set the From: header to its value. + (when sender + (mail-header-set 'from sender headers)) + (l
[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6
On Tue, 17 Jan 2012 11:50:53 +0100, Thomas Jost wrote: > There are lots of API changes in gmime 2.6 crypto handling. By adding > preprocessor directives, it is however possible to add gmime 2.6 compatibility > while preserving compatibility with gmime 2.4 too. > > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info". > > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test > fails (signature verification with signer key unavailable) but this will be > hard > to fix since the new API does not report the reason why a signature > verification > fails (other than the human-readable error message). > --- LGTM. Some whitespace things but most of those were there already; I'd have one uncrustify round to be applied to the source and after that be more strict about those... actually gmime 2.4 has GMIME_CHECK_VERSION defined as g_mime_check_version (major, minor, micro) so the comment about it is not entirely accurate (it is unusable in our context, though) Tomi
Partial words on notmuch search?
Quoth Jani Nikula on Jan 17 at 7:43 pm: > On Mon, 16 Jan 2012 21:34:31 -0500, Austin Clements > wrote: > > Quoth Andrei Popescu on Jan 16 at 10:21 pm: > > > This is also interesting: > > > $ notmuch count 'debian' > > > 65888 > > > $ notmuch count 'dEbian' > > > 65888 > > > $ notmuch count 'Debian' > > > 65887 > > > > The first two will match stemmed versions of "debian" such as > > "debian's" and "debianed". However, starting a term with a capital > > letter suppresses stemming (because it suggests that it's a name, > > which you wouldn't want to modify), so your last query matches only > > the term "debian". This is probably documented somewhere, though I > > don't know where. > > Interesting. Is this done when adding the terms to the database, or when > searching? I presume the latter. How much control does notmuch have over > this? This is getting a bit out of my depth, but I believe indexing is done with both stemmed and unstemmed versions of all terms (if stemming is enabled) so that search can use either. For indexing, Notmuch can set the stemmer (or no stemmer). Xapian provides stemmers for a variety of languages: http://xapian.org/docs/apidoc/html/classXapian_1_1Stem.html#6c46cedf2047b159a7e4c9d4468242b1 For query parsing, Notmuch can set both the stemmer and a "stemming strategy" that controls when it stems or doesn't stem terms: http://xapian.org/docs/apidoc/html/classXapian_1_1QueryParser.html#c7dc3b55b6083bd3ff98fc8b2726c8fd
Re: Infinite loop in emacs interface
Hi, Actually, this is starting to look like a problem with gnus in the latest emacs-snapshot. I didn't notice before, but when I view the thread, I get this error: Debugger entered--Lisp error: (void-variable gnus-inhibit-images) mm-shr((# ("text/html") nil nil nil nil nil nil)) mm-inline-text-html((# ("text/html") nil nil nil nil nil nil)) mm-display-inline((# ("text/html") nil nil nil nil nil nil)) mm-display-part((# ("text/html") nil nil nil nil nil nil)) notmuch-show-mm-display-part-inline(...snipped...) notmuch-search-show-thread(nil) call-interactively(notmuch-search-show-thread nil nil) Someone seems to have come across it quite a while ago. http://lists.gnu.org/archive/html/emacs-devel/2010-11/msg00625.html This is quite strange because the previous emacs snapshot (20120105) was working OK. Running this code before viewing the thread seems to remove the error and stop the infinite loop: (defvar gnus-inhibit-images nil "*testing") (set-variable 'gnus-inhibit-images nil) But that's about the extent of my elisp knowledge. I'm not sure how to actually fix the bug. Cheers, Rodney ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/3] test: Don't return the result of checking for running emacs to the tester.
(And for the list...) On Tue, 17 Jan 2012 18:20:04 +0400, Dmitry Kurochkin wrote: > Can you please elaborate why this is needed? This code: # wait until the emacs server is up until test_emacs '()' 2>/dev/null; do sleep 1 done outputs 'nil', so the first caller to test_emacs has 'nil\n' prepended to their expected output. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/af9c04db/attachment.pgp>
[PATCH 2/3] test: Add `test_emacs_expect_t'.
On Tue, 17 Jan 2012 18:26:41 +0400, Dmitry Kurochkin wrote: > Sorry, I still do not understand why we can not implement > test_emacs_expect_t() like: > > result=${test_emacs $@} > test_expect_equal $result t > > Can you please explain? In the failure case test_expect_equal does: test_failure_ "$test_subtest_name" "$(diff -u $testname.expected $testname.output)" that diff output is not useful here, because the test harness doesn't have any expected output other than `t' with which to diff the actual output. The emacs-address-cleaning test shows how we will provide expected vs. actual output directly from within emacs, making it easier for the developer to figure out what went wrong. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/9aca0d02/attachment.pgp>
Re: Notmuch fails to build with gmime 2.6.4
Quoth hollun...@lavabit.com on Jan 17 at 4:24 pm: > Hi there. I've seen gmime related discussion but it's hard to follow using > a web interface, so here's my bug report. There's a GMime 2.6 support patch that will probably make it into the master branch in the next day or two. Sorry for the inconvenience. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: Improving notmuch query documentation [was: Re: Partial words on notmuch search?]
Quoth Andrei Popescu on Jan 18 at 12:14 am: > On Lu, 16 ian 12, 21:34:31, Austin Clements wrote: > > Quoth Andrei Popescu on Jan 16 at 10:21 pm: > > > Where can I read more about this? (except the source :) > > > > Most of this is in the Xapian query syntax document you found. Really > > we ought to beef-up Notmuch's query syntax documentation. > > If I get around to write something myself where do you suggest I should > start, the wiki or the manpage? Probably expanding man/man7/notmuch-search-terms.7 would be the way to go. ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 1/1] Make buttons for attachments allow viewing as well as saving
> In general, yes, I think so. A few comments on your draft below. Ok I include a newer version which I am fairly happy with but I do have some queries. > > +(defvar notmuch-show-part-button-map > > + (let ((map (make-sparse-keymap))) > > + (set-keymap-parent map button-map) > > + (define-key map "s" 'notmuch-show-part-button-save) > > + (define-key map "v" 'notmuch-show-part-button-view) > > + (define-key map "o" 'notmuch-show-part-button-interactively-view) > > +map) > > + "Submap for button commands") > > +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) > > I don't think this fset is necessary. Actually, I've never seen this > outside of the notmuch code. It looks like it does appear in code > shipped with Emacs, but only in a handful of places. All of those > places look like very old code, so maybe this was necessary once upon > a time? I have no idea on this: at the moment I have left it in as fset for keymaps seems to occur throughout notmuch (I have the fset because I copied it from somewhere). > (defmacro notmuch-with-temp-part-buffer (message-id nth &rest body) > (declare (indent 2)) > (let ((process-crypto (make-symbol "process-crypto"))) > `(let ((,process-crypto notmuch-show-process-crypto)) >(with-temp-buffer > (setq notmuch-show-process-crypto ,process-crypto) > ;; Always acquires the part via `notmuch part', even if it is > ;; available in the JSON output. > (insert (notmuch-show-get-bodypart-internal message-id nth)) > ,@body I have followed the macro approach: since notmuch-show-save-part also uses it (which doesn't appear in the diff as it was unchanged). I have made all three functions use notmuch-with-temp-part-buffer. However, I used the macro exactly as you wrote it (and it seems to work) but I moderately understand why but could not justify it to someone! > (defun notmuch-show-interactively-view-part (message-id nth content-type) > (notmuch-with-temp-part-buffer message-id nth > (let ((handle (mm-make-handle (current-buffer) (list content-type > (mm-interactively-view-part handle) Emacs wants to indent the (let line level with message-id in the line above which looks odd (and makes the lines too long). Do I overrule emacs, or put message-id and nth onto a separate line or is there something better? Also note that, because of the unification with notmuch-show-save-part all three functions have to have the four arguments message-id, nth, filename and content-type (even though currently each individual function only uses three of them). However see below for another comment on this. > > +(defcustom notmuch-show-part-button-default-action > > 'notmuch-show-part-button-save > > + "Default part header button action (on ENTER or mouse click)." > > + :group 'notmuch > > + :type '(choice (const :tag "Save part" > > + notmuch-show-part-button-save) > > +(const :tag "View part" > > + notmuch-show-part-button-view) > > +(const :tag "View interactively" > > + notmuch-show-part-button-interactively-view))) > > You probably want this to be the handler function, rather than the > button function, since the interface to the button function is rather > awkward. That is, if someone wanted to plug in their own action, they > would want to define it in terms of the high-level handler interface > that you use above, rather than the low-level > button-with-magic-properties interface that Emacs forces you to use > below. I have done this. > This duplication is much worse, but also less necessary. > > (defun notmuch-show-part-button-interactively-view (&optional button) > (interactive) > (notmuch-show-part-button-internal button > #'notmuch-show-interactively-view-part)) > > (defun notmuch-show-part-button-internal (button handler) > (let ((button (or button (button-at (point) > (if button > (let ((nth (button-get button :notmuch-part))) > (if nth > (funcall handler (notmuch-show-get-message-id) nth > (button-get button :notmuch-content-type)) > (message "Not a valid part (is it a fake part?).")) Yes this is much nicer and I have done this too (modulo the extra argument mentioned above). Finally, I have discovered one bug/misfeature. If you try to "view" an attachment then it will offer to save it but will not offer a filename. If you try and save it (or use the default action) it will offer a filename as now. As far as I can see this is not fixable if I use mm-display-part: however, I could include a slight tweaked version, notmuch-show-mm-display-part say, which would fix this corner case. (Essentially, it would call notmuch-show-save-part if it failed to find a handler rather than mailcap-save-binary-file.) However, this is about 50 lines of lisp so I am not sure it is worth it. Best wi
Re: [PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6
Quoth Thomas Jost on Jan 17 at 11:50 am: > There are lots of API changes in gmime 2.6 crypto handling. By adding > preprocessor directives, it is however possible to add gmime 2.6 compatibility > while preserving compatibility with gmime 2.4 too. > > This is mostly based on id:"8762i8hrb9@bookbinder.fernseed.info". > > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test > fails (signature verification with signer key unavailable) but this will be > hard > to fix since the new API does not report the reason why a signature > verification > fails (other than the human-readable error message). > --- > mime-node.c | 56 ++-- > notmuch-client.h | 28 +++- > notmuch-reply.c |7 > notmuch-show.c | 95 > ++ > show-message.c |4 ++ > 5 files changed, 185 insertions(+), 5 deletions(-) > > diff --git a/mime-node.c b/mime-node.c > index d26bb44..e575e1c 100644 > --- a/mime-node.c > +++ b/mime-node.c > @@ -33,7 +33,11 @@ typedef struct mime_node_context { > GMimeMessage *mime_message; > > /* Context provided by the caller. */ > +#ifdef GMIME_26 > +GMimeCryptoContext *cryptoctx; > +#else > GMimeCipherContext *cryptoctx; > +#endif > notmuch_bool_t decrypt; > } mime_node_context_t; > > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res) > > notmuch_status_t > mime_node_open (const void *ctx, notmuch_message_t *message, > - GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt, > - mime_node_t **root_out) > +#ifdef GMIME_26 > + GMimeCryptoContext *cryptoctx, > +#else > + GMimeCipherContext *cryptoctx, > +#endif > + notmuch_bool_t decrypt, mime_node_t **root_out) > { > const char *filename = notmuch_message_get_filename (message); > mime_node_context_t *mctx; > @@ -112,12 +120,21 @@ DONE: > return status; > } > > +#ifdef GMIME_26 > +static int > +_signature_list_free (GMimeSignatureList **proxy) > +{ > +g_object_unref (*proxy); > +return 0; > +} > +#else > static int > _signature_validity_free (GMimeSignatureValidity **proxy) > { > g_mime_signature_validity_free (*proxy); > return 0; > } > +#endif > > static mime_node_t * > _mime_node_create (const mime_node_t *parent, GMimeObject *part) > @@ -165,11 +182,22 @@ _mime_node_create (const mime_node_t *parent, > GMimeObject *part) > GMimeMultipartEncrypted *encrypteddata = > GMIME_MULTIPART_ENCRYPTED (part); > node->decrypt_attempted = TRUE; > +#ifdef GMIME_26 > + GMimeDecryptResult *decrypt_result = NULL; Reading through the GMime code, it looks like we do have to unref decrypt_result. I think this is easy, though. Right after you call g_mime_decrypt_result_get_signatures below, do: g_object_ref (node->sig_list); g_object_unref (decrypt_result); > + node->decrypted_child = g_mime_multipart_encrypted_decrypt > + (encrypteddata, node->ctx->cryptoctx, &decrypt_result, &err); > +#else > node->decrypted_child = g_mime_multipart_encrypted_decrypt > (encrypteddata, node->ctx->cryptoctx, &err); > +#endif > if (node->decrypted_child) { > - node->decrypt_success = node->verify_attempted = TRUE; > + node->decrypt_success = node->verify_attempted =TRUE; Whitespace. (There should be no diff on the above line) > +#ifdef GMIME_26 > + /* This may be NULL if the part is not signed. */ > + node->sig_list = g_mime_decrypt_result_get_signatures > (decrypt_result); > +#else > node->sig_validity = > g_mime_multipart_encrypted_get_signature_validity (encrypteddata); > +#endif > } else { > fprintf (stderr, "Failed to decrypt part: %s\n", >(err ? err->message : "no error explanation given")); > @@ -182,6 +210,16 @@ _mime_node_create (const mime_node_t *parent, > GMimeObject *part) >"(must be exactly 2)\n", >node->nchildren); > } else { > +#ifdef GMIME_26 > + GMimeSignatureList *sig_list = g_mime_multipart_signed_verify > + (GMIME_MULTIPART_SIGNED (part), node->ctx->cryptoctx, &err); > + node->verify_attempted = TRUE; > + node->sig_list = sig_list; Just a nit. This could be node->sig_list = g_mime_multipart_signed_verify ( ... ) To me, the local variable just makes this code more verbose without adding anything. Up to you. > + > + if (!sig_list) > + fprintf (stderr, "Failed to verify signed part: %s\n", > + (err ? err->message : "no error explanation given")); > +#else > /* For some reason the GMimeSignatureValidity returned >* here is not a const (incon
[PATCH 1/2] emacs: add invisible dot instead of space at the end of notmuch-hello search box
On Tue, 17 Jan 2012 18:13:26 +0400, Dmitry Kurochkin wrote: > On Tue, 17 Jan 2012 14:08:58 +, David Edmondson wrote: > > On Tue, 17 Jan 2012 17:24:45 +0400, Dmitry Kurochkin > gmail.com> wrote: > > > This makes `show-trailing-whitespace' happy, i.e. it does not mark the > > > whole search box line as trailing spaces. > > > > Why should `whitespace-mode' be active in `notmuch-hello' buffers? > > I do not say that it should be active in notmuch-hello. > > For me `show-trailing-whitespace' is activated everywhere with some > exceptions. Notmuch-hello is one of these exceptions. This change make > it one step closer to removing the exception. Okay. Please add a comment to explain why it is a . rather than a space, then +1. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/140e24aa/attachment.pgp>
[PATCH v2 2/2] Add pseudo-compatibility with gmime 2.6
On Tue, 17 Jan 2012 14:48:34 +0200, Tomi Ollila wrote: > On Tue, 17 Jan 2012 11:50:53 +0100, Thomas Jost > wrote: > > There are lots of API changes in gmime 2.6 crypto handling. By adding > > preprocessor directives, it is however possible to add gmime 2.6 > > compatibility > > while preserving compatibility with gmime 2.4 too. > > > > This is mostly based on id:"8762i8hrb9.fsf at bookbinder.fernseed.info". > > > > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, the > > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto test > > fails (signature verification with signer key unavailable) but this will be > > hard > > to fix since the new API does not report the reason why a signature > > verification > > fails (other than the human-readable error message). > > --- > > LGTM. Some whitespace things but most of those were there already; > I'd have one uncrustify round to be applied to the source and after > that be more strict about those... Thanks! I'll fix the whitespace issues in these patches when the source in Git is uncrustified then. > actually gmime 2.4 has GMIME_CHECK_VERSION defined as > g_mime_check_version (major, minor, micro) so the comment about it > is not entirely accurate (it is unusable in our context, though) Oops, yes. What I really meant is that GMIME_MAJOR_VERSION is not available as a preprocessor constant in 2.4, and GMIME_CHECK_VERSION is unusable in our context since it just calls a runtime function. By the way, how do you guys feel about setting GMIME_26 in notmuch-client.h? Is that good enough, or should it be done in configure so that gcc is called with "-DGMIME_26"? I filed a bug about gmime 2.6 incorrect handling of signatures with missing public keys: https://bugzilla.gnome.org/show_bug.cgi?id=668085. A patch is attached there, feel free to test and comment. (Arch Linux users: I made a little PKGBUILD that includes this patch if you want to build your own gmime 2.6.4: http://fichiers.schnouki.net/tmp/gmime-2.6.4-1.src.tar.gz) Best regards, -- Thomas/Schnouki -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 489 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/e5f7d377/attachment-0001.pgp>
Improving notmuch query documentation [was: Re: Partial words on notmuch search?]
On Lu, 16 ian 12, 21:34:31, Austin Clements wrote: > Quoth Andrei Popescu on Jan 16 at 10:21 pm: > > This is also interesting: > > $ notmuch count 'debian' > > 65888 > > $ notmuch count 'dEbian' > > 65888 > > $ notmuch count 'Debian' > > 65887 > > The first two will match stemmed versions of "debian" such as > "debian's" and "debianed". However, starting a term with a capital > letter suppresses stemming (because it suggests that it's a name, > which you wouldn't want to modify), so your last query matches only > the term "debian". This is probably documented somewhere, though I > don't know where. Stemming is mentioned in the Xapian docs, but I didn't understand the meaning until I read your explanation, thanks :) > > Where can I read more about this? (except the source :) > > Most of this is in the Xapian query syntax document you found. Really > we ought to beef-up Notmuch's query syntax documentation. If I get around to write something myself where do you suggest I should start, the wiki or the manpage? Thanks, Andrei -- If you can't explain it simply, you don't understand it well enough. (Albert Einstein) signature.asc Description: Digital signature ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: on deleting messages
Hi, On Tue, 17 Jan 2012 11:01:45 -0800, Jameson Graef Rollins wrote: [ ... ] > Based on the show-mode improvements I recently sent [1], the following > patch set implements thread and message delete keys. > > This is the last I'm going to comment on this issue. If we don't want > to support this, we should put together something on the wiki that > states we don't want to support it and that users should just bind it > themselves (with a nice explanation how), so that we can try to reduce > the number of future patches on the issue. I think this is something every (new) users are expecting to have: a simple and sensible way "to list the trashed messages". So I'd go for it. /Xavier ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/2] emacs: add invisible dot instead of space at the end of notmuch-hello search box
On Tue, 17 Jan 2012 17:24:45 +0400, Dmitry Kurochkin wrote: > This makes `show-trailing-whitespace' happy, i.e. it does not mark the > whole search box line as trailing spaces. Why should `whitespace-mode' be active in `notmuch-hello' buffers? -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/039d0462/attachment.pgp>
[PATCH 3/3] test: Add address cleaning tests.
Including some more test framework in test-lib.el. --- notmuch-test-address-cleaning-3 currently fails, in order that you can see the output format in that case. test/emacs-address-cleaning.el | 29 + test/emacs-address-cleaning.sh | 12 test/notmuch-test |1 + test/test-lib.el | 29 + 4 files changed, 71 insertions(+), 0 deletions(-) create mode 100644 test/emacs-address-cleaning.el create mode 100755 test/emacs-address-cleaning.sh diff --git a/test/emacs-address-cleaning.el b/test/emacs-address-cleaning.el new file mode 100644 index 000..59e8d92 --- /dev/null +++ b/test/emacs-address-cleaning.el @@ -0,0 +1,29 @@ +(defun notmuch-test-address-cleaning-1 () + (notmuch-test-compare (notmuch-show-clean-address "dme at dme.org") + "dme at dme.org")) + +(defun notmuch-test-address-cleaning-2 () + (let* ((input '("foo at bar.com" + "" + "Foo Bar " + "foo at bar.com " + "\"Foo Bar\" ")) +(expected '("foo at bar.com" +"foo at bar.com" +"Foo Bar " +"foo at bar.com" +"Foo Bar ")) +(output (mapcar #'notmuch-show-clean-address input))) +(notmuch-test-compare output expected))) + +(defun notmuch-test-address-cleaning-3 () + (let* ((input '("?? " + "foo (at home) " + "foo [at home] " + "Foo Bar")) +(expected '("?? " +"foo (at home) " +"foo [at home] " +"Foo Bar")) +(output (mapcar #'notmuch-show-clean-address input))) +(notmuch-test-compare output expected))) diff --git a/test/emacs-address-cleaning.sh b/test/emacs-address-cleaning.sh new file mode 100755 index 000..1a6eff5 --- /dev/null +++ b/test/emacs-address-cleaning.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +test_description="emacs address cleaning" +. test-lib.sh + +for i in 1 2 3; do +test_begin_subtest "notmuch-test-address-clean-$i" +test_emacs_expect_t \ + '(load "emacs-address-cleaning.el") (notmuch-test-address-cleaning-'$i')' +done + +test_done diff --git a/test/notmuch-test b/test/notmuch-test index d034f99..3f1740c 100755 --- a/test/notmuch-test +++ b/test/notmuch-test @@ -53,6 +53,7 @@ TESTS=" hooks argument-parsing emacs-test-functions.sh + emacs-address-cleaning.sh " TESTS=${NOTMUCH_TESTS:=$TESTS} diff --git a/test/test-lib.el b/test/test-lib.el index 3b817c3..cf8a46d 100644 --- a/test/test-lib.el +++ b/test/test-lib.el @@ -20,6 +20,8 @@ ;; ;; Authors: Dmitry Kurochkin +(require 'cl) ;; This code is generally used uncompiled. + ;; `read-file-name' by default uses `completing-read' function to read ;; user input. It does not respect `standard-input' variable which we ;; use in tests to provide user input. So replace it with a plain @@ -76,3 +78,30 @@ nothing." (add-hook-counter 'notmuch-hello-mode-hook) (add-hook-counter 'notmuch-hello-refresh-hook) + +;; Functions to help when writing tests: + +(defun notmuch-test-reporter (output expected) + "Report that the `output' does not match the `expected' result." + (concat "Expect:\t" (prin1-to-string expected) "\n" + "Output:\t" (prin1-to-string output) "\n")) + +(defun notmuch-test-unsimilar (output expected) + "`output' and `expected' are dissimilar. Show a summary of +the differences, ignoring similarities." + (cond ((and (listp output) + (listp expected)) +(apply #'concat (loop for o in output + for e in expected + if (not (equal o e)) + collect (notmuch-test-reporter o e + + (t +;; Catch all case. +(notmuch-test-reporter output expected + +(defun notmuch-test-compare (output expected) + "Compare `output' with `expected'. Report any discrepencies." + (if (equal output expected) + t +(notmuch-test-unsimilar output expected))) -- 1.7.7.3
[PATCH 2/3] test: Add `test_emacs_expect_t'.
Add a new test function to allow simpler testing of emacs functionality. `test_emacs_expect_t' takes one argument - a list expression to evaluate. The test passes if the expression returns `t', otherwise it fails and the output is reported to the tester. --- Re-worked as Dmitry suggested. test/README |8 test/emacs-test-functions.sh |9 + test/notmuch-test|1 + test/test-lib.sh | 33 + 4 files changed, 51 insertions(+), 0 deletions(-) create mode 100755 test/emacs-test-functions.sh diff --git a/test/README b/test/README index bde6db0..9dbe2ee 100644 --- a/test/README +++ b/test/README @@ -189,6 +189,14 @@ library for your script to use. tests that may run in the same Emacs instance. Use `let' instead so the scope of the changed variables is limited to a single test. + test_emacs_expect_t + + This function executes the provided emacs lisp script within + emacs in a manner similar to 'test_emacs'. The expressions should + return the value `t' to indicate that the test has passed. If the + test does not return `t' then it is considered failed and all data + returned by the test is reported to the tester. + test_done Your test script must have test_done at the end. Its purpose diff --git a/test/emacs-test-functions.sh b/test/emacs-test-functions.sh new file mode 100755 index 000..0e1f9fc --- /dev/null +++ b/test/emacs-test-functions.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +test_description="emacs test function sanity" +. test-lib.sh + +test_begin_subtest "emacs test function sanity" +test_emacs_expect_t 't' + +test_done diff --git a/test/notmuch-test b/test/notmuch-test index 6a99ae3..d034f99 100755 --- a/test/notmuch-test +++ b/test/notmuch-test @@ -52,6 +52,7 @@ TESTS=" python hooks argument-parsing + emacs-test-functions.sh " TESTS=${NOTMUCH_TESTS:=$TESTS} diff --git a/test/test-lib.sh b/test/test-lib.sh index 7c9ce24..4b05760 100644 --- a/test/test-lib.sh +++ b/test/test-lib.sh @@ -503,6 +503,39 @@ test_expect_equal_file () fi } +test_emacs_expect_t () { + test "$#" = 1 || error "bug in the test script: not 1 parameter to test_emacs_expect_t" + + # Run the test. + if ! test_skip "$test_subtest_name" + then + # We cannot call 'test_emacs' in a subshell, because + # the setting of EMACS_SERVER would not persist + # throughout a sequence of tests, so we use a + # temporary file. + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi + output="$tmp/test_emacs_output.$$" + test_emacs "$1" > "${output}" + result=$(cat "${output}") + rm -f "${output}" + fi + + # Restore state after the test. + exec 1>&6 2>&7 # Restore stdout and stderr + inside_subtest= + + # Report success/failure. + if ! test_skip "$test_subtest_name" + then + if [ "$result" == t ] + then + test_ok_ "$test_subtest_name" + else + test_failure_ "$test_subtest_name" "$(eval printf ${result})" + fi + fi +} + NOTMUCH_NEW () { notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file' -- 1.7.7.3
[PATCH 1/3] test: Don't return the result of checking for running emacs to the tester.
--- test/test-lib.sh |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/test/test-lib.sh b/test/test-lib.sh index d1fbc05..7c9ce24 100644 --- a/test/test-lib.sh +++ b/test/test-lib.sh @@ -926,7 +926,7 @@ test_emacs () { --eval '(orphan-watchdog $$)'" || return EMACS_SERVER="$server_name" # wait until the emacs server is up - until test_emacs '()' 2>/dev/null; do + until test_emacs '()' >/dev/null 2>/dev/null; do sleep 1 done fi -- 1.7.7.3
Re: [PATCH 1/3] emacs: bind "s" to `notmuch-search' in notmuch-hello buffer
[of course I sent this email privately, sorry for duplicates] On Tue, 17 Jan 2012 23:22:30 +0200, Jani Nikula wrote: > On Tue, 17 Jan 2012 23:34:08 +0400, Dmitry Kurochkin > wrote: > > Before the change, "s" in notmuch-hello buffer would jump to the > > search box. The patch changes the binding to `notmuch-search' which > > is consistent with all other notmuch buffers. > > --- > > emacs/notmuch-hello.el | 19 ++- > > 1 files changed, 6 insertions(+), 13 deletions(-) > > > > diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el > > index 02017ce..08fcd22 100644 > > --- a/emacs/notmuch-hello.el > > +++ b/emacs/notmuch-hello.el > > @@ -29,9 +29,6 @@ > > (declare-function notmuch-search "notmuch" (query &optional oldest-first > > target-thread target-line continuation)) > > (declare-function notmuch-poll "notmuch" ()) > > > > -(defvar notmuch-hello-search-bar-marker nil > > - "The position of the search bar within the notmuch-hello buffer.") > > - > > (defcustom notmuch-recent-searches-max 10 > >"The number of recent searches to store and display." > >:type 'integer > > @@ -321,11 +318,6 @@ should be. Returns a cons cell `(tags-per-line > > width)'." > > (widget-insert "\n")) > > found-target-pos)) > > > > -(defun notmuch-hello-goto-search () > > - "Put point inside the `search' widget." > > - (interactive) > > - (goto-char notmuch-hello-search-bar-marker)) > > After this, what would the user have to do to bind some key to put the > point in the search box? If someone wants to restore old behaviour for > themselves. > There is no way to do that. From the previous discussions, I do not remember anyone wanted the current "s" jumping behavior. Let's wait for some feedback and see if anyone wants that. I would prefer to remove this function and the global variable it uses. > Also, it's perhaps out of scope for this patch, but it will become more > evident now that notmuch-search does not respect > notmuch-search-oldest-first when called without parameters like the new > 's' keybinding does. This is the same in search view. > I agree that this is an issue. But it is outisde of the scope of this patch series. Regards, Dmitry > > BR, > Jani. > > > > - > > (defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png"))) > > > > (defun notmuch-hello-search-continuation() > > @@ -355,7 +347,7 @@ should be. Returns a cons cell `(tags-per-line width)'." > > (define-key map "G" 'notmuch-hello-poll-and-update) > > (define-key map (kbd "") 'widget-backward) > > (define-key map "m" 'notmuch-mua-new-mail) > > -(define-key map "s" 'notmuch-hello-goto-search) > > +(define-key map "s" 'notmuch-search) > > map) > >"Keymap for \"notmuch hello\" buffers.") > > (fset 'notmuch-hello-mode-map notmuch-hello-mode-map) > > @@ -468,7 +460,8 @@ Complete list of currently available key bindings: > >(widget-insert " messages.\n")) > > > > (let ((found-target-pos nil) > > - (final-target-pos nil)) > > + (final-target-pos nil) > > + (search-bar-pos)) > >(let* ((saved-alist > > ;; Filter out empty saved searches if required. > > (if notmuch-show-empty-saved-searches > > @@ -500,7 +493,7 @@ Complete list of currently available key bindings: > > (indent-rigidly start (point) notmuch-hello-indent))) > > > > (widget-insert "\nSearch: ") > > - (setq notmuch-hello-search-bar-marker (point-marker)) > > + (setq search-bar-pos (point-marker)) > > (widget-create 'editable-field > >;; Leave some space at the start and end of the > >;; search boxes. > > @@ -589,7 +582,7 @@ Complete list of currently available key bindings: > > (when notmuch-saved-searches > > (widget-insert "Edit saved searches with the `edit' button.\n")) > > (widget-insert "Hit RET or click on a saved search or tag name to view > > matching threads.\n") > > - (widget-insert "`=' refreshes this screen. `s' jumps to the search box. > > `q' to quit.\n") > > + (widget-insert "`=' refreshes this screen. `s' to search messages. `q' > > to quit.\n") > > (let ((fill-column (- (window-width) notmuch-hello-indent))) > > (center-region start (point > > > > @@ -601,7 +594,7 @@ Complete list of currently available key bindings: > > (widget-forward 1))) > > > >(unless (widget-at) > > - (notmuch-hello-goto-search > > + (goto-char search-bar-pos > > > >(run-hooks 'notmuch-hello-refresh-hook)) > > > > -- > > 1.7.8.3 > > > > ___ > > notmuch mailing list > > notmuch@notmuchmail.org > > http://notmuchmail.org/mailman/listinfo/notmuch ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Notmuch fails to build with gmime 2.6.4
Hi there. I've seen gmime related discussion but it's hard to follow using a web interface, so here's my bug report. Arch Linux x86_64 gmime 2.6.4 notmuch git, last commit: 8ea82928b91e847298e4586f9db9734e727a418a Build error: CC -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 command-line-arguments.o CC -march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 debugger.o In file included from debugger.c:21:0: notmuch-client.h:72:5: error: unknown type name GMimeSignatureValidity notmuch-client.h:86:5: error: unknown type name GMimeCipherContext notmuch-client.h:297:5: error: unknown type name GMimeSignatureValidity notmuch-client.h:322:3: error: unknown type name GMimeCipherContext make: *** [debugger.o] Error 1 Regards, Philipp ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 1/4] test: Add `test_emacs_expect_t'.
(And one for the list...) On Tue, 17 Jan 2012 17:09:35 +0400, Dmitry Kurochkin wrote: > -1 > > This is not what I suggested. I do not like the approach when a single > function is used to both declare a subtest and test for result (as > opposed to test_begin_subtest). The fact that it is possible to write > tests in two different ways makes it hard to maintain and improve the > test framework (one example would be known broken test support). I > consider the proper way to write tests to be using the > test_begin_subtest function. Other functions are not currently > deprecated, but I am against adding new code that make the situation > worse. Sigh. Okay. > Also, please consider documenting new functions in README. Missed that, sorry. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/5f6808fd/attachment.pgp>
[PATCH 2/4] test: Add address cleaning tests.
On Tue, 17 Jan 2012 17:11:58 +0400, Dmitry Kurochkin wrote: > Since test/ directory is used for all kind of tests not just Emacs > UI-specific, so I think address-cleaning.* files should be > emacs-address-cleaning. Okay. -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/1da9e975/attachment.pgp>
Re: [PATCH 1/3] emacs: bind "s" to `notmuch-search' in notmuch-hello buffer
On Tue, 17 Jan 2012 23:34:08 +0400, Dmitry Kurochkin wrote: > Before the change, "s" in notmuch-hello buffer would jump to the > search box. The patch changes the binding to `notmuch-search' which > is consistent with all other notmuch buffers. > --- > emacs/notmuch-hello.el | 19 ++- > 1 files changed, 6 insertions(+), 13 deletions(-) > > diff --git a/emacs/notmuch-hello.el b/emacs/notmuch-hello.el > index 02017ce..08fcd22 100644 > --- a/emacs/notmuch-hello.el > +++ b/emacs/notmuch-hello.el > @@ -29,9 +29,6 @@ > (declare-function notmuch-search "notmuch" (query &optional oldest-first > target-thread target-line continuation)) > (declare-function notmuch-poll "notmuch" ()) > > -(defvar notmuch-hello-search-bar-marker nil > - "The position of the search bar within the notmuch-hello buffer.") > - > (defcustom notmuch-recent-searches-max 10 >"The number of recent searches to store and display." >:type 'integer > @@ -321,11 +318,6 @@ should be. Returns a cons cell `(tags-per-line width)'." > (widget-insert "\n")) > found-target-pos)) > > -(defun notmuch-hello-goto-search () > - "Put point inside the `search' widget." > - (interactive) > - (goto-char notmuch-hello-search-bar-marker)) After this, what would the user have to do to bind some key to put the point in the search box? If someone wants to restore old behaviour for themselves. Also, it's perhaps out of scope for this patch, but it will become more evident now that notmuch-search does not respect notmuch-search-oldest-first when called without parameters like the new 's' keybinding does. This is the same in search view. BR, Jani. > - > (defimage notmuch-hello-logo ((:type png :file "notmuch-logo.png"))) > > (defun notmuch-hello-search-continuation() > @@ -355,7 +347,7 @@ should be. Returns a cons cell `(tags-per-line width)'." > (define-key map "G" 'notmuch-hello-poll-and-update) > (define-key map (kbd "") 'widget-backward) > (define-key map "m" 'notmuch-mua-new-mail) > -(define-key map "s" 'notmuch-hello-goto-search) > +(define-key map "s" 'notmuch-search) > map) >"Keymap for \"notmuch hello\" buffers.") > (fset 'notmuch-hello-mode-map notmuch-hello-mode-map) > @@ -468,7 +460,8 @@ Complete list of currently available key bindings: >(widget-insert " messages.\n")) > > (let ((found-target-pos nil) > - (final-target-pos nil)) > + (final-target-pos nil) > + (search-bar-pos)) >(let* ((saved-alist > ;; Filter out empty saved searches if required. > (if notmuch-show-empty-saved-searches > @@ -500,7 +493,7 @@ Complete list of currently available key bindings: > (indent-rigidly start (point) notmuch-hello-indent))) > > (widget-insert "\nSearch: ") > - (setq notmuch-hello-search-bar-marker (point-marker)) > + (setq search-bar-pos (point-marker)) > (widget-create 'editable-field > ;; Leave some space at the start and end of the > ;; search boxes. > @@ -589,7 +582,7 @@ Complete list of currently available key bindings: > (when notmuch-saved-searches > (widget-insert "Edit saved searches with the `edit' button.\n")) > (widget-insert "Hit RET or click on a saved search or tag name to view > matching threads.\n") > - (widget-insert "`=' refreshes this screen. `s' jumps to the search box. > `q' to quit.\n") > + (widget-insert "`=' refreshes this screen. `s' to search messages. `q' > to quit.\n") > (let ((fill-column (- (window-width) notmuch-hello-indent))) > (center-region start (point > > @@ -601,7 +594,7 @@ Complete list of currently available key bindings: > (widget-forward 1))) > >(unless (widget-at) > - (notmuch-hello-goto-search > + (goto-char search-bar-pos > >(run-hooks 'notmuch-hello-refresh-hook)) > > -- > 1.7.8.3 > > ___ > notmuch mailing list > notmuch@notmuchmail.org > http://notmuchmail.org/mailman/listinfo/notmuch ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH 1/1] Make buttons for attachments allow viewing as well as saving
Quoth Mark Walters on Jan 17 at 8:39 pm: > > > I am happy to make that change. My original patch in the summer was more > > > like that: > > > id:"caludzswato+4mcuoomk+8vfs+pog-xuma6u-aqx2m6-sbyq...@mail.gmail.com" > > > > Is this the right id? I couldn't find it in the list archive. > > Sorry I messed up: it should be id:"87mxehqhbl.fsf@r102.config" However > I have included my current draft along these lines. I think it is > working but I am not submitting yet: just asking if this is the right > idea. In general, yes, I think so. A few comments on your draft below. > Best wishes > > Mark > > From 9e52414b9871369c1cbb5c3e72d833b56bb236d4 Mon Sep 17 00:00:00 2001 > From: Mark Walters > Date: Sat, 14 Jan 2012 18:04:22 + > Subject: [PATCH] Make buttons for attachments allow viewing as well as saving > > Define a keymap for attachment buttons to allow multiple actions. > Define 3 possible actions: > save attachment: exactly as currently, > view attachment: uses mailcap entry, > view attachment with user chosen program > > Keymap on a button is: s for save, v for view and o for view with > other program. Default (i.e. enter or mouse button) is save but this > is configurable in notmuch customize. > > One implementation detail: the view attachment function forces all > attachments to be "displayed" using mailcap even if emacs could > display them itself. Thus, for example, text/html appears in a browser > and text/plain asks whether to save (on a standard debian setup) > --- > emacs/notmuch-show.el | 87 > 1 files changed, 79 insertions(+), 8 deletions(-) > > diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el > index 03c1f6b..2413caa 100644 > --- a/emacs/notmuch-show.el > +++ b/emacs/notmuch-show.el > @@ -281,10 +281,21 @@ message at DEPTH in the current thread." > (run-hooks 'notmuch-show-markup-headers-hook) > > (define-button-type 'notmuch-show-part-button-type > - 'action 'notmuch-show-part-button-action > + 'action 'notmuch-show-part-button-default > + 'keymap 'notmuch-show-part-button-map >'follow-link t >'face 'message-mml) > > +(defvar notmuch-show-part-button-map > + (let ((map (make-sparse-keymap))) > + (set-keymap-parent map button-map) > + (define-key map "s" 'notmuch-show-part-button-save) > + (define-key map "v" 'notmuch-show-part-button-view) > + (define-key map "o" 'notmuch-show-part-button-interactively-view) > +map) > + "Submap for button commands") > +(fset 'notmuch-show-part-button-map notmuch-show-part-button-map) I don't think this fset is necessary. Actually, I've never seen this outside of the notmuch code. It looks like it does appear in code shipped with Emacs, but only in a handful of places. All of those places look like very old code, so maybe this was necessary once upon a time? > + > (defun notmuch-show-insert-part-header (nth content-type declared-type > &optional name comment) >(let ((button)) > (setq button > @@ -299,7 +310,8 @@ message at DEPTH in the current thread." > " ]") > :type 'notmuch-show-part-button-type > :notmuch-part nth > -:notmuch-filename name)) > +:notmuch-filename name > +:notmuch-content-type content-type)) > (insert "\n") > ;; return button > button)) > @@ -323,6 +335,28 @@ message at DEPTH in the current thread." > ;; ange-ftp, which is reasonable to use here. > (mm-write-region (point-min) (point-max) file nil nil nil > 'no-conversion t) > > +(defun notmuch-show-view-part (message-id nth content-type) > + (let ((process-crypto notmuch-show-process-crypto)) > +(with-temp-buffer > + (setq notmuch-show-process-crypto process-crypto) > + ;; Always acquires the part via `notmuch part', even if it is > + ;; available in the JSON output. > + (insert (notmuch-show-get-bodypart-internal message-id nth)) > + ;; set mm-inlined-types to nil to force an external viewer > + (let ((handle (mm-make-handle (current-buffer) (list content-type))) > + (mm-inlined-types nil)) > + (mm-display-part handle t) > + > +(defun notmuch-show-interactively-view-part (message-id nth content-type) > + (let ((process-crypto notmuch-show-process-crypto)) > +(with-temp-buffer > + (setq notmuch-show-process-crypto process-crypto) > + ;; Always acquires the part via `notmuch part', even if it is > + ;; available in the JSON output. > + (insert (notmuch-show-get-bodypart-internal message-id nth)) > + (let ((handle (mm-make-handle (current-buffer) (list content-type > + (mm-interactively-view-part handle) > + Yeah. Though you're right that the duplication is a little annoying. With the snippet I sent earlier, these could change to, e.g., (defun notmuch-show-interactively-view-part (message-id nth content-type) (notmuch-with-part-temp-buffer mes
[PATCH] NEWS: consistent 2-space indentation
In NEWS file, indentation for item descriptions is generally 2 spaces but in a few cases there were 3 or 4 (4 caused different markdown handling) space indentations. Indentation in those lines are brought to consistent 2-space indentation. --- NEWS | 16 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/NEWS b/NEWS index 1161c22..1e561a9 100644 --- a/NEWS +++ b/NEWS @@ -133,8 +133,8 @@ Bug-fix release. Fix crash in python bindings. -The python bindings did not call g_type_init, which caused crashes -for some, but not all users. + The python bindings did not call g_type_init, which caused crashes + for some, but not all users. Notmuch 0.10.1 (2011-11-25) === @@ -204,8 +204,8 @@ Add keybinding ('c I') for stashing Message-ID's without an id: prefix Do not query on notmuch-search exit - It is harmless to kill the external notmuch process, so the user - is no longer interrogated when they interrupt a search. + It is harmless to kill the external notmuch process, so the user + is no longer interrogated when they interrupt a search. Performance --- @@ -234,9 +234,9 @@ mailing list. nmbug - share tags with a given prefix - nmbug helps maintain a git repo containing all tags with a given - prefix (by default "notmuch::"). Tags can be shared by commiting - them to git in one location and restoring in another. + nmbug helps maintain a git repo containing all tags with a given + prefix (by default "notmuch::"). Tags can be shared by commiting + them to git in one location and restoring in another. Notmuch 0.9 (2011-10-01) @@ -621,7 +621,7 @@ Ruby bindings are now much more complete s1.union(s2) s2 -= s1 - Removed: + Removed: - len(Messages()) as it exhausted the iterator. Use len(list(Messages())) or Query.count_messages() to get the length. -- 1.7.7.3
Re: [PATCH 1/6] emacs: break up notmuch-show-archive-thread-internal into two generally useful functions
On Tue, 17 Jan 2012 12:17:54 -0800, Jameson Graef Rollins wrote: > > We're not currently in the habit of adding doc strings for > non-interactive programs. Do we need to go down that route? It is handy for developers, since the usual documentation facilities (describe-function, apropos, ...) will then work for that function too. Emacs documentation recommends(-ish) this: ,[ Elisp manual Section D.6 ] | An internal variable or subroutine of a Lisp program might as well | have a documentation string. In earlier Emacs versions, you could | save space by using a comment instead of a documentation string, | but that is no longer the case--documentation strings now take up | very little space in a running Emacs. ` -- Aaron Ecay ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
[PATCH 4/4] emacs: Another special case for `notmuch-show-clean-address'.
Remove backslashes. --- emacs/notmuch-show.el| 14 +- test/address-cleaning.el |6 -- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 8b2fbb3..90c9c05 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -248,11 +248,15 @@ unchanged ADDRESS if parsing fails." (t (setq p-address address))) - ;; Remove outer double quotes. They might be required during - ;; transport, but we don't need to see them. - (when (and p-name -(string-match "^\"\\(.*\\)\"$" p-name)) -(setq p-name (match-string 1 p-name))) + ;; Remove elements of the mailbox part that are not relevant for + ;; display, even if they are required during transport. + (when p-name + ;; Outer double quotes. + (when (string-match "^\"\\(.*\\)\"$" p-name) + (setq p-name (match-string 1 p-name))) + + ;; Backslashes. + (setq p-name (replace-regexp-in-string "" "" p-name))) ;; If the address is 'foo at bar.com ' then show just ;; 'foo at bar.com'. diff --git a/test/address-cleaning.el b/test/address-cleaning.el index 59e8d92..83d6263 100644 --- a/test/address-cleaning.el +++ b/test/address-cleaning.el @@ -20,10 +20,12 @@ (let* ((input '("?? " "foo (at home) " "foo [at home] " - "Foo Bar")) + "Foo Bar" + "Fred Dibna \\[extraordinaire\\] ")) (expected '("?? " "foo (at home) " "foo [at home] " -"Foo Bar")) +"Foo Bar" +"Fred Dibna [extraordinaire] ")) (output (mapcar #'notmuch-show-clean-address input))) (notmuch-test-compare output expected))) -- 1.7.7.3
[PATCH 3/4] emacs: Avoid `mail-header-parse-address' in `notmuch-show-clean-address'.
`mail-header-parse-address' expects un-decoded mailbox parts, which is not what we have at this point. Replace it with simple string deconstruction. --- emacs/notmuch-show.el | 48 +++- 1 files changed, 35 insertions(+), 13 deletions(-) diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el index 797f94b..8b2fbb3 100644 --- a/emacs/notmuch-show.el +++ b/emacs/notmuch-show.el @@ -227,21 +227,43 @@ indentation." "Try to clean a single email ADDRESS for display. Return unchanged ADDRESS if parsing fails." (condition-case nil -(let* ((parsed (mail-header-parse-address address)) - (address (car parsed)) - (name (cdr parsed))) - ;; Remove double quotes. They might be required during transport, - ;; but we don't need to see them. - (when name -(setq name (replace-regexp-in-string "\"" "" name))) +(let (p-name p-address) + ;; It would be convenient to use `mail-header-parse-address', + ;; but that expects un-decoded mailbox parts, whereas our + ;; mailbox parts are already decoded (and hence may contain + ;; UTF-8). Given that notmuch should handle most of the awkward + ;; cases, some simple string deconstruction should be sufficient + ;; here. + (cond + ;; "User " style. + ((string-match "\\(.*\\) <\\(.*\\)>" address) + (setq p-name (match-string 1 address) + p-address (match-string 2 address))) + + ;; "" style. + ((string-match "<\\(.*\\)>" address) + (setq p-address (match-string 1 address))) + + ;; Everything else. + (t + (setq p-address address))) + + ;; Remove outer double quotes. They might be required during + ;; transport, but we don't need to see them. + (when (and p-name +(string-match "^\"\\(.*\\)\"$" p-name)) +(setq p-name (match-string 1 p-name))) + ;; If the address is 'foo at bar.com ' then show just ;; 'foo at bar.com'. - (when (string= name address) -(setq name nil)) - - (if (not name) -address -(concat name " <" address ">"))) + (when (string= p-name p-address) +(setq p-name nil)) + + ;; If no name results, return just the address. + (if (not p-name) + p-address + ;; Otherwise format the name and address together. + (concat p-name " <" p-address ">"))) (error address))) (defun notmuch-show-insert-headerline (headers date tags depth) -- 1.7.7.3
[PATCH 2/4] test: Add address cleaning tests.
Including some more test framework in test-lib.el. --- test/address-cleaning.el | 29 + test/address-cleaning.sh | 11 +++ test/notmuch-test|1 + test/test-lib.el | 29 + 4 files changed, 70 insertions(+), 0 deletions(-) create mode 100644 test/address-cleaning.el create mode 100755 test/address-cleaning.sh diff --git a/test/address-cleaning.el b/test/address-cleaning.el new file mode 100644 index 000..59e8d92 --- /dev/null +++ b/test/address-cleaning.el @@ -0,0 +1,29 @@ +(defun notmuch-test-address-cleaning-1 () + (notmuch-test-compare (notmuch-show-clean-address "dme at dme.org") + "dme at dme.org")) + +(defun notmuch-test-address-cleaning-2 () + (let* ((input '("foo at bar.com" + "" + "Foo Bar " + "foo at bar.com " + "\"Foo Bar\" ")) +(expected '("foo at bar.com" +"foo at bar.com" +"Foo Bar " +"foo at bar.com" +"Foo Bar ")) +(output (mapcar #'notmuch-show-clean-address input))) +(notmuch-test-compare output expected))) + +(defun notmuch-test-address-cleaning-3 () + (let* ((input '("?? " + "foo (at home) " + "foo [at home] " + "Foo Bar")) +(expected '("?? " +"foo (at home) " +"foo [at home] " +"Foo Bar")) +(output (mapcar #'notmuch-show-clean-address input))) +(notmuch-test-compare output expected))) diff --git a/test/address-cleaning.sh b/test/address-cleaning.sh new file mode 100755 index 000..7ec011a --- /dev/null +++ b/test/address-cleaning.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +test_description="emacs address cleaning" +. test-lib.sh + +for i in 1 2 3; do +test_emacs_expect_t "notmuch-test-address-clean-$i" \ +'(load "address-cleaning.el") (notmuch-test-address-cleaning-'$i')' +done + +test_done diff --git a/test/notmuch-test b/test/notmuch-test index d034f99..7768c32 100755 --- a/test/notmuch-test +++ b/test/notmuch-test @@ -53,6 +53,7 @@ TESTS=" hooks argument-parsing emacs-test-functions.sh + address-cleaning.sh " TESTS=${NOTMUCH_TESTS:=$TESTS} diff --git a/test/test-lib.el b/test/test-lib.el index 3b817c3..cf8a46d 100644 --- a/test/test-lib.el +++ b/test/test-lib.el @@ -20,6 +20,8 @@ ;; ;; Authors: Dmitry Kurochkin +(require 'cl) ;; This code is generally used uncompiled. + ;; `read-file-name' by default uses `completing-read' function to read ;; user input. It does not respect `standard-input' variable which we ;; use in tests to provide user input. So replace it with a plain @@ -76,3 +78,30 @@ nothing." (add-hook-counter 'notmuch-hello-mode-hook) (add-hook-counter 'notmuch-hello-refresh-hook) + +;; Functions to help when writing tests: + +(defun notmuch-test-reporter (output expected) + "Report that the `output' does not match the `expected' result." + (concat "Expect:\t" (prin1-to-string expected) "\n" + "Output:\t" (prin1-to-string output) "\n")) + +(defun notmuch-test-unsimilar (output expected) + "`output' and `expected' are dissimilar. Show a summary of +the differences, ignoring similarities." + (cond ((and (listp output) + (listp expected)) +(apply #'concat (loop for o in output + for e in expected + if (not (equal o e)) + collect (notmuch-test-reporter o e + + (t +;; Catch all case. +(notmuch-test-reporter output expected + +(defun notmuch-test-compare (output expected) + "Compare `output' with `expected'. Report any discrepencies." + (if (equal output expected) + t +(notmuch-test-unsimilar output expected))) -- 1.7.7.3
[PATCH 1/4] test: Add `test_emacs_expect_t'.
Add a new test function to allow simpler testing of emacs functionality. `test_emacs_expect_t' takes two arguments: - the name of the test, - some lisp to evaluate. The test passes if the lisp returns `t', otherwise it fails and the output is reported to the tester. --- test/emacs-test-functions.sh |8 test/notmuch-test|1 + test/test-lib.sh | 24 3 files changed, 33 insertions(+), 0 deletions(-) create mode 100755 test/emacs-test-functions.sh diff --git a/test/emacs-test-functions.sh b/test/emacs-test-functions.sh new file mode 100755 index 000..969cc78 --- /dev/null +++ b/test/emacs-test-functions.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +test_description="emacs test function sanity" +. test-lib.sh + +test_emacs_expect_t "emacs test function sanity" 't' + +test_done diff --git a/test/notmuch-test b/test/notmuch-test index 6a99ae3..d034f99 100755 --- a/test/notmuch-test +++ b/test/notmuch-test @@ -52,6 +52,7 @@ TESTS=" python hooks argument-parsing + emacs-test-functions.sh " TESTS=${NOTMUCH_TESTS:=$TESTS} diff --git a/test/test-lib.sh b/test/test-lib.sh index 7c9ce24..15da973 100644 --- a/test/test-lib.sh +++ b/test/test-lib.sh @@ -503,6 +503,30 @@ test_expect_equal_file () fi } +test_emacs_expect_t () { + test "$#" = 2 || error "bug in the test script: not 2 parameters to test_emacs_expect_t" + test_reset_state_ + if ! test_skip "$1" + then + # We cannot call 'test_emacs' in a subshell, because + # the setting of EMACS_SERVER would not persist + # throughout a sequence of tests, so we use a + # temporary file. + tmp="$TMPDIR"; if [ -z "$tmp" ]; then tmp=/tmp; fi + output="$tmp/test_emacs_output.$$" + test_emacs "$2" >"${output}" + result=$(cat "${output}") + rm -f "${output}" + + if [ "$result" == t ] + then + test_ok_ "$1" + else + test_failure_ "$1" "$(eval printf ${result})" + fi + fi +} + NOTMUCH_NEW () { notmuch new | grep -v -E -e '^Processed [0-9]*( total)? file|Found [0-9]* total file' -- 1.7.7.3
emacs based tests, version 3
Taking Dmitry's suggestions on board. The end result does indeed feel better, thanks! [PATCH 1/4] test: Add `test_emacs_expect_t'. [PATCH 2/4] test: Add address cleaning tests. [PATCH 3/4] emacs: Avoid `mail-header-parse-address' in [PATCH 4/4] emacs: Another special case for
[PATCH] Add pseudo-compatibility with gmime 2.6
> > +printf (", \"sigstatus\": ["); > > + > > +if (!siglist) { > > + printf ("]"); > > + return; > > + } > > + > > +void *ctx_quote = talloc_new (NULL); > > +int i; > > +for (i = 0; i < g_mime_signature_list_length (siglist); ++i) { > > Style nit: notmuch uses i++. > > > + GMimeSignature *signature = g_mime_signature_list_get_signature > > (siglist, i); > > + > > + if (i > 0) > > + printf (", "); > > + > > + printf ("{"); > > + > > + /* status */ > > + GMimeSignatureStatus status = g_mime_signature_get_status (signature); > > + printf ("\"status\": %s", > > + json_quote_str (ctx_quote, > > + signature_status_to_string (status))); > > + > > + GMimeCertificate *certificate = g_mime_signature_get_certificate > > (signature); > > + if (status == GMIME_SIGNATURE_STATUS_GOOD) > > + { > > Style nit: break after brace. > > (Presumably this is copied from the existing > format_part_sigstatus_json, but since it's technically new code > there's no reason not to fix these up.) > > > + if (certificate) > > + printf (", \"fingerprint\": %s", json_quote_str (ctx_quote, > > g_mime_certificate_get_fingerprint (certificate))); > > + /* these dates are seconds since the epoch; should we > > +* provide a more human-readable format string? */ > > + time_t created = g_mime_signature_get_created (signature); > > + if (created != -1) > > + printf (", \"created\": %d", (int) created); > > + time_t expires = g_mime_signature_get_expires (signature); > > + if (expires > 0) > > + printf (", \"expires\": %d", (int) expires); > > Is it intentional that the two above checks are different? I would > think the second should be expires != -1. Yes, it should check for ?expires != -1?. Also, wouldn't it be needed to cast do ?expires != (time_t) -1? to avoid compiler warnings? (time_t may be different from int.) > > + /* output user id only if validity is FULL or ULTIMATE. */ > > + /* note that gmime is using the term "trust" here, which > > +* is WRONG. It's actually user id "validity". */ > > + if (certificate) > > + { > > Break after brace. > > > + const char *name = g_mime_certificate_get_name (certificate); > > + GMimeCertificateTrust trust = g_mime_certificate_get_trust > > (certificate); > > + if (name && (trust == GMIME_CERTIFICATE_TRUST_FULLY || trust == > > GMIME_CERTIFICATE_TRUST_ULTIMATE)) > > + printf (", \"userid\": %s", json_quote_str (ctx_quote, > > name)); > > + } > > + } else if (certificate) { > > + const char *key_id = g_mime_certificate_get_key_id (certificate); > > + if (key_id) > > + printf (", \"keyid\": %s", json_quote_str (ctx_quote, key_id)); > > + } > > + > > + GMimeSignatureError errors = g_mime_signature_get_errors (signature); > > + if (errors != GMIME_SIGNATURE_ERROR_NONE) { > > + printf (", \"errors\": %x", errors); > > This should be %d (I would say 0x%x, but JSON doesn't support hex > literals). I see this bug came from the original > format_part_sigstatus_json. Maybe there should be a quick patch > before this one that fixes the source of the bug? > > > + } > > + > > + printf ("}"); > > + } > > + > > +printf ("]"); > > + > > +talloc_free (ctx_quote); > > +} > > +#else > > static void > > format_part_sigstatus_json (const GMimeSignatureValidity* validity) > > { > > @@ -652,6 +741,7 @@ format_part_sigstatus_json (const > > GMimeSignatureValidity* validity) > > > > talloc_free (ctx_quote); > > } > > +#endif > > > > static void > > format_part_content_json (GMimeObject *part) > > @@ -990,13 +1080,20 @@ notmuch_show_command (void *ctx, unused (int argc), > > unused (char *argv[])) > > } else if ((STRNCMP_LITERAL (argv[i], "--verify") == 0) || > >(STRNCMP_LITERAL (argv[i], "--decrypt") == 0)) { > > if (params.cryptoctx == NULL) { > > +#ifdef GMIME_26 > > + /* TODO: GMimePasswordRequestFunc */ > > + if (NULL == (params.cryptoctx = g_mime_gpg_context_new(NULL, > > "gpg"))) > > +#else > > GMimeSession* session = g_object_new(g_mime_session_get_type(), > > NULL); > > if (NULL == (params.cryptoctx = g_mime_gpg_context_new(session, > > "gpg"))) > > +#endif > > fprintf (stderr, "Failed to construct gpg context.\n"); > > else > > > > g_mime_gpg_context_set_always_trust((GMimeGpgContext*)params.cryptoctx, > > FALSE); > > +#ifndef GMIME_26 > > g_object_unref (session); > > session = NULL; > > +#endif > > } > > if (STRNCMP_LITERAL (argv[i], "--decrypt") == 0) > > params.decrypt = 1; > > diff --git a/show-message.c b/show-message.c > > index 8768889..65269fd 100644 > > --- a/show-message.c > > +++ b/show-message.c > > @@ -48,7 +48,11 @@ show_message_part (mime_node_t *node, > > format->part_encstatus (node->decrypt_success); > > > > if (node->verify_attempted && format->part_sigstatus) > > +#ifdef GMIME_26 > > + format->part_sigstatus (node->sig_list); > > +#else > > format->part_sigstatus (node->sig_validity); > > +#endif > > > > format->part_content (part); > > -- Adrian Perez - Sent from my toaster Igalia - Free Software Engineering -- next part -- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 197 bytes Desc: not available URL: <http://notmuchmail.org/pipermail/notmuch/attachments/20120117/84d3b127/attachment.pgp>
[PATCH 2/3] emacs: whitespace-cleanup and indent-region for emacs/*.el files
On Mon, 16 Jan 2012 23:32:00 -0500, Austin Clements wrote: > Cleanup is the type of pain that should only be suffered once, so I'd > be much happier with this if there was an accompanying git hook that > prevented more mis-formatted code from slipping in. We'd need a script to be called from .git/hooks/pre-commit to do extra checking; developer needs first activate this pre-commit and then add call to our checking routine. Imagine the amount of false positives this hook starts to generate... ... but. developer can run 'git commit --no-verify' ...aargh no; I guess if pre-commit hook fails, commit-msg hook is not run and this is bypassed; maybe NO_FORMATCHECK_HOOK=1 git commit ... is the answer. But what we at least need is Guidelines document that states these formatting issues clearly and precicely. Surely self-respecting programmers understands to follow there (and soon adjusts their workflow -- i.e. activate/run these checkers after list response). > Quoth Tomi Ollila on Jan 16 at 11:04 am: > > diff --git a/emacs/notmuch-lib.el b/emacs/notmuch-lib.el > > index 00ed589..7b63348 100644 > > --- a/emacs/notmuch-lib.el > > +++ b/emacs/notmuch-lib.el > > @@ -143,7 +143,7 @@ The result is a new function which does the same as > > FUN, except that > > the first N arguments are fixed at the values with which this function > > was called." > > (lexical-let ((fun fun) (args1 args)) > > - (lambda (&rest args2) (apply fun (append args1 args2)) > > + (lambda (&rest args2) (apply fun (append args1 args2)) > > Ack. What happened here? This shows up in at least one other place, > too. I'm betting you need to load cl in some form to get the > indentation rule for lexical-let. Yes, thanks. (require 'cl) fixes that. I'll mark this and the RFC patch (of batch-tools.el) obsolete. Tomi
Re: [PATCH 1/1] Make buttons for attachments allow viewing as well as saving
On Tue, 17 Jan 2012 15:26:03 -0500, Austin Clements wrote: > Quoth Mark Walters on Jan 17 at 9:06 am: > > > > > > I wonder if the "problem" comes from me doing things in a non-lispy > > > > fashion (I am completely new to lisp). Thus > > > > notmuch-show-part-button-default-action is a variable that gets passed > > > > around rather than a function. > > > > > > Sorry, I should have looked at the bigger context in this patch. I > > > think Jameson was implying that notmuch-show-part-button-default > > > should change to > > > > > > (defun notmuch-show-part-button-default (&optional button) > > > (interactive) > > > (funcall notmuch-show-part-button-default-action button)) > > > > > > I would go one step further and say that each action should probably > > > be a separate function. That is, break notmuch-show-part-action into > > > separate functions and simply invoke the appropriate function, rather > > > than performing a fixed data dispatch. This would be more flexible > > > and Lispy. It may be that your approach works out better, but I'd at > > > least give this a shot. > > > > I am happy to make that change. My original patch in the summer was more > > like that: > > id:"caludzswato+4mcuoomk+8vfs+pog-xuma6u-aqx2m6-sbyq...@mail.gmail.com" > > Is this the right id? I couldn't find it in the list archive. > > > Is that more what you had in mind? (Only in broad terms: Obviously I > > would need to add in the customization and default function etc). I > > decided that I didn't like the code duplication (but I am completely new > > to lisp) which is why I changed it for this submission. > > Yes, I wondered about this, too. It seems like at worst the > notmuch-show-process-crypto stuff would be duplicated. This might be > little enough that it's not worth worrying about, or it might be worth > introducing something like > > (defun notmuch-with-temp-part-buffer (message-id nth action) > (let ((process-crypto notmuch-show-process-crypto)) > (with-temp-buffer > (setq notmuch-show-process-crypto process-crypto) > ;; Always acquires the part via `notmuch part', even if it is > ;; available in the JSON output. > (insert (notmuch-show-get-bodypart-internal message-id nth)) > (funcall action > > You could also do this as a macro, but that definitely seems like > overkill. It seems to me that a macro is in fact the best solution. If you do it with a function, you need two defuns per action: one to do the actual work: (defun notmuch-show-part-button-whatever-worker () ;; do stuff... ) and one that says: (defun notmuch-show-part-button-whatever () (notmuch-with-temp-part-buffer id part-number #'notmuch-show-part-button-whatever-worker)) It would be the latter function that the key would be bound to. If a macro is used, the split between the worker and glue fns can be abandoned, and only one function is needed: (defun notmuch-show-part-button-whatever () (notmuch-with-temp-part-buffer ;; do stuff... )) A further advantage is if interactive arguments (e.g. C-u prefix) are needed for the function, there is no need to thread them through as arguments of notmuch-with-temp-part-buffer. -- Aaron Ecay ___ notmuch mailing list notmuch@notmuchmail.org http://notmuchmail.org/mailman/listinfo/notmuch
Re: [PATCH] Add pseudo-compatibility with gmime 2.6
Quoth Thomas Jost on Jan 17 at 11:48 am: > On Mon, 16 Jan 2012 22:47:14 -0500, Austin Clements wrote: > > Quoth Thomas Jost on Jan 17 at 12:56 am: > > > This is mostly based on id:"8762i8hrb9@bookbinder.fernseed.info". > > > > > > This was tested against both gmime 2.6.4 and 2.4.31. With gmime 2.4.31, > > > the > > > crypto tests all work fine (as expected). With gmime 2.6.4, one crypto > > > test > > > fails (signature verification with signer key unavailable) but this will > > > be hard > > > to fix since the new API does not report the reason why a signature > > > verification > > > fails (other than the human-readable error message). > > > > What is the result of this failing test? > > The test looks like that: > > FAIL signature verification with signer key unavailable >--- crypto.4.expected 2012-01-16 23:05:06.765651183 + >+++ crypto.4.output 2012-01-16 23:05:06.765651183 + >@@ -12,9 +12,7 @@ > "Bcc": "", > "Date": "01 Jan 2000 12:00:00 -"}, > "body": [{"id": 1, >- "sigstatus": [{"status": "error", >- "keyid": "6D92612D94E46381", >- "errors": 2}], >+ "sigstatus": [], > "content-type": "multipart/signed", > "content": [{"id": 2, > "content-type": "text/plain", >Failed to verify signed part: gpg: keyblock resource > `/home/schnouki/dev/notmuch/test/tmp.crypto/gnupg/pubring.gpg': file open > error >gpg: armor header: Version: GnuPG v1.4.11 (GNU/Linux) >gpg: Signature made Mon Jan 16 23:05:06 2012 UTC using RSA key ID > 94E46381 >gpg: Can't check signature: public key not found > > So basically if a signer public key is missing, we can't get the status > signature: empty "sigstatus" field in the JSON output, "Unknown > signature status" in Emacs. > > IMHO this is a bug in gmime 2.6, and I think I know what causes it. I'll > file a bug in gmime and hopefully they'll find a cleaner way to fix it > than the one I came up with :) Oh, okay. That does seem like a bug in GMime. Do you think it would be possible to mark this test as "broken" if notmuch is using GMime 2.6? Off the top of my head, I can't think of an easy way to plumb that information through to the test suite. I don't think we should push any patches that knowingly break a test, even if it's in just one configuration. > > > > > --- > > > mime-node.c | 50 ++- > > > notmuch-client.h | 27 ++- > > > notmuch-reply.c |7 > > > notmuch-show.c | 97 > > > ++ > > > show-message.c |4 ++ > > > 5 files changed, 181 insertions(+), 4 deletions(-) > > > > > > diff --git a/mime-node.c b/mime-node.c > > > index d26bb44..ae2473d 100644 > > > --- a/mime-node.c > > > +++ b/mime-node.c > > > @@ -33,7 +33,11 @@ typedef struct mime_node_context { > > > GMimeMessage *mime_message; > > > > > > /* Context provided by the caller. */ > > > +#ifdef GMIME_26 > > > +GMimeCryptoContext *cryptoctx; > > > +#else > > > GMimeCipherContext *cryptoctx; > > > +#endif > > > notmuch_bool_t decrypt; > > > } mime_node_context_t; > > > > > > @@ -57,8 +61,12 @@ _mime_node_context_free (mime_node_context_t *res) > > > > > > notmuch_status_t > > > mime_node_open (const void *ctx, notmuch_message_t *message, > > > - GMimeCipherContext *cryptoctx, notmuch_bool_t decrypt, > > > - mime_node_t **root_out) > > > +#ifdef GMIME_26 > > > + GMimeCryptoContext *cryptoctx, > > > +#else > > > + GMimeCipherContext *cryptoctx, > > > +#endif > > > + notmuch_bool_t decrypt, mime_node_t **root_out) > > > { > > > const char *filename = notmuch_message_get_filename (message); > > > mime_node_context_t *mctx; > > > @@ -112,12 +120,21 @@ DONE: > > > return status; > > > } > > > > > > +#ifdef GMIME_26 > > > +static int > > > +_signature_list_free (GMimeSignatureList **proxy) > > > +{ > > > +g_object_unref (*proxy); > > > +return 0; > > > +} > > > +#else > > > static int > > > _signature_validity_free (GMimeSignatureValidity **proxy) > > > { > > > g_mime_signature_validity_free (*proxy); > > > return 0; > > > } > > > +#endif > > > > > > static mime_node_t * > > > _mime_node_create (const mime_node_t *parent, GMimeObject *part) > > > @@ -165,11 +182,23 @@ _mime_node_create (const mime_node_t *parent, > > > GMimeObject *part) > > > GMimeMultipartEncrypted *encrypteddata = > > > GMIME_MULTIPART_ENCRYPTED (part); > > > node->decrypt_attempted = TRUE; > > > +#ifdef GMIME_26 > > > + GMimeDecryptResult *decrypt_result = g_mime_decrypt_result_new (); > > > > I think g_mime_multipart_encrypted_decrypt allocates the > > GMimeDecryptResult for you, so this will just leak memory. > > You're right, fixed. Will it be freed