-
-
Notifications
You must be signed in to change notification settings - Fork 143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tree sitter breaks code folding in certain cases #868
Comments
We have test coverage for this, but certainly not on a file that's 3500 lines long. So I'll run these instructions against some of the larger files in our codebase to see if I can reproduce this issue. Thanks for the report! |
Hmm, initial experiments aren't giving me much to go on. I tried it on a 6,000-line file and it seemed to work just fine. A few questions:
My main theory is that Tree-sitter is getting confused by something in the file, but that would also probably affect the syntax highlighting. If this is a file you can post publicly somewhere, please do so and I can test on the exact input. If it isn't, then maybe see if you can get it to happen with some other JavaScript that's open-source or otherwise publicly available. |
I can confirm it is multiple files. Also, although the code folding "stops" you can proceed to fold it manually where you would usually expect (and the old tree sitter does fine) Syntax highlighting is also fine for the remainder of the file. Also, my file in question has changed over time and the point at which it stops does not vary by much, but the code around the point at which it terminates has changed so I don't think it is related to the code, more some kind of folding loop being terminated? |
OK, I can rule out most of my initial theories based on the fact that manual folding still works fine. Here's roughly how I've implemented this:
(I call it “indent level” because that's literally how it used to work, but that makes no sense now that folds are semantic. So now it's levels of nesting, and the “indent level” is actually how many other fold ranges completely surround a given fold range.) So there are a few possible points of failure here:
For now I'll rule out options 1 and 4. Offhand I can't see how 2 is possible. So that leaves Option 3. Try to fold at a different indent level — first level 2, then level 3 — and let me know what happens. If Option 3 is the culprit, then some of the folds you expected to occur on level 1 will actually happen on level 2, and so on. |
Ok, finally got a chance to look at this. Updated to latest (1.116) Folding still fails at level 1, beyond that things get weird as you suggested in your 3rd option. |
OK. I'll keep this ticket open until we can solve this mystery. If you can reproduce these symptoms on a long file whose source code you are allowed to show me, please put it into a Gist or something so that I can try to reproduce this. If you have other source files that are just as long, please confirm whether it's happening in multiple files or just one specific file. |
Just updated to 117 and confirming the bug still exists - legacy tree sitter still working. Happy yo share the one huge file privately to devs, but can't post it publicly. |
Just dropping by to say 118 still has the tree-sitter bug I experienced. |
You can find me on Discord if you like and send it to me in a private message. Haven't noticed this bug on any file of my own, so it'd be a coup if I could reproduce it on my machine with the same input. |
@gazhay and I figured it out; he was kind enough to provide me the offending file on Discord. The length of the file was a red herring! You can reproduce this bug with the following code: function foo () {
let results = [];
for (let thing of things) {
if (thing.bar) {results.push({
lorem: 'ipsum'
})} else {
// TODO
}
}
}
function bar () {
if (foo) {
baz();
}
} Invoke the Editor: Fold At Indent Level 1 command and you'll notice that Yet if you go to this line
and insert a newline here
then it works as expected. This is annoying because our Tree-sitter future was supposed to save us from using indentation level as a proxy for code folding depth (as is the default behavior in TextMate grammars). At first, I figured this was some sort of edge case that An
In this example, the fold starts at the end of line 1, no matter how long the line is — so An object literal has its own implicit folding range, too:
In this example, the fold starts at the end of line 1, no matter how long the line is — so Now let's combine them by having a statement block and an object literal start on the same line! if (bar) { obj = {
foo: 'foo'
}} Now we've got code that wants to place two different fold ranges that start on line 1. Only one of them can be toggled at once, so the editor has to pick a winner. That's the part that wasn't happening. Running Editor: Fold At Indent Level 1 is tricky for us because we have to figure out fold containment on the fly. We ask each language layer for its folds, combine them into one list via a red-black tree, then iterate through them in position order. When we find the starting point of a fold, we increment a depth counter; when we find an ending point, we decrement the counter. But that process doesn't seem to like when two folds report ranges that are basically identical! As a result, we seemed to be incrementing depth twice (when encountering the starting points of both fold ranges) but decrementing only once. This is probably the root cause of the bug! And I haven't quite solved that part yet. (Note that, as evidenced by the workaround, we seem to tolerate when the folds start at the same point as long as they end at different points.) But the headline is that we should be more aware of the constraint that only one fold can start on a given line, and only one fold can end on a given line. If we ask the grammars to mark folds for us in a buffer, then find out that two of the folds are supposed to start at the end of line 4, then we need to be consistent about how we pick the “correct” one. My suspicion is that we've been acting on the first match of a |
Thanks in advance for your bug report!
What happened?
After installing the latest 1.13 version of Pulsar code folding in large javascript files "stops" at ~3500 lines.
On previous versions "ctrl-k ctrl-1" would fold the entire file at level 1 - it no longer does this. It folds the first 3500 or so and then does nothing after. You can still manually fold if you wish.
When using the menu "Fold All" it does fold the entire file (at every level).
toggling legacy tree-sitter in settings immediately fixes this.
Pulsar version
1.13
Which OS does this happen on?
🐧 Debian based (Linux Mint, Ubuntu, etc.)
OS details
22.04.3 LTS
Which CPU architecture are you running this on?
x86_64/AMD64
What steps are needed to reproduce this?
2.Ctrl-k ctrl-1
3.Scroll down to find the point it stops being folded.
Additional Information:
I appreciate this may be an "edge" case with such a large file and currently I can enable legacy to work around.
The text was updated successfully, but these errors were encountered: