function! s:get_fields() if exists('g:muttgoobook_address_fields') "echomsg "Found g:muttgoobook_address_fields: " . g:muttgoobook_address_fields let fields = g:muttgoobook_address_fields else "echomsg "Using default fields..." let fields = '^\s*\(from\|to\|b\?cc\):\s*' endif return fields endfunction function! s:is_address_field(section) "echomsg "Checking whether we're in an address field..." let fields = s:get_fields() "echomsg "Section: " . a:section "echomsg "Fields: " . l:fields if a:section =~? l:fields "echomsg "In an address field!" return 1 else "echomsg "Not in an address field..." return 0 endif endfunction function! s:get_section() let cur = getline('.') if cur !~ '^\w\+:' return getline(search('^\w\+:', 'b')) else return getline('.') endif endfunction function! s:search_mutt_aliases(query) let aliases = {} if filereadable(expand('~/.mutt/aliases')) for myline in readfile(expand('~/.mutt/aliases')) if myline =~ '^alias' let mylist = split(myline) let myname = mylist[1] if l:myname =~ a:query let addresses = join(mylist[2:]) let aliases[l:myname] = l:addresses endif else continue endif endfor endif return aliases endfunction function! s:query_goobook(query) let addresses = {} for myline in systemlist('goobook query ' . a:query . ' | sed "/^$/d"') ""echomsg 'myline: ' . myline let entry = split(myline, '\t') let addr = entry[0] let name = entry[1] let addresses[l:name] = l:addr endfor return addresses endfunction function! s:address_map(name, address) return { \ 'menu': '[muttgoobook]', \ 'abbr': a:name, \ 'word': a:address \} endfunction function! asyncomplete#sources#muttgoobook#completor(opt, ctx) abort "echomsg 'Calling completor...' let l:matches = {} if !s:is_address_field(s:get_section()) "echomsg 'Not in an address field. Exiting...' call asyncomplete#complete(a:opt['name'], a:ctx, l:startcol, l:matches, 1) return endif "echomsg "a:ctx['col'] = " . a:ctx['col'] "echomsg "a:ctx['typed'] = " . a:ctx['typed'] let l:col = a:ctx['col'] let l:typed = a:ctx['typed'] "echomsg "Getting keyword..." let l:kw = substitute(l:typed, '\c' . s:get_fields() . '\(.*\)$', '\2', '') let l:kwlen = len(l:kw) let l:startcol = l:col - l:kwlen "echomsg "l:startcol: " . l:startcol "echomsg "keyword: " . l:kw . ", len(l:kw) " . l:kwlen if l:kwlen < 3 "echomsg "a:opt['name']: " . a:opt['name'] "echomsg "a:ctx: " . a:ctx "echomsg "l:startcol: " . l:startcol "echomsg "l:matches: " . l:matches call asyncomplete#complete(a:opt['name'], a:ctx, l:startcol, l:matches, 1) return endif "echomsg "Generating address dictionary..." let l:address_dict = extend(s:search_mutt_aliases(l:kw), s:query_goobook(l:kw)) "for [k, v] in items(l:address_dict) " "echomsg "Key: " . k " "echomsg "Value: " . v "endfor "echomsg "Getting matches..." let l:matches = values(map(l:address_dict, {key, val -> s:address_map(key, val)})) "echomsg l:matches "let i = 0 "for k in keys(l:matches) " let l:matches[i] = l:matches[k] " call remove(l:matches, k) " let i+=1 "endfor call asyncomplete#complete(a:opt['name'], a:ctx, l:startcol, l:matches) endfunction