]> luflow.net public git repositories - flow-web.git/blob - static/highlight/languages/nix.js
Initial commit.
[flow-web.git] / static / highlight / languages / nix.js
1 /*! `nix` grammar compiled for Highlight.js 11.11.1 */
2 (function(){
3 var hljsGrammar = (function () {
4 'use strict';
5
6 /*
7 Language: Nix
8 Author: Domen Kožar <domen@dev.si>
9 Description: Nix functional language
10 Website: http://nixos.org/nix
11 Category: system
12 */
13
14 /** @type LanguageFn */
15 function nix(hljs) {
16 const regex = hljs.regex;
17 const KEYWORDS = {
18 keyword: [
19 "assert",
20 "else",
21 "if",
22 "in",
23 "inherit",
24 "let",
25 "or",
26 "rec",
27 "then",
28 "with",
29 ],
30 literal: [
31 "true",
32 "false",
33 "null",
34 ],
35 built_in: [
36 // toplevel builtins
37 "abort",
38 "baseNameOf",
39 "builtins",
40 "derivation",
41 "derivationStrict",
42 "dirOf",
43 "fetchGit",
44 "fetchMercurial",
45 "fetchTarball",
46 "fetchTree",
47 "fromTOML",
48 "import",
49 "isNull",
50 "map",
51 "placeholder",
52 "removeAttrs",
53 "scopedImport",
54 "throw",
55 "toString",
56 ],
57 };
58
59 const BUILTINS = {
60 scope: 'built_in',
61 match: regex.either(...[
62 "abort",
63 "add",
64 "addDrvOutputDependencies",
65 "addErrorContext",
66 "all",
67 "any",
68 "appendContext",
69 "attrNames",
70 "attrValues",
71 "baseNameOf",
72 "bitAnd",
73 "bitOr",
74 "bitXor",
75 "break",
76 "builtins",
77 "catAttrs",
78 "ceil",
79 "compareVersions",
80 "concatLists",
81 "concatMap",
82 "concatStringsSep",
83 "convertHash",
84 "currentSystem",
85 "currentTime",
86 "deepSeq",
87 "derivation",
88 "derivationStrict",
89 "dirOf",
90 "div",
91 "elem",
92 "elemAt",
93 "false",
94 "fetchGit",
95 "fetchMercurial",
96 "fetchTarball",
97 "fetchTree",
98 "fetchurl",
99 "filter",
100 "filterSource",
101 "findFile",
102 "flakeRefToString",
103 "floor",
104 "foldl'",
105 "fromJSON",
106 "fromTOML",
107 "functionArgs",
108 "genList",
109 "genericClosure",
110 "getAttr",
111 "getContext",
112 "getEnv",
113 "getFlake",
114 "groupBy",
115 "hasAttr",
116 "hasContext",
117 "hashFile",
118 "hashString",
119 "head",
120 "import",
121 "intersectAttrs",
122 "isAttrs",
123 "isBool",
124 "isFloat",
125 "isFunction",
126 "isInt",
127 "isList",
128 "isNull",
129 "isPath",
130 "isString",
131 "langVersion",
132 "length",
133 "lessThan",
134 "listToAttrs",
135 "map",
136 "mapAttrs",
137 "match",
138 "mul",
139 "nixPath",
140 "nixVersion",
141 "null",
142 "parseDrvName",
143 "parseFlakeRef",
144 "partition",
145 "path",
146 "pathExists",
147 "placeholder",
148 "readDir",
149 "readFile",
150 "readFileType",
151 "removeAttrs",
152 "replaceStrings",
153 "scopedImport",
154 "seq",
155 "sort",
156 "split",
157 "splitVersion",
158 "storeDir",
159 "storePath",
160 "stringLength",
161 "sub",
162 "substring",
163 "tail",
164 "throw",
165 "toFile",
166 "toJSON",
167 "toPath",
168 "toString",
169 "toXML",
170 "trace",
171 "traceVerbose",
172 "true",
173 "tryEval",
174 "typeOf",
175 "unsafeDiscardOutputDependency",
176 "unsafeDiscardStringContext",
177 "unsafeGetAttrPos",
178 "warn",
179 "zipAttrsWith",
180 ].map(b => `builtins\\.${b}`)),
181 relevance: 10,
182 };
183
184 const IDENTIFIER_REGEX = '[A-Za-z_][A-Za-z0-9_\'-]*';
185
186 const LOOKUP_PATH = {
187 scope: 'symbol',
188 match: new RegExp(`<${IDENTIFIER_REGEX}(/${IDENTIFIER_REGEX})*>`),
189 };
190
191 const PATH_PIECE = "[A-Za-z0-9_\\+\\.-]+";
192 const PATH = {
193 scope: 'symbol',
194 match: new RegExp(`(\\.\\.|\\.|~)?/(${PATH_PIECE})?(/${PATH_PIECE})*(?=[\\s;])`),
195 };
196
197 const OPERATOR_WITHOUT_MINUS_REGEX = regex.either(...[
198 '==',
199 '=',
200 '\\+\\+',
201 '\\+',
202 '<=',
203 '<\\|',
204 '<',
205 '>=',
206 '>',
207 '->',
208 '//',
209 '/',
210 '!=',
211 '!',
212 '\\|\\|',
213 '\\|>',
214 '\\?',
215 '\\*',
216 '&&',
217 ]);
218
219 const OPERATOR = {
220 scope: 'operator',
221 match: regex.concat(OPERATOR_WITHOUT_MINUS_REGEX, /(?!-)/),
222 relevance: 0,
223 };
224
225 // '-' is being handled by itself to ensure we are able to tell the difference
226 // between a dash in an identifier and a minus operator
227 const NUMBER = {
228 scope: 'number',
229 match: new RegExp(`${hljs.NUMBER_RE}(?!-)`),
230 relevance: 0,
231 };
232 const MINUS_OPERATOR = {
233 variants: [
234 {
235 scope: 'operator',
236 beforeMatch: /\s/,
237 // The (?!>) is used to ensure this doesn't collide with the '->' operator
238 begin: /-(?!>)/,
239 },
240 {
241 begin: [
242 new RegExp(`${hljs.NUMBER_RE}`),
243 /-/,
244 /(?!>)/,
245 ],
246 beginScope: {
247 1: 'number',
248 2: 'operator'
249 },
250 },
251 {
252 begin: [
253 OPERATOR_WITHOUT_MINUS_REGEX,
254 /-/,
255 /(?!>)/,
256 ],
257 beginScope: {
258 1: 'operator',
259 2: 'operator'
260 },
261 },
262 ],
263 relevance: 0,
264 };
265
266 const ATTRS = {
267 beforeMatch: /(^|\{|;)\s*/,
268 begin: new RegExp(`${IDENTIFIER_REGEX}(\\.${IDENTIFIER_REGEX})*\\s*=(?!=)`),
269 returnBegin: true,
270 relevance: 0,
271 contains: [
272 {
273 scope: 'attr',
274 match: new RegExp(`${IDENTIFIER_REGEX}(\\.${IDENTIFIER_REGEX})*(?=\\s*=)`),
275 relevance: 0.2,
276 }
277 ],
278 };
279
280 const NORMAL_ESCAPED_DOLLAR = {
281 scope: 'char.escape',
282 match: /\\\$/,
283 };
284 const INDENTED_ESCAPED_DOLLAR = {
285 scope: 'char.escape',
286 match: /''\$/,
287 };
288 const ANTIQUOTE = {
289 scope: 'subst',
290 begin: /\$\{/,
291 end: /\}/,
292 keywords: KEYWORDS,
293 };
294 const ESCAPED_DOUBLEQUOTE = {
295 scope: 'char.escape',
296 match: /'''/,
297 };
298 const ESCAPED_LITERAL = {
299 scope: 'char.escape',
300 match: /\\(?!\$)./,
301 };
302 const STRING = {
303 scope: 'string',
304 variants: [
305 {
306 begin: "''",
307 end: "''",
308 contains: [
309 INDENTED_ESCAPED_DOLLAR,
310 ANTIQUOTE,
311 ESCAPED_DOUBLEQUOTE,
312 ESCAPED_LITERAL,
313 ],
314 },
315 {
316 begin: '"',
317 end: '"',
318 contains: [
319 NORMAL_ESCAPED_DOLLAR,
320 ANTIQUOTE,
321 ESCAPED_LITERAL,
322 ],
323 },
324 ],
325 };
326
327 const FUNCTION_PARAMS = {
328 scope: 'params',
329 match: new RegExp(`${IDENTIFIER_REGEX}\\s*:(?=\\s)`),
330 };
331
332 const EXPRESSIONS = [
333 NUMBER,
334 hljs.HASH_COMMENT_MODE,
335 hljs.C_BLOCK_COMMENT_MODE,
336 hljs.COMMENT(
337 /\/\*\*(?!\/)/,
338 /\*\//,
339 {
340 subLanguage: 'markdown',
341 relevance: 0
342 }
343 ),
344 BUILTINS,
345 STRING,
346 LOOKUP_PATH,
347 PATH,
348 FUNCTION_PARAMS,
349 ATTRS,
350 MINUS_OPERATOR,
351 OPERATOR,
352 ];
353
354 ANTIQUOTE.contains = EXPRESSIONS;
355
356 const REPL = [
357 {
358 scope: 'meta.prompt',
359 match: /^nix-repl>(?=\s)/,
360 relevance: 10,
361 },
362 {
363 scope: 'meta',
364 beforeMatch: /\s+/,
365 begin: /:([a-z]+|\?)/,
366 },
367 ];
368
369 return {
370 name: 'Nix',
371 aliases: [ "nixos" ],
372 keywords: KEYWORDS,
373 contains: EXPRESSIONS.concat(REPL),
374 };
375 }
376
377 return nix;
378
379 })();
380
381 hljs.registerLanguage('nix', hljsGrammar);
382 })();