11let s: self_version = expand (' <sfile>:t:r' )
22let s: self_file = expand (' <sfile>' )
3-
4- " Note: The extra argument to globpath() was added in Patch 7.2.051.
5- let s: globpath_third_arg = v: version > 702 || v: version == 702 && has (' patch51' )
3+ let s: base_dir = expand (' <sfile>:h' )
64
75let s: loaded = {}
86let s: cache_module_path = {}
97let s: cache_sid = {}
108
11- let s: _vital_files_cache_runtimepath = ' '
12- let s: _vital_files_cache = []
139let s: _unify_path_cache = {}
1410
11+ function ! s: plugin_name () abort
12+ let info_file = get (split (glob (s: base_dir . ' /*.vital' , 1 ), " \n " ), 0 , ' ' )
13+ return fnamemodify (info_file, ' :t:r' )
14+ endfunction
15+
16+ function ! s: vital_files () abort
17+ if ! exists (' s:vital_files' )
18+ let s: vital_files =
19+ \ map (
20+ \ s: plugin_name () == # ' vital'
21+ \ ? s: _global_vital_files ()
22+ \ : s: _self_vital_files (),
23+ \ ' fnamemodify(v:val, ":p:gs?[\\\\/]?/?")' )
24+ endif
25+ return copy (s: vital_files )
26+ endfunction
27+
1528function ! s: import (name, ... ) abort
1629 let target = {}
1730 let functions = []
@@ -67,42 +80,19 @@ function! s:unload() abort
6780 let s: loaded = {}
6881 let s: cache_sid = {}
6982 let s: cache_module_path = {}
83+ unlet ! s: vital_files
7084endfunction
7185
7286function ! s: exists (name) abort
7387 return s: _get_module_path (a: name ) !=# ' '
7488endfunction
7589
7690function ! s: search (pattern) abort
77- let paths = s: _vital_files (a: pattern )
91+ let paths = s: _extract_files (a: pattern, s: vital_files () )
7892 let modules = sort (map (paths, ' s:_file2module(v:val)' ))
7993 return s: _uniq (modules)
8094endfunction
8195
82- function ! s: expand_modules (entry, all ) abort
83- if type (a: entry ) == type ([])
84- let candidates = s: _concat (map (copy (a: entry ), ' s:search(v:val)' ))
85- if empty (candidates)
86- throw printf (' vital: Any of module %s is not found' , string (a: entry ))
87- endif
88- if eval (join (map (copy (candidates), ' has_key(a:all, v:val)' ), ' +' ))
89- let modules = []
90- else
91- let modules = [candidates[0 ]]
92- endif
93- else
94- let modules = s: search (a: entry )
95- if empty (modules)
96- throw printf (' vital: Module %s is not found' , a: entry )
97- endif
98- endif
99- call filter (modules, ' !has_key(a:all, v:val)' )
100- for module in modules
101- let a: all [module] = 1
102- endfor
103- return modules
104- endfunction
105-
10696function ! s: _import (name) abort
10797 if type (a: name ) == type (0 )
10898 return s: _build_module (a: name )
@@ -134,10 +124,8 @@ function! s:_get_module_path(name) abort
134124 if s: _is_absolute_path (a: name ) && filereadable (a: name )
135125 return a: name
136126 endif
137- if a: name == # ' '
138- let paths = [s: self_file ]
139- elseif a: name = ~# ' \v^\u\w*%(\.\u\w*)*$'
140- let paths = s: _vital_files (a: name )
127+ if a: name = ~# ' \v^\u\w*%(\.\u\w*)*$'
128+ let paths = s: _extract_files (a: name , s: vital_files ())
141129 else
142130 throw ' vital: Invalid module name: ' . a: name
143131 endif
@@ -154,8 +142,8 @@ function! s:_get_sid_by_script(path) abort
154142 endif
155143
156144 let path = s: _unify_path (a: path )
157- for line in filter ( split ( s: _redir ( ' scriptnames ' ) , " \n " ),
158- \ ' stridx(v:val, s:self_version) > 0 ' )
145+ let p = ' stridx(v:val, s:self_version) > 0 || stridx(v:val , "__latest__") > 0 '
146+ for line in filter ( split ( s: _redir ( ' scriptnames ' ), " \n " ), p )
159147 let list = matchlist (line , ' ^\s*\(\d\+\):\s\+\(.\+\)\s*$' )
160148 if ! empty (list ) && s: _unify_path (list [2 ]) == # path
161149 let s: cache_sid [a: path ] = list [1 ] - 0
@@ -191,28 +179,21 @@ else
191179 endfunction
192180endif
193181
194- if s: globpath_third_arg
195- function ! s: _runtime_files (path ) abort
196- return split (globpath (&runtimepath , a: path , 1 ), " \n " )
197- endfunction
198- else
199- function ! s: _runtime_files (path ) abort
200- return split (globpath (&runtimepath , a: path ), " \n " )
201- endfunction
202- endif
182+ function ! s: _self_vital_files () abort
183+ let base = s: base_dir . ' /*/**/*.vim'
184+ return split (glob (base, 1 ), " \n " )
185+ endfunction
203186
204- function ! s: _vital_files (pattern) abort
205- if s: _vital_files_cache_runtimepath !=# &runtimepath
206- let path = printf (' autoload/vital/%s/**/*.vim' , s: self_version )
207- let s: _vital_files_cache = s: _runtime_files (path )
208- let mod = ' :p:gs?[\\/]\+?/?'
209- call map (s: _vital_files_cache , ' fnamemodify(v:val, mod)' )
210- let s: _vital_files_cache_runtimepath = &runtimepath
211- endif
212- let target = substitute (a: pattern , ' \.' , ' /' , ' g' )
213- let target = substitute (target, ' \*' , ' [^/]*' , ' g' )
214- let regexp = printf (' autoload/vital/%s/%s.vim' , s: self_version , target)
215- return filter (copy (s: _vital_files_cache ), ' v:val =~# regexp' )
187+ function ! s: _global_vital_files () abort
188+ let pattern = ' autoload/vital/__latest__/**/*.vim'
189+ return split (globpath (&runtimepath , pattern, 1 ), " \n " )
190+ endfunction
191+
192+ function ! s: _extract_files (pattern, files ) abort
193+ let tr = {' .' : ' /' , ' *' : ' [^/]*' , ' **' : ' .*' }
194+ let target = substitute (a: pattern , ' \.\|\*\*\?' , ' \=tr[submatch(0)]' , ' g' )
195+ let regexp = printf (' autoload/vital/[^/]\+/%s.vim$' , target)
196+ return filter (a: files , ' v:val =~# regexp' )
216197endfunction
217198
218199" Copy from System.Filepath
@@ -241,10 +222,17 @@ function! s:_build_module(sid) abort
241222 call module._vital_created (module)
242223 endif
243224 let export_module = filter (copy (module), ' v:key =~# "^\\a"' )
225+ " Cache module before calling module.vital_debug() to avoid cyclic
226+ " dependences but remove the cache if module._vital_loaded() fails.
244227 let s: loaded [a: sid ] = get (g: , ' vital_debug' , 0 ) ? module : export_module
245228 if has_key (module, ' _vital_loaded' )
246- let V = vital#{s: self_version }#new ()
247- call module._vital_loaded (V)
229+ try
230+ let V = vital#{s: self_version }#new ()
231+ call module._vital_loaded (V)
232+ catch
233+ unlet s: loaded [a: sid ]
234+ throw ' vital: fail to call ._vital_loaded(): ' . v: exception
235+ endtry
248236 endif
249237 return copy (s: loaded [a: sid ])
250238endfunction
@@ -286,14 +274,6 @@ else
286274 endfunction
287275endif
288276
289- function ! s: _concat (lists) abort
290- let result_list = []
291- for list in a: lists
292- let result_list += list
293- endfor
294- return result_list
295- endfunction
296-
297277function ! s: _redir (cmd) abort
298278 let [save_verbose, save_verbosefile] = [&verbose , &verbosefile ]
299279 set verbose = 0 verbosefile =
@@ -305,5 +285,6 @@ function! s:_redir(cmd) abort
305285endfunction
306286
307287function ! vital#{s: self_version }#new () abort
308- return s: _import (' ' )
288+ let sid = s: _get_sid_by_script (s: self_file )
289+ return s: _build_module (sid )
309290endfunction
0 commit comments