Handle positions between CR and LF characters in TreeSitterTextBufferInput.seek

This commit is contained in:
Max Brunsfeld
2018-02-14 07:49:02 -08:00
parent b9e4febf03
commit 3e7e8aecce
3 changed files with 55 additions and 6 deletions

View File

@@ -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",

View File

@@ -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', () => {

View File

@@ -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
}