unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH] emacs: create patch filename from subject for inline patch fake parts
@ 2011-11-18 23:02 Jani Nikula
  2011-12-20 20:05 ` Jani Nikula
                   ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Jani Nikula @ 2011-11-18 23:02 UTC (permalink / raw)
  To: notmuch

Use the mail subject line for creating a descriptive filename for the wash
generated inline patch fake parts. The names are similar to the ones
created by 'git format-patch', just without the leading numbers.

Signed-off-by: Jani Nikula <jani@nikula.org>

---

I know notmuch-subject-to-patch-filename is totally un-lispy. Suggestions
welcome on how to make it lispy and keep it somewhat readable.

If we later want to have a '>' counterpart to '|' to save messages to files
rather than pipe, then this could be generalized and re-used for creating
the suggested filename for that.

I don't even use the notmuch-wash-convert-inline-patch-to-part option that
much, but having it suggest "inline patch" as filename is just ugly...
---
 emacs/notmuch-wash.el |   16 +++++++++++++++-
 1 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
index 1f420b2..755d64a 100644
--- a/emacs/notmuch-wash.el
+++ b/emacs/notmuch-wash.el
@@ -290,6 +290,17 @@ When doing so, maintaining citation leaders in the wrapped text."
 
 (defvar diff-file-header-re) ; From `diff-mode.el'.
 
+(defun notmuch-subject-to-patch-filename (str)
+  "Convert a typical patch mail subject line into a suitable filename."
+  (let ((s str))
+    (setq s (replace-regexp-in-string "^ *\\(\\[[^]]*\\]\\)? *" "" s))
+    (setq s (replace-regexp-in-string "[. ]*$" "" s))
+    (setq s (replace-regexp-in-string "[^A-Za-z0-9._-]+" "-" s))
+    (setq s (replace-regexp-in-string "\\.+" "." s))
+    (when (> (length s) 52)
+      (setq s (substring s 0 52)))
+    (concat s ".patch")))
+
 (defun notmuch-wash-convert-inline-patch-to-part (msg depth)
   "Convert an inline patch into a fake 'text/x-diff' attachment.
 
@@ -316,7 +327,10 @@ for error."
 	    (setq part (plist-put part :content-type "text/x-diff"))
 	    (setq part (plist-put part :content (buffer-string)))
 	    (setq part (plist-put part :id -1))
-	    (setq part (plist-put part :filename "inline patch"))
+	    (setq part (plist-put part :filename
+				  (notmuch-subject-to-patch-filename
+				   (plist-get
+				    (plist-get msg :headers) :Subject))))
 	    (delete-region (point-min) (point-max))
 	    (notmuch-show-insert-bodypart nil part depth))))))
 
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH] emacs: create patch filename from subject for inline patch fake parts
  2011-11-18 23:02 [PATCH] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
@ 2011-12-20 20:05 ` Jani Nikula
  2011-12-20 20:11   ` Dmitry Kurochkin
  2011-12-20 21:52   ` Austin Clements
  2011-12-25 22:00 ` [PATCH v2 0/2] emacs: patch filename from subject Jani Nikula
  2011-12-27 16:04 ` [PATCH v3 0/3] emacs: patch filename from subject Jani Nikula
  2 siblings, 2 replies; 20+ messages in thread
From: Jani Nikula @ 2011-12-20 20:05 UTC (permalink / raw)
  To: notmuch


Shameless promotion of own patches... I suppose not many use the
notmuch-wash-convert-inline-patch-to-part option, but with this patch
I've actually started to like it better. An actual patch name from
subject instead of "inline patch".

As I said, the lisp is less than perfect here, but this is still better
than what's existing.

Any comments?


BR,
Jani.


On Sat, 19 Nov 2011 01:02:48 +0200, Jani Nikula <jani@nikula.org> wrote:
> Use the mail subject line for creating a descriptive filename for the wash
> generated inline patch fake parts. The names are similar to the ones
> created by 'git format-patch', just without the leading numbers.
> 
> Signed-off-by: Jani Nikula <jani@nikula.org>
> 
> ---
> 
> I know notmuch-subject-to-patch-filename is totally un-lispy. Suggestions
> welcome on how to make it lispy and keep it somewhat readable.
> 
> If we later want to have a '>' counterpart to '|' to save messages to files
> rather than pipe, then this could be generalized and re-used for creating
> the suggested filename for that.
> 
> I don't even use the notmuch-wash-convert-inline-patch-to-part option that
> much, but having it suggest "inline patch" as filename is just ugly...
> ---
>  emacs/notmuch-wash.el |   16 +++++++++++++++-
>  1 files changed, 15 insertions(+), 1 deletions(-)
> 
> diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
> index 1f420b2..755d64a 100644
> --- a/emacs/notmuch-wash.el
> +++ b/emacs/notmuch-wash.el
> @@ -290,6 +290,17 @@ When doing so, maintaining citation leaders in the wrapped text."
>  
>  (defvar diff-file-header-re) ; From `diff-mode.el'.
>  
> +(defun notmuch-subject-to-patch-filename (str)
> +  "Convert a typical patch mail subject line into a suitable filename."
> +  (let ((s str))
> +    (setq s (replace-regexp-in-string "^ *\\(\\[[^]]*\\]\\)? *" "" s))
> +    (setq s (replace-regexp-in-string "[. ]*$" "" s))
> +    (setq s (replace-regexp-in-string "[^A-Za-z0-9._-]+" "-" s))
> +    (setq s (replace-regexp-in-string "\\.+" "." s))
> +    (when (> (length s) 52)
> +      (setq s (substring s 0 52)))
> +    (concat s ".patch")))
> +
>  (defun notmuch-wash-convert-inline-patch-to-part (msg depth)
>    "Convert an inline patch into a fake 'text/x-diff' attachment.
>  
> @@ -316,7 +327,10 @@ for error."
>  	    (setq part (plist-put part :content-type "text/x-diff"))
>  	    (setq part (plist-put part :content (buffer-string)))
>  	    (setq part (plist-put part :id -1))
> -	    (setq part (plist-put part :filename "inline patch"))
> +	    (setq part (plist-put part :filename
> +				  (notmuch-subject-to-patch-filename
> +				   (plist-get
> +				    (plist-get msg :headers) :Subject))))
>  	    (delete-region (point-min) (point-max))
>  	    (notmuch-show-insert-bodypart nil part depth))))))
>  
> -- 
> 1.7.5.4
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] emacs: create patch filename from subject for inline patch fake parts
  2011-12-20 20:05 ` Jani Nikula
@ 2011-12-20 20:11   ` Dmitry Kurochkin
  2011-12-20 21:52   ` Austin Clements
  1 sibling, 0 replies; 20+ messages in thread
From: Dmitry Kurochkin @ 2011-12-20 20:11 UTC (permalink / raw)
  To: Jani Nikula, notmuch

Hi Jani.

On Tue, 20 Dec 2011 22:05:31 +0200, Jani Nikula <jani@nikula.org> wrote:
> 
> Shameless promotion of own patches... I suppose not many use the
> notmuch-wash-convert-inline-patch-to-part option, but with this patch
> I've actually started to like it better. An actual patch name from
> subject instead of "inline patch".
> 
> As I said, the lisp is less than perfect here, but this is still better
> than what's existing.
> 
> Any comments?
> 

I do not use the option but the patch sounds useful to me.  I would try
to review it soon.

I think a simple test would be useful here BTW.

Regards,
  Dmitry

> 
> BR,
> Jani.
> 
> 
> On Sat, 19 Nov 2011 01:02:48 +0200, Jani Nikula <jani@nikula.org> wrote:
> > Use the mail subject line for creating a descriptive filename for the wash
> > generated inline patch fake parts. The names are similar to the ones
> > created by 'git format-patch', just without the leading numbers.
> > 
> > Signed-off-by: Jani Nikula <jani@nikula.org>
> > 
> > ---
> > 
> > I know notmuch-subject-to-patch-filename is totally un-lispy. Suggestions
> > welcome on how to make it lispy and keep it somewhat readable.
> > 
> > If we later want to have a '>' counterpart to '|' to save messages to files
> > rather than pipe, then this could be generalized and re-used for creating
> > the suggested filename for that.
> > 
> > I don't even use the notmuch-wash-convert-inline-patch-to-part option that
> > much, but having it suggest "inline patch" as filename is just ugly...
> > ---
> >  emacs/notmuch-wash.el |   16 +++++++++++++++-
> >  1 files changed, 15 insertions(+), 1 deletions(-)
> > 
> > diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
> > index 1f420b2..755d64a 100644
> > --- a/emacs/notmuch-wash.el
> > +++ b/emacs/notmuch-wash.el
> > @@ -290,6 +290,17 @@ When doing so, maintaining citation leaders in the wrapped text."
> >  
> >  (defvar diff-file-header-re) ; From `diff-mode.el'.
> >  
> > +(defun notmuch-subject-to-patch-filename (str)
> > +  "Convert a typical patch mail subject line into a suitable filename."
> > +  (let ((s str))
> > +    (setq s (replace-regexp-in-string "^ *\\(\\[[^]]*\\]\\)? *" "" s))
> > +    (setq s (replace-regexp-in-string "[. ]*$" "" s))
> > +    (setq s (replace-regexp-in-string "[^A-Za-z0-9._-]+" "-" s))
> > +    (setq s (replace-regexp-in-string "\\.+" "." s))
> > +    (when (> (length s) 52)
> > +      (setq s (substring s 0 52)))
> > +    (concat s ".patch")))
> > +
> >  (defun notmuch-wash-convert-inline-patch-to-part (msg depth)
> >    "Convert an inline patch into a fake 'text/x-diff' attachment.
> >  
> > @@ -316,7 +327,10 @@ for error."
> >  	    (setq part (plist-put part :content-type "text/x-diff"))
> >  	    (setq part (plist-put part :content (buffer-string)))
> >  	    (setq part (plist-put part :id -1))
> > -	    (setq part (plist-put part :filename "inline patch"))
> > +	    (setq part (plist-put part :filename
> > +				  (notmuch-subject-to-patch-filename
> > +				   (plist-get
> > +				    (plist-get msg :headers) :Subject))))
> >  	    (delete-region (point-min) (point-max))
> >  	    (notmuch-show-insert-bodypart nil part depth))))))
> >  
> > -- 
> > 1.7.5.4
> > 
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] emacs: create patch filename from subject for inline patch fake parts
  2011-12-20 20:05 ` Jani Nikula
  2011-12-20 20:11   ` Dmitry Kurochkin
@ 2011-12-20 21:52   ` Austin Clements
  2011-12-21  9:21     ` David Edmondson
  1 sibling, 1 reply; 20+ messages in thread
From: Austin Clements @ 2011-12-20 21:52 UTC (permalink / raw)
  To: Jani Nikula; +Cc: notmuch

Seems like a definite improvement, but perhaps a let* instead of all
of the setq's?

Quoth Jani Nikula on Dec 20 at 10:05 pm:
> 
> Shameless promotion of own patches... I suppose not many use the
> notmuch-wash-convert-inline-patch-to-part option, but with this patch
> I've actually started to like it better. An actual patch name from
> subject instead of "inline patch".
> 
> As I said, the lisp is less than perfect here, but this is still better
> than what's existing.
> 
> Any comments?
> 
> 
> BR,
> Jani.
> 
> 
> On Sat, 19 Nov 2011 01:02:48 +0200, Jani Nikula <jani@nikula.org> wrote:
> > Use the mail subject line for creating a descriptive filename for the wash
> > generated inline patch fake parts. The names are similar to the ones
> > created by 'git format-patch', just without the leading numbers.
> > 
> > Signed-off-by: Jani Nikula <jani@nikula.org>
> > 
> > ---
> > 
> > I know notmuch-subject-to-patch-filename is totally un-lispy. Suggestions
> > welcome on how to make it lispy and keep it somewhat readable.
> > 
> > If we later want to have a '>' counterpart to '|' to save messages to files
> > rather than pipe, then this could be generalized and re-used for creating
> > the suggested filename for that.
> > 
> > I don't even use the notmuch-wash-convert-inline-patch-to-part option that
> > much, but having it suggest "inline patch" as filename is just ugly...
> > ---
> >  emacs/notmuch-wash.el |   16 +++++++++++++++-
> >  1 files changed, 15 insertions(+), 1 deletions(-)
> > 
> > diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
> > index 1f420b2..755d64a 100644
> > --- a/emacs/notmuch-wash.el
> > +++ b/emacs/notmuch-wash.el
> > @@ -290,6 +290,17 @@ When doing so, maintaining citation leaders in the wrapped text."
> >  
> >  (defvar diff-file-header-re) ; From `diff-mode.el'.
> >  
> > +(defun notmuch-subject-to-patch-filename (str)
> > +  "Convert a typical patch mail subject line into a suitable filename."
> > +  (let ((s str))
> > +    (setq s (replace-regexp-in-string "^ *\\(\\[[^]]*\\]\\)? *" "" s))
> > +    (setq s (replace-regexp-in-string "[. ]*$" "" s))
> > +    (setq s (replace-regexp-in-string "[^A-Za-z0-9._-]+" "-" s))
> > +    (setq s (replace-regexp-in-string "\\.+" "." s))
> > +    (when (> (length s) 52)
> > +      (setq s (substring s 0 52)))
> > +    (concat s ".patch")))
> > +
> >  (defun notmuch-wash-convert-inline-patch-to-part (msg depth)
> >    "Convert an inline patch into a fake 'text/x-diff' attachment.
> >  
> > @@ -316,7 +327,10 @@ for error."
> >  	    (setq part (plist-put part :content-type "text/x-diff"))
> >  	    (setq part (plist-put part :content (buffer-string)))
> >  	    (setq part (plist-put part :id -1))
> > -	    (setq part (plist-put part :filename "inline patch"))
> > +	    (setq part (plist-put part :filename
> > +				  (notmuch-subject-to-patch-filename
> > +				   (plist-get
> > +				    (plist-get msg :headers) :Subject))))
> >  	    (delete-region (point-min) (point-max))
> >  	    (notmuch-show-insert-bodypart nil part depth))))))

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] emacs: create patch filename from subject for inline patch fake parts
  2011-12-20 21:52   ` Austin Clements
@ 2011-12-21  9:21     ` David Edmondson
  2011-12-21 14:40       ` Austin Clements
  0 siblings, 1 reply; 20+ messages in thread
From: David Edmondson @ 2011-12-21  9:21 UTC (permalink / raw)
  To: Austin Clements, Jani Nikula; +Cc: notmuch

[-- Attachment #1: Type: text/plain, Size: 1354 bytes --]

On Tue, 20 Dec 2011 16:52:52 -0500, Austin Clements <amdragon@MIT.EDU> wrote:
> Seems like a definite improvement, but perhaps a let* instead of all
> of the setq's?

What would be a lispy approach? I tried:

(defun notmuch-subject-to-patch-filename (subject)
  "Convert a typical patch mail subject line into a suitable filename."
  (concat 
   (let ((filename subject)
	 (transforms
	  '(("^ *\\(\\[[^]]*\\]\\)? *" . "")
	    ("[. ]*$" . "")
	    ("[^A-Za-z0-9._-]+" . "-")
	    ("\\.+" . "."))))
     (mapc (lambda (transform)
	     (setq filename (replace-regexp-in-string (car transform) (cdr transform) filename)))
	   transforms)
     (substring filename 0 (min (length filename) 50)))
   ".patch"))

...but that seems a bit unwieldy. `let*' looks best, but still feels a
bit odd:

(defun notmuch-subject-to-patch-filename (subject)
  "Convert a typical patch mail subject line into a suitable filename."
  (concat 
   (let* ((filename (replace-regexp-in-string "^ *\\(\\[[^]]*\\]\\)? *" "" subject))
	  (filename (replace-regexp-in-string "[. ]*$" "" filename))
	  (filename (replace-regexp-in-string "[^A-Za-z0-9._-]+" "-" filename))
	  (filename (replace-regexp-in-string "\\.+" "." filename)))
     (substring filename 0 (min (length filename) 50)))
   ".patch"))

dme.
-- 
David Edmondson, http://dme.org

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] emacs: create patch filename from subject for inline patch fake parts
  2011-12-21  9:21     ` David Edmondson
@ 2011-12-21 14:40       ` Austin Clements
  2011-12-21 20:21         ` Jani Nikula
  0 siblings, 1 reply; 20+ messages in thread
From: Austin Clements @ 2011-12-21 14:40 UTC (permalink / raw)
  To: David Edmondson; +Cc: notmuch

I would definitely go with the latter.

It might feel less unwieldy with a shorter variable name than
"filename", since that has to be repeated so many times.  (It's also
not really a filename in the middle of the replace process.)

This is splitting hairs, but in my original suggestion, I was thinking
something like

  (let* ((s subject)
         (s (replace-regexp-in-string "^ *\\(\\[[^]]*\\]\\)? *" "" s))
         (s (replace-regexp-in-string "[. ]*$" "" s))
         (s (replace-regexp-in-string "[^A-Za-z0-9._-]+" "-" s))
         (s (replace-regexp-in-string "\\.+" "." s))
         (s (substring s 0 (min (length s) 50))))
     (concat s ".patch"))

Out of curiosity, where'd the regexps come from?  They all seem
reasonable, but some of them seem somewhat arbitrary.

Quoth David Edmondson on Dec 21 at  9:21 am:
> On Tue, 20 Dec 2011 16:52:52 -0500, Austin Clements <amdragon@MIT.EDU> wrote:
> > Seems like a definite improvement, but perhaps a let* instead of all
> > of the setq's?
> 
> What would be a lispy approach? I tried:
> 
> (defun notmuch-subject-to-patch-filename (subject)
>   "Convert a typical patch mail subject line into a suitable filename."
>   (concat 
>    (let ((filename subject)
> 	 (transforms
> 	  '(("^ *\\(\\[[^]]*\\]\\)? *" . "")
> 	    ("[. ]*$" . "")
> 	    ("[^A-Za-z0-9._-]+" . "-")
> 	    ("\\.+" . "."))))
>      (mapc (lambda (transform)
> 	     (setq filename (replace-regexp-in-string (car transform) (cdr transform) filename)))
> 	   transforms)
>      (substring filename 0 (min (length filename) 50)))
>    ".patch"))
> 
> ...but that seems a bit unwieldy. `let*' looks best, but still feels a
> bit odd:
> 
> (defun notmuch-subject-to-patch-filename (subject)
>   "Convert a typical patch mail subject line into a suitable filename."
>   (concat 
>    (let* ((filename (replace-regexp-in-string "^ *\\(\\[[^]]*\\]\\)? *" "" subject))
> 	  (filename (replace-regexp-in-string "[. ]*$" "" filename))
> 	  (filename (replace-regexp-in-string "[^A-Za-z0-9._-]+" "-" filename))
> 	  (filename (replace-regexp-in-string "\\.+" "." filename)))
>      (substring filename 0 (min (length filename) 50)))
>    ".patch"))
> 
> dme.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH] emacs: create patch filename from subject for inline patch fake parts
  2011-12-21 14:40       ` Austin Clements
@ 2011-12-21 20:21         ` Jani Nikula
  0 siblings, 0 replies; 20+ messages in thread
From: Jani Nikula @ 2011-12-21 20:21 UTC (permalink / raw)
  To: Austin Clements, David Edmondson; +Cc: notmuch

On Wed, 21 Dec 2011 09:40:08 -0500, Austin Clements <amdragon@MIT.EDU> wrote:
> I would definitely go with the latter.
> 
> It might feel less unwieldy with a shorter variable name than
> "filename", since that has to be repeated so many times.  (It's also
> not really a filename in the middle of the replace process.)
> 
> This is splitting hairs, but in my original suggestion, I was thinking
> something like
> 
>   (let* ((s subject)
>          (s (replace-regexp-in-string "^ *\\(\\[[^]]*\\]\\)? *" "" s))
>          (s (replace-regexp-in-string "[. ]*$" "" s))
>          (s (replace-regexp-in-string "[^A-Za-z0-9._-]+" "-" s))
>          (s (replace-regexp-in-string "\\.+" "." s))
>          (s (substring s 0 (min (length s) 50))))
>      (concat s ".patch"))
> 
> Out of curiosity, where'd the regexps come from?  They all seem
> reasonable, but some of them seem somewhat arbitrary.

The regexps should definitely have some explanation. I tried to mimic
the 'git format-patch' behaviour [1] using as simple and straightforward
regexps as possible. For simplicity, there's no creation of patch
sequence numbers. The max length is the same as in git, excluding the
sequence number.

If the patch was sent using git format-patch/send-email, this should
result in re-creation of the same filename as the sender had (apart from
the sequence number, obviously).

I seem to be missing the trimming of any trailing '.' and '-' after
truncating the string to max length, though.


BR,
Jani.

[1] https://github.com/gitster/git/blob/master/pretty.c#L712

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2 0/2] emacs: patch filename from subject
  2011-11-18 23:02 [PATCH] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
  2011-12-20 20:05 ` Jani Nikula
@ 2011-12-25 22:00 ` Jani Nikula
  2011-12-25 22:00   ` [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
  2011-12-25 22:00   ` [PATCH v2 2/2] test: emacs: test notmuch-wash-subject-to-* functions Jani Nikula
  2011-12-27 16:04 ` [PATCH v3 0/3] emacs: patch filename from subject Jani Nikula
  2 siblings, 2 replies; 20+ messages in thread
From: Jani Nikula @ 2011-12-25 22:00 UTC (permalink / raw)
  To: notmuch

Hi all, v2 with the following changes:

* split the conversion function into three
* figure out patch sequence number from the [PATCH N/M] style prefixes
* write a bunch of tests for the functions
* update the regexps according to bugs found in tests :)

BR,
Jani.


