mirror of
https://github.com/SpaceVim/SpaceVim.git
synced 2025-01-24 05:30:07 +08:00
105 lines
3.1 KiB
VimL
105 lines
3.1 KiB
VimL
|
let s:t_list = type([])
|
||
|
let s:t_func = type(function('tr'))
|
||
|
|
||
|
function! s:_vital_loaded(V) abort
|
||
|
let s:String = a:V.import('Data.String')
|
||
|
endfunction
|
||
|
|
||
|
function! s:_vital_depends() abort
|
||
|
return ['Data.String']
|
||
|
endfunction
|
||
|
|
||
|
function! s:new() abort
|
||
|
let options = copy(s:options)
|
||
|
let options._options = {}
|
||
|
return options
|
||
|
endfunction
|
||
|
|
||
|
|
||
|
" Private --------------------------------------------------------------------
|
||
|
function! s:_filter(arglead, candidates) abort
|
||
|
let pattern = '^' . s:String.escape_pattern(a:arglead)
|
||
|
let candidates = copy(a:candidates)
|
||
|
call filter(candidates, 'v:val =~# pattern')
|
||
|
return candidates
|
||
|
endfunction
|
||
|
|
||
|
function! s:_complete_choice(arglead, cmdline, cursorpos, choices) abort
|
||
|
let leading = matchstr(a:arglead, '\%(-[^-]\|--\S\+=\)')
|
||
|
let candidates = map(
|
||
|
\ copy(a:choices),
|
||
|
\ 'leading . v:val'
|
||
|
\)
|
||
|
return s:_filter(a:arglead, candidates)
|
||
|
endfunction
|
||
|
|
||
|
function! s:_complete_callback(arglead, cmdline, cursorpos, callback) abort
|
||
|
let m = matchlist(a:arglead, '\(-[^-]\|--\S\+=\)\(.*\)')
|
||
|
let candidates = a:callback(m[2], a:cmdline, a:cursorpos)
|
||
|
return map(
|
||
|
\ copy(candidates),
|
||
|
\ 'm[1] . v:val'
|
||
|
\)
|
||
|
endfunction
|
||
|
|
||
|
function! s:_compare_options(lhs, rhs) abort
|
||
|
let lhs = a:lhs.names[-1]
|
||
|
let rhs = a:rhs.names[-1]
|
||
|
return lhs ==# rhs ? 0 : (lhs < rhs ? -1 : 1)
|
||
|
endfunction
|
||
|
|
||
|
|
||
|
" Options --------------------------------------------------------------------
|
||
|
let s:options = {}
|
||
|
|
||
|
function! s:options.define(query, description, ...) abort
|
||
|
let self._options[a:query] = extend(copy(s:option), {
|
||
|
\ 'names': split(a:query, '|'),
|
||
|
\ 'value': a:0 ? a:1 : v:null,
|
||
|
\ 'description': a:description,
|
||
|
\})
|
||
|
endfunction
|
||
|
|
||
|
function! s:options.help(...) abort
|
||
|
let lwidth = max(map(keys(self._options), 'len(v:val)')) + 3
|
||
|
let rwidth = get(a:000, 0, 80) - lwidth
|
||
|
let text = ['options:']
|
||
|
call map(
|
||
|
\ sort(values(self._options), function('s:_compare_options')),
|
||
|
\ 'extend(text, v:val.help(lwidth, rwidth))'
|
||
|
\)
|
||
|
redraw | echo join(text, "\n")
|
||
|
endfunction
|
||
|
|
||
|
function! s:options.complete(arglead, cmdline, cursorpos) abort
|
||
|
let leading = matchstr(a:arglead, '^\%(-[^-]\|--\S\+=\)')
|
||
|
let candidates = []
|
||
|
for option in values(self._options)
|
||
|
if index(option.names, leading) != -1
|
||
|
return option.complete(a:arglead, a:cmdline, a:cursorpos)
|
||
|
endif
|
||
|
call extend(candidates, option.names)
|
||
|
endfor
|
||
|
return s:_filter(a:arglead, candidates)
|
||
|
endfunction
|
||
|
|
||
|
|
||
|
" Option ---------------------------------------------------------------------
|
||
|
let s:option = {}
|
||
|
|
||
|
function! s:option.help(lwidth, rwidth) abort
|
||
|
let rhs = s:String.wrap(self.description, a:rwidth)
|
||
|
let lhs = [s:String.pad_right(join(self.names), a:lwidth)]
|
||
|
let lhs += repeat([repeat(' ', a:lwidth)], len(rhs) - 1)
|
||
|
return map(range(len(lhs)), 'lhs[v:val] . rhs[v:val]')
|
||
|
endfunction
|
||
|
|
||
|
function! s:option.complete(arglead, cmdline, cursorpos) abort
|
||
|
if type(self.value) == s:t_list
|
||
|
return s:_complete_choice(a:arglead, a:cmdline, a:cursorpos, self.value)
|
||
|
elseif type(self.value) == s:t_func
|
||
|
return s:_complete_callback(a:arglead, a:cmdline, a:cursorpos, self.value)
|
||
|
endif
|
||
|
return []
|
||
|
endfunction
|