Skip to content

Commit

Permalink
tree-sitter: add shell completions
Browse files Browse the repository at this point in the history
Adds shell completions for `bash`, `fish`, and `zsh`. Tree-sitter also
supports `elvish` and `powershell`, and will support `nushell` in the
next release.

Also properly formats the `tree-sitter` derivation.

Note that I have only tested the bash completions!
  • Loading branch information
ribru17 committed Dec 11, 2024
1 parent b343873 commit 3be7fe0
Showing 1 changed file with 137 additions and 63 deletions.
200 changes: 137 additions & 63 deletions pkgs/development/tools/parsing/tree-sitter/default.nix
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
{ lib
, stdenv
, fetchgit
, fetchFromGitHub
, nix-update-script
, runCommand
, which
, rustPlatform
, emscripten
, Security
, callPackage
, linkFarm
, substitute
, CoreServices
, enableShared ? !stdenv.hostPlatform.isStatic
, enableStatic ? stdenv.hostPlatform.isStatic
, webUISupport ? false
, extraGrammars ? { }

# tests
, lunarvim
{
lib,
stdenv,
fetchgit,
fetchFromGitHub,
nix-update-script,
runCommand,
which,
rustPlatform,
emscripten,
Security,
callPackage,
linkFarm,
substitute,
CoreServices,
enableShared ? !stdenv.hostPlatform.isStatic,
enableStatic ? stdenv.hostPlatform.isStatic,
webUISupport ? false,
extraGrammars ? { },

# tests
lunarvim,
}:

let
Expand All @@ -40,20 +41,35 @@ let

update-all-grammars = callPackage ./update.nix { };

fetchGrammar = (v: fetchgit { inherit (v) url rev sha256 fetchSubmodules; });
fetchGrammar = (
v:
fetchgit {
inherit (v)
url
rev
sha256
fetchSubmodules
;
}
);

grammars =
runCommand "grammars" { } (''
grammars = runCommand "grammars" { } (
''
mkdir $out
'' + (lib.concatStrings (lib.mapAttrsToList
(name: grammar: "ln -s ${if grammar ? src then grammar.src else fetchGrammar grammar} $out/${name}\n")
(import ./grammars { inherit lib; }))));
''
+ (lib.concatStrings (
lib.mapAttrsToList (
name: grammar: "ln -s ${if grammar ? src then grammar.src else fetchGrammar grammar} $out/${name}\n"
) (import ./grammars { inherit lib; })
))
);

buildGrammar = callPackage ./grammar.nix { };

builtGrammars =
let
build = name: grammar:
build =
name: grammar:
buildGrammar {
language = grammar.language or name;
inherit version;
Expand All @@ -62,17 +78,59 @@ let
generate = grammar.generate or false;
};
grammars' = import ./grammars { inherit lib; } // extraGrammars;
grammars = grammars' //
{ tree-sitter-latex = grammars'.tree-sitter-latex // { generate = true; }; } //
{ tree-sitter-ocaml = grammars'.tree-sitter-ocaml // { location = "grammars/ocaml"; }; } //
{ tree-sitter-ocaml-interface = grammars'.tree-sitter-ocaml // { location = "grammars/interface"; }; } //
{ tree-sitter-org-nvim = grammars'.tree-sitter-org-nvim // { language = "tree-sitter-org"; }; } //
{ tree-sitter-typescript = grammars'.tree-sitter-typescript // { location = "typescript"; }; } //
{ tree-sitter-tsx = grammars'.tree-sitter-typescript // { location = "tsx"; }; } //
{ tree-sitter-markdown = grammars'.tree-sitter-markdown // { location = "tree-sitter-markdown"; }; } //
{ tree-sitter-markdown-inline = grammars'.tree-sitter-markdown // { language = "tree-sitter-markdown_inline"; location = "tree-sitter-markdown-inline"; }; } //
{ tree-sitter-php = grammars'.tree-sitter-php // { location = "php"; }; } //
{ tree-sitter-sql = grammars'.tree-sitter-sql // { generate = true; }; };
grammars =
grammars'
// {
tree-sitter-latex = grammars'.tree-sitter-latex // {
generate = true;
};
}
// {
tree-sitter-ocaml = grammars'.tree-sitter-ocaml // {
location = "grammars/ocaml";
};
}
// {
tree-sitter-ocaml-interface = grammars'.tree-sitter-ocaml // {
location = "grammars/interface";
};
}
// {
tree-sitter-org-nvim = grammars'.tree-sitter-org-nvim // {
language = "tree-sitter-org";
};
}
// {
tree-sitter-typescript = grammars'.tree-sitter-typescript // {
location = "typescript";
};
}
// {
tree-sitter-tsx = grammars'.tree-sitter-typescript // {
location = "tsx";
};
}
// {
tree-sitter-markdown = grammars'.tree-sitter-markdown // {
location = "tree-sitter-markdown";
};
}
// {
tree-sitter-markdown-inline = grammars'.tree-sitter-markdown // {
language = "tree-sitter-markdown_inline";
location = "tree-sitter-markdown-inline";
};
}
// {
tree-sitter-php = grammars'.tree-sitter-php // {
location = "php";
};
}
// {
tree-sitter-sql = grammars'.tree-sitter-sql // {
generate = true;
};
};
in
lib.mapAttrs build (grammars);