Jani Nikula (2):
  emacs: create patch filename from subject for inline patch fake parts
  test: emacs: test notmuch-wash-subject-to-* functions

 emacs/notmuch-wash.el          |   43 ++++++++++++-
 test/emacs-subject-to-filename |  138 ++++++++++++++++++++++++++++++++++++++++
 test/notmuch-test              |    1 +
 3 files changed, 181 insertions(+), 1 deletions(-)
 create mode 100755 test/emacs-subject-to-filename

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts
  2011-12-25 22:00 ` [PATCH v2 0/2] emacs: patch filename from subject Jani Nikula
@ 2011-12-25 22:00   ` Jani Nikula
  2011-12-26 12:06     ` David Edmondson
  2011-12-25 22:00   ` [PATCH v2 2/2] test: emacs: test notmuch-wash-subject-to-* functions Jani Nikula
  1 sibling, 1 reply; 20+ messages in thread
From: Jani Nikula @ 2011-12-25 22:00 UTC (permalink / raw)
  To: notmuch

Use the mail subject line for creating a descriptive filename for the wash
generated inline patch fake parts. The names are similar to the ones
created by 'git format-patch'.

If the user has notmuch-wash-convert-inline-patch-to-part hook enabled in
notmuch-show-insert-text/plain-hook, this will change the old default
filename of "inline patch":

[ inline patch: text/x-diff ]

into, for example:

[ 0001-emacs-create-patch-filename-from-subject-for-inline.patch: text/x-diff ]

which is typically the same filename the sender had if he was using 'git
format-patch' and 'git send-email'.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-wash.el |   43 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
index 1f420b2..7d037f5 100644
--- a/emacs/notmuch-wash.el
+++ b/emacs/notmuch-wash.el
@@ -290,6 +290,44 @@ When doing so, maintaining citation leaders in the wrapped text."
 
 (defvar diff-file-header-re) ; From `diff-mode.el'.
 
+(defun notmuch-wash-subject-to-filename (subject &optional maxlen)
+  "Convert a mail SUBJECT into a filename.
+
+The resulting filename is similar to the names generated by \"git
+format-patch\", without the leading patch sequence number
+\"0001-\" and \".patch\" extension. Any leading \"[PREFIX]\"
+style strings are removed prior to conversion.
+
+Optional argument MAXLEN is the maximum length of the resulting
+filename, before trimming any trailing . and - characters."
+  (let* ((s (replace-regexp-in-string "^ *\\(\\[[^]]*\\] *\\)*" "" subject))
+	 (s (replace-regexp-in-string "[^A-Za-z0-9._]+" "-" s))
+	 (s (replace-regexp-in-string "\\.+" "." s))
+	 (s (if maxlen (substring s 0 (min (length s) maxlen)) s))
+	 (s (replace-regexp-in-string "[.-]*$" "" s)))
+    s))
+
+(defun notmuch-wash-subject-to-patch-sequence-number (subject)
+  "Convert a patch mail SUBJECT into a patch sequence number.
+
+Return the patch sequence number N from the last \"[PATCH N/M]\"
+style prefix in SUBJECT, or nil if such a prefix can't be found."
+  (when (string-match
+	 "^ *\\(\\[[^]]*\\] *\\)*\\[[^]]*?\\([0-9]+\\)/[0-9]+[^]]*\\].*"
+	 subject)
+      (string-to-number (substring subject (match-beginning 2) (match-end 2)))))
+
+(defun notmuch-wash-subject-to-patch-filename (subject)
+  "Convert a patch mail SUBJECT into a filename.
+
+The resulting filename is similar to the names generated by \"git
+format-patch\". If the patch mail was generated and sent using
+\"git format-patch/send-email\", this should re-create the
+original filename the sender had."
+  (let* ((n (notmuch-wash-subject-to-patch-sequence-number subject))
+	 (n (if n n 1)))
+    (format "%04d-%s.patch" n (notmuch-wash-subject-to-filename subject 52))))
+
 (defun notmuch-wash-convert-inline-patch-to-part (msg depth)
   "Convert an inline patch into a fake 'text/x-diff' attachment.
 
@@ -316,7 +354,10 @@ for error."
 	    (setq part (plist-put part :content-type "text/x-diff"))
 	    (setq part (plist-put part :content (buffer-string)))
 	    (setq part (plist-put part :id -1))
-	    (setq part (plist-put part :filename "inline patch"))
+	    (setq part (plist-put part :filename
+				  (notmuch-wash-subject-to-patch-filename
+				   (plist-get
+				    (plist-get msg :headers) :Subject))))
 	    (delete-region (point-min) (point-max))
 	    (notmuch-show-insert-bodypart nil part depth))))))
 
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v2 2/2] test: emacs: test notmuch-wash-subject-to-* functions
  2011-12-25 22:00 ` [PATCH v2 0/2] emacs: patch filename from subject Jani Nikula
  2011-12-25 22:00   ` [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
@ 2011-12-25 22:00   ` Jani Nikula
  1 sibling, 0 replies; 20+ messages in thread
From: Jani Nikula @ 2011-12-25 22:00 UTC (permalink / raw)
  To: notmuch

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 test/emacs-subject-to-filename |  138 ++++++++++++++++++++++++++++++++++++++++
 test/notmuch-test              |    1 +
 2 files changed, 139 insertions(+), 0 deletions(-)
 create mode 100755 test/emacs-subject-to-filename

