Update vital

This commit is contained in:
Shougo Matsushita 2016-12-14 06:23:37 +09:00
parent 3929abc353
commit c179a51f02
7 changed files with 253 additions and 134 deletions

View File

@ -26,8 +26,10 @@
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
let s:V = vital#neosnippet#of()
function! neosnippet#util#get_vital() abort "{{{ function! neosnippet#util#get_vital() abort "{{{
if !exists('s:V')
let s:V = vital#neosnippet#new()
endif
return s:V return s:V
endfunction"}}} endfunction"}}}
function! s:get_prelude() abort "{{{ function! s:get_prelude() abort "{{{
@ -74,7 +76,7 @@ function! neosnippet#util#get_last_status(...) abort "{{{
return call(s:get_process().get_last_status, a:000) return call(s:get_process().get_last_status, a:000)
endfunction"}}} endfunction"}}}
function! neosnippet#util#escape_pattern(...) abort "{{{ function! neosnippet#util#escape_pattern(...) abort "{{{
return call(s:get_prelude().escape_pattern, a:000) return call(s:get_string().escape_pattern, a:000)
endfunction"}}} endfunction"}}}
function! neosnippet#util#iconv(...) abort "{{{ function! neosnippet#util#iconv(...) abort "{{{
return call(s:get_process().iconv, a:000) return call(s:get_process().iconv, a:000)

View File

@ -1,5 +1,5 @@
function! vital#of(name) abort function! vital#of(name) abort
let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital') let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital', 1)
let file = split(files, "\n") let file = split(files, "\n")
if empty(file) if empty(file)
throw 'vital: version file not found: ' . a:name throw 'vital: version file not found: ' . a:name

View File

@ -1,5 +1,5 @@
let s:_plugin_name = expand('<sfile>:t:r') let s:_plugin_name = expand('<sfile>:t:r')
function! vital#{s:_plugin_name}#new() abort function! vital#{s:_plugin_name}#new() abort
return vital#{s:_plugin_name[1:]}#of() return vital#{s:_plugin_name[1:]}#new()
endfunction endfunction

View File

