zig.vim
zig.vim copied to clipboard
wrong coloring of field names that collide with builtin primitive types
const foo = enum {
u8,
isize,
noreturn,
aeouaoeu,
};
These are all valid field identifiers that do not clash against identifiers in the main namespace.
The same thing also seems to happen with struct
, union
, their initialization literals (such as MyStruct{ .u8 = 20 }
).
I came up with an idea that we could enable these types' highlighting of these types when they are used in type specifications (a.k.a. after a colon), such as u8
in:
var my_var: u8 = 10;
The problem with this solution, though, is that this same type u8
wouldn't be shown as a primitive type in other contexts, such as function calls:
@as(u8, value);
fn doSomething(comptime T: type) void {}
doSomething(u8);
I then had another idea - preventing the highlighting of these types in field declarations and on field accesses:
const En = enum { u8 }; // this wouldn't be highlighted because of the surrounding brackets and the
// enum keyword right before
_ = En.u8; // neither would this because it comes right after a dot
const St = struct { u8: u16 }; // u8 wouldn't be highlighted here; the u16 would. This could be done by
// detecting the `:` right after it, and also maybe only while inside a
// `{}` block with a `struct` keyword before (might be complicated)
const inst = St{ .u8 = 53 }; // I believe we can re-use the same rule as in `En.u8` here
_ = inst.u8; // same thing here
This might be a little complicated for structs and enums, but for the rest it seems quite simple.
Also, although the code below doesn't compile (because it shadows u8
and u16
), I'm not sure if these identifiers should be highlighted as they are currently (as builtin types). They could be detected as normal identifiers by simply not highlighting builtin primitives that come right after fn
, var
or const
; or there could be a special "error" highlight color to indicate they aren't valid.
const std = @import("std");
const MyStruct = struct {
pub fn u8() void {
std.debug.print("(hopefully) this is not a valid function name.\n", .{});
}
var u16 = struct {}; // neither is this for a variable name
};
main namespace
Unfortunately the vim grammar is rather primitive/simple in that any nesting logic must be encoded explicitly with regexes (and the rather long regex becomes more slow to evaluate).
there could be a special "error" highlight color to indicate they aren't valid.
Dont try fancy with regexes, when the problem requires a parser to detect all cases.
@YohananDiamond If the solution only works for some cases, its probably not worth it.
Closing?
Fair enough. I've heard nvim-treesiter may help with this, but it seems to work in a completely different way and probably is neovim-only.
@YohananDiamond The alternative is to go out full crazy with implementing a parser in vim.
The problem with nvim-treesitter is that it adds significant initial delay for big files (>a few thousand LOC) and a workaround is still not upstream (its just disabled for big files) https://github.com/nvim-treesitter/nvim-treesitter/issues/1708
And sure, its neovim only.
A full parser in vimscript probably wouldn't be worth the effort, I think.
But anyways: if I understood correctly, https://github.com/ziglang/zig/issues/6062 being accepted solves this issue, right?
Apparently as of 0.9.0 these names need to be wrapped in @""
to be used as identifiers.
need to be wrapped in @"" to be used as identifiers.
Within neovim: The stalling for very big file is not the case anymore, as the highlighting tokens are now added asynchronously without blocking the editor. A workaround for the slowdown for very big files exists also.
However, very big files like Sema.zig
are still not supported and without internal info I think zls will be too slow. So this will remain open for a while.