mirror of https://github.com/helix-editor/helix
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 configpull/1385/head
parent
60f3225c7f
commit
0e7d757869
|
@ -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…
Reference in New Issue