diff --git a/package-lock.json b/package-lock.json index 8ee46f9d2..16c4c1c44 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1111,8 +1111,8 @@ } }, "bracket-matcher": { - "version": "https://www.atom.io/api/packages/bracket-matcher/versions/0.89.4/tarball", - "integrity": "sha512-rTQnr/dPXLFIV/MZGnOUlgkpWJoE9BQoopW9HFXpzWk2J4U/3I6c0V33Qtk/QH3Adayyf4qoWl/eYBEcgnM74A==", + "version": "https://www.atom.io/api/packages/bracket-matcher/versions/0.90.2/tarball", + "integrity": "sha512-ANAi0fOKm5Air6jgv682ye3UFYQpYy3s3Dk89Ap7bcNnZgsdmojA7Lq1EmeD+yobjYUqemSp/qelkktttAOgzg==", "requires": { "first-mate": "^7.0.1", "underscore-plus": "1.x" @@ -5459,9 +5459,9 @@ } }, "text-buffer": { - "version": "13.14.12", - "resolved": "https://registry.npmjs.org/text-buffer/-/text-buffer-13.14.12.tgz", - "integrity": "sha512-MDHAblId2rrjpl3wMUv9QF+jSqMyG/ZVEPHZk4H6ZrbpyjWzHDvkI6PFVgiPXrOZfepGV2FZoOS9zOg5NxRT3g==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/text-buffer/-/text-buffer-13.15.0.tgz", + "integrity": "sha512-8X2rSI/W+w+nzSLQ8vm1xLFKZbgcLndDEOsMzN3lNKCy3Zuzru40fl2KHEko6MqHXAGKgA78+kvEDW/gryCP1g==", "requires": { "delegato": "^1.0.0", "diff": "^2.2.1", @@ -5541,9 +5541,9 @@ "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==" }, "tree-sitter": { - "version": "0.13.21", - "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.13.21.tgz", - "integrity": "sha512-BDbCtkNiDxVNcOl47zZl0mBnJuZNVp71iqBhNd3bucIIsIvKdNxiRjp0C2KcfNplnJ0Mgf0Vv7YN8XB8knzHCQ==", + "version": "0.13.23", + "resolved": "https://registry.npmjs.org/tree-sitter/-/tree-sitter-0.13.23.tgz", + "integrity": "sha512-75AiPbMEstv+YK8h4FkAHnmAJ6nNIUj/NFzRvKCHovmwSEKMi8Wc/E/crB4lJnHBOfV/f/DMQjN+e1Y36kagug==", "requires": { "nan": "^2.10.0", "prebuild-install": "^5.0.0" diff --git a/package.json b/package.json index 81f20df6d..5b1bfb0b3 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "base16-tomorrow-dark-theme": "file:packages/base16-tomorrow-dark-theme", "base16-tomorrow-light-theme": "file:packages/base16-tomorrow-light-theme", "bookmarks": "https://www.atom.io/api/packages/bookmarks/versions/0.45.1/tarball", - "bracket-matcher": "https://www.atom.io/api/packages/bracket-matcher/versions/0.89.4/tarball", + "bracket-matcher": "https://www.atom.io/api/packages/bracket-matcher/versions/0.90.2/tarball", "cached-run-in-this-context": "0.5.0", "chai": "3.5.0", "chart.js": "^2.3.0", @@ -157,9 +157,9 @@ "symbols-view": "https://www.atom.io/api/packages/symbols-view/versions/0.118.2/tarball", "tabs": "https://www.atom.io/api/packages/tabs/versions/0.109.2/tarball", "temp": "^0.8.3", - "text-buffer": "13.14.12", + "text-buffer": "13.15.0", "timecop": "https://www.atom.io/api/packages/timecop/versions/0.36.2/tarball", - "tree-sitter": "0.13.21", + "tree-sitter": "0.13.23", "tree-sitter-css": "^0.13.7", "tree-view": "https://www.atom.io/api/packages/tree-view/versions/0.224.4/tarball", "typescript-simple": "1.0.0", @@ -195,7 +195,7 @@ "autosave": "0.24.6", "background-tips": "0.28.0", "bookmarks": "0.45.1", - "bracket-matcher": "0.89.4", + "bracket-matcher": "0.90.2", "command-palette": "0.43.5", "dalek": "file:./packages/dalek", "deprecation-cop": "file:./packages/deprecation-cop", diff --git a/spec/tree-sitter-language-mode-spec.js b/spec/tree-sitter-language-mode-spec.js index 4c7ff8689..b6e5db70e 100644 --- a/spec/tree-sitter-language-mode-spec.js +++ b/spec/tree-sitter-language-mode-spec.js @@ -1424,7 +1424,8 @@ describe('TreeSitterLanguageMode', () => { parser: 'tree-sitter-javascript', scopes: { program: 'source.js', - property_identifier: 'property.name' + property_identifier: 'property.name', + comment: 'comment.block' } }) @@ -1447,6 +1448,15 @@ describe('TreeSitterLanguageMode', () => { 'source.js', 'property.name' ]) + + buffer.setText('// baz\n') + + // Adjust position when at end of line + buffer.setLanguageMode(new TreeSitterLanguageMode({buffer, grammar})) + expect(editor.scopeDescriptorForBufferPosition([0, '// baz'.length]).getScopesArray()).toEqual([ + 'source.js', + 'comment.block' + ]) }) it('includes nodes in injected syntax trees', async () => { @@ -1560,6 +1570,15 @@ describe('TreeSitterLanguageMode', () => { 'pair', 'property_identifier' ]) + + buffer.setText('//bar\n') + + buffer.setLanguageMode(new TreeSitterLanguageMode({buffer, grammar})) + expect(editor.syntaxTreeScopeDescriptorForBufferPosition([0, 5]).getScopesArray()).toEqual([ + 'source.js', + 'program', + 'comment' + ]) }) it('includes nodes in injected syntax trees', async () => { diff --git a/src/text-mate-language-mode.js b/src/text-mate-language-mode.js index 471af9af2..8cfd23a34 100644 --- a/src/text-mate-language-mode.js +++ b/src/text-mate-language-mode.js @@ -375,6 +375,8 @@ class TextMateLanguageMode { } } + bufferDidFinishTransaction () {} + isFoldableAtRow (row) { return this.endRowForFoldAtRow(row, 1, true) != null } diff --git a/src/tree-sitter-language-mode.js b/src/tree-sitter-language-mode.js index 870127625..c6b5a85ee 100644 --- a/src/tree-sitter-language-mode.js +++ b/src/tree-sitter-language-mode.js @@ -46,20 +46,6 @@ class TreeSitterLanguageMode { this.grammarForLanguageString = this.grammarForLanguageString.bind(this) - this.subscription = this.buffer.onDidChangeText(({changes}) => { - for (let i = 0, {length} = changes; i < length; i++) { - const {oldRange, newRange} = changes[i] - spliceArray( - this.isFoldableCache, - newRange.start.row, - oldRange.end.row - oldRange.start.row, - {length: newRange.end.row - newRange.start.row} - ) - } - - this.rootLanguageLayer.update(null) - }) - this.rootLanguageLayer.update(null).then(() => this.emitter.emit('did-tokenize') ) @@ -90,7 +76,6 @@ class TreeSitterLanguageMode { destroy () { this.injectionsMarkerLayer.destroy() - this.subscription.dispose() this.rootLanguageLayer = null this.parser = null } @@ -109,6 +94,19 @@ class TreeSitterLanguageMode { } } + bufferDidFinishTransaction (changes) { + for (let i = 0, {length} = changes; i < length; i++) { + const {oldRange, newRange} = changes[i] + spliceArray( + this.isFoldableCache, + newRange.start.row, + oldRange.end.row - oldRange.start.row, + {length: newRange.end.row - newRange.start.row} + ) + } + this.rootLanguageLayer.update(null) + } + parse (language, oldTree, ranges) { const parser = PARSER_POOL.pop() || new Parser() parser.setLanguage(language) @@ -455,7 +453,15 @@ class TreeSitterLanguageMode { syntaxTreeScopeDescriptorForPosition (point) { const nodes = [] - point = Point.fromObject(point) + point = this.buffer.clipPosition(Point.fromObject(point)) + + // If the position is the end of a line, get node of left character instead of newline + // This is to match TextMate behaviour, see https://github.com/atom/atom/issues/18463 + if (point.column > 0 && point.column === this.buffer.lineLengthForRow(point.row)) { + point = point.copy() + point.column-- + } + this._forEachTreeWithRange(new Range(point, point), tree => { let node = tree.rootNode.descendantForPosition(point) while (node) { @@ -478,7 +484,15 @@ class TreeSitterLanguageMode { } scopeDescriptorForPosition (point) { - point = Point.fromObject(point) + point = this.buffer.clipPosition(Point.fromObject(point)) + + // If the position is the end of a line, get scope of left character instead of newline + // This is to match TextMate behaviour, see https://github.com/atom/atom/issues/18463 + if (point.column > 0 && point.column === this.buffer.lineLengthForRow(point.row)) { + point = point.copy() + point.column-- + } + const iterator = this.buildHighlightIterator() const scopes = [] for (const scope of iterator.seek(point, point.row + 1)) {