diff --git a/spec/tree-sitter-language-mode-spec.js b/spec/tree-sitter-language-mode-spec.js
index bad30a506..db0229e9b 100644
--- a/spec/tree-sitter-language-mode-spec.js
+++ b/spec/tree-sitter-language-mode-spec.js
@@ -1692,6 +1692,54 @@ describe('TreeSitterLanguageMode', () => {
})
})
+ describe('.commentStringsForPosition(position)', () => {
+ it('returns the correct comment strings for nested languages', () => {
+ const jsGrammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
+ scopeName: 'javascript',
+ parser: 'tree-sitter-javascript',
+ comments: {start: '//'},
+ injectionRegExp: 'javascript',
+ injectionPoints: [HTML_TEMPLATE_LITERAL_INJECTION_POINT]
+ })
+
+ const htmlGrammar = new TreeSitterGrammar(atom.grammars, htmlGrammarPath, {
+ scopeName: 'html',
+ parser: 'tree-sitter-html',
+ scopes: {},
+ comments: {start: ''},
+ injectionRegExp: 'html',
+ injectionPoints: [SCRIPT_TAG_INJECTION_POINT]
+ })
+
+ atom.grammars.addGrammar(jsGrammar)
+ atom.grammars.addGrammar(htmlGrammar)
+
+ const languageMode = new TreeSitterLanguageMode({buffer, grammar: htmlGrammar, grammars: atom.grammars})
+ buffer.setLanguageMode(languageMode)
+ buffer.setText(`
+
hi
+
+ `.trim())
+
+
+ const htmlCommentStrings = {commentStartString: ''}
+ const jsCommentStrings = {commentStartString: '//', commentEndString: undefined}
+
+ expect(languageMode.commentStringsForPosition(new Point(0, 0))).toEqual(htmlCommentStrings)
+ expect(languageMode.commentStringsForPosition(new Point(1, 0))).toEqual(htmlCommentStrings)
+ expect(languageMode.commentStringsForPosition(new Point(2, 0))).toEqual(jsCommentStrings)
+ expect(languageMode.commentStringsForPosition(new Point(3, 0))).toEqual(jsCommentStrings)
+ expect(languageMode.commentStringsForPosition(new Point(4, 0))).toEqual(htmlCommentStrings)
+ expect(languageMode.commentStringsForPosition(new Point(5, 0))).toEqual(jsCommentStrings)
+ expect(languageMode.commentStringsForPosition(new Point(6, 0))).toEqual(htmlCommentStrings)
+ })
+ })
+
describe('TextEditor.selectLargerSyntaxNode and .selectSmallerSyntaxNode', () => {
it('expands and contracts the selection based on the syntax tree', async () => {
const grammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, {
diff --git a/src/text-editor.js b/src/text-editor.js
index 8b575d4eb..abdbb9c51 100644
--- a/src/text-editor.js
+++ b/src/text-editor.js
@@ -4768,7 +4768,7 @@ class TextEditor {
const languageMode = this.buffer.getLanguageMode()
let {commentStartString, commentEndString} =
languageMode.commentStringsForPosition &&
- languageMode.commentStringsForPosition(Point(start, 0)) || {}
+ languageMode.commentStringsForPosition(new Point(start, 0)) || {}
if (!commentStartString) return
commentStartString = commentStartString.trim()
diff --git a/src/tree-sitter-language-mode.js b/src/tree-sitter-language-mode.js
index fc87f16ac..ae11274e7 100644
--- a/src/tree-sitter-language-mode.js
+++ b/src/tree-sitter-language-mode.js
@@ -144,17 +144,16 @@ class TreeSitterLanguageMode {
Section - Commenting
*/
- commentStringsForPosition () {
- return this.grammar.commentStrings
+ commentStringsForPosition (position) {
+ const range = this.firstNonWhitespaceRange(position.row) || new Range(position, position)
+ const {grammar} = this.getSyntaxNodeAndGrammarContainingRange(range)
+ return grammar.commentStrings
}
isRowCommented (row) {
- const firstNonWhitespaceRange = this.buffer.findInRangeSync(
- /\S/,
- new Range(new Point(row, 0), new Point(row, Infinity))
- )
- if (firstNonWhitespaceRange) {
- const firstNode = this.getSyntaxNodeContainingRange(firstNonWhitespaceRange)
+ const range = this.firstNonWhitespaceRange(row)
+ if (range) {
+ const firstNode = this.getSyntaxNodeContainingRange(range)
if (firstNode) return firstNode.type.includes('comment')
}
return false
@@ -367,23 +366,31 @@ class TreeSitterLanguageMode {
*/
getSyntaxNodeContainingRange (range, where = _ => true) {
+ return this.getSyntaxNodeAndGrammarContainingRange(range, where).node
+ }
+
+ getSyntaxNodeAndGrammarContainingRange (range, where = _ => true) {
const startIndex = this.buffer.characterIndexForPosition(range.start)
const endIndex = this.buffer.characterIndexForPosition(range.end)
const searchEndIndex = Math.max(0, endIndex - 1)
- let smallestNode
+ let smallestNode = null
+ let smallestNodeGrammar = this.grammar
this._forEachTreeWithRange(range, (tree, grammar) => {
let node = tree.rootNode.descendantForIndex(startIndex, searchEndIndex)
while (node) {
if (nodeContainsIndices(node, startIndex, endIndex) && where(node, grammar)) {
- if (nodeIsSmaller(node, smallestNode)) smallestNode = node
+ if (nodeIsSmaller(node, smallestNode)) {
+ smallestNode = node
+ smallestNodeGrammar = grammar
+ }
break
}
node = node.parent
}
})
- return smallestNode
+ return {node: smallestNode, grammar: smallestNodeGrammar}
}
getRangeForSyntaxNodeContainingRange (range, where) {
@@ -482,6 +489,10 @@ class TreeSitterLanguageMode {
Section - Private
*/
+ firstNonWhitespaceRange (row) {
+ return this.buffer.findInRangeSync(/\S/, new Range(new Point(row, 0), new Point(row, Infinity)))
+ }
+
grammarForLanguageString (languageString) {
return this.grammarRegistry.treeSitterGrammarForLanguageString(languageString)
}
@@ -599,7 +610,6 @@ class LanguageLayer {
params.async = true
tree = await tree
}
- tree.buffer = this.languageMode.buffer
const changes = this.patchSinceCurrentParseStarted.getChanges()
this.patchSinceCurrentParseStarted = null