nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 fetchFromGitLab,
6 fetchFromSourcehut,
7 nix-update-script,
8 runCommand,
9 which,
10 rustPlatform,
11 emscripten,
12 openssl,
13 pkg-config,
14 callPackage,
15 linkFarm,
16 substitute,
17 installShellFiles,
18 buildPackages,
19 enableShared ? !stdenv.hostPlatform.isStatic,
20 enableStatic ? stdenv.hostPlatform.isStatic,
21 webUISupport ? false,
22
23 # tests
24 lunarvim,
25}:
26
27let
28 /**
29 Build a parser grammar and put the resulting shared object in `$out/parser`.
30
31 # Example
32
33 ```nix
34 tree-sitter-foo = pkgs.tree-sitter.buildGrammar {
35 language = "foo";
36 version = "0.42.0";
37 src = fetchFromGitHub { ... };
38 };
39 ```
40 */
41 buildGrammar = callPackage ./build-grammar.nix { };
42
43 /**
44 Attrset of grammar sources.
45
46 Values are of the form { language, version, src }. These may be referenced
47 directly by other areas of the tree-sitter ecosystem in nixpkgs. Src will
48 contain all language bindings provided by the upstream grammar.
49
50 Use pkgs.tree-sitter.grammars.<name> to access.
51 */
52 grammars = import ./grammars {
53 inherit
54 lib
55 nix-update-script
56 fetchFromGitHub
57 fetchFromGitLab
58 fetchFromSourcehut
59 ;
60 };
61
62 /**
63 Attrset of compiled grammars.
64
65 Compiled grammars contain the pre-built shared library and any queries from
66 the grammar source.
67
68 Use pkgs.tree-sitter-grammars.<name> to access.
69 */
70 builtGrammars = lib.mapAttrs (_: lib.makeOverridable buildGrammar) grammars;
71
72 # Usage:
73 # pkgs.tree-sitter.withPlugins (p: [ p.tree-sitter-c p.tree-sitter-java ... ])
74 #
75 # or for all grammars:
76 # pkgs.tree-sitter.withPlugins (_: pkgs.tree-sitter.allGrammars)
77 # which is equivalent to
78 # pkgs.tree-sitter.withPlugins (p: builtins.attrValues p)
79 withPlugins =
80 grammarFn:
81 let
82 grammars = grammarFn builtGrammars;
83 in
84 linkFarm "grammars" (
85 map (
86 drv:
87 let
88 name = lib.strings.getName drv;
89 in
90 {
91 name =
92 (lib.strings.replaceStrings [ "-" ] [ "_" ] (
93 lib.strings.removePrefix "tree-sitter-" (lib.strings.removeSuffix "-grammar" name)
94 ))
95 + ".so";
96 path = "${drv}/parser";
97 }
98 ) grammars
99 );
100
101 allGrammars = lib.filter (p: !(p.meta.broken or false)) (lib.attrValues builtGrammars);
102
103in
104rustPlatform.buildRustPackage (final: {
105 pname = "tree-sitter";
106 version = "0.25.10";
107
108 src = fetchFromGitHub {
109 owner = "tree-sitter";
110 repo = "tree-sitter";
111 tag = "v${final.version}";
112 hash = "sha256-aHszbvLCLqCwAS4F4UmM3wbSb81QuG9FM7BDHTu1ZvM=";
113 fetchSubmodules = true;
114 };
115
116 cargoHash = "sha256-4R5Y9yancbg/w3PhACtsWq0+gieUd2j8YnmEj/5eqkg=";
117
118 buildInputs = [
119 installShellFiles
120 ]
121 ++ lib.optionals webUISupport [
122 openssl
123 ];
124 nativeBuildInputs = [
125 which
126 ]
127 ++ lib.optionals webUISupport [
128 emscripten
129 pkg-config
130 ];
131
132 patches = lib.optionals (!webUISupport) [
133 (substitute {
134 src = ./remove-web-interface.patch;
135 })
136 ];
137
138 postPatch =
139 lib.optionalString webUISupport ''
140 substituteInPlace cli/loader/src/lib.rs \
141 --replace-fail 'let emcc_name = if cfg!(windows) { "emcc.bat" } else { "emcc" };' 'let emcc_name = "${lib.getExe' emscripten "emcc"}";'
142 ''
143 # when building on static platforms:
144 # 1. remove the `libtree-sitter.$(SOEXT)` step from `all`
145 # 2. remove references to shared object files in the Makefile
146 + lib.optionalString stdenv.hostPlatform.isStatic ''
147 substituteInPlace ./Makefile \
148 --replace-fail 'all: libtree-sitter.a libtree-sitter.$(SOEXT) tree-sitter.pc' 'all: libtree-sitter.a tree-sitter.pc'
149 sed -i '/^install:/,/^[^[:space:]]/ { /$(SOEXT/d; }' ./Makefile
150 '';
151
152 # Compile web assembly with emscripten. The --debug flag prevents us from
153 # minifying the JavaScript; passing it allows us to side-step more Node
154 # JS dependencies for installation.
155 preBuild = lib.optionalString webUISupport ''
156 mkdir -p .emscriptencache
157 export EM_CACHE=$(pwd)/.emscriptencache
158 cargo run --package xtask -- build-wasm --debug
159 '';
160
161 postInstall = ''
162 PREFIX=$out make install
163 ${lib.optionalString (!enableShared) "rm -f $out/lib/*.so{,.*}"}
164 ${lib.optionalString (!enableStatic) "rm -f $out/lib/*.a"}
165 ''
166 + lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
167 installShellCompletion --cmd tree-sitter \
168 --bash <("$out/bin/tree-sitter" complete --shell bash) \
169 --zsh <("$out/bin/tree-sitter" complete --shell zsh) \
170 --fish <("$out/bin/tree-sitter" complete --shell fish)
171 ''
172 + lib.optionalString (!stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
173 installShellCompletion --cmd tree-sitter \
174 --bash "${buildPackages.tree-sitter}"/share/bash-completion/completions/*.bash \
175 --zsh "${buildPackages.tree-sitter}"/share/zsh/site-functions/* \
176 --fish "${buildPackages.tree-sitter}"/share/fish/*/*
177 '';
178
179 # test result: FAILED. 120 passed; 13 failed; 0 ignored; 0 measured; 0 filtered out
180 doCheck = false;
181
182 passthru = {
183 inherit
184 grammars
185 buildGrammar
186 builtGrammars
187 withPlugins
188 allGrammars
189 ;
190
191 updateScript = nix-update-script { };
192
193 tests = {
194 # make sure all grammars build
195 builtGrammars = lib.recurseIntoAttrs builtGrammars;
196
197 inherit lunarvim;
198 };
199 };
200
201 meta = {
202 homepage = "https://github.com/tree-sitter/tree-sitter";
203 description = "Parser generator tool and an incremental parsing library";
204 mainProgram = "tree-sitter";
205 changelog = "https://github.com/tree-sitter/tree-sitter/releases/tag/v${final.version}";
206 longDescription = ''
207 Tree-sitter is a parser generator tool and an incremental parsing library.
208 It can build a concrete syntax tree for a source file and efficiently update the syntax tree as the source file is edited.
209
210 Tree-sitter aims to be:
211
212 * General enough to parse any programming language
213 * Fast enough to parse on every keystroke in a text editor
214 * Robust enough to provide useful results even in the presence of syntax errors
215 * Dependency-free so that the runtime library (which is written in pure C) can be embedded in any application
216 '';
217 license = lib.licenses.mit;
218 maintainers = with lib.maintainers; [
219 Profpatsch
220 uncenter
221 amaanq
222 ];
223 };
224})