@@ -330,7 +330,7 @@ impl State {
330
330
Ok ( ( ) )
331
331
}
332
332
333
- fn display_diagnostics ( & mut self , filename : & str , diagnostics : & [ Diagnostic ] ) -> Result < ( ) > {
333
+ fn process_diagnostics ( & mut self , filename : & str , diagnostics : & [ Diagnostic ] ) -> Result < ( ) > {
334
334
// Line diagnostics.
335
335
self . update ( |state| {
336
336
state
@@ -360,38 +360,36 @@ impl State {
360
360
} ) ?;
361
361
362
362
// Signs.
363
- if self . text_documents . contains_key ( filename ) {
364
- let text = self . text_documents
363
+ {
364
+ let lines : Option < Vec < _ > > = self . text_documents
365
365
. get ( filename)
366
- . ok_or_else ( || format_err ! ( "TextDocumentItem not found! filename: {}" , filename) ) ?
367
- . text
368
- . clone ( ) ;
369
- let lines: Vec < & str > = text. lines ( ) . collect ( ) ;
370
- let mut signs: Vec < _ > = diagnostics
371
- . iter ( )
372
- . map ( |dn| {
373
- let line = dn. range . start . line ;
374
- let text = lines
375
- . get ( line as usize )
376
- . map ( |l| l. to_string ( ) )
377
- . unwrap_or_default ( ) ;
378
- Some ( Sign :: new ( line + 1 , text, dn. severity ) )
379
- } )
380
- . collect ( ) ;
366
+ . map ( |d| d. text . lines ( ) . collect ( ) ) ;
367
+ let mut signs = if let Some ( lines) = lines {
368
+ diagnostics
369
+ . iter ( )
370
+ . map ( |dn| {
371
+ let line = dn. range . start . line ;
372
+ let text = lines
373
+ . get ( line as usize )
374
+ . map ( |l| l. to_string ( ) )
375
+ . unwrap_or_default ( ) ;
376
+
377
+ Sign :: new ( line + 1 , text, dn. severity )
378
+ } )
379
+ . collect ( )
380
+ } else {
381
+ vec ! [ ]
382
+ } ;
383
+
384
+ // There might be multiple diagnostics for one line. Show only highest severity.
381
385
signs. sort_unstable ( ) ;
382
- signs. dedup_by_key ( |s| s. line ) ;
386
+ signs. dedup ( ) ;
387
+
383
388
if let Some ( diagnosticSignsMax) = self . diagnosticsSignsMax {
384
389
signs. truncate ( diagnosticSignsMax as usize ) ;
385
390
}
386
391
387
- let cmd = self . update ( |state| {
388
- let signs_prev = state. signs . remove ( filename) . unwrap_or_default ( ) ;
389
- let ( signs_next, cmd) = get_command_update_signs ( & signs_prev, & signs, filename) ;
390
- state. signs . insert ( filename. to_string ( ) , signs_next) ;
391
- Ok ( cmd)
392
- } ) ?;
393
- info ! ( "Command to update signs: {}" , cmd) ;
394
- self . command ( & cmd) ?;
392
+ self . signs . insert ( filename. to_owned ( ) , signs) ;
395
393
}
396
394
397
395
let diagnosticsDisplay = self . get ( |state| Ok ( state. diagnosticsDisplay . clone ( ) ) ) ?;
@@ -708,8 +706,9 @@ impl State {
708
706
}
709
707
}
710
708
for f in filenames {
711
- self . display_diagnostics ( & f, & [ ] ) ?;
709
+ self . process_diagnostics ( & f, & [ ] ) ?;
712
710
}
711
+ self . languageClient_handleCursorMoved ( & json ! ( { } ) . to_params ( ) ?) ?;
713
712
714
713
self . diagnostics . retain ( |f, _| !f. starts_with ( & root) ) ;
715
714
self . update_quickfixlist ( ) ?;
@@ -1818,7 +1817,8 @@ impl State {
1818
1817
if filename != current_filename. canonicalize ( ) {
1819
1818
return Ok ( ( ) ) ;
1820
1819
}
1821
- self . display_diagnostics ( & current_filename, & diagnostics) ?;
1820
+ self . process_diagnostics ( & current_filename, & diagnostics) ?;
1821
+ self . languageClient_handleCursorMoved ( & json ! ( { } ) . to_params ( ) ?) ?;
1822
1822
self . call :: < _ , u8 > ( None , "s:ExecuteAutocmd" , "LanguageClientDiagnosticsChanged" ) ?;
1823
1823
1824
1824
info ! ( "End {}" , lsp:: notification:: PublishDiagnostics :: METHOD ) ;
@@ -2071,7 +2071,7 @@ impl State {
2071
2071
self . textDocument_didOpen ( params) ?;
2072
2072
2073
2073
if let Some ( diagnostics) = self . diagnostics . get ( & filename) . cloned ( ) {
2074
- self . display_diagnostics ( & filename, & diagnostics) ?;
2074
+ self . process_diagnostics ( & filename, & diagnostics) ?;
2075
2075
self . languageClient_handleCursorMoved ( params) ?;
2076
2076
}
2077
2077
} else {
@@ -2145,36 +2145,51 @@ impl State {
2145
2145
info ! ( "Begin {}" , NOTIFICATION__HandleCursorMoved ) ;
2146
2146
let ( buftype, filename, line) : ( String , String , u64 ) =
2147
2147
self . gather_args ( & [ VimVar :: Buftype , VimVar :: Filename , VimVar :: Line ] , params) ?;
2148
- if !buftype. is_empty ( ) || line == self . get ( |state| Ok ( state. last_cursor_line ) ) ? {
2148
+ let ( visible_line_start, visible_line_end) : ( u64 , u64 ) = self . gather_args (
2149
+ & [ "LSP#visible_line_start()" , "LSP#visible_line_end()" ] ,
2150
+ params,
2151
+ ) ?;
2152
+ if !buftype. is_empty ( ) && !self . diagnostics . contains_key ( & filename) {
2149
2153
return Ok ( ( ) ) ;
2150
2154
}
2151
2155
2152
- self . update ( |state| {
2153
- state. last_cursor_line = line;
2154
- Ok ( ( ) )
2155
- } ) ?;
2156
- let message = self . get ( |state| {
2157
- state
2158
- . line_diagnostics
2156
+ if line != self . last_cursor_line {
2157
+ self . last_cursor_line = line;
2158
+
2159
+ let message = self . line_diagnostics
2159
2160
. get ( & ( filename. clone ( ) , line) )
2160
2161
. cloned ( )
2161
- . ok_or_else ( || {
2162
- format_err ! (
2163
- "Line diagnostic message not found! filename: {}, line: {}" ,
2164
- filename,
2165
- line
2166
- )
2167
- } )
2168
- } ) . unwrap_or_default ( ) ;
2169
- if message == self . get ( |state| Ok ( state. last_line_diagnostic . clone ( ) ) ) ? {
2170
- return Ok ( ( ) ) ;
2162
+ . unwrap_or_default ( ) ;
2163
+
2164
+ if message != self . last_line_diagnostic {
2165
+ self . echo_ellipsis ( & message) ?;
2166
+ self . last_line_diagnostic = message;
2167
+ }
2171
2168
}
2172
2169
2173
- self . update ( |state| {
2174
- state. last_line_diagnostic = message. clone ( ) ;
2175
- Ok ( ( ) )
2176
- } ) ?;
2177
- self . echo_ellipsis ( & message) ?;
2170
+ let signs_prev = self . signs_placed
2171
+ . get ( & filename)
2172
+ . cloned ( )
2173
+ . unwrap_or_default ( ) ;
2174
+ let signs: Vec < _ > = self . signs
2175
+ . entry ( filename. clone ( ) )
2176
+ . or_insert_with ( || vec ! [ ] )
2177
+ . iter ( )
2178
+ . filter_map ( |s| {
2179
+ if s. line < visible_line_start || s. line > visible_line_end {
2180
+ return None ;
2181
+ }
2182
+
2183
+ Some ( s. clone ( ) )
2184
+ } )
2185
+ . collect ( ) ;
2186
+ if signs != signs_prev {
2187
+ let ( signs, cmds) = get_command_update_signs ( & signs_prev, & signs, & filename) ;
2188
+ self . signs_placed . insert ( filename. clone ( ) , signs) ;
2189
+
2190
+ info ! ( "Updating signs: {:?}" , cmds) ;
2191
+ self . command ( & cmds) ?;
2192
+ }
2178
2193
2179
2194
info ! ( "End {}" , NOTIFICATION__HandleCursorMoved ) ;
2180
2195
Ok ( ( ) )
0 commit comments