unofficial mirror of notmuch@notmuchmail.org
 help / color / mirror / code / Atom feed
* [PATCH] VIM: Add better attachment support
@ 2014-10-02  7:48 Ian Main
  2014-10-10  9:57 ` Franz Fellner
  2014-10-23 22:04 ` Ian Main
  0 siblings, 2 replies; 4+ messages in thread
From: Ian Main @ 2014-10-02  7:48 UTC (permalink / raw)
  To: notmuch

This patch changes how the notmuch vim client supports attachments:

- For each attachment an 'Attachment <number>: <filename>' is added
  to the header
- You can then use 'e' to extract the attachment under the cursor
  or use it elsewhere to extract all attachments (the prior behavior)
- You can use 'v' to 'view' the attachment using xdg-open by default.

    Ian
---
 vim/notmuch.txt |  8 +++++++-
 vim/notmuch.vim | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/vim/notmuch.txt b/vim/notmuch.txt
index 4374102..838a904 100644
--- a/vim/notmuch.txt
+++ b/vim/notmuch.txt
@@ -72,6 +72,9 @@ q	Quit view
 A	Archive (-inbox -unread)
 I	Mark as read (-unread)
 t	Tag (prompted)
+e       Extract attachment on the current 'Attachment' line or all
+	attachments if the cursor is elsewhere.
+v       View attachment on the current 'Attachment' line.
 s	Search
 p	Save patches
 r	Reply
@@ -148,6 +151,9 @@ You can also configure your externail mail reader and sendemail program:
 >
 	let g:notmuch_reader = 'mutt -f %s'
 	let g:notmuch_sendmail = 'sendmail'
-<
+
+You can also configure what probram is used to view attachments:
+
+	let g:notmuch_view_attachment = 'xdg-open'
 
 vim:tw=78:ts=8:noet:ft=help:
