WIP: Working on position translation. Pretty broken right now.

The layered relationship between the line wrapper and the folder is
still not quite ironed out yet. The editor behaves pretty erratically
when text is folded.
This commit is contained in:
Nathan Sobo 2012-02-24 21:05:12 -07:00
parent 33ff32f9a4
commit 17205cae3f
11 changed files with 176 additions and 95 deletions

View File

@ -65,13 +65,13 @@ describe "Editor", ->
expect(editor.lines.find('pre:eq(3)').text()).toBe " var pivot = items.shift(), current, left = [], "
expect(editor.lines.find('pre:eq(4)').text()).toBe "right = [];"
editor.cursor.setScreenPosition([3, 51])
editor.cursor.setBufferPosition([3, 51])
expect(editor.cursor.position()).toEqual(editor.lines.find('pre:eq(4)').position())
editor.cursor.setScreenPosition([4, 0])
editor.cursor.setBufferPosition([4, 0])
expect(editor.cursor.position()).toEqual(editor.lines.find('pre:eq(5)').position())
editor.selection.setRange(new Range([6, 30], [6, 55]))
editor.selection.setBufferRange(new Range([6, 30], [6, 55]))
[region1, region2] = editor.selection.regions
expect(region1.position().top).toBe(editor.lines.find('.line:eq(7)').position().top)
expect(region2.position().top).toBe(editor.lines.find('.line:eq(8)').position().top)
@ -333,7 +333,7 @@ describe "Editor", ->
[pageX, pageY] = window.pixelPositionForPoint(editor, [4, 7])
editor.lines.trigger mousedownEvent({pageX, pageY})
expect(editor.getCursorScreenPosition()).toEqual(row: 3, column: 58)
expect(editor.getCursorBufferPosition()).toEqual(row: 3, column: 58)
describe "when soft-wrap is disabled", ->
describe "when it is a single click", ->
@ -394,33 +394,33 @@ describe "Editor", ->
editor.trigger keydownEvent('right', shiftKey: true)
expect(selection.isEmpty()).toBeFalsy()
range = selection.getRange()
range = selection.getScreenRange()
expect(range.start).toEqual(row: 1, column: 6)
expect(range.end).toEqual(row: 1, column: 7)
editor.trigger keydownEvent('right', shiftKey: true)
range = selection.getRange()
range = selection.getScreenRange()
expect(range.start).toEqual(row: 1, column: 6)
expect(range.end).toEqual(row: 1, column: 8)
editor.trigger keydownEvent('down', shiftKey: true)
range = selection.getRange()
range = selection.getScreenRange()
expect(range.start).toEqual(row: 1, column: 6)
expect(range.end).toEqual(row: 2, column: 8)
editor.trigger keydownEvent('left', shiftKey: true)
range = selection.getRange()
range = selection.getScreenRange()
expect(range.start).toEqual(row: 1, column: 6)
expect(range.end).toEqual(row: 2, column: 7)
editor.trigger keydownEvent('up', shiftKey: true)
range = selection.getRange()
range = selection.getScreenRange()
expect(range.start).toEqual(row: 1, column: 6)
expect(range.end).toEqual(row: 1, column: 7)
describe "when the arrow keys are pressed without the shift modifier", ->
makeNonEmpty = ->
selection.setRange(new Range({row: 1, column: 2}, {row: 1, column: 5}))
selection.setBufferRange(new Range({row: 1, column: 2}, {row: 1, column: 5}))
expect(selection.isEmpty()).toBeFalsy()
it "clears the selection", ->
@ -453,7 +453,7 @@ describe "Editor", ->
[pageX, pageY] = window.pixelPositionForPoint(editor, [5, 27])
editor.lines.trigger mousemoveEvent({pageX, pageY})
range = editor.selection.getRange()
range = editor.selection.getScreenRange()
expect(range.start).toEqual({row: 4, column: 10})
expect(range.end).toEqual({row: 5, column: 27})
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
@ -465,7 +465,7 @@ describe "Editor", ->
[pageX, pageY] = window.pixelPositionForPoint(editor, [8, 8])
editor.lines.trigger mousemoveEvent({pageX, pageY})
range = editor.selection.getRange()
range = editor.selection.getScreenRange()
expect(range.start).toEqual({row: 4, column: 10})
expect(range.end).toEqual({row: 5, column: 27})
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
@ -484,7 +484,7 @@ describe "Editor", ->
[pageX, pageY] = window.pixelPositionForPoint(editor, [5, 27])
editor.lines.trigger mousemoveEvent({pageX, pageY})
range = editor.selection.getRange()
range = editor.selection.getScreenRange()
expect(range.start).toEqual({row: 4, column: 4})
expect(range.end).toEqual({row: 5, column: 27})
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
@ -496,7 +496,7 @@ describe "Editor", ->
[pageX, pageY] = window.pixelPositionForPoint(editor, [8, 8])
editor.lines.trigger mousemoveEvent({pageX, pageY})
range = editor.selection.getRange()
range = editor.selection.getScreenRange()
expect(range.start).toEqual({row: 4, column: 4})
expect(range.end).toEqual({row: 5, column: 27})
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
@ -518,7 +518,7 @@ describe "Editor", ->
[pageX, pageY] = window.pixelPositionForPoint(editor, [5, 27])
editor.lines.trigger mousemoveEvent({pageX, pageY})
range = editor.selection.getRange()
range = editor.selection.getScreenRange()
expect(range.start).toEqual({row: 4, column: 0})
expect(range.end).toEqual({row: 5, column: 27})
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
@ -530,7 +530,7 @@ describe "Editor", ->
[pageX, pageY] = window.pixelPositionForPoint(editor, [8, 8])
editor.lines.trigger mousemoveEvent({pageX, pageY})
range = editor.selection.getRange()
range = editor.selection.getScreenRange()
expect(range.start).toEqual({row: 4, column: 0})
expect(range.end).toEqual({row: 5, column: 27})
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
@ -551,7 +551,7 @@ describe "Editor", ->
describe "when there is a selection", ->
it "replaces the selected text with the typed text", ->
editor.selection.setRange(new Range([1, 6], [2, 4]))
editor.selection.setBufferRange(new Range([1, 6], [2, 4]))
editor.hiddenInput.textInput 'q'
expect(buffer.getLine(1)).toBe ' var qif (items.length <= 1) return items;'
@ -625,7 +625,7 @@ describe "Editor", ->
describe "when there is a selection", ->
it "deletes the selection, but not the character before it", ->
editor.selection.setRange(new Range([0,5], [0,9]))
editor.selection.setBufferRange(new Range([0,5], [0,9]))
editor.trigger keydownEvent('backspace')
expect(editor.buffer.getLine(0)).toBe 'var qsort = function () {'
@ -644,7 +644,7 @@ describe "Editor", ->
describe "when there is a selection", ->
it "deletes the selection, but not the character following it", ->
editor.selection.setRange(new Range([1,6], [1,8]))
editor.selection.setBufferRange(new Range([1,6], [1,8]))
editor.trigger keydownEvent 'delete'
expect(buffer.getLine(1)).toBe ' var rt = function(items) {'
@ -697,12 +697,12 @@ describe "Editor", ->
it "sets the cursor to the beginning of the file", ->
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
describe ".clipPosition(point)", ->
describe ".clipScreenPosition(point)", ->
it "selects the nearest valid position to the given point", ->
expect(editor.clipPosition(row: 1000, column: 0)).toEqual(row: buffer.lastRow(), column: buffer.getLine(buffer.lastRow()).length)
expect(editor.clipPosition(row: -5, column: 0)).toEqual(row: 0, column: 0)
expect(editor.clipPosition(row: 1, column: 10000)).toEqual(row: 1, column: buffer.getLine(1).length)
expect(editor.clipPosition(row: 1, column: -5)).toEqual(row: 1, column: 0)
expect(editor.clipScreenPosition(row: 1000, column: 0)).toEqual(row: buffer.lastRow(), column: buffer.getLine(buffer.lastRow()).length)
expect(editor.clipScreenPosition(row: -5, column: 0)).toEqual(row: 0, column: 0)
expect(editor.clipScreenPosition(row: 1, column: 10000)).toEqual(row: 1, column: buffer.getLine(1).length)
expect(editor.clipScreenPosition(row: 1, column: -5)).toEqual(row: 1, column: 0)
describe "cut, copy & paste", ->
beforeEach ->
@ -711,14 +711,14 @@ describe "Editor", ->
describe "when a cut event is triggered", ->
it "removes the selected text from the buffer and places it on the pasteboard", ->
editor.getSelection().setRange new Range([0,4], [0,9])
editor.getSelection().setBufferRange new Range([0,4], [0,9])
editor.trigger "cut"
expect(editor.buffer.getLine(0)).toBe "var sort = function () {"
expect(atom.native.readFromPasteboard()).toBe 'quick'
describe "when a copy event is triggered", ->
it "copies selected text onto the clipboard", ->
editor.getSelection().setRange new Range([0,4], [0, 13])
editor.getSelection().setBufferRange new Range([0,4], [0, 13])
editor.trigger "copy"
expect(atom.native.readFromPasteboard()).toBe 'quicksort'
@ -729,14 +729,17 @@ describe "Editor", ->
expect(editor.buffer.getLine(0)).toBe "var firstquicksort = function () {"
expect(editor.buffer.getLine(1)).toBe " var sort = function(items) {"
editor.getSelection().setRange new Range([1,6], [1,10])
editor.getSelection().setBufferRange new Range([1,6], [1,10])
editor.trigger "paste"
expect(editor.buffer.getLine(1)).toBe " var first = function(items) {"
describe "folding", ->
describe "when a fold-selection event is triggered", ->
it "folds the selected text and renders a placeholder for it", ->
editor.selection.setRange(new Range([4, 29], [7, 4]))
it "folds the selected text and moves the cursor to just after the placeholder", ->
editor.selection.setBufferRange(new Range([4, 29], [7, 4]))
editor.trigger 'fold-selection'
expect(editor.lines.find('.line:eq(4)').text()).toBe ' while(items.length > 0) {...}'
expect(editor.selection.isEmpty()).toBeTruthy()
expect(editor.getCursorScreenPosition()).toEqual [4, 32]

View File

@ -312,6 +312,7 @@ describe "LineFolder", ->
expect(folder.bufferPositionForScreenPosition([4, 5])).toEqual [4, 5]
expect(folder.bufferPositionForScreenPosition([4, 13])).toEqual [4, 15]
expect(folder.bufferPositionForScreenPosition([4, 18])).toEqual [4, 20]
describe ".clipScreenPosition(screenPosition)", ->
beforeEach ->
folder.createFold(new Range([4, 29], [7, 4]))
@ -323,11 +324,12 @@ describe "LineFolder", ->
expect(folder.clipScreenPosition([2, 15])).toEqual [2, 15]
expect(folder.clipScreenPosition([4, 32])).toEqual [4, 32]
expect(folder.clipScreenPosition([4, 1000])).toEqual [4, 33]
expect(folder.clipScreenPosition([1000, 1000])).toEqual [10, 2]
expect(folder.clipScreenPosition([1000, 1000])).toEqual [9, 2]
it "clips positions inside a placeholder to the beginning of the placeholder", ->
expect(folder.clipScreenPosition([4, 30])).toEqual [4, 29]
expect(folder.clipScreenPosition([4, 31])).toEqual [4, 29]
# expect(folder.clipScreenPosition([4, 31])).toEqual [4, 29]
# expect(folder.clipScreenPosition([4, 32])).toEqual [4, 32]

