aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWojciech Kępka2021-06-06 09:59:32 +0000
committerBlaž Hrastnik2021-06-07 00:11:52 +0000
commit16b1cfa3be2665e78bea6c876d3ced96dbfeb44f (patch)
tree08abe1f4a6a4c2b9286ce226498792e014ac050f
parent2066e866c739fec210df85534b9fbc1de02c155b (diff)
Add diagnostics keybindings
-rw-r--r--helix-term/src/application.rs2
-rw-r--r--helix-term/src/commands.rs112
-rw-r--r--helix-term/src/keymap.rs8
-rw-r--r--helix-term/src/ui/editor.rs8
-rw-r--r--helix-view/src/document.rs10
5 files changed, 133 insertions, 7 deletions
diff --git a/helix-term/src/application.rs b/helix-term/src/application.rs
index f064e866..84824b51 100644
--- a/helix-term/src/application.rs
+++ b/helix-term/src/application.rs
@@ -217,7 +217,7 @@ impl Application {
})
.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();
}
diff --git a/helix-term/src/commands.rs b/helix-term/src/commands.rs
index 7992a517..52d3acbc 100644
--- a/helix-term/src/commands.rs
+++ b/helix-term/src/commands.rs
@@ -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),
+ _ => (),
+ }
+ }
+ })
+}
diff --git a/helix-term/src/keymap.rs b/helix-term/src/keymap.rs
index 6ef53915..27ef9b9e 100644
--- a/helix-term/src/keymap.rs
+++ b/helix-term/src/keymap.rs
@@ -85,6 +85,10 @@ use std::collections::HashMap;
//
// 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
diff --git a/helix-term/src/ui/editor.rs b/helix-term/src/ui/editor.rs
index 2464528c..f47d6c26 100644
--- a/helix-term/src/ui/editor.rs
+++ b/helix-term/src/ui/editor.rs
@@ -195,7 +195,7 @@ impl EditorView {
}
// 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 @@ impl EditorView {
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 @@ impl EditorView {
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 @@ impl EditorView {
surface.set_stringn(
viewport.x + viewport.width.saturating_sub(15),
viewport.y,
- format!("{}", doc.diagnostics.len()),
+ format!("{}", doc.diagnostics().len()),
4,
text_color,
);
diff --git a/helix-view/src/document.rs b/helix-view/src/document.rs
index 9093dbe8..783e1117 100644
--- a/helix-view/src/document.rs
+++ b/helix-view/src/document.rs
@@ -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 @@ impl Document {
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)]