Pull diagnostics
This commit is contained in:
parent
35575b0b0f
commit
d5c6f805cf
13 changed files with 295 additions and 6 deletions
|
@ -332,6 +332,7 @@ pub enum LanguageServerFeature {
|
||||||
WorkspaceSymbols,
|
WorkspaceSymbols,
|
||||||
// Symbols, use bitflags, see above?
|
// Symbols, use bitflags, see above?
|
||||||
Diagnostics,
|
Diagnostics,
|
||||||
|
PullDiagnostics,
|
||||||
RenameSymbol,
|
RenameSymbol,
|
||||||
InlayHints,
|
InlayHints,
|
||||||
}
|
}
|
||||||
|
@ -355,6 +356,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",
|
||||||
};
|
};
|
||||||
|
|
|
@ -348,6 +348,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(_))
|
||||||
|
@ -581,6 +582,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 {
|
||||||
|
@ -658,6 +662,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 {
|
||||||
|
@ -1223,6 +1231,32 @@ impl Client {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn text_document_diagnostic(
|
||||||
|
&self,
|
||||||
|
text_document: lsp::TextDocumentIdentifier,
|
||||||
|
previous_result_id: Option<String>,
|
||||||
|
) -> Option<impl Future<Output = Result<Value>>> {
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -733,6 +733,15 @@ impl Application {
|
||||||
doc.text(),
|
doc.text(),
|
||||||
language_id,
|
language_id,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if language_server
|
||||||
|
.supports_feature(syntax::LanguageServerFeature::PullDiagnostics)
|
||||||
|
{
|
||||||
|
handlers::diagnostics::pull_diagnostics_for_document(
|
||||||
|
doc,
|
||||||
|
language_server,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Notification::PublishDiagnostics(params) => {
|
Notification::PublishDiagnostics(params) => {
|
||||||
|
@ -753,6 +762,7 @@ impl Application {
|
||||||
uri,
|
uri,
|
||||||
params.version,
|
params.version,
|
||||||
params.diagnostics,
|
params.diagnostics,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Notification::ShowMessage(params) => {
|
Notification::ShowMessage(params) => {
|
||||||
|
@ -1028,6 +1038,16 @@ 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) => {
|
||||||
|
for document in self.editor.documents() {
|
||||||
|
let language_server = language_server!();
|
||||||
|
handlers::diagnostics::pull_diagnostics_for_document(
|
||||||
|
document,
|
||||||
|
language_server,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(serde_json::Value::Null)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let language_server = language_server!();
|
let language_server = language_server!();
|
||||||
|
|
|
@ -916,6 +916,10 @@ fn goto_buffer(editor: &mut Editor, direction: Direction, count: usize) {
|
||||||
|
|
||||||
let id = *id;
|
let id = *id;
|
||||||
|
|
||||||
|
if let Some(doc) = editor.document(id) {
|
||||||
|
helix_event::dispatch(helix_view::events::DocumentDidOpen { doc });
|
||||||
|
};
|
||||||
|
|
||||||
editor.switch(id, Action::Replace);
|
editor.switch(id, Action::Replace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use helix_event::{events, register_event};
|
use helix_event::{events, register_event};
|
||||||
use helix_view::document::Mode;
|
use helix_view::document::Mode;
|
||||||
use helix_view::events::{
|
use helix_view::events::{
|
||||||
DiagnosticsDidChange, DocumentDidChange, DocumentFocusLost, SelectionDidChange,
|
DiagnosticsDidChange, DocumentDidChange, DocumentDidOpen, DocumentFocusLost, SelectionDidChange,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::commands;
|
use crate::commands;
|
||||||
|
@ -18,6 +18,7 @@ pub fn register() {
|
||||||
register_event::<PostInsertChar>();
|
register_event::<PostInsertChar>();
|
||||||
register_event::<PostCommand>();
|
register_event::<PostCommand>();
|
||||||
register_event::<DocumentDidChange>();
|
register_event::<DocumentDidChange>();
|
||||||
|
register_event::<DocumentDidOpen>();
|
||||||
register_event::<DocumentFocusLost>();
|
register_event::<DocumentFocusLost>();
|
||||||
register_event::<SelectionDidChange>();
|
register_event::<SelectionDidChange>();
|
||||||
register_event::<DiagnosticsDidChange>();
|
register_event::<DiagnosticsDidChange>();
|
||||||
|
|
|
@ -6,13 +6,14 @@ 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::Handlers;
|
pub use helix_view::handlers::Handlers;
|
||||||
|
|
||||||
mod auto_save;
|
mod auto_save;
|
||||||
pub mod completion;
|
pub mod completion;
|
||||||
mod diagnostics;
|
pub mod diagnostics;
|
||||||
mod signature_help;
|
mod signature_help;
|
||||||
mod snippet;
|
mod snippet;
|
||||||
|
|
||||||
|
@ -22,11 +23,13 @@ pub fn setup(config: Arc<ArcSwap<Config>>) -> Handlers {
|
||||||
let event_tx = completion::CompletionHandler::new(config).spawn();
|
let event_tx = completion::CompletionHandler::new(config).spawn();
|
||||||
let signature_hints = SignatureHelpHandler::new().spawn();
|
let signature_hints = SignatureHelpHandler::new().spawn();
|
||||||
let auto_save = AutoSaveHandler::new().spawn();
|
let auto_save = AutoSaveHandler::new().spawn();
|
||||||
|
let pull_diagnostics = PullDiagnosticsHandler::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),
|
||||||
signature_hints,
|
signature_hints,
|
||||||
auto_save,
|
auto_save,
|
||||||
|
pull_diagnostics,
|
||||||
};
|
};
|
||||||
|
|
||||||
completion::register_hooks(&handlers);
|
completion::register_hooks(&handlers);
|
||||||
|
|
|
@ -1,12 +1,22 @@
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use helix_core::syntax::LanguageServerFeature;
|
||||||
|
use helix_core::Uri;
|
||||||
use helix_event::{register_hook, send_blocking};
|
use helix_event::{register_hook, send_blocking};
|
||||||
|
use helix_lsp::{lsp, LanguageServerId};
|
||||||
use helix_view::document::Mode;
|
use helix_view::document::Mode;
|
||||||
use helix_view::events::DiagnosticsDidChange;
|
use helix_view::events::{DiagnosticsDidChange, DocumentDidChange, DocumentDidOpen};
|
||||||
use helix_view::handlers::diagnostics::DiagnosticEvent;
|
use helix_view::handlers::diagnostics::DiagnosticEvent;
|
||||||
|
use helix_view::handlers::lsp::PullDiagnosticsEvent;
|
||||||
use helix_view::handlers::Handlers;
|
use helix_view::handlers::Handlers;
|
||||||
|
use helix_view::{DocumentId, Editor};
|
||||||
|
use tokio::time::Instant;
|
||||||
|
|
||||||
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 +31,194 @@ pub(super) fn register_hooks(_handlers: &Handlers) {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let tx = handlers.pull_diagnostics.clone();
|
||||||
|
register_hook!(move |event: &mut DocumentDidChange<'_>| {
|
||||||
|
if event
|
||||||
|
.doc
|
||||||
|
.has_language_server_with_feature(LanguageServerFeature::PullDiagnostics)
|
||||||
|
{
|
||||||
|
let document_id = event.doc.id();
|
||||||
|
send_blocking(&tx, PullDiagnosticsEvent { document_id });
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
|
||||||
|
register_hook!(move |event: &mut DocumentDidOpen<'_>| {
|
||||||
|
if event
|
||||||
|
.doc
|
||||||
|
.has_language_server_with_feature(LanguageServerFeature::PullDiagnostics)
|
||||||
|
{
|
||||||
|
let document_id = event.doc.id();
|
||||||
|
job::dispatch_blocking(move |editor, _| {
|
||||||
|
let Some(doc) = editor.document(document_id) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let language_servers =
|
||||||
|
doc.language_servers_with_feature(LanguageServerFeature::PullDiagnostics);
|
||||||
|
|
||||||
|
for language_server in language_servers {
|
||||||
|
pull_diagnostics_for_document(doc, language_server);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub(super) struct PullDiagnosticsHandler {
|
||||||
|
document_ids: HashSet<DocumentId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PullDiagnosticsHandler {
|
||||||
|
pub fn new() -> PullDiagnosticsHandler {
|
||||||
|
PullDiagnosticsHandler {
|
||||||
|
document_ids: [].into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl helix_event::AsyncHook for PullDiagnosticsHandler {
|
||||||
|
type Event = PullDiagnosticsEvent;
|
||||||
|
|
||||||
|
fn handle_event(
|
||||||
|
&mut self,
|
||||||
|
event: Self::Event,
|
||||||
|
existing_debounce: Option<tokio::time::Instant>,
|
||||||
|
) -> Option<tokio::time::Instant> {
|
||||||
|
if existing_debounce.is_none() {
|
||||||
|
dispatch_pull_diagnostic_for_document(event.document_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.document_ids.insert(event.document_id);
|
||||||
|
Some(Instant::now() + Duration::from_millis(500))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn finish_debounce(&mut self) {
|
||||||
|
for document_id in self.document_ids.clone() {
|
||||||
|
dispatch_pull_diagnostic_for_document(document_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch_pull_diagnostic_for_document(document_id: DocumentId) {
|
||||||
|
job::dispatch_blocking(move |editor, _| {
|
||||||
|
let Some(doc) = editor.document(document_id) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let language_servers =
|
||||||
|
doc.language_servers_with_feature(LanguageServerFeature::PullDiagnostics);
|
||||||
|
|
||||||
|
for language_server in language_servers {
|
||||||
|
pull_diagnostics_for_document(doc, language_server);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pull_diagnostics_for_document(
|
||||||
|
doc: &helix_view::Document,
|
||||||
|
language_server: &helix_lsp::Client,
|
||||||
|
) {
|
||||||
|
let Some(future) = language_server
|
||||||
|
.text_document_diagnostic(doc.identifier(), doc.previous_diagnostic_id.clone())
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(uri) = doc.uri() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let server_id = language_server.id();
|
||||||
|
let document_id = doc.id();
|
||||||
|
|
||||||
|
tokio::spawn(async move {
|
||||||
|
match future.await {
|
||||||
|
Ok(res) => {
|
||||||
|
job::dispatch(move |editor, _| {
|
||||||
|
let response = match serde_json::from_value(res) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
handle_pull_diagnostics_response(editor, response, server_id, uri, document_id)
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
Err(err) => log::error!("Pull diagnostic request failed: {err}"),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_pull_diagnostics_response(
|
||||||
|
editor: &mut Editor,
|
||||||
|
response: lsp::DocumentDiagnosticReport,
|
||||||
|
server_id: LanguageServerId,
|
||||||
|
uri: Uri,
|
||||||
|
document_id: DocumentId,
|
||||||
|
) {
|
||||||
|
let Some(doc) = editor.document_mut(document_id) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
match response {
|
||||||
|
lsp::DocumentDiagnosticReport::Full(report) => {
|
||||||
|
// Diagnostic for requested file
|
||||||
|
editor.handle_lsp_diagnostics(
|
||||||
|
server_id,
|
||||||
|
uri,
|
||||||
|
None,
|
||||||
|
report.full_document_diagnostic_report.items,
|
||||||
|
report.full_document_diagnostic_report.result_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Diagnostic for related files
|
||||||
|
handle_document_diagnostic_report_kind(
|
||||||
|
editor,
|
||||||
|
document_id,
|
||||||
|
report.related_documents,
|
||||||
|
server_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
lsp::DocumentDiagnosticReport::Unchanged(report) => {
|
||||||
|
doc.previous_diagnostic_id =
|
||||||
|
Some(report.unchanged_document_diagnostic_report.result_id);
|
||||||
|
|
||||||
|
handle_document_diagnostic_report_kind(
|
||||||
|
editor,
|
||||||
|
document_id,
|
||||||
|
report.related_documents,
|
||||||
|
server_id,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_document_diagnostic_report_kind(
|
||||||
|
editor: &mut Editor,
|
||||||
|
document_id: DocumentId,
|
||||||
|
report: Option<HashMap<lsp::Url, lsp::DocumentDiagnosticReportKind>>,
|
||||||
|
server_id: LanguageServerId,
|
||||||
|
) {
|
||||||
|
for (url, report) in report.into_iter().flatten() {
|
||||||
|
match report {
|
||||||
|
lsp::DocumentDiagnosticReportKind::Full(report) => {
|
||||||
|
let Ok(uri) = Uri::try_from(url) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
editor.handle_lsp_diagnostics(server_id, uri, None, report.items, report.result_id);
|
||||||
|
}
|
||||||
|
lsp::DocumentDiagnosticReportKind::Unchanged(report) => {
|
||||||
|
let Some(doc) = editor.document_mut(document_id) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
doc.previous_diagnostic_id = Some(report.result_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,8 @@ pub struct Document {
|
||||||
pub focused_at: std::time::Instant,
|
pub focused_at: std::time::Instant,
|
||||||
|
|
||||||
pub readonly: bool,
|
pub readonly: bool,
|
||||||
|
|
||||||
|
pub previous_diagnostic_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inlay hints for a single `(Document, View)` combo.
|
/// Inlay hints for a single `(Document, View)` combo.
|
||||||
|
@ -698,6 +700,7 @@ impl Document {
|
||||||
focused_at: std::time::Instant::now(),
|
focused_at: std::time::Instant::now(),
|
||||||
readonly: false,
|
readonly: false,
|
||||||
jump_labels: HashMap::new(),
|
jump_labels: HashMap::new(),
|
||||||
|
previous_diagnostic_id: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2174,6 +2177,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)]
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
||||||
document::{
|
document::{
|
||||||
DocumentOpenError, DocumentSavedEventFuture, DocumentSavedEventResult, Mode, SavePoint,
|
DocumentOpenError, DocumentSavedEventFuture, DocumentSavedEventResult, Mode, SavePoint,
|
||||||
},
|
},
|
||||||
events::DocumentFocusLost,
|
events::{DocumentDidOpen, DocumentFocusLost},
|
||||||
graphics::{CursorKind, Rect},
|
graphics::{CursorKind, Rect},
|
||||||
handlers::Handlers,
|
handlers::Handlers,
|
||||||
info::Info,
|
info::Info,
|
||||||
|
@ -1770,6 +1770,11 @@ impl Editor {
|
||||||
};
|
};
|
||||||
|
|
||||||
self.switch(id, action);
|
self.switch(id, action);
|
||||||
|
|
||||||
|
if let Some(doc) = self.document_mut(id) {
|
||||||
|
helix_event::dispatch(DocumentDidOpen { doc });
|
||||||
|
};
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ events! {
|
||||||
changes: &'a ChangeSet,
|
changes: &'a ChangeSet,
|
||||||
ghost_transaction: bool
|
ghost_transaction: bool
|
||||||
}
|
}
|
||||||
|
DocumentDidOpen<'a> { doc: &'a Document}
|
||||||
SelectionDidChange<'a> { doc: &'a mut Document, view: ViewId }
|
SelectionDidChange<'a> { doc: &'a mut Document, view: ViewId }
|
||||||
DiagnosticsDidChange<'a> { editor: &'a mut Editor, doc: DocumentId }
|
DiagnosticsDidChange<'a> { editor: &'a mut Editor, doc: DocumentId }
|
||||||
// called **after** a document loses focus (but not when its closed)
|
// called **after** a document loses focus (but not when its closed)
|
||||||
|
|
|
@ -21,6 +21,7 @@ pub struct Handlers {
|
||||||
pub completions: CompletionHandler,
|
pub completions: CompletionHandler,
|
||||||
pub signature_hints: Sender<lsp::SignatureHelpEvent>,
|
pub signature_hints: Sender<lsp::SignatureHelpEvent>,
|
||||||
pub auto_save: Sender<AutoSaveEvent>,
|
pub auto_save: Sender<AutoSaveEvent>,
|
||||||
|
pub pull_diagnostics: Sender<lsp::PullDiagnosticsEvent>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Handlers {
|
impl Handlers {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::fmt::Display;
|
||||||
|
|
||||||
use crate::editor::Action;
|
use crate::editor::Action;
|
||||||
use crate::events::DiagnosticsDidChange;
|
use crate::events::DiagnosticsDidChange;
|
||||||
use crate::Editor;
|
use crate::{DocumentId, Editor};
|
||||||
use helix_core::Uri;
|
use helix_core::Uri;
|
||||||
use helix_lsp::util::generate_transaction_from_edits;
|
use helix_lsp::util::generate_transaction_from_edits;
|
||||||
use helix_lsp::{lsp, LanguageServerId, OffsetEncoding};
|
use helix_lsp::{lsp, LanguageServerId, OffsetEncoding};
|
||||||
|
@ -22,6 +22,10 @@ pub enum SignatureHelpEvent {
|
||||||
RequestComplete { open: bool },
|
RequestComplete { open: bool },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct PullDiagnosticsEvent {
|
||||||
|
pub document_id: DocumentId,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ApplyEditError {
|
pub struct ApplyEditError {
|
||||||
pub kind: ApplyEditErrorKind,
|
pub kind: ApplyEditErrorKind,
|
||||||
|
@ -280,6 +284,7 @@ impl Editor {
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
version: Option<i32>,
|
version: Option<i32>,
|
||||||
mut diagnostics: Vec<lsp::Diagnostic>,
|
mut diagnostics: Vec<lsp::Diagnostic>,
|
||||||
|
report_id: Option<String>,
|
||||||
) {
|
) {
|
||||||
let doc = self
|
let doc = self
|
||||||
.documents
|
.documents
|
||||||
|
@ -357,6 +362,10 @@ impl Editor {
|
||||||
);
|
);
|
||||||
doc.replace_diagnostics(diagnostics, &unchanged_diag_sources, Some(server_id));
|
doc.replace_diagnostics(diagnostics, &unchanged_diag_sources, Some(server_id));
|
||||||
|
|
||||||
|
if report_id.is_some() {
|
||||||
|
doc.previous_diagnostic_id = report_id;
|
||||||
|
}
|
||||||
|
|
||||||
let doc = doc.id();
|
let doc = doc.id();
|
||||||
helix_event::dispatch(DiagnosticsDidChange { editor: self, doc });
|
helix_event::dispatch(DiagnosticsDidChange { editor: self, doc });
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue