Fix remote clients unable to query custom, lsp_ext, commands (#27775)

Closes https://github.com/zed-industries/zed/issues/20583
Closes https://github.com/zed-industries/zed/issues/27133

A preparation for rust-analyzer's LSP tasks fetching, ensures all remote
clients are able to query custom, lsp_ext, commands.

Release Notes:

- Fixed remote clients unable to query custom, lsp_ext, commands
This commit is contained in:
Kirill Bulatov 2025-03-31 19:13:09 +03:00 committed by GitHub
parent c8a9a74e6a
commit e1e8c1786e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 430 additions and 140 deletions

View file

@ -316,6 +316,14 @@ impl Server {
.add_request_handler(forward_read_only_project_request::<proto::GitGetBranches>)
.add_request_handler(forward_read_only_project_request::<proto::OpenUnstagedDiff>)
.add_request_handler(forward_read_only_project_request::<proto::OpenUncommittedDiff>)
.add_request_handler(forward_read_only_project_request::<proto::LspExtExpandMacro>)
.add_request_handler(forward_read_only_project_request::<proto::LspExtOpenDocs>)
.add_request_handler(
forward_read_only_project_request::<proto::LspExtSwitchSourceHeader>,
)
.add_request_handler(
forward_read_only_project_request::<proto::LanguageServerIdForName>,
)
.add_request_handler(
forward_mutating_project_request::<proto::RegisterBufferWithLanguageServers>,
)

View file

@ -5,10 +5,13 @@ use crate::{
use call::ActiveCall;
use editor::{
actions::{
ConfirmCodeAction, ConfirmCompletion, ConfirmRename, ContextMenuFirst, Redo, Rename,
ToggleCodeActions, Undo,
ConfirmCodeAction, ConfirmCompletion, ConfirmRename, ContextMenuFirst,
ExpandMacroRecursively, Redo, Rename, ToggleCodeActions, Undo,
},
test::{
editor_test_context::{AssertionContextManager, EditorTestContext},
expand_macro_recursively,
},
test::editor_test_context::{AssertionContextManager, EditorTestContext},
Editor, RowInfo,
};
use fs::Fs;
@ -20,6 +23,10 @@ use language::{
FakeLspAdapter,
};
use project::{
lsp_store::{
lsp_ext_command::{ExpandedMacro, LspExpandMacro},
rust_analyzer_ext::RUST_ANALYZER_NAME,
},
project_settings::{InlineBlameSettings, ProjectSettings},
ProjectPath, SERVER_PROGRESS_THROTTLE_TIMEOUT,
};
@ -2619,6 +2626,147 @@ async fn test_add_breakpoints(cx_a: &mut TestAppContext, cx_b: &mut TestAppConte
assert_eq!(breakpoints_a, breakpoints_b);
}
#[gpui::test]
async fn test_client_can_query_lsp_ext(cx_a: &mut TestAppContext, cx_b: &mut TestAppContext) {
let mut server = TestServer::start(cx_a.executor()).await;
let client_a = server.create_client(cx_a, "user_a").await;
let client_b = server.create_client(cx_b, "user_b").await;
server
.create_room(&mut [(&client_a, cx_a), (&client_b, cx_b)])
.await;
let active_call_a = cx_a.read(ActiveCall::global);
let active_call_b = cx_b.read(ActiveCall::global);
cx_a.update(editor::init);
cx_b.update(editor::init);
client_a.language_registry().add(rust_lang());
client_b.language_registry().add(rust_lang());
let mut fake_language_servers = client_a.language_registry().register_fake_lsp(
"Rust",
FakeLspAdapter {
name: RUST_ANALYZER_NAME,
..FakeLspAdapter::default()
},
);
client_a
.fs()
.insert_tree(
path!("/a"),
json!({
"main.rs": "fn main() {}",
}),
)
.await;
let (project_a, worktree_id) = client_a.build_local_project(path!("/a"), cx_a).await;
active_call_a
.update(cx_a, |call, cx| call.set_location(Some(&project_a), cx))
.await
.unwrap();
let project_id = active_call_a
.update(cx_a, |call, cx| call.share_project(project_a.clone(), cx))
.await
.unwrap();
let project_b = client_b.join_remote_project(project_id, cx_b).await;
active_call_b
.update(cx_b, |call, cx| call.set_location(Some(&project_b), cx))
.await
.unwrap();
let (workspace_a, cx_a) = client_a.build_workspace(&project_a, cx_a);
let (workspace_b, cx_b) = client_b.build_workspace(&project_b, cx_b);
let editor_a = workspace_a
.update_in(cx_a, |workspace, window, cx| {
workspace.open_path((worktree_id, "main.rs"), None, true, window, cx)
})
.await
.unwrap()
.downcast::<Editor>()
.unwrap();
let editor_b = workspace_b
.update_in(cx_b, |workspace, window, cx| {
workspace.open_path((worktree_id, "main.rs"), None, true, window, cx)
})
.await
.unwrap()
.downcast::<Editor>()
.unwrap();
let fake_language_server = fake_language_servers.next().await.unwrap();
// host
let mut expand_request_a =
fake_language_server.set_request_handler::<LspExpandMacro, _, _>(|params, _| async move {
assert_eq!(
params.text_document.uri,
lsp::Url::from_file_path(path!("/a/main.rs")).unwrap(),
);
assert_eq!(params.position, lsp::Position::new(0, 0),);
Ok(Some(ExpandedMacro {
name: "test_macro_name".to_string(),
expansion: "test_macro_expansion on the host".to_string(),
}))
});
editor_a.update_in(cx_a, |editor, window, cx| {
expand_macro_recursively(editor, &ExpandMacroRecursively, window, cx)
});
expand_request_a.next().await.unwrap();
cx_a.run_until_parked();
workspace_a.update(cx_a, |workspace, cx| {
workspace.active_pane().update(cx, |pane, cx| {
assert_eq!(
pane.items_len(),
2,
"Should have added a macro expansion to the host's pane"
);
let new_editor = pane.active_item().unwrap().downcast::<Editor>().unwrap();
new_editor.update(cx, |editor, cx| {
assert_eq!(editor.text(cx), "test_macro_expansion on the host");
});
})
});
// client
let mut expand_request_b =
fake_language_server.set_request_handler::<LspExpandMacro, _, _>(|params, _| async move {
assert_eq!(
params.text_document.uri,
lsp::Url::from_file_path(path!("/a/main.rs")).unwrap(),
);
assert_eq!(params.position, lsp::Position::new(0, 0),);
Ok(Some(ExpandedMacro {
name: "test_macro_name".to_string(),
expansion: "test_macro_expansion on the client".to_string(),
}))
});
editor_b.update_in(cx_b, |editor, window, cx| {
expand_macro_recursively(editor, &ExpandMacroRecursively, window, cx)
});
expand_request_b.next().await.unwrap();
cx_b.run_until_parked();
workspace_b.update(cx_b, |workspace, cx| {
workspace.active_pane().update(cx, |pane, cx| {
assert_eq!(
pane.items_len(),
2,
"Should have added a macro expansion to the client's pane"
);
let new_editor = pane.active_item().unwrap().downcast::<Editor>().unwrap();
new_editor.update(cx, |editor, cx| {
assert_eq!(editor.text(cx), "test_macro_expansion on the client");
});
})
});
}
#[track_caller]
fn tab_undo_assert(
cx_a: &mut EditorTestContext,