[RFC PATCHv2 6/8] vim: show: add multipart/alternative picking

Subject: [RFC PATCHv2 6/8] vim: show: add multipart/alternative picking

Date: Thu, 13 Oct 2016 14:47:54 -0600

To: notmuch@notmuchmail.org

Cc: nlhowell@gmail.com

From: Nick Howell


Instead of just blindly showing every part of multipart/*, add special
handling for multipart/alternative (which is designed for alternative
content-types containing the same message). Two new preferences are
added:

- g:notmuch_multipart_alternative_display
        = "best-only" (default)
        Display only the favorite content-type.

        = "best-sort"
        Display all content-types, sorted by preference.

        = "verbatim"
        Display all content-types in the order they appear.

- g:notmuch_multipart_alternative_preference
        Array which orders mimetypes based on preference; note that if a
        part has a mimetype which matches none of these, the part will
        not be displayed!

        e.g. ['text/plain', 'text/*', '*'] (default)

The RFC describing multipart/alternative has some subtleties regarding
ways the sender can influence which content-type is shown; we mostly
ignore these, and give the user the choice.

Note that the defaults break some mail programs (**cough apple**) which,
when attaching images, prefer to embed the image in text/html, but then
list a multipart/alternative of text/plain without attaching the image.
---
 vim/notmuch.vim | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/vim/notmuch.vim b/vim/notmuch.vim
index 5cb8d20..795ab26 100644
--- a/vim/notmuch.vim
+++ b/vim/notmuch.vim
@@ -61,6 +61,8 @@ let s:notmuch_sendmail_default = 'sendmail'
 let s:notmuch_folders_count_threads_default = 0
 let s:notmuch_compose_start_insert_default = 1
 let s:notmuch_mailcap_filter_default = "DISPLAY= run-mailcap --action=view %s:-"
+let s:notmuch_multipart_alternative_display_default = "best-only"
+let s:notmuch_multipart_alternative_preference_default = ['text/plain', 'text/*', '*']
 
 function! s:new_file_buffer(type, fname)
 	exec printf('edit %s', a:fname)
@@ -324,6 +326,8 @@ ruby << EOF
 			nm_m = Message.new(msg, m)
 			$messages << nm_m
 			mailcap = VIM::evaluate('g:notmuch_mailcap_filter')
+			alternative_preference = VIM::evaluate('g:notmuch_multipart_alternative_preference')
+			alternative_display = VIM::evaluate('g:notmuch_multipart_alternative_display')
 			date_fmt = VIM::evaluate('g:notmuch_datetime_format')
 			date = Time.at(msg.date).strftime(date_fmt)
 			nm_m.start = b.count
@@ -337,7 +341,24 @@ ruby << EOF
 			while parts.any?(&:multipart?)
 				parts = parts.collect do |part|
 					if part.multipart?
-						part.parts
+						if part.mime_type == "multipart/alternative"
+							case alternative_display
+							when "best-only"
+								alternative_preference.each.collect do |mime_type|
+									part.parts.find { |p| File.fnmatch(mime_type, p.mime_type) }
+								end.first
+							when "best-sort"
+								part.parts.sort_by do |p|
+									alternative_preference.collect.with_index do |mime_type, i|
+										(File.fnmatch(mime_type, p.mime_type) ? 0 : 1) << i
+									end.reduce(:+)
+								end
+							when "verbatim"
+								part.parts
+							end
+						else
+							part.parts
+						end
 					else
 						part
 					end
@@ -417,6 +438,14 @@ endfunction
 "" root
 
 function! s:set_defaults()
+	if !exists('g:notmuch_multipart_alternative_display')
+		let g:notmuch_multipart_alternative_display = s:notmuch_multipart_alternative_display_default
+	endif
+
+	if !exists('g:notmuch_multipart_alternative_preference')
+		let g:notmuch_multipart_alternative_preference = s:notmuch_multipart_alternative_preference_default
+	endif
+
 	if !exists('g:notmuch_mailcap_filter')
 		let g:notmuch_mailcap_filter = s:notmuch_mailcap_filter_default
 	endif
-- 
2.7.3


Thread: