Skip to content

Commit

Permalink
lsp: store and use previous result of document diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
vitallium committed Oct 15, 2024
1 parent e83fd76 commit 5f35960
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 16 deletions.
52 changes: 39 additions & 13 deletions crates/project/src/lsp_command.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
mod signature_help;

use crate::{
lsp_store::LspStore, CodeAction, CoreCompletion, DocumentHighlight, Hover, HoverBlock,
HoverBlockKind, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayHintLabelPartTooltip,
InlayHintTooltip, Location, LocationLink, MarkupContent, ProjectTransaction, ResolveState,
lsp_store::{LanguageServerState, LspStore},
CodeAction, CoreCompletion, DocumentHighlight, Hover, HoverBlock, HoverBlockKind, InlayHint,
InlayHintLabel, InlayHintLabelPart, InlayHintLabelPartTooltip, InlayHintTooltip, Location,
LocationLink, MarkupContent, ProjectTransaction, ResolveState,
};
use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
Expand Down Expand Up @@ -183,7 +184,8 @@ pub(crate) struct LinkedEditingRange {

#[derive(Debug)]
pub(crate) struct GetDocumentDiagnostics {
// pub previous_result_id: Option<String>,
pub language_server_id: LanguageServerId,
pub previous_result_id: Option<String>,
}

#[async_trait(?Send)]
Expand Down Expand Up @@ -3059,7 +3061,7 @@ impl LspCommand for GetDocumentDiagnostics {
uri: lsp::Url::from_file_path(path).unwrap(),
},
identifier,
previous_result_id: None,
previous_result_id: self.previous_result_id.clone(),
partial_result_params: Default::default(),
work_done_progress_params: Default::default(),
}
Expand All @@ -3068,16 +3070,28 @@ impl LspCommand for GetDocumentDiagnostics {
async fn response_from_lsp(
self,
message: lsp::DocumentDiagnosticReportResult,
_: Model<LspStore>,
lsp_store: Model<LspStore>,
_: Model<Buffer>,
_server_id: LanguageServerId,
_: AsyncAppContext,
language_server_id: LanguageServerId,
mut cx: AsyncAppContext,
) -> Result<Vec<Diagnostic>> {
match message {
lsp::DocumentDiagnosticReportResult::Report(report) => match report {
lsp::DocumentDiagnosticReport::Full(report) => {
// TODO: Handle related_documents in the report
// TODO: Store the result in the adapter?
let previous_result_id =
report.full_document_diagnostic_report.result_id.clone();
lsp_store.update(&mut cx, |store, _| {
if let Some(LanguageServerState::Running {
previous_document_diagnostic_result_id,
..
}) = store.as_local_mut().and_then(|local_store| {
local_store.language_servers.get_mut(&language_server_id)
}) {
*previous_document_diagnostic_result_id = previous_result_id;
}
})?;

Ok(report.full_document_diagnostic_report.items.clone())
}
lsp::DocumentDiagnosticReport::Unchanged(_) => {
Expand All @@ -3094,18 +3108,30 @@ impl LspCommand for GetDocumentDiagnostics {
proto::GetDocumentDiagnostics {
project_id,
buffer_id: buffer.remote_id().into(),
language_server_id: self.language_server_id.to_proto(),
version: serialize_version(&buffer.version()),
}
}

async fn from_proto(
_: proto::GetDocumentDiagnostics,
_: Model<LspStore>,
message: proto::GetDocumentDiagnostics,
lsp_store: Model<LspStore>,
_: Model<Buffer>,
_: AsyncAppContext,
mut cx: AsyncAppContext,
) -> Result<Self> {
let language_server_adapter = lsp_store
.update(&mut cx, |lsp_store, _| {
lsp_store.language_server_adapter_for_id(LanguageServerId::from_proto(
message.language_server_id,
))
})?
.ok_or_else(|| anyhow!("no such language server"))?;

Ok(Self {
// previous_result_id: None,
language_server_id: LanguageServerId::from_proto(message.language_server_id),
previous_result_id: language_server_adapter
.previous_document_diagnostic_result_id
.clone(),
})
}

Expand Down
15 changes: 14 additions & 1 deletion crates/project/src/lsp_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2969,10 +2969,21 @@ impl LspStore {

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 {},
GetDocumentDiagnostics {
language_server_id,
previous_result_id,
},
cx,
);

Expand Down Expand Up @@ -6431,6 +6442,7 @@ impl LspStore {
language: language.clone(),
server: language_server.clone(),
simulate_disk_based_diagnostics_completion: None,
previous_document_diagnostic_result_id: None,
},
);
}
Expand Down Expand Up @@ -7431,6 +7443,7 @@ pub enum LanguageServerState {
adapter: Arc<CachedLspAdapter>,
server: Arc<LanguageServer>,
simulate_disk_based_diagnostics_completion: Option<Task<()>>,
previous_document_diagnostic_result_id: Option<String>,
},
}

Expand Down
5 changes: 3 additions & 2 deletions crates/proto/proto/zed.proto
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ message Envelope {
RemoveWorktree remove_worktree = 258;

LanguageServerLog language_server_log = 260;

GetDocumentDiagnostics get_document_diagnostics = 261;
GetDocumentDiagnosticsResponse get_document_diagnostics_response = 262; // current max
}
Expand Down Expand Up @@ -2494,7 +2494,8 @@ message RemoveWorktree {
message GetDocumentDiagnostics {
uint64 project_id = 1;
uint64 buffer_id = 2;
repeated VectorClockEntry version = 3;
uint64 language_server_id = 3;
repeated VectorClockEntry version = 4;
}
message GetDocumentDiagnosticsResponse {
string result_id = 1;
Expand Down

0 comments on commit 5f35960

Please sign in to comment.