From c179a51f024e27edf4354a52ff8b9fa69c4c803c Mon Sep 17 00:00:00 2001 From: Shougo Matsushita Date: Wed, 14 Dec 2016 06:23:37 +0900 Subject: [PATCH] Update vital --- autoload/neosnippet/util.vim | 6 +- autoload/vital.vim | 2 +- autoload/vital/_neosnippet.vim | 2 +- autoload/vital/_neosnippet/Data/String.vim | 160 ++++++++++++++------- autoload/vital/_neosnippet/Prelude.vim | 84 +++++++---- autoload/vital/neosnippet.vim | 131 +++++++++++------ autoload/vital/neosnippet.vital | 2 +- 7 files changed, 253 insertions(+), 134 deletions(-) diff --git a/autoload/neosnippet/util.vim b/autoload/neosnippet/util.vim index 1b45641..a9a603a 100644 --- a/autoload/neosnippet/util.vim +++ b/autoload/neosnippet/util.vim @@ -26,8 +26,10 @@ let s:save_cpo = &cpo set cpo&vim -let s:V = vital#neosnippet#of() function! neosnippet#util#get_vital() abort "{{{ + if !exists('s:V') + let s:V = vital#neosnippet#new() + endif return s:V endfunction"}}} 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) endfunction"}}} 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"}}} function! neosnippet#util#iconv(...) abort "{{{ return call(s:get_process().iconv, a:000) diff --git a/autoload/vital.vim b/autoload/vital.vim index 1004dfc..f1ba849 100644 --- a/autoload/vital.vim +++ b/autoload/vital.vim @@ -1,5 +1,5 @@ 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") if empty(file) throw 'vital: version file not found: ' . a:name diff --git a/autoload/vital/_neosnippet.vim b/autoload/vital/_neosnippet.vim index ae19f5b..9eba177 100644 --- a/autoload/vital/_neosnippet.vim +++ b/autoload/vital/_neosnippet.vim @@ -1,5 +1,5 @@ let s:_plugin_name = expand(':t:r') function! vital#{s:_plugin_name}#new() abort - return vital#{s:_plugin_name[1:]}#of() + return vital#{s:_plugin_name[1:]}#new() endfunction diff --git a/autoload/vital/_neosnippet/Data/String.vim b/autoload/vital/_neosnippet/Data/String.vim index 2824472..e87c2f6 100644 --- a/autoload/vital/_neosnippet/Data/String.vim +++ b/autoload/vital/_neosnippet/Data/String.vim @@ -3,13 +3,13 @@ " Do not mofidify the code nor insert new lines before '" ___vital___' if v:version > 703 || v:version == 703 && has('patch1170') 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 else function! s:_SID() abort return matchstr(expand(''), '\zs\d\+\ze__SID$') 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('%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('%s_' . v:key)\")", s:_SID()), 'endfunction'], "\n") delfunction s:_SID endif " ___vital___ @@ -20,12 +20,21 @@ set cpo&vim function! s:_vital_loaded(V) abort let s:V = a:V - let s:P = s:V.import('Prelude') let s:L = s:V.import('Data.List') endfunction 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 " Substitute a:from => a:to by string. @@ -143,9 +152,7 @@ endfunction " even if a:str contains multibyte character(s). " s:strchars(str) {{{ if exists('*strchars') - function! s:strchars(str) abort - return strchars(a:str) - endfunction + let s:strchars = function('strchars') else function! s:strchars(str) abort 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 length1 = len(letters1) 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) let distances[i1][0] = i1 @@ -453,8 +460,9 @@ function! s:truncate(str, width) abort " http://github.com/mattn/googlereader-vim/tree/master if a:str =~# '^[\x00-\x7f]*$' - return len(a:str) < a:width ? - \ printf('%-'.a:width.'s', a:str) : strpart(a:str, 0, a:width) + return len(a:str) < a:width + \ ? printf('%-' . a:width . 's', a:str) + \ : strpart(a:str, 0, a:width) endif let ret = a:str @@ -484,57 +492,20 @@ function! s:truncate_skipping(str, max, footer_width, separator) abort endfunction function! s:strwidthpart(str, width) abort - if a:width <= 0 - return '' - endif - 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], '') : '' + let str = tr(a:str, "\t", ' ') + let vcol = a:width + 2 + return matchstr(str, '.*\%<' . (vcol < 0 ? 0 : vcol) . 'v') endfunction function! s:strwidthpart_reverse(str, width) abort - if a:width <= 0 - return '' - endif - 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):], '') : '' + let str = tr(a:str, "\t", ' ') + let vcol = s:wcswidth(str) - a:width + return matchstr(str, '\%>' . (vcol < 0 ? 0 : vcol) . 'v.*') endfunction if v:version >= 703 " Use builtin function. - function! s:wcswidth(str) abort - return strwidth(a:str) - endfunction + let s:wcswidth = function('strwidth') else function! s:wcswidth(str) abort if a:str =~# '^[\x00-\x7f]*$' @@ -577,7 +548,86 @@ else endfunction 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- s +" plus a terminating " +" That's why {stdin} always ends with 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 to the end of +" the last line. +" That's why add a trailing 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- s +" plus a terminating " +" 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- s +" plus a terminating " +" 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 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 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 unlet s:save_cpo - " vim:set et ts=2 sts=2 sw=2 tw=0: diff --git a/autoload/vital/_neosnippet/Prelude.vim b/autoload/vital/_neosnippet/Prelude.vim index ed80ed7..31f6768 100644 --- a/autoload/vital/_neosnippet/Prelude.vim +++ b/autoload/vital/_neosnippet/Prelude.vim @@ -16,39 +16,60 @@ endif let s:save_cpo = &cpo set cpo&vim -if v:version ># 703 || -\ (v:version is 703 && has('patch465')) +if v:version > 703 || +\ (v:version == 703 && has('patch465')) function! s:glob(expr) abort return glob(a:expr, 1, 1) endfunction else function! s:glob(expr) abort - let R = glob(a:expr, 1) - return split(R, '\n') + return split(glob(a:expr, 1), '\n') endfunction endif -function! s:globpath(path, expr) abort - let R = globpath(a:path, a:expr, 1) - return split(R, '\n') -endfunction +if v:version > 704 || +\ (v:version == 704 && has('patch279')) + function! s:globpath(path, expr) abort + 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(). -let [ -\ s:__TYPE_NUMBER, -\ s:__TYPE_STRING, -\ s:__TYPE_FUNCREF, -\ s:__TYPE_LIST, -\ s:__TYPE_DICT, -\ s:__TYPE_FLOAT] = [ - \ type(3), - \ type(''), - \ type(function('tr')), - \ type([]), - \ type({}), - \ has('float') ? type(str2float('0')) : -1] -" __TYPE_FLOAT = -1 when -float -" This doesn't match to anything. +" NOTE: __TYPE_FLOAT = -1 when -float. +" this doesn't match to anything. +if has('patch-7.4.2071') + let [ + \ s:__TYPE_NUMBER, + \ s:__TYPE_STRING, + \ 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(''), + \ type(function('tr')), + \ type([]), + \ type({}), + \ has('float') ? type(str2float('0')) : -1] +endif " Number or Float function! s:is_numeric(Value) abort @@ -62,27 +83,32 @@ function! s:is_number(Value) abort return type(a:Value) ==# s:__TYPE_NUMBER endfunction -" Float -function! s:is_float(Value) abort - return type(a:Value) ==# s:__TYPE_FLOAT -endfunction " String function! s:is_string(Value) abort return type(a:Value) ==# s:__TYPE_STRING endfunction + " Funcref function! s:is_funcref(Value) abort return type(a:Value) ==# s:__TYPE_FUNCREF endfunction + " List function! s:is_list(Value) abort return type(a:Value) ==# s:__TYPE_LIST endfunction + " Dictionary function! s:is_dict(Value) abort return type(a:Value) ==# s:__TYPE_DICT 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 call s:_warn_deprecated('truncate_skipping', 'Data.String.truncate_skipping') @@ -248,6 +274,10 @@ function! s:escape_file_searching(buffer_name) abort endfunction function! s:escape_pattern(str) abort + call s:_warn_deprecated( + \ 'escape_pattern', + \ 'Data.String.escape_pattern', + \) return escape(a:str, '~"\.^$[]*') endfunction diff --git a/autoload/vital/neosnippet.vim b/autoload/vital/neosnippet.vim index bec6299..d428cc2 100644 --- a/autoload/vital/neosnippet.vim +++ b/autoload/vital/neosnippet.vim @@ -1,8 +1,7 @@ let s:plugin_name = expand(':t:r') let s:vital_base_dir = expand(':h') let s:project_root = expand(':h:h:h') -let s:has_latest_module = isdirectory(expand(':h') . '/__latest__') -let s:is_vital_vim = s:plugin_name is# '_latest__' +let s:is_vital_vim = s:plugin_name is# 'vital' let s:loaded = {} let s:cache_sid = {} @@ -22,15 +21,22 @@ else endfunction endif -function! vital#{s:plugin_name}#of() abort +function! vital#{s:plugin_name}#new() abort return s:new(s:plugin_name) 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 = {} function! s:new(plugin_name) abort let base = deepcopy(s:Vital) - let base.plugin_name = a:plugin_name + let base._plugin_name = a:plugin_name return base endfunction @@ -104,18 +110,10 @@ endfunction let s:Vital.unload = s:_function('s:unload') function! s:exists(name) abort dict - let b = exists(printf('*vital#_%s#%s#import', self.plugin_name, substitute(a:name, '\.', '#', 'g'))) - if b - return b + if a:name !~# '\v^\u\w*%(\.\u\w*)*$' + throw 'vital: Invalid module name: ' . a:name endif - let name_path = substitute(a:name, '\.', '/', 'g') - 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) + return s:_module_path(a:name) isnot# '' endfunction let s:Vital.exists = s:_function('s:exists') @@ -126,13 +124,20 @@ function! s:search(pattern) abort dict endfunction 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 - let base = s:vital_base_dir . '/*/**/*.vim' - return split(glob(base, 1), "\n") + let builtin = printf('%s/__%s__/', s:vital_base_dir, s:plugin_name) + let installed = printf('%s/_%s/', s:vital_base_dir, s:plugin_name) + let base = builtin . ',' . installed + return split(globpath(base, '**/*.vim', 1), "\n") endfunction function! s:_global_vital_files() abort - let pattern = 'autoload/vital/__latest__/**/*.vim' + let pattern = 'autoload/vital/__*__/**/*.vim' return split(globpath(&runtimepath, pattern, 1), "\n") endfunction @@ -165,7 +170,7 @@ function! s:_import(name) abort dict let s:loaded[a:name] = export_module if has_key(module, '_vital_loaded') try - call module._vital_loaded(vital#{s:plugin_name}#of()) + call module._vital_loaded(vital#{s:plugin_name}#new()) catch unlet s:loaded[a:name] 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. function! s:_get_module(name) abort dict - try - let module = vital#_{self.plugin_name}#{substitute(a:name, '\.', '#', 'g')}#import() - catch /E117: Unknown function:/ - if !s:has_latest_module - throw 'vital: module not found: ' . a:name - endif - " Retry to support loading self modules. - let module = s:_get_latest_module(a:name) - endtry - return module + let funcname = s:_import_func_name(self.plugin_name(), a:name) + if s:_exists_autoload_func_with_source(funcname) + return call(funcname, []) + else + return s:_get_builtin_module(a:name) + endif 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)) 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 - let module_rel_path = 'autoload/vital/__latest__/' . substitute(a:name, '\.', '/', 'g') . '.vim' - let module_full_path = s:_unify_path(get(split(globpath(s:_module_sid_base_dir(), module_rel_path, 0), "\n"), 0, '')) - if !filereadable(module_full_path) + let path = s:_module_path(a:name) + if !filereadable(path) throw 'vital: module not found: ' . a:name endif - let p = substitute(module_rel_path, '/', '[/\\\\]\\+', 'g') - let sid = s:_sid(module_full_path, p) + let vital_dir = s:is_vital_vim ? '__\w\+__' : printf('_\{1,2}%s\%%(__\)\?', s:plugin_name) + let base = join([vital_dir, ''], '[/\\]\+') + let p = base . substitute('' . a:name, '\.', '[/\\\\]\\+', 'g') + let sid = s:_sid(path, p) if !sid - call s:_source(module_full_path) - let sid = s:_sid(module_full_path, p) + call s:_source(path) + let sid = s:_sid(path, p) if !sid - throw 'vital: cannot get from path' + throw printf('vital: cannot get from path: %s', path) endif endif return sid 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 return s:is_vital_vim ? &rtp : s:project_root 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 execute 'source' fnameescape(a:path) endfunction " @vimlint(EVL102, 1, l:_) " @vimlint(EVL102, 1, l:__) -function! s:_sid(fullpath, filter_pattern) abort - if has_key(s:cache_sid, a:fullpath) - return s:cache_sid[a:fullpath] +function! s:_sid(path, filter_pattern) abort + let unified_path = s:_unify_path(a:path) + if has_key(s:cache_sid, unified_path) + return s:cache_sid[unified_path] endif for line in filter(split(s:_redir(':scriptnames'), "\n"), 'v:val =~# a:filter_pattern') let [_, sid, path; __] = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$') - if s:_unify_path(path) is# a:fullpath - let s:cache_sid[a:fullpath] = sid - return s:cache_sid[a:fullpath] + if s:_unify_path(path) is# unified_path + let s:cache_sid[unified_path] = sid + return s:cache_sid[unified_path] endif endfor return 0 @@ -246,7 +283,7 @@ function! s:_redir(cmd) abort return res endfunction -if filereadable(expand(':r') . '.VIM') +if filereadable(expand(':r') . '.VIM') " is case-insensitive or not let s:_unify_path_cache = {} " resolve() is slow, so we cache results. " Note: On windows, vim can't expand path names from 8.3 formats. @@ -295,7 +332,7 @@ else if a:list[i] ==# a:list[i - 1] call remove(a:list, i) endif - let i -= 1 + let i -= 1 endwhile return a:list endfunction diff --git a/autoload/vital/neosnippet.vital b/autoload/vital/neosnippet.vital index c3243ed..6d4f6a3 100644 --- a/autoload/vital/neosnippet.vital +++ b/autoload/vital/neosnippet.vital @@ -1,5 +1,5 @@ neosnippet -024411ba1a5f3d545899c1be6eaa40bba036ae0d +645fe7142afdf5ef90e07cd275a15657c3328f53 Prelude Data.List