mirror of
https://github.com/nix-community/nixvim.git
synced 2025-12-23 01:11:12 +01:00
plugins/treesitter: support new api
New treesitter branch will have a completely new API. update to support both legacy and new apis
This commit is contained in:
parent
7b6824421a
commit
22ee0f0721
2 changed files with 159 additions and 202 deletions
|
|
@ -21,23 +21,42 @@ let
|
||||||
in
|
in
|
||||||
lib.nixvim.plugins.mkNeovimPlugin {
|
lib.nixvim.plugins.mkNeovimPlugin {
|
||||||
name = "treesitter";
|
name = "treesitter";
|
||||||
moduleName = "nvim-treesitter.configs";
|
moduleName = "nvim-treesitter";
|
||||||
package = "nvim-treesitter";
|
package = "nvim-treesitter";
|
||||||
|
|
||||||
description = ''
|
description = ''
|
||||||
Provides an interface to [tree-sitter]
|
Provides an interface to [tree-sitter] for Neovim.
|
||||||
|
|
||||||
> [!NOTE]
|
> [!NOTE]
|
||||||
> This plugin defaults to all functionality disabled.
|
> This module targets the nvim-treesitter **main** branch (the current standard) and enables features via Neovim's native treesitter APIs.
|
||||||
>
|
> For backwards compatibility, if the legacy **master** branch is detected at runtime, your `settings` are forwarded to `require('nvim-treesitter.configs').setup()`.
|
||||||
> Please explicitly enable the features you would like to use in `plugins.treesitter.settings`.
|
|
||||||
> For example, to enable syntax highlighting use the `plugins.treesitter.settings.highlight.enable` option.
|
|
||||||
|
|
||||||
### Installing tree-sitter grammars from Nixpkgs
|
## Quick Start
|
||||||
|
|
||||||
By default, **all** available grammars packaged in the `nvim-treesitter` package are installed.
|
```nix
|
||||||
|
{
|
||||||
|
plugins.treesitter = {
|
||||||
|
enable = true;
|
||||||
|
folding = true;
|
||||||
|
highlight.enable = true;
|
||||||
|
indent.enable = true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
If you'd like more control, you could instead specify which packages to install. For example:
|
Features are enabled via Neovim's native APIs:
|
||||||
|
- `folding` → Configures vim fold options to use `vim.treesitter.foldexpr()`
|
||||||
|
- `highlight.enable` → Calls `vim.treesitter.start()` on FileType events
|
||||||
|
- `indent.enable` → Sets `indentexpr` to use treesitter's indent function
|
||||||
|
|
||||||
|
## Installing Grammar Parsers
|
||||||
|
|
||||||
|
### Via Nix (Recommended)
|
||||||
|
|
||||||
|
By default, **all** available grammars are installed via Nix. This provides reproducible builds,
|
||||||
|
no runtime compilation, and offline availability.
|
||||||
|
|
||||||
|
Customize which parsers to install:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
|
|
@ -62,46 +81,31 @@ lib.nixvim.plugins.mkNeovimPlugin {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Installing tree-sitter grammars from nvim-treesitter
|
Verify installed parsers with `:checkhealth vim.treesitter`.
|
||||||
|
|
||||||
The default behavior is **not** to install any grammars through the plugin.
|
### Via Runtime Installation
|
||||||
We usually recommend installing grammars through nixpkgs instead (see above).
|
|
||||||
|
|
||||||
If you'd like to install a grammar through nvim-treesitter, you can run `:TSInstall <grammar>` within vim
|
Parsers cannot be configured to auto-install. Instead:
|
||||||
or use the `plugins.treesitter.settings.ensure_installed` option to specify grammars you want the plugin to fetch and install.
|
- Use `:TSInstall <language>` to install parsers manually
|
||||||
|
- Use `:TSUninstall <language>` to remove parsers
|
||||||
|
|
||||||
|
Configure the parser installation directory if needed:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
plugins.treesitter = {
|
plugins.treesitter.settings = {
|
||||||
enable = true;
|
install_dir.__raw = "vim.fs.joinpath(vim.fn.stdpath('data'), 'site')";
|
||||||
|
|
||||||
settings = {
|
|
||||||
# NOTE: You can set whether `nvim-treesitter` should automatically install the grammars.
|
|
||||||
auto_install = false;
|
|
||||||
ensure_installed = [
|
|
||||||
"git_config"
|
|
||||||
"git_rebase"
|
|
||||||
"gitattributes"
|
|
||||||
"gitcommit"
|
|
||||||
"gitignore"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
NOTE: You can combine the functionality of `plugins.treesitter.nixGrammars` and `plugins.treesitter.settings.ensure_installed`.
|
## Custom Grammars
|
||||||
This may be useful if a grammar isn't available from nixpkgs or you prefer to have specific grammars managed by nvim-treesitter.
|
|
||||||
|
|
||||||
### Installing Your Own Grammars with Nixvim
|
Build and install your own grammar:
|
||||||
|
|
||||||
The grammars you want will usually be included in `nixGrammars` by default.
|
|
||||||
But, in the rare case it isn't, you can build your own and use it with Nixvim like so:
|
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
let
|
let
|
||||||
# Example of building your own grammar
|
|
||||||
treesitter-nu-grammar = pkgs.tree-sitter.buildGrammar {
|
treesitter-nu-grammar = pkgs.tree-sitter.buildGrammar {
|
||||||
language = "nu";
|
language = "nu";
|
||||||
version = "0.0.0+rev=0bb9a60";
|
version = "0.0.0+rev=0bb9a60";
|
||||||
|
|
@ -113,71 +117,22 @@ lib.nixvim.plugins.mkNeovimPlugin {
|
||||||
};
|
};
|
||||||
meta.homepage = "https://github.com/nushell/tree-sitter-nu";
|
meta.homepage = "https://github.com/nushell/tree-sitter-nu";
|
||||||
};
|
};
|
||||||
|
|
||||||
# or you can yoink any grammars in tree-sitter.grammars.''${grammar-name}
|
|
||||||
# treesitter-nu-grammar = pkgs.tree-sitter-grammars.tree-sitter-nu;
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
programs.nixvim = {
|
programs.nixvim.plugins.treesitter = {
|
||||||
plugins = {
|
enable = true;
|
||||||
treesitter = {
|
grammarPackages = pkgs.vimPlugins.nvim-treesitter.passthru.allGrammars ++ [ treesitter-nu-grammar ];
|
||||||
enable = true;
|
|
||||||
settings.indent.enable = true;
|
|
||||||
grammarPackages = pkgs.vimPlugins.nvim-treesitter.passthru.allGrammars ++ [
|
|
||||||
treesitter-nu-grammar
|
|
||||||
];
|
|
||||||
luaConfig.post=
|
|
||||||
'''
|
|
||||||
do
|
|
||||||
local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
|
|
||||||
-- change the following as needed
|
|
||||||
parser_config.nu = {
|
|
||||||
install_info = {
|
|
||||||
url = "''${treesitter-nu-grammar}", -- local path or git repo
|
|
||||||
files = {"src/parser.c"}, -- note that some parsers also require src/scanner.c or src/scanner.cc
|
|
||||||
-- optional entries:
|
|
||||||
-- branch = "main", -- default branch in case of git repo if different from master
|
|
||||||
-- generate_requires_npm = false, -- if stand-alone parser without npm dependencies
|
|
||||||
-- requires_generate_from_grammar = false, -- if folder contains pre-generated src/parser.c
|
|
||||||
},
|
|
||||||
filetype = "nu", -- if filetype does not match the parser name
|
|
||||||
}
|
|
||||||
end
|
|
||||||
''';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Add as extra plugins so that their `queries/{language}/*.scm` get
|
# Register the parser to filetype
|
||||||
# installed and can be picked up by `tree-sitter`
|
languageRegister.nu = "nu";
|
||||||
extraPlugins = [
|
|
||||||
treesitter-nu-grammar
|
|
||||||
];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
programs.nixvim.extraPlugins = [ treesitter-nu-grammar ];
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The queries for the grammar should be added to one of the runtime directories under `queries/{language}` but sometimes plugins do not conform to this structure.
|
Verify with `:checkhealth vim.treesitter`.
|
||||||
|
|
||||||
In such cases, you can override the source derivation (or the grammar derivation) to move the queries to the appropriate folder:
|
|
||||||
|
|
||||||
```nix
|
|
||||||
(
|
|
||||||
(pkgs.fetchFromGitLab {
|
|
||||||
owner = "joncoole";
|
|
||||||
repo = "tree-sitter-nginx";
|
|
||||||
rev = "b4b61db443602b69410ab469c122c01b1e685aa0";
|
|
||||||
hash = "sha256-Sa7audtwH8EgrHJ5XIUKTdveZU2pDPoUq70InQ6qcKA=";
|
|
||||||
}).overrideAttrs
|
|
||||||
(drv: {
|
|
||||||
fixupPhase = '''
|
|
||||||
mkdir -p $out/queries/nginx
|
|
||||||
mv $out/queries/*.scm $out/queries/nginx/
|
|
||||||
''';
|
|
||||||
})
|
|
||||||
)
|
|
||||||
```
|
|
||||||
|
|
||||||
Verify if the queries were picked up by running `:TSModuleInfo`.
|
|
||||||
|
|
||||||
[tree-sitter]: https://github.com/tree-sitter/tree-sitter
|
[tree-sitter]: https://github.com/tree-sitter/tree-sitter
|
||||||
'';
|
'';
|
||||||
|
|
@ -190,39 +145,20 @@ lib.nixvim.plugins.mkNeovimPlugin {
|
||||||
}) buildGrammarDeps;
|
}) buildGrammarDeps;
|
||||||
|
|
||||||
settingsExample = {
|
settingsExample = {
|
||||||
auto_install = false;
|
install_dir = lib.nixvim.nestedLiteralLua "vim.fs.joinpath(vim.fn.stdpath('data'), 'site')";
|
||||||
ensure_installed = "all";
|
|
||||||
ignore_install = [ "rust" ];
|
|
||||||
parser_install_dir.__raw = "vim.fs.joinpath(vim.fn.stdpath('data'), 'treesitter')";
|
|
||||||
sync_install = false;
|
|
||||||
|
|
||||||
highlight = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
additional_vim_regex_highlighting = true;
|
|
||||||
disable = [ "rust" ];
|
|
||||||
custom_captures = { };
|
|
||||||
};
|
|
||||||
|
|
||||||
incremental_selection = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
keymaps = {
|
|
||||||
init_selection = false;
|
|
||||||
node_decremental = "grm";
|
|
||||||
node_incremental = "grn";
|
|
||||||
scope_incremental = "grc";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
indent = {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extraOptions = {
|
extraOptions = {
|
||||||
folding = lib.mkEnableOption "tree-sitter based folding";
|
folding = lib.mkEnableOption "tree-sitter based folding";
|
||||||
|
|
||||||
|
highlight = {
|
||||||
|
enable = lib.mkEnableOption "tree-sitter based syntax highlighting";
|
||||||
|
};
|
||||||
|
|
||||||
|
indent = {
|
||||||
|
enable = lib.mkEnableOption "tree-sitter based indentation";
|
||||||
|
};
|
||||||
|
|
||||||
grammarPackages = mkOption {
|
grammarPackages = mkOption {
|
||||||
type = with types; listOf package;
|
type = with types; listOf package;
|
||||||
default = config.plugins.treesitter.package.passthru.allGrammars;
|
default = config.plugins.treesitter.package.passthru.allGrammars;
|
||||||
|
|
@ -270,24 +206,77 @@ lib.nixvim.plugins.mkNeovimPlugin {
|
||||||
callSetup = false;
|
callSetup = false;
|
||||||
|
|
||||||
extraConfig = cfg: opt: {
|
extraConfig = cfg: opt: {
|
||||||
|
# TODO: Added 2025-12-18 Runtime detection to support legacy api
|
||||||
|
# Should be removed after transition period
|
||||||
|
# Runtime API detection and conditional setup
|
||||||
plugins.treesitter.luaConfig.content =
|
plugins.treesitter.luaConfig.content =
|
||||||
# NOTE: Upstream state that the parser MUST be at the beginning of runtimepath.
|
let
|
||||||
# Otherwise the parsers from Neovim takes precedent, which may be incompatible with some queries.
|
# TODO: Added 2025-12-18 Check both legacy and new api options
|
||||||
(optionalString (cfg.settings.parser_install_dir != null) ''
|
# Add warning after transition period
|
||||||
vim.opt.runtimepath:prepend(${lib.nixvim.toLuaObject cfg.settings.parser_install_dir})
|
# Top-level options (cfg.highlight.enable, cfg.indent.enable) are for main branch
|
||||||
'')
|
# For master branch compatibility, users should use settings.highlight.enable directly
|
||||||
+ ''
|
highlightEnabled = cfg.highlight.enable || (cfg.settings.highlight.enable or false);
|
||||||
require('nvim-treesitter.configs').setup(${lib.nixvim.toLuaObject cfg.settings})
|
indentEnabled = cfg.indent.enable || (cfg.settings.indent.enable or false);
|
||||||
''
|
|
||||||
+ (optionalString (cfg.languageRegister != { }) ''
|
|
||||||
do
|
|
||||||
local __parserFiletypeMappings = ${lib.nixvim.toLuaObject cfg.languageRegister}
|
|
||||||
|
|
||||||
for parser_name, ft in pairs(__parserFiletypeMappings) do
|
# TODO: Added 2025-12-18 Coerce string disable functions to rawLua
|
||||||
require('vim.treesitter.language').register(parser_name, ft)
|
# Before it was dropped, the `highlight.disable` option did str→raw coercion
|
||||||
end
|
# Remove after transition period
|
||||||
|
legacySettings =
|
||||||
|
cfg.settings
|
||||||
|
// lib.optionalAttrs (lib.isString (cfg.settings.highlight.disable or null)) {
|
||||||
|
highlight = cfg.settings.highlight // {
|
||||||
|
disable.__raw = cfg.settings.highlight.disable;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# TODO: Added 2025-12-18 Configure install_dir for main branch
|
||||||
|
# Map parser_install_dir to install_dir if install_dir not already set
|
||||||
|
# Remove after transition period
|
||||||
|
mainBranchSettings =
|
||||||
|
lib.optionalAttrs (legacySettings ? parser_install_dir) {
|
||||||
|
install_dir = legacySettings.parser_install_dir;
|
||||||
|
}
|
||||||
|
// legacySettings;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
-- Create autogroup for treesitter autocmds
|
||||||
|
local augroup = vim.api.nvim_create_augroup('nixvim_treesitter', { clear = true })
|
||||||
|
|
||||||
|
-- Detect nvim-treesitter API
|
||||||
|
local has_configs_module = pcall(require, 'nvim-treesitter.configs')
|
||||||
|
|
||||||
|
if has_configs_module then
|
||||||
|
require('nvim-treesitter.configs').setup(${lib.nixvim.toLuaObject legacySettings})
|
||||||
|
else
|
||||||
|
${optionalString (mainBranchSettings != { }) ''
|
||||||
|
require'nvim-treesitter'.setup(${lib.nixvim.toLuaObject mainBranchSettings})
|
||||||
|
''}
|
||||||
|
${optionalString (highlightEnabled || indentEnabled) ''
|
||||||
|
-- Enable features via autocommands for modern nvim-treesitter
|
||||||
|
vim.api.nvim_create_autocmd('FileType', {
|
||||||
|
group = augroup,
|
||||||
|
pattern = '*',
|
||||||
|
callback = function()
|
||||||
|
${optionalString highlightEnabled ''
|
||||||
|
pcall(vim.treesitter.start)
|
||||||
|
''}${optionalString indentEnabled ''
|
||||||
|
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
|
||||||
|
''}
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
''}
|
||||||
end
|
end
|
||||||
'');
|
${optionalString (cfg.languageRegister != { }) ''
|
||||||
|
|
||||||
|
do
|
||||||
|
local __parserFiletypeMappings = ${lib.nixvim.toLuaObject cfg.languageRegister}
|
||||||
|
|
||||||
|
for parser_name, ft in pairs(__parserFiletypeMappings) do
|
||||||
|
vim.treesitter.language.register(parser_name, ft)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
''}
|
||||||
|
'';
|
||||||
|
|
||||||
extraFiles = mkIf cfg.nixvimInjections { "queries/nix/injections.scm".source = ./injections.scm; };
|
extraFiles = mkIf cfg.nixvimInjections { "queries/nix/injections.scm".source = ./injections.scm; };
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,36 +3,12 @@
|
||||||
default = {
|
default = {
|
||||||
plugins.treesitter = {
|
plugins.treesitter = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
folding = true;
|
||||||
|
highlight.enable = true;
|
||||||
|
indent.enable = true;
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
auto_install = false;
|
install_dir.__raw = "vim.fs.joinpath(vim.fn.stdpath('data'), 'site')";
|
||||||
ensure_installed.__empty = { };
|
|
||||||
ignore_install.__empty = { };
|
|
||||||
# NOTE: This is our default, not the plugin's
|
|
||||||
parser_install_dir.__raw = "vim.fs.joinpath(vim.fn.stdpath('data'), 'site')";
|
|
||||||
|
|
||||||
sync_install = false;
|
|
||||||
|
|
||||||
highlight = {
|
|
||||||
additional_vim_regex_highlighting = false;
|
|
||||||
enable = false;
|
|
||||||
custom_captures.__empty = { };
|
|
||||||
disable.__raw = "nil";
|
|
||||||
};
|
|
||||||
|
|
||||||
incremental_selection = {
|
|
||||||
enable = false;
|
|
||||||
keymaps = {
|
|
||||||
init_selection = "gnn";
|
|
||||||
node_incremental = "grn";
|
|
||||||
scope_incremental = "grc";
|
|
||||||
node_decremental = "grm";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
indent = {
|
|
||||||
enable = false;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
@ -44,31 +20,14 @@
|
||||||
empty-grammar-packages = {
|
empty-grammar-packages = {
|
||||||
plugins.treesitter = {
|
plugins.treesitter = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
grammarPackages = [ ];
|
grammarPackages = [ ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
highlight-disable-function = {
|
with-injections = {
|
||||||
plugins.treesitter = {
|
|
||||||
enable = true;
|
|
||||||
|
|
||||||
settings = {
|
|
||||||
highlight = {
|
|
||||||
enable = true;
|
|
||||||
disable = ''
|
|
||||||
function(lang, bufnr)
|
|
||||||
return api.nvim_buf_line_count(bufnr) > 50000
|
|
||||||
end
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
nixvim-injections = {
|
|
||||||
plugins.treesitter = {
|
plugins.treesitter = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
highlight.enable = true;
|
||||||
nixvimInjections = true;
|
nixvimInjections = true;
|
||||||
|
|
||||||
languageRegister = {
|
languageRegister = {
|
||||||
|
|
@ -81,7 +40,7 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
no-nix = {
|
no-nix-grammars = {
|
||||||
plugins.treesitter = {
|
plugins.treesitter = {
|
||||||
enable = true;
|
enable = true;
|
||||||
nixGrammars = false;
|
nixGrammars = false;
|
||||||
|
|
@ -91,43 +50,52 @@
|
||||||
specific-grammars = {
|
specific-grammars = {
|
||||||
plugins.treesitter = {
|
plugins.treesitter = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
highlight.enable = true;
|
||||||
|
indent.enable = true;
|
||||||
|
|
||||||
grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [
|
grammarPackages = with pkgs.vimPlugins.nvim-treesitter.builtGrammars; [
|
||||||
bash
|
bash
|
||||||
git_config
|
|
||||||
git_rebase
|
|
||||||
gitattributes
|
|
||||||
gitcommit
|
|
||||||
gitignore
|
|
||||||
json
|
|
||||||
jsonc
|
|
||||||
lua
|
lua
|
||||||
make
|
|
||||||
markdown
|
|
||||||
meson
|
|
||||||
ninja
|
|
||||||
nix
|
nix
|
||||||
readline
|
|
||||||
regex
|
|
||||||
ssh-config
|
|
||||||
toml
|
|
||||||
vim
|
vim
|
||||||
vimdoc
|
vimdoc
|
||||||
xml
|
|
||||||
yaml
|
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
disable-init-selection = {
|
legacy-master = {
|
||||||
plugins.treesitter = {
|
plugins.treesitter = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
|
auto_install = false;
|
||||||
|
ensure_installed.__empty = { };
|
||||||
|
ignore_install.__empty = { };
|
||||||
|
parser_install_dir.__raw = "vim.fs.joinpath(vim.fn.stdpath('data'), 'treesitter')";
|
||||||
|
sync_install = false;
|
||||||
|
|
||||||
|
highlight = {
|
||||||
|
enable = true;
|
||||||
|
additional_vim_regex_highlighting = false;
|
||||||
|
disable = ''
|
||||||
|
function(lang, bufnr)
|
||||||
|
return api.nvim_buf_line_count(bufnr) > 50000
|
||||||
|
end
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
incremental_selection = {
|
incremental_selection = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
keymaps = {
|
||||||
|
init_selection = "gnn";
|
||||||
|
node_incremental = "grn";
|
||||||
|
scope_incremental = "grc";
|
||||||
|
node_decremental = "grm";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
keymaps.init_selection = false;
|
indent = {
|
||||||
|
enable = true;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue