nvim-ts-rainbow2
nvim-ts-rainbow2 copied to clipboard
Long freezes when opening/editing zig files
Describe the bug
I get huge freezes when opening a .zig source file (around 0.8-1.0 seconds), even when adding "zig" to disabled languages. I found this delay to be caused by nvim-ts-rainbow2 and for me only occurs with zig files so far.
Steps to reproduce
Open any .zig file, including the hello world example generated by zig init-exe
:
const std = @import("std");
pub fn main() !void {
// Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
std.debug.print("All your {s} are belong too us.\n", .{"codebase"});
// stdout is for the actual output of your application, for example if you
// are implementing gzip, then only the compressed bytes should be sent to
// stdout, not any debugging messages.
const stdout_file = std.io.getStdOut().writer();
var bw = std.io.bufferedWriter(stdout_file);
const stdout = bw.writer();
try stdout.print("Run `zig build test` to run the tests.\n", .{});
try bw.flush(); // don't forget to flush!
}
test "simple test" {
var list = std.ArrayList(i32).init(std.testing.allocator);
// defer list.deinit(); // try commenting this out and see if zig detects the memory leak!
try list.append(42);
try std.testing.expectEqual(@as(i32, 42), list.pop());
}
Expected behavior
Either no freezes when editing a (simple) zig file (lag occurs on multiple events, like inserting new text or removing lines etc), or no freeze at all when adding zig to disabled languages.
I can reproduce the issue, but I doubt that anything can be done on my end. Here is what I have tried:
- There is a new strategy on the current
master
branch callednoop
(require('ts-rainbow').strategy.noop
) which does absolutely nothing, and yet the slowdown happens with that strategy as well. - I profiled the
attach
function inlua/ts-rainbow/internal.lua
and the time spent is imperceptible - I commented out the contents of both the
attach
anddetach
functions, yet no speedup - In addition I also commented out the autocommand, still slow
I cannot think of any other function that could be the bottleneck. My best guess is that something about the Zig grammar itself that causes the slowdown. However, if I disable the rainbow
module of nvim-treesitter Zig files do load quickly. Very strange indeed.
OK, it looks like I spoke too soon. Try the following: in the file lua/ts-rainbow/module.lua
on line 29 there is a function is_supported
. Change its contents to return true
:
is_supported = function(lang)
return true
end,
This should get rid of the slowdown or at least reduce it. The question is, why is out of all languages only Zig slow? I have tested Python and Lua, both are blazing fast.
OK, I think I'm done for now. The bottleneck is the function vim.treesitter.query.get
when called on the rainbow-parens
query.
vim.treesitter.query.get('zig', 'rainbow-parens')
Commenting-out the content of the query gets rid of the slowdown, but with every pattern I add back the call gets slower and slower. The following patterns result in a query that is still in the ~microseconds~ milliseconds range:
(ParamDeclList
"(" @opening
")" @closing) @container
(ForPrefix
"(" @opening
")" @closing) @container
(AsmInputItem
"[" @opening
"]" @closing) @container
(AsmOutputItem
"[" @opening
"]" @closing) @container
(AsmOutputItem
"(" @opening
")" @closing) @container
(Block
"{" @opening
"}" @closing) @container
(ContainerDecl
"{" @opening
"}" @closing) @container
(FormatSequence
"{" @opening
"}" @closing) @container
(Payload
"|" @opening
"|" @closing) @container
(PtrListPayload
"|" @opening
"|" @closing) @container
(PtrIndexPayload
"|" @opening
"|" @closing) @container
That's still quite slow compared to other queries of that size. Fennel and Rust are close in query size to the full Zig query and they are still in the ~microsecond~ milliseconds ange.
I don't know what more I can do here; we know that the bottleneck is the Zig parser. You can either live with the initial delay, reduce the query in size or report the issue to the Zig grammar maintainer. Once the query has been loaded future calls to the function will be almost instantaneous, so you only suffer the delay when opening the first Zig buffer.
EDIT: Sorry, got my metric prefixes wrong. It's milliseconds, not microseconds.
Thank you for investigating this! I have disabled the rainbow brackets for zig for now, but I'll try reporting the issue further to the nvim-treesitter and/or zig parser.
This plugin is now deprecated because of upcoming changes to nvim-treesitter. The new rainbow plugin is here: rainbow-delimiters.nvim (GitHub mirror). Please file an issue over there if the problem still persists.