Adds attachment support through the mail gem. Notmuch-Attach headers list files which are added to the message before sending. Files are added by constructing a new post-processed transport Mail object using the Notmuch-Attach header and the original Mail object. Any attachments added (say by hand, or by some other method) to the pre-transport message are preserved. Adds a helper which prompts for an attachment (with filename completion) and adds the header for you (bound to ,a). --- vim/notmuch.vim | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/vim/notmuch.vim b/vim/notmuch.vim index bea30f8..09685c3 100644 --- a/vim/notmuch.vim +++ b/vim/notmuch.vim @@ -45,6 +45,7 @@ let g:notmuch_show_maps = { let g:notmuch_compose_maps = { \ ',s': 'compose_send()', + \ ',a': 'compose_attach()', \ ',q': 'compose_quit()', \ } @@ -84,6 +85,20 @@ function! s:compose_quit() call s:kill_this_buffer() endfunction +function! s:compose_attach() +ruby << EOF + raise "Attachment support unavailable." unless NotmuchHeaders.include?("Attach") +EOF + let attachment = input('attach: ', '~/', 'file') +ruby << EOF + r, c = $curwin.cursor + non_help_lines = (1..$curbuf.count).reject { |i| $curbuf[i].start_with?("Notmuch-Help: ") } + attachment = File.expand_path(VIM::evaluate('attachment')) + $curbuf.append(non_help_lines[0] - 1, "Notmuch-Attach: #{attachment}") + $curwin.cursor = [r + 1, c] +EOF +endfunction + function! s:compose_send() let b:compose_done = 1 let fname = expand('%') @@ -91,18 +106,39 @@ function! s:compose_send() ruby << EOF # Generate proper mail to send text = [] + attachments = [] eval_nm_headers = true VIM::evaluate('getline(0, \'$\')').each do |line| unless eval_nm_headers and NotmuchHeaders.any? { |h| line.start_with?("Notmuch-#{h}: ") } text << line eval_nm_headers = false + else + if line.start_with?("Notmuch-Attach: ") + attachments << line["Notmuch-Attach: ".length..-1] + end end end fname = VIM::evaluate('fname') transport = Mail.new(text.join("\n")) transport.message_id = generate_message_id transport.charset = 'utf-8' - File.write(fname, transport.to_s) + + transport_fin = Mail.new do + transport.header_fields.reject do |f| + [ + "Content-Type", + "Content-Transfer-Encoding", + ].include?(f.name) + end.each do |f| + header[f.name] = f.value + end + transport.attachments.each { |a| add_file(:filename => a.filename, :mime_type => a.mime_type, :content => a.decoded) } + attachments.each { |a| add_file(a) } + + body (transport.find_first_text || transport).body.to_s + end + + File.write(fname, transport_fin.to_s) EOF let cmdtxt = g:notmuch_sendmail . ' -t -f ' . s:reply_from . ' < ' . fname @@ -489,7 +525,9 @@ ruby << EOF $messages = [] $mail_installed = defined?(Mail) - NotmuchHeaders = ["Help"] + NotmuchHeaders = ["Help", + $mail_installed && "Attach", + ].select { |s| s.is_a?(String) } def get_config_item(item) result = '' @@ -557,9 +595,10 @@ ruby << EOF help_lines = [ 'Notmuch-Help: Type in your message here; to help you use these bindings:', 'Notmuch-Help: ,s - send the message', + NotmuchHeaders.include?("Attach") && 'Notmuch-Help: ,a - prompt for attachment', 'Notmuch-Help: ,q - abort the message', "Notmuch-Help: Magic Notmuch- headers (removed on send): #{NotmuchHeaders.join(", ")}.", - ] + ].select { |s| s.is_a?(String) } dir = File.expand_path('~/.notmuch/compose') FileUtils.mkdir_p(dir) -- 2.7.3