Files
oak-gpui/crates/extension_api/src/extension_api.rs
T
Max Brunsfeld 51ebe0eb01 Allow wasm extensions to do arbitrary file I/O in their own directory to install language servers (#9043)
This PR provides WASM extensions with write access to their own specific
working directory under the Zed `extensions` dir. This directory is set
as the extensions `current_dir` when they run. Extensions can return
relative paths from the `Extension::language_server_command` method, and
those relative paths will be interpreted relative to this working dir.

With this functionality, most language servers that we currently build
into zed can be installed using extensions.

Release Notes:

- N/A
2024-03-08 08:49:27 -08:00

64 lines
1.6 KiB
Rust

pub struct Guest;
pub use wit::*;
pub type Result<T, E = String> = core::result::Result<T, E>;
pub trait Extension: Send + Sync {
fn new() -> Self
where
Self: Sized;
fn language_server_command(
&mut self,
config: wit::LanguageServerConfig,
worktree: &wit::Worktree,
) -> Result<Command>;
}
#[macro_export]
macro_rules! register_extension {
($extension_type:ty) => {
#[export_name = "init-extension"]
pub extern "C" fn __init_extension() {
std::env::set_current_dir(std::env::var("PWD").unwrap()).unwrap();
zed_extension_api::register_extension(|| {
Box::new(<$extension_type as zed_extension_api::Extension>::new())
});
}
};
}
#[doc(hidden)]
pub fn register_extension(build_extension: fn() -> Box<dyn Extension>) {
unsafe { EXTENSION = Some((build_extension)()) }
}
fn extension() -> &'static mut dyn Extension {
unsafe { EXTENSION.as_deref_mut().unwrap() }
}
static mut EXTENSION: Option<Box<dyn Extension>> = None;
#[cfg(target_arch = "wasm32")]
#[link_section = "zed:api-version"]
#[doc(hidden)]
pub static ZED_API_VERSION: [u8; 6] = *include_bytes!(concat!(env!("OUT_DIR"), "/version_bytes"));
mod wit {
wit_bindgen::generate!({
exports: { world: super::Component },
skip: ["init-extension"]
});
}
struct Component;
impl wit::Guest for Component {
fn language_server_command(
config: wit::LanguageServerConfig,
worktree: &wit::Worktree,
) -> Result<wit::Command> {
extension().language_server_command(config, worktree)
}
}