72 lines · 2.8 KB · Rust
RawDownload
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(|mut cx| async move {                                let extension_project =                                    project.update(&mut 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()),                                })                            })                        }                    }),                )            });    }}