Fix issues with extension API that come up when moving Svelte into an extension (#9611)
We're doing it. Svelte support is moving into an extension. This PR fixes some issues that came up along the way. Notes * extensions need to be able to retrieve the path the `node` binary installed by Zed * previously we were silently swallowing any errors that occurred while loading a grammar * npm commands ran by extensions weren't run in the right directory * Tree-sitter's WASM stdlib didn't support a C function (`strncmp`) needed by the Svelte parser's external scanner * the way that LSP installation status was reported was unnecessarily complex Release Notes: - Removed built-in support for the Svelte and Gleam languages, because full support for those languages is now available via extensions. These extensions will be suggested for download when you open a `.svelte` or `.gleam` file. --------- Co-authored-by: Marshall <marshall@zed.dev>
This commit is contained in:
parent
4459eacc98
commit
6ebe599c98
70 changed files with 1278 additions and 1223 deletions
|
@ -25,7 +25,7 @@ use sum_tree::Bias;
|
|||
use text::{Point, Rope};
|
||||
use theme::Theme;
|
||||
use unicase::UniCase;
|
||||
use util::{paths::PathExt, post_inc, ResultExt};
|
||||
use util::{maybe, paths::PathExt, post_inc, ResultExt};
|
||||
|
||||
pub struct LanguageRegistry {
|
||||
state: RwLock<LanguageRegistryState>,
|
||||
|
@ -54,10 +54,9 @@ struct LanguageRegistryState {
|
|||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum LanguageServerBinaryStatus {
|
||||
None,
|
||||
CheckingForUpdate,
|
||||
Downloading,
|
||||
Downloaded,
|
||||
Cached,
|
||||
Failed { error: String },
|
||||
}
|
||||
|
||||
|
@ -91,9 +90,10 @@ enum AvailableGrammar {
|
|||
Loaded(#[allow(unused)] PathBuf, tree_sitter::Language),
|
||||
Loading(
|
||||
#[allow(unused)] PathBuf,
|
||||
Vec<oneshot::Sender<Result<tree_sitter::Language>>>,
|
||||
Vec<oneshot::Sender<Result<tree_sitter::Language, Arc<anyhow::Error>>>>,
|
||||
),
|
||||
Unloaded(PathBuf),
|
||||
LoadFailed(Arc<anyhow::Error>),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -213,7 +213,20 @@ impl LanguageRegistry {
|
|||
.lsp_adapters
|
||||
.entry(language_name)
|
||||
.or_default()
|
||||
.push(CachedLspAdapter::new(adapter));
|
||||
.push(CachedLspAdapter::new(adapter, true));
|
||||
}
|
||||
|
||||
pub fn register_secondary_lsp_adapter(
|
||||
&self,
|
||||
language_name: Arc<str>,
|
||||
adapter: Arc<dyn LspAdapter>,
|
||||
) {
|
||||
self.state
|
||||
.write()
|
||||
.lsp_adapters
|
||||
.entry(language_name)
|
||||
.or_default()
|
||||
.push(CachedLspAdapter::new(adapter, false));
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "test-support", test))]
|
||||
|
@ -227,7 +240,7 @@ impl LanguageRegistry {
|
|||
.lsp_adapters
|
||||
.entry(language_name.into())
|
||||
.or_default()
|
||||
.push(CachedLspAdapter::new(Arc::new(adapter)));
|
||||
.push(CachedLspAdapter::new(Arc::new(adapter), true));
|
||||
self.fake_language_servers(language_name)
|
||||
}
|
||||
|
||||
|
@ -578,6 +591,9 @@ impl LanguageRegistry {
|
|||
|
||||
if let Some(grammar) = state.grammars.get_mut(name.as_ref()) {
|
||||
match grammar {
|
||||
AvailableGrammar::LoadFailed(error) => {
|
||||
tx.send(Err(error.clone())).ok();
|
||||
}
|
||||
AvailableGrammar::Native(grammar) | AvailableGrammar::Loaded(_, grammar) => {
|
||||
tx.send(Ok(grammar.clone())).ok();
|
||||
}
|
||||
|
@ -586,46 +602,47 @@ impl LanguageRegistry {
|
|||
}
|
||||
AvailableGrammar::Unloaded(wasm_path) => {
|
||||
let this = self.clone();
|
||||
let wasm_path = wasm_path.clone();
|
||||
*grammar = AvailableGrammar::Loading(wasm_path.clone(), vec![tx]);
|
||||
self.executor
|
||||
.spawn({
|
||||
let wasm_path = wasm_path.clone();
|
||||
async move {
|
||||
.spawn(async move {
|
||||
let grammar_result = maybe!({
|
||||
let wasm_bytes = std::fs::read(&wasm_path)?;
|
||||
let grammar_name = wasm_path
|
||||
.file_stem()
|
||||
.and_then(OsStr::to_str)
|
||||
.ok_or_else(|| anyhow!("invalid grammar filename"))?;
|
||||
let grammar = PARSER.with(|parser| {
|
||||
anyhow::Ok(PARSER.with(|parser| {
|
||||
let mut parser = parser.borrow_mut();
|
||||
let mut store = parser.take_wasm_store().unwrap();
|
||||
let grammar = store.load_language(&grammar_name, &wasm_bytes);
|
||||
parser.set_wasm_store(store).unwrap();
|
||||
grammar
|
||||
})?;
|
||||
})?)
|
||||
})
|
||||
.map_err(Arc::new);
|
||||
|
||||
if let Some(AvailableGrammar::Loading(_, txs)) =
|
||||
this.state.write().grammars.insert(
|
||||
name,
|
||||
AvailableGrammar::Loaded(wasm_path, grammar.clone()),
|
||||
)
|
||||
{
|
||||
for tx in txs {
|
||||
tx.send(Ok(grammar.clone())).ok();
|
||||
}
|
||||
let value = match &grammar_result {
|
||||
Ok(grammar) => AvailableGrammar::Loaded(wasm_path, grammar.clone()),
|
||||
Err(error) => AvailableGrammar::LoadFailed(error.clone()),
|
||||
};
|
||||
|
||||
let old_value = this.state.write().grammars.insert(name, value);
|
||||
if let Some(AvailableGrammar::Loading(_, txs)) = old_value {
|
||||
for tx in txs {
|
||||
tx.send(grammar_result.clone()).ok();
|
||||
}
|
||||
|
||||
anyhow::Ok(())
|
||||
}
|
||||
})
|
||||
.detach();
|
||||
*grammar = AvailableGrammar::Loading(wasm_path.clone(), vec![tx]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tx.send(Err(anyhow!("no such grammar {}", name))).ok();
|
||||
tx.send(Err(Arc::new(anyhow!("no such grammar {}", name))))
|
||||
.ok();
|
||||
}
|
||||
|
||||
async move { rx.await? }
|
||||
async move { rx.await?.map_err(|e| anyhow!(e)) }
|
||||
}
|
||||
|
||||
pub fn to_vec(&self) -> Vec<Arc<Language>> {
|
||||
|
@ -691,7 +708,7 @@ impl LanguageRegistry {
|
|||
// the login shell to be set on our process.
|
||||
login_shell_env_loaded.await;
|
||||
|
||||
let binary = adapter
|
||||
let binary_result = adapter
|
||||
.clone()
|
||||
.get_language_server_command(
|
||||
language.clone(),
|
||||
|
@ -699,8 +716,11 @@ impl LanguageRegistry {
|
|||
delegate.clone(),
|
||||
&mut cx,
|
||||
)
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
delegate.update_status(adapter.name.clone(), LanguageServerBinaryStatus::None);
|
||||
|
||||
let binary = binary_result?;
|
||||
let options = adapter
|
||||
.adapter
|
||||
.clone()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue