feat(lsp): configurable diagnostic severity (#1325)

* feat(lsp): configurable diagnostic severity

Allow severity of diagnostic messages to be configured.
E.g. allow turning of Hint level diagnostics.

Fixes: https://github.com/helix-editor/helix/issues/1007

* Use language_config() method

* Add documentation for diagnostic_severity

* Use unreachable for unknown severity level

* fix: documentation for diagnostic_severity config
pull/1385/head
Matouš Dzivjak 3 years ago committed by GitHub
parent 60f3225c7f
commit 0e7d757869
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -27,18 +27,19 @@ directory](../configuration.md).
These are the available keys and descriptions for the file. These are the available keys and descriptions for the file.
| Key | Description | | Key | Description |
| ---- | ----------- | | ---- | ----------- |
| name | The name of the language | | name | The name of the language |
| scope | A string like `source.js` that identifies the language. Currently, we strive to match the scope names used by popular TextMate grammars and by the Linguist library. Usually `source.<name>` or `text.<name>` in case of markup languages | | scope | A string like `source.js` that identifies the language. Currently, we strive to match the scope names used by popular TextMate grammars and by the Linguist library. Usually `source.<name>` or `text.<name>` in case of markup languages |
| injection-regex | regex pattern that will be tested against a language name in order to determine whether this language should be used for a potential [language injection][treesitter-language-injection] site. | | injection-regex | regex pattern that will be tested against a language name in order to determine whether this language should be used for a potential [language injection][treesitter-language-injection] site. |
| file-types | The filetypes of the language, for example `["yml", "yaml"]` | | file-types | The filetypes of the language, for example `["yml", "yaml"]` |
| shebangs | The interpreters from the shebang line, for example `["sh", "bash"]` | | shebangs | The interpreters from the shebang line, for example `["sh", "bash"]` |
| roots | A set of marker files to look for when trying to find the workspace root. For example `Cargo.lock`, `yarn.lock` | | roots | A set of marker files to look for when trying to find the workspace root. For example `Cargo.lock`, `yarn.lock` |
| auto-format | Whether to autoformat this language when saving | | auto-format | Whether to autoformat this language when saving |
| comment-token | The token to use as a comment-token | | diagnostic-severity | Minimal severity of diagnostic for it to be displayed. (Allowed values: `Error`, `Warning`, `Info`, `Hint`) |
| indent | The indent to use. Has sub keys `tab-width` and `unit` | | comment-token | The token to use as a comment-token |
| config | Language server configuration | | indent | The indent to use. Has sub keys `tab-width` and `unit` |
| config | Language server configuration |
## Queries ## Queries

@ -11,4 +11,3 @@ Changes made to the `languages.toml` file in a user's [configuration directory](
name = "rust" name = "rust"
auto-format = false auto-format = false
``` ```

@ -1,12 +1,19 @@
//! LSP diagnostic utility types. //! LSP diagnostic utility types.
use serde::{Deserialize, Serialize};
/// Describes the severity level of a [`Diagnostic`]. /// Describes the severity level of a [`Diagnostic`].
#[derive(Debug, Clone, Copy, Eq, PartialEq)] #[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Deserialize, Serialize)]
pub enum Severity { pub enum Severity {
Error,
Warning,
Info,
Hint, Hint,
Info,
Warning,
Error,
}
impl Default for Severity {
fn default() -> Self {
Self::Hint
}
} }
/// A range of `char`s within the text. /// A range of `char`s within the text.

@ -442,6 +442,7 @@ where
); );
let doc = Rope::from(doc); let doc = Rope::from(doc);
use crate::diagnostic::Severity;
use crate::syntax::{ use crate::syntax::{
Configuration, IndentationConfiguration, LanguageConfiguration, Loader, Configuration, IndentationConfiguration, LanguageConfiguration, Loader,
}; };
@ -459,6 +460,7 @@ where
roots: vec![], roots: vec![],
comment_token: None, comment_token: None,
auto_format: false, auto_format: false,
diagnostic_severity: Severity::Warning,
language_server: None, language_server: None,
indent: Some(IndentationConfiguration { indent: Some(IndentationConfiguration {
tab_width: 4, tab_width: 4,

@ -1,5 +1,6 @@
use crate::{ use crate::{
chars::char_is_line_ending, chars::char_is_line_ending,
diagnostic::Severity,
regex::Regex, regex::Regex,
transaction::{ChangeSet, Operation}, transaction::{ChangeSet, Operation},
Rope, RopeSlice, Tendril, Rope, RopeSlice, Tendril,
@ -63,6 +64,8 @@ pub struct LanguageConfiguration {
#[serde(default)] #[serde(default)]
pub auto_format: bool, pub auto_format: bool,
#[serde(default)]
pub diagnostic_severity: Severity,
// content_regex // content_regex
#[serde(default, skip_serializing, deserialize_with = "deserialize_regex")] #[serde(default, skip_serializing, deserialize_with = "deserialize_regex")]

@ -378,6 +378,7 @@ impl Application {
let doc = self.editor.document_by_path_mut(&path); let doc = self.editor.document_by_path_mut(&path);
if let Some(doc) = doc { if let Some(doc) = doc {
let lang_conf = doc.language_config();
let text = doc.text(); let text = doc.text();
let diagnostics = params let diagnostics = params
@ -415,19 +416,31 @@ impl Application {
return None; return None;
}; };
let severity =
diagnostic.severity.map(|severity| match severity {
DiagnosticSeverity::ERROR => Error,
DiagnosticSeverity::WARNING => Warning,
DiagnosticSeverity::INFORMATION => Info,
DiagnosticSeverity::HINT => Hint,
severity => unreachable!(
"unrecognized diagnostic severity: {:?}",
severity
),
});
if let Some(lang_conf) = lang_conf {
if let Some(severity) = severity {
if severity < lang_conf.diagnostic_severity {
return None;
}
}
};
Some(Diagnostic { Some(Diagnostic {
range: Range { start, end }, range: Range { start, end },
line: diagnostic.range.start.line as usize, line: diagnostic.range.start.line as usize,
message: diagnostic.message, message: diagnostic.message,
severity: diagnostic.severity.map( severity,
|severity| match severity {
DiagnosticSeverity::ERROR => Error,
DiagnosticSeverity::WARNING => Warning,
DiagnosticSeverity::INFORMATION => Info,
DiagnosticSeverity::HINT => Hint,
severity => unimplemented!("{:?}", severity),
},
),
// code // code
// source // source
}) })

Loading…
Cancel
Save