gitscope
← rgit / main / grammars.nix
https://dev.kronoz.win/r/rgit.git
grammars.nix · Nix
Blame Raw
  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''