mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-24 17:28:40 +00:00
lsp: make LspDiagnostics response optional
This commit is contained in:
parent
6601140870
commit
63f7686d49
5 changed files with 105 additions and 144 deletions
|
@ -13535,11 +13535,11 @@ pub trait DiagnosticsProvider {
|
|||
buffer: &Model<Buffer>,
|
||||
position: text::Anchor,
|
||||
cx: &mut AppContext,
|
||||
) -> Task<Result<Vec<LspDiagnostics>>>;
|
||||
) -> Task<Result<Vec<Option<LspDiagnostics>>>>;
|
||||
|
||||
fn update_diagnostics(
|
||||
&self,
|
||||
diagnostics: Vec<LspDiagnostics>,
|
||||
diagnostics: Vec<Option<LspDiagnostics>>,
|
||||
cx: &mut AppContext,
|
||||
) -> Result<()>;
|
||||
}
|
||||
|
@ -13884,7 +13884,7 @@ impl DiagnosticsProvider for Model<Project> {
|
|||
buffer: &Model<Buffer>,
|
||||
position: text::Anchor,
|
||||
cx: &mut AppContext,
|
||||
) -> Task<Result<Vec<LspDiagnostics>>> {
|
||||
) -> Task<Result<Vec<Option<LspDiagnostics>>>> {
|
||||
self.update(cx, |project, cx| {
|
||||
project.document_diagnostics(buffer, position, cx)
|
||||
})
|
||||
|
@ -13892,23 +13892,27 @@ impl DiagnosticsProvider for Model<Project> {
|
|||
|
||||
fn update_diagnostics(
|
||||
&self,
|
||||
diagnostics: Vec<LspDiagnostics>,
|
||||
diagnostics: Vec<Option<LspDiagnostics>>,
|
||||
cx: &mut AppContext,
|
||||
) -> Result<()> {
|
||||
self.update(cx, |project, cx| {
|
||||
diagnostics
|
||||
.into_iter()
|
||||
.map(|diagnostic_set| {
|
||||
project.update_diagnostics(
|
||||
.iter()
|
||||
.filter_map(|diagnostic_set| match diagnostic_set {
|
||||
Some(diagnostic_set) => Some(project.update_diagnostics(
|
||||
diagnostic_set.server_id,
|
||||
lsp::PublishDiagnosticsParams {
|
||||
uri: diagnostic_set.uri.unwrap(),
|
||||
diagnostics: diagnostic_set.diagnostics.unwrap_or_else(Vec::new),
|
||||
uri: diagnostic_set.uri.as_ref().unwrap().clone(),
|
||||
diagnostics: match diagnostic_set.diagnostics.as_ref() {
|
||||
Some(diagnostics) => diagnostics.clone(),
|
||||
None => Vec::new(),
|
||||
},
|
||||
version: None,
|
||||
},
|
||||
&[],
|
||||
cx,
|
||||
)
|
||||
)),
|
||||
None => None,
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
|
|
|
@ -318,7 +318,7 @@ pub fn deserialize_operation(message: proto::Operation) -> Result<crate::Operati
|
|||
value: message.lamport_timestamp,
|
||||
},
|
||||
server_id: LanguageServerId(message.server_id as usize),
|
||||
diagnostics: Arc::from(deserialize_diagnostics(message.diagnostics)),
|
||||
diagnostics: deserialize_diagnostics(message.diagnostics),
|
||||
}
|
||||
}
|
||||
proto::operation::Variant::UpdateCompletionTriggers(message) => {
|
||||
|
@ -397,7 +397,7 @@ pub fn deserialize_selection(selection: proto::Selection) -> Option<Selection<An
|
|||
/// Deserializes a list of diagnostics from the RPC representation.
|
||||
pub fn deserialize_diagnostics(
|
||||
diagnostics: Vec<proto::Diagnostic>,
|
||||
) -> Vec<DiagnosticEntry<Anchor>> {
|
||||
) -> Arc<[DiagnosticEntry<Anchor>]> {
|
||||
diagnostics
|
||||
.into_iter()
|
||||
.filter_map(|diagnostic| {
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
lsp_store::{LocalLspStore, LspStore},
|
||||
CodeAction, CoreCompletion, DocumentHighlight, Hover, HoverBlock, HoverBlockKind, InlayHint,
|
||||
InlayHintLabel, InlayHintLabelPart, InlayHintLabelPartTooltip, InlayHintTooltip, Location,
|
||||
LocationLink, MarkupContent, ProjectTransaction, ResolveState,
|
||||
LocationLink, LspDiagnostics, MarkupContent, ProjectTransaction, ResolveState,
|
||||
};
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_trait::async_trait;
|
||||
|
@ -3161,7 +3161,7 @@ impl GetDocumentDiagnostics {
|
|||
|
||||
#[async_trait(?Send)]
|
||||
impl LspCommand for GetDocumentDiagnostics {
|
||||
type Response = LspDiagnostics;
|
||||
type Response = Option<LspDiagnostics>;
|
||||
type LspRequest = lsp::request::DocumentDiagnosticRequest;
|
||||
type ProtoRequest = proto::GetDocumentDiagnostics;
|
||||
|
||||
|
@ -3211,24 +3211,28 @@ impl LspCommand for GetDocumentDiagnostics {
|
|||
Some(lsp::Url::from_file_path(file.abs_path(cx).clone()).unwrap())
|
||||
})?;
|
||||
|
||||
if uri.is_none() {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
match message {
|
||||
lsp::DocumentDiagnosticReportResult::Report(report) => match report {
|
||||
lsp::DocumentDiagnosticReport::Full(report) => Ok(LspDiagnostics {
|
||||
lsp::DocumentDiagnosticReport::Full(report) => Ok(Some(LspDiagnostics {
|
||||
server_id,
|
||||
uri,
|
||||
diagnostics: Some(report.full_document_diagnostic_report.items.clone()),
|
||||
}),
|
||||
lsp::DocumentDiagnosticReport::Unchanged(_) => Ok(LspDiagnostics {
|
||||
})),
|
||||
lsp::DocumentDiagnosticReport::Unchanged(_) => Ok(Some(LspDiagnostics {
|
||||
server_id,
|
||||
uri,
|
||||
diagnostics: None,
|
||||
}),
|
||||
})),
|
||||
},
|
||||
lsp::DocumentDiagnosticReportResult::Partial(_) => Ok(LspDiagnostics {
|
||||
lsp::DocumentDiagnosticReportResult::Partial(_) => Ok(Some(LspDiagnostics {
|
||||
server_id,
|
||||
uri,
|
||||
diagnostics: None,
|
||||
}),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3268,19 +3272,27 @@ impl LspCommand for GetDocumentDiagnostics {
|
|||
_: &clock::Global,
|
||||
_: &mut AppContext,
|
||||
) -> proto::GetDocumentDiagnosticsResponse {
|
||||
let diagnostics = if let Some(diagnostics) = response.diagnostics {
|
||||
diagnostics
|
||||
.into_iter()
|
||||
.map(GetDocumentDiagnostics::serialize_lsp_diagnostic)
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
if let Some(response) = response {
|
||||
let diagnostics = if let Some(diagnostics) = response.diagnostics {
|
||||
diagnostics
|
||||
.into_iter()
|
||||
.map(GetDocumentDiagnostics::serialize_lsp_diagnostic)
|
||||
.collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
proto::GetDocumentDiagnosticsResponse {
|
||||
server_id: LanguageServerId::to_proto(response.server_id),
|
||||
uri: response.uri.unwrap().to_string(),
|
||||
diagnostics,
|
||||
proto::GetDocumentDiagnosticsResponse {
|
||||
server_id: LanguageServerId::to_proto(response.server_id),
|
||||
uri: response.uri.unwrap().to_string(),
|
||||
diagnostics,
|
||||
}
|
||||
} else {
|
||||
proto::GetDocumentDiagnosticsResponse {
|
||||
server_id: 0,
|
||||
uri: Default::default(),
|
||||
diagnostics: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3297,11 +3309,11 @@ impl LspCommand for GetDocumentDiagnostics {
|
|||
.map(GetDocumentDiagnostics::deserialize_lsp_diagnostic)
|
||||
.collect();
|
||||
|
||||
Ok(LspDiagnostics {
|
||||
Ok(Some(LspDiagnostics {
|
||||
server_id: LanguageServerId::from_proto(response.server_id),
|
||||
uri: Some(lsp::Url::from_str(response.uri.as_str()).unwrap()),
|
||||
diagnostics: Some(diagnostics),
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
fn buffer_id_from_proto(message: &proto::GetDocumentDiagnostics) -> Result<BufferId> {
|
||||
|
|
|
@ -4497,7 +4497,7 @@ impl LspStore {
|
|||
buffer_handle: &Model<Buffer>,
|
||||
position: Anchor,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Vec<LspDiagnostics>>> {
|
||||
) -> Task<Result<Vec<Option<LspDiagnostics>>>> {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
let buffer_id = buffer.remote_id();
|
||||
|
||||
|
@ -4933,57 +4933,6 @@ impl LspStore {
|
|||
}
|
||||
}
|
||||
|
||||
fn pull_diagnostic(
|
||||
&mut self,
|
||||
language_server_id: LanguageServerId,
|
||||
buffer_handle: Model<Buffer>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Option<()> {
|
||||
const PULL_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_millis(125);
|
||||
|
||||
let previous_result_id = match self.as_local()?.language_servers.get(&language_server_id) {
|
||||
Some(LanguageServerState::Running {
|
||||
previous_document_diagnostic_result_id,
|
||||
..
|
||||
}) => previous_document_diagnostic_result_id.clone(),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let lsp_request_task = self.request_lsp(
|
||||
buffer_handle.clone(),
|
||||
LanguageServerToQuery::Other(language_server_id),
|
||||
GetDocumentDiagnostics {
|
||||
language_server_id,
|
||||
previous_result_id,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
|
||||
let snapshot =
|
||||
self.buffer_snapshot_for_lsp_version(&buffer_handle, language_server_id, None, cx);
|
||||
|
||||
cx.spawn(move |_, mut cx| async move {
|
||||
let snapshot = snapshot?;
|
||||
|
||||
cx.background_executor()
|
||||
.timer(PULL_DIAGNOSTICS_DEBOUNCE)
|
||||
.await;
|
||||
|
||||
let diagnostics = lsp_request_task
|
||||
.await
|
||||
.context("Unable to pull document diagnostic")
|
||||
.unwrap_or_default();
|
||||
|
||||
buffer_handle.update(&mut cx, |buffer, cx| {
|
||||
let set = DiagnosticSet::from_sorted_entries(diagnostics, &snapshot);
|
||||
buffer.update_diagnostics(language_server_id, set, cx);
|
||||
})
|
||||
})
|
||||
.detach();
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn diagnostic_summary(&self, include_ignored: bool, cx: &AppContext) -> DiagnosticSummary {
|
||||
let mut summary = DiagnosticSummary::default();
|
||||
for (_, _, path_summary) in self.diagnostic_summaries(include_ignored, cx) {
|
||||
|
@ -5898,6 +5847,47 @@ impl LspStore {
|
|||
.collect(),
|
||||
})
|
||||
}
|
||||
Some(proto::multi_lsp_query::Request::GetDocumentDiagnostics(
|
||||
get_document_diagnostics,
|
||||
)) => {
|
||||
let get_document_diagnostics = GetDocumentDiagnostics::from_proto(
|
||||
get_document_diagnostics,
|
||||
this.clone(),
|
||||
buffer.clone(),
|
||||
cx.clone(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
let all_diagnostics = this
|
||||
.update(&mut cx, |project, cx| {
|
||||
project.request_multiple_lsp_locally(
|
||||
&buffer,
|
||||
Some(get_document_diagnostics.position),
|
||||
get_document_diagnostics,
|
||||
cx,
|
||||
)
|
||||
})?
|
||||
.await
|
||||
.into_iter();
|
||||
|
||||
this.update(&mut cx, |project, cx| proto::MultiLspQueryResponse {
|
||||
responses: all_diagnostics
|
||||
.map(|lsp_diagnostic| proto::LspResponse {
|
||||
response: Some(
|
||||
proto::lsp_response::Response::GetDocumentDiagnosticsResponse(
|
||||
GetDocumentDiagnostics::response_to_proto(
|
||||
lsp_diagnostic,
|
||||
project,
|
||||
sender_id,
|
||||
&buffer_version,
|
||||
cx,
|
||||
),
|
||||
),
|
||||
),
|
||||
})
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
None => anyhow::bail!("empty multi lsp query request"),
|
||||
}
|
||||
}
|
||||
|
@ -7318,63 +7308,6 @@ impl LspStore {
|
|||
.detach();
|
||||
}
|
||||
|
||||
fn pull_diagnostic(
|
||||
&mut self,
|
||||
language_server_id: LanguageServerId,
|
||||
buffer_handle: Model<Buffer>,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Option<()> {
|
||||
let buffer = buffer_handle.read(cx);
|
||||
let file = File::from_dyn(buffer.file())?;
|
||||
let abs_path = file.as_local()?.abs_path(cx);
|
||||
let uri = lsp::Url::from_file_path(abs_path).log_err()?;
|
||||
|
||||
const PULL_DIAGNOSTICS_DEBOUNCE: Duration = Duration::from_millis(125);
|
||||
|
||||
let previous_result_id = match self.as_local()?.language_servers.get(&language_server_id) {
|
||||
Some(LanguageServerState::Running {
|
||||
previous_document_diagnostic_result_id,
|
||||
..
|
||||
}) => previous_document_diagnostic_result_id.clone(),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let lsp_request_task = self.request_lsp(
|
||||
buffer_handle,
|
||||
LanguageServerToQuery::Other(language_server_id),
|
||||
GetDocumentDiagnostics {
|
||||
language_server_id,
|
||||
previous_result_id,
|
||||
},
|
||||
cx,
|
||||
);
|
||||
|
||||
cx.spawn(move |this, mut cx| async move {
|
||||
cx.background_executor()
|
||||
.timer(PULL_DIAGNOSTICS_DEBOUNCE)
|
||||
.await;
|
||||
|
||||
let diagnostics = lsp_request_task.await;
|
||||
this.update(&mut cx, |this, cx| {
|
||||
this.update_diagnostics(
|
||||
language_server_id,
|
||||
lsp::PublishDiagnosticsParams {
|
||||
uri: uri.clone(),
|
||||
diagnostics: diagnostics.unwrap(),
|
||||
version: None,
|
||||
},
|
||||
&[],
|
||||
cx,
|
||||
)
|
||||
.log_err()
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.detach();
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn update_diagnostics(
|
||||
&mut self,
|
||||
language_server_id: LanguageServerId,
|
||||
|
|
|
@ -3037,12 +3037,24 @@ impl Project {
|
|||
buffer_handle: &Model<Buffer>,
|
||||
position: Anchor,
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Task<Result<Vec<LspDiagnostics>>> {
|
||||
) -> Task<Result<Vec<Option<LspDiagnostics>>>> {
|
||||
self.lsp_store.update(cx, |lsp_store, cx| {
|
||||
lsp_store.document_diagnostic(buffer_handle, position, cx)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn update_diagnostics(
|
||||
&mut self,
|
||||
language_server_id: LanguageServerId,
|
||||
params: lsp::PublishDiagnosticsParams,
|
||||
disk_based_sources: &[String],
|
||||
cx: &mut ModelContext<Self>,
|
||||
) -> Result<(), anyhow::Error> {
|
||||
self.lsp_store.update(cx, |lsp_store, cx| {
|
||||
lsp_store.update_diagnostics(language_server_id, params, disk_based_sources, cx)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn search(
|
||||
&mut self,
|
||||
query: SearchQuery,
|
||||
|
|
Loading…
Reference in a new issue