]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/asyncomplete-lsp/plugin/asyncomplete-lsp.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

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.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge commit 'd49e95aa7ba744f0a7f544aca43afdb6aab41f24' as '.vim/bundle/asyncomplete...
[etc/vim.git] / .vim / bundle / asyncomplete-lsp / plugin / asyncomplete-lsp.vim
1 if exists('g:asyncomplete_lsp_loaded')
2     finish
3 endif
4 let g:asyncomplete_lsp_loaded = 1
5
6 let s:servers = {} " { server_name: 1 }
7
8 augroup asyncomplete_lsp
9     au!
10     au User lsp_server_init call s:server_initialized()
11     au User lsp_server_exit call s:server_exited()
12 augroup END
13
14 function! s:server_initialized() abort
15     let l:server_names = lsp#get_server_names()
16     for l:server_name in l:server_names
17         if has_key(s:servers, l:server_name)
18             continue
19         endif
20         let l:init_capabilities = lsp#get_server_capabilities(l:server_name)
21         if !has_key(l:init_capabilities, 'completionProvider')
22             continue
23         endif
24
25         let l:server = lsp#get_server_info(l:server_name)
26         let l:name = s:generate_asyncomplete_name(l:server_name)
27         let l:source_opt = {
28             \ 'name': l:name,
29             \ 'completor': function('s:completor', [l:server]),
30             \ }
31         if type(l:init_capabilities['completionProvider']) == type({}) && has_key(l:init_capabilities['completionProvider'], 'triggerCharacters')
32             let l:source_opt['triggers'] = { '*': l:init_capabilities['completionProvider']['triggerCharacters'] }
33         endif
34         if has_key(l:server, 'allowlist')
35             let l:source_opt['allowlist'] = l:server['allowlist']
36         elseif has_key(l:server, 'whitelist')
37             let l:source_opt['allowlist'] = l:server['whitelist']
38         endif
39         if has_key(l:server, 'blocklist')
40             let l:source_opt['blocklist'] = l:server['blocklist']
41         elseif has_key(l:server, 'blacklist')
42             let l:source_opt['blocklist'] = l:server['blacklist']
43         endif
44         if has_key(l:server, 'priority')
45             let l:source_opt['priority'] = l:server['priority']
46         endif
47         call asyncomplete#register_source(l:source_opt)
48         let s:servers[l:server_name] = 1
49     endfor
50 endfunction
51
52 function! s:server_exited() abort
53     let l:server_names = lsp#get_server_names()
54     for l:server_name in l:server_names
55         if !has_key(s:servers, l:server_name)
56             continue
57         endif
58         let l:name = s:generate_asyncomplete_name(l:server_name)
59         if s:servers[l:server_name]
60             call asyncomplete#unregister_source(l:name)
61         endif
62         unlet s:servers[l:server_name]
63     endfor
64 endfunction
65
66 function! s:generate_asyncomplete_name(server_name) abort
67     return 'asyncomplete_lsp_' . a:server_name
68 endfunction
69
70 function! s:completor(server, opt, ctx) abort
71     let l:position = lsp#get_position()
72     call lsp#send_request(a:server['name'], {
73         \ 'method': 'textDocument/completion',
74         \ 'params': {
75         \   'textDocument': lsp#get_text_document_identifier(),
76         \   'position': l:position,
77         \ },
78         \ 'on_notification': function('s:handle_completion', [a:server, l:position, a:opt, a:ctx]),
79         \ })
80 endfunction
81
82 function! s:handle_completion(server, position, opt, ctx, data) abort
83     if lsp#client#is_error(a:data) || !has_key(a:data, 'response') || !has_key(a:data['response'], 'result')
84         return
85     endif
86
87     let l:options = {
88         \ 'server': a:server,
89         \ 'position': a:position,
90         \ 'response': a:data['response'],
91         \ }
92
93     let l:completion_result = lsp#omni#get_vim_completion_items(l:options)
94
95     let l:col = a:ctx['col']
96     let l:typed = a:ctx['typed']
97     let l:kw = matchstr(l:typed, get(b:, 'asyncomplete_refresh_pattern', '\k\+$'))
98     let l:kwlen = len(l:kw)
99     let l:startcol = l:col - l:kwlen
100     let l:startcol = min([l:startcol, get(l:completion_result, 'startcol', l:startcol)])
101
102     call asyncomplete#complete(a:opt['name'], a:ctx, l:startcol, l:completion_result['items'], l:completion_result['incomplete'])
103 endfunction