Support relative paths in LSP & DAP binaries (#42135)
Closes #41214 Release Notes: - Added support for relative paths in LSP and DAP binaries --------- Co-authored-by: Cole Miller <cole@zed.dev> Co-authored-by: Julia Ryan <juliaryan3.14@gmail.com>
This commit is contained in:
@@ -261,7 +261,10 @@ impl DapStore {
|
||||
.get(&adapter.name());
|
||||
let user_installed_path = dap_settings.and_then(|s| match &s.binary {
|
||||
DapBinary::Default => None,
|
||||
DapBinary::Custom(binary) => Some(PathBuf::from(binary)),
|
||||
DapBinary::Custom(binary) => {
|
||||
// if `binary` is absolute, `.join()` will keep it unmodified
|
||||
Some(worktree.read(cx).abs_path().join(PathBuf::from(binary)))
|
||||
}
|
||||
});
|
||||
let user_args = dap_settings.map(|s| s.args.clone());
|
||||
let user_env = dap_settings.map(|s| s.env.clone());
|
||||
|
||||
@@ -563,8 +563,8 @@ impl LocalLspStore {
|
||||
allow_binary_download: bool,
|
||||
cx: &mut App,
|
||||
) -> Task<Result<LanguageServerBinary>> {
|
||||
if let Some(settings) = settings.binary.as_ref()
|
||||
&& settings.path.is_some()
|
||||
if let Some(settings) = &settings.binary
|
||||
&& let Some(path) = settings.path.as_ref().map(PathBuf::from)
|
||||
{
|
||||
let settings = settings.clone();
|
||||
|
||||
@@ -573,7 +573,8 @@ impl LocalLspStore {
|
||||
env.extend(settings.env.unwrap_or_default());
|
||||
|
||||
Ok(LanguageServerBinary {
|
||||
path: PathBuf::from(&settings.path.unwrap()),
|
||||
// if `path` is absolute, `.join()` will keep it unmodified
|
||||
path: delegate.worktree_root_path().join(path),
|
||||
env: Some(env),
|
||||
arguments: settings
|
||||
.arguments
|
||||
|
||||
@@ -1208,6 +1208,73 @@ async fn test_managing_language_servers(cx: &mut gpui::TestAppContext) {
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_language_server_relative_path(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
let settings_json_contents = json!({
|
||||
"languages": {
|
||||
"Rust": {
|
||||
"language_servers": ["my_fake_lsp"]
|
||||
}
|
||||
},
|
||||
"lsp": {
|
||||
"my_fake_lsp": {
|
||||
"binary": {
|
||||
"path": path!("relative_path/to/my_fake_lsp_binary.exe").to_string(),
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
let fs = FakeFs::new(cx.executor());
|
||||
fs.insert_tree(
|
||||
path!("/the-root"),
|
||||
json!({
|
||||
".zed": {
|
||||
"settings.json": settings_json_contents.to_string(),
|
||||
},
|
||||
"relative_path": {
|
||||
"to": {
|
||||
"my_fake_lsp.exe": "",
|
||||
},
|
||||
},
|
||||
"src": {
|
||||
"main.rs": "",
|
||||
}
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
|
||||
let project = Project::test(fs.clone(), [path!("/the-root").as_ref()], cx).await;
|
||||
let language_registry = project.read_with(cx, |project, _| project.languages().clone());
|
||||
language_registry.add(rust_lang());
|
||||
|
||||
let mut fake_rust_servers = language_registry.register_fake_lsp(
|
||||
"Rust",
|
||||
FakeLspAdapter {
|
||||
name: "my_fake_lsp",
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
cx.run_until_parked();
|
||||
|
||||
// Start the language server by opening a buffer with a compatible file extension.
|
||||
project
|
||||
.update(cx, |project, cx| {
|
||||
project.open_local_buffer_with_lsp(path!("/the-root/src/main.rs"), cx)
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let lsp_path = fake_rust_servers.next().await.unwrap().binary.path;
|
||||
assert_eq!(
|
||||
lsp_path.to_string_lossy(),
|
||||
path!("/the-root/relative_path/to/my_fake_lsp_binary.exe"),
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_reporting_fs_changes_to_language_servers(cx: &mut gpui::TestAppContext) {
|
||||
init_test(cx);
|
||||
|
||||
@@ -2352,8 +2352,8 @@ impl Snapshot {
|
||||
self.entries_by_path.first()
|
||||
}
|
||||
|
||||
/// TODO: what's the difference between `root_dir` and `abs_path`?
|
||||
/// is there any? if so, document it.
|
||||
/// Returns `None` for a single file worktree, or `Some(self.abs_path())` if
|
||||
/// it is a directory.
|
||||
pub fn root_dir(&self) -> Option<Arc<Path>> {
|
||||
self.root_entry()
|
||||
.filter(|entry| entry.is_dir())
|
||||
|
||||
Reference in New Issue
Block a user