Add mailcap filters, which allow us to display multiple parts. See http://packages.debian.org/unstable/net/mime-support for details on run-mailcap, the mailcap program we default to; the TLDR is that mailcap is a program which accepts a mimetype argument, looks up a translation program based on this, and hooks up stdin/stdout to this program. This is useful for inline display of html, pdfs, docx, images (through caca), etc, as well as external display (by launching an image viewer). The implementation here linearizes the part tree of the message (treating all multipart pieces as multipart/mixed) and then popens a mailcap process for each. If mailcap fails for some reason (e.g. no display rule), the contents are listed as "unavailable." A sample $HOME/.mailcap configuration file: application/pdf; pdftotext -layout '%s' - | fmt; copiousoutput; text/html; vilistextum -u '%s' -w 72 -; copiousoutput; text/plain; fmt -s Some suggested converters: - antiword, antixls, vilistextum, docx2txt --- vim/notmuch.vim | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/vim/notmuch.vim b/vim/notmuch.vim index ad8b7c8..c66c874 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -60,6 +60,7 @@ let s:notmuch_reader_default = 'mutt -f %s' 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 = "run-mailcap --action=view %s:-" function! s:new_file_buffer(type, fname) exec printf('edit %s', a:fname) @@ -320,9 +321,9 @@ ruby << EOF msgs = q.search_messages msgs.each do |msg| m = Mail.read(msg.filename) - part = m.find_first_text nm_m = Message.new(msg, m) $messages << nm_m + mailcap = VIM::evaluate('g:notmuch_mailcap_filter') date_fmt = VIM::evaluate('g:notmuch_datetime_format') date = Time.at(msg.date).strftime(date_fmt) nm_m.start = b.count @@ -332,9 +333,31 @@ ruby << EOF b << "Cc: %s" % msg['cc'] b << "Date: %s" % msg['date'] nm_m.body_start = b.count - b << "--- %s ---" % part.mime_type - part.convert.each_line do |l| - b << l.chomp + parts = [m] + while parts.any?(&:multipart?) + parts = parts.collect do |part| + if part.multipart? + part.parts + else + part + end + end.flatten + end + + parts.each do |part| + b << "--- %s ---" % part.mime_type + begin + IO.popen(mailcap % part.mime_type, "r+b") do |io| + io.write(part.decoded) + io.close_write + io.each_line do |l| + b << l.chomp + end + end + rescue + b << "--- unavailable ---" + end + b << "" end b << "" nm_m.end = b.count @@ -393,6 +416,9 @@ endfunction "" root function! s:set_defaults() + if !exists('g:notmuch_mailcap_filter') + let g:notmuch_mailcap_filter = s:notmuch_mailcap_filter_default + endif if !exists('g:notmuch_date_format') if exists('g:notmuch_rb_date_format') let g:notmuch_date_format = g:notmuch_rb_date_format -- 2.7.3