Unverified Commit 7f560e22 authored by Norbert Melzer's avatar Norbert Melzer Committed by GitHub
Browse files

neovimUtils: make installing queries in treesitter grammars optional (#344849)

parents 15516822 8cc8689d
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
echo "Sourcing to-nvim-treesitter-grammar.sh"

toNvimTreesitterGrammar() {
    echo "Executing toNvimTreesitterGrammar"

    mkdir -p "$out/parser"
    ln -s "$origGrammar/parser" "$out/parser/$grammarName.so"

    if [ "$installQueries" != 1 ]; then
        echo "Installing queries is disabled: installQueries=$installQueries"
        return
    fi

    echo "Installing queries for $grammarName"

    mkdir -p "$out/queries/$grammarName"
    if [ -d "$origGrammar/queries/$grammarName" ]; then
        echo "Moving queries from neovim queries dir"
        for file in "$origGrammar/queries/$grammarName/"*; do
            ln -s "$file" "$out/queries/$grammarName/$(basename "$file")"
        done
    else
        if [ -d "$origGrammar/queries" ]; then
            echo "Moving queries from standard queries dir"

            for file in "$origGrammar/queries/"*; do
                ln -s "$file" "$out/queries/$grammarName/$(basename "$file")"
            done
        else
            echo "Missing queries for $grammarName"
        fi
    fi
}

echo "Using toNvimTreesitterGrammar"
preDistPhases+=" toNvimTreesitterGrammar"
+44 −28
Original line number Diff line number Diff line
{ lib
, stdenv
, makeSetupHook
, callPackage
, vimUtils
, vimPlugins
, nodejs
, neovim-unwrapped
, bundlerEnv
@@ -8,7 +11,6 @@
, lua
, python3Packages
, wrapNeovimUnstable
, runCommand
}:
let
  inherit (vimUtils) toVimPlugin;
@@ -173,35 +175,49 @@ let
        (lib.removePrefix "tree-sitter-")
        (lib.replaceStrings [ "-" ] [ "_" ])
      ];

      nvimGrammars = lib.mapAttrsToList (name: value: value.origGrammar) vimPlugins.nvim-treesitter.grammarPlugins;
      isNvimGrammar = x: builtins.elem x nvimGrammars;

      toNvimTreesitterGrammar = callPackage ({ }:
        makeSetupHook {
          name = "to-nvim-treesitter-grammar";
        } ./to-nvim-treesitter-grammar.sh) {};
    in

    toVimPlugin (runCommand "treesitter-grammar-${name}"
      {
    (toVimPlugin (stdenv.mkDerivation {
      name = "treesitter-grammar-${name}";

      origGrammar = grammar;
      grammarName = name;

      # Queries for nvim-treesitter's (not just tree-sitter's) officially
      # supported languages are bundled with nvim-treesitter
      # Queries from repositories for such languages are incompatible
      # with nvim's implementation of treesitter.
      #
      # We try our best effort to only include queries for niche languages
      # (there are grammars for them in nixpkgs, but they're in
      # `tree-sitter-grammars.tree-sitter-*`; `vimPlugins.nvim-treesitter-parsers.*`
      # only includes officially supported languages)
      #
      # To use grammar for a niche language, users usually do:
      #   packages.all.start = with final.vimPlugins; [
      #     (pkgs.neovimUtils.grammarToPlugin pkgs.tree-sitter-grammars.tree-sitter-LANG)
      #   ]
      #
      # See also https://github.com/NixOS/nixpkgs/pull/344849#issuecomment-2381447839
      installQueries = !isNvimGrammar grammar;

      dontUnpack = true;
      __structuredAttrs = true;

      nativeBuildInputs = [ toNvimTreesitterGrammar ];

      meta = {
        platforms = lib.platforms.all;
      } // grammar.meta;
      }
      ''
        mkdir -p "$out/parser"
        ln -s "${grammar}/parser" "$out/parser/${name}.so"

        mkdir -p "$out/queries/${name}"
        if [ -d "${grammar}/queries/${name}" ]; then
          echo "moving queries from neovim queries dir"
          for file in "${grammar}/queries/${name}"*; do
            ln -s "$file" "$out/queries/${name}/$(basename "$file")"
          done
        else
          if [ -d "${grammar}/queries" ]; then
            echo "moving queries from standard queries dir"
            for file in "${grammar}/queries/"*; do
              ln -s "$file" "$out/queries/${name}/$(basename "$file")"
            done
          else
            echo "missing queries for ${name}"
          fi
        fi
      '');
    }));

  /*
    Fork of vimUtils.packDir that additionnally generates a propagated-build-inputs-file that
+93 −28
Original line number Diff line number Diff line
{ lib, callPackage, tree-sitter, neovim, neovimUtils, runCommand }:
{ lib, callPackage, tree-sitter, neovim, neovimUtils, runCommand, vimPlugins, tree-sitter-grammars }:

self: super:

let
  inherit (neovimUtils) grammarToPlugin;

  initialGeneratedGrammars = callPackage ./generated.nix {
  generatedGrammars = callPackage ./generated.nix {
    inherit (tree-sitter) buildGrammar;
  };
  grammarOverrides = final: prev: {
    nix = prev.nix.overrideAttrs {
      # workaround for https://github.com/NixOS/nixpkgs/issues/332580
      prePatch = "rm queries/highlights.scm";
    };
  };
  generatedGrammars = lib.fix (lib.extends grammarOverrides (_: initialGeneratedGrammars));

  generatedDerivations = lib.filterAttrs (_: lib.isDerivation) generatedGrammars;

@@ -61,7 +53,8 @@ in

    grammarPlugins = lib.mapAttrs (_: grammarToPlugin) generatedDerivations;

    tests.check-queries =
    tests = {
      check-queries =
        let
          nvimWithAllGrammars = neovim.override {
            configure.packages.all.start = [ withAllGrammars ];
@@ -84,6 +77,78 @@ in
              exit 1
            fi
          '';

      tree-sitter-queries-are-present-for-custom-grammars =
        let
          pluginsToCheck =
            builtins.map
            (grammar: grammarToPlugin grammar)
            # true is here because there is `recurseForDerivations = true`
            (lib.remove true
              (lib.attrValues tree-sitter-grammars)
            );
        in
        runCommand "nvim-treesitter-test-queries-are-present-for-custom-grammars"
        { CI = true; }
        ''
          function check_grammar {
            EXPECTED_FILES="$2/parser/$1.so `ls $2/queries/$1/*.scm`"

            echo
            echo expected files for $1:
            echo $EXPECTED_FILES

            # the derivation has only symlinks, and `find` doesn't count them as files
            # so we cannot use `-type f`
            for file in `find $2 -not -type d`; do
              echo checking $file
              # see https://stackoverflow.com/a/8063284
              if ! echo "$EXPECTED_FILES" | grep -wqF "$file"; then
                echo $file is unexpected, exiting
                exit 1
              fi
            done
          }

          ${lib.concatLines
            (lib.forEach
              pluginsToCheck
              (g: "check_grammar \"${g.grammarName}\" \"${g}\"")
            )
          }
          touch $out
        '';

      no-queries-for-official-grammars =
        let
          pluginsToCheck =
            # true is here because there is `recurseForDerivations = true`
            (lib.remove true
              (lib.attrValues vimPlugins.nvim-treesitter-parsers)
            );
        in
        runCommand "nvim-treesitter-test-no-queries-for-official-grammars"
        { CI = true; }
        ''
          touch $out

          function check_grammar {
            echo checking $1...
            if [ -d $2/queries ]; then
              echo Queries dir exists in $1
              echo This is unexpected, see https://github.com/NixOS/nixpkgs/pull/344849#issuecomment-2381447839
              exit 1
            fi
          }

          ${lib.concatLines
            (lib.forEach
              pluginsToCheck
              (g: "check_grammar \"${g.grammarName}\" \"${g}\"")
            )
          }
        '';
    };
  };

  meta = with lib; (super.nvim-treesitter.meta or { }) // {