add other MUA related config files
This commit is contained in:
242
vim/.vim/plugin/querycommandcomplete.vim
Normal file
242
vim/.vim/plugin/querycommandcomplete.vim
Normal file
@@ -0,0 +1,242 @@
|
||||
" Query Command Complete
|
||||
" ======================
|
||||
"
|
||||
" Vim plugin to suggest completions with the results of 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: 2013 Jun 16
|
||||
" Author: Caio Romão (http://caioromao.com)
|
||||
" License: This file is placed in the public domain
|
||||
" Contributors:
|
||||
" Brian Henderson https://github.com/bhenderson
|
||||
" Mark Stillwell https://github.com/marklee77
|
||||
" Rui Abreu Ferreira http://ruiabreu.org
|
||||
"
|
||||
" 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:
|
||||
" Note: Overriding settings on a buffer-basis is supported. So
|
||||
" b:qcc_query_command takes precedence over g:qcc_query_command
|
||||
"
|
||||
" 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\):'
|
||||
"
|
||||
" g:qcc_multiline
|
||||
" Whether to try matching g:qcc_pattern against the current
|
||||
" and any previous line
|
||||
" default: 0
|
||||
"
|
||||
" g:qcc_multiline_pattern
|
||||
" Pattern to match against the current line when deciding
|
||||
" wether to keep looking for a line that matches g:qcc_pattern
|
||||
" This provides finer control over the recursion, which
|
||||
" is useful if calling the completion on really big files.
|
||||
" default: '.*'
|
||||
"
|
||||
" g:qcc_format_word
|
||||
" Format string to be used when building the word field
|
||||
" of the completion (i.e.: the final result, what gets fed into
|
||||
" the current line when you select an option)
|
||||
" default: '${1} <${0}>' (as in: FirstName <email@domain.com>)
|
||||
"
|
||||
" g:qcc_format_abbr
|
||||
" Format string to be used when building the abbreviation
|
||||
" for the completion menu (i.e.: the first row in the completion
|
||||
" menu).
|
||||
" default: '${1}'
|
||||
"
|
||||
" g:qcc_format_menu
|
||||
" Format string for the optional second column of the completion
|
||||
" menu.
|
||||
" default: '${2}'
|
||||
"
|
||||
|
||||
|
||||
if exists("g:loaded_QueryCommandComplete") || &cp
|
||||
finish
|
||||
endif
|
||||
|
||||
function! s:GetSetting(name)
|
||||
let global_option = 'g:qcc_' . a:name
|
||||
let local_option = 'b:qcc_' . a:name
|
||||
|
||||
let result = ''
|
||||
if exists(local_option)
|
||||
let result = {local_option}
|
||||
elseif exists(global_option)
|
||||
let result = {global_option}
|
||||
endif
|
||||
|
||||
return result
|
||||
endfunction
|
||||
|
||||
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', '.*')
|
||||
call s:DefaultIfUnset('g:qcc_format_word', '${1} <${0}>')
|
||||
call s:DefaultIfUnset('g:qcc_format_abbr', '${1}')
|
||||
call s:DefaultIfUnset('g:qcc_format_menu', '${2}')
|
||||
|
||||
" Given a format string where the placeholders are in the format
|
||||
" '${index}' and index is a valid index the the given 'fields'
|
||||
" argument, this function returns a string with all placeholders
|
||||
" replaced by the corresponding data in the fields list.
|
||||
" FIXME I can't help but think there's a standard way to do this
|
||||
" but I failed finding it. Please call me a dumbass if you
|
||||
" know The Easy Way.
|
||||
function! s:ApplyFieldsToFormatString(fields, format)
|
||||
let result = a:format
|
||||
|
||||
while 1
|
||||
let placeholder = matchstr(result, '${[0-9]}')
|
||||
|
||||
if (empty(placeholder))
|
||||
break
|
||||
endif
|
||||
|
||||
let index = matchstr(placeholder, '[0-9]')
|
||||
|
||||
" If ${NUMBER} is not a valid index in a:fields,
|
||||
" use '' as a fallback.
|
||||
" FIXME Decide whether to warn/err/whatever here
|
||||
let content = ''
|
||||
if (len(a:fields) > index)
|
||||
let content = a:fields[index]
|
||||
endif
|
||||
|
||||
let result = substitute(result, placeholder, content, 'g')
|
||||
|
||||
endwhile
|
||||
|
||||
return result
|
||||
endfunction
|
||||
|
||||
function! s:MakeCompletionEntry(fields)
|
||||
let entry = {}
|
||||
let entry.word = s:ApplyFieldsToFormatString(a:fields, s:GetSetting('format_word'))
|
||||
let entry.abbr = s:ApplyFieldsToFormatString(a:fields, s:GetSetting('format_abbr'))
|
||||
let entry.menu = s:ApplyFieldsToFormatString(a:fields, s:GetSetting('format_menu'))
|
||||
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 = s:GetSetting('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)
|
||||
|
||||
let entry = s:MakeCompletionEntry(fields)
|
||||
|
||||
call add(results, entry)
|
||||
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! s:CheckSettings()
|
||||
" Try to use mutt's query_command by default if nothing is set
|
||||
if empty(s:GetSetting('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!"
|
||||
return 0
|
||||
endif
|
||||
endif
|
||||
return 1
|
||||
endfunction
|
||||
|
||||
function! QueryCommandComplete(findstart, base)
|
||||
if s:CheckSettings() && s:ShouldGenerateCompletions(line('.'))
|
||||
return s:GenerateCompletions(a:findstart, a:base)
|
||||
endif
|
||||
endfunction
|
||||
|
||||
let &cpo = s:save_cpo
|
||||
Reference in New Issue
Block a user