Detailed changes
@@ -1,7 +1,7 @@
pub mod extension_builder;
mod extension_manifest;
-use std::path::Path;
+use std::path::{Path, PathBuf};
use std::sync::Arc;
use anyhow::{anyhow, bail, Context as _, Result};
@@ -11,6 +11,15 @@ use semantic_version::SemanticVersion;
pub use crate::extension_manifest::*;
+#[async_trait]
+pub trait WorktreeDelegate: Send + Sync + 'static {
+ fn id(&self) -> u64;
+ fn root_path(&self) -> String;
+ async fn read_text_file(&self, path: PathBuf) -> Result<String>;
+ async fn which(&self, binary_name: String) -> Option<String>;
+ async fn shell_env(&self) -> Vec<(String, String)>;
+}
+
pub trait KeyValueStoreDelegate: Send + Sync + 'static {
fn insert(&self, key: String, docs: String) -> Task<Result<()>>;
}
@@ -5,6 +5,7 @@ use crate::wasm_host::{
use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use collections::HashMap;
+use extension::WorktreeDelegate;
use futures::{Future, FutureExt};
use gpui::AsyncAppContext;
use language::{
@@ -18,6 +19,35 @@ use std::{any::Any, path::PathBuf, pin::Pin, sync::Arc};
use util::{maybe, ResultExt};
use wasmtime_wasi::WasiView as _;
+/// An adapter that allows an [`LspAdapterDelegate`] to be used as a [`WorktreeDelegate`].
+pub struct WorktreeDelegateAdapter(pub Arc<dyn LspAdapterDelegate>);
+
+#[async_trait]
+impl WorktreeDelegate for WorktreeDelegateAdapter {
+ fn id(&self) -> u64 {
+ self.0.worktree_id().to_proto()
+ }
+
+ fn root_path(&self) -> String {
+ self.0.worktree_root_path().to_string_lossy().to_string()
+ }
+
+ async fn read_text_file(&self, path: PathBuf) -> Result<String> {
+ self.0.read_text_file(path).await
+ }
+
+ async fn which(&self, binary_name: String) -> Option<String> {
+ self.0
+ .which(binary_name.as_ref())
+ .await
+ .map(|path| path.to_string_lossy().to_string())
+ }
+
+ async fn shell_env(&self) -> Vec<(String, String)> {
+ self.0.shell_env().await.into_iter().collect()
+ }
+}
+
pub struct ExtensionLspAdapter {
pub(crate) extension: WasmExtension,
pub(crate) language_server_id: LanguageServerName,
@@ -45,6 +75,7 @@ impl LspAdapter for ExtensionLspAdapter {
let this = self.clone();
|extension, store| {
async move {
+ let delegate = Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _;
let resource = store.data_mut().table().push(delegate)?;
let command = extension
.call_language_server_command(
@@ -166,6 +197,7 @@ impl LspAdapter for ExtensionLspAdapter {
let this = self.clone();
|extension, store| {
async move {
+ let delegate = Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _;
let resource = store.data_mut().table().push(delegate)?;
let options = extension
.call_language_server_initialization_options(
@@ -204,6 +236,7 @@ impl LspAdapter for ExtensionLspAdapter {
let this = self.clone();
|extension, store| {
async move {
+ let delegate = Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _;
let resource = store.data_mut().table().push(delegate)?;
let options = extension
.call_language_server_workspace_configuration(
@@ -3,14 +3,13 @@ mod since_v0_0_4;
mod since_v0_0_6;
mod since_v0_1_0;
mod since_v0_2_0;
-use extension::KeyValueStoreDelegate;
+use extension::{KeyValueStoreDelegate, WorktreeDelegate};
use lsp::LanguageServerName;
use release_channel::ReleaseChannel;
use since_v0_2_0 as latest;
use super::{wasm_engine, WasmState};
use anyhow::{anyhow, Context, Result};
-use language::LspAdapterDelegate;
use semantic_version::SemanticVersion;
use std::{ops::RangeInclusive, sync::Arc};
use wasmtime::{
@@ -152,7 +151,7 @@ impl Extension {
store: &mut Store<WasmState>,
language_server_id: &LanguageServerName,
config: &LanguageServerConfig,
- resource: Resource<Arc<dyn LspAdapterDelegate>>,
+ resource: Resource<Arc<dyn WorktreeDelegate>>,
) -> Result<Result<Command, String>> {
match self {
Extension::V020(ext) => {
@@ -183,7 +182,7 @@ impl Extension {
store: &mut Store<WasmState>,
language_server_id: &LanguageServerName,
config: &LanguageServerConfig,
- resource: Resource<Arc<dyn LspAdapterDelegate>>,
+ resource: Resource<Arc<dyn WorktreeDelegate>>,
) -> Result<Result<Option<String>, String>> {
match self {
Extension::V020(ext) => {
@@ -229,7 +228,7 @@ impl Extension {
&self,
store: &mut Store<WasmState>,
language_server_id: &LanguageServerName,
- resource: Resource<Arc<dyn LspAdapterDelegate>>,
+ resource: Resource<Arc<dyn WorktreeDelegate>>,
) -> Result<Result<Option<String>, String>> {
match self {
Extension::V020(ext) => {
@@ -366,7 +365,7 @@ impl Extension {
store: &mut Store<WasmState>,
command: &SlashCommand,
arguments: &[String],
- resource: Option<Resource<Arc<dyn LspAdapterDelegate>>>,
+ resource: Option<Resource<Arc<dyn WorktreeDelegate>>>,
) -> Result<Result<SlashCommandOutput, String>> {
match self {
Extension::V020(ext) => {
@@ -3,7 +3,8 @@ use crate::wasm_host::wit::since_v0_0_4;
use crate::wasm_host::WasmState;
use anyhow::Result;
use async_trait::async_trait;
-use language::{LanguageServerBinaryStatus, LspAdapterDelegate};
+use extension::WorktreeDelegate;
+use language::LanguageServerBinaryStatus;
use semantic_version::SemanticVersion;
use std::sync::{Arc, OnceLock};
use wasmtime::component::{Linker, Resource};
@@ -21,7 +22,7 @@ wasmtime::component::bindgen!({
},
});
-pub type ExtensionWorktree = Arc<dyn LspAdapterDelegate>;
+pub type ExtensionWorktree = Arc<dyn WorktreeDelegate>;
pub fn linker() -> &'static Linker<WasmState> {
static LINKER: OnceLock<Linker<WasmState>> = OnceLock::new();
@@ -62,7 +63,7 @@ impl From<Command> for latest::Command {
impl HostWorktree for WasmState {
async fn read_text_file(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
path: String,
) -> wasmtime::Result<Result<String, String>> {
latest::HostWorktree::read_text_file(self, delegate, path).await
@@ -70,14 +71,14 @@ impl HostWorktree for WasmState {
async fn shell_env(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
) -> wasmtime::Result<EnvVars> {
latest::HostWorktree::shell_env(self, delegate).await
}
async fn which(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
binary_name: String,
) -> wasmtime::Result<Option<String>> {
latest::HostWorktree::which(self, delegate, binary_name).await
@@ -2,7 +2,7 @@ use super::latest;
use crate::wasm_host::WasmState;
use anyhow::Result;
use async_trait::async_trait;
-use language::LspAdapterDelegate;
+use extension::WorktreeDelegate;
use semantic_version::SemanticVersion;
use std::sync::{Arc, OnceLock};
use wasmtime::component::{Linker, Resource};
@@ -20,7 +20,7 @@ wasmtime::component::bindgen!({
},
});
-pub type ExtensionWorktree = Arc<dyn LspAdapterDelegate>;
+pub type ExtensionWorktree = Arc<dyn WorktreeDelegate>;
pub fn linker() -> &'static Linker<WasmState> {
static LINKER: OnceLock<Linker<WasmState>> = OnceLock::new();
@@ -71,7 +71,7 @@ impl From<Command> for latest::Command {
impl HostWorktree for WasmState {
async fn read_text_file(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
path: String,
) -> wasmtime::Result<Result<String, String>> {
latest::HostWorktree::read_text_file(self, delegate, path).await
@@ -79,14 +79,14 @@ impl HostWorktree for WasmState {
async fn shell_env(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
) -> wasmtime::Result<EnvVars> {
latest::HostWorktree::shell_env(self, delegate).await
}
async fn which(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
binary_name: String,
) -> wasmtime::Result<Option<String>> {
latest::HostWorktree::which(self, delegate, binary_name).await
@@ -2,7 +2,7 @@ use super::{latest, since_v0_1_0};
use crate::wasm_host::WasmState;
use anyhow::Result;
use async_trait::async_trait;
-use language::LspAdapterDelegate;
+use extension::WorktreeDelegate;
use semantic_version::SemanticVersion;
use std::sync::{Arc, OnceLock};
use wasmtime::component::{Linker, Resource};
@@ -26,7 +26,7 @@ mod settings {
include!(concat!(env!("OUT_DIR"), "/since_v0.0.6/settings.rs"));
}
-pub type ExtensionWorktree = Arc<dyn LspAdapterDelegate>;
+pub type ExtensionWorktree = Arc<dyn WorktreeDelegate>;
pub fn linker() -> &'static Linker<WasmState> {
static LINKER: OnceLock<Linker<WasmState>> = OnceLock::new();
@@ -113,23 +113,20 @@ impl From<CodeLabel> for latest::CodeLabel {
#[async_trait]
impl HostWorktree for WasmState {
- async fn id(
- &mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
- ) -> wasmtime::Result<u64> {
+ async fn id(&mut self, delegate: Resource<Arc<dyn WorktreeDelegate>>) -> wasmtime::Result<u64> {
latest::HostWorktree::id(self, delegate).await
}
async fn root_path(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
) -> wasmtime::Result<String> {
latest::HostWorktree::root_path(self, delegate).await
}
async fn read_text_file(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
path: String,
) -> wasmtime::Result<Result<String, String>> {
latest::HostWorktree::read_text_file(self, delegate, path).await
@@ -137,14 +134,14 @@ impl HostWorktree for WasmState {
async fn shell_env(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
) -> wasmtime::Result<EnvVars> {
latest::HostWorktree::shell_env(self, delegate).await
}
async fn which(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
binary_name: String,
) -> wasmtime::Result<Option<String>> {
latest::HostWorktree::which(self, delegate, binary_name).await
@@ -5,13 +5,11 @@ use anyhow::{anyhow, bail, Context, Result};
use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
use async_trait::async_trait;
-use extension::KeyValueStoreDelegate;
+use extension::{KeyValueStoreDelegate, WorktreeDelegate};
use futures::{io::BufReader, FutureExt as _};
use futures::{lock::Mutex, AsyncReadExt};
use language::LanguageName;
-use language::{
- language_settings::AllLanguageSettings, LanguageServerBinaryStatus, LspAdapterDelegate,
-};
+use language::{language_settings::AllLanguageSettings, LanguageServerBinaryStatus};
use project::project_settings::ProjectSettings;
use semantic_version::SemanticVersion;
use std::{
@@ -47,7 +45,7 @@ mod settings {
include!(concat!(env!("OUT_DIR"), "/since_v0.1.0/settings.rs"));
}
-pub type ExtensionWorktree = Arc<dyn LspAdapterDelegate>;
+pub type ExtensionWorktree = Arc<dyn WorktreeDelegate>;
pub type ExtensionKeyValueStore = Arc<dyn KeyValueStoreDelegate>;
pub type ExtensionHttpResponseStream = Arc<Mutex<::http_client::Response<AsyncBody>>>;
@@ -251,52 +249,38 @@ impl HostKeyValueStore for WasmState {
#[async_trait]
impl HostWorktree for WasmState {
- async fn id(
- &mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
- ) -> wasmtime::Result<u64> {
- let delegate = self.table.get(&delegate)?;
- Ok(delegate.worktree_id().to_proto())
+ async fn id(&mut self, delegate: Resource<Arc<dyn WorktreeDelegate>>) -> wasmtime::Result<u64> {
+ latest::HostWorktree::id(self, delegate).await
}
async fn root_path(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
) -> wasmtime::Result<String> {
- let delegate = self.table.get(&delegate)?;
- Ok(delegate.worktree_root_path().to_string_lossy().to_string())
+ latest::HostWorktree::root_path(self, delegate).await
}
async fn read_text_file(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
path: String,
) -> wasmtime::Result<Result<String, String>> {
- let delegate = self.table.get(&delegate)?;
- Ok(delegate
- .read_text_file(path.into())
- .await
- .map_err(|error| error.to_string()))
+ latest::HostWorktree::read_text_file(self, delegate, path).await
}
async fn shell_env(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
) -> wasmtime::Result<EnvVars> {
- let delegate = self.table.get(&delegate)?;
- Ok(delegate.shell_env().await.into_iter().collect())
+ latest::HostWorktree::shell_env(self, delegate).await
}
async fn which(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
binary_name: String,
) -> wasmtime::Result<Option<String>> {
- let delegate = self.table.get(&delegate)?;
- Ok(delegate
- .which(binary_name.as_ref())
- .await
- .map(|path| path.to_string_lossy().to_string()))
+ latest::HostWorktree::which(self, delegate, binary_name).await
}
fn drop(&mut self, _worktree: Resource<Worktree>) -> Result<()> {
@@ -6,13 +6,10 @@ use async_compression::futures::bufread::GzipDecoder;
use async_tar::Archive;
use async_trait::async_trait;
use context_servers::manager::ContextServerSettings;
-use extension::KeyValueStoreDelegate;
+use extension::{KeyValueStoreDelegate, WorktreeDelegate};
use futures::{io::BufReader, FutureExt as _};
use futures::{lock::Mutex, AsyncReadExt};
-use language::{
- language_settings::AllLanguageSettings, LanguageName, LanguageServerBinaryStatus,
- LspAdapterDelegate,
-};
+use language::{language_settings::AllLanguageSettings, LanguageName, LanguageServerBinaryStatus};
use project::project_settings::ProjectSettings;
use semantic_version::SemanticVersion;
use std::{
@@ -44,7 +41,7 @@ mod settings {
include!(concat!(env!("OUT_DIR"), "/since_v0.2.0/settings.rs"));
}
-pub type ExtensionWorktree = Arc<dyn LspAdapterDelegate>;
+pub type ExtensionWorktree = Arc<dyn WorktreeDelegate>;
pub type ExtensionKeyValueStore = Arc<dyn KeyValueStoreDelegate>;
pub type ExtensionHttpResponseStream = Arc<Mutex<::http_client::Response<AsyncBody>>>;
@@ -93,25 +90,22 @@ impl HostProject for WasmState {
#[async_trait]
impl HostWorktree for WasmState {
- async fn id(
- &mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
- ) -> wasmtime::Result<u64> {
+ async fn id(&mut self, delegate: Resource<Arc<dyn WorktreeDelegate>>) -> wasmtime::Result<u64> {
let delegate = self.table.get(&delegate)?;
- Ok(delegate.worktree_id().to_proto())
+ Ok(delegate.id())
}
async fn root_path(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
) -> wasmtime::Result<String> {
let delegate = self.table.get(&delegate)?;
- Ok(delegate.worktree_root_path().to_string_lossy().to_string())
+ Ok(delegate.root_path())
}
async fn read_text_file(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
path: String,
) -> wasmtime::Result<Result<String, String>> {
let delegate = self.table.get(&delegate)?;
@@ -123,7 +117,7 @@ impl HostWorktree for WasmState {
async fn shell_env(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
) -> wasmtime::Result<EnvVars> {
let delegate = self.table.get(&delegate)?;
Ok(delegate.shell_env().await.into_iter().collect())
@@ -131,14 +125,11 @@ impl HostWorktree for WasmState {
async fn which(
&mut self,
- delegate: Resource<Arc<dyn LspAdapterDelegate>>,
+ delegate: Resource<Arc<dyn WorktreeDelegate>>,
binary_name: String,
) -> wasmtime::Result<Option<String>> {
let delegate = self.table.get(&delegate)?;
- Ok(delegate
- .which(binary_name.as_ref())
- .await
- .map(|path| path.to_string_lossy().to_string()))
+ Ok(delegate.which(binary_name).await)
}
fn drop(&mut self, _worktree: Resource<Worktree>) -> Result<()> {
@@ -5,6 +5,7 @@ use assistant_slash_command::{
ArgumentCompletion, SlashCommand, SlashCommandOutput, SlashCommandOutputSection,
SlashCommandResult,
};
+use extension_host::extension_lsp_adapter::WorktreeDelegateAdapter;
use futures::FutureExt as _;
use gpui::{Task, WeakView, WindowContext};
use language::{BufferSnapshot, LspAdapterDelegate};
@@ -97,6 +98,8 @@ impl SlashCommand for ExtensionSlashCommand {
move |extension, store| {
async move {
let resource = if let Some(delegate) = delegate {
+ let delegate =
+ Arc::new(WorktreeDelegateAdapter(delegate.clone())) as _;
Some(store.data_mut().table().push(delegate)?)
} else {
None