Created
January 5, 2022 04:48
-
-
Save yuki-yano/79e87b5f6b26c17b19157ec71aeb91bb to your computer and use it in GitHub Desktop.
searchx + fuzzy-motion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function! s:has(list, value) abort | |
| return index(a:list, a:value) isnot -1 | |
| endfunction | |
| function! s:_get_unary_caller(f) abort | |
| return type(a:f) is type(function('function')) | |
| \ ? function('call') | |
| \ : function('s:_call_string_expr') | |
| endfunction | |
| function! s:_call_string_expr(expr, args) abort | |
| return map([a:args[0]], a:expr)[0] | |
| endfunction | |
| function! s:sort(list, f) abort | |
| if type(a:f) is type(function('function')) | |
| return sort(a:list, a:f) | |
| else | |
| let s:sort_expr = a:f | |
| return sort(a:list, 's:_compare_by_string_expr') | |
| endif | |
| endfunction | |
| function! s:_compare_by_string_expr(a, b) abort | |
| return eval(s:sort_expr) | |
| endfunction | |
| function! s:uniq(list) abort | |
| return s:uniq_by(a:list, 'v:val') | |
| endfunction | |
| function! s:uniq_by(list, f) abort | |
| let l:Call = s:_get_unary_caller(a:f) | |
| let applied = [] | |
| let result = [] | |
| for x in a:list | |
| let y = l:Call(a:f, [x]) | |
| if !s:has(applied, y) | |
| call add(result, x) | |
| call add(applied, y) | |
| endif | |
| unlet x y | |
| endfor | |
| return result | |
| endfunction | |
| function! s:product(lists) abort | |
| let result = [[]] | |
| for pool in a:lists | |
| let tmp = [] | |
| for x in result | |
| let tmp += map(copy(pool), 'x + [v:val]') | |
| endfor | |
| let result = tmp | |
| endfor | |
| return result | |
| endfunction | |
| function! s:permutations(list, ...) abort | |
| if a:0 > 1 | |
| throw 'vital: Data.List: too many arguments' | |
| endif | |
| let r = a:0 == 1 ? a:1 : len(a:list) | |
| if r > len(a:list) | |
| return [] | |
| elseif r < 0 | |
| throw 'vital: Data.List: {r} must be non-negative integer' | |
| endif | |
| let n = len(a:list) | |
| let result = [] | |
| for indices in s:product(map(range(r), 'range(n)')) | |
| if len(s:uniq(indices)) == r | |
| call add(result, map(indices, 'a:list[v:val]')) | |
| endif | |
| endfor | |
| return result | |
| endfunction | |
| function! s:combinations(list, r) abort | |
| if a:r > len(a:list) | |
| return [] | |
| elseif a:r < 0 | |
| throw 'vital: Data.List: {r} must be non-negative integer' | |
| endif | |
| let n = len(a:list) | |
| let result = [] | |
| for indices in s:permutations(range(n), a:r) | |
| if s:sort(copy(indices), 'a:a - a:b') == indices | |
| call add(result, map(indices, 'a:list[v:val]')) | |
| endif | |
| endfor | |
| return result | |
| endfunction | |
| function! s:fuzzy_query(input) abort | |
| if match(a:input, ';') == -1 | |
| return [a:input] | |
| endif | |
| let input = substitute(a:input, ';', '', 'g') | |
| let trigger_count = len(a:input) - len(input) | |
| let arr = range(1, len(input) - 1) | |
| let result = [] | |
| for ps in s:combinations(arr, trigger_count) | |
| let ps = reverse(ps) | |
| let str = input | |
| for p in ps | |
| let str = str[0 : p - 1] . ' ' . str[p : -1] | |
| endfor | |
| let result += [str] | |
| endfor | |
| return result | |
| endfunction | |
| function! g:searchx.convert(input) abort | |
| if a:input !~# '\k' | |
| return '\V' .. a:input | |
| endif | |
| if a:input =~# ';' | |
| let max_score = 0 | |
| for q in s:fuzzy_query(a:input) | |
| let targets = denops#request('fuzzy-motion', 'targets', [q]) | |
| if len(targets) > 0 && targets[0].score > max_score | |
| let max_score = targets[0].score | |
| let fuzzy_input = join(split(q, ' '), '.\{-}') | |
| endif | |
| endfor | |
| return fuzzy_input ==# '' ? a:input : fuzzy_input | |
| endif | |
| return join(split(a:input, ' '), '.\{-}') | |
| endfunction |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment