This is the core change: https://github.com/zed-industries/zed/pull/26758/files#diff-044302c0d57147af17e68a0009fee3e8dcdfb4f32c27a915e70cfa80e987f765R1052 TODO: - [x] Use AsyncFn instead of Fn() -> Future in GPUI spawn methods - [x] Implement it in the whole app - [x] Implement it in the debugger - [x] Glance at the RPC crate, and see if those box future methods can be switched over. Answer: It can't directly, as you can't make an AsyncFn* into a trait object. There's ways around that, but they're all more complex than just keeping the code as is. - [ ] Fix platform specific code Release Notes: - N/A
72 lines
2.7 KiB
Rust
72 lines
2.7 KiB
Rust
use std::sync::Arc;
|
|
|
|
use extension::{Extension, ExtensionContextServerProxy, ExtensionHostProxy, ProjectDelegate};
|
|
use gpui::{App, Entity};
|
|
|
|
use crate::{ContextServerFactoryRegistry, ServerCommand};
|
|
|
|
struct ExtensionProject {
|
|
worktree_ids: Vec<u64>,
|
|
}
|
|
|
|
impl ProjectDelegate for ExtensionProject {
|
|
fn worktree_ids(&self) -> Vec<u64> {
|
|
self.worktree_ids.clone()
|
|
}
|
|
}
|
|
|
|
pub fn init(cx: &mut App) {
|
|
let proxy = ExtensionHostProxy::default_global(cx);
|
|
proxy.register_context_server_proxy(ContextServerFactoryRegistryProxy {
|
|
context_server_factory_registry: ContextServerFactoryRegistry::global(cx),
|
|
});
|
|
}
|
|
|
|
struct ContextServerFactoryRegistryProxy {
|
|
context_server_factory_registry: Entity<ContextServerFactoryRegistry>,
|
|
}
|
|
|
|
impl ExtensionContextServerProxy for ContextServerFactoryRegistryProxy {
|
|
fn register_context_server(&self, extension: Arc<dyn Extension>, id: Arc<str>, cx: &mut App) {
|
|
self.context_server_factory_registry
|
|
.update(cx, |registry, _| {
|
|
registry.register_server_factory(
|
|
id.clone(),
|
|
Arc::new({
|
|
move |project, cx| {
|
|
log::info!(
|
|
"loading command for context server {id} from extension {}",
|
|
extension.manifest().id
|
|
);
|
|
|
|
let id = id.clone();
|
|
let extension = extension.clone();
|
|
cx.spawn(async move |cx| {
|
|
let extension_project = project.update(cx, |project, cx| {
|
|
Arc::new(ExtensionProject {
|
|
worktree_ids: project
|
|
.visible_worktrees(cx)
|
|
.map(|worktree| worktree.read(cx).id().to_proto())
|
|
.collect(),
|
|
})
|
|
})?;
|
|
|
|
let command = extension
|
|
.context_server_command(id.clone(), extension_project)
|
|
.await?;
|
|
|
|
log::info!("loaded command for context server {id}: {command:?}");
|
|
|
|
Ok(ServerCommand {
|
|
path: command.command,
|
|
args: command.args,
|
|
env: Some(command.env.into_iter().collect()),
|
|
})
|
|
})
|
|
}
|
|
}),
|
|
)
|
|
});
|
|
}
|
|
}
|