All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
2 Save g:ale_completion_enabled
3 Save g:ale_completion_delay
4 Save g:ale_completion_max_suggestions
8 unlet! b:ale_completion_enabled
9 let g:ale_completion_enabled = 1
10 let g:get_completions_called = 0
11 let g:feedkeys_calls = []
15 \ 'typescript': ['tsserver'],
18 let &l:completeopt = 'menu,menuone,preview,noselect,noinsert'
20 runtime autoload/ale/util.vim
22 function! ale#util#FeedKeys(string) abort
23 call add(g:feedkeys_calls, [a:string])
26 " Pretend we're in insert mode for most tests.
27 function! ale#util#Mode(...) abort
31 function! CheckCompletionCalled(expect_success) abort
32 let g:get_completions_called = 0
34 " We just want to check if the function is called.
35 function! ale#completion#GetCompletions(source)
36 let g:get_completions_called = 1
39 let g:ale_completion_delay = 0
41 " Run this check a few times, as it can fail randomly.
42 for l:i in range(has('nvim-0.3') || has('win32') ? 5 : 1)
43 call ale#completion#Queue()
46 if g:get_completions_called is a:expect_success
51 AssertEqual a:expect_success, g:get_completions_called
54 let g:handle_code_action_called = 0
55 function! MockHandleCodeAction() abort
56 " delfunction! ale#code_action#HandleCodeAction
57 function! ale#code_action#HandleCodeAction(action, options) abort
58 Assert !get(a:options, 'should_save')
59 let g:handle_code_action_called += 1
66 unlet! b:ale_completion_enabled
69 unlet! g:get_completions_called
70 unlet! g:handle_code_action_called
71 unlet! b:ale_old_omnifunc
72 unlet! b:ale_old_completeopt
73 unlet! b:ale_completion_info
74 unlet! b:ale_completion_result
75 unlet! b:ale_complete_done_time
78 delfunction CheckCompletionCalled
79 delfunction ale#code_action#HandleCodeAction
80 delfunction MockHandleCodeAction
82 if exists('*CompleteCallback')
83 delfunction CompleteCallback
86 " Stop any timers we left behind.
87 " This stops the tests from failing randomly.
88 call ale#completion#StopTimer()
90 " Reset the function. The runtime command below should fix this, but doesn't
92 function! ale#util#Mode(...) abort
93 return call('mode', a:000)
96 runtime autoload/ale/completion.vim
97 runtime autoload/ale/code_action.vim
98 runtime autoload/ale/util.vim
100 Execute(ale#completion#GetCompletions should be called when the cursor position stays the same):
101 call CheckCompletionCalled(1)
103 Execute(ale#completion#GetCompletions should not be called if the global setting is disabled):
104 let g:ale_completion_enabled = 0
105 call CheckCompletionCalled(0)
107 Execute(ale#completion#GetCompletions should not be called if the buffer setting is disabled):
108 let b:ale_completion_enabled = 0
109 call CheckCompletionCalled(0)
116 Execute(ale#completion#GetCompletions should not be called when the cursor position changes):
117 call setpos('.', [bufnr(''), 1, 2, 0])
119 " We just want to check if the function is called.
120 function! ale#completion#GetCompletions(source)
121 let g:get_completions_called = 1
124 let g:ale_completion_delay = 0
125 call ale#completion#Queue()
127 " Change the cursor position before the callback is triggered.
128 call setpos('.', [bufnr(''), 2, 2, 0])
132 Assert !g:get_completions_called
134 Execute(ale#completion#GetCompletions should not be called if you switch to normal mode):
135 let &l:completeopt = 'menu,preview'
136 let g:fake_mode = 'n'
138 " We just want to check if the function is called.
139 function! ale#completion#GetCompletions(source)
140 let g:get_completions_called = 1
143 let g:ale_completion_delay = 0
144 call ale#completion#Queue()
148 Assert !g:get_completions_called
150 Execute(Completion should not be done shortly after the CompleteDone function):
151 call CheckCompletionCalled(1)
152 call ale#completion#Done()
153 call CheckCompletionCalled(0)
155 Execute(ale#completion#Show() should remember the omnifunc setting and replace it):
156 let &l:omnifunc = 'FooBar'
158 let b:ale_completion_info = {'source': 'ale-automatic'}
159 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
161 AssertEqual 'FooBar', b:ale_old_omnifunc
162 AssertEqual 'ale#completion#AutomaticOmniFunc', &l:omnifunc
164 AssertEqual [], g:feedkeys_calls
166 AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls
168 Execute(ale#completion#Show() should remember the completeopt setting and replace it):
169 let &l:completeopt = 'menu'
171 let b:ale_completion_info = {'source': 'ale-automatic'}
172 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
174 AssertEqual 'menu', b:ale_old_completeopt
175 AssertEqual 'menu,menuone,noinsert', &l:completeopt
177 AssertEqual [], g:feedkeys_calls
179 AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls
181 Execute(ale#completion#Show() should set the preview option if it's set):
182 let &l:completeopt = 'menu,preview'
184 let b:ale_completion_info = {'source': 'ale-automatic'}
185 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
187 AssertEqual 'menu,preview', b:ale_old_completeopt
188 AssertEqual 'menu,menuone,noinsert,preview', &l:completeopt
190 AssertEqual [], g:feedkeys_calls
192 AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls
194 Execute(ale#completion#Show() should not replace the completeopt setting for manual completion):
195 let b:ale_completion_info = {'source': 'ale-manual'}
197 let &l:completeopt = 'menu,preview'
199 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
201 Assert !exists('b:ale_old_completeopt')
203 AssertEqual [], g:feedkeys_calls
205 AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls
207 Execute(ale#completion#AutomaticOmniFunc() should also remember the completeopt setting and replace it):
208 let &l:completeopt = 'menu,noselect'
210 let b:ale_completion_info = {'source': 'ale-automatic'}
211 call ale#completion#AutomaticOmniFunc(0, '')
213 AssertEqual 'menu,noselect', b:ale_old_completeopt
214 AssertEqual 'menu,menuone,noinsert,noselect', &l:completeopt
216 Execute(ale#completion#AutomaticOmniFunc() should set the preview option if it's set):
217 let &l:completeopt = 'menu,preview'
219 let b:ale_completion_info = {'source': 'ale-automatic'}
220 call ale#completion#AutomaticOmniFunc(0, '')
222 AssertEqual 'menu,preview', b:ale_old_completeopt
223 AssertEqual 'menu,menuone,noinsert,preview', &l:completeopt
225 Execute(ale#completion#Show() should make the correct feedkeys() call for automatic completion):
226 let b:ale_completion_info = {'source': 'ale-automatic'}
227 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
229 AssertEqual [], g:feedkeys_calls
231 AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls
233 Execute(ale#completion#Show() should make the correct feedkeys() call for manual completion):
234 let b:ale_completion_info = {'source': 'ale-automatic'}
235 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
237 AssertEqual [], g:feedkeys_calls
239 AssertEqual [["\<Plug>(ale_show_completion_menu)"]], g:feedkeys_calls
241 Execute(ale#completion#Show() should not call feedkeys() for other sources):
242 let b:ale_completion_info = {'source': 'other-source'}
243 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
246 AssertEqual [], g:feedkeys_calls
248 Execute(ale#completion#Show() shouldn't do anything if you switch back to normal mode):
249 let &l:completeopt = 'menu,preview'
250 let g:fake_mode = 'n'
252 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
254 AssertEqual 'menu,preview', &l:completeopt
255 Assert !exists('b:ale_old_omnifunc')
256 Assert !exists('b:ale_old_completeopt')
257 Assert !exists('b:ale_completion_result')
258 AssertEqual [], g:feedkeys_calls
260 Execute(ale#completion#Show() should save the result it is given):
261 call ale#completion#Show([])
263 AssertEqual [], b:ale_completion_result
265 call ale#completion#Show([{'word': 'x', 'kind': 'v', 'icase': 1}])
267 AssertEqual [{'word': 'x', 'kind': 'v', 'icase': 1}], b:ale_completion_result
269 Execute(ale#completion#Done() should restore old omnifunc values):
270 let b:ale_old_omnifunc = 'FooBar'
272 call ale#completion#Done()
274 " We reset the old omnifunc setting and remove the buffer variable.
275 AssertEqual 'FooBar', &l:omnifunc
276 Assert !has_key(b:, 'ale_old_omnifunc')
278 Execute(ale#completion#Done() should restore the old completeopt setting):
279 let b:ale_old_completeopt = 'menu'
281 call ale#completion#Done()
283 AssertEqual 'menu', &l:completeopt
284 Assert !has_key(b:, 'ale_old_completeopt')
286 Execute(ale#completion#Done() should leave settings alone when none were remembered):
287 let &l:omnifunc = 'BazBoz'
288 let &l:completeopt = 'menu'
290 call ale#completion#Done()
292 AssertEqual 'BazBoz', &l:omnifunc
293 AssertEqual 'menu', &l:completeopt
295 Execute(The completion request_id should be reset when queuing again):
296 let b:ale_completion_info = {'request_id': 123}
298 let g:ale_completion_delay = 0
299 call ale#completion#Queue()
302 AssertEqual 0, b:ale_completion_info.request_id
304 Execute(b:ale_completion_info should be set up correctly when requesting completions automatically):
305 let b:ale_completion_result = []
306 call setpos('.', [bufnr(''), 3, 14, 0])
307 call ale#completion#GetCompletions('ale-automatic')
317 \ 'source': 'ale-automatic',
319 \ b:ale_completion_info
320 Assert !exists('b:ale_completion_result')
322 Execute(b:ale_completion_info should be set up correctly when requesting completions manually):
323 let b:ale_completion_result = []
324 call setpos('.', [bufnr(''), 3, 14, 0])
335 \ 'source': 'ale-manual',
337 \ b:ale_completion_info
338 Assert !exists('b:ale_completion_result')
340 Execute(b:ale_completion_info should be set up correctly for other sources):
341 let b:ale_completion_result = []
342 call setpos('.', [bufnr(''), 3, 14, 0])
343 call ale#completion#GetCompletions('ale-callback')
353 \ 'source': 'ale-callback',
355 \ b:ale_completion_info
356 Assert !exists('b:ale_completion_result')
358 Execute(b:ale_completion_info should be set up correctly when requesting completions via callback):
359 let b:ale_completion_result = []
360 call setpos('.', [bufnr(''), 3, 14, 0])
362 function! CompleteCallback() abort
367 call ale#completion#GetCompletions('ale-callback', {'callback': funcref('CompleteCallback')})
377 \ 'source': 'ale-callback',
379 \ b:ale_completion_info
380 Assert !exists('b:ale_completion_result')
382 Execute(The correct keybinds should be configured):
384 silent map <Plug>(ale_show_completion_menu)
389 \ 'n <Plug>(ale_show_completion_menu) * :call ale#completion#RestoreCompletionOptions()<CR>',
390 \ 'o <Plug>(ale_show_completion_menu) * <Nop>',
391 \ 'v <Plug>(ale_show_completion_menu) * <Nop>',
393 \ sort(split(g:output, "\n"))
395 Execute(Running the normal mode <Plug> keybind should reset the settings):
396 let b:ale_old_omnifunc = 'FooBar'
397 let b:ale_old_completeopt = 'menu'
399 " We can't run the keybind, but we can call the function.
400 call ale#completion#RestoreCompletionOptions()
402 AssertEqual 'FooBar', &l:omnifunc
403 AssertEqual 'menu', &l:completeopt
404 Assert !has_key(b:, 'ale_old_omnifunc')
405 Assert !has_key(b:, 'ale_old_completeopt')
407 Execute(HandleUserData should call ale#code_action#HandleCodeAction):
408 let b:ale_completion_info = {'source': 'ale-manual'}
409 call MockHandleCodeAction()
411 call ale#completion#HandleUserData({})
412 AssertEqual g:handle_code_action_called, 0
414 call ale#completion#HandleUserData({
417 AssertEqual g:handle_code_action_called, 0
419 call ale#completion#HandleUserData({
420 \ 'user_data': json_encode({}),
422 AssertEqual g:handle_code_action_called, 0
424 call ale#completion#HandleUserData({
425 \ 'user_data': json_encode({
426 \ '_ale_completion_item': 1,
427 \ 'code_actions': [],
430 AssertEqual g:handle_code_action_called, 0
432 call ale#completion#HandleUserData({
433 \ 'user_data': json_encode({
434 \ '_ale_completion_item': 1,
436 \ {'description': '', 'changes': []},
440 AssertEqual g:handle_code_action_called, 1
442 let b:ale_completion_info = {'source': 'ale-automatic'}
443 call ale#completion#HandleUserData({
444 \ 'user_data': json_encode({
445 \ '_ale_completion_item': 1,
447 \ {'description': '', 'changes': []},
451 AssertEqual g:handle_code_action_called, 2
453 let b:ale_completion_info = {'source': 'ale-callback'}
454 call ale#completion#HandleUserData({
455 \ 'user_data': json_encode({
456 \ '_ale_completion_item': 1,
458 \ {'description': '', 'changes': []},
462 AssertEqual g:handle_code_action_called, 3
464 let b:ale_completion_info = {'source': 'ale-omnifunc'}
465 call ale#completion#HandleUserData({
466 \ 'user_data': json_encode({
467 \ '_ale_completion_item': 1,
469 \ {'description': '', 'changes': []},
473 AssertEqual g:handle_code_action_called, 4
475 Execute(ale#code_action#HandleCodeAction should not be called when when source is not ALE):
476 call MockHandleCodeAction()
477 let b:ale_completion_info = {'source': 'syntastic'}
478 call ale#completion#HandleUserData({
479 \ 'user_data': json_encode({
480 \ '_ale_completion_item': 1,
482 \ {'description': '', 'changes': []},
486 AssertEqual g:handle_code_action_called, 0