Refactor language server startup
Avoid parallel vecs Co-Authored-By: Max Brunsfeld <max@zed.dev>
This commit is contained in:
parent
c59204c5e6
commit
9e2949e7ba
2 changed files with 325 additions and 333 deletions
|
@ -782,13 +782,14 @@ impl LanguageRegistry {
|
||||||
self.state.read().languages.iter().cloned().collect()
|
self.state.read().languages.iter().cloned().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_language_servers(
|
pub fn start_language_server(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
language: Arc<Language>,
|
language: Arc<Language>,
|
||||||
|
adapter: Arc<CachedLspAdapter>,
|
||||||
root_path: Arc<Path>,
|
root_path: Arc<Path>,
|
||||||
http_client: Arc<dyn HttpClient>,
|
http_client: Arc<dyn HttpClient>,
|
||||||
cx: &mut AppContext,
|
cx: &mut AppContext,
|
||||||
) -> Vec<PendingLanguageServer> {
|
) -> Option<PendingLanguageServer> {
|
||||||
#[cfg(any(test, feature = "test-support"))]
|
#[cfg(any(test, feature = "test-support"))]
|
||||||
if language.fake_adapter.is_some() {
|
if language.fake_adapter.is_some() {
|
||||||
let task = cx.spawn(|cx| async move {
|
let task = cx.spawn(|cx| async move {
|
||||||
|
@ -819,22 +820,15 @@ impl LanguageRegistry {
|
||||||
});
|
});
|
||||||
|
|
||||||
let server_id = post_inc(&mut self.state.write().next_language_server_id);
|
let server_id = post_inc(&mut self.state.write().next_language_server_id);
|
||||||
return vec![PendingLanguageServer { server_id, task }];
|
return Some(PendingLanguageServer { server_id, task });
|
||||||
}
|
}
|
||||||
|
|
||||||
let download_dir = self
|
let download_dir = self
|
||||||
.language_server_download_dir
|
.language_server_download_dir
|
||||||
.clone()
|
.clone()
|
||||||
.ok_or_else(|| anyhow!("language server download directory has not been assigned"))
|
.ok_or_else(|| anyhow!("language server download directory has not been assigned"))
|
||||||
.log_err();
|
.log_err()?;
|
||||||
let download_dir = match download_dir {
|
|
||||||
Some(download_dir) => download_dir,
|
|
||||||
None => return Vec::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut results = Vec::new();
|
|
||||||
|
|
||||||
for adapter in &language.adapters {
|
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
let language = language.clone();
|
let language = language.clone();
|
||||||
let http_client = http_client.clone();
|
let http_client = http_client.clone();
|
||||||
|
@ -879,10 +873,7 @@ impl LanguageRegistry {
|
||||||
Ok(server)
|
Ok(server)
|
||||||
});
|
});
|
||||||
|
|
||||||
results.push(PendingLanguageServer { server_id, task });
|
Some(PendingLanguageServer { server_id, task })
|
||||||
}
|
|
||||||
|
|
||||||
results
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn language_server_binary_statuses(
|
pub fn language_server_binary_statuses(
|
||||||
|
|
|
@ -2137,17 +2137,23 @@ impl Project {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let adapters = language.lsp_adapters();
|
for adapter in language.lsp_adapters() {
|
||||||
let language_servers = self.languages.start_language_servers(
|
let key = (worktree_id, adapter.name.clone());
|
||||||
|
if self.language_server_ids.contains_key(&key) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let pending_server = match self.languages.start_language_server(
|
||||||
language.clone(),
|
language.clone(),
|
||||||
|
adapter.clone(),
|
||||||
worktree_path.clone(),
|
worktree_path.clone(),
|
||||||
self.client.http_client(),
|
self.client.http_client(),
|
||||||
cx,
|
cx,
|
||||||
);
|
) {
|
||||||
debug_assert_eq!(adapters.len(), language_servers.len());
|
Some(pending_server) => pending_server,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
for (adapter, pending_server) in adapters.into_iter().zip(language_servers.into_iter()) {
|
|
||||||
let key = (worktree_id, adapter.name.clone());
|
|
||||||
let lsp = &cx.global::<Settings>().lsp.get(&adapter.name.0);
|
let lsp = &cx.global::<Settings>().lsp.get(&adapter.name.0);
|
||||||
let override_options = lsp.map(|s| s.initialization_options.clone()).flatten();
|
let override_options = lsp.map(|s| s.initialization_options.clone()).flatten();
|
||||||
|
|
||||||
|
@ -2160,8 +2166,8 @@ impl Project {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.language_server_ids.contains_key(&key) {
|
let server_id = pending_server.server_id;
|
||||||
let adapter = self.setup_pending_language_server(
|
let state = self.setup_pending_language_server(
|
||||||
initialization_options,
|
initialization_options,
|
||||||
pending_server,
|
pending_server,
|
||||||
adapter.clone(),
|
adapter.clone(),
|
||||||
|
@ -2169,8 +2175,8 @@ impl Project {
|
||||||
key.clone(),
|
key.clone(),
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
self.language_server_ids.insert(key.clone(), adapter);
|
self.language_servers.insert(server_id, state);
|
||||||
}
|
self.language_server_ids.insert(key.clone(), server_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2182,12 +2188,10 @@ impl Project {
|
||||||
language: Arc<Language>,
|
language: Arc<Language>,
|
||||||
key: (WorktreeId, LanguageServerName),
|
key: (WorktreeId, LanguageServerName),
|
||||||
cx: &mut ModelContext<Project>,
|
cx: &mut ModelContext<Project>,
|
||||||
) -> usize {
|
) -> LanguageServerState {
|
||||||
let server_id = pending_server.server_id;
|
let server_id = pending_server.server_id;
|
||||||
let languages = self.languages.clone();
|
let languages = self.languages.clone();
|
||||||
|
|
||||||
self.language_servers.insert(
|
|
||||||
server_id,
|
|
||||||
LanguageServerState::Starting(cx.spawn_weak(|this, mut cx| async move {
|
LanguageServerState::Starting(cx.spawn_weak(|this, mut cx| async move {
|
||||||
let workspace_config = cx.update(|cx| languages.workspace_configuration(cx)).await;
|
let workspace_config = cx.update(|cx| languages.workspace_configuration(cx)).await;
|
||||||
let language_server = pending_server.task.await.log_err()?;
|
let language_server = pending_server.task.await.log_err()?;
|
||||||
|
@ -2229,7 +2233,6 @@ impl Project {
|
||||||
move |params, mut cx| {
|
move |params, mut cx| {
|
||||||
let languages = languages.clone();
|
let languages = languages.clone();
|
||||||
async move {
|
async move {
|
||||||
dbg!(¶ms.items);
|
|
||||||
let workspace_config =
|
let workspace_config =
|
||||||
cx.update(|cx| languages.workspace_configuration(cx)).await;
|
cx.update(|cx| languages.workspace_configuration(cx)).await;
|
||||||
Ok(params
|
Ok(params
|
||||||
|
@ -2459,9 +2462,7 @@ impl Project {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
Some(language_server)
|
Some(language_server)
|
||||||
})
|
})
|
||||||
})),
|
}))
|
||||||
);
|
|
||||||
server_id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a list of all of the worktrees which no longer have a language server and the root path
|
// Returns a list of all of the worktrees which no longer have a language server and the root path
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue