1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
|
{
config,
lib,
pkgs,
...
}: let
inherit (lib) mkIf foldl' mapAttrsToList;
inherit (lib.strings) optionalString;
inherit (lib.lists) optionals optional partition;
inherit (lib.nvim.dag) entryAfter;
inherit (lib.nvim.lua) toLuaObject;
cfg = config.vim.treesitter;
in {
config = mkIf cfg.enable {
vim = {
startPlugins = ["nvim-treesitter"];
# cmp-treesitter doesn't work on blink.cmp
autocomplete.nvim-cmp = mkIf config.vim.autocomplete.nvim-cmp.enable {
sources = {treesitter = "[Treesitter]";};
sourcePlugins = ["cmp-treesitter"];
};
extraPackages = mkIf cfg.vendorCLI [
(pkgs.symlinkJoin {
name = "tree-sitter";
paths = [pkgs.tree-sitter];
meta.mainProgram = "tree-sitter";
buildInputs = [pkgs.makeBinaryWrapper];
postBuild = "wrapProgram $out/bin/tree-sitter --prefix PATH : ${pkgs.gcc}/bin";
})
];
treesitter.grammars = optionals cfg.addDefaultGrammars cfg.defaultGrammars;
pluginRC = {
treesitter-autocommands = entryAfter ["basic"] ''
vim.api.nvim_create_augroup("nvf_treesitter", { clear = true })
${lib.optionalString cfg.highlight.enable ''
-- Enable treesitter highlighting for all filetypes
vim.api.nvim_create_autocmd("FileType", {
group = "nvf_treesitter",
pattern = "*",
callback = function()
pcall(vim.treesitter.start)
end,
})
''}
${lib.optionalString cfg.indent.enable ''
-- Enable treesitter highlighting for all filetypes
vim.api.nvim_create_autocmd("FileType", {
group = "nvf_treesitter",
pattern = ${toLuaObject cfg.indent.pattern},
callback = function(args)
${optionalString (builtins.length cfg.indent.excludes > 0) ''
local ft = vim.bo[args.buf].filetype
if vim.tbl_contains(${toLuaObject cfg.indent.excludes}, ft) then
return
end
''}
vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
end,
})
''}
${lib.optionalString cfg.fold ''
-- Enable treesitter folding for all filetypes
vim.api.nvim_create_autocmd("FileType", {
group = "nvf_treesitter",
pattern = "*",
callback = function()
vim.wo[0][0].foldmethod = "expr"
vim.wo[0][0].foldexpr = "v:lua.vim.treesitter.foldexpr()"
end,
})
''}
'';
treesitter-filetype-mappings = entryAfter ["basic"] ''
for lang, ft in pairs(${toLuaObject cfg.filetypeMappings}) do
vim.treesitter.language.register(lang, ft)
end
'';
};
additionalRuntimePaths = mkIf (cfg.queries != []) (
let
mkQueryGroup = entries:
foldl' (acc: entry:
foldl' (inner: filetype: let
path = "queries/${filetype}/${entry.type}.scm";
prev = inner.${path} or "";
query = ''${optionalString (entry.loadtype == "extends") "; extends\n"} ${entry.query} '';
in
inner // {${path} = prev + query;})
acc
entry.filetypes)
{}
entries;
mkQueryRuntimePath = name: queries:
pkgs.linkFarm "treesitter-queries-${name}" (mapAttrsToList (path: query: {
name = path;
path = pkgs.writeText path query;
})
queries);
inherit (partition (entry: entry.loadtype == "overwrite") cfg.queries) right wrong;
overwriteQueries = mkQueryGroup right;
extendsQueries = mkQueryGroup wrong;
in
optional (overwriteQueries != {}) {
path = mkQueryRuntimePath "overwrite" overwriteQueries;
position = "prepend";
}
++ optional (extendsQueries != {}) {
path = mkQueryRuntimePath "extends" extendsQueries;
position = "append";
}
);
};
};
}
|