From ecdf993ff1047fd3cc9f408f583a656010b725bb Mon Sep 17 00:00:00 2001 From: Wilfred Hughes Date: Tue, 29 Mar 2022 22:46:09 -0700 Subject: [PATCH] Add support for Nix Closes #196 --- CHANGELOG.md | 3 +-- README.md | 1 + build.rs | 5 +++++ manual/src/upstream_parsers.md | 1 + sample_files/compare.expected | 3 +++ sample_files/nix_after.nix | 24 +++++++++++++++++++++++ sample_files/nix_before.nix | 35 ++++++++++++++++++++++++++++++++++ src/guess_language.rs | 2 ++ src/tree_sitter_parser.rs | 17 +++++++++++++++++ vendor/highlights/nix.scm | 1 + vendor/tree-sitter-nix-src | 1 + 11 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 sample_files/nix_after.nix create mode 100644 sample_files/nix_before.nix create mode 120000 vendor/highlights/nix.scm create mode 120000 vendor/tree-sitter-nix-src diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d3033d20..601a8526b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,7 @@ syntactic changes". Fixed an issue in C and C++ where blank lines were highlighted after novel preprocessor lines. -Added support for Janet. -Added support for Lua. +Added support for Janet, Lua and Nix. ## 0.24 (release 26th March 2022) diff --git a/README.md b/README.md index 29f1fa5ca..dc34dbcf1 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ Difftastic supports the following languages: * JavaScript (and JSX) * JSON * Lua +* Nix * OCaml * PHP * Python diff --git a/build.rs b/build.rs index 35d58b311..1d986fd7e 100644 --- a/build.rs +++ b/build.rs @@ -139,6 +139,11 @@ fn main() { src_dir: "vendor/tree-sitter-lua-src", extra_files: vec!["scanner.cc"], }, + TreeSitterParser { + name: "tree-sitter-nix", + src_dir: "vendor/tree-sitter-nix-src", + extra_files: vec!["scanner.c"], + }, TreeSitterParser { name: "tree-sitter-ocaml", src_dir: "vendor/tree-sitter-ocaml-src/ocaml/src", diff --git a/manual/src/upstream_parsers.md b/manual/src/upstream_parsers.md index 2be5592b5..3df5528da 100644 --- a/manual/src/upstream_parsers.md +++ b/manual/src/upstream_parsers.md @@ -21,6 +21,7 @@ Difftastic uses the following tree-sitter parsers: | JavaScript, JSX | [tree-sitter/tree-sitter-javascript](https://github.com/tree-sitter/tree-sitter-javascript) | | JSON | [tree-sitter/tree-sitter-json](https://github.com/tree-sitter/tree-sitter-json) | | Lua | [nvim-treesitter/tree-sitter-lua](https://github.com/nvim-treesitter/tree-sitter-lua) | +| Nix | [cstrahan/tree-sitter-nix](https://github.com/cstrahan/tree-sitter-nix) | | OCaml | [tree-sitter/tree-sitter-ocaml](https://github.com/tree-sitter/tree-sitter-ocaml) | | PHP | [tree-sitter/tree-sitter-php](https://github.com/tree-sitter/tree-sitter-php) | | Python | [tree-sitter/tree-sitter-python](https://github.com/tree-sitter/tree-sitter-python) | diff --git a/sample_files/compare.expected b/sample_files/compare.expected index f7a7262a6..acb02a7a7 100644 --- a/sample_files/compare.expected +++ b/sample_files/compare.expected @@ -85,6 +85,9 @@ sample_files/nest_before.rs sample_files/nest_after.rs sample_files/nesting_before.el sample_files/nesting_after.el 6af3112dad0de540b4104655119970e8 - +sample_files/nix_before.nix sample_files/nix_after.nix +2f8e64ce28f4067210e9f12f10cb4579 - + sample_files/ocaml_before.ml sample_files/ocaml_after.ml 2e415fe09d7cee050f8143a8d8c209bd - diff --git a/sample_files/nix_after.nix b/sample_files/nix_after.nix new file mode 100644 index 000000000..18fd01165 --- /dev/null +++ b/sample_files/nix_after.nix @@ -0,0 +1,24 @@ +{ lib, fetchFromGitHub, rustPlatform, tree-sitter }: + +rustPlatform.buildRustPackage rec { + pname = "difftastic"; + version = "0.24.0"; + + src = fetchFromGitHub { + owner = "wilfred"; + repo = pname; + rev = version; + sha256 = "sha256-Yp0WwzGo8nuRZuiHdUPxPM1SYBeeVA3SMDfHnQmqUqY="; + }; + + cargoSha256 = "sha256-m80PT2UQYhA5KEh7ax/fhh6vuse0DXhbFsh2x4pwkWY="; + + meta = with lib; { + description = "A syntax-aware diff"; + homepage = "https://github.com/Wilfred/difftastic"; + changelog = "https://github.com/Wilfred/difftastic/raw/${version}/CHANGELOG.md"; + license = licenses.mit; + maintainers = with maintainers; [ ethancedwards8 figsoda ]; + mainProgram = "difft"; + }; +} diff --git a/sample_files/nix_before.nix b/sample_files/nix_before.nix new file mode 100644 index 000000000..ee86bcd63 --- /dev/null +++ b/sample_files/nix_before.nix @@ -0,0 +1,35 @@ +{ lib, fetchFromGitHub, rustPlatform, tree-sitter }: + +rustPlatform.buildRustPackage rec { + pname = "difftastic"; + version = "0.12.0"; + + src = fetchFromGitHub { + owner = "wilfred"; + repo = pname; + rev = version; + sha256 = "sha256-A6Z3g6fbYBynyN4OhRrZNO0ZghvT3XnIahdUQ8SE8tU="; + }; + + cargoSha256 = "sha256-6/JwrPymtpj/CXqx3Pe43v+MJTNONArU2WEo/zgJhT4="; + + postPatch = '' + pushd vendor + for grammar in */; do + if [ -d "${tree-sitter.grammars}/$grammar" ]; then + rm -r "$grammar" + ln -s "${tree-sitter.grammars}/$grammar" + fi + done + popd + ''; + + meta = with lib; { + description = "A syntax-aware diff"; + homepage = "https://github.com/Wilfred/difftastic"; + changelog = "https://github.com/Wilfred/difftastic/raw/${version}/CHANGELOG.md"; + license = licenses.mit; + maintainers = with maintainers; [ ethancedwards8 figsoda ]; + mainProgram = "difft"; + }; +} diff --git a/src/guess_language.rs b/src/guess_language.rs index 8d82ba3f6..596e946d0 100644 --- a/src/guess_language.rs +++ b/src/guess_language.rs @@ -36,6 +36,7 @@ pub enum Language { Json, Jsx, Lua, + Nix, OCaml, OCamlInterface, Php, @@ -197,6 +198,7 @@ fn from_extension(extension: &OsStr, src: &str) -> Option { "jsx" => Some(Jsx), "json" => Some(Json), "lua" => Some(Lua), + "nix" => Some(Nix), "ml" => Some(OCaml), "mli" => Some(OCamlInterface), "php" if !src.starts_with(" Some(Php), diff --git a/src/tree_sitter_parser.rs b/src/tree_sitter_parser.rs index c6156703d..e4da7c634 100644 --- a/src/tree_sitter_parser.rs +++ b/src/tree_sitter_parser.rs @@ -60,6 +60,7 @@ extern "C" { fn tree_sitter_javascript() -> ts::Language; fn tree_sitter_json() -> ts::Language; fn tree_sitter_lua() -> ts::Language; + fn tree_sitter_nix() -> ts::Language; fn tree_sitter_ocaml() -> ts::Language; fn tree_sitter_ocaml_interface() -> ts::Language; fn tree_sitter_php() -> ts::Language; @@ -366,6 +367,22 @@ pub fn from_language(language: guess::Language) -> TreeSitterConfig { .unwrap(), } } + Nix => { + let language = unsafe { tree_sitter_nix() }; + TreeSitterConfig { + name: "Nix", + language, + atom_nodes: vec!["string_expression", "indented_string_expression"] + .into_iter() + .collect(), + delimiter_tokens: vec![("{", "}"), ("[", "]")].into_iter().collect(), + highlight_query: ts::Query::new( + language, + include_str!("../vendor/highlights/nix.scm"), + ) + .unwrap(), + } + } OCaml => { let language = unsafe { tree_sitter_ocaml() }; TreeSitterConfig { diff --git a/vendor/highlights/nix.scm b/vendor/highlights/nix.scm new file mode 120000 index 000000000..9e4535c26 --- /dev/null +++ b/vendor/highlights/nix.scm @@ -0,0 +1 @@ +../tree-sitter-nix/queries/highlights.scm \ No newline at end of file diff --git a/vendor/tree-sitter-nix-src b/vendor/tree-sitter-nix-src new file mode 120000 index 000000000..31ca572ab --- /dev/null +++ b/vendor/tree-sitter-nix-src @@ -0,0 +1 @@ +tree-sitter-nix/src \ No newline at end of file