mirror of
https://github.com/helix-editor/helix.git
synced 2025-03-31 09:27:45 +03:00
Add pull diagnostics identifier
to LSP diagnostic provider
This includes a change to lsp-types to store the identifier as an Arc since it will be cloned for each diagnostic.
This commit is contained in:
parent
683fac65e7
commit
2cc33b5c47
3 changed files with 49 additions and 8 deletions
|
@ -1,5 +1,5 @@
|
|||
//! LSP diagnostic utility types.
|
||||
use std::fmt;
|
||||
use std::{fmt, sync::Arc};
|
||||
|
||||
pub use helix_stdx::range::Range;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -50,9 +50,24 @@ pub struct Diagnostic {
|
|||
pub data: Option<serde_json::Value>,
|
||||
}
|
||||
|
||||
/// The source of a diagnostic.
|
||||
///
|
||||
/// This type is cheap to clone: all data is either `Copy` or wrapped in an `Arc`.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum DiagnosticProvider {
|
||||
Lsp { server_id: LanguageServerId },
|
||||
Lsp {
|
||||
/// The ID of the language server which sent the diagnostic.
|
||||
server_id: LanguageServerId,
|
||||
/// An optional identifier under which diagnostics are managed by the client.
|
||||
///
|
||||
/// `identifier` is a field from the LSP "Pull Diagnostics" feature meant to provide an
|
||||
/// optional "namespace" for diagnostics: a language server can respond to a diagnostics
|
||||
/// pull request with an identifier and these diagnostics should be treated as separate
|
||||
/// from push diagnostics. Rust-analyzer uses this feature for example to provide Cargo
|
||||
/// diagnostics with push and internal diagnostics with pull. The push diagnostics should
|
||||
/// not clear the pull diagnostics and vice-versa.
|
||||
identifier: Option<Arc<str>>,
|
||||
},
|
||||
// Future internal features can go here...
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashMap;
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -33,8 +33,13 @@ pub struct DiagnosticClientCapabilities {
|
|||
pub struct DiagnosticOptions {
|
||||
/// An optional identifier under which the diagnostics are
|
||||
/// managed by the client.
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub identifier: Option<String>,
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
serialize_with = "serialize_option_arc_str",
|
||||
deserialize_with = "deserialize_option_arc_str"
|
||||
)]
|
||||
pub identifier: Option<Arc<str>>,
|
||||
|
||||
/// Whether the language has inter file dependencies, meaning that editing code in one file can
|
||||
/// result in a different diagnostic set in another file. Inter file dependencies are common
|
||||
|
@ -48,6 +53,19 @@ pub struct DiagnosticOptions {
|
|||
pub work_done_progress_options: WorkDoneProgressOptions,
|
||||
}
|
||||
|
||||
fn serialize_option_arc_str<S: serde::Serializer>(
|
||||
val: &Option<Arc<str>>,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
serializer.serialize_str(val.as_ref().unwrap())
|
||||
}
|
||||
|
||||
fn deserialize_option_arc_str<'de, D: serde::Deserializer<'de>>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<Arc<str>>, D::Error> {
|
||||
Option::<String>::deserialize(deserializer).map(|opt| opt.map(|s| s.into()))
|
||||
}
|
||||
|
||||
/// Diagnostic registration options.
|
||||
///
|
||||
/// @since 3.17.0
|
||||
|
@ -81,7 +99,13 @@ pub struct DocumentDiagnosticParams {
|
|||
pub text_document: TextDocumentIdentifier,
|
||||
|
||||
/// The additional identifier provided during registration.
|
||||
pub identifier: Option<String>,
|
||||
#[serde(
|
||||
default,
|
||||
skip_serializing_if = "Option::is_none",
|
||||
serialize_with = "serialize_option_arc_str",
|
||||
deserialize_with = "deserialize_option_arc_str"
|
||||
)]
|
||||
pub identifier: Option<Arc<str>>,
|
||||
|
||||
/// The result ID of a previous response if provided.
|
||||
pub previous_result_id: Option<String>,
|
||||
|
|
|
@ -740,8 +740,10 @@ impl Application {
|
|||
log::error!("Discarding publishDiagnostic notification sent by an uninitialized server: {}", language_server.name());
|
||||
return;
|
||||
}
|
||||
let provider =
|
||||
helix_core::diagnostic::DiagnosticProvider::Lsp { server_id };
|
||||
let provider = helix_core::diagnostic::DiagnosticProvider::Lsp {
|
||||
server_id,
|
||||
identifier: None,
|
||||
};
|
||||
self.editor.handle_lsp_diagnostics(
|
||||
&provider,
|
||||
uri,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue