]> git.madduck.net Git - etc/vim.git/blob - autoload/ale/symbol.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:

Squashed '.vim/bundle/ale/' content from commit 22185c4c
[etc/vim.git] / autoload / ale / symbol.vim
1 let s:symbol_map = {}
2
3 " Used to get the symbol map in tests.
4 function! ale#symbol#GetMap() abort
5     return deepcopy(s:symbol_map)
6 endfunction
7
8 " Used to set the symbol map in tests.
9 function! ale#symbol#SetMap(map) abort
10     let s:symbol_map = a:map
11 endfunction
12
13 function! ale#symbol#ClearLSPData() abort
14     let s:symbol_map = {}
15 endfunction
16
17 function! ale#symbol#HandleLSPResponse(conn_id, response) abort
18     if has_key(a:response, 'id')
19     \&& has_key(s:symbol_map, a:response.id)
20         let l:options = remove(s:symbol_map, a:response.id)
21
22         let l:result = get(a:response, 'result', v:null)
23         let l:item_list = []
24
25         if type(l:result) is v:t_list
26             " Each item looks like this:
27             " {
28             "   'name': 'foo',
29             "   'kind': 123,
30             "   'deprecated': v:false,
31             "   'location': {
32             "     'uri': 'file://...',
33             "     'range': {
34             "       'start': {'line': 0, 'character': 0},
35             "       'end': {'line': 0, 'character': 0},
36             "     },
37             "   },
38             "   'containerName': 'SomeContainer',
39             " }
40             for l:response_item in l:result
41                 let l:location = l:response_item.location
42
43                 call add(l:item_list, {
44                 \ 'filename': ale#util#ToResource(l:location.uri),
45                 \ 'line': l:location.range.start.line + 1,
46                 \ 'column': l:location.range.start.character + 1,
47                 \ 'match': l:response_item.name,
48                 \})
49             endfor
50         endif
51
52         if empty(l:item_list)
53             call ale#util#Execute('echom ''No symbols found.''')
54         else
55             call ale#preview#ShowSelection(l:item_list, l:options)
56         endif
57     endif
58 endfunction
59
60 function! s:OnReady(query, options, linter, lsp_details) abort
61     let l:id = a:lsp_details.connection_id
62
63     if !ale#lsp#HasCapability(l:id, 'symbol_search')
64         return
65     endif
66
67     let l:buffer = a:lsp_details.buffer
68
69     " If we already made a request, stop here.
70     if getbufvar(l:buffer, 'ale_symbol_request_made', 0)
71         return
72     endif
73
74     let l:Callback = function('ale#symbol#HandleLSPResponse')
75     call ale#lsp#RegisterCallback(l:id, l:Callback)
76
77     let l:message = ale#lsp#message#Symbol(a:query)
78     let l:request_id = ale#lsp#Send(l:id, l:message)
79
80     call setbufvar(l:buffer, 'ale_symbol_request_made', 1)
81     let s:symbol_map[l:request_id] = {
82     \   'buffer': l:buffer,
83     \   'use_relative_paths': has_key(a:options, 'use_relative_paths') ? a:options.use_relative_paths : 0
84     \}
85 endfunction
86
87 function! ale#symbol#Search(args) abort
88     let [l:opts, l:query] = ale#args#Parse(['relative'], a:args)
89
90     if empty(l:query)
91         throw 'A non-empty string must be provided!'
92     endif
93
94     let l:buffer = bufnr('')
95     let l:options = {}
96
97     if has_key(l:opts, 'relative')
98         let l:options.use_relative_paths = 1
99     endif
100
101     " Set a flag so we only make one request.
102     call setbufvar(l:buffer, 'ale_symbol_request_made', 0)
103     let l:Callback = function('s:OnReady', [l:query, l:options])
104
105     for l:linter in ale#lsp_linter#GetEnabled(l:buffer)
106         if l:linter.lsp isnot# 'tsserver'
107             call ale#lsp_linter#StartLSP(l:buffer, l:linter, l:Callback)
108         endif
109     endfor
110 endfunction