Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

See #6417 instead [Feat: CodeLens-style diagnostics] #6059

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions book/src/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ The following statusline elements can be configured:
| `auto-signature-help` | Enable automatic popup of signature help (parameter hints) | `true` |
| `display-inlay-hints` | Display inlay hints[^2] | `false` |
| `display-signature-help-docs` | Display docs under signature help popup | `true` |
| `display-inline-diagnostics` | Display diagnostics under their starting line | `true` |

[^1]: By default, a progress spinner is shown in the statusline beside the file path.
[^2]: You may also have to activate them in the LSP config for them to appear, not just in Helix.
Expand Down
1 change: 1 addition & 0 deletions book/src/themes.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ These scopes are used for theming the editor interface:
| `ui.text.info` | The key: command text in `ui.popup.info` boxes |
| `ui.virtual.ruler` | Ruler columns (see the [`editor.rulers` config][editor-section]) |
| `ui.virtual.whitespace` | Visible whitespace characters |
| `ui.virtual.diagnostics` | Default style for inline diagnostics lines (notably control the background) |
| `ui.virtual.indent-guide` | Vertical indent width guides |
| `ui.virtual.inlay-hint` | Default style for inlay hints of all kinds |
| `ui.virtual.inlay-hint.parameter` | Style for inlay hints of kind `parameter` (LSPs are not required to set a kind) |
Expand Down
5 changes: 4 additions & 1 deletion helix-core/src/diagnostic.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//! LSP diagnostic utility types.
use std::rc::Rc;

use serde::{Deserialize, Serialize};

