diff --git a/spec/tree-sitter-language-mode-spec.js b/spec/tree-sitter-language-mode-spec.js index ee435d90d..bc386b03a 100644 --- a/spec/tree-sitter-language-mode-spec.js +++ b/spec/tree-sitter-language-mode-spec.js @@ -866,6 +866,23 @@ describe('TreeSitterLanguageMode', () => { ]); }); + it('reports scopes from shallower layers when they are at the start or end of an injection', async () => { + await atom.packages.activatePackage('language-javascript') + + editor.setGrammar(atom.grammars.grammarForScopeName('source.js')) + editor.setText('/** @babel */\n{\n}') + expectTokensToEqual(editor, [ + [ + { text: '/** ', scopes: ['source js', 'comment block'] }, + { text: '@babel', scopes: ['source js', 'comment block', 'keyword control'] }, + { text: ' *', scopes: ['source js', 'comment block'] }, + { text: '/', scopes: ['source js', 'comment block', 'meta delimiter slash'] } + ], + [{ text: '{', scopes: ['source js', 'punctuation definition function body begin bracket curly'] }], + [{ text: '}', scopes: ['source js', 'punctuation definition function body end bracket curly'] }] + ]); + }) + it('respects the `includeChildren` property of injection points', async () => { const rustGrammar = new TreeSitterGrammar( atom.grammars, diff --git a/src/tree-sitter-language-mode.js b/src/tree-sitter-language-mode.js index ba27d19bd..e922743d0 100644 --- a/src/tree-sitter-language-mode.js +++ b/src/tree-sitter-language-mode.js @@ -32,7 +32,7 @@ class TreeSitterLanguageMode { this.config = config; this.grammarRegistry = grammars; this.parser = new Parser(); - this.rootLanguageLayer = new LanguageLayer(this, grammar, 0); + this.rootLanguageLayer = new LanguageLayer(this, grammar, 0, buffer.getRange()); this.injectionsMarkerLayer = buffer.addMarkerLayer(); if (syncTimeoutMicros != null) { @@ -637,13 +637,14 @@ class TreeSitterLanguageMode { } class LanguageLayer { - constructor(languageMode, grammar, depth) { + constructor(languageMode, grammar, depth, range) { this.languageMode = languageMode; this.grammar = grammar; this.tree = null; this.currentParsePromise = null; this.patchSinceCurrentParseStarted = null; this.depth = depth; + this.range = range } buildHighlightIterator() { @@ -885,7 +886,8 @@ class LanguageLayer { marker.languageLayer = new LanguageLayer( this.languageMode, grammar, - this.depth + 1 + this.depth + 1, + injectionRange ); marker.parentLanguageLayer = this; } @@ -1011,7 +1013,7 @@ class HighlightIterator { next.offset === first.offset && next.atEnd === first.atEnd && next.depth > first.depth && - next.openTags.length + next.closeTags.length > 0 + next.languageLayer.range.containsPoint(first.getPosition(), true) ) { this.currentScopeIsCovered = true; return;