View File

@ -235,3 +235,21 @@ describe "LineWrapper", ->
expect(line2.endColumn).toBe 14
expect(line2.text.length).toBe 3
describe ".clipScreenPosition(screenPosition)", ->
it "returns the nearest valid position based on the current screen lines", ->
expect(wrapper.clipScreenPosition([-1, -1])).toEqual [0, 0]
expect(wrapper.clipScreenPosition([0, -1])).toEqual [0, 0]
expect(wrapper.clipScreenPosition([1, 10000])).toEqual [1, 30]
expect(wrapper.clipScreenPosition([3, 51])).toEqual [4, 0]
expect(wrapper.clipScreenPosition([3, 58])).toEqual [4, 0]
expect(wrapper.clipScreenPosition([4, 5])).toEqual [4, 5]
expect(wrapper.clipScreenPosition([4, 11])).toEqual [4, 11]
expect(wrapper.clipScreenPosition([4, 30])).toEqual [4, 11]
expect(wrapper.clipScreenPosition([4, 1000])).toEqual [4, 11]
expect(wrapper.clipScreenPosition([1000, 1000])).toEqual [15, 2]
it "also clips the screen position with respect to fold placeholders", ->
folder.createFold(new Range([3, 55], [3, 59]))
expect(wrapper.clipScreenPosition([4, 5])).toEqual [4, 4]
expect(wrapper.clipScreenPosition([4, 6])).toEqual [4, 4]

