caio.co/de/querycommandcomplete.vim


Make default setup comment clearer by Caio 11 years ago (log)

Blob plugin/querycommandcomplete.vim

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
" Query Command Complete
" ======================
"
" Vim plugin to suggest completions with the results or an external
" query command.
"
" The original intention is to use it as a mutt query_command wrapper
" to complete addresses in the mail headers, but it can be adapted
" to any other kind of functionality by modifying the exposed setting
" parameters.
"
" Last Change: 2012 Sep 17
" Maintainer: Caio Romão <caioromao@gmail.com>
" License: This file is placed in the public domain
" Contributors:
"   Brian Henderson <https://github.com/bhenderson>
"
" Setup:
"   This plugin exports the completion function QueryCommandComplete,
"   which can be set as the complete function (or omni function) for
"   any filetype. If you have a working mutt setup with query_command
"   configured, the plugin works out of the box.
"
"   Example:
"       let g:qcc_query_command='abook'
"       au BufRead /tmp/mutt* setlocal omnifunc=QueryCommandComplete
"
" Settings:
"   g:qcc_query_command
"       External command that queries for contacts
"       If empty, QueryCommandComplete tries to guess what command to
"       run by executing `mutt -Q query_command`.
"
"   g:qcc_line_separator
"       Separator for each entry in the result from the query
"       default: '\n'
"
"   g:qcc_field_separator
"       Separator for the fields of an entry from the result
"       default: '\t'
"
"   g:qcc_pattern
"       Pattern used to match against the current line to decide
"       whether to call the query command
"       default: '^\(To\|Cc\|Bcc\|From\|Reply-To\):'

if exists("g:loaded_QueryCommandComplete") || &cp
  finish
endif

" Try to use mutt's query_command by default if nothing is set
if !exists("g:qcc_query_command")
    let s:querycmd = system('mutt -Q query_command 2>/dev/null')
    let s:querycmd = substitute(s:querycmd, '^query_command="\(.*\)"\n', '\1','')

    if len(s:querycmd)
        let g:qcc_query_command = s:querycmd
        let g:qcc_multiline = 1
        autocmd FileType mail setlocal omnifunc=QueryCommandComplete
    else
        echoerr "QueryCommandComplete: g:qcc_query_command not set!"
        finish
    endif
endif

let g:loaded_QueryCommandComplete = 1
let s:save_cpo = &cpo
set cpo&vim

function! s:DefaultIfUnset(name, default)
    if !exists(a:name)
        let {a:name} = a:default
    endif
endfunction

call s:DefaultIfUnset('g:qcc_line_separator', '\n')
call s:DefaultIfUnset('g:qcc_field_separator', '\t')
call s:DefaultIfUnset('g:qcc_pattern', '^\(To\|Cc\|Bcc\|From\|Reply-To\):')
call s:DefaultIfUnset('g:qcc_multiline', 0)
call s:DefaultIfUnset('g:qcc_multiline_pattern', '.*')

function! s:MakeCompletionEntry(name, email, other)
    let entry = {}
    let entry.word = a:name . ' <' . a:email . '>'
    let entry.abbr = a:name
    let entry.menu = a:other
    let entry.icase = 1
    return entry
endfunction

function! s:FindStartingIndex()
    let cur_line = getline('.')

    " locate the start of the word
    let start = col('.') - 1
    while start > 0 && cur_line[start - 1] =~ '[^:,]'
        let start -= 1
    endwhile

    " lstrip()
    while cur_line[start] =~ '[ ]'
        let start += 1
    endwhile

    return start
endfunction

function! s:GenerateCompletions(findstart, base)
    if a:findstart
        return s:FindStartingIndex()
    endif

    let results = []
    let cmd = g:qcc_query_command
    if cmd !~ '%s'
        let cmd .= ' %s'
    endif
    let cmd = substitute(cmd, '%s', shellescape(a:base), '')
    let lines = split(system(cmd), g:qcc_line_separator)

    for my_line in lines
        let fields = split(my_line, g:qcc_field_separator)

        if (len(fields) < 2)
            continue
        endif

        let email = fields[0]
        let name = fields[1]
        let other = ''

        if (len(fields) > 2)
            let other = fields[2]
        endif

        let contact = s:MakeCompletionEntry(name, email, other)

        call add(results, contact)
    endfor

    return results
endfunction

function! s:ShouldGenerateCompletions(line_number)
    let current_line = getline(a:line_number)

    if current_line =~ g:qcc_pattern
        return 1
    endif

    if ! g:qcc_multiline || a:line_number <= 1 || current_line !~ g:qcc_multiline_pattern
        return 0
    endif

    return s:ShouldGenerateCompletions(a:line_number - 1)
endfunction

function! QueryCommandComplete(findstart, base)
    if s:ShouldGenerateCompletions(line('.'))
        return s:GenerateCompletions(a:findstart, a:base)
    endif
endfunction

let &cpo = s:save_cpo