add support for fuzzy matching (#246)

This commit is contained in:
Prabir Shrestha
2020-12-22 23:28:06 -08:00
committed by GitHub
parent c5f5808581
commit e546095e4a
3 changed files with 44 additions and 14 deletions

View File

@@ -28,6 +28,7 @@ let s:already_setup = 0
let s:sources = {}
let s:matches = {} " { server_name: { incomplete: 1, startcol: 0, items: [], refresh: 0, status: 'idle|pending|success|failure', ctx: ctx } }
let s:has_complete_info = exists('*complete_info')
let s:has_matchfuzzypos = exists('*matchfuzzypos')
function! s:setup_if_required() abort
if !s:already_setup
@@ -458,21 +459,24 @@ function! s:default_preprocessor(options, matches) abort
let l:items += l:result[0]
let l:startcols += l:result[1]
else
for l:item in l:matches['items']
if stridx(l:item['word'], l:base) == 0
" Strip pair characters. If pre-typed text is '"', candidates
" should have '"' suffix.
if has_key(s:pair, l:base[0])
let [l:lhs, l:rhs, l:str] = [l:base[0], s:pair[l:base[0]], l:item['word']]
if len(l:str) > 1 && l:str[0] ==# l:lhs && l:str[-1:] ==# l:rhs
let l:before = l:item['word']
let l:item['word'] = l:str[:-2]
endif
endif
if empty(l:base)
for l:item in l:matches['items']
call add(l:items, s:strip_pair_characters(l:base, l:item))
let l:startcols += [l:startcol]
call add(l:items, l:item)
endif
endfor
endfor
elseif s:has_matchfuzzypos && g:asyncomplete_matchfuzzy
for l:item in matchfuzzypos(l:matches['items'], l:base, {'key':'word'})[0]
call add(l:items, s:strip_pair_characters(l:base, l:item))
let l:startcols += [l:startcol]
endfor
else
for l:item in l:matches['items']
if stridx(l:item['word'], l:base) == 0
call add(l:items, s:strip_pair_characters(l:base, l:item))
let l:startcols += [l:startcol]
endif
endfor
endif
endif
endfor
@@ -481,6 +485,20 @@ function! s:default_preprocessor(options, matches) abort
call asyncomplete#preprocess_complete(a:options, l:items)
endfunction
function! s:strip_pair_characters(base, item) abort
" Strip pair characters. If pre-typed text is '"', candidates
" should have '"' suffix.
let l:item = a:item
if has_key(s:pair, a:base[0])
let [l:lhs, l:rhs, l:str] = [a:base[0], s:pair[a:base[0]], l:item['word']]
if len(l:str) > 1 && l:str[0] ==# l:lhs && l:str[-1:] ==# l:rhs
let l:item = copy({}, l:item)
let l:item['word'] = l:str[:-2]
endif
endif
return l:item
endfunction
function! asyncomplete#preprocess_complete(ctx, items) abort
" TODO: handle cases where this is called asynchronsouly. Currently not supported
if s:should_skip() | return | endif

View File

@@ -112,6 +112,17 @@ g:asyncomplete_min_chars *g:asyncomplete_min_chars*
Minimum consecutive characters to trigger auto-popup. Overridden by buffer
variable if set (`b:asyncomplete_min_chars`)
g:asyncomplete_matchfuzzy *g:asyncomplete_matchfuzzy*
Type: |Number|
Default: `exists('*matchfuzzypos')`
Use |matchfuzzypos| to support fuzzy matching of 'word' when completing
items. Requires vim with `matchfuzzypos()` function to exists.
Set to `0` to disable fuzzy matching.
===============================================================================
3. Functions *asyncomplete-functions*

View File

@@ -20,5 +20,6 @@ let g:asyncomplete_auto_popup = get(g:, 'asyncomplete_auto_popup', 1)
let g:asyncomplete_popup_delay = get(g:, 'asyncomplete_popup_delay', 30)
let g:asyncomplete_log_file = get(g:, 'asyncomplete_log_file', '')
let g:asyncomplete_preprocessor = get(g:, 'asyncomplete_preprocessor', [])
let g:asyncomplete_matchfuzzy = get(g:, 'asyncomplete_matchfuzzy', exists('*matchfuzzypos'))
inoremap <silent> <expr> <Plug>(asyncomplete_force_refresh) asyncomplete#force_refresh()