View File

@ -12,34 +12,34 @@ describe "Selection", ->
editor.setBuffer(buffer)
selection = editor.selection
describe ".setRange(range)", ->
describe ".setBufferRange(range)", ->
it "places the anchor at the start of the range and the cursor at the end", ->
range = new Range({row: 2, column: 7}, {row: 3, column: 18})
selection.setRange(range)
selection.setBufferRange(range)
expect(selection.anchor.getScreenPosition()).toEqual range.start
expect(selection.cursor.getScreenPosition()).toEqual range.end
describe ".delete()", ->
describe "when nothing is selected", ->
it "deletes nothing", ->
selection.setRange new Range([0,3], [0,3])
selection.setBufferRange new Range([0,3], [0,3])
selection.delete()
expect(editor.buffer.getLine(0)).toBe "var quicksort = function () {"
describe "when one line is selected", ->
it "deletes selected text", ->
selection.setRange new Range([0,4], [0,14])
selection.setBufferRange new Range([0,4], [0,14])
selection.delete()
expect(editor.buffer.getLine(0)).toBe "var = function () {"
endOfLine = editor.buffer.getLine(0).length
selection.setRange new Range([0,0], [0, endOfLine])
selection.setBufferRange new Range([0,0], [0, endOfLine])
selection.delete()
expect(editor.buffer.getLine(0)).toBe ""
describe "when multiple lines are selected", ->
it "deletes selected text", ->
selection.setRange new Range([0,1], [2,39])
selection.setBufferRange new Range([0,1], [2,39])
selection.delete()
expect(editor.buffer.getLine(0)).toBe "v;"
@ -53,7 +53,7 @@ describe "Selection", ->
describe "when the selection is within a single line", ->
it "covers the selection's range with a single region", ->
selection.setRange(new Range({row: 2, column: 7}, {row: 2, column: 25}))
selection.setBufferRange(new Range({row: 2, column: 7}, {row: 2, column: 25}))
expect(selection.regions.length).toBe 1
region = selection.regions[0]
@ -64,7 +64,7 @@ describe "Selection", ->
describe "when the selection spans 2 lines", ->
it "covers the selection's range with 2 regions", ->
selection.setRange(new Range({row: 2, column: 7}, {row: 3, column: 25}))
selection.setBufferRange(new Range({row: 2, column: 7}, {row: 3, column: 25}))
expect(selection.regions.length).toBe 2
@ -82,7 +82,7 @@ describe "Selection", ->
describe "when the selection spans more than 2 lines", ->
it "covers the selection's range with 3 regions", ->
selection.setRange(new Range({row: 2, column: 7}, {row: 6, column: 25}))
selection.setBufferRange(new Range({row: 2, column: 7}, {row: 6, column: 25}))
expect(selection.regions.length).toBe 3
@ -110,7 +110,7 @@ describe "Selection", ->
expect(region3.width()).toBe(25 * charWidth)
it "clears previously drawn regions before creating new ones", ->
selection.setRange(new Range({row: 2, column: 7}, {row: 4, column: 25}))
selection.setBufferRange(new Range({row: 2, column: 7}, {row: 4, column: 25}))
expect(selection.regions.length).toBe 3
expect(selection.find('.selection').length).toBe 3
@ -124,19 +124,19 @@ describe "Selection", ->
expect(atom.native.readFromPasteboard()).toBe 'first'
it "removes selected text from the buffer and places it on the clipboard", ->
selection.setRange new Range([0,4], [0,13])
selection.setBufferRange new Range([0,4], [0,13])
selection.cut()
expect(atom.native.readFromPasteboard()).toBe 'quicksort'
expect(editor.buffer.getLine(0)).toBe "var = function () {"
expect(selection.isEmpty()).toBeTruthy()
selection.setRange new Range([1,6], [3,8])
selection.setBufferRange new Range([1,6], [3,8])
selection.cut()
expect(atom.native.readFromPasteboard()).toBe "sort = function(items) {\n if (items.length <= 1) return items;\n var "
expect(editor.buffer.getLine(1)).toBe " var pivot = items.shift(), current, left = [], right = [];"
it "places nothing on the clipboard when there is no selection", ->
selection.setRange new Range([0,4], [0,4])
selection.setBufferRange new Range([0,4], [0,4])
selection.copy()
expect(atom.native.readFromPasteboard()).toBe 'first'
@ -146,16 +146,16 @@ describe "Selection", ->
expect(atom.native.readFromPasteboard()).toBe 'first'
it "places selected text on the clipboard", ->
selection.setRange new Range([0,4], [0,13])
selection.setBufferRange new Range([0,4], [0,13])
selection.copy()
expect(atom.native.readFromPasteboard()).toBe 'quicksort'
selection.setRange new Range([0,4], [3,13])
selection.setBufferRange new Range([0,4], [3,13])
selection.copy()
expect(atom.native.readFromPasteboard()).toBe "quicksort = function () {\n var sort = function(items) {\n if (items.length <= 1) return items;\n var pivot"
it "places nothing on the clipboard when there is no selection", ->
selection.setRange new Range([0,4], [0,4])
selection.setBufferRange new Range([0,4], [0,4])
selection.copy()
expect(atom.native.readFromPasteboard()).toBe 'first'

