Open ycmjason opened 6 years ago
Yeah this is a known issue and I am not entirely sure it's possible to fix with Vim's built in regex syntax system.
The TL;DR is that we can only really detect them as arguments if the opening and closing paren are on the same line.
This is so sad, no regex guru is solving this?
It doesn't work with one line either:
function someDefault() {}
export const a = ({first: f, second: s = someDefault()}) => {
return f + s;
}
@jigfox i know this is really sad. do you wanna look into the plugin and fix this please. i want proper syntax highlighting.. 😢
sorry, but I don't know how, I have never done any syntax highlighting for vim, I just stumbled over the problem myself, and then I found this issue
ðŸ˜
@jigfox your example breaks because there are parens in it, not because it's on one line.
export const a = ({first: f, second: s = 2}) => {
return f + s;
}
This above example will work fine.
Thing is, there might be a super complex regex that can do this, but it would most likely make our syntax highlighting very slow (if someone can figure it out, I am would be more than willing to test it, but I doubt it's possible and performant).
Just for some context on why it is expensive/hard:
an opening (
can mean a couple different things. It can mean an expression or it can mean an arrow function arguments. What makes it an arrow function argument, is that AFTER its closing paren, there has to be =>
- this is something tokenizers do a great job of, but not a regex parser (known as a look ahead).
On it's own it's not that complex, but when you add the possibility of destructuring, it gets insanely complex.
({example: [x = 2 + 2, {another = ({wow = (2 + x) / 10}) => [wow, another]}]}) => {};
This is a valid destructuring statement, and knowing how to find the actual beginning and end of each matching parenthesis is just a flat out nightmare for a regex. It's best done with a tokenizer.
I actually kinda wish that Vim had a sort of async api that you could pipe a file through a tokenizer and then have it return syntax highlighting information - so we could initially use our regex stuff, then when the tokenizer parses it properly, update it to the correct
syntax highlighting groups (this is often what IDEs do)
I see, the inner ()
is the problem, il look into it
could it just skip jsExpression? i think skipping nested parens is possible with vim syntax engine, but it needs one additional sytax match
for each level, and it doesn't allow recursion, so it is really ugly.
anyways, the syntax stuff is really hard, have to keep in mind priority and stuff
@bounceme I don't think we can use the syntax region
feature either, because it only requires matching on the start argument and doesn't require the ending regex to match. There's no way to differentiate or prioritize it over the jsParen
group. Basically we'd have to create an insane regex, then basically have it contain a ton of other shit in order to work, and we'd get none of the great region
features that we normally get for free.
~I work around this by forcing the current arrow argument region to be oneline
. This enables the @end
regex to match in order to continue.~ I've actually since refactored it and don't do this anymore, but I forget why.
I actually made a request on the Vim mailing list - to add a feature to region like requireend
to require the end argument to match in order for the region to match, but Braam pushed back saying it went against what regions are intended for and could affect performance.
any update on this?
I am slowly moving to VSCode now because vim's syntax highlighting support seems incomplete. Thank you @amadeus for spending so much time on this tho!
The Vim experience on VSCode is not perfect 😢
Nope, there's no update. Until we can use a tokenizer to do syntax highlighting, i don't think this issue will ever get fixed.
The reason is that the jsArrowFuncArgs
group doesn't support multiline parameters,
I tried to define the jsArrowFuncArgs
using region
, it will fix this issue, but it will break the jsParsen
group. E.g., parens in (a + b) / 10
will be matched as jsArrowFuncArgs
incorrectly.
The root cause for this issue is that the parens expression and the arrow function arguments are ambiguous. For example, (a, b, c)
is a parens expression, while (a, b, c) =>
is a arrow function arguments. We can not decide what it is until we see the =>
sign. And it's not possible to distinguish them in the Vim syntax file.
Another proposed solution is that we shall not distinct the arrow function arguments parens from the normal parens. We treat the former as the normal parens, and the syntax should work. Although the arrow function arguments may not be highlighted precisely, it won't break the following syntax highlighting.
Has anything ever come up in the past 3 years that now makes this possible?
Treesitter support in Neovim can do it, but then you wouldn’t be using this plugin at all
The color are not quite right for default values in object destructing. Below should be a reproducible code.