Skip to content

Commit c6fa7c6

Browse files
authored
Merge pull request #367 from vim-denops/fix-cache-update
🐛 Refactor `denops#plugin` module and fix `denops#cache#update()` to use registered plugins instead
2 parents 6e14ad1 + c616af0 commit c6fa7c6

File tree

3 files changed

+129
-109
lines changed

3 files changed

+129
-109
lines changed

autoload/denops/_internal/plugin.vim

Lines changed: 65 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,69 @@
1-
function! denops#_internal#plugin#collect() abort
2-
let l:pattern = denops#_internal#path#join(['denops', '*', 'main.ts'])
3-
let l:plugins = []
4-
for l:script in globpath(&runtimepath, l:pattern, 1, 1, 1)
5-
let l:name = fnamemodify(l:script, ':h:t')
6-
if l:name[:0] ==# '@' || !filereadable(l:script)
7-
continue
8-
endif
9-
call add(l:plugins, #{ name: l:name, script: l:script })
10-
endfor
11-
return l:plugins
1+
const s:STATE_RESERVED = 'reserved'
2+
const s:STATE_LOADING = 'loading'
3+
const s:STATE_LOADED = 'loaded'
4+
const s:STATE_FAILED = 'failed'
5+
6+
let s:plugins = {}
7+
8+
function! denops#_internal#plugin#get(name) abort
9+
if !has_key(s:plugins, a:name)
10+
let s:plugins[a:name] = #{name: a:name, script: '', state: s:STATE_RESERVED, callbacks: []}
11+
endif
12+
return s:plugins[a:name]
13+
endfunction
14+
15+
function! denops#_internal#plugin#list() abort
16+
return values(s:plugins)
17+
endfunction
18+
19+
function! denops#_internal#plugin#load(name, script) abort
20+
const l:script = denops#_internal#path#norm(a:script)
21+
const l:args = [a:name, l:script]
22+
let l:plugin = denops#_internal#plugin#get(a:name)
23+
let l:plugin.state = s:STATE_LOADING
24+
let l:plugin.script = l:script
25+
let s:plugins[a:name] = l:plugin
26+
call denops#_internal#echo#debug(printf('load plugin: %s', l:args))
27+
call denops#_internal#server#chan#notify('invoke', ['load', l:args])
1228
endfunction
1329

14-
function! denops#_internal#plugin#find(name) abort
15-
let l:pattern = denops#_internal#path#join(['denops', a:name, 'main.ts'])
16-
for l:script in globpath(&runtimepath, l:pattern, 1, 1, 1)
17-
let l:name = fnamemodify(l:script, ':h:t')
18-
if l:name[:0] ==# '@' || !filereadable(l:script)
19-
continue
20-
endif
21-
return #{ name: l:name, script: l:script }
30+
function! denops#_internal#plugin#reload(name) abort
31+
const l:args = [a:name]
32+
let l:plugin = denops#_internal#plugin#get(a:name)
33+
let l:plugin.state = s:STATE_LOADING
34+
call denops#_internal#echo#debug(printf('reload plugin: %s', l:args))
35+
call denops#_internal#server#chan#notify('invoke', ['reload', l:args])
36+
endfunction
37+
38+
function! s:DenopsSystemPluginPre() abort
39+
const l:name = matchstr(expand('<amatch>'), 'DenopsSystemPluginPre:\zs.*')
40+
execute printf('doautocmd <nomodeline> User DenopsPluginPre:%s', l:name)
41+
endfunction
42+
43+
function! s:DenopsSystemPluginPost() abort
44+
const l:name = matchstr(expand('<amatch>'), 'DenopsSystemPluginPost:\zs.*')
45+
let l:plugin = denops#_internal#plugin#get(l:name)
46+
const l:callbacks = l:plugin.callbacks
47+
let l:plugin.state = s:STATE_LOADED
48+
let l:plugin.callbacks = []
49+
for l:Callback in l:callbacks
50+
call l:Callback()
2251
endfor
23-
throw printf('No denops plugin for "%s" exists', a:name)
52+
execute printf('doautocmd <nomodeline> User DenopsPluginPost:%s', l:name)
2453
endfunction
54+
55+
function! s:DenopsSystemPluginFail() abort
56+
const l:name = matchstr(expand('<amatch>'), 'DenopsSystemPluginFail:\zs.*')
57+
let l:plugin = denops#_internal#plugin#get(a:name)
58+
let l:plugin.state = s:STATE_FAILED
59+
let l:plugin.callbacks = []
60+
execute printf('doautocmd <nomodeline> User DenopsPluginFail:%s', l:name)
61+
endfunction
62+
63+
augroup denops_autoload_plugin_internal
64+
autocmd!
65+
autocmd User DenopsSystemPluginPre:* ++nested call s:DenopsSystemPluginPre()
66+
autocmd User DenopsSystemPluginPost:* ++nested call s:DenopsSystemPluginPost()
67+
autocmd User DenopsSystemPluginFail:* ++nested call s:DenopsSystemPluginFail()
68+
autocmd User DenopsClosed let s:plugins = {}
69+
augroup END

autoload/denops/cache.vim

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
let s:root = expand('<sfile>:p:h:h:h')
1+
const s:root = expand('<sfile>:p:h:h:h')
2+
const s:mod = denops#_internal#path#join([s:root, 'denops', '@denops-private', 'mod.ts'])
23
let s:job = v:null
34

45
function! denops#cache#update(...) abort
5-
let l:options = extend(#{ reload: v:false }, a:0 ? a:1 : {})
6-
let l:entryfiles = extend([
7-
\ denops#_internal#path#join([s:root, 'denops', '@denops-private', 'mod.ts']),
8-
\], map(denops#_internal#plugin#collect(), { _, v -> v.script }))
6+
const l:options = extend(#{ reload: v:false }, a:0 ? a:1 : {})
7+
const l:plugins = denops#_internal#plugin#list()
8+
const l:entryfiles = extend([s:mod], map(copy(l:plugins), { _, v -> v.script }))
99

1010
let l:args = [g:denops#deno, 'cache']
1111

autoload/denops/plugin.vim

Lines changed: 59 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
let s:loaded_plugins = {}
2-
let s:load_callbacks = {}
3-
41
function! denops#plugin#is_loaded(name) abort
5-
return has_key(s:loaded_plugins, a:name)
2+
return denops#_internal#plugin#get(a:name).state =~# '^\%(loaded\|failed\)$'
63
endfunction
74

85
function! denops#plugin#wait(name, ...) abort
@@ -21,80 +18,63 @@ function! denops#plugin#wait(name, ...) abort
2118
endif
2219
return -2
2320
endif
24-
if has_key(s:loaded_plugins, a:name)
25-
return s:loaded_plugins[a:name]
26-
endif
27-
let l:ret = denops#_internal#wait#for(
28-
\ l:options.timeout,
29-
\ { -> has_key(s:loaded_plugins, a:name) },
30-
\ l:options.interval,
31-
\)
32-
if l:ret is# -1
33-
if !l:options.silent
34-
call denops#_internal#echo#error(printf(
35-
\ 'Failed to wait for "%s" to start. It took more than %d milliseconds and timed out.',
36-
\ a:name,
37-
\ l:options.timeout,
38-
\))
21+
if !denops#plugin#is_loaded(a:name)
22+
let l:ret = denops#_internal#wait#for(
23+
\ l:options.timeout,
24+
\ { -> denops#plugin#is_loaded(a:name) },
25+
\ l:options.interval,
26+
\)
27+
if l:ret is# -1
28+
if !l:options.silent
29+
call denops#_internal#echo#error(printf(
30+
\ 'Failed to wait for "%s" to start. It took more than %d milliseconds and timed out.',
31+
\ a:name,
32+
\ l:options.timeout,
33+
\))
34+
endif
35+
return -1
3936
endif
40-
return -1
4137
endif
38+
return denops#_internal#plugin#get(a:name).state ==# 'loaded' ? 0 : -3
4239
endfunction
4340

4441
function! denops#plugin#wait_async(name, callback) abort
45-
if has_key(s:loaded_plugins, a:name)
46-
if s:loaded_plugins[a:name] isnot# 0
47-
return
48-
endif
42+
let l:plugin = denops#_internal#plugin#get(a:name)
43+
if l:plugin.state ==# 'loaded'
4944
call a:callback()
5045
return
46+
elseif l:plugin.state ==# 'failed'
47+
return
5148
endif
52-
let l:callbacks = get(s:load_callbacks, a:name, [])
53-
call add(l:callbacks, a:callback)
54-
let s:load_callbacks[a:name] = l:callbacks
55-
endfunction
56-
57-
" DEPRECATED
58-
" Some plugins (e.g. dein.vim) use this function with options thus we cannot
59-
" change the interface of this function.
60-
" That's why we introduce 'load' function that replaces this function.
61-
function! denops#plugin#register(name, ...) abort
62-
call denops#_internal#echo#deprecate(
63-
\ 'denops#plugin#register() is deprecated. Use denops#plugin#load() instead.',
64-
\)
65-
if a:0 is# 0 || type(a:1) is# v:t_dict
66-
let l:script = denops#_internal#plugin#find(a:name).script
67-
else
68-
let l:script = a:1
69-
endif
70-
return denops#plugin#load(a:name, l:script)
49+
call add(l:plugin.callbacks, a:callback)
7150
endfunction
7251

