" Name: lbdbq.vim
" Summary: functions and mode mappings for querying lbdb from Vim
" Copyright: Copyright (C) 2007 Stefano Zacchiroli <zack@bononia.it>
" License: GNU GPL version 3 or above
" Maintainer: Stefano Zacchiroli <zack@bononia.it>
" URL: http://www.vim.org/scripts/script.php?script_id=1757
" Version: 0.3
if exists("loaded_lbdbq")
finish
endif
let loaded_lbdbq = 1
" queries lbdb with a query string and return a list of pairs:
" [['full name', 'email'], ['full name', 'email'], ...]
function! LbdbQuery(qstring)
let output = system("lbdbq '" . a:qstring . "'")
let results = []
for line in split(output, "\n")[1:] " skip first line (lbdbq summary)
let fields = split(line, "\t")
let results += [ [fields[1], fields[0]] ]
endfor
return results
endfunction
" check if a potential query string has already been expanded in a complete
" recipient. E.g.: 'Stefano Zacchiroli <zack@bononia.it>' is a complete
" recipient, 'stefano zacchiroli' and 'stefano' are not
function! LbdbIsExpanded(qstring)
return (a:qstring =~ '^\S\+@\S\+$\|<\S\+@\S\+>$')
endfunction
function! LbdbTrim(s)
return substitute(a:s, '^\s*\(.\{-}\)\s*$', '\1', '')
endfunction
" expand a (short) contact given as a query string, asking interactively if
" disambiguation is needed
" E.g.: 'stefano zacchiroli' -> 'Stefano Zacchiroli <zack@bononia.it>'
function! LbdbExpandContact(qstring)
let qstring = LbdbTrim(a:qstring)
if LbdbIsExpanded(qstring)
return qstring
else " try to expand (short) contact
let contacts = LbdbQuery(qstring)
let contact = []
if empty(contacts) " no matching (long) contact found
return qstring
elseif len(contacts) > 1 " multiple matches: disambiguate
echo "Choose a recipient for '" . qstring . "':"
let choices = []
let counter = 0
for contact in contacts
let choices += [ printf("%2d. %s <%s>", counter, contact[0], contact[1]) ]
let counter += 1
endfor
let contact = contacts[inputlist(choices)]
else " len(contacts) == 1, i.e. one single match
let contact = contacts[0]
endif
return printf("\"%s\" <%s>", escape(contact[0], '"'), contact[1])
endif
endfunction
" as above but support input strings composed by comma separated (short)
" contacts
function! LbdbExpandContacts(raw)
let raw = LbdbTrim(a:raw)
let qstrings = split(raw, '\s*,\s*')
let exp_strings = []
for qstring in qstrings
let exp_strings += [ LbdbExpandContact(qstring) ]
endfor
return join(exp_strings, ', ')
endfunction
" expand all (short) contacts on a given recipient line, asking interactively
" if disambiguation is needed.
" E.g.:
" 'To: stefano zacchiroli, bram'
" -> 'To: Stefano Zacchiroli <zack@bononia.it>, Bram Moolenaar <Bram@moolenaar.net>
function! LbdbExpandRcptLine(recpt_line)
if a:recpt_line =~ '^\w\+:' " line is the *beginning* of a RFC822 field
let raw = substitute(a:recpt_line, '^\w\+:\s*', '', '')
let recpt_kind = substitute(a:recpt_line, '^\(\w\+\):\s*.*$', '\1', '')
let exp_line = recpt_kind . ': ' . LbdbExpandContacts(raw)
elseif a:recpt_line =~ '^\s\+' " line is the *continuation* of a RFC822 field
let raw = substitute(a:recpt_line, '^\s\+', '', '')
let lpadding = substitute(a:recpt_line, '\S.*$', '', '')
let exp_line = lpadding . LbdbExpandContacts(raw)
else
return a:recpt_line
endif
if a:recpt_line =~ ',\s*$'
let exp_line .= ','
endif
return exp_line
endfunction
function! LbdbExpandCurLine()
call setline(line('.'), LbdbExpandRcptLine(getline('.')))
endfunction
function! LbdbExpandVisual()
if visualmode() ==# 'v'
normal gvy
let raw = getreg('"')
let expanded = ''
if raw =~ ","
let expanded = LbdbExpandContacts(raw)
else
let expanded = LbdbExpandContact(raw)
endif
call setreg('"', expanded)
normal gvP
elseif visualmode() ==# 'V'
call LbdbExpandCurLine()
end
endfunction
nmap <silent> <LocalLeader>lb :call LbdbExpandCurLine()<RETURN>
vmap <silent> <LocalLeader>lb :call LbdbExpandVisual()<RETURN>
imap <silent> <LocalLeader>lb <ESC>:call LbdbExpandCurLine()<RETURN>A