From 3e7e8aecce7c0d63d9c4a0412bb39ea962a466f3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 14 Feb 2018 07:49:02 -0800 Subject: [PATCH] Handle positions between CR and LF characters in TreeSitterTextBufferInput.seek --- package.json | 2 +- spec/tree-sitter-language-mode-spec.js | 43 ++++++++++++++++++++++++++ src/tree-sitter-language-mode.js | 16 +++++++--- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index a066f23f7..9d9e37f87 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "sinon": "1.17.4", "temp": "^0.8.3", "text-buffer": "13.11.8", - "tree-sitter": "^0.9.0", + "tree-sitter": "^0.9.1", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", diff --git a/spec/tree-sitter-language-mode-spec.js b/spec/tree-sitter-language-mode-spec.js index 58a098dca..ae3daf83c 100644 --- a/spec/tree-sitter-language-mode-spec.js +++ b/spec/tree-sitter-language-mode-spec.js @@ -170,6 +170,49 @@ describe('TreeSitterLanguageMode', () => { [{text: ')', scopes: []}] ]) }) + + it('handles edits after tokens that end between CR and LF characters (regression)', () => { + const grammar = new TreeSitterGrammar(atom.grammars, jsGrammarPath, { + parser: 'tree-sitter-javascript', + scopes: { + 'comment': 'comment', + 'string': 'string', + 'property_identifier': 'property', + } + }) + + buffer.setLanguageMode(new TreeSitterLanguageMode({buffer, grammar})) + + buffer.setText([ + '// abc', + '', + 'a("b").c' + ].join('\r\n')) + + expectTokensToEqual(editor, [ + [{text: '// abc', scopes: ['comment']}], + [{text: '', scopes: []}], + [ + {text: 'a(', scopes: []}, + {text: '"b"', scopes: ['string']}, + {text: ').', scopes: []}, + {text: 'c', scopes: ['property']} + ] + ]) + + buffer.insert([2, 0], ' ') + expectTokensToEqual(editor, [ + [{text: '// abc', scopes: ['comment']}], + [{text: '', scopes: []}], + [ + {text: ' ', scopes: ['whitespace']}, + {text: 'a(', scopes: []}, + {text: '"b"', scopes: ['string']}, + {text: ').', scopes: []}, + {text: 'c', scopes: ['property']} + ] + ]) + }) }) describe('folding', () => { diff --git a/src/tree-sitter-language-mode.js b/src/tree-sitter-language-mode.js index 945af9331..e6d207ebc 100644 --- a/src/tree-sitter-language-mode.js +++ b/src/tree-sitter-language-mode.js @@ -495,16 +495,22 @@ class TreeSitterHighlightIterator { class TreeSitterTextBufferInput { constructor (buffer) { this.buffer = buffer - this.seek(0) + this.position = {row: 0, column: 0} + this.isBetweenCRLF = false } - seek (characterIndex) { - this.position = this.buffer.positionForCharacterIndex(characterIndex) + seek (offset, position) { + this.position = position + this.isBetweenCRLF = this.position.column > this.buffer.lineLengthForRow(this.position.row) } read () { - const endPosition = this.buffer.clipPosition(this.position.traverse({row: 1000, column: 0})) - const text = this.buffer.getTextInRange([this.position, endPosition]) + const endPosition = this.buffer.clipPosition(new Point(this.position.row + 1000, 0)) + let text = this.buffer.getTextInRange([this.position, endPosition]) + if (this.isBetweenCRLF) { + text = text.slice(1) + this.isBetweenCRLF = false + } this.position = endPosition return text }