Use line ending length for mapping positions/characters

Previously the line ending length was hard-coded to one which
would cause TextBuffer.scanInRange() to return incorrect results
since one character per line wasn't being accounted for.

Closes #428
This commit is contained in:
Kevin Sawicki
2013-03-30 00:25:57 -04:00
parent dc3b26c934
commit da090b57d4
2 changed files with 21 additions and 3 deletions

View File

@@ -725,6 +725,13 @@ describe 'Buffer', ->
expect(buffer.characterIndexForPosition([2, 0])).toBe 61
expect(buffer.characterIndexForPosition([12, 2])).toBe 408
describe "when the buffer contains crlf line endings", ->
it "returns the total number of characters that precede the given position", ->
buffer.setText("line1\r\nline2\nline3\r\nline4")
expect(buffer.characterIndexForPosition([1])).toBe 7
expect(buffer.characterIndexForPosition([2])).toBe 13
expect(buffer.characterIndexForPosition([3])).toBe 20
describe ".positionForCharacterIndex(position)", ->
it "returns the position based on character index", ->
expect(buffer.positionForCharacterIndex(0)).toEqual [0, 0]
@@ -734,6 +741,13 @@ describe 'Buffer', ->
expect(buffer.positionForCharacterIndex(61)).toEqual [2, 0]
expect(buffer.positionForCharacterIndex(408)).toEqual [12, 2]
describe "when the buffer contains crlf line endings", ->
it "returns the position based on character index", ->
buffer.setText("line1\r\nline2\nline3\r\nline4")
expect(buffer.positionForCharacterIndex(7)).toEqual [1, 0]
expect(buffer.positionForCharacterIndex(13)).toEqual [2, 0]
expect(buffer.positionForCharacterIndex(20)).toEqual [3, 0]
describe "markers", ->
describe "marker creation", ->
it "allows markers to be created with ranges and positions", ->

View File

@@ -145,6 +145,9 @@ class Buffer
lineLengthForRow: (row) ->
@lines[row].length
lineEndingLengthForRow: (row) ->
(@lineEndingForRow(row) ? '').length
rangeForRow: (row, { includeNewline } = {}) ->
if includeNewline and row < @getLastRow()
new Range([row, 0], [row + 1, 0])
@@ -168,12 +171,13 @@ class Buffer
position = Point.fromObject(position)
index = 0
index += @lineLengthForRow(row) + 1 for row in [0...position.row]
for row in [0...position.row]
index += @lineLengthForRow(row) + Math.max(@lineEndingLengthForRow(row), 1)
index + position.column
positionForCharacterIndex: (index) ->
row = 0
while index >= (lineLength = @lineLengthForRow(row) + 1)
while index >= (lineLength = @lineLengthForRow(row) + Math.max(@lineEndingLengthForRow(row), 1))
index -= lineLength
row++
@@ -358,7 +362,7 @@ class Buffer
@scanInRange(regex, @getRange(), iterator)
scanInRange: (regex, range, iterator, reverse=false) ->
range = Range.fromObject(range)
range = @clipRange(range)
global = regex.global
flags = "gm"
flags += "i" if regex.ignoreCase