diff --git a/test/emacs-subject-to-filename b/test/emacs-subject-to-filename
new file mode 100755
index 0000000..176e685
--- /dev/null
+++ b/test/emacs-subject-to-filename
@@ -0,0 +1,138 @@
+#!/usr/bin/env bash
+
+test_description="emacs: mail subject to filename"
+. test-lib.sh
+
+# emacs server can't be started in a child process with $(test_emacs ...)
+test_emacs '(ignore)'
+
+# test notmuch-wash-subject-to-patch-sequence-number (subject)
+test_begin_subtest "no patch sequence number"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[PATCH] A normal patch subject without numbers")'
+)
+test_expect_equal "$output" ""
+
+test_begin_subtest "patch sequence number #1"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[PATCH 2/3] A most regular patch subject")'
+)
+test_expect_equal "$output" 2
+
+test_begin_subtest "patch sequence number #2"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "  [dummy list prefix]  [RFC PATCH v2 13/42]  Special prefixes")'
+)
+test_expect_equal "$output" 13
+
+test_begin_subtest "patch sequence number #3"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[PATCH 2/3] [PATCH 032/037] use the last prefix")'
+)
+test_expect_equal "$output" 32
+
+test_begin_subtest "patch sequence number #4"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[dummy list prefix] [PATCH 2/3] PATCH 3/3] do not use a broken prefix")'
+)
+test_expect_equal "$output" 2
+
+test_begin_subtest "patch sequence number #5"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[RFC][PATCH 3/5][PATCH 4/5][PATCH 5/5] A made up test")'
+)
+test_expect_equal "$output" 5
+
+test_begin_subtest "patch sequence number #6"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[PATCH 2/3] this -> [PATCH 3/3] is not a prefix anymore [nor this 4/4]")'
+)
+test_expect_equal "$output" 2
+
+test_begin_subtest "patch sequence number #7"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[liberally accept crapola right before123/456and after] the numbers")'
+)
+test_expect_equal "$output" 123
+
+# test notmuch-wash-subject-to-filename (subject &optional maxlen)
+test_begin_subtest "filename #1"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "just a subject line")'
+)
+test_expect_equal $output '"just-a-subject-line"'
+
+test_begin_subtest "filename #2"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      " [any]  [prefixes are ] [removed!] from the subject")'
+)
+test_expect_equal $output '"from-the-subject"'
+
+test_begin_subtest "filename #3"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "  leading and trailing space  ")'
+)
+test_expect_equal $output '"leading-and-trailing-space"'
+
+test_begin_subtest "filename #4"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "!#  leading ()// &%, and in between_and_trailing garbage ()(&%%")'
+)
+test_expect_equal $output '"-leading-and-in-between_and_trailing-garbage"'
+
+test_begin_subtest "filename #5"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_01234567890")'
+)
+test_expect_equal $output '"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_01234567890"'
+
+test_begin_subtest "filename #6"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "sequences of ... are squashed and trailing are removed ...")'
+)
+test_expect_equal $output '"sequences-of-.-are-squashed-and-trailing-are-removed"'
+
+test_begin_subtest "filename #7"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "max length test" 1)'
+)
+test_expect_equal $output '"m"'
+
+test_begin_subtest "filename #8"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "max length test /&(/%&/%%&¤%¤" 20)'
+)
+test_expect_equal $output '"max-length-test"'
+
+test_begin_subtest "filename #9"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "[a prefix] [is only separated] by [spaces], so \"by\" is not okay!")'
+)
+test_expect_equal $output '"by-spaces-so-by-is-not-okay"'
+
+# test notmuch-wash-subject-to-patch-filename (subject)
+test_begin_subtest "patch filename #1"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-filename
+      "[RFC][PATCH 099/100] rewrite notmuch")'
+)
+test_expect_equal "$output" '"0099-rewrite-notmuch.patch"'
+
+test_begin_subtest "patch filename #2"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-filename
+      "[RFC PATCH v1] has no patch number, default to 1")'
+)
+test_expect_equal "$output" '"0001-has-no-patch-number-default-to-1.patch"'
+
+test_begin_subtest "patch filename #3"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-filename
+      "[PATCH 4/5] the maximum length of a patch filename is 52 + patch sequence number + .patch extension")'
+)
+test_expect_equal "$output" '"0004-the-maximum-length-of-a-patch-filename-is-52-patch-s.patch"'
+
+test_begin_subtest "patch filename #4"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-filename
+      "[PATCH 4/5] the maximum length of a patch filename is 52 + patchh ! sequence number + .patch extension, *before* trimming trailing - and .")'
+)
+test_expect_equal "$output" '"0004-the-maximum-length-of-a-patch-filename-is-52-patchh.patch"'
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index ded79e8..e40ef86 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -42,6 +42,7 @@ TESTS="
   encoding
   emacs
   emacs-large-search-buffer
+  emacs-subject-to-filename
   maildir-sync
   crypto
   symbol-hiding
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts
  2011-12-25 22:00   ` [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
@ 2011-12-26 12:06     ` David Edmondson
  2011-12-26 12:24       ` Jani Nikula
  0 siblings, 1 reply; 20+ messages in thread
From: David Edmondson @ 2011-12-26 12:06 UTC (permalink / raw)
  To: Jani Nikula, notmuch

[-- Attachment #1: Type: text/plain, Size: 1022 bytes --]

On Mon, 26 Dec 2011 00:00:05 +0200, Jani Nikula <jani@nikula.org> wrote:
> +(defun notmuch-wash-subject-to-patch-filename (subject)
> +  "Convert a patch mail SUBJECT into a filename.
> +
> +The resulting filename is similar to the names generated by \"git
> +format-patch\". If the patch mail was generated and sent using
> +\"git format-patch/send-email\", this should re-create the
> +original filename the sender had."
> +  (let* ((n (notmuch-wash-subject-to-patch-sequence-number subject))
> +	 (n (if n n 1)))
> +    (format "%04d-%s.patch" n (notmuch-wash-subject-to-filename subject 52))))
> +

(format "%04d-%s.patch"
  (or (notmuch-wash-subject-to-patch-sequence-number subject) 1)
  (notmuch-wash-subject-to-filename subject 52))

or something would be more lispy.

Clicking on the button for the part saves the wrong thing, though,
because it's not a real MIME part. That looks a bit awkward to fix, so
perhaps you could still prefix the name with "inline: " to indicate that
it's odd?

Otherwise, looks good.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts
  2011-12-26 12:06     ` David Edmondson
@ 2011-12-26 12:24       ` Jani Nikula
  2011-12-26 20:38         ` Jameson Graef Rollins
  0 siblings, 1 reply; 20+ messages in thread
From: Jani Nikula @ 2011-12-26 12:24 UTC (permalink / raw)
  To: David Edmondson, notmuch

On Mon, 26 Dec 2011 12:06:02 +0000, David Edmondson <dme@dme.org> wrote:
> On Mon, 26 Dec 2011 00:00:05 +0200, Jani Nikula <jani@nikula.org> wrote:
> > +(defun notmuch-wash-subject-to-patch-filename (subject)
> > +  "Convert a patch mail SUBJECT into a filename.
> > +
> > +The resulting filename is similar to the names generated by \"git
> > +format-patch\". If the patch mail was generated and sent using
> > +\"git format-patch/send-email\", this should re-create the
> > +original filename the sender had."
> > +  (let* ((n (notmuch-wash-subject-to-patch-sequence-number subject))
> > +	 (n (if n n 1)))
> > +    (format "%04d-%s.patch" n (notmuch-wash-subject-to-filename subject 52))))
> > +
> 
> (format "%04d-%s.patch"
>   (or (notmuch-wash-subject-to-patch-sequence-number subject) 1)
>   (notmuch-wash-subject-to-filename subject 52))
> 
> or something would be more lispy.

Yes, definitely. I am still very much a beginner in lisp.

> Clicking on the button for the part saves the wrong thing, though,
> because it's not a real MIME part. That looks a bit awkward to fix, so
> perhaps you could still prefix the name with "inline: " to indicate that
> it's odd?

I'm not sure I follow you here. Could you elaborate what you mean by
"the wrong thing", please?

I don't think the user would want to have an "inline: " prefix in the
filename that would have to be removed every time. I think that kind of
defeats the purpose here. Or where exactly are you proposing to have the
prefix?


BR,
Jani.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts
  2011-12-26 12:24       ` Jani Nikula
@ 2011-12-26 20:38         ` Jameson Graef Rollins
  2011-12-26 21:52           ` Jani Nikula
  0 siblings, 1 reply; 20+ messages in thread
From: Jameson Graef Rollins @ 2011-12-26 20:38 UTC (permalink / raw)
  To: Jani Nikula, David Edmondson, notmuch

[-- Attachment #1: Type: text/plain, Size: 1467 bytes --]

On Mon, 26 Dec 2011 14:24:42 +0200, Jani Nikula <jani@nikula.org> wrote:
> > Clicking on the button for the part saves the wrong thing, though,
> > because it's not a real MIME part. That looks a bit awkward to fix, so
> > perhaps you could still prefix the name with "inline: " to indicate that
> > it's odd?
> 
> I'm not sure I follow you here. Could you elaborate what you mean by
> "the wrong thing", please?

Yes, this is a problem/bug with the current behavior of these fake
inline parts, actually.  The button should behave as those it is
representing an actual MIME part of the message.  However, clicking the
button saves the entire part that the fake part is derived from, rather
than just the data in the fake part.  This is countereintuitive and
confusing.

> I don't think the user would want to have an "inline: " prefix in the
> filename that would have to be removed every time. I think that kind of
> defeats the purpose here. Or where exactly are you proposing to have the
> prefix?

It's confusing to have this fake part button look just like a real part
button, without any indication that it's really a fake part, and then to
behave differently as well.  The button needs some indication that it
does not represent a real mime part of the message.  Giving the fake
part a proper filename is fine, but it needs some other indicator that
the part is fake and that the button is not going to behave as expected.

jamie.

[-- Attachment #2: Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts
  2011-12-26 20:38         ` Jameson Graef Rollins
