@@ -23,6 +23,26 @@ function! ale#lsp_linter#SetLSPLinterMap(replacement_map) abort
2323 let s: lsp_linter_map = a: replacement_map
2424endfunction
2525
26+ " A map for tracking URIs for diagnostic request IDs
27+ if ! has_key (s: , ' diagnostic_uri_map' )
28+ let s: diagnostic_uri_map = {}
29+ endif
30+
31+ " For internal use only.
32+ function ! ale#lsp_linter#ClearDiagnosticURIMap () abort
33+ let s: diagnostic_uri_map = {}
34+ endfunction
35+
36+ " For internal use only.
37+ function ! ale#lsp_linter#GetDiagnosticURIMap () abort
38+ return s: diagnostic_uri_map
39+ endfunction
40+
41+ " Just for tests.
42+ function ! ale#lsp_linter#SetDiagnosticURIMap (replacement_map) abort
43+ let s: diagnostic_uri_map = a: replacement_map
44+ endfunction
45+
2646" Get all enabled LSP linters.
2747" This list still includes linters ignored with `ale_linters_ignore`.
2848"
@@ -77,14 +97,17 @@ function! s:ShouldIgnoreDiagnostics(buffer, linter) abort
7797 return 0
7898endfunction
7999
80- function ! s: HandleLSPDiagnostics (conn_id, response) abort
100+ " Handle LSP diagnostics for a given URI.
101+ " The special value 'unchanged' can be used for diagnostics to indicate
102+ " that diagnostics haven't changed since we last checked.
103+ function ! s: HandleLSPDiagnostics (conn_id, uri, diagnostics) abort
81104 let l: linter = get (s: lsp_linter_map , a: conn_id )
82105
83106 if empty (l: linter )
84107 return
85108 endif
86109
87- let l: filename = ale#util#ToResource (a: response .params. uri)
110+ let l: filename = ale#util#ToResource (a: uri )
88111 let l: escaped_name = escape (
89112 \ fnameescape (l: filename ),
90113 \ has (' win32' ) ? ' ^' : ' ^,}]'
@@ -100,9 +123,12 @@ function! s:HandleLSPDiagnostics(conn_id, response) abort
100123 return
101124 endif
102125
103- let l: loclist = ale#lsp#response#ReadDiagnostics (a: response )
104-
105- call ale#engine#HandleLoclist (l: linter .name, l: buffer , l: loclist , 0 )
126+ if a: diagnostics is # ' unchanged'
127+ call ale#engine#MarkLinterInactive (l: info , l: linter )
128+ else
129+ let l: loclist = ale#lsp#response#ReadDiagnostics (a: diagnostics )
130+ call ale#engine#HandleLoclist (l: linter .name, l: buffer , l: loclist , 0 )
131+ endif
106132endfunction
107133
108134function ! s: HandleTSServerDiagnostics (response, error_type) abort
@@ -204,7 +230,17 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
204230
205231 call s: HandleLSPErrorMessage (l: linter , a: response )
206232 elseif l: method is # ' textDocument/publishDiagnostics'
207- call s: HandleLSPDiagnostics (a: conn_id , a: response )
233+ let l: uri = a: response .params.uri
234+ let l: diagnostics = a: response .params.diagnostics
235+
236+ call s: HandleLSPDiagnostics (a: conn_id , l: uri , l: diagnostics )
237+ elseif has_key (s: diagnostic_uri_map , get (a: response , ' id' ))
238+ let l: uri = remove (s: diagnostic_uri_map , a: response .id)
239+ let l: diagnostics = a: response .result.kind is # ' unchanged'
240+ \ ? ' unchanged'
241+ \ : a: response .result.items
242+
243+ call s: HandleLSPDiagnostics (a: conn_id , l: uri , l: diagnostics )
208244 elseif l: method is # ' window/showMessage'
209245 call ale#lsp_window#HandleShowMessage (
210246 \ s: lsp_linter_map [a: conn_id ].name,
@@ -530,6 +566,23 @@ function! s:CheckWithLSP(linter, details) abort
530566 let l: save_message = ale#lsp#message#DidSave (l: buffer , l: include_text )
531567 let l: notified = ale#lsp#Send (l: id , l: save_message ) != 0
532568 endif
569+
570+ let l: diagnostic_request_id = 0
571+
572+ " If the document is updated and we can pull diagnostics, try to.
573+ if ale#lsp#HasCapability (l: id , ' pull_model' )
574+ let l: diagnostic_message = ale#lsp#message#Diagnostic (l: buffer )
575+
576+ let l: diagnostic_request_id = ale#lsp#Send (l: id , l: diagnostic_message )
577+ endif
578+
579+ " If we are going to pull diagnostics, then mark the linter as active,
580+ " and remember the URI we sent the request for.
581+ if l: diagnostic_request_id
582+ call ale#engine#MarkLinterActive (l: info , a: linter )
583+ let s: diagnostic_uri_map [l: diagnostic_request_id ] =
584+ \ l: diagnostic_message [2 ].textDocument.uri
585+ endif
533586 endif
534587endfunction
535588
0 commit comments