summaryrefslogtreecommitdiff
path: root/helix-core
diff options
context:
space:
mode:
Diffstat (limited to 'helix-core')
-rw-r--r--helix-core/Cargo.toml5
-rw-r--r--helix-core/src/syntax.rs36
2 files changed, 36 insertions, 5 deletions
diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml
index 6682c37f..5582d38b 100644
--- a/helix-core/Cargo.toml
+++ b/helix-core/Cargo.toml
@@ -13,8 +13,6 @@ include = ["src/**/*", "README.md"]
[features]
[dependencies]
-helix-syntax = { version = "0.6", path = "../helix-syntax" }
-
ropey = "1.3"
smallvec = "1.8"
smartstring = "1.0.0"
@@ -40,5 +38,8 @@ encoding_rs = "0.8"
chrono = { version = "0.4", default-features = false, features = ["alloc", "std"] }
+libloading = "0.7"
+anyhow = "1"
+
[dev-dependencies]
quickcheck = { version = "1", default-features = false }
diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs
index 53d20da3..0f7d224d 100644
--- a/helix-core/src/syntax.rs
+++ b/helix-core/src/syntax.rs
@@ -7,7 +7,9 @@ use crate::{
Rope, RopeSlice, Tendril,
};
-pub use helix_syntax::get_language;
+use anyhow::{Context, Result};
+use libloading::{Library, Symbol};
+use tree_sitter::Language;
use arc_swap::{ArcSwap, Guard};
use slotmap::{DefaultKey as LayerId, HopSlotMap};
@@ -25,6 +27,34 @@ use std::{
use once_cell::sync::{Lazy, OnceCell};
use serde::{Deserialize, Serialize};
+#[cfg(unix)]
+pub const DYLIB_EXTENSION: &str = "so";
+
+#[cfg(windows)]
+pub const DYLIB_EXTENSION: &str = "dll";
+
+fn replace_dashes_with_underscores(name: &str) -> String {
+ name.replace('-', "_")
+}
+
+pub fn get_language(runtime_path: &std::path::Path, name: &str) -> Result<Language> {
+ let name = name.to_ascii_lowercase();
+ let mut library_path = runtime_path.join("grammars").join(&name);
+ library_path.set_extension(DYLIB_EXTENSION);
+
+ let library = unsafe { Library::new(&library_path) }
+ .with_context(|| format!("Error opening dynamic library {:?}", &library_path))?;
+ let language_fn_name = format!("tree_sitter_{}", replace_dashes_with_underscores(&name));
+ let language = unsafe {
+ let language_fn: Symbol<unsafe extern "C" fn() -> Language> = library
+ .get(language_fn_name.as_bytes())
+ .with_context(|| format!("Failed to load symbol {}", language_fn_name))?;
+ language_fn()
+ };
+ std::mem::forget(library);
+ Ok(language)
+}
+
fn deserialize_regex<'de, D>(deserializer: D) -> Result<Option<Regex>, D::Error>
where
D: serde::Deserializer<'de>,
@@ -426,7 +456,7 @@ impl LanguageConfiguration {
&injections_query,
&locals_query,
)
- .unwrap(); // TODO: avoid panic
+ .unwrap_or_else(|query_error| panic!("Could not parse queries for language {:?}. Are your grammars out of sync? Try running 'hx --fetch-grammars' and 'hx --build-grammars'. This query could not be parsed: {:?}", self.language_id, query_error));
config.configure(scopes);
Some(Arc::new(config))
@@ -2023,7 +2053,7 @@ mod test {
);
let loader = Loader::new(Configuration { language: vec![] });
- let language = get_language(&crate::RUNTIME_DIR, "Rust").unwrap();
+ let language = get_language("Rust").unwrap();
let query = Query::new(language, query_str).unwrap();
let textobject = TextObjectQuery { query };