@ 2011-12-26 21:52           ` Jani Nikula
  2011-12-26 22:05             ` David Edmondson
  0 siblings, 1 reply; 20+ messages in thread
From: Jani Nikula @ 2011-12-26 21:52 UTC (permalink / raw)
  To: Jameson Graef Rollins, David Edmondson, notmuch

On Mon, 26 Dec 2011 12:38:35 -0800, Jameson Graef Rollins <jrollins@finestructure.net> wrote:
> On Mon, 26 Dec 2011 14:24:42 +0200, Jani Nikula <jani@nikula.org> wrote:
> > > Clicking on the button for the part saves the wrong thing, though,
> > > because it's not a real MIME part. That looks a bit awkward to fix, so
> > > perhaps you could still prefix the name with "inline: " to indicate that
> > > it's odd?
> > 
> > I'm not sure I follow you here. Could you elaborate what you mean by
> > "the wrong thing", please?
> 
> Yes, this is a problem/bug with the current behavior of these fake
> inline parts, actually.  The button should behave as those it is
> representing an actual MIME part of the message.  However, clicking the
> button saves the entire part that the fake part is derived from, rather
> than just the data in the fake part.  This is countereintuitive and
> confusing.

Okay, thanks for the explanation. This might be beyond my elisp
skills. And IMHO out of the scope of the patch anyway.

> > I don't think the user would want to have an "inline: " prefix in the
> > filename that would have to be removed every time. I think that kind of
> > defeats the purpose here. Or where exactly are you proposing to have the
> > prefix?
> 
> It's confusing to have this fake part button look just like a real part
> button, without any indication that it's really a fake part, and then to
> behave differently as well.  The button needs some indication that it
> does not represent a real mime part of the message.  Giving the fake
> part a proper filename is fine, but it needs some other indicator that
> the part is fake and that the button is not going to behave as expected.

Below is an idea I came up with, utilizing the content-type
vs. declared-type distinction. I think it's really simple and neat, but
I hope not too magical.

Picking up an example mail from the list, inline patches would show up
like this:

[ 0001-emacs-unify-search-mechanisms.patch: inline patch (as text/x-diff) ]


BR,
Jani.


From b1847714f7368247fbc5c93767f59d8269eadc1c Mon Sep 17 00:00:00 2001
From: Jani Nikula <jani@nikula.org>
Date: Mon, 26 Dec 2011 23:31:41 +0200
Subject: [PATCH] emacs: add inline patch fake parts through a special handler

Add wash generated inline patch fake parts through a special
"inline-patch-fake-part" handler to distinguish them from real MIME
parts. The fake parts are described as "inline patch (as text/x-diff)".

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-show.el |    4 ++++
 emacs/notmuch-wash.el |    2 +-
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index eee4da9..6ef3f90 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -585,6 +585,10 @@ current buffer, if possible."
 		nil))
 	  nil))))
 
+;; Handler for wash generated inline patch fake parts.
+(defun notmuch-show-insert-part-inline-patch-fake-part (msg part content-type nth depth declared-type)
+  (notmuch-show-insert-part-*/* msg part "text/x-diff" nth depth "inline patch"))
+
 (defun notmuch-show-insert-part-*/* (msg part content-type nth depth declared-type)
   ;; This handler _must_ succeed - it is the handler of last resort.
   (notmuch-show-insert-part-header nth content-type declared-type (plist-get part :filename))
diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
index 7d037f5..de51c88 100644
--- a/emacs/notmuch-wash.el
+++ b/emacs/notmuch-wash.el
@@ -351,7 +351,7 @@ for error."
 	      (setq patch-end (match-beginning 0)))
 	  (save-restriction
 	    (narrow-to-region patch-start patch-end)
-	    (setq part (plist-put part :content-type "text/x-diff"))
+	    (setq part (plist-put part :content-type "inline-patch-fake-part"))
 	    (setq part (plist-put part :content (buffer-string)))
 	    (setq part (plist-put part :id -1))
 	    (setq part (plist-put part :filename
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts
  2011-12-26 21:52           ` Jani Nikula
@ 2011-12-26 22:05             ` David Edmondson
  0 siblings, 0 replies; 20+ messages in thread
From: David Edmondson @ 2011-12-26 22:05 UTC (permalink / raw)
  To: Jani Nikula, Jameson Graef Rollins, notmuch

[-- Attachment #1: Type: text/plain, Size: 430 bytes --]

On Mon, 26 Dec 2011 23:52:23 +0200, Jani Nikula <jani@nikula.org> wrote:
> Below is an idea I came up with, utilizing the content-type
> vs. declared-type distinction. I think it's really simple and neat,
> but I hope not too magical.
> 
> Picking up an example mail from the list, inline patches would show up
> like this:
> 
> [ 0001-emacs-unify-search-mechanisms.patch: inline patch (as text/x-diff) ]

I like this.

[-- Attachment #2: Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v3 0/3] emacs: patch filename from subject
  2011-11-18 23:02 [PATCH] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
  2011-12-20 20:05 ` Jani Nikula
  2011-12-25 22:00 ` [PATCH v2 0/2] emacs: patch filename from subject Jani Nikula
@ 2011-12-27 16:04 ` Jani Nikula
  2011-12-27 16:04   ` [PATCH v3 1/3] emacs: add inline patch fake parts through a special handler Jani Nikula
                     ` (3 more replies)
  2 siblings, 4 replies; 20+ messages in thread
From: Jani Nikula @ 2011-12-27 16:04 UTC (permalink / raw)
  To: notmuch

Hi all, v3 with the following changes:

* new patch 1/3 to add fake parts through a special handler to make them stand
  out from real MIME parts

* make notmuch-wash-subject-to-patch-filename more lispy as suggested by David
  in id:"cun62h3tu51.fsf@hotblack-desiato.hh.sledj.net"

BR,
Jani.

Jani Nikula (3):
  emacs: add inline patch fake parts through a special handler
  emacs: create patch filename from subject for inline patch fake parts
  test: emacs: test notmuch-wash-subject-to-* functions

 emacs/notmuch-show.el          |    4 +
 emacs/notmuch-wash.el          |   45 ++++++++++++-
 test/emacs-subject-to-filename |  138 ++++++++++++++++++++++++++++++++++++++++
 test/notmuch-test              |    1 +
 4 files changed, 186 insertions(+), 2 deletions(-)
 create mode 100755 test/emacs-subject-to-filename

-- 
1.7.5.4

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v3 1/3] emacs: add inline patch fake parts through a special handler
  2011-12-27 16:04 ` [PATCH v3 0/3] emacs: patch filename from subject Jani Nikula
@ 2011-12-27 16:04   ` Jani Nikula
  2011-12-27 16:04   ` [PATCH v3 2/3] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Jani Nikula @ 2011-12-27 16:04 UTC (permalink / raw)
  To: notmuch

Add wash generated inline patch fake parts through a special
"inline-patch-fake-part" handler to distinguish them from real MIME
parts. The fake parts are described as "inline patch (as text/x-diff)".

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-show.el |    4 ++++
 emacs/notmuch-wash.el |    2 +-
 2 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index eee4da9..6ef3f90 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -585,6 +585,10 @@ current buffer, if possible."
 		nil))
 	  nil))))
 
