Skip to content

Commit d4d1db7

Browse files
authored
Add function and plug mappings to cycle diagnostics (#1075)
* Add function and plug mappings to cycle diagnostics * Fix lint errors
1 parent 217feed commit d4d1db7

File tree

6 files changed

+95
-1
lines changed

6 files changed

+95
-1
lines changed

autoload/LanguageClient.vim

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,22 @@ function! LanguageClient#setLoggingLevel(level) abort
10501050
return LanguageClient#Call('languageClient/setLoggingLevel', l:params, v:null)
10511051
endfunction
10521052

1053+
function! LanguageClient#diagnosticsPrevious() abort
1054+
let l:params = {
1055+
\ 'filename': LSP#filename(),
1056+
\ 'position': LSP#position(),
1057+
\ }
1058+
return LanguageClient#Notify('languageClient/diagnosticsPrevious', l:params)
1059+
endfunction
1060+
1061+
function! LanguageClient#diagnosticsNext() abort
1062+
let l:params = {
1063+
\ 'filename': LSP#filename(),
1064+
\ 'position': LSP#position(),
1065+
\ }
1066+
return LanguageClient#Notify('languageClient/diagnosticsNext', l:params)
1067+
endfunction
1068+
10531069
function! LanguageClient#setDiagnosticsList(diagnosticsList) abort
10541070
let l:params = {
10551071
\ 'diagnosticsList': a:diagnosticsList,

doc/LanguageClient.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -912,6 +912,17 @@ Signature: LanguageClient#debugInfo(...)
912912

913913
Print out debug info.
914914

915+
*LanguageClient#diagnosticsNext*
916+
Signature: LanguageClient#diagnosticsNext()
917+
918+
Moves the cursor to the next diagnostic in the buffer, relative to the current cursor position.
919+
920+
*LanguageClient#diagnosticsPrevious*
921+
Signature: LanguageClient#diagnosticsPrevious()
922+
923+
Moves the cursor to the previous diagnostic in the buffer, relative to the current cursor position.
924+
925+
915926
==============================================================================
916927
5. Mappings *LanguageClientMappings*
917928

@@ -966,6 +977,12 @@ Calls LanguageClient_textDocument_formatting.
966977
*(lcn-format-sync)*
967978
Calls LanguageClient_textDocument_formatting_sync.
968979

980+
*(lcn-diagnostics-next)*
981+
Calls LanguageClient_diagnosticsNext.
982+
983+
*(lcn-diagnostics-prev)*
984+
Calls LanguageClient_diagnosticsPrevious.
985+
969986

970987
==============================================================================
971988
6. Events *LanguageClientEvents*

plugin/LanguageClient.vim

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,14 @@ function! LanguageClient_statusLine(...)
110110
return call('LanguageClient#statusLine', a:000)
111111
endfunction
112112

113+
function! LanguageClient_diagnosticsPrevious(...)
114+
return call('LanguageClient#diagnosticsPrevious', a:000)
115+
endfunction
116+
117+
function! LanguageClient_diagnosticsNext(...)
118+
return call('LanguageClient#diagnosticsNext', a:000)
119+
endfunction
120+
113121
function! LanguageClient_statusLineDiagnosticsCounts(...)
114122
return call('LanguageClient#statusLineDiagnosticsCounts', a:000)
115123
endfunction
@@ -178,4 +186,6 @@ augroup languageClient
178186
nnoremap <Plug>(lcn-explain-error) :call LanguageClient_explainErrorAtPoint()<CR>
179187
nnoremap <Plug>(lcn-format) :call LanguageClient_textDocument_formatting()<CR>
180188
nnoremap <Plug>(lcn-format-sync) :call LanguageClient_textDocument_formatting_sync()<CR>
189+
nnoremap <Plug>(lcn-diagnostics-next) :call LanguageClient_diagnosticsNext()<CR>
190+
nnoremap <Plug>(lcn-diagnostics-prev) :call LanguageClient_diagnosticsPrevious()<CR>
181191
augroup END

src/language_server_protocol.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ use std::{
5858
time::{Duration, Instant},
5959
};
6060

61+
#[derive(PartialEq)]
62+
pub enum Direction {
63+
Next,
64+
Previous,
65+
}
66+
6167
impl LanguageClient {
6268
pub fn get_client(&self, language_id: &LanguageId) -> Result<Arc<RpcClient>> {
6369
self.get(|state| state.clients.get(language_id).cloned())?
@@ -607,6 +613,45 @@ impl LanguageClient {
607613
Ok(position)
608614
}
609615

616+
// moves the cursor to the next or previous diagnostic, depending on the value of direction.
617+
pub fn cycle_diagnostics(&self, params: &Value, direction: Direction) -> Result<()> {
618+
let filename = self.vim()?.get_filename(params)?;
619+
let pos = self.vim()?.get_position(params)?;
620+
let mut diagnostics = self.get(|state| state.diagnostics.clone())?;
621+
if let Some(diagnostics) = diagnostics.get_mut(&filename) {
622+
if direction == Direction::Next {
623+
diagnostics.sort_by_key(|edit| (edit.range.start.line, edit.range.start.character));
624+
} else {
625+
diagnostics.sort_by_key(|edit| {
626+
(
627+
-(edit.range.start.line as i64),
628+
-(edit.range.start.character as i64),
629+
)
630+
});
631+
}
632+
633+
let (line, col) = (pos.line, pos.character);
634+
if let Some((_, diagnostic)) = diagnostics.iter_mut().find_position(|it| {
635+
let start = it.range.start;
636+
if direction == Direction::Next {
637+
start.line > line || (start.line == line && start.character > col)
638+
} else {
639+
start.line < line || (start.line == line && start.character < col)
640+
}
641+
}) {
642+
let line = diagnostic.range.start.line + 1;
643+
let col = diagnostic.range.start.character + 1;
644+
let _: String = self.vim()?.rpcclient.call("cursor", json!([line, col]))?;
645+
} else {
646+
self.vim()?.echomsg("No diagnostics found")?;
647+
}
648+
} else {
649+
self.vim()?.echomsg("No diagnostics found")?;
650+
}
651+
652+
Ok(())
653+
}
654+
610655
fn update_quickfixlist(&self) -> Result<()> {
611656
let diagnostics = self.get(|state| state.diagnostics.clone())?;
612657
let qflist: Vec<_> = diagnostics

src/rpchandler.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{language_client::LanguageClient, types::*};
1+
use crate::{language_client::LanguageClient, language_server_protocol::Direction, types::*};
22
use anyhow::{anyhow, Result};
33
use log::*;
44
use lsp_types::notification::{self, Notification};
@@ -196,6 +196,10 @@ impl LanguageClient {
196196
NOTIFICATION_RUST_BEGIN_BUILD => self.rust_handle_begin_build(&params)?,
197197
NOTIFICATION_RUST_DIAGNOSTICS_BEGIN => self.rust_handle_diagnostics_begin(&params)?,
198198
NOTIFICATION_RUST_DIAGNOSTICS_END => self.rust_handle_diagnostics_end(&params)?,
199+
NOTIFICATION_DIAGNOSTICS_NEXT => self.cycle_diagnostics(&params, Direction::Next)?,
200+
NOTIFICATION_DIAGNOSTICS_PREVIOUS => {
201+
self.cycle_diagnostics(&params, Direction::Previous)?
202+
}
199203

200204
_ => {
201205
let language_id_target = if language_id.is_some() {

src/types.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ pub const NOTIFICATION_RUST_DIAGNOSTICS_BEGIN: &str = "rustDocument/diagnosticsB
8181
pub const NOTIFICATION_RUST_DIAGNOSTICS_END: &str = "rustDocument/diagnosticsEnd";
8282
pub const NOTIFICATION_WINDOW_PROGRESS: &str = "window/progress";
8383
pub const NOTIFICATION_LANGUAGE_STATUS: &str = "language/status";
84+
pub const NOTIFICATION_DIAGNOSTICS_NEXT: &str = "languageClient/diagnosticsNext";
85+
pub const NOTIFICATION_DIAGNOSTICS_PREVIOUS: &str = "languageClient/diagnosticsPrevious";
8486

8587
pub const VIM_SERVER_STATUS: &str = "g:LanguageClient_serverStatus";
8688
pub const VIM_SERVER_STATUS_MESSAGE: &str = "g:LanguageClient_serverStatusMessage";

0 commit comments

Comments
 (0)