Add diagnostics keybindings

This commit is contained in:
Wojciech Kępka 2021-06-06 11:59:32 +02:00 committed by Blaž Hrastnik
parent 2066e866c7
commit 16b1cfa3be
5 changed files with 133 additions and 7 deletions

View File

@ -217,7 +217,7 @@ pub async fn handle_language_server_message(&mut self, call: helix_lsp::Call) {
})
.collect();
doc.diagnostics = diagnostics;
doc.set_diagnostics(diagnostics);
// TODO: we want to process all the events in queue, then render. publishDiagnostic tends to send a whole bunch of events
self.render();
}

View File

@ -1536,6 +1536,86 @@ pub fn goto_reference(cx: &mut Context) {
);
}
fn goto_pos(editor: &mut Editor, pos: usize) {
push_jump(editor);
let (view, doc) = editor.current();
doc.set_selection(view.id, Selection::point(pos));
align_view(doc, view, Align::Center);
}
pub fn goto_first_diag(cx: &mut Context) {
let editor = &mut cx.editor;
let (view, doc) = editor.current();
let cursor_pos = doc.selection(view.id).cursor();
let diag = if let Some(diag) = doc.diagnostics().first() {
diag.range.start
} else {
return;
};
goto_pos(editor, diag);
}
pub fn goto_last_diag(cx: &mut Context) {
let editor = &mut cx.editor;
let (view, doc) = editor.current();
let cursor_pos = doc.selection(view.id).cursor();
let diag = if let Some(diag) = doc.diagnostics().last() {
diag.range.start
} else {
return;
};
goto_pos(editor, diag);
}
pub fn goto_next_diag(cx: &mut Context) {
let editor = &mut cx.editor;
let (view, doc) = editor.current();
let cursor_pos = doc.selection(view.id).cursor();
let diag = if let Some(diag) = doc
.diagnostics()
.iter()
.map(|diag| diag.range.start)
.find(|&pos| pos > cursor_pos)
{
diag
} else if let Some(diag) = doc.diagnostics().first() {
diag.range.start
} else {
return;
};
goto_pos(editor, diag);
}
pub fn goto_prev_diag(cx: &mut Context) {
let editor = &mut cx.editor;
let (view, doc) = editor.current();
let cursor_pos = doc.selection(view.id).cursor();
let diag = if let Some(diag) = doc
.diagnostics()
.iter()
.rev()
.map(|diag| diag.range.start)
.find(|&pos| pos < cursor_pos)
{
diag
} else if let Some(diag) = doc.diagnostics().last() {
diag.range.start
} else {
return;
};
goto_pos(editor, diag);
}
pub fn signature_help(cx: &mut Context) {
let (view, doc) = cx.current();
@ -2433,3 +2513,35 @@ pub fn view_mode(cx: &mut Context) {
}
})
}
pub fn left_bracket_mode(cx: &mut Context) {
cx.on_next_key(move |cx, event| {
if let KeyEvent {
code: KeyCode::Char(ch),
..
} = event
{
match ch {
'd' => goto_prev_diag(cx),
'D' => goto_first_diag(cx),
_ => (),
}
}
})
}
pub fn right_bracket_mode(cx: &mut Context) {
cx.on_next_key(move |cx, event| {
if let KeyEvent {
code: KeyCode::Char(ch),
..
} = event
{
match ch {
'd' => goto_next_diag(cx),
'D' => goto_last_diag(cx),
_ => (),
}
}
})
}

View File

@ -85,6 +85,10 @@
//
// gd = goto definition
// gr = goto reference
// [d = previous diagnostic
// d] = next diagnostic
// [D = first diagnostic
// D] = last diagnostic
// }
// #[cfg(feature = "term")]
@ -209,7 +213,9 @@ pub fn default() -> Keymaps {
// repeat_select
// TODO: figure out what key to use
key!('[') => commands::expand_selection,
// key!('[') => commands::expand_selection, ??
key!('[') => commands::left_bracket_mode,
key!(']') => commands::right_bracket_mode,
key!('/') => commands::search,
// ? for search_reverse

View File

@ -195,7 +195,7 @@ pub fn render_buffer(
}
// ugh,interleave highlight spans with diagnostic spans
let is_diagnostic = doc.diagnostics.iter().any(|diagnostic| {
let is_diagnostic = doc.diagnostics().iter().any(|diagnostic| {
diagnostic.range.start <= char_index
&& diagnostic.range.end > char_index
});
@ -343,7 +343,7 @@ pub fn render_buffer(
for (i, line) in (view.first_line..=last_line).enumerate() {
use helix_core::diagnostic::Severity;
if let Some(diagnostic) = doc.diagnostics.iter().find(|d| d.line == line) {
if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
surface.set_stringn(
viewport.x - OFFSET,
viewport.y + i as u16,
@ -387,7 +387,7 @@ pub fn render_diagnostics(
let cursor = doc.selection(view.id).cursor();
let line = doc.text().char_to_line(cursor);
let diagnostics = doc.diagnostics.iter().filter(|diagnostic| {
let diagnostics = doc.diagnostics().iter().filter(|diagnostic| {
diagnostic.range.start <= cursor && diagnostic.range.end >= cursor
});
@ -469,7 +469,7 @@ pub fn render_statusline(
surface.set_stringn(
viewport.x + viewport.width.saturating_sub(15),
viewport.y,
format!("{}", doc.diagnostics.len()),
format!("{}", doc.diagnostics().len()),
4,
text_color,
);

View File

@ -48,7 +48,7 @@ pub struct Document {
last_saved_revision: usize,
version: i32, // should be usize?
pub diagnostics: Vec<Diagnostic>,
diagnostics: Vec<Diagnostic>,
language_server: Option<Arc<helix_lsp::Client>>,
}
@ -519,6 +519,14 @@ pub fn identifier(&self) -> lsp::TextDocumentIdentifier {
pub fn versioned_identifier(&self) -> lsp::VersionedTextDocumentIdentifier {
lsp::VersionedTextDocumentIdentifier::new(self.url().unwrap(), self.version)
}
pub fn diagnostics(&self) -> &[Diagnostic] {
&self.diagnostics
}
pub fn set_diagnostics(&mut self, diagnostics: Vec<Diagnostic>) {
self.diagnostics = diagnostics;
}
}
#[cfg(test)]