Skip to content

Conversation

savetheclocktower
Copy link
Contributor

I found this bug yesterday while working on a new language package, so I've got a brand-new Tree-sitter PR ready to go after the 1.129 release.

I am fully aware how bad our bus factor is for anything relating to modern Tree-sitter, so this first commit is a small change with a very long commit message.

…between `suggestedIndentForBufferRow` and `suggestedIndentForEditedBufferRow`.

The first function is called when we decide how to indent a line that you're not typing on, like when you press `Return` or invoke auto-indent.

It's a two-phase process: run one Tree-sitter query to find things that may increase the indent level, then run another to find things that may decrease the indent level. Then sum them up.

And if you’re in an environment with multiple “language layers” — e.g., the middle of a `script` tag in an HTML file — it’s not always clear which query you should run. When should you run queries against the HTML layer, and when should you run them against the JavaScript layer?

And, amazingly, the answer might be different for each phase of the query! So to select the right layer, we ask for all active language layers at a given point, then choose the most specific layer that also fulfills certain criteria.

For phase one of the indentation query, we reject layers that _start_ at the point we’re measuring from. Because most of what determines the indentation level of line 10 is controlled by stuff on line 9, so we want to favor the layer that has already been active over the layer that starts on line 10.

For phase two of the indentation query, we reject layers that _end_ at the point we’re measuring from. Because most of what determines whether line 10 should be _dedented_ while you type (imagine typing the closing `}` of a block in JS) comes from the content of the line itself, not anything that happened before it.

We have to capture all this nuance in order to select the correct layer in `suggestedIndentForBufferRow`. But `suggestedIndentForEditedBufferRow` is the function that runs over and over again as you type on the current line, and its own layer-selection logic was much more blunt (“give me the deepest layer at this point that has an `indents.scm`”).

This commit took forever to explain, but all it does is correct this mismatch. Now the logic it uses to select a layer is identical to what’s used for the second (dedent) phase of `suggestedIndentForBufferRow`.
Also add the beginnings of a grammar spec. Baby steps!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant