]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/vim-lsp/autoload/lsp/internal/diagnostics/signs.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 '56df844d3c39ec494dacc69eae34272b27db185a' as '.vim/bundle/asyncomplete'
[etc/vim.git] / .vim / bundle / vim-lsp / autoload / lsp / internal / diagnostics / signs.vim
1 " internal state for whether it is enabled or not to avoid multiple subscriptions
2 let s:enabled = 0
3 let s:sign_group = 'vim_lsp'
4
5 let s:severity_sign_names_mapping = {
6     \ 1: 'LspError',
7     \ 2: 'LspWarning',
8     \ 3: 'LspInformation',
9     \ 4: 'LspHint',
10     \ }
11
12 if !hlexists('LspErrorText')
13     highlight link LspErrorText Error
14 endif
15
16 if !hlexists('LspWarningText')
17     highlight link LspWarningText Todo
18 endif
19
20 if !hlexists('LspInformationText')
21     highlight link LspInformationText Normal
22 endif
23
24 if !hlexists('LspHintText')
25     highlight link LspHintText Normal
26 endif
27
28 " imports
29 let s:Buffer = vital#lsp#import('VS.Vim.Buffer')
30
31 function! lsp#internal#diagnostics#signs#_enable() abort
32     " don't even bother registering if the feature is disabled
33     if !lsp#utils#_has_signs() | return | endif
34     if !g:lsp_diagnostics_signs_enabled | return | endif 
35
36     if s:enabled | return | endif
37     let s:enabled = 1
38
39     call s:define_sign('LspError', 'E>', g:lsp_diagnostics_signs_error)
40     call s:define_sign('LspWarning', 'W>', g:lsp_diagnostics_signs_warning)
41     call s:define_sign('LspInformation', 'I>', g:lsp_diagnostics_signs_information)
42     call s:define_sign('LspHint', 'H>', g:lsp_diagnostics_signs_hint)
43
44     let s:Dispose = lsp#callbag#pipe(
45         \ lsp#callbag#merge(
46         \   lsp#callbag#pipe(
47         \       lsp#stream(),
48         \       lsp#callbag#filter({x->has_key(x, 'server') && has_key(x, 'response')
49         \       && has_key(x['response'], 'method') && x['response']['method'] ==# '$/vimlsp/lsp_diagnostics_updated'
50         \       && !lsp#client#is_error(x['response'])}),
51         \       lsp#callbag#map({x->x['response']['params']}),
52         \   ),
53         \   lsp#callbag#pipe(
54         \       lsp#callbag#fromEvent(['InsertEnter', 'InsertLeave']),
55         \       lsp#callbag#filter({_->!g:lsp_diagnostics_signs_insert_mode_enabled}),
56         \       lsp#callbag#map({_->{ 'uri': lsp#utils#get_buffer_uri() }}),
57         \   ),
58         \ ),
59         \ lsp#callbag#filter({_->g:lsp_diagnostics_signs_enabled}),
60         \ lsp#callbag#debounceTime(g:lsp_diagnostics_signs_delay),
61         \ lsp#callbag#tap({x->s:clear_signs(x)}),
62         \ lsp#callbag#tap({x->s:set_signs(x)}),
63         \ lsp#callbag#subscribe(),
64         \ )
65 endfunction
66
67 function! lsp#internal#diagnostics#signs#_disable() abort
68     if !s:enabled | return | endif
69     if exists('s:Dispose')
70         call s:Dispose()
71         unlet s:Dispose
72     endif
73     call s:clear_all_signs()
74     call s:undefine_signs()
75     let s:enabled = 0
76 endfunction
77
78 " Set default sign text to handle case when user provides empty dict
79 function! s:define_sign(sign_name, sign_default_text, sign_options) abort
80     let l:options = {
81         \ 'text': get(a:sign_options, 'text', a:sign_default_text),
82         \ 'texthl': a:sign_name . 'Text',
83         \ 'linehl': a:sign_name . 'Line',
84         \ }
85     let l:sign_icon = get(a:sign_options, 'icon', '')
86     if !empty(l:sign_icon)
87         let l:options['icon'] = l:sign_icon
88     endif
89     call sign_define(a:sign_name, l:options)
90 endfunction
91
92 function! s:undefine_signs() abort
93     call sign_undefine('LspError')
94     call sign_undefine('LspWarning')
95     call sign_undefine('LspInformation')
96     call sign_undefine('LspHint')
97 endfunction
98
99 function! s:clear_all_signs() abort
100     call sign_unplace(s:sign_group)
101 endfunction
102
103 " params => {
104 "   server: ''  " optional
105 "   uri: ''     " optional
106 " }
107 function! s:clear_signs(params) abort
108     " TODO: optimize by looking at params
109     call s:clear_all_signs()
110 endfunction
111
112 " params => {
113 "   server: ''  " optional
114 "   uri: ''     " optional
115 " }
116 function! s:set_signs(params) abort
117     " TODO: optimize by looking at params
118     if !g:lsp_diagnostics_signs_insert_mode_enabled
119         if mode()[0] ==# 'i' | return | endif
120     endif
121
122     for l:bufnr in range(1, bufnr('$'))
123         if lsp#internal#diagnostics#state#_is_enabled_for_buffer(l:bufnr) && bufexists(l:bufnr) && bufloaded(l:bufnr)
124             let l:uri = lsp#utils#get_buffer_uri(l:bufnr)
125             for [l:server, l:diagnostics_response] in items(lsp#internal#diagnostics#state#_get_all_diagnostics_grouped_by_server_for_uri(l:uri))
126                 call s:place_signs(l:server, l:diagnostics_response, l:bufnr)
127             endfor
128         endif
129     endfor
130 endfunction
131
132 function! s:place_signs(server, diagnostics_response, bufnr) abort
133     let l:linecount = s:Buffer.get_line_count(a:bufnr)
134     for l:item in lsp#utils#iteratable(a:diagnostics_response['params']['diagnostics'])
135         let l:line = lsp#utils#position#lsp_line_to_vim(a:bufnr, l:item['range']['start'])
136
137         " Some language servers report an unexpected EOF one line past the end
138         if  l:line == l:linecount + 1
139             let l:line = l:line - 1
140         endif
141
142         if has_key(l:item, 'severity') && !empty(l:item['severity'])
143             let l:sign_name = get(s:severity_sign_names_mapping, l:item['severity'], 'LspError')
144             let l:sign_priority = get(g:lsp_diagnostics_signs_priority_map, l:sign_name, g:lsp_diagnostics_signs_priority)
145             let l:sign_priority = get(g:lsp_diagnostics_signs_priority_map,
146                 \ a:server . '_' . l:sign_name, l:sign_priority)
147             " pass 0 and let vim generate sign id
148             let l:sign_id = sign_place(0, s:sign_group, l:sign_name, a:bufnr,
149                 \{ 'lnum': l:line, 'priority': l:sign_priority })
150         endif
151     endfor
152 endfunction