View File

@ -15,9 +15,9 @@ class Cursor extends View
bufferChanged: (e) ->
@setScreenPosition(e.newRange.end)
setScreenPosition: (point) ->
point = Point.fromObject(point)
@$position = @editor.clipPosition(point)
setScreenPosition: (position) ->
position = Point.fromObject(position)
@screenPosition = @editor.clipScreenPosition(position)
@goalColumn = null
@updateAppearance()
@trigger 'cursor:position-changed'
@ -26,7 +26,13 @@ class Cursor extends View
window.clearTimeout(@idleTimeout) if @idleTimeout
@idleTimeout = window.setTimeout (=> @addClass 'idle'), 200
getScreenPosition: -> _.clone(@$position)
setBufferPosition: (bufferPosition) ->
@setScreenPosition(@editor.screenPositionForBufferPosition(bufferPosition))
getBufferPosition: ->
@editor.bufferPositionForScreenPosition(@getScreenPosition())
getScreenPosition: -> _.clone(@screenPosition)
getColumn: ->
@getScreenPosition().column
@ -111,7 +117,7 @@ class Cursor extends View
@setScreenPosition [row, column + offset]
updateAppearance: ->
position = @editor.pixelPositionFromPoint(@getScreenPosition())
position = @editor.pixelPositionForScreenPosition(@getScreenPosition())
@css(position)
@autoScrollVertically(position)
@autoScrollHorizontally(position)

View File

