From 9507c24f6845c86fd69fd380045753e4d89c3471 Mon Sep 17 00:00:00 2001 From: dependabot[bot] Date: Mon, 5 Jul 2021 23:08:19 +0000 Subject: Bump thiserror from 1.0.25 to 1.0.26 Bumps [thiserror](https://github.com/dtolnay/thiserror) from 1.0.25 to 1.0.26. - [Release notes](https://github.com/dtolnay/thiserror/releases) - [Commits](https://github.com/dtolnay/thiserror/compare/1.0.25...1.0.26) --- updated-dependencies: - dependency-name: thiserror dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index 2cd202f3..a44ed5b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -957,18 +957,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa6f76457f59514c7eeb4e59d891395fab0b2fd1d40723ae737d64153392e9c6" +checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a36768c0fbf1bb15eca10defa29526bda730a2376c2ab4393ccfa16fb1a318d" +checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745" dependencies = [ "proc-macro2", "quote", -- cgit v1.2.3-70-g09d2 From bb41a82a85f6cc2b2867bf77c36d2b642eaa4f3e Mon Sep 17 00:00:00 2001 From: dependabot[bot] Date: Mon, 5 Jul 2021 23:08:06 +0000 Subject: Bump slotmap from 1.0.3 to 1.0.5 Bumps [slotmap](https://github.com/orlp/slotmap) from 1.0.3 to 1.0.5. - [Release notes](https://github.com/orlp/slotmap/releases) - [Changelog](https://github.com/orlp/slotmap/blob/master/RELEASES.md) - [Commits](https://github.com/orlp/slotmap/compare/v1.0.3...v1.0.5) --- updated-dependencies: - dependency-name: slotmap dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index a44ed5b4..a65950ab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -914,9 +914,9 @@ checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" [[package]] name = "slotmap" -version = "1.0.3" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585cd5dffe4e9e06f6dfdf66708b70aca3f781bed561f4f667b2d9c0d4559e36" +checksum = "a952280edbecfb1d4bd3cf2dbc309dc6ab523e53487c438ae21a6df09fe84bc4" dependencies = [ "version_check", ] -- cgit v1.2.3-70-g09d2 From c8681a820ccd149dedc631b6e94bc6ece0442fcb Mon Sep 17 00:00:00 2001 From: dependabot[bot] Date: Mon, 5 Jul 2021 23:07:56 +0000 Subject: Bump unicode-segmentation from 1.7.1 to 1.8.0 Bumps [unicode-segmentation](https://github.com/unicode-rs/unicode-segmentation) from 1.7.1 to 1.8.0. - [Release notes](https://github.com/unicode-rs/unicode-segmentation/releases) - [Commits](https://github.com/unicode-rs/unicode-segmentation/compare/1.7.1...v1.8.0) --- updated-dependencies: - dependency-name: unicode-segmentation dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- helix-core/Cargo.toml | 2 +- helix-tui/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index a65950ab..657df77c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1104,9 +1104,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" diff --git a/helix-core/Cargo.toml b/helix-core/Cargo.toml index 80d559a9..634c4d9f 100644 --- a/helix-core/Cargo.toml +++ b/helix-core/Cargo.toml @@ -19,7 +19,7 @@ helix-syntax = { version = "0.3", path = "../helix-syntax" } ropey = "1.3" smallvec = "1.4" tendril = "0.4.2" -unicode-segmentation = "1.7" +unicode-segmentation = "1.8" unicode-width = "0.1" unicode-general-category = "0.4" # slab = "0.4.2" diff --git a/helix-tui/Cargo.toml b/helix-tui/Cargo.toml index 7f98144c..33a9427a 100644 --- a/helix-tui/Cargo.toml +++ b/helix-tui/Cargo.toml @@ -18,7 +18,7 @@ default = ["crossterm"] [dependencies] bitflags = "1.0" cassowary = "0.3" -unicode-segmentation = "1.2" +unicode-segmentation = "1.8" crossterm = { version = "0.20", optional = true } serde = { version = "1", "optional" = true, features = ["derive"]} helix-view = { version = "0.3", path = "../helix-view", features = ["term"] } -- cgit v1.2.3-70-g09d2 From 47a6882738c7a125f6746bd20f4c67c517108a56 Mon Sep 17 00:00:00 2001 From: dependabot[bot] Date: Mon, 5 Jul 2021 23:07:47 +0000 Subject: Bump tokio from 1.7.1 to 1.8.0 Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.7.1 to 1.8.0. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.7.1...tokio-1.8.0) --- updated-dependencies: - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- helix-lsp/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index 657df77c..ab3cdd1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1010,9 +1010,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fb2ed024293bb19f7a5dc54fe83bf86532a44c12a2bb8ba40d64a4509395ca2" +checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4" dependencies = [ "autocfg", "bytes", diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index 8d43af69..3a13fb56 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -23,5 +23,5 @@ lsp-types = { version = "0.89", features = ["proposed"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" -tokio = { version = "1.7", features = ["full"] } +tokio = { version = "1.8", features = ["full"] } tokio-stream = "0.1.6" -- cgit v1.2.3-70-g09d2 From 929f553f896cbdc2a628d715de62d8acb3ce6868 Mon Sep 17 00:00:00 2001 From: dependabot[bot] Date: Mon, 12 Jul 2021 23:06:58 +0000 Subject: Bump tokio from 1.8.0 to 1.8.1 Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.8.0 to 1.8.1. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.8.0...tokio-1.8.1) --- updated-dependencies: - dependency-name: tokio dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index ab3cdd1e..7d30977b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1010,9 +1010,9 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4" +checksum = "98c8b05dc14c75ea83d63dd391100353789f5f24b8b3866542a5e85c8be8e985" dependencies = [ "autocfg", "bytes", -- cgit v1.2.3-70-g09d2 From c74198a3bf3456140f07df068abe7dc1a9515fbc Mon Sep 17 00:00:00 2001 From: dependabot[bot] Date: Mon, 12 Jul 2021 23:07:07 +0000 Subject: Bump tokio-stream from 0.1.6 to 0.1.7 Bumps [tokio-stream](https://github.com/tokio-rs/tokio) from 0.1.6 to 0.1.7. - [Release notes](https://github.com/tokio-rs/tokio/releases) - [Commits](https://github.com/tokio-rs/tokio/compare/tokio-stream-0.1.6...tokio-stream-0.1.7) --- updated-dependencies: - dependency-name: tokio-stream dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- helix-lsp/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index 7d30977b..ec389404 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1041,9 +1041,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8864d706fdb3cc0843a49647ac892720dac98a6eeb818b77190592cf4994066" +checksum = "7b2f3f698253f03119ac0102beaa64f67a67e08074d03a22d18784104543727f" dependencies = [ "futures-core", "pin-project-lite", diff --git a/helix-lsp/Cargo.toml b/helix-lsp/Cargo.toml index 3a13fb56..be099821 100644 --- a/helix-lsp/Cargo.toml +++ b/helix-lsp/Cargo.toml @@ -24,4 +24,4 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" thiserror = "1.0" tokio = { version = "1.8", features = ["full"] } -tokio-stream = "0.1.6" +tokio-stream = "0.1.7" -- cgit v1.2.3-70-g09d2 From 7e5c20cc58a94c4af2fa525dcccfdc35ec0d58f6 Mon Sep 17 00:00:00 2001 From: dependabot[bot] Date: Mon, 12 Jul 2021 23:07:15 +0000 Subject: Bump cc from 1.0.68 to 1.0.69 Bumps [cc](https://github.com/alexcrichton/cc-rs) from 1.0.68 to 1.0.69. - [Release notes](https://github.com/alexcrichton/cc-rs/releases) - [Commits](https://github.com/alexcrichton/cc-rs/compare/1.0.68...1.0.69) --- updated-dependencies: - dependency-name: cc dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index ec389404..cd55edde 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,9 +58,9 @@ checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] name = "cc" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72c244c1ff497a746a7e1fb3d14bd08420ecda70c8f25c7112f2781652d787" +checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" dependencies = [ "jobserver", ] -- cgit v1.2.3-70-g09d2 From dd5e8082e410032c9782835cf0fc52a469d050b1 Mon Sep 17 00:00:00 2001 From: dependabot[bot] Date: Mon, 12 Jul 2021 23:07:25 +0000 Subject: Bump anyhow from 1.0.41 to 1.0.42 Bumps [anyhow](https://github.com/dtolnay/anyhow) from 1.0.41 to 1.0.42. - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.41...1.0.42) --- updated-dependencies: - dependency-name: anyhow dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Cargo.lock') diff --git a/Cargo.lock b/Cargo.lock index cd55edde..222751df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,9 +13,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15af2628f6890fe2609a3b91bef4c83450512802e59489f9c1cb1fa5df064a61" +checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" [[package]] name = "arc-swap" -- cgit v1.2.3-70-g09d2 From dd2903ff10387c04e933aa37846663131297b8b3 Mon Sep 17 00:00:00 2001 From: Blaž Hrastnik Date: Sun, 11 Jul 2021 19:36:45 +0900 Subject: Dynamically load grammar libraries at runtime --- .gitignore | 1 + Cargo.lock | 25 +++--- helix-core/src/indent.rs | 4 +- helix-core/src/syntax.rs | 12 +-- helix-syntax/Cargo.toml | 6 +- helix-syntax/build.rs | 204 +++++++++++++++++++++++++++++++++------------- helix-syntax/src/lib.rs | 115 +++++++------------------- runtime/grammars/.gitkeep | 0 8 files changed, 201 insertions(+), 166 deletions(-) create mode 100644 runtime/grammars/.gitkeep (limited to 'Cargo.lock') diff --git a/.gitignore b/.gitignore index 1a42b440..346d0946 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ target helix-term/rustfmt.toml helix-syntax/languages/ result +runtime/grammars diff --git a/Cargo.lock b/Cargo.lock index 222751df..e262f081 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,9 +61,6 @@ name = "cc" version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2" -dependencies = [ - "jobserver", -] [[package]] name = "cfg-if" @@ -354,8 +351,9 @@ dependencies = [ name = "helix-syntax" version = "0.3.0" dependencies = [ + "anyhow", "cc", - "serde", + "libloading", "threadpool", "tree-sitter", ] @@ -475,15 +473,6 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" -[[package]] -name = "jobserver" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "972f5ae5d1cb9c6ae417789196c803205313edde988685da5e3aae0827b9e7fd" -dependencies = [ - "libc", -] - [[package]] name = "jsonrpc-core" version = "17.1.0" @@ -509,6 +498,16 @@ version = "0.2.97" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12b8adadd720df158f4d70dfe7ccc6adb0472d7c55ca83445f6a5ab3e36f8fb6" +[[package]] +name = "libloading" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a" +dependencies = [ + "cfg-if 1.0.0", + "winapi", +] + [[package]] name = "lock_api" version = "0.4.4" diff --git a/helix-core/src/indent.rs b/helix-core/src/indent.rs index 81bdffc0..1b36db7b 100644 --- a/helix-core/src/indent.rs +++ b/helix-core/src/indent.rs @@ -253,14 +253,14 @@ where let doc = Rope::from(doc); use crate::syntax::{ - Configuration, IndentationConfiguration, Lang, LanguageConfiguration, Loader, + Configuration, IndentationConfiguration, LanguageConfiguration, Loader, }; use once_cell::sync::OnceCell; let loader = Loader::new(Configuration { language: vec![LanguageConfiguration { scope: "source.rust".to_string(), file_types: vec!["rs".to_string()], - language_id: Lang::Rust, + language_id: "Rust".to_string(), highlight_config: OnceCell::new(), // roots: vec![], diff --git a/helix-core/src/syntax.rs b/helix-core/src/syntax.rs index 833ccfb9..f249f5fe 100644 --- a/helix-core/src/syntax.rs +++ b/helix-core/src/syntax.rs @@ -5,7 +5,7 @@ use crate::{ Rope, RopeSlice, Tendril, }; -pub use helix_syntax::{get_language, get_language_name, Lang}; +pub use helix_syntax::get_language; use arc_swap::ArcSwap; @@ -31,7 +31,7 @@ pub struct Configuration { #[serde(rename_all = "kebab-case")] pub struct LanguageConfiguration { #[serde(rename = "name")] - pub(crate) language_id: Lang, + pub(crate) language_id: String, pub scope: String, // source.rust pub file_types: Vec, // filename ends_with? pub roots: Vec, // these indicate project roots <.git, Cargo.toml> @@ -153,7 +153,7 @@ fn read_query(language: &str, filename: &str) -> String { impl LanguageConfiguration { fn initialize_highlight(&self, scopes: &[String]) -> Option> { - let language = get_language_name(self.language_id).to_ascii_lowercase(); + let language = self.language_id.to_ascii_lowercase(); let highlights_query = read_query(&language, "highlights.scm"); // always highlight syntax errors @@ -166,7 +166,7 @@ impl LanguageConfiguration { if highlights_query.is_empty() { None } else { - let language = get_language(self.language_id); + let language = get_language(&crate::RUNTIME_DIR, &self.language_id).ok()?; let config = HighlightConfiguration::new( language, &highlights_query, @@ -198,7 +198,7 @@ impl LanguageConfiguration { pub fn indent_query(&self) -> Option<&IndentQuery> { self.indent_query .get_or_init(|| { - let language = get_language_name(self.language_id).to_ascii_lowercase(); + let language = self.language_id.to_ascii_lowercase(); let toml = load_runtime_file(&language, "indents.toml").ok()?; toml::from_slice(toml.as_bytes()).ok() @@ -1802,7 +1802,7 @@ mod test { .map(String::from) .collect(); - let language = get_language(Lang::Rust); + let language = get_language(&crate::RUNTIME_DIR, "Rust").unwrap(); let config = HighlightConfiguration::new( language, &std::fs::read_to_string( diff --git a/helix-syntax/Cargo.toml b/helix-syntax/Cargo.toml index 140e3d24..7ad24488 100644 --- a/helix-syntax/Cargo.toml +++ b/helix-syntax/Cargo.toml @@ -12,8 +12,10 @@ include = ["src/**/*", "languages/**/*", "build.rs", "!**/docs/**/*", "!**/test/ [dependencies] tree-sitter = "0.19" -serde = { version = "1.0", features = ["derive"] } +libloading = "0.7" +anyhow = "1" [build-dependencies] -cc = { version = "1", features = ["parallel"] } +cc = { version = "1" } threadpool = { version = "1.0" } +anyhow = "1" diff --git a/helix-syntax/build.rs b/helix-syntax/build.rs index 847f8a67..02a5bf49 100644 --- a/helix-syntax/build.rs +++ b/helix-syntax/build.rs @@ -1,5 +1,7 @@ +use anyhow::Result; use std::fs; use std::path::PathBuf; +use std::time::SystemTime; use std::sync::mpsc::channel; @@ -15,66 +17,156 @@ fn collect_tree_sitter_dirs(ignore: &[String]) -> Vec { dirs } -fn collect_src_files(dir: &str) -> (Vec, Vec) { - eprintln!("Collect files for {}", dir); +#[cfg(unix)] +const DYLIB_EXTENSION: &str = "so"; - let mut c_files = Vec::new(); - let mut cpp_files = Vec::new(); - let path = PathBuf::from("languages").join(&dir).join("src"); - for entry in fs::read_dir(path).unwrap().flatten() { - let path = entry.path(); - if path - .file_stem() - .unwrap() - .to_str() - .unwrap() - .starts_with("binding") - { - continue; +#[cfg(windows)] +const DYLIB_EXTENSION: &str = "dll"; + +// const BUILD_TARGET: &'static str = env!("BUILD_TARGET"); + +use anyhow::{anyhow, Context}; +use std::{path::Path, process::Command}; + +fn build_library(src_path: &Path, language: &str) -> Result<()> { + let header_path = src_path; + // let grammar_path = src_path.join("grammar.json"); + let parser_path = src_path.join("parser.c"); + let mut scanner_path = src_path.join("scanner.c"); + + let scanner_path = if scanner_path.exists() { + Some(scanner_path) + } else { + scanner_path.set_extension("cc"); + if scanner_path.exists() { + Some(scanner_path) + } else { + None + } + }; + let parser_lib_path = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../runtime/grammars"); + let mut library_path = parser_lib_path.join(language); + library_path.set_extension(DYLIB_EXTENSION); + + let recompile = needs_recompile(&library_path, &parser_path, &scanner_path) + .with_context(|| "Failed to compare source and binary timestamps")?; + + if !recompile { + return Ok(()); + } + + let mut config = cc::Build::new(); + config.cpp(true).opt_level(2).cargo_metadata(false); + // .target(BUILD_TARGET) + // .host(BUILD_TARGET); + let compiler = config.get_compiler(); + let mut command = Command::new(compiler.path()); + for (key, value) in compiler.env() { + command.env(key, value); + } + + if cfg!(windows) { + command + .args(&["/nologo", "/LD", "/I"]) + .arg(header_path) + .arg("/Od") + .arg(parser_path); + if let Some(scanner_path) = scanner_path.as_ref() { + command.arg(scanner_path); } - if let Some(ext) = path.extension() { - if ext == "c" { - c_files.push(path.to_str().unwrap().to_string()); - } else if ext == "cc" || ext == "cpp" || ext == "cxx" { - cpp_files.push(path.to_str().unwrap().to_string()); + command + .arg("/link") + .arg(format!("/out:{}", library_path.to_str().unwrap())); + } else { + command + .arg("-shared") + .arg("-fPIC") + .arg("-fno-exceptions") + .arg("-g") + .arg("-I") + .arg(header_path) + .arg("-o") + .arg(&library_path) + .arg("-O2"); + if let Some(scanner_path) = scanner_path.as_ref() { + if scanner_path.extension() == Some("c".as_ref()) { + command.arg("-xc").arg("-std=c99").arg(scanner_path); + } else { + command.arg(scanner_path); } } + command.arg("-xc").arg(parser_path); } - (c_files, cpp_files) -} -fn build_c(files: Vec, language: &str) { - let mut build = cc::Build::new(); - for file in files { - build - .file(&file) - .include(PathBuf::from(file).parent().unwrap()) - .pic(true) - .warnings(false); + let output = command + .output() + .with_context(|| "Failed to execute C compiler")?; + if !output.status.success() { + return Err(anyhow!( + "Parser compilation failed.\nStdout: {}\nStderr: {}", + String::from_utf8_lossy(&output.stdout), + String::from_utf8_lossy(&output.stderr) + )); } - build.compile(&format!("tree-sitter-{}-c", language)); + + Ok(()) +} +fn needs_recompile( + lib_path: &Path, + parser_c_path: &Path, + scanner_path: &Option, +) -> Result { + if !lib_path.exists() { + return Ok(true); + } + let lib_mtime = mtime(lib_path)?; + if mtime(parser_c_path)? > lib_mtime { + return Ok(true); + } + if let Some(scanner_path) = scanner_path { + if mtime(scanner_path)? > lib_mtime { + return Ok(true); + } + } + Ok(false) } -fn build_cpp(files: Vec, language: &str) { - let mut build = cc::Build::new(); +fn mtime(path: &Path) -> Result { + Ok(fs::metadata(path)?.modified()?) +} - let flag = if build.get_compiler().is_like_msvc() { - "/std:c++17" - } else { - "-std=c++14" - }; +// fn build_c(files: Vec, language: &str) { +// let mut build = cc::Build::new(); +// for file in files { +// build +// .file(&file) +// .include(PathBuf::from(file).parent().unwrap()) +// .pic(true) +// .warnings(false); +// } +// build.compile(&format!("tree-sitter-{}-c", language)); +// } - for file in files { - build - .file(&file) - .include(PathBuf::from(file).parent().unwrap()) - .pic(true) - .warnings(false) - .cpp(true) - .flag_if_supported(flag); - } - build.compile(&format!("tree-sitter-{}-cpp", language)); -} +// fn build_cpp(files: Vec, language: &str) { +// let mut build = cc::Build::new(); + +// let flag = if build.get_compiler().is_like_msvc() { +// "/std:c++17" +// } else { +// "-std=c++14" +// }; + +// for file in files { +// build +// .file(&file) +// .include(PathBuf::from(file).parent().unwrap()) +// .pic(true) +// .warnings(false) +// .cpp(true) +// .flag_if_supported(flag); +// } +// build.compile(&format!("tree-sitter-{}-cpp", language)); +// } fn build_dir(dir: &str, language: &str) { println!("Build language {}", language); @@ -92,13 +184,9 @@ fn build_dir(dir: &str, language: &str) { eprintln!("You can fix in using 'git submodule init && git submodule update --recursive'."); std::process::exit(1); } - let (c, cpp) = collect_src_files(dir); - if !c.is_empty() { - build_c(c, language); - } - if !cpp.is_empty() { - build_cpp(cpp, language); - } + + let path = Path::new("languages").join(dir).join("src"); + build_library(&path, language).unwrap(); } fn main() { @@ -129,6 +217,6 @@ fn main() { // drop(tx); assert_eq!(rx.try_iter().sum::(), n_jobs); - build_dir("tree-sitter-typescript/tsx", "tsx"); - build_dir("tree-sitter-typescript/typescript", "typescript"); + // build_dir("tree-sitter-typescript/tsx", "tsx"); + // build_dir("tree-sitter-typescript/typescript", "typescript"); } diff --git a/helix-syntax/src/lib.rs b/helix-syntax/src/lib.rs index 5e3bb3ea..b6c0ecf3 100644 --- a/helix-syntax/src/lib.rs +++ b/helix-syntax/src/lib.rs @@ -1,94 +1,39 @@ -use serde::{Deserialize, Serialize}; +use anyhow::{Context, Result}; +use libloading::{Library, Symbol}; use tree_sitter::Language; -#[macro_export] -macro_rules! mk_extern { - ( $( $name:ident ),* ) => { - $( - extern "C" { pub fn $name() -> Language; } - )* - }; -} - -#[macro_export] -macro_rules! mk_enum { - ( $( $camel:ident ),* ) => { - #[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)] - #[serde(rename_all = "lowercase")] - pub enum Lang { - $( - $camel, - )* +fn replace_dashes_with_underscores(name: &str) -> String { + let mut result = String::with_capacity(name.len()); + for c in name.chars() { + if c == '-' { + result.push('_'); + } else { + result.push(c); } - }; + } + result } +#[cfg(unix)] +const DYLIB_EXTENSION: &str = "so"; -#[macro_export] -macro_rules! mk_get_language { - ( $( ($camel:ident, $name:ident) ),* ) => { - #[must_use] - pub fn get_language(lang: Lang) -> Language { - unsafe { - match lang { - $( - Lang::$camel => $name(), - )* - } - } - } - }; -} +#[cfg(windows)] +const DYLIB_EXTENSION: &str = "dll"; -#[macro_export] -macro_rules! mk_get_language_name { - ( $( $camel:ident ),* ) => { - #[must_use] - pub const fn get_language_name(lang: Lang) -> &'static str { - match lang { - $( - Lang::$camel => stringify!($camel), - )* - } - } - }; -} +pub fn get_language(runtime_path: &std::path::Path, name: &str) -> Result { + let name = name.to_ascii_lowercase(); + let mut library_path = runtime_path.join("grammars").join(&name); + // TODO: duplicated under build + library_path.set_extension(DYLIB_EXTENSION); -#[macro_export] -macro_rules! mk_langs { - ( $( ($camel:ident, $name:ident) ),* ) => { - mk_extern!($( $name ),*); - mk_enum!($( $camel ),*); - mk_get_language!($( ($camel, $name) ),*); - mk_get_language_name!($( $camel ),*); + 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 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) } - -mk_langs!( - // 1) Name for enum - // 2) tree-sitter function to call to get a Language - (Agda, tree_sitter_agda), - (Bash, tree_sitter_bash), - (Cpp, tree_sitter_cpp), - (CSharp, tree_sitter_c_sharp), - (Css, tree_sitter_css), - (C, tree_sitter_c), - (Elixir, tree_sitter_elixir), - (Go, tree_sitter_go), - // (Haskell, tree_sitter_haskell), - (Html, tree_sitter_html), - (Javascript, tree_sitter_javascript), - (Java, tree_sitter_java), - (Json, tree_sitter_json), - (Julia, tree_sitter_julia), - (Latex, tree_sitter_latex), - (Nix, tree_sitter_nix), - (Php, tree_sitter_php), - (Python, tree_sitter_python), - (Ruby, tree_sitter_ruby), - (Rust, tree_sitter_rust), - (Scala, tree_sitter_scala), - (Swift, tree_sitter_swift), - (Toml, tree_sitter_toml), - (Tsx, tree_sitter_tsx), - (Typescript, tree_sitter_typescript) -); diff --git a/runtime/grammars/.gitkeep b/runtime/grammars/.gitkeep new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3-70-g09d2