on master help sign in
Add diagnostics keybindings
16b1cfaWojciech Kępka
helix-term/src/application.rs+1−1
@@ -217,7 +217,7 @@ impl Application {
217 })
217 })
218 .collect();
218 .collect();
219
219
220− doc.diagnostics = diagnostics;
220+ doc.set_diagnostics(diagnostics);
221 // TODO: we want to process all the events in queue, then render. publishDiagnostic tends to send a whole bunch of events
221 // TODO: we want to process all the events in queue, then render. publishDiagnostic tends to send a whole bunch of events
222 self.render();
222 self.render();
223 }
223 }
helix-term/src/commands.rs+112
@@ -1536,6 +1536,86 @@ pub fn goto_reference(cx: &mut Context) {
1536 );
1536 );
1537}
1537}
1538
1538
1539+fn goto_pos(editor: &mut Editor, pos: usize) {
1540+ push_jump(editor);
1541+
1542+ let (view, doc) = editor.current();
1543+
1544+ doc.set_selection(view.id, Selection::point(pos));
1545+ align_view(doc, view, Align::Center);
1546+}
1547+
1548+pub fn goto_first_diag(cx: &mut Context) {
1549+ let editor = &mut cx.editor;
1550+ let (view, doc) = editor.current();
1551+
1552+ let cursor_pos = doc.selection(view.id).cursor();
1553+ let diag = if let Some(diag) = doc.diagnostics().first() {
1554+ diag.range.start
1555+ } else {
1556+ return;
1557+ };
1558+
1559+ goto_pos(editor, diag);
1560+}
1561+
1562+pub fn goto_last_diag(cx: &mut Context) {
1563+ let editor = &mut cx.editor;
1564+ let (view, doc) = editor.current();
1565+
1566+ let cursor_pos = doc.selection(view.id).cursor();
1567+ let diag = if let Some(diag) = doc.diagnostics().last() {
1568+ diag.range.start
1569+ } else {
1570+ return;
1571+ };
1572+
1573+ goto_pos(editor, diag);
1574+}
1575+
1576+pub fn goto_next_diag(cx: &mut Context) {
1577+ let editor = &mut cx.editor;
1578+ let (view, doc) = editor.current();
1579+
1580+ let cursor_pos = doc.selection(view.id).cursor();
1581+ let diag = if let Some(diag) = doc
1582+ .diagnostics()
1583+ .iter()
1584+ .map(|diag| diag.range.start)
1585+ .find(|&pos| pos > cursor_pos)
1586+ {
1587+ diag
1588+ } else if let Some(diag) = doc.diagnostics().first() {
1589+ diag.range.start
1590+ } else {
1591+ return;
1592+ };
1593+
1594+ goto_pos(editor, diag);
1595+}
1596+
1597+pub fn goto_prev_diag(cx: &mut Context) {
1598+ let editor = &mut cx.editor;
1599+ let (view, doc) = editor.current();
1600+
1601+ let cursor_pos = doc.selection(view.id).cursor();
1602+ let diag = if let Some(diag) = doc
1603+ .diagnostics()
1604+ .iter()
1605+ .rev()
1606+ .map(|diag| diag.range.start)
1607+ .find(|&pos| pos < cursor_pos)
1608+ {
1609+ diag
1610+ } else if let Some(diag) = doc.diagnostics().last() {
1611+ diag.range.start
1612+ } else {
1613+ return;
1614+ };
1615+
1616+ goto_pos(editor, diag);
1617+}
1618+
1539pub fn signature_help(cx: &mut Context) {
1619pub fn signature_help(cx: &mut Context) {
1540 let (view, doc) = cx.current();
1620 let (view, doc) = cx.current();
1541
1621
@@ -2433,3 +2513,35 @@ pub fn view_mode(cx: &mut Context) {
2433 }
2513 }
2434 })
2514 })
2435}
2515}
2516+
2517+pub fn left_bracket_mode(cx: &mut Context) {
2518+ cx.on_next_key(move |cx, event| {
2519+ if let KeyEvent {
2520+ code: KeyCode::Char(ch),
2521+ ..
2522+ } = event
2523+ {
2524+ match ch {
2525+ 'd' => goto_prev_diag(cx),
2526+ 'D' => goto_first_diag(cx),
2527+ _ => (),
2528+ }
2529+ }
2530+ })
2531+}
2532+
2533+pub fn right_bracket_mode(cx: &mut Context) {
2534+ cx.on_next_key(move |cx, event| {
2535+ if let KeyEvent {
2536+ code: KeyCode::Char(ch),
2537+ ..
2538+ } = event
2539+ {
2540+ match ch {
2541+ 'd' => goto_next_diag(cx),
2542+ 'D' => goto_last_diag(cx),
2543+ _ => (),
2544+ }
2545+ }
2546+ })
2547+}
helix-term/src/keymap.rs+7−1
@@ -85,6 +85,10 @@ use std::collections::HashMap;
85//
85//
86// gd = goto definition
86// gd = goto definition
87// gr = goto reference
87// gr = goto reference
88+// [d = previous diagnostic
89+// d] = next diagnostic
90+// [D = first diagnostic
91+// D] = last diagnostic
88// }
92// }
89
93
90// #[cfg(feature = "term")]
94// #[cfg(feature = "term")]
@@ -209,7 +213,9 @@ pub fn default() -> Keymaps {
209 // repeat_select
213 // repeat_select
210
214
211 // TODO: figure out what key to use
215 // TODO: figure out what key to use
212− key!('[') => commands::expand_selection,
216+ // key!('[') => commands::expand_selection, ??
217+ key!('[') => commands::left_bracket_mode,
218+ key!(']') => commands::right_bracket_mode,
213
219
214 key!('/') => commands::search,
220 key!('/') => commands::search,
215 // ? for search_reverse
221 // ? for search_reverse
helix-term/src/ui/editor.rs+4−4
@@ -195,7 +195,7 @@ impl EditorView {
195 }
195 }
196
196
197 // ugh,interleave highlight spans with diagnostic spans
197 // ugh,interleave highlight spans with diagnostic spans
198− let is_diagnostic = doc.diagnostics.iter().any(|diagnostic| {
198+ let is_diagnostic = doc.diagnostics().iter().any(|diagnostic| {
199 diagnostic.range.start <= char_index
199 diagnostic.range.start <= char_index
200 && diagnostic.range.end > char_index
200 && diagnostic.range.end > char_index
201 });
201 });
@@ -343,7 +343,7 @@ impl EditorView {
343
343
344 for (i, line) in (view.first_line..=last_line).enumerate() {
344 for (i, line) in (view.first_line..=last_line).enumerate() {
345 use helix_core::diagnostic::Severity;
345 use helix_core::diagnostic::Severity;
346− if let Some(diagnostic) = doc.diagnostics.iter().find(|d| d.line == line) {
346+ if let Some(diagnostic) = doc.diagnostics().iter().find(|d| d.line == line) {
347 surface.set_stringn(
347 surface.set_stringn(
348 viewport.x - OFFSET,
348 viewport.x - OFFSET,
349 viewport.y + i as u16,
349 viewport.y + i as u16,
@@ -387,7 +387,7 @@ impl EditorView {
387 let cursor = doc.selection(view.id).cursor();
387 let cursor = doc.selection(view.id).cursor();
388 let line = doc.text().char_to_line(cursor);
388 let line = doc.text().char_to_line(cursor);
389
389
390− let diagnostics = doc.diagnostics.iter().filter(|diagnostic| {
390+ let diagnostics = doc.diagnostics().iter().filter(|diagnostic| {
391 diagnostic.range.start <= cursor && diagnostic.range.end >= cursor
391 diagnostic.range.start <= cursor && diagnostic.range.end >= cursor
392 });
392 });
393
393
@@ -469,7 +469,7 @@ impl EditorView {
469 surface.set_stringn(
469 surface.set_stringn(
470 viewport.x + viewport.width.saturating_sub(15),
470 viewport.x + viewport.width.saturating_sub(15),
471 viewport.y,
471 viewport.y,
472− format!("{}", doc.diagnostics.len()),
472+ format!("{}", doc.diagnostics().len()),
473 4,
473 4,
474 text_color,
474 text_color,
475 );
475 );
helix-view/src/document.rs+9−1
@@ -48,7 +48,7 @@ pub struct Document {
48 last_saved_revision: usize,
48 last_saved_revision: usize,
49 version: i32, // should be usize?
49 version: i32, // should be usize?
50
50
51− pub diagnostics: Vec<Diagnostic>,
51+ diagnostics: Vec<Diagnostic>,
52 language_server: Option<Arc<helix_lsp::Client>>,
52 language_server: Option<Arc<helix_lsp::Client>>,
53}
53}
54
54
@@ -519,6 +519,14 @@ impl Document {
519 pub fn versioned_identifier(&self) -> lsp::VersionedTextDocumentIdentifier {
519 pub fn versioned_identifier(&self) -> lsp::VersionedTextDocumentIdentifier {
520 lsp::VersionedTextDocumentIdentifier::new(self.url().unwrap(), self.version)
520 lsp::VersionedTextDocumentIdentifier::new(self.url().unwrap(), self.version)
521 }
521 }
522+
523+ pub fn diagnostics(&self) -> &[Diagnostic] {
524+ &self.diagnostics
525+ }
526+
527+ pub fn set_diagnostics(&mut self, diagnostics: Vec<Diagnostic>) {
528+ self.diagnostics = diagnostics;
529+ }
522}
530}
523
531
524#[cfg(test)]
532#[cfg(test)]