Cargo.lock 🔗
@@ -6256,6 +6256,7 @@ dependencies = [
"libc",
"log",
"log-panics",
+ "lsp",
"num_cpus",
"parking_lot",
"people_panel",
Max Brunsfeld created
Cargo.lock | 1
crates/server/src/rpc.rs | 111 +++++++++++++++++++++++++++++++++++++++
crates/zed/Cargo.toml | 3 +
crates/zed/src/language.rs | 2
crates/zed/src/lib.rs | 1
5 files changed, 116 insertions(+), 2 deletions(-)
@@ -6256,6 +6256,7 @@ dependencies = [
"libc",
"log",
"log-panics",
+ "lsp",
"num_cpus",
"parking_lot",
"people_panel",
@@ -982,7 +982,8 @@ mod tests {
},
editor::{Editor, EditorSettings, Input},
fs::{FakeFs, Fs as _},
- language::LanguageRegistry,
+ language::{Diagnostic, LanguageRegistry, Point},
+ lsp,
people_panel::JoinWorktree,
project::{ProjectPath, Worktree},
workspace::{Workspace, WorkspaceParams},
@@ -1602,6 +1603,114 @@ mod tests {
.await;
}
+ #[gpui::test]
+ async fn test_collaborating_with_diagnostics(
+ mut cx_a: TestAppContext,
+ mut cx_b: TestAppContext,
+ ) {
+ cx_a.foreground().forbid_parking();
+ let lang_registry = Arc::new(LanguageRegistry::new());
+
+ let (language_server, mut fake_lsp) = lsp::LanguageServer::fake(cx_a.background()).await;
+
+ // Connect to a server as 2 clients.
+ let mut server = TestServer::start().await;
+ let (client_a, _) = server.create_client(&mut cx_a, "user_a").await;
+ let (client_b, _) = server.create_client(&mut cx_a, "user_b").await;
+
+ // Share a local worktree as client A
+ let fs = Arc::new(FakeFs::new());
+ fs.insert_tree(
+ "/a",
+ json!({
+ ".zed.toml": r#"collaborators = ["user_b"]"#,
+ "a.txt": "one two three",
+ "b.txt": "b-contents",
+ }),
+ )
+ .await;
+ let worktree_a = Worktree::open_local(
+ client_a.clone(),
+ "/a".as_ref(),
+ fs,
+ lang_registry.clone(),
+ Some(language_server),
+ &mut cx_a.to_async(),
+ )
+ .await
+ .unwrap();
+ worktree_a
+ .read_with(&cx_a, |tree, _| tree.as_local().unwrap().scan_complete())
+ .await;
+ let worktree_id = worktree_a
+ .update(&mut cx_a, |tree, cx| tree.as_local_mut().unwrap().share(cx))
+ .await
+ .unwrap();
+
+ // Simulate a language server reporting errors for a file.
+ fake_lsp
+ .notify::<lsp::notification::PublishDiagnostics>(lsp::PublishDiagnosticsParams {
+ uri: lsp::Url::from_file_path("/a/a.txt").unwrap(),
+ version: None,
+ diagnostics: vec![
+ lsp::Diagnostic {
+ severity: Some(lsp::DiagnosticSeverity::ERROR),
+ range: lsp::Range::new(lsp::Position::new(0, 0), lsp::Position::new(0, 3)),
+ message: "message 1".to_string(),
+ ..Default::default()
+ },
+ lsp::Diagnostic {
+ severity: Some(lsp::DiagnosticSeverity::WARNING),
+ range: lsp::Range::new(lsp::Position::new(0, 8), lsp::Position::new(0, 13)),
+ message: "message 2".to_string(),
+ ..Default::default()
+ },
+ ],
+ })
+ .await;
+
+ // Join the worktree as client B.
+ let worktree_b = Worktree::open_remote(
+ client_b.clone(),
+ worktree_id,
+ lang_registry.clone(),
+ &mut cx_b.to_async(),
+ )
+ .await
+ .unwrap();
+
+ // Open the file with the errors.
+ let buffer_b = cx_b
+ .background()
+ .spawn(worktree_b.update(&mut cx_b, |worktree, cx| worktree.open_buffer("a.txt", cx)))
+ .await
+ .unwrap();
+
+ buffer_b.read_with(&cx_b, |buffer, _| {
+ assert_eq!(
+ buffer
+ .diagnostics_in_range(0..buffer.len())
+ .collect::<Vec<_>>(),
+ &[
+ (
+ Point::new(0, 0)..Point::new(0, 3),
+ &Diagnostic {
+ message: "message 1".to_string(),
+ severity: lsp::DiagnosticSeverity::ERROR,
+ }
+ ),
+ (
+ Point { row: 0, column: 8 }..Point { row: 0, column: 13 },
+ &Diagnostic {
+ severity: lsp::DiagnosticSeverity::WARNING,
+ message: "message 2".to_string()
+ }
+ )
+ ]
+ );
+ });
+ }
+
#[gpui::test]
async fn test_basic_chat(mut cx_a: TestAppContext, mut cx_b: TestAppContext) {
cx_a.foreground().forbid_parking();
@@ -20,6 +20,7 @@ test-support = [
"editor/test-support",
"gpui/test-support",
"language/test-support",
+ "lsp/test-support",
"project/test-support",
"rpc/test-support",
"tempdir",
@@ -37,6 +38,7 @@ editor = { path = "../editor" }
file_finder = { path = "../file_finder" }
gpui = { path = "../gpui" }
language = { path = "../language" }
+lsp = { path = "../lsp" }
people_panel = { path = "../people_panel" }
project = { path = "../project" }
project_panel = { path = "../project_panel" }
@@ -90,6 +92,7 @@ buffer = { path = "../buffer", features = ["test-support"] }
editor = { path = "../editor", features = ["test-support"] }
gpui = { path = "../gpui", features = ["test-support"] }
language = { path = "../language", features = ["test-support"] }
+lsp = { path = "../lsp", features = ["test-support"] }
project = { path = "../project", features = ["test-support"] }
rpc = { path = "../rpc", features = ["test-support"] }
client = { path = "../client", features = ["test-support"] }
@@ -1,4 +1,4 @@
-pub use language::{Language, LanguageRegistry};
+pub use language::{Buffer, Diagnostic, Language, LanguageRegistry, Point};
use rust_embed::RustEmbed;
use std::borrow::Cow;
use std::{str, sync::Arc};
@@ -15,6 +15,7 @@ use gpui::{
platform::WindowOptions,
ModelHandle, MutableAppContext, PathPromptOptions, Task, ViewContext,
};
+pub use lsp;
use parking_lot::Mutex;
pub use people_panel;
use people_panel::PeoplePanel;