Use the entire ProjectPath to find open buffer for an LSP diagnostic
Previously, we would only compare the path relative to the worktree root, which would cause Zed to sometimes update diagnostics on the wrong buffer. This manifested in the project diagnostics not showing those errors/warnings while the status bar and the tab title displayed a summary with errors/warnings. This commit simply uses `Project::get_open_buffer` which correctly locates a buffer with the given project path.
This commit is contained in:
+119
-12
@@ -1961,19 +1961,10 @@ impl Project {
|
||||
worktree_id: worktree.read(cx).id(),
|
||||
path: relative_path.into(),
|
||||
};
|
||||
|
||||
for buffer in self.opened_buffers.values() {
|
||||
if let Some(buffer) = buffer.upgrade(cx) {
|
||||
if buffer
|
||||
.read(cx)
|
||||
.file()
|
||||
.map_or(false, |file| *file.path() == project_path.path)
|
||||
{
|
||||
self.update_buffer_diagnostics(&buffer, diagnostics.clone(), version, cx)?;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(buffer) = self.get_open_buffer(&project_path, cx) {
|
||||
self.update_buffer_diagnostics(&buffer, diagnostics.clone(), version, cx)?;
|
||||
}
|
||||
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
worktree
|
||||
.as_local_mut()
|
||||
@@ -5347,6 +5338,122 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_single_file_worktrees_diagnostics(cx: &mut gpui::TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
|
||||
let fs = FakeFs::new(cx.background());
|
||||
fs.insert_tree(
|
||||
"/dir",
|
||||
json!({
|
||||
"a.rs": "let a = 1;",
|
||||
"b.rs": "let b = 2;"
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs, cx);
|
||||
let worktree_a_id = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_local_worktree("/dir/a.rs", true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.0
|
||||
.read_with(cx, |tree, _| tree.id());
|
||||
let worktree_b_id = project
|
||||
.update(cx, |project, cx| {
|
||||
project.find_or_create_local_worktree("/dir/b.rs", true, cx)
|
||||
})
|
||||
.await
|
||||
.unwrap()
|
||||
.0
|
||||
.read_with(cx, |tree, _| tree.id());
|
||||
|
||||
let buffer_a = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_buffer((worktree_a_id, ""), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
let buffer_b = project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_buffer((worktree_b_id, ""), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
project.update(cx, |project, cx| {
|
||||
project
|
||||
.update_diagnostics(
|
||||
lsp::PublishDiagnosticsParams {
|
||||
uri: Url::from_file_path("/dir/a.rs").unwrap(),
|
||||
version: None,
|
||||
diagnostics: vec![lsp::Diagnostic {
|
||||
range: lsp::Range::new(
|
||||
lsp::Position::new(0, 4),
|
||||
lsp::Position::new(0, 5),
|
||||
),
|
||||
severity: Some(lsp::DiagnosticSeverity::ERROR),
|
||||
message: "error 1".to_string(),
|
||||
..Default::default()
|
||||
}],
|
||||
},
|
||||
&[],
|
||||
cx,
|
||||
)
|
||||
.unwrap();
|
||||
project
|
||||
.update_diagnostics(
|
||||
lsp::PublishDiagnosticsParams {
|
||||
uri: Url::from_file_path("/dir/b.rs").unwrap(),
|
||||
version: None,
|
||||
diagnostics: vec![lsp::Diagnostic {
|
||||
range: lsp::Range::new(
|
||||
lsp::Position::new(0, 4),
|
||||
lsp::Position::new(0, 5),
|
||||
),
|
||||
severity: Some(lsp::DiagnosticSeverity::WARNING),
|
||||
message: "error 2".to_string(),
|
||||
..Default::default()
|
||||
}],
|
||||
},
|
||||
&[],
|
||||
cx,
|
||||
)
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
buffer_a.read_with(cx, |buffer, _| {
|
||||
let chunks = chunks_with_diagnostics(&buffer, 0..buffer.len());
|
||||
assert_eq!(
|
||||
chunks
|
||||
.iter()
|
||||
.map(|(s, d)| (s.as_str(), *d))
|
||||
.collect::<Vec<_>>(),
|
||||
&[
|
||||
("let ", None),
|
||||
("a", Some(DiagnosticSeverity::ERROR)),
|
||||
(" = 1;", None),
|
||||
]
|
||||
);
|
||||
});
|
||||
buffer_b.read_with(cx, |buffer, _| {
|
||||
let chunks = chunks_with_diagnostics(&buffer, 0..buffer.len());
|
||||
assert_eq!(
|
||||
chunks
|
||||
.iter()
|
||||
.map(|(s, d)| (s.as_str(), *d))
|
||||
.collect::<Vec<_>>(),
|
||||
&[
|
||||
("let ", None),
|
||||
("b", Some(DiagnosticSeverity::WARNING)),
|
||||
(" = 2;", None),
|
||||
]
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_disk_based_diagnostics_progress(cx: &mut gpui::TestAppContext) {
|
||||
cx.foreground().forbid_parking();
|
||||
|
||||
Reference in New Issue
Block a user