+;; Handler for wash generated inline patch fake parts.
+(defun notmuch-show-insert-part-inline-patch-fake-part (msg part content-type nth depth declared-type)
+  (notmuch-show-insert-part-*/* msg part "text/x-diff" nth depth "inline patch"))
+
 (defun notmuch-show-insert-part-*/* (msg part content-type nth depth declared-type)
   ;; This handler _must_ succeed - it is the handler of last resort.
   (notmuch-show-insert-part-header nth content-type declared-type (plist-get part :filename))
diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
index 1f420b2..e9f2dba 100644
--- a/emacs/notmuch-wash.el
+++ b/emacs/notmuch-wash.el
@@ -313,7 +313,7 @@ for error."
 	      (setq patch-end (match-beginning 0)))
 	  (save-restriction
 	    (narrow-to-region patch-start patch-end)
-	    (setq part (plist-put part :content-type "text/x-diff"))
+	    (setq part (plist-put part :content-type "inline-patch-fake-part"))
 	    (setq part (plist-put part :content (buffer-string)))
 	    (setq part (plist-put part :id -1))
 	    (setq part (plist-put part :filename "inline patch"))
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 2/3] emacs: create patch filename from subject for inline patch fake parts
  2011-12-27 16:04 ` [PATCH v3 0/3] emacs: patch filename from subject Jani Nikula
  2011-12-27 16:04   ` [PATCH v3 1/3] emacs: add inline patch fake parts through a special handler Jani Nikula
@ 2011-12-27 16:04   ` Jani Nikula
  2011-12-27 16:04   ` [PATCH v3 3/3] test: emacs: test notmuch-wash-subject-to-* functions Jani Nikula
  2011-12-28 12:22   ` [PATCH v3 0/3] emacs: patch filename from subject David Bremner
  3 siblings, 0 replies; 20+ messages in thread
From: Jani Nikula @ 2011-12-27 16:04 UTC (permalink / raw)
  To: notmuch

Use the mail subject line for creating a descriptive filename for the wash
generated inline patch fake parts. The names are similar to the ones
created by 'git format-patch'.

If the user has notmuch-wash-convert-inline-patch-to-part hook enabled in
notmuch-show-insert-text/plain-hook, this will change the old default
filename of "inline patch" in fake parts:

[ inline patch: inline patch (as text/x-diff) ]

into, for example:

[ 0002-emacs-create-patch-filename-from-subject-for-inline.patch: inline patch (as text/x-diff) ]

which is typically the same filename the sender had if he was using 'git
format-patch' and 'git send-email'.

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 emacs/notmuch-wash.el |   43 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 42 insertions(+), 1 deletions(-)

diff --git a/emacs/notmuch-wash.el b/emacs/notmuch-wash.el
index e9f2dba..5c1e830 100644
--- a/emacs/notmuch-wash.el
+++ b/emacs/notmuch-wash.el
@@ -290,6 +290,44 @@ When doing so, maintaining citation leaders in the wrapped text."
 
 (defvar diff-file-header-re) ; From `diff-mode.el'.
 
+(defun notmuch-wash-subject-to-filename (subject &optional maxlen)
+  "Convert a mail SUBJECT into a filename.
+
+The resulting filename is similar to the names generated by \"git
+format-patch\", without the leading patch sequence number
+\"0001-\" and \".patch\" extension. Any leading \"[PREFIX]\"
+style strings are removed prior to conversion.
+
+Optional argument MAXLEN is the maximum length of the resulting
+filename, before trimming any trailing . and - characters."
+  (let* ((s (replace-regexp-in-string "^ *\\(\\[[^]]*\\] *\\)*" "" subject))
+	 (s (replace-regexp-in-string "[^A-Za-z0-9._]+" "-" s))
+	 (s (replace-regexp-in-string "\\.+" "." s))
+	 (s (if maxlen (substring s 0 (min (length s) maxlen)) s))
+	 (s (replace-regexp-in-string "[.-]*$" "" s)))
+    s))
+
+(defun notmuch-wash-subject-to-patch-sequence-number (subject)
+  "Convert a patch mail SUBJECT into a patch sequence number.
+
+Return the patch sequence number N from the last \"[PATCH N/M]\"
+style prefix in SUBJECT, or nil if such a prefix can't be found."
+  (when (string-match
+	 "^ *\\(\\[[^]]*\\] *\\)*\\[[^]]*?\\([0-9]+\\)/[0-9]+[^]]*\\].*"
+	 subject)
+      (string-to-number (substring subject (match-beginning 2) (match-end 2)))))
+
+(defun notmuch-wash-subject-to-patch-filename (subject)
+  "Convert a patch mail SUBJECT into a filename.
+
+The resulting filename is similar to the names generated by \"git
+format-patch\". If the patch mail was generated and sent using
+\"git format-patch/send-email\", this should re-create the
+original filename the sender had."
+  (format "%04d-%s.patch"
+	  (or (notmuch-wash-subject-to-patch-sequence-number subject) 1)
+	  (notmuch-wash-subject-to-filename subject 52)))
+
 (defun notmuch-wash-convert-inline-patch-to-part (msg depth)
   "Convert an inline patch into a fake 'text/x-diff' attachment.
 
@@ -316,7 +354,10 @@ for error."
 	    (setq part (plist-put part :content-type "inline-patch-fake-part"))
 	    (setq part (plist-put part :content (buffer-string)))
 	    (setq part (plist-put part :id -1))
-	    (setq part (plist-put part :filename "inline patch"))
+	    (setq part (plist-put part :filename
+				  (notmuch-wash-subject-to-patch-filename
+				   (plist-get
+				    (plist-get msg :headers) :Subject))))
 	    (delete-region (point-min) (point-max))
 	    (notmuch-show-insert-bodypart nil part depth))))))
 
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 3/3] test: emacs: test notmuch-wash-subject-to-* functions
  2011-12-27 16:04 ` [PATCH v3 0/3] emacs: patch filename from subject Jani Nikula
  2011-12-27 16:04   ` [PATCH v3 1/3] emacs: add inline patch fake parts through a special handler Jani Nikula
  2011-12-27 16:04   ` [PATCH v3 2/3] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
@ 2011-12-27 16:04   ` Jani Nikula
  2011-12-28 12:22   ` [PATCH v3 0/3] emacs: patch filename from subject David Bremner
  3 siblings, 0 replies; 20+ messages in thread
From: Jani Nikula @ 2011-12-27 16:04 UTC (permalink / raw)
  To: notmuch

Signed-off-by: Jani Nikula <jani@nikula.org>
---
 test/emacs-subject-to-filename |  138 ++++++++++++++++++++++++++++++++++++++++
 test/notmuch-test              |    1 +
 2 files changed, 139 insertions(+), 0 deletions(-)
 create mode 100755 test/emacs-subject-to-filename

diff --git a/test/emacs-subject-to-filename b/test/emacs-subject-to-filename
new file mode 100755
index 0000000..176e685
--- /dev/null
+++ b/test/emacs-subject-to-filename
@@ -0,0 +1,138 @@
+#!/usr/bin/env bash
+
+test_description="emacs: mail subject to filename"
+. test-lib.sh
+
+# emacs server can't be started in a child process with $(test_emacs ...)
+test_emacs '(ignore)'
+
+# test notmuch-wash-subject-to-patch-sequence-number (subject)
+test_begin_subtest "no patch sequence number"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[PATCH] A normal patch subject without numbers")'
+)
+test_expect_equal "$output" ""
+
+test_begin_subtest "patch sequence number #1"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[PATCH 2/3] A most regular patch subject")'
+)
+test_expect_equal "$output" 2
+
+test_begin_subtest "patch sequence number #2"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "  [dummy list prefix]  [RFC PATCH v2 13/42]  Special prefixes")'
+)
+test_expect_equal "$output" 13
+
+test_begin_subtest "patch sequence number #3"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[PATCH 2/3] [PATCH 032/037] use the last prefix")'
+)
+test_expect_equal "$output" 32
+
+test_begin_subtest "patch sequence number #4"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[dummy list prefix] [PATCH 2/3] PATCH 3/3] do not use a broken prefix")'
+)
+test_expect_equal "$output" 2
+
+test_begin_subtest "patch sequence number #5"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[RFC][PATCH 3/5][PATCH 4/5][PATCH 5/5] A made up test")'
+)
+test_expect_equal "$output" 5
+
+test_begin_subtest "patch sequence number #6"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[PATCH 2/3] this -> [PATCH 3/3] is not a prefix anymore [nor this 4/4]")'
+)
+test_expect_equal "$output" 2
+
+test_begin_subtest "patch sequence number #7"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-sequence-number
+      "[liberally accept crapola right before123/456and after] the numbers")'
+)
+test_expect_equal "$output" 123
+
+# test notmuch-wash-subject-to-filename (subject &optional maxlen)
+test_begin_subtest "filename #1"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "just a subject line")'
+)
+test_expect_equal $output '"just-a-subject-line"'
+
+test_begin_subtest "filename #2"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      " [any]  [prefixes are ] [removed!] from the subject")'
+)
+test_expect_equal $output '"from-the-subject"'
+
+test_begin_subtest "filename #3"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "  leading and trailing space  ")'
+)
+test_expect_equal $output '"leading-and-trailing-space"'
+
+test_begin_subtest "filename #4"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "!#  leading ()// &%, and in between_and_trailing garbage ()(&%%")'
+)
+test_expect_equal $output '"-leading-and-in-between_and_trailing-garbage"'
+
+test_begin_subtest "filename #5"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_01234567890")'
+)
+test_expect_equal $output '"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.-_01234567890"'
+
+test_begin_subtest "filename #6"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "sequences of ... are squashed and trailing are removed ...")'
+)
+test_expect_equal $output '"sequences-of-.-are-squashed-and-trailing-are-removed"'
+
+test_begin_subtest "filename #7"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "max length test" 1)'
+)
+test_expect_equal $output '"m"'
+
+test_begin_subtest "filename #8"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "max length test /&(/%&/%%&¤%¤" 20)'
+)
+test_expect_equal $output '"max-length-test"'
+
+test_begin_subtest "filename #9"
+output=$(test_emacs '(notmuch-wash-subject-to-filename
+      "[a prefix] [is only separated] by [spaces], so \"by\" is not okay!")'
+)
+test_expect_equal $output '"by-spaces-so-by-is-not-okay"'
+
+# test notmuch-wash-subject-to-patch-filename (subject)
+test_begin_subtest "patch filename #1"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-filename
+      "[RFC][PATCH 099/100] rewrite notmuch")'
+)
+test_expect_equal "$output" '"0099-rewrite-notmuch.patch"'
+
+test_begin_subtest "patch filename #2"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-filename
+      "[RFC PATCH v1] has no patch number, default to 1")'
+)
+test_expect_equal "$output" '"0001-has-no-patch-number-default-to-1.patch"'
+
+test_begin_subtest "patch filename #3"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-filename
+      "[PATCH 4/5] the maximum length of a patch filename is 52 + patch sequence number + .patch extension")'
+)
+test_expect_equal "$output" '"0004-the-maximum-length-of-a-patch-filename-is-52-patch-s.patch"'
+
+test_begin_subtest "patch filename #4"
+output=$(test_emacs '(notmuch-wash-subject-to-patch-filename
+      "[PATCH 4/5] the maximum length of a patch filename is 52 + patchh ! sequence number + .patch extension, *before* trimming trailing - and .")'
+)
+test_expect_equal "$output" '"0004-the-maximum-length-of-a-patch-filename-is-52-patchh.patch"'
+
+test_done
diff --git a/test/notmuch-test b/test/notmuch-test
index ded79e8..e40ef86 100755
--- a/test/notmuch-test
+++ b/test/notmuch-test
@@ -42,6 +42,7 @@ TESTS="
   encoding
   emacs
   emacs-large-search-buffer
+  emacs-subject-to-filename
   maildir-sync
   crypto
   symbol-hiding
-- 
1.7.5.4

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 0/3] emacs: patch filename from subject
  2011-12-27 16:04 ` [PATCH v3 0/3] emacs: patch filename from subject Jani Nikula
                     ` (2 preceding siblings ...)
  2011-12-27 16:04   ` [PATCH v3 3/3] test: emacs: test notmuch-wash-subject-to-* functions Jani Nikula
@ 2011-12-28 12:22   ` David Bremner
  3 siblings, 0 replies; 20+ messages in thread
From: David Bremner @ 2011-12-28 12:22 UTC (permalink / raw)
  To: Jani Nikula, notmuch

On Tue, 27 Dec 2011 18:04:37 +0200, Jani Nikula <jani@nikula.org> wrote:
> Hi all, v3 with the following changes:
> 
> * new patch 1/3 to add fake parts through a special handler to make them stand
>   out from real MIME parts
> 

Pushed.

d

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2011-12-28 12:22 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-18 23:02 [PATCH] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
2011-12-20 20:05 ` Jani Nikula
2011-12-20 20:11   ` Dmitry Kurochkin
2011-12-20 21:52   ` Austin Clements
2011-12-21  9:21     ` David Edmondson
2011-12-21 14:40       ` Austin Clements
2011-12-21 20:21         ` Jani Nikula
2011-12-25 22:00 ` [PATCH v2 0/2] emacs: patch filename from subject Jani Nikula
2011-12-25 22:00   ` [PATCH v2 1/2] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
2011-12-26 12:06     ` David Edmondson
2011-12-26 12:24       ` Jani Nikula
2011-12-26 20:38         ` Jameson Graef Rollins
2011-12-26 21:52           ` Jani Nikula
2011-12-26 22:05             ` David Edmondson
2011-12-25 22:00   ` [PATCH v2 2/2] test: emacs: test notmuch-wash-subject-to-* functions Jani Nikula
2011-12-27 16:04 ` [PATCH v3 0/3] emacs: patch filename from subject Jani Nikula
2011-12-27 16:04   ` [PATCH v3 1/3] emacs: add inline patch fake parts through a special handler Jani Nikula
2011-12-27 16:04   ` [PATCH v3 2/3] emacs: create patch filename from subject for inline patch fake parts Jani Nikula
2011-12-27 16:04   ` [PATCH v3 3/3] test: emacs: test notmuch-wash-subject-to-* functions Jani Nikula
2011-12-28 12:22   ` [PATCH v3 0/3] emacs: patch filename from subject David Bremner

Code repositories for project(s) associated with this public inbox

	https://yhetil.org/notmuch.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).