Expand All @@ -83,26 +141,27 @@ let
# pkgs.tree-sitter.withPlugins (_: allGrammars)
# which is equivalent to
# pkgs.tree-sitter.withPlugins (p: builtins.attrValues p)
withPlugins = grammarFn:
withPlugins =
grammarFn:
let
grammars = grammarFn builtGrammars;
in
linkFarm "grammars"
(map
(drv:
let
name = lib.strings.getName drv;
in
{
name =
(lib.strings.replaceStrings [ "-" ] [ "_" ]
(lib.strings.removePrefix "tree-sitter-"
(lib.strings.removeSuffix "-grammar" name)))
+ ".so";
path = "${drv}/parser";
}
)
grammars);
linkFarm "grammars" (
map (
drv:
let
name = lib.strings.getName drv;
in
{
name =
(lib.strings.replaceStrings [ "-" ] [ "_" ] (
lib.strings.removePrefix "tree-sitter-" (lib.strings.removeSuffix "-grammar" name)
))
+ ".so";
path = "${drv}/parser";
}
) grammars
);

allGrammars = builtins.attrValues builtGrammars;

Expand All @@ -113,16 +172,20 @@ rustPlatform.buildRustPackage {

cargoHash = "sha256-0ZoXf0eV3kmHaRoHcWrVEgoWnYNBsY9GiFfy84H+0mc=";

buildInputs =
lib.optionals stdenv.hostPlatform.isDarwin [ Security CoreServices ];
nativeBuildInputs =
[ which ]
++ lib.optionals webUISupport [ emscripten ];
buildInputs = lib.optionals stdenv.hostPlatform.isDarwin [
Security
CoreServices
];
nativeBuildInputs = [ which ] ++ lib.optionals webUISupport [ emscripten ];

patches = lib.optionals webUISupport [
(substitute {
src = ./fix-paths.patch;
substitutions = [ "--subst-var-by" "emcc" "${emscripten}/bin/emcc" ];
substitutions = [
"--subst-var-by"
"emcc"
"${emscripten}/bin/emcc"
];
})
];

Expand Down Expand Up @@ -150,6 +213,11 @@ rustPlatform.buildRustPackage {
PREFIX=$out make install
${lib.optionalString (!enableShared) "rm $out/lib/*.so{,.*}"}
${lib.optionalString (!enableStatic) "rm $out/lib/*.a"}
mkdir -p $out/share/{bash-completion/completions,fish/vendor_completions.d,zsh/site-functions}
$out/bin/tree-sitter complete --shell bash > $out/share/bash-completion/completions/tree-sitter
$out/bin/tree-sitter complete --shell fish > $out/share/fish/vendor_completions.d/tree-sitter.fish
$out/bin/tree-sitter complete --shell zsh > $out/share/zsh/site-functions/_tree-sitter
'';

# test result: FAILED. 120 passed; 13 failed; 0 ignored; 0 measured; 0 filtered out
Expand All @@ -159,7 +227,13 @@ rustPlatform.buildRustPackage {
updater = {
inherit update-all-grammars;
};
inherit grammars buildGrammar builtGrammars withPlugins allGrammars;
inherit
grammars
buildGrammar
builtGrammars
withPlugins
allGrammars
;

updateScript = nix-update-script { };

Expand Down

0 comments on commit 3be7fe0

Please sign in to comment.