From 43cbbcd586001eeefec1581958623f7b1073dedd Mon Sep 17 00:00:00 2001 From: Sofus Addington Date: Thu, 8 May 2025 08:27:33 +0200 Subject: [PATCH] Add separate event for pulling visible documents diagnostics --- helix-term/src/handlers.rs | 3 + helix-term/src/handlers/diagnostics.rs | 88 +++++++++++++++++++++----- helix-view/src/handlers.rs | 1 + helix-view/src/handlers/lsp.rs | 2 + 4 files changed, 78 insertions(+), 16 deletions(-) diff --git a/helix-term/src/handlers.rs b/helix-term/src/handlers.rs index 13f980e31..e65dde9d3 100644 --- a/helix-term/src/handlers.rs +++ b/helix-term/src/handlers.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use arc_swap::ArcSwap; +use diagnostics::PullAllDocumentsDiagnosticHandler; use helix_event::AsyncHook; use crate::config::Config; @@ -28,6 +29,7 @@ pub fn setup(config: Arc>) -> Handlers { let auto_save = AutoSaveHandler::new().spawn(); let document_colors = DocumentColorsHandler::default().spawn(); let pull_diagnostics = PullDiagnosticsHandler::new().spawn(); + let pull_all_documents_diagnostics = PullAllDocumentsDiagnosticHandler::new().spawn(); let handlers = Handlers { completions: helix_view::handlers::completion::CompletionHandler::new(event_tx), @@ -35,6 +37,7 @@ pub fn setup(config: Arc>) -> Handlers { auto_save, document_colors, pull_diagnostics, + pull_all_documents_diagnostics, }; helix_view::handlers::register_hooks(&handlers); diff --git a/helix-term/src/handlers/diagnostics.rs b/helix-term/src/handlers/diagnostics.rs index 848723e5e..3a148ffc6 100644 --- a/helix-term/src/handlers/diagnostics.rs +++ b/helix-term/src/handlers/diagnostics.rs @@ -1,3 +1,4 @@ +use std::collections::HashSet; use std::time::Duration; use tokio::time::Instant; @@ -11,7 +12,7 @@ use helix_view::events::{ DiagnosticsDidChange, DocumentDidChange, DocumentDidOpen, LanguageServerInitialized, }; use helix_view::handlers::diagnostics::DiagnosticEvent; -use helix_view::handlers::lsp::PullDiagnosticsEvent; +use helix_view::handlers::lsp::{PullAllDocumentsDiagnosticsEvent, PullDiagnosticsEvent}; use helix_view::handlers::Handlers; use helix_view::{DocumentId, Editor}; @@ -35,6 +36,7 @@ pub(super) fn register_hooks(handlers: &Handlers) { }); 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 @@ -42,6 +44,7 @@ pub(super) fn register_hooks(handlers: &Handlers) { { let document_id = event.doc.id(); send_blocking(&tx, PullDiagnosticsEvent { document_id }); + send_blocking(&tx_all_documents, PullAllDocumentsDiagnosticsEvent {}); } Ok(()) }); @@ -74,11 +77,15 @@ pub(super) fn register_hooks(handlers: &Handlers) { } #[derive(Debug)] -pub(super) struct PullDiagnosticsHandler {} +pub(super) struct PullDiagnosticsHandler { + document_ids: HashSet, +} impl PullDiagnosticsHandler { pub fn new() -> Self { - PullDiagnosticsHandler {} + PullDiagnosticsHandler { + document_ids: Default::default(), + } } } @@ -87,31 +94,80 @@ impl helix_event::AsyncHook for PullDiagnosticsHandler { fn handle_event( &mut self, - _event: Self::Event, + event: Self::Event, _timeout: Option, ) -> Option { + self.document_ids.insert(event.document_id); Some(Instant::now() + Duration::from_millis(125)) } fn finish_debounce(&mut self) { - dispatch_pull_diagnostic_for_open_documents(); + let document_ids = self.document_ids.clone(); + job::dispatch_blocking(move |editor, _| { + for document_id in document_ids { + let document = editor.document(document_id); + + let Some(document) = document else { + return; + }; + + let language_servers = document + .language_servers_with_feature(LanguageServerFeature::PullDiagnostics) + .filter(|ls| ls.is_initialized()); + + for language_server in language_servers { + pull_diagnostics_for_document(document, language_server); + } + } + }) } } -fn dispatch_pull_diagnostic_for_open_documents() { - job::dispatch_blocking(move |editor, _| { - let documents = editor.documents.values(); +#[derive(Debug)] +pub(super) struct PullAllDocumentsDiagnosticHandler {} - for document in documents { - let language_servers = document - .language_servers_with_feature(LanguageServerFeature::PullDiagnostics) - .filter(|ls| ls.is_initialized()); +impl PullAllDocumentsDiagnosticHandler { + pub fn new() -> Self { + PullAllDocumentsDiagnosticHandler {} + } +} - for language_server in language_servers { - pull_diagnostics_for_document(document, language_server); +impl helix_event::AsyncHook for PullAllDocumentsDiagnosticHandler { + type Event = PullAllDocumentsDiagnosticsEvent; + + fn handle_event( + &mut self, + _event: Self::Event, + _timeout: Option, + ) -> Option { + Some(Instant::now() + Duration::from_millis(500)) + } + + fn finish_debounce(&mut self) { + job::dispatch_blocking(move |editor, _| { + for document in editor.documents.values() { + let language_servers = document + .language_servers_with_feature(LanguageServerFeature::PullDiagnostics) + .filter(|ls| ls.is_initialized()) + .filter(|ls| { + ls.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 + } + }, + ) + }); + + for language_server in language_servers { + pull_diagnostics_for_document(document, language_server); + } } - } - }) + }) + } } pub fn pull_diagnostics_for_document( diff --git a/helix-view/src/handlers.rs b/helix-view/src/handlers.rs index 6563c2094..57238f0af 100644 --- a/helix-view/src/handlers.rs +++ b/helix-view/src/handlers.rs @@ -23,6 +23,7 @@ pub struct Handlers { pub auto_save: Sender, pub document_colors: Sender, pub pull_diagnostics: Sender, + pub pull_all_documents_diagnostics: Sender, } impl Handlers { diff --git a/helix-view/src/handlers/lsp.rs b/helix-view/src/handlers/lsp.rs index 073d9581b..84ba31183 100644 --- a/helix-view/src/handlers/lsp.rs +++ b/helix-view/src/handlers/lsp.rs @@ -34,6 +34,8 @@ pub struct PullDiagnosticsEvent { pub document_id: DocumentId, } +pub struct PullAllDocumentsDiagnosticsEvent {} + #[derive(Debug)] pub struct ApplyEditError { pub kind: ApplyEditErrorKind,