@ -95,7 +95,7 @@ class Editor extends View
clickCount = e.originalEvent.detail
if clickCount == 1
@setCursorScreenPosition @pointFromMouseEvent(e)
@setCursorScreenPosition @screenPositionFromMouseEvent(e)
else if clickCount == 2
@selection.selectWord()
else if clickCount >= 3
@ -107,7 +107,7 @@ class Editor extends View
@insertText(e.originalEvent.data)
@on 'cursor:position-changed', =>
@hiddenInput.css(@pixelPositionFromPoint(@cursor.getScreenPosition()))
@hiddenInput.css(@pixelPositionForScreenPosition(@cursor.getScreenPosition()))
@one 'attach', =>
@calculateDimensions()
@ -116,7 +116,7 @@ class Editor extends View
@focus()
selectTextOnMouseMovement: ->
moveHandler = (e) => @selectToPosition(@pointFromMouseEvent(e))
moveHandler = (e) => @selectToScreenPosition(@screenPositionFromMouseEvent(e))
@on 'mousemove', moveHandler
$(document).one 'mouseup', => @off 'mousemove', moveHandler
@ -146,6 +146,9 @@ class Editor extends View
@buffer.on 'change', (e) =>
@cursor.bufferChanged(e)
@lineFolder.on 'fold', (range) =>
@setCursorBufferPosition(range.end)
@lineWrapper.on 'change', (e) =>
{ oldRange, newRange } = e
screenLines = @lineWrapper.linesForScreenRows(newRange.start.row, newRange.end.row)
@ -202,27 +205,30 @@ class Editor extends View
else
$(window).off 'resize', @_setMaxLineLength
clipPosition: ({row, column}) ->
if row > @buffer.lastRow()
row = @buffer.lastRow()
column = @buffer.getLine(row).length
else
row = Math.min(Math.max(0, row), @buffer.numLines() - 1)
column = Math.min(Math.max(0, column), @buffer.getLine(row).length)
clipScreenPosition: (screenPosition) ->
@lineWrapper.clipScreenPosition(screenPosition)
new Point(row, column)
pixelPositionFromPoint: (position) ->
{ row, column } = @lineWrapper.screenPositionForBufferPosition(position)
pixelPositionForScreenPosition: ({row, column}) ->
{ top: row * @lineHeight, left: column * @charWidth }
pointFromPixelPosition: ({top, left}) ->
screenPositionFromPixelPosition: ({top, left}) ->
screenPosition = new Point(Math.floor(top / @lineHeight), Math.floor(left / @charWidth))
@lineWrapper.bufferPositionForScreenPosition screenPosition
pointFromMouseEvent: (e) ->
screenPositionForBufferPosition: (position) ->
@lineWrapper.screenPositionForBufferPosition(position)
bufferPositionForScreenPosition: (position) ->
@lineWrapper.bufferPositionForScreenPosition(position)
screenRangeForBufferRange: (range) ->
@lineWrapper.screenRangeForBufferRange(range)
bufferRangeForScreenRange: (range) ->
@lineWrapper.bufferRangeForScreenRange(range)
screenPositionFromMouseEvent: (e) ->
{ pageX, pageY } = e
@pointFromPixelPosition
@screenPositionFromPixelPosition
top: pageY - @lines.offset().top
left: pageX - @lines.offset().left
@ -254,8 +260,10 @@ class Editor extends View
moveCursorDown: -> @cursor.moveDown()
moveCursorRight: -> @cursor.moveRight()
moveCursorLeft: -> @cursor.moveLeft()
setCursorScreenPosition: (point) -> @cursor.setScreenPosition(point)
setCursorScreenPosition: (position) -> @cursor.setScreenPosition(position)
getCursorScreenPosition: -> @cursor.getScreenPosition()
setCursorBufferPosition: (position) -> @cursor.setBufferPosition(position)
getCursorBufferPosition: -> @cursor.getBufferPosition()
setCursorRow: (row) -> @cursor.setRow(row)
getCursorRow: -> @cursor.getRow()
setCursorColumn: (column) -> @cursor.setColumn(column)
@ -265,8 +273,10 @@ class Editor extends View
selectLeft: -> @selection.selectLeft()
selectUp: -> @selection.selectUp()
selectDown: -> @selection.selectDown()
selectToPosition: (position) ->
@selection.selectToPosition(position)
selectToScreenPosition: (position) ->
@selection.selectToScreenPosition(position)
selectToBufferPosition: (position) ->
@selection.selectToBufferPosition(position)
insertText: (text) -> @selection.insertText(text)
insertNewline: -> @selection.insertNewline()