diff --git a/vim/notmuch.vim b/vim/notmuch.vim
index 331e930..a5830b5 100644
--- a/vim/notmuch.vim
+++ b/vim/notmuch.vim
@@ -35,6 +35,7 @@ let g:notmuch_show_maps = {
 	\ 't':		'show_tag("")',
 	\ 'o':		'show_open_msg()',
 	\ 'e':		'show_extract_msg()',
+	\ 'v':		'show_view_attachment()',
 	\ 's':		'show_save_msg()',
 	\ 'p':		'show_save_patches()',
 	\ 'r':		'show_reply()',
@@ -58,6 +59,8 @@ let s:notmuch_date_format_default = '%d.%m.%y'
 let s:notmuch_datetime_format_default = '%d.%m.%y %H:%M:%S'
 let s:notmuch_reader_default = 'mutt -f %s'
 let s:notmuch_sendmail_default = 'sendmail'
+let s:notmuch_view_attachment_default = 'xdg-open'
+let s:notmuch_attachment_tmpdir_default = '~/.notmuch/tmp'
 let s:notmuch_folders_count_threads_default = 0
 
 function! s:new_file_buffer(type, fname)
@@ -147,13 +150,53 @@ function! s:show_info()
 	ruby vim_puts get_message.inspect
 endfunction
 
+function! s:show_view_attachment()
+	let line = getline(".")
+ruby << EOF
+	m = get_message
+	line = VIM::evaluate('line')
+
+	match = line.match(/^Attachment (\d*):/)
+	if match and match.length == 2
+		a = m.mail.attachments[match[1].to_i - 1]
+		tmpdir = VIM::evaluate('g:notmuch_attachment_tmpdir')
+		tmpdir = File.expand_path(tmpdir)
+		Dir.mkdir(tmpdir) unless Dir.exists?(tmpdir)
+		filename = File.expand_path("#{tmpdir}/#{a.filename}")
+		vim_puts "Viewing attachment #{filename}"
+		File.open(filename, 'w') do |f|
+			f.write a.body.decoded
+			cmd = VIM::evaluate('g:notmuch_view_attachment')
+			system(cmd, filename)
+		end
+	else
+		vim_puts "No attachment on this line."
+	end
+EOF
+endfunction
+
 function! s:show_extract_msg()
+	let line = getline(".")
 ruby << EOF
 	m = get_message
-	m.mail.attachments.each do |a|
+	line = VIM::evaluate('line')
+
+	# If the user is on a line that has an 'Attachment'
+	# line, we just extract the one attachment.
+	match = line.match(/^Attachment (\d*):/)
+	if match and match.length == 2
+		a = m.mail.attachments[match[1].to_i - 1]
 		File.open(a.filename, 'w') do |f|
 			f.write a.body.decoded
-			print "Extracted '#{a.filename}'"
+			vim_puts "Extracted #{a.filename}"
+		end
+	else
+		# Extract them all..
+		m.mail.attachments.each do |a|
+			File.open(a.filename, 'w') do |f|
+				f.write a.body.decoded
+				vim_puts "Extracted #{a.filename}"
+			end
 		end
 	end
 EOF
@@ -326,6 +369,11 @@ ruby << EOF
 			b << "To: %s" % msg['to']
 			b << "Cc: %s" % msg['cc']
 			b << "Date: %s" % msg['date']
+			cnt = 0
+			nm_m.mail.attachments.each do |a|
+				cnt += 1
+				b << "Attachment %d: %s" % [cnt, a.filename]
+			end
 			nm_m.body_start = b.count
 			b << "--- %s ---" % part.mime_type
 			part.convert.each_line do |l|
@@ -420,6 +468,14 @@ function! s:set_defaults()
 		endif
 	endif
 
+	if !exists('g:notmuch_attachment_tmpdir')
+		let g:notmuch_attachment_tmpdir = s:notmuch_attachment_tmpdir_default
+	endif
+
+	if !exists('g:notmuch_view_attachment')
+		let g:notmuch_view_attachment = s:notmuch_view_attachment_default
+	endif
+
 	if !exists('g:notmuch_folders_count_threads')
 		if exists('g:notmuch_rb_count_threads')
 			let g:notmuch_count_threads = g:notmuch_rb_count_threads
-- 
1.9.3

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

* Re: [PATCH] VIM: Add better attachment support
  2014-10-02  7:48 [PATCH] VIM: Add better attachment support Ian Main
@ 2014-10-10  9:57 ` Franz Fellner
  2014-10-10 18:15   ` Ian Main
  2014-10-23 22:04 ` Ian Main
  1 sibling, 1 reply; 4+ messages in thread
From: Franz Fellner @ 2014-10-10  9:57 UTC (permalink / raw)
  To: notmuch

It works as described. But IMHO it would be better to prompt the user to
enter the location where he wants to save the attachment(s). This path
could be taken if s:notmuch_attachment_tmpdir_default is set to empty.
Or implement a different function for "save to".

On Thu,  2 Oct 2014 00:48:52 -0700, Ian Main <imain@stemwinder.org> wrote:
> This patch changes how the notmuch vim client supports attachments:
> 
> - For each attachment an 'Attachment <number>: <filename>' is added
>   to the header
> - You can then use 'e' to extract the attachment under the cursor
>   or use it elsewhere to extract all attachments (the prior behavior)
> - You can use 'v' to 'view' the attachment using xdg-open by default.
> 
>     Ian
> ---
>  vim/notmuch.txt |  8 +++++++-
>  vim/notmuch.vim | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 65 insertions(+), 3 deletions(-)
> 
> diff --git a/vim/notmuch.txt b/vim/notmuch.txt
> index 4374102..838a904 100644
> --- a/vim/notmuch.txt
> +++ b/vim/notmuch.txt
> @@ -72,6 +72,9 @@ q	Quit view
>  A	Archive (-inbox -unread)
>  I	Mark as read (-unread)
>  t	Tag (prompted)
> +e       Extract attachment on the current 'Attachment' line or all
> +	attachments if the cursor is elsewhere.
> +v       View attachment on the current 'Attachment' line.
>  s	Search
>  p	Save patches
>  r	Reply
> @@ -148,6 +151,9 @@ You can also configure your externail mail reader and sendemail program:
>  >
>  	let g:notmuch_reader = 'mutt -f %s'
>  	let g:notmuch_sendmail = 'sendmail'
> -<
> +
> +You can also configure what probram is used to view attachments:
> +
> +	let g:notmuch_view_attachment = 'xdg-open'
>  
>  vim:tw=78:ts=8:noet:ft=help:
> diff --git a/vim/notmuch.vim b/vim/notmuch.vim
> index 331e930..a5830b5 100644
> --- a/vim/notmuch.vim
> +++ b/vim/notmuch.vim
> @@ -35,6 +35,7 @@ let g:notmuch_show_maps = {
>  	\ 't':		'show_tag("")',
>  	\ 'o':		'show_open_msg()',
>  	\ 'e':		'show_extract_msg()',
> +	\ 'v':		'show_view_attachment()',
>  	\ 's':		'show_save_msg()',
>  	\ 'p':		'show_save_patches()',
>  	\ 'r':		'show_reply()',
> @@ -58,6 +59,8 @@ let s:notmuch_date_format_default = '%d.%m.%y'
>  let s:notmuch_datetime_format_default = '%d.%m.%y %H:%M:%S'
>  let s:notmuch_reader_default = 'mutt -f %s'
>  let s:notmuch_sendmail_default = 'sendmail'
> +let s:notmuch_view_attachment_default = 'xdg-open'
> +let s:notmuch_attachment_tmpdir_default = '~/.notmuch/tmp'
>  let s:notmuch_folders_count_threads_default = 0
>  
>  function! s:new_file_buffer(type, fname)
> @@ -147,13 +150,53 @@ function! s:show_info()
>  	ruby vim_puts get_message.inspect
>  endfunction
>  
> +function! s:show_view_attachment()
> +	let line = getline(".")
> +ruby << EOF
> +	m = get_message
> +	line = VIM::evaluate('line')
> +
> +	match = line.match(/^Attachment (\d*):/)
> +	if match and match.length == 2
> +		a = m.mail.attachments[match[1].to_i - 1]
> +		tmpdir = VIM::evaluate('g:notmuch_attachment_tmpdir')
> +		tmpdir = File.expand_path(tmpdir)
> +		Dir.mkdir(tmpdir) unless Dir.exists?(tmpdir)
> +		filename = File.expand_path("#{tmpdir}/#{a.filename}")
> +		vim_puts "Viewing attachment #{filename}"
> +		File.open(filename, 'w') do |f|
> +			f.write a.body.decoded
> +			cmd = VIM::evaluate('g:notmuch_view_attachment')
> +			system(cmd, filename)
> +		end
> +	else
> +		vim_puts "No attachment on this line."
> +	end
> +EOF
> +endfunction
> +
>  function! s:show_extract_msg()
> +	let line = getline(".")
>  ruby << EOF
>  	m = get_message
> -	m.mail.attachments.each do |a|
> +	line = VIM::evaluate('line')
> +
> +	# If the user is on a line that has an 'Attachment'
> +	# line, we just extract the one attachment.
> +	match = line.match(/^Attachment (\d*):/)
> +	if match and match.length == 2
> +		a = m.mail.attachments[match[1].to_i - 1]
>  		File.open(a.filename, 'w') do |f|
>  			f.write a.body.decoded
> -			print "Extracted '#{a.filename}'"
> +			vim_puts "Extracted #{a.filename}"
> +		end
> +	else
> +		# Extract them all..
> +		m.mail.attachments.each do |a|
> +			File.open(a.filename, 'w') do |f|
> +				f.write a.body.decoded
> +				vim_puts "Extracted #{a.filename}"
> +			end
>  		end
>  	end
>  EOF
> @@ -326,6 +369,11 @@ ruby << EOF
>  			b << "To: %s" % msg['to']
>  			b << "Cc: %s" % msg['cc']
>  			b << "Date: %s" % msg['date']
> +			cnt = 0
> +			nm_m.mail.attachments.each do |a|
> +				cnt += 1
> +				b << "Attachment %d: %s" % [cnt, a.filename]
> +			end
>  			nm_m.body_start = b.count
>  			b << "--- %s ---" % part.mime_type
>  			part.convert.each_line do |l|
> @@ -420,6 +468,14 @@ function! s:set_defaults()
>  		endif
>  	endif
>  
> +	if !exists('g:notmuch_attachment_tmpdir')
> +		let g:notmuch_attachment_tmpdir = s:notmuch_attachment_tmpdir_default
> +	endif
> +
> +	if !exists('g:notmuch_view_attachment')
> +		let g:notmuch_view_attachment = s:notmuch_view_attachment_default
> +	endif
> +
>  	if !exists('g:notmuch_folders_count_threads')
>  		if exists('g:notmuch_rb_count_threads')
>  			let g:notmuch_count_threads = g:notmuch_rb_count_threads
> -- 
> 1.9.3
> 
> _______________________________________________
> notmuch mailing list
> notmuch@notmuchmail.org
> http://notmuchmail.org/mailman/listinfo/notmuch

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

* Re: [PATCH] VIM: Add better attachment support
  2014-10-10  9:57 ` Franz Fellner
@ 2014-10-10 18:15   ` Ian Main
  0 siblings, 0 replies; 4+ messages in thread
From: Ian Main @ 2014-10-10 18:15 UTC (permalink / raw)
  To: Franz Fellner; +Cc: notmuch

Franz Fellner wrote:
> It works as described. But IMHO it would be better to prompt the user to
> enter the location where he wants to save the attachment(s). This path
> could be taken if s:notmuch_attachment_tmpdir_default is set to empty.
> Or implement a different function for "save to".

It would be easy to add a filename prompt for saving a specific attachment.
I can preload it with the default value and it'll just mean one more keystroke
if that location is ok with you.

Sound good?

    Ian

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

* [PATCH] VIM: Add better attachment support
  2014-10-02  7:48 [PATCH] VIM: Add better attachment support Ian Main
  2014-10-10  9:57 ` Franz Fellner
@ 2014-10-23 22:04 ` Ian Main
  1 sibling, 0 replies; 4+ messages in thread
From: Ian Main @ 2014-10-23 22:04 UTC (permalink / raw)
  To: notmuch

This patch changes how the notmuch vim client supports attachments:

- For each message part a 'Part <number>: <filename>' is added
  to the header.
- You can then use 'e' to extract the attachment under the cursor
  or use it elsewhere to extract all attachments (the prior behavior)
- You can use 'v' to 'view' the attachment/part using xdg-open by default.
- If the message is 'text/html' we include a 'Part:' for the body of the
  message so you can easily view it in a web browser if you so choose.

    Ian
---
 vim/notmuch.txt |  8 +++++-
 vim/notmuch.vim | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 89 insertions(+), 3 deletions(-)

diff --git a/vim/notmuch.txt b/vim/notmuch.txt
index 4374102..838a904 100644
--- a/vim/notmuch.txt
+++ b/vim/notmuch.txt
@@ -72,6 +72,9 @@ q	Quit view
 A	Archive (-inbox -unread)
 I	Mark as read (-unread)
 t	Tag (prompted)
+e       Extract attachment on the current 'Attachment' line or all
+	attachments if the cursor is elsewhere.
+v       View attachment on the current 'Attachment' line.
 s	Search
 p	Save patches
 r	Reply
@@ -148,6 +151,9 @@ You can also configure your externail mail reader and sendemail program:
 >
 	let g:notmuch_reader = 'mutt -f %s'
 	let g:notmuch_sendmail = 'sendmail'
-<
+
+You can also configure what probram is used to view attachments:
+
+	let g:notmuch_view_attachment = 'xdg-open'
 
 vim:tw=78:ts=8:noet:ft=help:
diff --git a/vim/notmuch.vim b/vim/notmuch.vim
index 331e930..5f73dce 100644
--- a/vim/notmuch.vim
+++ b/vim/notmuch.vim
@@ -35,6 +35,7 @@ let g:notmuch_show_maps = {
 	\ 't':		'show_tag("")',
 	\ 'o':		'show_open_msg()',
 	\ 'e':		'show_extract_msg()',
+	\ '<Enter>':	'show_view_attachment()',
 	\ 's':		'show_save_msg()',
 	\ 'p':		'show_save_patches()',
 	\ 'r':		'show_reply()',
@@ -58,6 +59,8 @@ let s:notmuch_date_format_default = '%d.%m.%y'
 let s:notmuch_datetime_format_default = '%d.%m.%y %H:%M:%S'
 let s:notmuch_reader_default = 'mutt -f %s'
 let s:notmuch_sendmail_default = 'sendmail'
+let s:notmuch_view_attachment_default = 'xdg-open'
+let s:notmuch_attachment_tmpdir_default = '~/.notmuch/tmp'
 let s:notmuch_folders_count_threads_default = 0
 
 function! s:new_file_buffer(type, fname)
@@ -147,13 +150,72 @@ function! s:show_info()
 	ruby vim_puts get_message.inspect
 endfunction
 
+function! s:show_view_attachment()
+	let line = getline(".")
+ruby << EOF
+	m = get_message
+	line = VIM::evaluate('line')
+
+	match = line.match(/^Part (\d*):/)
+	if match and match.length == 2
+		# Set up the tmpdir
+		tmpdir = VIM::evaluate('g:notmuch_attachment_tmpdir')
+		tmpdir = File.expand_path(tmpdir)
+		Dir.mkdir(tmpdir) unless Dir.exists?(tmpdir)
+
+		p = m.mail.parts[match[1].to_i - 1]
+		if p == nil
+			# Not a multipart message, use the message itself.
+			p = m.mail
+		end
+		if p.filename and p.filename.length > 0
+			filename = p.filename
+		else
+			suffix = ''
+			if p.mime_type == 'text/html'
+				suffix = '.html'
+			end
+			filename = "part-#{match[1]}#{suffix}"
+		end
+
+		# Sanitize just in case..
+		filename.gsub!(/[^0-9A-Za-z.\-]/, '_')
+
+		fullpath = File.expand_path("#{tmpdir}/#{filename}")
+		vim_puts "Viewing attachment #{fullpath}"
+		File.open(fullpath, 'w') do |f|
+			f.write p.body.decoded
+			cmd = VIM::evaluate('g:notmuch_view_attachment')
+			system(cmd, fullpath)
+		end
+	else
+		vim_puts "No attachment on this line."
+	end
+EOF
+endfunction
+
 function! s:show_extract_msg()
+	let line = getline(".")
 ruby << EOF
 	m = get_message
-	m.mail.attachments.each do |a|
+	line = VIM::evaluate('line')
+
+	# If the user is on a line that has an 'Part'
+	# line, we just extract the one attachment.
+	match = line.match(/^Part (\d*):/)
+	if match and match.length == 2
+		a = m.mail.parts[match[1].to_i - 1]
 		File.open(a.filename, 'w') do |f|
 			f.write a.body.decoded
-			print "Extracted '#{a.filename}'"
+			vim_puts "Extracted #{a.filename}"
+		end
+	else
+		# Extract them all..
+		m.mail.attachments.each do |a|
+			File.open(a.filename, 'w') do |f|
+				f.write a.body.decoded
+				vim_puts "Extracted #{a.filename}"
+			end
 		end
 	end
 EOF
@@ -326,6 +388,16 @@ ruby << EOF
 			b << "To: %s" % msg['to']
 			b << "Cc: %s" % msg['cc']
 			b << "Date: %s" % msg['date']
+			cnt = 0
+			m.parts.each do |p|
+				cnt += 1
+				b << "Part %d: %s (%s)" % [cnt, p.mime_type, p.filename]
+			end
+			# Add a special case for text/html messages.  Here we show the
+			# only 'part' so that we can view it in a web browser if we want.
+			if m.parts.length == 0 and part.mime_type == 'text/html'
+				b << "Part 1: text/html"
+			end
 			nm_m.body_start = b.count
 			b << "--- %s ---" % part.mime_type
 			part.convert.each_line do |l|
@@ -420,6 +492,14 @@ function! s:set_defaults()
 		endif
 	endif
 
+	if !exists('g:notmuch_attachment_tmpdir')
+		let g:notmuch_attachment_tmpdir = s:notmuch_attachment_tmpdir_default
+	endif
+
+	if !exists('g:notmuch_view_attachment')
+		let g:notmuch_view_attachment = s:notmuch_view_attachment_default
+	endif
+
 	if !exists('g:notmuch_folders_count_threads')
 		if exists('g:notmuch_rb_count_threads')
 			let g:notmuch_count_threads = g:notmuch_rb_count_threads
-- 
1.9.3

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

end of thread, other threads:[~2014-10-23 22:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-02  7:48 [PATCH] VIM: Add better attachment support Ian Main
2014-10-10  9:57 ` Franz Fellner
2014-10-10 18:15   ` Ian Main
2014-10-23 22:04 ` Ian Main

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).