@ -3,13 +3,13 @@
" Do not mofidify the code nor insert new lines before '" ___vital___' " Do not mofidify the code nor insert new lines before '" ___vital___'
if v:version > 703 || v:version == 703 && has('patch1170') if v:version > 703 || v:version == 703 && has('patch1170')
function! vital#_neosnippet#Data#String#import() abort function! vital#_neosnippet#Data#String#import() abort
return map({'trim': '', 'chomp': '', 'starts_with': '', 'truncate_skipping': '', 'pad_left': '', 'hash': '', 'trim_end': '', 'nr2enc_char': '', '_vital_depends': '', 'wrap': '', 'split3': '', 'strwidthpart_reverse': '', 'pad_both_sides': '', 'chop': '', 'lines': '', 'contains_multibyte': '', 'nr2byte': '', 'dstring': '', 'replace': '', 'scan': '', 'diffidx': '', 'strchars': '', 'pad_between_letters': '', 'ends_with': '', 'nsplit': '', 'justify_equal_spacing': '', 'strwidthpart': '', 'split_leftright': '', 'truncate': '', 'substitute_last': '', 'pad_right': '', 'replace_first': '', 'split_by_displaywidth': '', 'wcswidth': '', 'common_head': '', 'levenshtein_distance': '', 'reverse': '', 'trim_start': '', 'nr2hex': '', 'padding_by_displaywidth': '', '_vital_loaded': ''}, 'function("s:" . v:key)') return map({'starts_with': '', 'split3': '', 'replace_first': '', 'chop': '', 'unescape': '', 'split_posix_text': '', 'replace': '', 'scan': '', 'strwidthpart': '', 'common_head': '', 'reverse': '', 'escape_pattern': '', 'trim_end': '', '_vital_depends': '', 'wrap': '', 'join_posix_lines': '', 'contains_multibyte': '', 'truncate_skipping': '', 'split_leftright': '', 'ends_with': '', 'nsplit': '', 'strwidthpart_reverse': '', 'unescape_pattern': '', 'levenshtein_distance': '', 'trim_start': '', 'justify_equal_spacing': '', 'nr2hex': '', 'iconv': '', 'pad_left': '', 'nr2enc_char': '', 'lines': '', 'repair_posix_text': '', 'nr2byte': '', 'trim': '', 'diffidx': '', 'truncate': '', 'split_by_displaywidth': '', '_vital_created': '', 'padding_by_displaywidth': '', 'hash': '', 'chomp': '', 'pad_between_letters': '', 'dstring': '', 'pad_both_sides': '', 'substitute_last': '', 'pad_right': '', 'remove_ansi_sequences': '', '_vital_loaded': ''}, 'function("s:" . v:key)')
endfunction endfunction
else else
function! s:_SID() abort function! s:_SID() abort
return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$') return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze__SID$')
endfunction endfunction
execute join(['function! vital#_neosnippet#Data#String#import() abort', printf("return map({'trim': '', 'chomp': '', 'starts_with': '', 'truncate_skipping': '', 'pad_left': '', 'hash': '', 'trim_end': '', 'nr2enc_char': '', '_vital_depends': '', 'wrap': '', 'split3': '', 'strwidthpart_reverse': '', 'pad_both_sides': '', 'chop': '', 'lines': '', 'contains_multibyte': '', 'nr2byte': '', 'dstring': '', 'replace': '', 'scan': '', 'diffidx': '', 'strchars': '', 'pad_between_letters': '', 'ends_with': '', 'nsplit': '', 'justify_equal_spacing': '', 'strwidthpart': '', 'split_leftright': '', 'truncate': '', 'substitute_last': '', 'pad_right': '', 'replace_first': '', 'split_by_displaywidth': '', 'wcswidth': '', 'common_head': '', 'levenshtein_distance': '', 'reverse': '', 'trim_start': '', 'nr2hex': '', 'padding_by_displaywidth': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") execute join(['function! vital#_neosnippet#Data#String#import() abort', printf("return map({'starts_with': '', 'split3': '', 'replace_first': '', 'chop': '', 'unescape': '', 'split_posix_text': '', 'replace': '', 'scan': '', 'strwidthpart': '', 'common_head': '', 'reverse': '', 'escape_pattern': '', 'trim_end': '', '_vital_depends': '', 'wrap': '', 'join_posix_lines': '', 'contains_multibyte': '', 'truncate_skipping': '', 'split_leftright': '', 'ends_with': '', 'nsplit': '', 'strwidthpart_reverse': '', 'unescape_pattern': '', 'levenshtein_distance': '', 'trim_start': '', 'justify_equal_spacing': '', 'nr2hex': '', 'iconv': '', 'pad_left': '', 'nr2enc_char': '', 'lines': '', 'repair_posix_text': '', 'nr2byte': '', 'trim': '', 'diffidx': '', 'truncate': '', 'split_by_displaywidth': '', '_vital_created': '', 'padding_by_displaywidth': '', 'hash': '', 'chomp': '', 'pad_between_letters': '', 'dstring': '', 'pad_both_sides': '', 'substitute_last': '', 'pad_right': '', 'remove_ansi_sequences': '', '_vital_loaded': ''}, \"function('<SNR>%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n")
delfunction s:_SID delfunction s:_SID
endif endif
" ___vital___ " ___vital___
@ -20,12 +20,21 @@ set cpo&vim
function! s:_vital_loaded(V) abort function! s:_vital_loaded(V) abort
let s:V = a:V let s:V = a:V
let s:P = s:V.import('Prelude')
let s:L = s:V.import('Data.List') let s:L = s:V.import('Data.List')
endfunction endfunction
function! s:_vital_depends() abort function! s:_vital_depends() abort
return ['Prelude', 'Data.List'] return ['Data.List']
endfunction
function! s:_vital_created(module) abort
" Expose script-local funcref
if exists('s:strchars')
let a:module.strchars = s:strchars
endif
if exists('s:wcswidth')
let a:module.wcswidth = s:wcswidth
endif
endfunction endfunction
" Substitute a:from => a:to by string. " Substitute a:from => a:to by string.
@ -143,9 +152,7 @@ endfunction
" even if a:str contains multibyte character(s). " even if a:str contains multibyte character(s).
" s:strchars(str) {{{ " s:strchars(str) {{{
if exists('*strchars') if exists('*strchars')
function! s:strchars(str) abort let s:strchars = function('strchars')
return strchars(a:str)
endfunction
else else
function! s:strchars(str) abort function! s:strchars(str) abort
return strlen(substitute(copy(a:str), '.', 'x', 'g')) return strlen(substitute(copy(a:str), '.', 'x', 'g'))
@ -331,7 +338,7 @@ function! s:levenshtein_distance(str1, str2) abort
let letters2 = split(a:str2, '\zs') let letters2 = split(a:str2, '\zs')
let length1 = len(letters1) let length1 = len(letters1)
let length2 = len(letters2) let length2 = len(letters2)
let distances = map(range(1, length1 + 1), 'map(range(1, length2 + 1), "0")') let distances = map(range(1, length1 + 1), 'map(range(1, length2 + 1), ''0'')')
for i1 in range(0, length1) for i1 in range(0, length1)
let distances[i1][0] = i1 let distances[i1][0] = i1
@ -453,8 +460,9 @@ function! s:truncate(str, width) abort
" http://github.com/mattn/googlereader-vim/tree/master " http://github.com/mattn/googlereader-vim/tree/master
if a:str =~# '^[\x00-\x7f]*$' if a:str =~# '^[\x00-\x7f]*$'
return len(a:str) < a:width ? return len(a:str) < a:width
\ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width) \ ? printf('%-' . a:width . 's', a:str)
\ : strpart(a:str, 0, a:width)
endif endif
let ret = a:str let ret = a:str
@ -484,57 +492,20 @@ function! s:truncate_skipping(str, max, footer_width, separator) abort
endfunction endfunction
function! s:strwidthpart(str, width) abort function! s:strwidthpart(str, width) abort
if a:width <= 0 let str = tr(a:str, "\t", ' ')
return '' let vcol = a:width + 2
endif return matchstr(str, '.*\%<' . (vcol < 0 ? 0 : vcol) . 'v')
let strarr = split(a:str, '\zs')
let width = s:wcswidth(a:str)
let index = len(strarr)
let diff = (index + 1) / 2
let rightindex = index - 1
while width > a:width
let index = max([rightindex - diff + 1, 0])
let partwidth = s:wcswidth(join(strarr[(index):(rightindex)], ''))
if width - partwidth >= a:width || diff <= 1
let width -= partwidth
let rightindex = index - 1
endif
if diff > 1
let diff = diff / 2
endif
endwhile
return index ? join(strarr[:index - 1], '') : ''
endfunction endfunction
function! s:strwidthpart_reverse(str, width) abort function! s:strwidthpart_reverse(str, width) abort
if a:width <= 0 let str = tr(a:str, "\t", ' ')
return '' let vcol = s:wcswidth(str) - a:width
endif return matchstr(str, '\%>' . (vcol < 0 ? 0 : vcol) . 'v.*')
let strarr = split(a:str, '\zs')
let width = s:wcswidth(a:str)
let strlen = len(strarr)
let diff = (strlen + 1) / 2
let leftindex = 0
let index = -1
while width > a:width
let index = min([leftindex + diff, strlen]) - 1
let partwidth = s:wcswidth(join(strarr[(leftindex):(index)], ''))
if width - partwidth >= a:width || diff <= 1
let width -= partwidth
let leftindex = index + 1
endif
if diff > 1
let diff = diff / 2
endif
endwhile
return index < strlen ? join(strarr[(index + 1):], '') : ''
endfunction endfunction
if v:version >= 703 if v:version >= 703
" Use builtin function. " Use builtin function.
function! s:wcswidth(str) abort let s:wcswidth = function('strwidth')
return strwidth(a:str)
endfunction
else else
function! s:wcswidth(str) abort function! s:wcswidth(str) abort
if a:str =~# '^[\x00-\x7f]*$' if a:str =~# '^[\x00-\x7f]*$'
@ -577,7 +548,86 @@ else
endfunction endfunction
endif endif
function! s:remove_ansi_sequences(text) abort
return substitute(a:text, '\e\[\%(\%(\d\+;\)*\d\+\)\?[mK]', '', 'g')
endfunction
function! s:escape_pattern(str) abort
" escape characters for no-magic
return escape(a:str, '^$~.*[]\')
endfunction
function! s:unescape_pattern(str) abort
" unescape characters for no-magic
return s:unescape(a:str, '^$~.*[]\')
endfunction
function! s:unescape(str, chars) abort
let chars = map(split(a:chars, '\zs'), 'escape(v:val, ''^$~.*[]\'')')
return substitute(a:str, '\\\(' . join(chars, '\|') . '\)', '\1', 'g')
endfunction
function! s:iconv(expr, from, to) abort
if a:from ==# '' || a:to ==# '' || a:from ==? a:to
return a:expr
endif
let result = iconv(a:expr, a:from, a:to)
return empty(result) ? a:expr : result
endfunction
" NOTE:
" A definition of a TEXT file is "A file that contains characters organized
" into one or more lines."
" A definition of a LINE is "A sequence of zero or more non- <newline>s
" plus a terminating <newline>"
" That's why {stdin} always ends with <newline> ideally. However, there are
" some programs which does not follow the POSIX rule and a Vim's way to join
" List into TEXT; join({text}, "\n"); does not add <newline> to the end of
" the last line.
" That's why add a trailing <newline> if it does not exist.
" REF:
" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392
" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205
" :help split()
" NOTE:
" it does nothing if the text is a correct POSIX text
function! s:repair_posix_text(text, ...) abort
let newline = get(a:000, 0, "\n")
return a:text =~# '\n$' ? a:text : a:text . newline
endfunction
" NOTE:
" A definition of a TEXT file is "A file that contains characters organized
" into one or more lines."
" A definition of a LINE is "A sequence of zero or more non- <newline>s
" plus a terminating <newline>"
" REF:
" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392
" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205
function! s:join_posix_lines(lines, ...) abort
let newline = get(a:000, 0, "\n")
return join(a:lines, newline) . newline
endfunction
" NOTE:
" A definition of a TEXT file is "A file that contains characters organized
" into one or more lines."
" A definition of a LINE is "A sequence of zero or more non- <newline>s
" plus a terminating <newline>"
" TEXT into List; split({text}, '\r\?\n', 1); add an extra empty line at the
" end of List because the end of TEXT ends with <newline> and keepempty=1 is
" specified. (btw. keepempty=0 cannot be used because it will remove
" emptylines in the head and the tail).
" That's why removing a trailing <newline> before proceeding to 'split' is required
" REF:
" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_392
" http://pubs.opengroup.org/onlinepubs/000095399/basedefs/xbd_chap03.html#tag_03_205
function! s:split_posix_text(text, ...) abort
let newline = get(a:000, 0, '\r\?\n')
let text = substitute(a:text, newline . '$', '', '')
return split(text, newline, 1)
endfunction
let &cpo = s:save_cpo let &cpo = s:save_cpo
unlet s:save_cpo unlet s:save_cpo
" vim:set et ts=2 sts=2 sw=2 tw=0: " vim:set et ts=2 sts=2 sw=2 tw=0:

View File

@ -16,39 +16,60 @@ endif
let s:save_cpo = &cpo let s:save_cpo = &cpo
set cpo&vim set cpo&vim
if v:version ># 703 || if v:version > 703 ||
\ (v:version is 703 && has('patch465')) \ (v:version == 703 && has('patch465'))
function! s:glob(expr) abort function! s:glob(expr) abort
return glob(a:expr, 1, 1) return glob(a:expr, 1, 1)
endfunction endfunction
else else
function! s:glob(expr) abort function! s:glob(expr) abort
let R = glob(a:expr, 1) return split(glob(a:expr, 1), '\n')
return split(R, '\n')
endfunction endfunction
endif endif
function! s:globpath(path, expr) abort if v:version > 704 ||
let R = globpath(a:path, a:expr, 1) \ (v:version == 704 && has('patch279'))
return split(R, '\n') function! s:globpath(path, expr) abort
endfunction return globpath(a:path, a:expr, 1, 1)
endfunction
else
function! s:globpath(path, expr) abort
return split(globpath(a:path, a:expr, 1), '\n')
endfunction
endif
" Wrapper functions for type(). " Wrapper functions for type().
let [ " NOTE: __TYPE_FLOAT = -1 when -float.
\ s:__TYPE_NUMBER, " this doesn't match to anything.
\ s:__TYPE_STRING, if has('patch-7.4.2071')
\ s:__TYPE_FUNCREF, let [
\ s:__TYPE_LIST, \ s:__TYPE_NUMBER,
\ s:__TYPE_DICT, \ s:__TYPE_STRING,
\ s:__TYPE_FLOAT] = [ \ s:__TYPE_FUNCREF,
\ s:__TYPE_LIST,
\ s:__TYPE_DICT,
\ s:__TYPE_FLOAT] = [
\ v:t_number,
\ v:t_string,
\ v:t_func,
\ v:t_list,
\ v:t_dict,
\ v:t_float]
else
let [
\ s:__TYPE_NUMBER,
\ s:__TYPE_STRING,
\ s:__TYPE_FUNCREF,
\ s:__TYPE_LIST,
\ s:__TYPE_DICT,
\ s:__TYPE_FLOAT] = [
\ type(3), \ type(3),
\ type(''), \ type(''),
\ type(function('tr')), \ type(function('tr')),
\ type([]), \ type([]),
\ type({}), \ type({}),
\ has('float') ? type(str2float('0')) : -1] \ has('float') ? type(str2float('0')) : -1]
" __TYPE_FLOAT = -1 when -float endif
" This doesn't match to anything.
" Number or Float " Number or Float
function! s:is_numeric(Value) abort function! s:is_numeric(Value) abort
@ -62,27 +83,32 @@ function! s:is_number(Value) abort
return type(a:Value) ==# s:__TYPE_NUMBER return type(a:Value) ==# s:__TYPE_NUMBER
endfunction endfunction
" Float
function! s:is_float(Value) abort
return type(a:Value) ==# s:__TYPE_FLOAT
endfunction
" String " String
function! s:is_string(Value) abort function! s:is_string(Value) abort
return type(a:Value) ==# s:__TYPE_STRING return type(a:Value) ==# s:__TYPE_STRING
endfunction endfunction
" Funcref " Funcref
function! s:is_funcref(Value) abort function! s:is_funcref(Value) abort
return type(a:Value) ==# s:__TYPE_FUNCREF return type(a:Value) ==# s:__TYPE_FUNCREF
endfunction endfunction
" List " List
function! s:is_list(Value) abort function! s:is_list(Value) abort
return type(a:Value) ==# s:__TYPE_LIST return type(a:Value) ==# s:__TYPE_LIST
endfunction endfunction
" Dictionary " Dictionary
function! s:is_dict(Value) abort function! s:is_dict(Value) abort
return type(a:Value) ==# s:__TYPE_DICT return type(a:Value) ==# s:__TYPE_DICT
endfunction endfunction
" Float
function! s:is_float(Value) abort
return type(a:Value) ==# s:__TYPE_FLOAT
endfunction
function! s:truncate_skipping(str, max, footer_width, separator) abort function! s:truncate_skipping(str, max, footer_width, separator) abort
call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping') call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping')
@ -248,6 +274,10 @@ function! s:escape_file_searching(buffer_name) abort
endfunction endfunction
function! s:escape_pattern(str) abort function! s:escape_pattern(str) abort
call s:_warn_deprecated(
\ 'escape_pattern',
\ 'Data.String.escape_pattern',
\)
return escape(a:str, '~"\.^$[]*') return escape(a:str, '~"\.^$[]*')
endfunction endfunction

View File

@ -1,8 +1,7 @@
let s:plugin_name = expand('<sfile>:t:r') let s:plugin_name = expand('<sfile>:t:r')
let s:vital_base_dir = expand('<sfile>:h') let s:vital_base_dir = expand('<sfile>:h')
let s:project_root = expand('<sfile>:h:h:h') let s:project_root = expand('<sfile>:h:h:h')
let s:has_latest_module = isdirectory(expand('<sfile>:h') . '/__latest__') let s:is_vital_vim = s:plugin_name is# 'vital'
let s:is_vital_vim = s:plugin_name is# '_latest__'
let s:loaded = {} let s:loaded = {}
let s:cache_sid = {} let s:cache_sid = {}
@ -22,15 +21,22 @@ else
endfunction endfunction
endif endif
function! vital#{s:plugin_name}#of() abort function! vital#{s:plugin_name}#new() abort
return s:new(s:plugin_name) return s:new(s:plugin_name)
endfunction endfunction
function! vital#{s:plugin_name}#import(...) abort
if !exists('s:V')
let s:V = s:new(s:plugin_name)
endif
return call(s:V.import, a:000, s:V)
endfunction
let s:Vital = {} let s:Vital = {}
function! s:new(plugin_name) abort function! s:new(plugin_name) abort
let base = deepcopy(s:Vital) let base = deepcopy(s:Vital)
let base.plugin_name = a:plugin_name let base._plugin_name = a:plugin_name
return base return base
endfunction endfunction
@ -104,18 +110,10 @@ endfunction
let s:Vital.unload = s:_function('s:unload') let s:Vital.unload = s:_function('s:unload')
function! s:exists(name) abort dict function! s:exists(name) abort dict
let b = exists(printf('*vital#_%s#%s#import', self.plugin_name, substitute(a:name, '\.', '#', 'g'))) if a:name !~# '\v^\u\w*%(\.\u\w*)*$'
if b throw 'vital: Invalid module name: ' . a:name
return b
endif endif
let name_path = substitute(a:name, '\.', '/', 'g') return s:_module_path(a:name) isnot# ''
let path = printf('%s/_%s/%s.vim', s:vital_base_dir, self.plugin_name, name_path)
let b = filereadable(path)
if b
return b
endif
let path = printf('%s/_%s/%s.vim', s:vital_base_dir, '_latest__', name_path)
let b = filereadable(path)
endfunction endfunction
let s:Vital.exists = s:_function('s:exists') let s:Vital.exists = s:_function('s:exists')
@ -126,13 +124,20 @@ function! s:search(pattern) abort dict
endfunction endfunction
let s:Vital.search = s:_function('s:search') let s:Vital.search = s:_function('s:search')
function! s:plugin_name() abort dict
return self._plugin_name
endfunction
let s:Vital.plugin_name = s:_function('s:plugin_name')
function! s:_self_vital_files() abort function! s:_self_vital_files() abort
let base = s:vital_base_dir . '/*/**/*.vim' let builtin = printf('%s/__%s__/', s:vital_base_dir, s:plugin_name)
return split(glob(base, 1), "\n") let installed = printf('%s/_%s/', s:vital_base_dir, s:plugin_name)
let base = builtin . ',' . installed
return split(globpath(base, '**/*.vim', 1), "\n")
endfunction endfunction
function! s:_global_vital_files() abort function! s:_global_vital_files() abort
let pattern = 'autoload/vital/__latest__/**/*.vim' let pattern = 'autoload/vital/__*__/**/*.vim'
return split(globpath(&runtimepath, pattern, 1), "\n") return split(globpath(&runtimepath, pattern, 1), "\n")
endfunction endfunction
@ -165,7 +170,7 @@ function! s:_import(name) abort dict
let s:loaded[a:name] = export_module let s:loaded[a:name] = export_module
if has_key(module, '_vital_loaded') if has_key(module, '_vital_loaded')
try try
call module._vital_loaded(vital#{s:plugin_name}#of()) call module._vital_loaded(vital#{s:plugin_name}#new())
catch catch
unlet s:loaded[a:name] unlet s:loaded[a:name]
throw 'vital: fail to call ._vital_loaded(): ' . v:exception throw 'vital: fail to call ._vital_loaded(): ' . v:exception
@ -177,60 +182,92 @@ let s:Vital._import = s:_function('s:_import')
" s:_get_module() returns module object wihch has all script local functions. " s:_get_module() returns module object wihch has all script local functions.
function! s:_get_module(name) abort dict function! s:_get_module(name) abort dict
try let funcname = s:_import_func_name(self.plugin_name(), a:name)
let module = vital#_{self.plugin_name}#{substitute(a:name, '\.', '#', 'g')}#import() if s:_exists_autoload_func_with_source(funcname)
catch /E117: Unknown function:/ return call(funcname, [])
if !s:has_latest_module else
throw 'vital: module not found: ' . a:name return s:_get_builtin_module(a:name)
endif endif
" Retry to support loading self modules.
let module = s:_get_latest_module(a:name)
endtry
return module
endfunction endfunction
let s:Vital._get_module = s:_function('s:_get_module')
function! s:_get_latest_module(name) abort function! s:_get_builtin_module(name) abort
return s:sid2sfuncs(s:_module_sid(a:name)) return s:sid2sfuncs(s:_module_sid(a:name))
endfunction endfunction
if s:is_vital_vim
" For vital.vim, we can use s:_get_builtin_module directly
let s:Vital._get_module = s:_function('s:_get_builtin_module')
else
let s:Vital._get_module = s:_function('s:_get_module')
endif
function! s:_import_func_name(plugin_name, module_name) abort
return printf('vital#_%s#%s#import', a:plugin_name, s:_dot_to_sharp(a:module_name))
endfunction
function! s:_module_sid(name) abort function! s:_module_sid(name) abort
let module_rel_path = 'autoload/vital/__latest__/' . substitute(a:name, '\.', '/', 'g') . '.vim' let path = s:_module_path(a:name)
let module_full_path = s:_unify_path(get(split(globpath(s:_module_sid_base_dir(), module_rel_path, 0), "\n"), 0, '')) if !filereadable(path)
if !filereadable(module_full_path)
throw 'vital: module not found: ' . a:name throw 'vital: module not found: ' . a:name
endif endif
let p = substitute(module_rel_path, '/', '[/\\\\]\\+', 'g') let vital_dir = s:is_vital_vim ? '__\w\+__' : printf('_\{1,2}%s\%%(__\)\?', s:plugin_name)
let sid = s:_sid(module_full_path, p) let base = join([vital_dir, ''], '[/\\]\+')
let p = base . substitute('' . a:name, '\.', '[/\\\\]\\+', 'g')
let sid = s:_sid(path, p)
if !sid if !sid
call s:_source(module_full_path) call s:_source(path)
let sid = s:_sid(module_full_path, p) let sid = s:_sid(path, p)
if !sid if !sid
throw 'vital: cannot get <SID> from path' throw printf('vital: cannot get <SID> from path: %s', path)
endif endif
endif endif
return sid return sid
endfunction endfunction
function! s:_module_path(name) abort
return get(s:_extract_files(a:name, s:vital_files()), 0, '')
endfunction
function! s:_module_sid_base_dir() abort function! s:_module_sid_base_dir() abort
return s:is_vital_vim ? &rtp : s:project_root return s:is_vital_vim ? &rtp : s:project_root
endfunction endfunction
function! s:_dot_to_sharp(name) abort
return substitute(a:name, '\.', '#', 'g')
endfunction
" It will sources autoload file if a given func is not already defined.
function! s:_exists_autoload_func_with_source(funcname) abort
if exists('*' . a:funcname)
" Return true if a given func is already defined
return 1
endif
" source a file which may include a given func definition and try again.
let path = 'autoload/' . substitute(substitute(a:funcname, '#[^#]*$', '.vim', ''), '#', '/', 'g')
call s:_runtime(path)
return exists('*' . a:funcname)
endfunction
function! s:_runtime(path) abort
execute 'runtime' fnameescape(a:path)
endfunction
function! s:_source(path) abort function! s:_source(path) abort
execute 'source' fnameescape(a:path) execute 'source' fnameescape(a:path)
endfunction endfunction
" @vimlint(EVL102, 1, l:_) " @vimlint(EVL102, 1, l:_)
" @vimlint(EVL102, 1, l:__) " @vimlint(EVL102, 1, l:__)
function! s:_sid(fullpath, filter_pattern) abort function! s:_sid(path, filter_pattern) abort
if has_key(s:cache_sid, a:fullpath) let unified_path = s:_unify_path(a:path)
return s:cache_sid[a:fullpath] if has_key(s:cache_sid, unified_path)
return s:cache_sid[unified_path]
endif endif
for line in filter(split(s:_redir(':scriptnames'), "\n"), 'v:val =~# a:filter_pattern') for line in filter(split(s:_redir(':scriptnames'), "\n"), 'v:val =~# a:filter_pattern')
let [_, sid, path; __] = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$') let [_, sid, path; __] = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$')
if s:_unify_path(path) is# a:fullpath if s:_unify_path(path) is# unified_path
let s:cache_sid[a:fullpath] = sid let s:cache_sid[unified_path] = sid
return s:cache_sid[a:fullpath] return s:cache_sid[unified_path]
endif endif
endfor endfor
return 0 return 0
@ -246,7 +283,7 @@ function! s:_redir(cmd) abort
return res return res
endfunction endfunction
if filereadable(expand('<sfile>:r') . '.VIM') if filereadable(expand('<sfile>:r') . '.VIM') " is case-insensitive or not
let s:_unify_path_cache = {} let s:_unify_path_cache = {}
" resolve() is slow, so we cache results. " resolve() is slow, so we cache results.
" Note: On windows, vim can't expand path names from 8.3 formats. " Note: On windows, vim can't expand path names from 8.3 formats.

View File

@ -1,5 +1,5 @@
neosnippet neosnippet
024411ba1a5f3d545899c1be6eaa40bba036ae0d 645fe7142afdf5ef90e07cd275a15657c3328f53
Prelude Prelude
Data.List Data.List