[PATCH] VIM: Fix header management and fold threads

Subject: [PATCH] VIM: Fix header management and fold threads

Date: Thu, 23 Oct 2014 21:05:03 -0700

To: notmuch@notmuchmail.org

Cc:

From: Ian Main


Yes, it's here, the patch you've all been waiting for!  Well, maybe:

- Add a variable to control which headers are displayed normally.
- Any header that is not displayed normally will be listed in a folded
  area in the message so you can access it at will (can be turned off).
- Add the (optional) ability to list threads using vim folding so that
  you can see at a glance the whole thread, which messages are new etc.

    Ian
---
 vim/notmuch.vim | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 54 insertions(+), 7 deletions(-)

diff --git a/vim/notmuch.vim b/vim/notmuch.vim
index cad9517..affd1e2 100644
--- a/vim/notmuch.vim
+++ b/vim/notmuch.vim
@@ -54,12 +54,22 @@ let s:notmuch_folders_default = [
 	\ [ 'unread', 'tag:unread' ],
 	\ ]
 
+let s:notmuch_show_headers_default = [
+	\ 'Subject',
+	\ 'To',
+	\ 'Cc',
+	\ 'Date',
+	\ 'Message-ID',
+	\ ]
+
 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_folders_count_threads_default = 0
 let s:notmuch_compose_start_insert_default = 1
+let s:notmuch_show_folded_full_headers_default = 1
+let s:notmuch_show_folded_threads_default = 1
 
 function! s:new_file_buffer(type, fname)
 	exec printf('edit %s', a:fname)
@@ -311,6 +321,9 @@ function! s:show(thread_id)
 	call s:new_buffer('show')
 	setlocal modifiable
 ruby << EOF
+	show_full_headers = VIM::evaluate('g:notmuch_show_folded_full_headers')
+	show_threads_folded = VIM::evaluate('g:notmuch_show_folded_threads_default')
+
 	thread_id = VIM::evaluate('a:thread_id')
 	$cur_thread = thread_id
 	$messages.clear
@@ -326,11 +339,22 @@ ruby << EOF
 			date_fmt = VIM::evaluate('g:notmuch_datetime_format')
 			date = Time.at(msg.date).strftime(date_fmt)
 			nm_m.start = b.count
-			b << "%s %s (%s)" % [msg['from'], date, msg.tags]
-			b << "Subject: %s" % [msg['subject']]
-			b << "To: %s" % msg['to']
-			b << "Cc: %s" % msg['cc']
-			b << "Date: %s" % msg['date']
+			b << "From: %s %s (%s)" % [msg['from'], date, msg.tags]
+			showheaders = VIM::evaluate('g:notmuch_show_headers')
+			showheaders.each do |h|
+				b << "%s: %s" % [h, m.header[h]]
+			end
+			if show_full_headers
+				# Now show the rest in a folded area.
+				nm_m.full_header_start = b.count
+				m.header.fields.each do |k|
+					# Only show the ones we haven't already printed out.
+					if not showheaders.include?(k.name)
+					    b << '%s: %s' % [k.name, k.to_s]
+					end
+				end
+				nm_m.full_header_end = b.count
+			end
 			nm_m.body_start = b.count
 			b << "--- %s ---" % part.mime_type
 			part.convert.each_line do |l|
@@ -343,11 +367,19 @@ ruby << EOF
 	end
 	$messages.each_with_index do |msg, i|
 		VIM::command("syntax region nmShowMsg#{i}Desc start='\\%%%il' end='\\%%%il' contains=@nmShowMsgDesc" % [msg.start, msg.start + 1])
-		VIM::command("syntax region nmShowMsg#{i}Head start='\\%%%il' end='\\%%%il' contains=@nmShowMsgHead" % [msg.start + 1, msg.body_start])
+		VIM::command("syntax region nmShowMsg#{i}Head start='\\%%%il' end='\\%%%il' contains=@nmShowMsgHead" % [msg.start + 1, msg.full_header_start])
 		VIM::command("syntax region nmShowMsg#{i}Body start='\\%%%il' end='\\%%%dl' contains=@nmShowMsgBody" % [msg.body_start, msg.end])
+		if show_full_headers
+			VIM::command("syntax region nmFold#{i}Headers start='\\%%%il' end='\\%%%il' fold transparent contains=@nmShowMsgHead" % [msg.full_header_start, msg.full_header_end])
+		end
+		# Only fold the whole message if there are multiple emails in this thread.
+		if $messages.count > 1 and show_threads_folded
+			VIM::command("syntax region nmShowMsgFold#{i} start='\\%%%il' end='\\%%%il' fold transparent contains=ALL" % [msg.start, msg.end])
+		end
 	end
 EOF
 	setlocal nomodifiable
+	setlocal foldmethod=syntax
 	call s:set_map(g:notmuch_show_maps)
 endfunction
 
@@ -460,6 +492,19 @@ function! s:set_defaults()
 			let g:notmuch_folders = s:notmuch_folders_default
 		endif
 	endif
+
+	if !exists('g:notmuch_show_headers')
+		let g:notmuch_show_headers = s:notmuch_show_headers_default
+	endif
+
+	if !exists('g:notmuch_show_folded_threads')
+		let g:notmuch_show_folded_threads = s:notmuch_show_folded_threads_default
+	endif
+
+	if !exists('g:notmuch_show_folded_full_headers')
+		let g:notmuch_show_folded_full_headers = s:notmuch_show_folded_full_headers_default
+	endif
+
 endfunction
 
 function! s:NotMuch(...)
@@ -723,7 +768,7 @@ ruby << EOF
 	end
 
 	class Message
-		attr_accessor :start, :body_start, :end
+		attr_accessor :start, :body_start, :end, :full_header_start, :full_header_end
 		attr_reader :message_id, :filename, :mail
 
 		def initialize(msg, mail)
@@ -732,6 +777,8 @@ ruby << EOF
 			@mail = mail
 			@start = 0
 			@end = 0
+			@full_header_start = 0
+			@full_header_end = 0
 			mail.import_headers(msg) if not $mail_installed
 		end
 
-- 
1.9.3


Thread: