Skip to content

Commit c1be742

Browse files
tsufekiprabirshrestha
authored andcommitted
Add diagnostics highlighting via +textprop. (#375)
* Add diagnostics highlighting via +textprop. * Use textprop 'combine' option, added in 8.1.1276 * Add textprop docs. * Enable textprop highlights by default.
1 parent feba6d6 commit c1be742

File tree

6 files changed

+192
-2
lines changed

6 files changed

+192
-2
lines changed

README.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,20 @@ highlight link LspErrorText GruvboxRedSign " requires gruvbox
106106
highlight clear LspWarningLine
107107
```
108108

109-
### Virtual text
109+
#### Highlights
110+
111+
Highlighting diagnostics requires either NeoVim 0.3+ or Vim with patch 8.1.0579.
112+
They are enabled by default when supported, but can be turned off respectively by
113+
114+
```viml
115+
let g:lsp_highlights_enabled = 0
116+
let g:lsp_textprop_enabled = 0
117+
```
118+
119+
Can be customized by setting or linking `LspErrorHighlight`, `LspWarningHighlight`,
120+
`LspInformationHighlight` and `LspHintHighlight` highlight groups.
121+
122+
#### Virtual text
110123

111124
In NeoVim 0.3 or newer you can use virtual text feature (enabled by default).
112125
You can disable it by adding

autoload/lsp.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ function! lsp#enable() abort
5252
if g:lsp_signs_enabled | call lsp#ui#vim#signs#enable() | endif
5353
if g:lsp_virtual_text_enabled | call lsp#ui#vim#virtual#enable() | endif
5454
if g:lsp_highlights_enabled | call lsp#ui#vim#highlights#enable() | endif
55+
if g:lsp_textprop_enabled | call lsp#ui#vim#diagnostics#textprop#enable() | endif
5556
endif
5657
call s:register_events()
5758
endfunction

autoload/lsp/ui/vim/diagnostics.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ function! lsp#ui#vim#diagnostics#handle_text_document_publish_diagnostics(server
1616

1717
call lsp#ui#vim#virtual#set(a:server_name, a:data)
1818
call lsp#ui#vim#highlights#set(a:server_name, a:data)
19+
call lsp#ui#vim#diagnostics#textprop#set(a:server_name, a:data)
1920
call lsp#ui#vim#signs#set(a:server_name, a:data)
2021
endfunction
2122

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
let s:supports_hl = exists('*prop_add')
2+
let s:enabled = 0
3+
let s:prop_type_prefix = 'vim_lsp_hl_'
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('LspErrorHighlight')
13+
highlight link LspErrorHighlight Error
14+
endif
15+
16+
if !hlexists('LspWarningHighlight')
17+
highlight link LspWarningHighlight Todo
18+
endif
19+
20+
if !hlexists('LspInformationHighlight')
21+
highlight link LspInformationHighlight Normal
22+
endif
23+
24+
if !hlexists('LspHintHighlight')
25+
highlight link LspHintHighlight Normal
26+
endif
27+
28+
function! lsp#ui#vim#diagnostics#textprop#enable() abort
29+
if !s:supports_hl
30+
call lsp#log('vim-lsp highlighting requires vim with +textprop')
31+
return
32+
endif
33+
if !s:enabled
34+
let s:enabled = 1
35+
call lsp#log('vim-lsp highlighting enabled (textprop)')
36+
endif
37+
endfunction
38+
39+
function! lsp#ui#vim#diagnostics#textprop#disable() abort
40+
if s:enabled
41+
call s:clear_all_highlights()
42+
let s:enabled = 0
43+
call lsp#log('vim-lsp highlighting disabled')
44+
endif
45+
endfunction
46+
47+
function! lsp#ui#vim#diagnostics#textprop#set(server_name, data) abort
48+
if !s:enabled | return | endif
49+
50+
if lsp#client#is_error(a:data['response'])
51+
return
52+
endif
53+
54+
let l:uri = a:data['response']['params']['uri']
55+
let l:diagnostics = a:data['response']['params']['diagnostics']
56+
let l:path = lsp#utils#uri_to_path(l:uri)
57+
58+
call s:clear_highlights(a:server_name, l:path)
59+
call s:place_highlights(a:server_name, l:path, l:diagnostics)
60+
endfunction
61+
62+
function! s:get_prop_type(server_name, severity) abort
63+
let l:severity = has_key(s:severity_sign_names_mapping, a:severity) ? a:severity : 0
64+
let l:name = s:prop_type_prefix . l:severity . '_' . a:server_name
65+
if empty(prop_type_get(l:name))
66+
call prop_type_add(l:name, {
67+
\ 'highlight': s:severity_sign_names_mapping[l:severity] . 'Highlight',
68+
\ 'combine': v:true,
69+
\ })
70+
endif
71+
return l:name
72+
endfunction
73+
74+
function! s:clear_all_highlights() abort
75+
for l:prop_type in prop_type_list()
76+
if l:prop_type !~# '^' . s:prop_type_prefix
77+
continue
78+
endif
79+
80+
for l:bufnr in range(1, bufnr('$'))
81+
if bufexists(l:bufnr)
82+
call prop_remove({
83+
\ 'type': l:prop_type,
84+
\ 'bufnr': l:bufnr,
85+
\ 'all': v:true,
86+
\ })
87+
endif
88+
endfor
89+
90+
call prop_type_delete(l:prop_type)
91+
endfor
92+
endfunction
93+
94+
function! s:clear_highlights(server_name, path) abort
95+
if !s:enabled | return | endif
96+
97+
let l:bufnr = bufnr(a:path)
98+
for l:severity in keys(s:severity_sign_names_mapping)
99+
let l:prop_type = s:get_prop_type(a:server_name, l:severity)
100+
call prop_remove({
101+
\ 'type': l:prop_type,
102+
\ 'bufnr': l:bufnr,
103+
\ 'all': v:true,
104+
\ })
105+
endfor
106+
endfunction
107+
108+
function! s:place_highlights(server_name, path, diagnostics) abort
109+
if !s:enabled | return | endif
110+
111+
let l:bufnr = bufnr(a:path)
112+
if !empty(a:diagnostics) && l:bufnr >= 0
113+
for l:item in a:diagnostics
114+
let l:start_line = l:item['range']['start']['line'] + 1
115+
let l:start_col = l:item['range']['start']['character'] + 1
116+
let l:end_line = l:item['range']['end']['line'] + 1
117+
let l:end_col = l:item['range']['end']['character'] + 1
118+
119+
let l:prop_type = s:get_prop_type(a:server_name, l:item['severity'])
120+
call prop_add(l:start_line, l:start_col, {
121+
\ 'end_lnum': l:end_line,
122+
\ 'end_col': l:end_col,
123+
\ 'bufnr': l:bufnr,
124+
\ 'type': l:prop_type,
125+
\ })
126+
endfor
127+
endif
128+
endfunction

doc/vim-lsp.txt

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ CONTENTS *vim-lsp-contents*
1515
g:lsp_preview_keep_focus |g:lsp_preview_keep_focus|
1616
g:lsp_insert_text_enabled |g:lsp_insert_text_enabled|
1717
g:lsp_text_edit_enabled |g:lsp_text_edit_enabled|
18-
g:lsp_signs_enabled |g:lsp_signs_enabled|
1918
g:lsp_diagnostics_echo_cursor |g:lsp_diagnostics_echo_cursor|
19+
g:lsp_signs_enabled |g:lsp_signs_enabled|
20+
g:lsp_virtual_text_enabled |g:lsp_virtual_text_enabled|
21+
g:lsp_highlights_enabled |g:lsp_highlights_enabled|
22+
g:lsp_textprop_enabled |g:lsp_textprop_enabled|
2023
g:lsp_use_event_queue |g:lsp_use_event_queue|
2124
g:lsp_highlight_references_enabled |g:lsp_highlight_references_enabled|
2225
Functions |vim-lsp-functions|
@@ -203,6 +206,49 @@ g:lsp_virtual_text_enabled *g:lsp_virtual_text_enable
203206
let g:lsp_virtual_text_enabled = 0
204207
<
205208

209+
g:lsp_highlights_enabled *g:lsp_highlights_enabled*
210+
Type: |Number|
211+
Default: `1` for neovim 0.3+
212+
213+
Enables highlighting of diagnostics. Requires NeoVim with version 0.3 or
214+
newer.
215+
216+
Example:
217+
>
218+
let g:lsp_highlights_enabled = 1
219+
let g:lsp_highlights_enabled = 0
220+
<
221+
222+
To change the style of the highlighting, you can set or link
223+
`LspErrorHighlight`, `LspWarningHighlight`, `LspInformationHighlight` and
224+
`LspHintHighlight` highlight groups.
225+
226+
Example:
227+
>
228+
highlight link LspErrorHighlight Error
229+
<
230+
231+
g:lsp_textprop_enabled *g:lsp_textprop_enabled*
232+
Type: |Number|
233+
Default: `1` for vim with +textprop
234+
235+
Enables highlighting of diagnostics. Requires vim with +textprop
236+
(patch 8.1.0579).
237+
238+
Example:
239+
>
240+
let g:lsp_textprop_enabled = 1
241+
let g:lsp_textprop_enabled = 0
242+
<
243+
244+
To change the style of the highlighting, you can set or link
245+
`LspErrorHighlight`, `LspWarningHighlight`, `LspInformationHighlight` and
246+
`LspHintHighlight` highlight groups.
247+
248+
Example:
249+
>
250+
highlight LspErrorHighlight term=underline cterm=underline gui=underline
251+
<
206252

207253
g:lsp_use_event_queue *g:lsp_use_event_queue*
208254
Type: |Number|

plugin/lsp.vim

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ let g:lsp_debug_servers = get(g:, 'lsp_debug_servers', [])
1111
let g:lsp_signs_enabled = get(g:, 'lsp_signs_enabled', has('patch-8.1.0772') && exists('*sign_define'))
1212
let g:lsp_virtual_text_enabled = get(g:, 'lsp_virtual_text_enabled', exists('*nvim_buf_set_virtual_text'))
1313
let g:lsp_highlights_enabled = get(g:, 'lsp_highlights_enabled', exists('*nvim_buf_add_highlight'))
14+
let g:lsp_textprop_enabled = get(g:, 'lsp_textprop_enabled', exists('*prop_add') && !g:lsp_highlights_enabled)
1415
let g:lsp_signs_error = get(g:, 'lsp_signs_error', {})
1516
let g:lsp_signs_warning = get(g:, 'lsp_signs_warning', {})
1617
let g:lsp_signs_information = get(g:, 'lsp_signs_information', {})

0 commit comments

Comments
 (0)