/// Describes the severity level of a [`Diagnostic`].
Expand Down Expand Up @@ -40,7 +42,8 @@ pub enum DiagnosticTag {
pub struct Diagnostic {
pub range: Range,
pub line: usize,
pub message: String,
// Messages will also be copied in the inline diagnostics, let's avoid allocating twice
pub message: Rc<String>,
pub severity: Option<Severity>,
pub code: Option<NumberOrString>,
pub tags: Vec<DiagnosticTag>,
Expand Down
2 changes: 1 addition & 1 deletion helix-core/src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ pub fn visual_offset_from_anchor(
anchor_line = Some(last_pos.row);
}
if char_pos > pos {
last_pos.row -= anchor_line.unwrap();
last_pos.row -= anchor_line?;
return Some((last_pos, block_start));
}

Expand Down
2 changes: 1 addition & 1 deletion helix-lsp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ pub mod util {
severity,
code,
source: diag.source.clone(),
message: diag.message.to_owned(),
message: diag.message.as_str().into(),
related_information: None,
tags,
data: diag.data.to_owned(),
Expand Down
38 changes: 35 additions & 3 deletions helix-term/src/application.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@ use futures_util::Stream;
use helix_core::{
diagnostic::{DiagnosticTag, NumberOrString},
path::get_relative_path,
pos_at_coords, syntax, Selection,
pos_at_coords, syntax,
text_annotations::LineAnnotation,
Selection,
};
use helix_lsp::{lsp, util::lsp_pos_to_pos, LspProgressMap};
use helix_view::{
align_view,
document::annotations::{diagnostic_inline_messages_from_diagnostics, DiagnosticAnnotations},
document::DocumentSavedEventResult,
editor::{ConfigEvent, EditorEvent},
graphics::Rect,
Expand All @@ -30,8 +33,10 @@ use crate::{

use log::{debug, error, warn};
use std::{
collections::BTreeMap,
io::{stdin, stdout},
path::Path,
rc::Rc,
sync::Arc,
time::{Duration, Instant},
};
Expand Down Expand Up @@ -687,12 +692,17 @@ impl Application {
return;
}
};

let enabled_inline_diagnostics =
self.editor.config().lsp.display_inline_diagnostics;
let doc = self.editor.document_by_path_mut(&path);

if let Some(doc) = doc {
let lang_conf = doc.language_config();
let text = doc.text();

let mut diagnostic_annotations = BTreeMap::new();

let diagnostics = params
.diagnostics
.iter()
Expand Down Expand Up @@ -776,18 +786,39 @@ impl Application {
Vec::new()
};

if enabled_inline_diagnostics {
*diagnostic_annotations.entry(start).or_default() += diagnostic.message.trim().lines().count();
}

Some(Diagnostic {
range: Range { start, end },
line: diagnostic.range.start.line as usize,
message: diagnostic.message.clone(),
message: Rc::new(diagnostic.message.clone()),
severity,
code,
tags,
source: diagnostic.source.clone(),
data: diagnostic.data.clone(),
})
})
.collect();
.collect::<Vec<_>>();

if enabled_inline_diagnostics {
let diagnostic_annotations = diagnostic_annotations
.into_iter()
.map(|(anchor_char_idx, height)| LineAnnotation {
anchor_char_idx,
height,
})
.collect::<Vec<_>>();

doc.set_diagnostics_annotations(DiagnosticAnnotations {
annotations: diagnostic_annotations.into(),
messages: diagnostic_inline_messages_from_diagnostics(
&diagnostics,
),
})
}

doc.set_diagnostics(diagnostics);
}
Expand Down Expand Up @@ -909,6 +940,7 @@ impl Application {
== Some(server_id)
{
doc.set_diagnostics(Vec::new());
doc.set_diagnostics_annotations(Default::default());
doc.url()
} else {
None
Expand Down
24 changes: 19 additions & 5 deletions helix-term/src/ui/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
};

use helix_core::{
diagnostic::Severity,
graphemes::{
ensure_grapheme_boundary_next_byte, next_grapheme_boundary, prev_grapheme_boundary,
},
Expand All @@ -35,6 +36,8 @@ use tui::buffer::Buffer as Surface;
use super::statusline;
use super::{document::LineDecoration, lsp::SignatureHelp};

mod diagnostics_annotations;

pub struct EditorView {
pub keymaps: Keymaps,
on_next_key: Option<OnKeyCallback>,
Expand Down Expand Up @@ -126,6 +129,16 @@ impl EditorView {
}
}

if config.lsp.display_inline_diagnostics {
line_decorations.push(diagnostics_annotations::inline_diagnostics_decorator(
doc,
view,
inner,
theme,
&text_annotations,
));
}

if is_focused && config.cursorline {
line_decorations.push(Self::cursorline_decorator(doc, view, theme))
}
Expand Down Expand Up @@ -223,7 +236,11 @@ impl EditorView {
}
}

Self::render_diagnostics(doc, view, inner, surface, theme);
// If inline diagnostics are already displayed, we don't need to add the diagnostics in the
// top right corner, they would be redundant
if !config.lsp.display_inline_diagnostics {
Self::render_diagnostics(doc, view, inner, surface, theme);
}

let statusline_area = view
.area
Expand Down Expand Up @@ -346,7 +363,6 @@ impl EditorView {
doc: &Document,
theme: &Theme,
) -> [Vec<(usize, std::ops::Range<usize>)>; 5] {
use helix_core::diagnostic::Severity;
let get_scope_of = |scope| {
theme
.find_scope_index_exact(scope)
Expand Down Expand Up @@ -650,7 +666,6 @@ impl EditorView {
surface: &mut Surface,
theme: &Theme,
) {
use helix_core::diagnostic::Severity;
use tui::{
layout::Alignment,
text::Text,
Expand Down Expand Up @@ -682,7 +697,7 @@ impl EditorView {
Some(Severity::Info) => info,
Some(Severity::Hint) => hint,
});
let text = Text::styled(&diagnostic.message, style);
let text = Text::styled(&*diagnostic.message, style);
lines.extend(text.lines);
}

Expand Down Expand Up @@ -1392,7 +1407,6 @@ impl Component for EditorView {
// render status msg
if let Some((status_msg, severity)) = &cx.editor.status_msg {
status_msg_width = status_msg.width();
use helix_view::editor::Severity;
let style = if *severity == Severity::Error {
cx.editor.theme.get("error")
} else {
Expand Down
Loading