From 80227fc6263ca864227de8b9d8d9f93f19ad173a Mon Sep 17 00:00:00 2001 From: Tom Ryder Date: Wed, 1 Jan 2020 16:08:21 +1300 Subject: Reimplement mail header importance flagging Just for fun, write something a little more comprehensive to read in the entire mail header as a data structure, in order to add or set header fields correctly. I don't think this is totally RFC-compliant yet; I'll need to check. --- vim/autoload/mail.vim | 32 ---------------------- vim/autoload/mail/header.vim | 54 ++++++++++++++++++++++++++++++++++++++ vim/autoload/mail/header/field.vim | 39 +++++++++++++++++++++++++++ vim/autoload/mail/importance.vim | 24 +++++++++++++++++ 4 files changed, 117 insertions(+), 32 deletions(-) create mode 100644 vim/autoload/mail/header.vim create mode 100644 vim/autoload/mail/header/field.vim create mode 100644 vim/autoload/mail/importance.vim (limited to 'vim/autoload') diff --git a/vim/autoload/mail.vim b/vim/autoload/mail.vim index abed119a..cd585af4 100644 --- a/vim/autoload/mail.vim +++ b/vim/autoload/mail.vim @@ -1,35 +1,3 @@ -" Add a header to a mail message -function! mail#AddHeaderField(name, body) abort - let num = 0 - while num < line('$') && getline(num + 1) !=# '' - let num += 1 - endwhile - call append(num, a:name.': '.a:body) -endfunction - -" Add a set of headers to a mail message -function! mail#AddHeaderFields(fields) abort - for name in sort(keys(a:fields)) - call mail#AddHeaderField(name, a:fields[name]) - endfor -endfunction - -" Flag a message as important -function! mail#FlagImportant() abort - call mail#AddHeaderFields({ - \ 'Importance': 'High', - \ 'X-Priority': 1, - \ }) -endfunction - -" Flag a message as unimportant -function! mail#FlagUnimportant() abort - call mail#AddHeaderFields({ - \ 'Importance': 'Low', - \ 'X-Priority': 5, - \ }) -endfunction - " Move through quoted paragraphs like normal-mode `{` and `}` function! mail#NewBlank(count, up, visual) abort diff --git a/vim/autoload/mail/header.vim b/vim/autoload/mail/header.vim new file mode 100644 index 00000000..8495a721 --- /dev/null +++ b/vim/autoload/mail/header.vim @@ -0,0 +1,54 @@ +function! mail#header#Read() abort + let fields = [] + for lnum in range(1, line('$')) + let line = getline(lnum) + let matchlist = matchlist( + \ line, + \ '^\([a-zA-Z0-9-]\+\):\s*\(\_.*\)', + \) + if !empty(matchlist) + let field = { + \ 'name': matchlist[1], + \ 'body': matchlist[2], + \} + call add(fields, field) + elseif line =~ '^\s' && exists('field') + let field['body'] .= "\n" . line + elseif line ==# '' + break + else + throw 'Parse error' + endif + endfor + let header = { + \'fields': fields, + \} + return header +endfunction + +function! mail#header#String(header) abort + let fields = copy(a:header['fields']) + return join( + \ map( + \ copy(a:header['fields']), + \ 'v:val[''name''] . '': '' . v:val[''body''] . "\n"'), + \ '', + \) +endfunction + +function! mail#header#Write(header) abort + let start = 1 + for lnum in range(1, line('$')) + if getline(lnum) ==# '' + break + endif + let end = lnum + endfor + let curpos = getpos('.') + if exists('end') + let range = join([start, end], ',') + execute join(['silent', range, 'delete']) + endif + silent 0 put =mail#header#String(a:header) + call setpos('.', curpos) +endfunction diff --git a/vim/autoload/mail/header/field.vim b/vim/autoload/mail/header/field.vim new file mode 100644 index 00000000..ab3d405a --- /dev/null +++ b/vim/autoload/mail/header/field.vim @@ -0,0 +1,39 @@ +function! mail#header#field#Add(header, name, body) abort + let new = { + \ 'name': a:name, + \ 'body': a:body, + \} + call add(a:header['fields'], new) +endfunction + +function! mail#header#field#Set(header, name, body) abort + let fields = [] + let new = { + \ 'name': a:name, + \ 'body': a:body, + \} + for field in a:header['fields'] + if field['name'] ==? a:name + if exists('new') + let field = new | unlet new + else + continue + endif + endif + call add(fields, field) + endfor + if exists('new') + call add(fields, new) | unlet new + endif + let a:header['fields'] = fields +endfunction + +function! mail#header#field#Clear(header, name) abort + let fields = [] + for field in a:header['fields'] + if field['name'] !=? a:name + call add(fields, field) + endif + endfor + let a:header['fields'] = fields +endfunction diff --git a/vim/autoload/mail/importance.vim b/vim/autoload/mail/importance.vim new file mode 100644 index 00000000..6a5ed096 --- /dev/null +++ b/vim/autoload/mail/importance.vim @@ -0,0 +1,24 @@ +let s:fields = { + \ 'high': { + \ 'Importance': 'High', + \ 'X-Priority': '1', + \}, + \ 'low': { + \ 'Importance': 'Low', + \ 'X-Priority': '5', + \}, + \ 'normal': {}, + \} + +function! mail#importance#Set(level) abort + let header = mail#header#Read() + let fields = s:fields[a:level] + for name in ['Importance', 'X-Priority'] + if has_key(fields, name) + call mail#header#field#Set(header, name, fields[name]) + else + call mail#header#field#Clear(header, name) + endif + endfor + call mail#header#Write(header) +endfunction -- cgit v1.2.3