Ensure suggestedIndentForBufferRows works right…

…when straddling an injection boundary.

When we do this one row at a time, the controlling layer for an indent query is
the comparison (previous) row, because that's where the query starts. The batch
version should be no different.

The new spec describes the exact scenario that revealed this bug.
This commit is contained in:
Andrew Dupont 2023-05-19 14:18:04 -07:00
parent 5e950a0aba
commit 8afe2f6fc4
2 changed files with 46 additions and 1 deletions

View File

@ -1609,6 +1609,47 @@ describe('WASMTreeSitterLanguageMode', () => {
});
});
describe('.suggestedIndentForBufferRows', () => {
it('works correctly when straddling an injection boundary', async () => {
const jsGrammar = new WASMTreeSitterGrammar(atom.grammars, jsGrammarPath, jsConfig);
jsGrammar.addInjectionPoint(HTML_TEMPLATE_LITERAL_INJECTION_POINT);
const htmlGrammar = new WASMTreeSitterGrammar(
atom.grammars,
htmlGrammarPath,
htmlConfig
);
htmlGrammar.addInjectionPoint(SCRIPT_TAG_INJECTION_POINT);
atom.grammars.addGrammar(jsGrammar);
atom.grammars.addGrammar(htmlGrammar);
// `suggestedIndentForBufferRows` should use the HTML grammar to
// determine the indent level of `let foo` rather than the JS grammar.
buffer.setText(dedent`
<script>
let foo;
</script>
`);
const languageMode = new WASMTreeSitterLanguageMode({
grammar: htmlGrammar,
buffer,
config: atom.config,
grammars: atom.grammars
});
buffer.setLanguageMode(languageMode);
await languageMode.ready;
let map = languageMode.suggestedIndentForBufferRows(1, 1, editor.getTabLength());
expect(map.get(1)).toBe(1);
});
});
describe('folding', () => {
it('can fold nodes that start and end with specified tokens', async () => {
const grammar = new WASMTreeSitterGrammar(atom.grammars, jsGrammarPath, jsConfig);

View File

@ -1473,8 +1473,12 @@ class WASMTreeSitterLanguageMode {
let indentDelta;
for (let row = startRow; row <= endRow; row++) {
// If this row were being indented by `suggestedIndentForBufferRow`, it'd
// look at the end of the previous row to find the controlling layer,
// because we start at the previous row to find the suggested indent for
// the current row.
let controllingLayer = this.controllingLayerAtPoint(
new Point(row, Infinity),
new Point(row - 1, Infinity),
(layer) => !!layer.indentsQuery && !!layer.tree
);