View File

@ -21,9 +21,7 @@ class LineFolder
@lineMap.insertAtBufferRow(0, @highlighter.screenLines)
logLines: (start=0, end=@lastRow())->
for row in [start..end]
line = @lineForScreenRow(row).text
console.log row, line, line.length
@lineMap.logLines(start, end)
createFold: (bufferRange) ->
fold = new Fold(this, bufferRange)
@ -142,6 +140,9 @@ class LineFolder
screenRangeForBufferRange: (bufferRange) ->
@lineMap.screenRangeForBufferRange(bufferRange)
bufferRangeForScreenRange: (screenRange) ->
@lineMap.bufferRangeForScreenRange(screenRange)
expandScreenRangeToLineEnds: (screenRange) ->
{ start, end } = screenRange
new Range([start.row, 0], [end.row, @lineMap.lineForScreenRow(end.row).text.length])

View File

@ -99,6 +99,9 @@ class LineMap
delta = delta.add(screenLine.screenDelta)
delta.row
lastScreenRow: ->
@screenLineCount() - 1
screenPositionForBufferPosition: (bufferPosition, eagerWrap=true) ->
bufferPosition = Point.fromObject(bufferPosition)
bufferDelta = new Point
@ -135,9 +138,20 @@ class LineMap
end = @screenPositionForBufferPosition(bufferRange.end)
new Range(start, end)
bufferRangeForScreenRange: (screenRange) ->
start = @bufferPositionForScreenPosition(screenRange.start)
end = @bufferPositionForScreenPosition(screenRange.end)
new Range(start, end)
clipScreenPosition: (screenPosition) ->
screenPosition = Point.fromObject(screenPosition)
debugger if screenPosition.isEqual [7,4]
screenPosition = new Point(Math.max(0, screenPosition.row), Math.max(0, screenPosition.column))
maxRow = @lastScreenRow()
if screenPosition.row > maxRow
screenPosition.row = maxRow
screenPosition.column = Infinity
screenDelta = new Point
for screenLine in @screenLines
@ -147,6 +161,9 @@ class LineMap
maxColumn = screenDelta.column + screenLine.lengthForClipping()
screenDelta.column = Math.min(maxColumn, screenPosition.column)
screenDelta
logLines: (start=0, end=@screenLineCount() - 1)->
for row in [start..end]
line = @lineForScreenRow(row).text
console.log row, line, line.length

View File

@ -76,9 +76,6 @@ class LineWrapper
return column + 1 if /\s/.test(line[column])
return @maxLength
screenRangeForBufferRange: (bufferRange) ->
@lineMap.screenRangeForBufferRange(bufferRange)
screenPositionForBufferPosition: (bufferPosition, eagerWrap=true) ->
@lineMap.screenPositionForBufferPosition(
@lineFolder.screenPositionForBufferPosition(bufferPosition),
@ -88,6 +85,23 @@ class LineWrapper
@lineFolder.bufferPositionForScreenPosition(
@lineMap.bufferPositionForScreenPosition(screenPosition))
screenRangeForBufferRange: (bufferRange) ->
@lineMap.screenRangeForBufferRange(
@lineFolder.screenRangeForBufferRange(bufferRange))
bufferRangeForScreenRange: (screenRange) ->
@lineFolder.bufferRangeForScreenRange(
@lineMap.bufferRangeForScreenRange(screenRange))
clipScreenPosition: (screenPosition) ->
# console.log @lineMap.bufferPositionForScreenPosition(@lineMap.clipScreenPosition(screenPosition)).inspect()
@lineFolder.clipScreenPosition(@lineMap.clipScreenPosition(screenPosition))
# @lineMap.clipScreenPosition(screenPosition)
# @lineMap.screenPositionForBufferPosition(
# @lineFolder.clipScreenPosition(
# @lineMap.bufferPositionForScreenPosition(
# @lineMap.clipScreenPosition(screenPosition))))
lineForScreenRow: (screenRow) ->
@linesForScreenRows(screenRow, screenRow)[0]
@ -100,4 +114,7 @@ class LineWrapper
lineCount: ->
@lineMap.screenLineCount()
logLines: (start=0, end=@lineCount() - 1)->
@lineMap.logLines(start, end)
_.extend(LineWrapper.prototype, EventEmitter)

View File

@ -60,35 +60,38 @@ class Selection extends View
region.remove() for region in @regions
@regions = []
getRange: ->
getScreenRange: ->
if @anchor
new Range(@anchor.getScreenPosition(), @cursor.getScreenPosition())
else
new Range(@cursor.getScreenPosition(), @cursor.getScreenPosition())
setRange: (range) ->
setScreenRange: (range) ->
@cursor.setScreenPosition(range.start)
@modifySelection =>
@cursor.setScreenPosition(range.end)
getScreenRange: ->
@editor.lineWrapper.screenRangeForBufferRange(@getRange())
getBufferRange: ->
@editor.bufferRangeForScreenRange(@getScreenRange())
setBufferRange: (bufferRange) ->
@setScreenRange(@editor.screenRangeForBufferRange(bufferRange))
getText: ->
@editor.buffer.getTextInRange @getRange()
@editor.buffer.getTextInRange @getBufferRange()
insertText: (text) ->
@editor.buffer.change(@getRange(), text)
@editor.buffer.change(@getBufferRange(), text)
insertNewline: ->
@insertText('\n')
delete: ->
range = @getRange()
range = @getBufferRange()
@editor.buffer.change(range, '') unless range.isEmpty()
isEmpty: ->
@getRange().isEmpty()
@getBufferRange().isEmpty()
modifySelection: (fn) ->
@placeAnchor()
@ -114,11 +117,11 @@ class Selection extends View
endOffset = regex.exec(rightSide)?[0]?.length or 0
range = new Range([row, column + startOffset], [row, column + endOffset])
@setRange range
@setBufferRange range
selectLine: (row) ->
rowLength = @editor.buffer.getLine(row).length
@setRange new Range([row, 0], [row, rowLength])
@setBufferRange new Range([row, 0], [row, rowLength])
selectRight: ->
@modifySelection =>
@ -140,10 +143,14 @@ class Selection extends View
@modifySelection =>
@cursor.moveLeftUntilMatch(regex)
selectToPosition: (position) ->
selectToScreenPosition: (position) ->
@modifySelection =>
@cursor.setScreenPosition(position)
selectToBufferPosition: (position) ->
@modifySelection =>
@cursor.setBufferPosition(position)
moveCursorToLineEnd: ->
@cursor.moveToLineEnd()
@ -156,8 +163,8 @@ class Selection extends View
copy: ->
return if @isEmpty()
text = @editor.buffer.getTextInRange @getRange()
text = @editor.buffer.getTextInRange(@getBufferRange())
atom.native.writeToPasteboard text
fold: ->
@editor.lineFolder.createFold(@getRange())
@editor.lineFolder.createFold(@getBufferRange())

View File

@ -13,7 +13,7 @@ class MoveLeft extends Motion
select: ->
position = @editor.getCursorScreenPosition()
position.column-- if position.column > 0
@editor.selectToPosition position
@editor.selectToBufferPosition(position)
class MoveRight extends Motion
execute: ->
@ -42,7 +42,7 @@ class MoveToNextWord extends Motion
@editor.setCursorScreenPosition(@nextWordPosition())
select: ->
@editor.selectToPosition(@nextWordPosition())
@editor.selectToBufferPosition(@nextWordPosition())
nextWordPosition: ->
regex = getWordRegex()