Re-enable language plugin functionality with some fixes (#7105)

Part of https://github.com/zed-industries/zed/issues/7096

* [x] Load all queries for language plugins, not just highlight query
* [x] Auto-reload languages when changing the `plugins` directory
* [x] Bump Tree-sitter for language loading and unloading fixes
* [x] Figure out code signing

Release Notes:

- N/A

---------

Co-authored-by: Antonio <antonio@zed.dev>
Co-authored-by: Marshall Bowers <elliott.codes@gmail.com>
This commit is contained in:
Max Brunsfeld 2024-01-30 19:59:13 -08:00 committed by GitHub
parent db99d4fef1
commit 9459394ea0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 527 additions and 64 deletions

View file

@ -52,7 +52,7 @@ use std::{
};
use syntax_map::SyntaxSnapshot;
use theme::{SyntaxTheme, Theme};
use tree_sitter::{self, Query};
use tree_sitter::{self, wasmtime, Query, WasmStore};
use unicase::UniCase;
use util::{http::HttpClient, paths::PathExt};
use util::{post_inc, ResultExt, TryFutureExt as _, UnwrapFuture};
@ -96,7 +96,9 @@ impl LspBinaryStatusSender {
thread_local! {
static PARSER: RefCell<Parser> = {
RefCell::new(Parser::new())
let mut parser = Parser::new();
parser.set_wasm_store(WasmStore::new(WASM_ENGINE.clone()).unwrap()).unwrap();
RefCell::new(parser)
};
}
@ -104,6 +106,7 @@ lazy_static! {
pub(crate) static ref NEXT_GRAMMAR_ID: AtomicUsize = Default::default();
/// A shared grammar for plain text, exposed for reuse by downstream crates.
#[doc(hidden)]
pub static ref WASM_ENGINE: wasmtime::Engine = wasmtime::Engine::default();
pub static ref PLAIN_TEXT: Arc<Language> = Arc::new(Language::new(
LanguageConfig {
name: "Plain Text".into(),
@ -706,8 +709,8 @@ enum AvailableGrammar {
get_queries: fn(&str) -> LanguageQueries,
},
Wasm {
_grammar_name: Arc<str>,
_path: Arc<Path>,
path: Arc<Path>,
get_queries: fn(&Path) -> LanguageQueries,
},
}
@ -773,9 +776,6 @@ impl LanguageRegistry {
}
/// Clear out all of the loaded languages and reload them from scratch.
///
/// This is useful in development, when queries have changed.
#[cfg(debug_assertions)]
pub fn reload(&self) {
self.state.write().reload();
}
@ -802,15 +802,17 @@ impl LanguageRegistry {
});
}
pub fn register_wasm(&self, path: Arc<Path>, grammar_name: Arc<str>, config: LanguageConfig) {
pub fn register_wasm(
&self,
path: Arc<Path>,
config: LanguageConfig,
get_queries: fn(&Path) -> LanguageQueries,
) {
let state = &mut *self.state.write();
state.available_languages.push(AvailableLanguage {
id: post_inc(&mut state.next_available_language_id),
config,
grammar: AvailableGrammar::Wasm {
_grammar_name: grammar_name,
_path: path,
},
grammar: AvailableGrammar::Wasm { path, get_queries },
lsp_adapters: Vec::new(),
loaded: false,
});
@ -944,8 +946,23 @@ impl LanguageRegistry {
asset_dir,
get_queries,
} => (grammar, (get_queries)(asset_dir)),
AvailableGrammar::Wasm { .. } => {
Err(anyhow!("not supported"))?
AvailableGrammar::Wasm { path, get_queries } => {
let grammar_name =
&language.config.grammar_name.as_ref().ok_or_else(
|| anyhow!("missing grammar name"),
)?;
let mut wasm_path = path.join(grammar_name.as_ref());
wasm_path.set_extension("wasm");
let wasm_bytes = std::fs::read(&wasm_path)?;
let grammar = 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
})?;
(grammar, get_queries(path.as_ref()))
}
};
Language::new(language.config, Some(grammar))
@ -1172,7 +1189,6 @@ impl LanguageRegistryState {
*self.subscription.0.borrow_mut() = ();
}
#[cfg(debug_assertions)]
fn reload(&mut self) {
self.languages.clear();
self.version += 1;