[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-18 Thread Austin Clements
Quoth Mark Walters on Jan 18 at 10:46 am:
> 
> > > +(defun notmuch-show-view-part (message-id nth  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 ( 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 ( args) (notmuch-show-save-part 
> >message-id nth filename content-type)))
> >   (mm-display-part handle))
> 
> Unfortunately that does not work since mm-display-part has a local
> variable "filename".  I could copy the variables to some notmuch
> prefixed variables but maybe there is some obvious "quoting" to avoid
> the problem? (I can't easily check now as the gnu site is closed for the
> day.)

Arrrg, dynamic scoping.  Well, you can

;; Lexically bind everything we need in mm-save-part to prevent
;; potential dynamic shadowing.
(lexical-let ((message-id message-id)
  (nth nth)
  (filename filename)
  (content-type content-type))
  (flet ((mm-save-part ( args) (notmuch-show-save-part 
 message-id nth filename content-type)))
(mm-display-part handle)))

Or you could just, y'know, do what were doing.


[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-18 Thread Mark Walters

> > +(defun notmuch-show-view-part (message-id nth  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 ( 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 ( args) (notmuch-show-save-part 
>message-id nth filename content-type)))
>   (mm-display-part handle))

Unfortunately that does not work since mm-display-part has a local
variable "filename".  I could copy the variables to some notmuch
prefixed variables but maybe there is some obvious "quoting" to avoid
the problem? (I can't easily check now as the gnu site is closed for the
day.)

Best wishes

Mark


[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-18 Thread Antoine Beaupré
On Tue, 17 Jan 2012 23:44:46 +, Mark Walters  
wrote:
> 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)

This works pretty much as advertised, +1 from me, good work.

A.

-- 
C'est trop facile quand les guerres sont finies
D'aller gueuler que c'?tait la derni?re
Amis bourgeois vous me faites envie
Ne voyez vous pas donc point vos cimeti?res?
- Jaques Brel
-- next part --
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 835 bytes
Desc: not available
URL: 



[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-18 Thread Mark Walters

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


Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-18 Thread Mark Walters

  +(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))

Unfortunately that does not work since mm-display-part has a local
variable filename.  I could copy the variables to some notmuch
prefixed variables but maybe there is some obvious quoting to avoid
the problem? (I can't easily check now as the gnu site is closed for the
day.)

Best wishes

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


Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-18 Thread Austin Clements
Quoth Mark Walters on Jan 18 at 10:46 am:
 
   +(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))
 
 Unfortunately that does not work since mm-display-part has a local
 variable filename.  I could copy the variables to some notmuch
 prefixed variables but maybe there is some obvious quoting to avoid
 the problem? (I can't easily check now as the gnu site is closed for the
 day.)

Arrrg, dynamic scoping.  Well, you can

;; Lexically bind everything we need in mm-save-part to prevent
;; potential dynamic shadowing.
(lexical-let ((message-id message-id)
  (nth nth)
  (filename filename)
  (content-type content-type))
  (flet ((mm-save-part (rest args) (notmuch-show-save-part 
 message-id nth filename content-type)))
(mm-display-part handle)))

Or you could just, y'know, do what were doing.
___
notmuch mailing list
notmuch@notmuchmail.org
http://notmuchmail.org/mailman/listinfo/notmuch


[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Mark Walters
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 
 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  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  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  filename content-type)
+  (notmuch-with-temp-part-buffer message-id nth
+(let ((file (read-file-name
+"Filename to save as: "
+(or mailcap-download-directory "~/")
+nil nil
+filename)))
+  ;; Don't re-compress .gz & al.  Arguably we should make
+  ;; `file-name-handler-alist' nil, but that would chop
+  ;; ange-ftp, which is reasonable to use here.
+  (mm-write-region (point-min) (point-max) file nil nil nil 'no-conversion 
t
+
+(defun notmuch-show-view-part (message-id nth  filename content-type )
+  (notmuch-with-temp-part-buffer message-id nth
+;; 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  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-part-button-action (button)
-  (let ((nth 

[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Austin Clements
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  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 ( 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 ( args) (notmuch-show-save-part 
   message-id nth filename content-type)))
  (mm-display-part handle))

(Yeah, flet indentation is lame.)

> Best wishes
> 
> Mark


[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Austin Clements
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 
>  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  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  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  filename 
> content-type)
> +  (notmuch-with-temp-part-buffer message-id nth
> +(let ((file (read-file-name
> +  "Filename to save as: "
> +  (or mailcap-download-directory "~/")
> +  nil nil
> +  filename)))
> +  ;; Don't re-compress .gz & al.  Arguably we should make
> +  ;; `file-name-handler-alist' nil, but that would chop
> +  ;; ange-ftp, which is reasonable to use here.
> +  (mm-write-region (point-min) (point-max) file nil nil nil 
> 'no-conversion t
> +
> +(defun notmuch-show-view-part (message-id nth  filename 
> content-type )
> +  (notmuch-with-temp-part-buffer message-id nth
> +;; 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  
> filename content-type)
> +  (notmuch-with-temp-part-buffer message-id nth
> +(let ((handle (mm-make-handle 

[PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Mark Walters
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-show-part-button-action (button)
-  

Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Austin Clements
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 message-id nth
 +(let ((handle (mm-make-handle (current-buffer) (list content-type
 +  (mm-interactively-view-part handle
  
  (defun 

Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving

2012-01-17 Thread Mark Walters

 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


Re: [PATCH v3] Make buttons for attachments allow viewing as well as saving

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