276 lines
7.5 KiB
Nix
276 lines
7.5 KiB
Nix
{
|
|
lib,
|
|
stdenv,
|
|
fetchgit,
|
|
fetchFromGitHub,
|
|
nix-update-script,
|
|
runCommand,
|
|
which,
|
|
rustPlatform,
|
|
emscripten,
|
|
openssl,
|
|
pkg-config,
|
|
callPackage,
|
|
linkFarm,
|
|
substitute,
|
|
installShellFiles,
|
|
buildPackages,
|
|
enableShared ? !stdenv.hostPlatform.isStatic,
|
|
enableStatic ? stdenv.hostPlatform.isStatic,
|
|
webUISupport ? false,
|
|
extraGrammars ? { },
|
|
|
|
# tests
|
|
lunarvim,
|
|
}:
|
|
|
|
let
|
|
# to update:
|
|
# 1) change all these hashes
|
|
# 2) nix-build -A tree-sitter.updater.update-all-grammars
|
|
# 3) Set GITHUB_TOKEN env variable to avoid api rate limit (Use a Personal Access Token from https://github.com/settings/tokens It does not need any permissions)
|
|
# 4) run the ./result script that is output by that (it updates ./grammars)
|
|
version = "0.25.6";
|
|
hash = "sha256-2/DF2xyiKi5HAqqeGt1TIMvAWFfZgcfVccK4zrTqq88=";
|
|
|
|
src = fetchFromGitHub {
|
|
owner = "tree-sitter";
|
|
repo = "tree-sitter";
|
|
tag = "v${version}";
|
|
inherit hash;
|
|
fetchSubmodules = true;
|
|
};
|
|
|
|
update-all-grammars = callPackage ./update.nix { };
|
|
|
|
fetchGrammar =
|
|
v:
|
|
fetchgit {
|
|
inherit (v)
|
|
url
|
|
rev
|
|
sha256
|
|
fetchSubmodules
|
|
;
|
|
};
|
|
|
|
grammars = runCommand "grammars" { } (
|
|
''
|
|
mkdir $out
|
|
''
|
|
+ (lib.concatStrings (
|
|
lib.mapAttrsToList (
|
|
name: grammar: "ln -s ${grammar.src or (fetchGrammar grammar)} $out/${name}\n"
|
|
) (import ./grammars { inherit lib; })
|
|
))
|
|
);
|
|
|
|
buildGrammar = callPackage ./grammar.nix { };
|
|
|
|
builtGrammars =
|
|
let
|
|
build =
|
|
name: grammar:
|
|
buildGrammar {
|
|
language = grammar.language or name;
|
|
inherit version;
|
|
src = grammar.src or (fetchGrammar grammar);
|
|
location = grammar.location or null;
|
|
generate = grammar.generate or false;
|
|
};
|
|
grammars' = import ./grammars { inherit lib; } // extraGrammars;
|
|
grammars =
|
|
grammars'
|
|
// {
|
|
tree-sitter-latex = grammars'.tree-sitter-latex // {
|
|
generate = true;
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-ocaml = grammars'.tree-sitter-ocaml // {
|
|
location = "grammars/ocaml";
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-ocaml-interface = grammars'.tree-sitter-ocaml // {
|
|
location = "grammars/interface";
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-org-nvim = grammars'.tree-sitter-org-nvim // {
|
|
language = "tree-sitter-org";
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-typescript = grammars'.tree-sitter-typescript // {
|
|
location = "typescript";
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-tsx = grammars'.tree-sitter-typescript // {
|
|
location = "tsx";
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-markdown = grammars'.tree-sitter-markdown // {
|
|
location = "tree-sitter-markdown";
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-markdown-inline = grammars'.tree-sitter-markdown // {
|
|
language = "tree-sitter-markdown_inline";
|
|
location = "tree-sitter-markdown-inline";
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-php = grammars'.tree-sitter-php // {
|
|
location = "php";
|
|
};
|
|
}
|
|
// {
|
|
tree-sitter-sql = grammars'.tree-sitter-sql // {
|
|
generate = true;
|
|
};
|
|
};
|
|
in
|
|
lib.mapAttrs build grammars;
|
|
|
|
# Usage:
|
|
# pkgs.tree-sitter.withPlugins (p: [ p.tree-sitter-c p.tree-sitter-java ... ])
|
|
#
|
|
# or for all grammars:
|
|
# pkgs.tree-sitter.withPlugins (_: allGrammars)
|
|
# which is equivalent to
|
|
# pkgs.tree-sitter.withPlugins (p: builtins.attrValues p)
|
|
withPlugins =
|
|
grammarFn:
|
|
let
|
|
grammars = grammarFn builtGrammars;
|
|
in
|
|
linkFarm "grammars" (
|
|
map (
|
|
drv:
|
|
let
|
|
name = lib.strings.getName drv;
|
|
in
|
|
{
|
|
name =
|
|
(lib.strings.replaceStrings [ "-" ] [ "_" ] (
|
|
lib.strings.removePrefix "tree-sitter-" (lib.strings.removeSuffix "-grammar" name)
|
|
))
|
|
+ ".so";
|
|
path = "${drv}/parser";
|
|
}
|
|
) grammars
|
|
);
|
|
|
|
allGrammars = builtins.attrValues builtGrammars;
|
|
|
|
in
|
|
rustPlatform.buildRustPackage {
|
|
pname = "tree-sitter";
|
|
inherit src version;
|
|
|
|
cargoHash = "sha256-sGh16M7cbT5ct1sT2FcUUoIQFcoOftTuQ0aSCjtkTEs=";
|
|
|
|
buildInputs = [
|
|
installShellFiles
|
|
]
|
|
++ lib.optionals webUISupport [
|
|
openssl
|
|
];
|
|
nativeBuildInputs = [
|
|
which
|
|
]
|
|
++ lib.optionals webUISupport [
|
|
emscripten
|
|
pkg-config
|
|
];
|
|
|
|
patches = lib.optionals (!webUISupport) [
|
|
(substitute {
|
|
src = ./remove-web-interface.patch;
|
|
})
|
|
];
|
|
|
|
postPatch = lib.optionalString webUISupport ''
|
|
substituteInPlace cli/loader/src/lib.rs \
|
|
--replace-fail 'let emcc_name = if cfg!(windows) { "emcc.bat" } else { "emcc" };' 'let emcc_name = "${lib.getExe' emscripten "emcc"}";'
|
|
'';
|
|
|
|
# Compile web assembly with emscripten. The --debug flag prevents us from
|
|
# minifying the JavaScript; passing it allows us to side-step more Node
|
|
# JS dependencies for installation.
|
|
preBuild = lib.optionalString webUISupport ''
|
|
mkdir -p .emscriptencache
|
|
export EM_CACHE=$(pwd)/.emscriptencache
|
|
cargo run --package xtask -- build-wasm --debug
|
|
'';
|
|
|
|
postInstall = ''
|
|
PREFIX=$out make install
|
|
${lib.optionalString (!enableShared) "rm $out/lib/*.so{,.*}"}
|
|
${lib.optionalString (!enableStatic) "rm $out/lib/*.a"}
|
|
''
|
|
+ lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
|
|
installShellCompletion --cmd tree-sitter \
|
|
--bash <("$out/bin/tree-sitter" complete --shell bash) \
|
|
--zsh <("$out/bin/tree-sitter" complete --shell zsh) \
|
|
--fish <("$out/bin/tree-sitter" complete --shell fish)
|
|
''
|
|
+ lib.optionalString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
|
|
installShellCompletion --cmd tree-sitter \
|
|
--bash "${buildPackages.tree-sitter}"/share/bash-completion/completions/*.bash \
|
|
--zsh "${buildPackages.tree-sitter}"/share/zsh/site-functions/* \
|
|
--fish "${buildPackages.tree-sitter}"/share/fish/*/*
|
|
'';
|
|
|
|
# test result: FAILED. 120 passed; 13 failed; 0 ignored; 0 measured; 0 filtered out
|
|
doCheck = false;
|
|
|
|
passthru = {
|
|
updater = {
|
|
inherit update-all-grammars;
|
|
};
|
|
inherit
|
|
grammars
|
|
buildGrammar
|
|
builtGrammars
|
|
withPlugins
|
|
allGrammars
|
|
;
|
|
|
|
updateScript = nix-update-script { };
|
|
|
|
tests = {
|
|
# make sure all grammars build
|
|
builtGrammars = lib.recurseIntoAttrs builtGrammars;
|
|
|
|
inherit lunarvim;
|
|
};
|
|
};
|
|
|
|
meta = {
|
|
homepage = "https://github.com/tree-sitter/tree-sitter";
|
|
description = "Parser generator tool and an incremental parsing library";
|
|
mainProgram = "tree-sitter";
|
|
changelog = "https://github.com/tree-sitter/tree-sitter/releases/tag/v${version}";
|
|
longDescription = ''
|
|
Tree-sitter is a parser generator tool and an incremental parsing library.
|
|
It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited.
|
|
|
|
Tree-sitter aims to be:
|
|
|
|
* General enough to parse any programming language
|
|
* Fast enough to parse on every keystroke in a text editor
|
|
* Robust enough to provide useful results even in the presence of syntax errors
|
|
* Dependency-free so that the runtime library (which is written in pure C) can be embedded in any application
|
|
'';
|
|
license = lib.licenses.mit;
|
|
maintainers = with lib.maintainers; [
|
|
Profpatsch
|
|
uncenter
|
|
];
|
|
};
|
|
}
|