https://dev.kronoz.win/r/rgit.git
1# adapted from https://github.com/helix-editor/helix/blob/217818681ea9bbc7f995c87f8794c46eeb012b1c/grammars.nix
2{ stdenv
3, lib
4, runCommand
5, includeGrammarIf ? _: true
6, grammarOverlays ? [ ]
7, helix
8, ...
9}:
10let
11 languagesConfig = builtins.fromTOML (builtins.readFile "${helix}/languages.toml");
12 isGitGrammar = grammar:
13 builtins.hasAttr "source" grammar
14 && builtins.hasAttr "git" grammar.source
15 && builtins.hasAttr "rev" grammar.source;
16 isGitHubGrammar = grammar: lib.hasPrefix "https://github.com" grammar.source.git;
17 toGitHubFetcher = url:
18 let
19 match = builtins.match "https://github\.com/([^/]*)/([^/]*)/?" url;
20 in
21 {
22 owner = builtins.elemAt match 0;
23 repo = builtins.elemAt match 1;
24 };
25 # If `use-grammars.only` is set, use only those grammars.
26 # If `use-grammars.except` is set, use all other grammars.
27 # Otherwise use all grammars.
28 useGrammar = grammar:
29 if languagesConfig?use-grammars.only then
30 builtins.elem grammar.name languagesConfig.use-grammars.only
31 else if languagesConfig?use-grammars.except then
32 !(builtins.elem grammar.name languagesConfig.use-grammars.except)
33 else true;
34 grammarsToUse = builtins.filter useGrammar languagesConfig.grammar;
35 gitGrammars = builtins.filter isGitGrammar grammarsToUse;
36 buildGrammar = grammar:
37 let
38 gh = toGitHubFetcher grammar.source.git;
39 sourceGit = builtins.fetchTree {
40 type = "git";
41 url = grammar.source.git;
42 inherit (grammar.source) rev;
43 ref = grammar.source.ref or "HEAD";
44 shallow = true;
45 };
46 sourceGitHub = builtins.fetchTree {
47 type = "github";
48 inherit (gh) owner;
49 inherit (gh) repo;
50 inherit (grammar.source) rev;
51 };
52 source =
53 if isGitHubGrammar grammar
54 then sourceGitHub
55 else sourceGit;
56 in
57 stdenv.mkDerivation {
58 # see https://github.com/NixOS/nixpkgs/blob/fbdd1a7c0bc29af5325e0d7dd70e804a972eb465/pkgs/development/tools/parsing/tree-sitter/grammar.nix
59
60 pname = "tree-sitter-${grammar.name}";
61 version = grammar.source.rev;
62
63 src = source;
64 sourceRoot =
65 if builtins.hasAttr "subpath" grammar.source then
66 "source/${grammar.source.subpath}"
67 else
68 "source";
69
70 dontConfigure = true;
71
72 FLAGS = [
73 "-Isrc"
74 "-g"
75 "-O3"
76 "-fPIC"
77 "-fno-exceptions"
78 "-Wl,-z,relro,-z,now"
79 ];
80
81 NAME = "libtree-sitter-${grammar.name}";
82
83 buildPhase = ''
84 runHook preBuild
85
86 if [[ -e src/scanner.cc ]]; then
87 $CXX -c src/scanner.cc -o scanner.o $FLAGS
88 elif [[ -e src/scanner.c ]]; then
89 $CC -c src/scanner.c -o scanner.o $FLAGS
90 fi
91
92 $CC -c src/parser.c -o parser.o $FLAGS
93 $CXX -shared${lib.optionalString stdenv.isDarwin " -install_name $out/$NAME.so"} -o $NAME.so *.o
94
95 runHook postBuild
96 '';
97
98 installPhase = ''
99 runHook preInstall
100 mkdir $out
101 mv $NAME.so $out/
102 runHook postInstall
103 '';
104
105 # Strip failed on darwin: strip: error: symbols referenced by indirect symbol table entries that can't be stripped
106 fixupPhase = lib.optionalString stdenv.isLinux ''
107 runHook preFixup
108 $STRIP $out/$NAME.so
109 runHook postFixup
110 '';
111 };
112 grammarsToBuild = builtins.filter includeGrammarIf gitGrammars;
113 builtGrammars = builtins.map
114 (grammar: {
115 inherit (grammar) name;
116 value = buildGrammar grammar;
117 })
118 grammarsToBuild;
119 extensibleGrammars =
120 lib.makeExtensible (self: builtins.listToAttrs builtGrammars);
121 overlayedGrammars = lib.pipe extensibleGrammars
122 (builtins.map (overlay: grammar: grammar.extend overlay) grammarOverlays);
123 grammarLinks = lib.mapAttrsToList
124 (name: artifact: "ln -s ${artifact}/libtree-sitter-${name}.so $out/libtree-sitter-${name}.so")
125 (lib.filterAttrs (n: v: lib.isDerivation v) overlayedGrammars);
126in
127runCommand "consolidated-rit-grammars" { } ''
128 mkdir -p $out
129 ${builtins.concatStringsSep "\n" grammarLinks}
130 ln -s "${helix}/languages.toml" "$out/languages.toml"
131 ln -s "${helix}/runtime/queries" "$out/queries"
132''