7352
function! denops#plugin#load(name, script) abort
74-
let l:script = denops#_internal#path#norm(a:script)
75-
let l:args = [a:name, l:script]
76-
call denops#_internal#echo#debug(printf('load plugin: %s', l:args))
77-
call denops#_internal#server#chan#notify('invoke', ['load', l:args])
53+
call denops#_internal#plugin#load(a:name, a:script)
7854
endfunction
7955

8056
function! denops#plugin#reload(name) abort
81-
let l:args = [a:name]
82-
call denops#_internal#echo#debug(printf('reload plugin: %s', l:args))
83-
call denops#_internal#server#chan#notify('invoke', ['reload', l:args])
57+
call denops#_internal#plugin#reload(a:name)
8458
endfunction
8559

8660
function! denops#plugin#discover() abort
87-
let l:plugins = denops#_internal#plugin#collect()
88-
call denops#_internal#echo#debug(printf('%d plugins are discovered', len(l:plugins)))
89-
for l:plugin in l:plugins
90-
call denops#plugin#load(l:plugin.name, l:plugin.script)
61+
const l:pattern = denops#_internal#path#join(['denops', '*', 'main.ts'])
62+
let l:counter = 0
63+
for l:script in globpath(&runtimepath, l:pattern, 1, 1, 1)
64+
let l:name = fnamemodify(l:script, ':h:t')
65+
if l:name[:0] ==# '@' || !filereadable(l:script)
66+
continue
67+
endif
68+
call denops#plugin#load(l:name, l:script)
69+
let l:counter += 1
9170
endfor
71+
call denops#_internal#echo#debug(printf('%d plugins are discovered', l:counter))
9272
endfunction
9373

