mirror of https://github.com/helix-editor/helix
Compare commits
3 Commits
bed6268afd
...
cae5e5079f
Author | SHA1 | Date |
---|---|---|
|
cae5e5079f | |
|
4281228da3 | |
|
0831043ffa |
|
@ -268,6 +268,7 @@ pub enum LanguageServerFeature {
|
||||||
WorkspaceSymbols,
|
WorkspaceSymbols,
|
||||||
// Symbols, use bitflags, see above?
|
// Symbols, use bitflags, see above?
|
||||||
Diagnostics,
|
Diagnostics,
|
||||||
|
PullDiagnostics,
|
||||||
RenameSymbol,
|
RenameSymbol,
|
||||||
InlayHints,
|
InlayHints,
|
||||||
DocumentColors,
|
DocumentColors,
|
||||||
|
@ -292,6 +293,7 @@ impl Display for LanguageServerFeature {
|
||||||
DocumentSymbols => "document-symbols",
|
DocumentSymbols => "document-symbols",
|
||||||
WorkspaceSymbols => "workspace-symbols",
|
WorkspaceSymbols => "workspace-symbols",
|
||||||
Diagnostics => "diagnostics",
|
Diagnostics => "diagnostics",
|
||||||
|
PullDiagnostics => "pull-diagnostics",
|
||||||
RenameSymbol => "rename-symbol",
|
RenameSymbol => "rename-symbol",
|
||||||
InlayHints => "inlay-hints",
|
InlayHints => "inlay-hints",
|
||||||
DocumentColors => "document-colors",
|
DocumentColors => "document-colors",
|
||||||
|
|
|
@ -372,6 +372,7 @@ impl Client {
|
||||||
Some(OneOf::Left(true) | OneOf::Right(_))
|
Some(OneOf::Left(true) | OneOf::Right(_))
|
||||||
),
|
),
|
||||||
LanguageServerFeature::Diagnostics => true, // there's no extra server capability
|
LanguageServerFeature::Diagnostics => true, // there's no extra server capability
|
||||||
|
LanguageServerFeature::PullDiagnostics => capabilities.diagnostic_provider.is_some(),
|
||||||
LanguageServerFeature::RenameSymbol => matches!(
|
LanguageServerFeature::RenameSymbol => matches!(
|
||||||
capabilities.rename_provider,
|
capabilities.rename_provider,
|
||||||
Some(OneOf::Left(true)) | Some(OneOf::Right(_))
|
Some(OneOf::Left(true)) | Some(OneOf::Right(_))
|
||||||
|
@ -602,6 +603,9 @@ impl Client {
|
||||||
did_rename: Some(true),
|
did_rename: Some(true),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
diagnostic: Some(lsp::DiagnosticWorkspaceClientCapabilities {
|
||||||
|
refresh_support: Some(true),
|
||||||
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
text_document: Some(lsp::TextDocumentClientCapabilities {
|
text_document: Some(lsp::TextDocumentClientCapabilities {
|
||||||
|
@ -679,6 +683,10 @@ impl Client {
|
||||||
}),
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
|
diagnostic: Some(lsp::DiagnosticClientCapabilities {
|
||||||
|
dynamic_registration: Some(false),
|
||||||
|
related_document_support: Some(true),
|
||||||
|
}),
|
||||||
publish_diagnostics: Some(lsp::PublishDiagnosticsClientCapabilities {
|
publish_diagnostics: Some(lsp::PublishDiagnosticsClientCapabilities {
|
||||||
version_support: Some(true),
|
version_support: Some(true),
|
||||||
tag_support: Some(lsp::TagSupport {
|
tag_support: Some(lsp::TagSupport {
|
||||||
|
@ -1229,6 +1237,32 @@ impl Client {
|
||||||
Some(self.call::<lsp::request::RangeFormatting>(params))
|
Some(self.call::<lsp::request::RangeFormatting>(params))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn text_document_diagnostic(
|
||||||
|
&self,
|
||||||
|
text_document: lsp::TextDocumentIdentifier,
|
||||||
|
previous_result_id: Option<String>,
|
||||||
|
) -> Option<impl Future<Output = Result<lsp::DocumentDiagnosticReportResult>>> {
|
||||||
|
let capabilities = self.capabilities();
|
||||||
|
|
||||||
|
// Return early if the server does not support pull diagnostic.
|
||||||
|
let identifier = match capabilities.diagnostic_provider.as_ref()? {
|
||||||
|
lsp::DiagnosticServerCapabilities::Options(cap) => cap.identifier.clone(),
|
||||||
|
lsp::DiagnosticServerCapabilities::RegistrationOptions(cap) => {
|
||||||
|
cap.diagnostic_options.identifier.clone()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let params = lsp::DocumentDiagnosticParams {
|
||||||
|
text_document,
|
||||||
|
identifier,
|
||||||
|
previous_result_id,
|
||||||
|
work_done_progress_params: lsp::WorkDoneProgressParams::default(),
|
||||||
|
partial_result_params: lsp::PartialResultParams::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(self.call::<lsp::request::DocumentDiagnosticRequest>(params))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn text_document_document_highlight(
|
pub fn text_document_document_highlight(
|
||||||
&self,
|
&self,
|
||||||
text_document: lsp::TextDocumentIdentifier,
|
text_document: lsp::TextDocumentIdentifier,
|
||||||
|
|
|
@ -463,6 +463,7 @@ pub enum MethodCall {
|
||||||
RegisterCapability(lsp::RegistrationParams),
|
RegisterCapability(lsp::RegistrationParams),
|
||||||
UnregisterCapability(lsp::UnregistrationParams),
|
UnregisterCapability(lsp::UnregistrationParams),
|
||||||
ShowDocument(lsp::ShowDocumentParams),
|
ShowDocument(lsp::ShowDocumentParams),
|
||||||
|
WorkspaceDiagnosticRefresh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MethodCall {
|
impl MethodCall {
|
||||||
|
@ -494,6 +495,7 @@ impl MethodCall {
|
||||||
let params: lsp::ShowDocumentParams = params.parse()?;
|
let params: lsp::ShowDocumentParams = params.parse()?;
|
||||||
Self::ShowDocument(params)
|
Self::ShowDocument(params)
|
||||||
}
|
}
|
||||||
|
lsp::request::WorkspaceDiagnosticRefresh::METHOD => Self::WorkspaceDiagnosticRefresh,
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::Unhandled);
|
return Err(Error::Unhandled);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1021,6 +1021,27 @@ impl Application {
|
||||||
let result = self.handle_show_document(params, offset_encoding);
|
let result = self.handle_show_document(params, offset_encoding);
|
||||||
Ok(json!(result))
|
Ok(json!(result))
|
||||||
}
|
}
|
||||||
|
Ok(MethodCall::WorkspaceDiagnosticRefresh) => {
|
||||||
|
let language_server = language_server!().id();
|
||||||
|
|
||||||
|
let documents: Vec<_> = self
|
||||||
|
.editor
|
||||||
|
.documents
|
||||||
|
.values()
|
||||||
|
.filter(|x| x.supports_language_server(language_server))
|
||||||
|
.map(|x| x.id())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for document in documents {
|
||||||
|
handlers::diagnostics::request_document_diagnostics(
|
||||||
|
&mut self.editor,
|
||||||
|
document,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(serde_json::Value::Null)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let language_server = language_server!();
|
let language_server = language_server!();
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use arc_swap::ArcSwap;
|
use arc_swap::ArcSwap;
|
||||||
|
use diagnostics::PullAllDocumentsDiagnosticHandler;
|
||||||
use helix_event::AsyncHook;
|
use helix_event::AsyncHook;
|
||||||
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::events;
|
use crate::events;
|
||||||
use crate::handlers::auto_save::AutoSaveHandler;
|
use crate::handlers::auto_save::AutoSaveHandler;
|
||||||
|
use crate::handlers::diagnostics::PullDiagnosticsHandler;
|
||||||
use crate::handlers::signature_help::SignatureHelpHandler;
|
use crate::handlers::signature_help::SignatureHelpHandler;
|
||||||
|
|
||||||
pub use helix_view::handlers::{word_index, Handlers};
|
pub use helix_view::handlers::{word_index, Handlers};
|
||||||
|
@ -14,7 +16,7 @@ use self::document_colors::DocumentColorsHandler;
|
||||||
|
|
||||||
mod auto_save;
|
mod auto_save;
|
||||||
pub mod completion;
|
pub mod completion;
|
||||||
mod diagnostics;
|
pub mod diagnostics;
|
||||||
mod document_colors;
|
mod document_colors;
|
||||||
mod signature_help;
|
mod signature_help;
|
||||||
mod snippet;
|
mod snippet;
|
||||||
|
@ -27,6 +29,8 @@ pub fn setup(config: Arc<ArcSwap<Config>>) -> Handlers {
|
||||||
let auto_save = AutoSaveHandler::new().spawn();
|
let auto_save = AutoSaveHandler::new().spawn();
|
||||||
let document_colors = DocumentColorsHandler::default().spawn();
|
let document_colors = DocumentColorsHandler::default().spawn();
|
||||||
let word_index = word_index::Handler::spawn();
|
let word_index = word_index::Handler::spawn();
|
||||||
|
let pull_diagnostics = PullDiagnosticsHandler::new().spawn();
|
||||||
|
let pull_all_documents_diagnostics = PullAllDocumentsDiagnosticHandler::new().spawn();
|
||||||
|
|
||||||
let handlers = Handlers {
|
let handlers = Handlers {
|
||||||
completions: helix_view::handlers::completion::CompletionHandler::new(event_tx),
|
completions: helix_view::handlers::completion::CompletionHandler::new(event_tx),
|
||||||
|
@ -34,6 +38,8 @@ pub fn setup(config: Arc<ArcSwap<Config>>) -> Handlers {
|
||||||
auto_save,
|
auto_save,
|
||||||
document_colors,
|
document_colors,
|
||||||
word_index,
|
word_index,
|
||||||
|
pull_diagnostics,
|
||||||
|
pull_all_documents_diagnostics,
|
||||||
};
|
};
|
||||||
|
|
||||||
helix_view::handlers::register_hooks(&handlers);
|
helix_view::handlers::register_hooks(&handlers);
|
||||||
|
|
|
@ -1,12 +1,27 @@
|
||||||
use helix_event::{register_hook, send_blocking};
|
use futures_util::stream::FuturesOrdered;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::time::Duration;
|
||||||
|
use tokio::time::Instant;
|
||||||
|
use tokio_stream::StreamExt;
|
||||||
|
|
||||||
|
use helix_core::diagnostic::DiagnosticProvider;
|
||||||
|
use helix_core::syntax::config::LanguageServerFeature;
|
||||||
|
use helix_core::Uri;
|
||||||
|
use helix_event::{cancelable_future, register_hook, send_blocking};
|
||||||
|
use helix_lsp::lsp;
|
||||||
use helix_view::document::Mode;
|
use helix_view::document::Mode;
|
||||||
use helix_view::events::DiagnosticsDidChange;
|
use helix_view::events::{
|
||||||
|
DiagnosticsDidChange, DocumentDidChange, DocumentDidOpen, LanguageServerInitialized,
|
||||||
|
};
|
||||||
use helix_view::handlers::diagnostics::DiagnosticEvent;
|
use helix_view::handlers::diagnostics::DiagnosticEvent;
|
||||||
|
use helix_view::handlers::lsp::{PullAllDocumentsDiagnosticsEvent, PullDiagnosticsEvent};
|
||||||
use helix_view::handlers::Handlers;
|
use helix_view::handlers::Handlers;
|
||||||
|
use helix_view::{DocumentId, Editor};
|
||||||
|
|
||||||
use crate::events::OnModeSwitch;
|
use crate::events::OnModeSwitch;
|
||||||
|
use crate::job;
|
||||||
|
|
||||||
pub(super) fn register_hooks(_handlers: &Handlers) {
|
pub(super) fn register_hooks(handlers: &Handlers) {
|
||||||
register_hook!(move |event: &mut DiagnosticsDidChange<'_>| {
|
register_hook!(move |event: &mut DiagnosticsDidChange<'_>| {
|
||||||
if event.editor.mode != Mode::Insert {
|
if event.editor.mode != Mode::Insert {
|
||||||
for (view, _) in event.editor.tree.views_mut() {
|
for (view, _) in event.editor.tree.views_mut() {
|
||||||
|
@ -21,4 +36,264 @@ pub(super) fn register_hooks(_handlers: &Handlers) {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let tx = handlers.pull_diagnostics.clone();
|
||||||
|
let tx_all_documents = handlers.pull_all_documents_diagnostics.clone();
|
||||||
|
register_hook!(move |event: &mut DocumentDidChange<'_>| {
|
||||||
|
if event
|
||||||
|
.doc
|
||||||
|
.has_language_server_with_feature(LanguageServerFeature::PullDiagnostics)
|
||||||
|
&& !event.ghost_transaction
|
||||||
|
{
|
||||||
|
// Cancel the ongoing request, if present.
|
||||||
|
event.doc.pull_diagnostic_controller.cancel();
|
||||||
|
let document_id = event.doc.id();
|
||||||
|
send_blocking(&tx, PullDiagnosticsEvent { document_id });
|
||||||
|
send_blocking(&tx_all_documents, PullAllDocumentsDiagnosticsEvent {});
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
register_hook!(move |event: &mut DocumentDidOpen<'_>| {
|
||||||
|
request_document_diagnostics(event.editor, event.doc, false);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
register_hook!(move |event: &mut LanguageServerInitialized<'_>| {
|
||||||
|
let doc_ids: Vec<_> = event.editor.documents().map(|doc| doc.id()).collect();
|
||||||
|
|
||||||
|
for doc_id in doc_ids {
|
||||||
|
request_document_diagnostics(event.editor, doc_id, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(super) struct PullDiagnosticsHandler {
|
||||||
|
document_ids: HashSet<DocumentId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PullDiagnosticsHandler {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
PullDiagnosticsHandler {
|
||||||
|
document_ids: Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl helix_event::AsyncHook for PullDiagnosticsHandler {
|
||||||
|
type Event = PullDiagnosticsEvent;
|
||||||
|
|
||||||
|
fn handle_event(
|
||||||
|
&mut self,
|
||||||
|
event: Self::Event,
|
||||||
|
_timeout: Option<tokio::time::Instant>,
|
||||||
|
) -> Option<tokio::time::Instant> {
|
||||||
|
self.document_ids.insert(event.document_id);
|
||||||
|
Some(Instant::now() + Duration::from_millis(250))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish_debounce(&mut self) {
|
||||||
|
let document_ids = self.document_ids.clone();
|
||||||
|
job::dispatch_blocking(move |editor, _| {
|
||||||
|
for document_id in document_ids {
|
||||||
|
request_document_diagnostics(editor, document_id, false);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(super) struct PullAllDocumentsDiagnosticHandler {}
|
||||||
|
|
||||||
|
impl PullAllDocumentsDiagnosticHandler {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
PullAllDocumentsDiagnosticHandler {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl helix_event::AsyncHook for PullAllDocumentsDiagnosticHandler {
|
||||||
|
type Event = PullAllDocumentsDiagnosticsEvent;
|
||||||
|
|
||||||
|
fn handle_event(
|
||||||
|
&mut self,
|
||||||
|
_event: Self::Event,
|
||||||
|
_timeout: Option<tokio::time::Instant>,
|
||||||
|
) -> Option<tokio::time::Instant> {
|
||||||
|
Some(Instant::now() + Duration::from_secs(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish_debounce(&mut self) {
|
||||||
|
job::dispatch_blocking(move |editor, _| {
|
||||||
|
let documents: Vec<_> = editor.documents.values().map(|doc| doc.id()).collect();
|
||||||
|
|
||||||
|
for document in documents {
|
||||||
|
request_document_diagnostics(editor, document, true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn request_document_diagnostics(
|
||||||
|
editor: &mut Editor,
|
||||||
|
doc_id: DocumentId,
|
||||||
|
only_providers_with_inter_file_dependencies: bool,
|
||||||
|
) {
|
||||||
|
let Some(doc) = editor.document_mut(doc_id) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut seen_language_servers = HashSet::new();
|
||||||
|
let mut futures: FuturesOrdered<_> = doc
|
||||||
|
.language_servers_with_feature(LanguageServerFeature::PullDiagnostics)
|
||||||
|
.filter(|ls| seen_language_servers.insert(ls.id()))
|
||||||
|
.filter_map(|language_server| {
|
||||||
|
if only_providers_with_inter_file_dependencies
|
||||||
|
&& !language_server
|
||||||
|
.capabilities()
|
||||||
|
.diagnostic_provider
|
||||||
|
.as_ref()
|
||||||
|
.is_some_and(|diagnostic_provider| match diagnostic_provider {
|
||||||
|
lsp::DiagnosticServerCapabilities::Options(options) => {
|
||||||
|
options.inter_file_dependencies
|
||||||
|
}
|
||||||
|
lsp::DiagnosticServerCapabilities::RegistrationOptions(options) => {
|
||||||
|
options.diagnostic_options.inter_file_dependencies
|
||||||
|
}
|
||||||
|
})
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let future = language_server
|
||||||
|
.text_document_diagnostic(doc.identifier(), doc.previous_diagnostic_id.clone())?;
|
||||||
|
|
||||||
|
let identifier = language_server
|
||||||
|
.capabilities()
|
||||||
|
.diagnostic_provider
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|diagnostic_provider| match diagnostic_provider {
|
||||||
|
lsp::DiagnosticServerCapabilities::Options(options) => {
|
||||||
|
options.identifier.clone()
|
||||||
|
}
|
||||||
|
lsp::DiagnosticServerCapabilities::RegistrationOptions(options) => {
|
||||||
|
options.diagnostic_options.identifier.clone()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let language_server_id = language_server.id();
|
||||||
|
let provider = DiagnosticProvider::Lsp {
|
||||||
|
server_id: language_server_id,
|
||||||
|
identifier,
|
||||||
|
};
|
||||||
|
let uri = doc.uri()?;
|
||||||
|
|
||||||
|
Some(async move {
|
||||||
|
let result = future.await;
|
||||||
|
|
||||||
|
(result, provider, uri)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if futures.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
job::dispatch_blocking(move |editor, _| {
|
||||||
|
let Some(doc) = editor.document_mut(doc_id) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let cancel = doc.pull_diagnostic_controller.restart();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
match cancelable_future(futures.next(), &cancel).await {
|
||||||
|
Some(Some(future_result)) => match future_result.0 {
|
||||||
|
Ok(result) => {
|
||||||
|
job::dispatch(move |editor, _| {
|
||||||
|
handle_pull_diagnostics_response(
|
||||||
|
editor,
|
||||||
|
result,
|
||||||
|
future_result.1,
|
||||||
|
future_result.2,
|
||||||
|
doc_id,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
let parsed_cancellation_data = if let helix_lsp::Error::Rpc(error) = err
|
||||||
|
{
|
||||||
|
error.data.and_then(|data| {
|
||||||
|
serde_json::from_value::<lsp::DiagnosticServerCancellationData>(
|
||||||
|
data,
|
||||||
|
)
|
||||||
|
.ok()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log::error!("Pull diagnostic request failed: {err}");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(parsed_cancellation_data) = parsed_cancellation_data {
|
||||||
|
if parsed_cancellation_data.retrigger_request {
|
||||||
|
tokio::time::sleep(Duration::from_millis(500)).await;
|
||||||
|
|
||||||
|
job::dispatch(move |editor, _| {
|
||||||
|
request_document_diagnostics(
|
||||||
|
editor,
|
||||||
|
doc_id,
|
||||||
|
only_providers_with_inter_file_dependencies,
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Some(None) => break,
|
||||||
|
// The request was cancelled.
|
||||||
|
None => return,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_pull_diagnostics_response(
|
||||||
|
editor: &mut Editor,
|
||||||
|
result: lsp::DocumentDiagnosticReportResult,
|
||||||
|
provider: DiagnosticProvider,
|
||||||
|
uri: Uri,
|
||||||
|
document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
match result {
|
||||||
|
lsp::DocumentDiagnosticReportResult::Report(report) => {
|
||||||
|
let result_id = match report {
|
||||||
|
lsp::DocumentDiagnosticReport::Full(report) => {
|
||||||
|
editor.handle_lsp_diagnostics(
|
||||||
|
&provider,
|
||||||
|
uri,
|
||||||
|
None,
|
||||||
|
report.full_document_diagnostic_report.items,
|
||||||
|
);
|
||||||
|
|
||||||
|
report.full_document_diagnostic_report.result_id
|
||||||
|
}
|
||||||
|
lsp::DocumentDiagnosticReport::Unchanged(report) => {
|
||||||
|
Some(report.unchanged_document_diagnostic_report.result_id)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(doc) = editor.document_mut(document_id) {
|
||||||
|
doc.previous_diagnostic_id = result_id;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
lsp::DocumentDiagnosticReportResult::Partial(_) => {}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,11 +204,14 @@ pub struct Document {
|
||||||
|
|
||||||
pub readonly: bool,
|
pub readonly: bool,
|
||||||
|
|
||||||
|
pub previous_diagnostic_id: Option<String>,
|
||||||
|
|
||||||
/// Annotations for LSP document color swatches
|
/// Annotations for LSP document color swatches
|
||||||
pub color_swatches: Option<DocumentColorSwatches>,
|
pub color_swatches: Option<DocumentColorSwatches>,
|
||||||
// NOTE: ideally this would live on the handler for color swatches. This is blocked on a
|
// NOTE: ideally this would live on the handler for color swatches. This is blocked on a
|
||||||
// large refactor that would make `&mut Editor` available on the `DocumentDidChange` event.
|
// large refactor that would make `&mut Editor` available on the `DocumentDidChange` event.
|
||||||
pub color_swatch_controller: TaskController,
|
pub color_swatch_controller: TaskController,
|
||||||
|
pub pull_diagnostic_controller: TaskController,
|
||||||
|
|
||||||
// NOTE: this field should eventually go away - we should use the Editor's syn_loader instead
|
// NOTE: this field should eventually go away - we should use the Editor's syn_loader instead
|
||||||
// of storing a copy on every doc. Then we can remove the surrounding `Arc` and use the
|
// of storing a copy on every doc. Then we can remove the surrounding `Arc` and use the
|
||||||
|
@ -728,6 +731,8 @@ impl Document {
|
||||||
color_swatches: None,
|
color_swatches: None,
|
||||||
color_swatch_controller: TaskController::new(),
|
color_swatch_controller: TaskController::new(),
|
||||||
syn_loader,
|
syn_loader,
|
||||||
|
previous_diagnostic_id: None,
|
||||||
|
pull_diagnostic_controller: TaskController::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2284,6 +2289,10 @@ impl Document {
|
||||||
pub fn reset_all_inlay_hints(&mut self) {
|
pub fn reset_all_inlay_hints(&mut self) {
|
||||||
self.inlay_hints = Default::default();
|
self.inlay_hints = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn has_language_server_with_feature(&self, feature: LanguageServerFeature) -> bool {
|
||||||
|
self.language_servers_with_feature(feature).next().is_some()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|
|
@ -24,6 +24,8 @@ pub struct Handlers {
|
||||||
pub auto_save: Sender<AutoSaveEvent>,
|
pub auto_save: Sender<AutoSaveEvent>,
|
||||||
pub document_colors: Sender<lsp::DocumentColorsEvent>,
|
pub document_colors: Sender<lsp::DocumentColorsEvent>,
|
||||||
pub word_index: word_index::Handler,
|
pub word_index: word_index::Handler,
|
||||||
|
pub pull_diagnostics: Sender<lsp::PullDiagnosticsEvent>,
|
||||||
|
pub pull_all_documents_diagnostics: Sender<lsp::PullAllDocumentsDiagnosticsEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handlers {
|
impl Handlers {
|
||||||
|
|
|
@ -30,6 +30,12 @@ pub enum SignatureHelpEvent {
|
||||||
RequestComplete { open: bool },
|
RequestComplete { open: bool },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PullDiagnosticsEvent {
|
||||||
|
pub document_id: DocumentId,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PullAllDocumentsDiagnosticsEvent {}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ApplyEditError {
|
pub struct ApplyEditError {
|
||||||
pub kind: ApplyEditErrorKind,
|
pub kind: ApplyEditErrorKind,
|
||||||
|
|
Loading…
Reference in New Issue