Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-loader/src/grammar.rs')
-rw-r--r--helix-loader/src/grammar.rs61
1 files changed, 22 insertions, 39 deletions
diff --git a/helix-loader/src/grammar.rs b/helix-loader/src/grammar.rs
index 11ddc0e4..99e91154 100644
--- a/helix-loader/src/grammar.rs
+++ b/helix-loader/src/grammar.rs
@@ -9,7 +9,7 @@ use std::{
sync::mpsc::channel,
};
use tempfile::TempPath;
-use tree_house::tree_sitter::Grammar;
+use tree_sitter::Language;
#[cfg(unix)]
const DYLIB_EXTENSION: &str = "so";
@@ -61,21 +61,28 @@ const BUILD_TARGET: &str = env!("BUILD_TARGET");
const REMOTE_NAME: &str = "origin";
#[cfg(target_arch = "wasm32")]
-pub fn get_language(name: &str) -> Result<Option<Grammar>> {
+pub fn get_language(name: &str) -> Result<Language> {
unimplemented!()
}
#[cfg(not(target_arch = "wasm32"))]
-pub fn get_language(name: &str) -> Result<Option<Grammar>> {
+pub fn get_language(name: &str) -> Result<Language> {
+ use libloading::{Library, Symbol};
let mut rel_library_path = PathBuf::new().join("grammars").join(name);
rel_library_path.set_extension(DYLIB_EXTENSION);
let library_path = crate::runtime_file(&rel_library_path);
- if !library_path.exists() {
- return Ok(None);
- }
- let grammar = unsafe { Grammar::new(name, &library_path) }?;
- Ok(Some(grammar))
+ let library = unsafe { Library::new(&library_path) }
+ .with_context(|| format!("Error opening dynamic library {:?}", library_path))?;
+ let language_fn_name = format!("tree_sitter_{}", name.replace('-', "_"));
+ 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 ensure_git_is_available() -> Result<()> {
@@ -213,27 +220,6 @@ fn get_grammar_configs() -> Result<Vec<GrammarConfiguration>> {
Ok(grammars)
}
-pub fn get_grammar_names() -> Result<Option<HashSet<String>>> {
- let config: Configuration = crate::config::user_lang_config()
- .context("Could not parse languages.toml")?
- .try_into()?;
-
- let grammars = match config.grammar_selection {
- Some(GrammarSelection::Only { only: selections }) => Some(selections),
- Some(GrammarSelection::Except { except: rejections }) => Some(
- config
- .grammar
- .into_iter()
- .map(|grammar| grammar.grammar_id)
- .filter(|id| !rejections.contains(id))
- .collect(),
- ),
- None => None,
- };
-
- Ok(grammars)
-}
-
fn run_parallel<F, Res>(grammars: Vec<GrammarConfiguration>, job: F) -> Vec<(String, Result<Res>)>
where
F: Fn(GrammarConfiguration) -> Result<Res> + Send + 'static + Clone,
@@ -287,12 +273,12 @@ fn fetch_grammar(grammar: GrammarConfiguration) -> Result<FetchStatus> {
}
// ensure the remote matches the configured remote
- if get_remote_url(&grammar_dir).as_ref() != Some(&remote) {
+ if get_remote_url(&grammar_dir).map_or(true, |s| s != remote) {
set_remote(&grammar_dir, &remote)?;
}
// ensure the revision matches the configured revision
- if get_revision(&grammar_dir).as_ref() != Some(&revision) {
+ if get_revision(&grammar_dir).map_or(true, |s| s != revision) {
// Fetch the exact revision from the remote.
// Supported by server-side git since v2.5.0 (July 2015),
// enabled by default on major git hosts.
@@ -465,6 +451,7 @@ fn build_tree_sitter_library(
command
.args(["/nologo", "/LD", "/I"])
.arg(header_path)
+ .arg("/Od")
.arg("/utf-8")
.arg("/std:c11");
if let Some(scanner_path) = scanner_path.as_ref() {
@@ -482,6 +469,7 @@ fn build_tree_sitter_library(
cpp_command
.args(["/nologo", "/LD", "/I"])
.arg(header_path)
+ .arg("/Od")
.arg("/utf-8")
.arg("/std:c++14")
.arg(format!("/Fo{}", object_file.display()))
@@ -508,11 +496,9 @@ fn build_tree_sitter_library(
.arg("/link")
.arg(format!("/out:{}", library_path.to_str().unwrap()));
} else {
- #[cfg(not(windows))]
- command.arg("-fPIC");
-
command
.arg("-shared")
+ .arg("-fPIC")
.arg("-fno-exceptions")
.arg("-I")
.arg(header_path)
@@ -531,11 +517,8 @@ fn build_tree_sitter_library(
cpp_command.args(compiler.args());
let object_file =
library_path.with_file_name(format!("{}_scanner.o", &grammar.grammar_id));
-
- #[cfg(not(windows))]
- cpp_command.arg("-fPIC");
-
cpp_command
+ .arg("-fPIC")
.arg("-fno-exceptions")
.arg("-I")
.arg(header_path)
@@ -609,6 +592,6 @@ fn mtime(path: &Path) -> Result<SystemTime> {
/// Gives the contents of a file from a language's `runtime/queries/<lang>`
/// directory
pub fn load_runtime_file(language: &str, filename: &str) -> Result<String, std::io::Error> {
- let path = crate::runtime_file(PathBuf::new().join("queries").join(language).join(filename));
+ let path = crate::runtime_file(&PathBuf::new().join("queries").join(language).join(filename));
std::fs::read_to_string(path)
}