9474
function! denops#plugin#check_type(...) abort
9575
let l:plugins = a:0
96-
\ ? [denops#_internal#plugin#find(a:1)]
97-
\ : denops#_internal#plugin#collect()
76+
\ ? [denops#_internal#plugin#get(a:1)]
77+
\ : denops#_internal#plugin#list()
9878
let l:args = [g:denops#deno, 'check']
9979
let l:args = extend(l:args, map(l:plugins, { _, v -> v.script }))
10080
let l:job = denops#_internal#job#start(l:args, {
@@ -110,38 +90,33 @@ function! denops#plugin#check_type(...) abort
11090
\ })
11191
endfunction
11292

113-
function! s:relay_autocmd(name) abort
114-
let l:plugin = matchstr(expand('<amatch>'), '^[^:]\+:\zs.*')
115-
execute printf('doautocmd <nomodeline> User %s:%s', a:name, l:plugin)
116-
endfunction
117-
118-
function! s:DenopsSystemPluginPost() abort
119-
let l:plugin = matchstr(expand('<amatch>'), 'DenopsSystemPluginPost:\zs.*')
120-
let s:loaded_plugins[l:plugin] = 0
121-
if has_key(s:load_callbacks, l:plugin)
122-
for l:Callback in remove(s:load_callbacks, l:plugin)
123-
call l:Callback()
124-
endfor
93+
" DEPRECATED
94+
" Some plugins (e.g. dein.vim) use this function with options thus we cannot
95+
" change the interface of this function.
96+
" That's why we introduce 'load' function that replaces this function.
97+
function! denops#plugin#register(name, ...) abort
98+
call denops#_internal#echo#deprecate(
99+
\ 'denops#plugin#register() is deprecated. Use denops#plugin#load() instead.',
100+
\)
101+
if a:0 is# 0 || type(a:1) is# v:t_dict
102+
let l:script = s:find_script(a:name)
103+
else
104+
let l:script = a:1
125105
endif
126-
execute printf('doautocmd <nomodeline> User DenopsPluginPost:%s', l:plugin)
106+
return denops#plugin#load(a:name, l:script)
127107
endfunction
128108

129-
function! s:DenopsSystemPluginFail() abort
130-
let l:plugin = matchstr(expand('<amatch>'), 'DenopsSystemPluginFail:\zs.*')
131-
let s:loaded_plugins[l:plugin] = -3
132-
if has_key(s:load_callbacks, l:plugin)
133-
call remove(s:load_callbacks, l:plugin)
134-
endif
135-
execute printf('doautocmd <nomodeline> User DenopsPluginFail:%s', l:plugin)
109+
function! s:find_script(name) abort
110+
const l:pattern = denops#_internal#path#join(['denops', a:name, 'main.ts'])
111+
for l:script in globpath(&runtimepath, l:pattern, 1, 1, 1)
112+
let l:name = fnamemodify(l:script, ':h:t')
113+
if l:name[:0] ==# '@' || !filereadable(l:script)
114+
continue
115+
endif
116+
return l:script
117+
endfor
118+
throw printf('Denops plugin "%s" does not exist in the runtimepath', a:name)
136119
endfunction
137120

138-
augroup denops_autoload_plugin_internal
139-
autocmd!
140-
autocmd User DenopsSystemPluginPre:* call s:relay_autocmd('DenopsPluginPre')
141-
autocmd User DenopsSystemPluginPost:* ++nested call s:DenopsSystemPluginPost()
142-
autocmd User DenopsSystemPluginFail:* call s:DenopsSystemPluginFail()
143-
autocmd User DenopsClosed let s:loaded_plugins = {}
144-
augroup END
145-
146121
call denops#_internal#conf#define('denops#plugin#wait_interval', 200)
147122
call denops#_internal#conf#define('denops#plugin#wait_timeout', 30000)

0 commit comments

Comments
 (0)