This commit is contained in:
Nathan Sobo 2012-01-26 13:46:12 -08:00
parent c70206fc9c
commit 2825c945e5
3 changed files with 100 additions and 93 deletions

View File

@ -25,13 +25,13 @@ describe "Editor", ->
expect(editor.lines.find('pre:eq(10)').html()).toBe ' '
it "sets the cursor to the beginning of the file", ->
expect(editor.getPosition()).toEqual(row: 0, column: 0)
expect(editor.getCursorPosition()).toEqual(row: 0, column: 0)
describe "cursor movement", ->
describe ".setPosition({row, column})", ->
describe ".setCursorPosition({row, column})", ->
it "moves the cursor to cover the character at the given row and column", ->
editor.attachToDom()
editor.setPosition(row: 2, column: 2)
editor.setCursorPosition(row: 2, column: 2)
expect(editor.getCursor().position().top).toBe(2 * editor.lineHeight)
expect(editor.getCursor().position().left).toBe(2 * editor.charWidth)
@ -39,16 +39,16 @@ describe "Editor", ->
describe "when the arrow keys are pressed", ->
it "moves the cursor by a single row/column", ->
editor.trigger keydownEvent('right')
expect(editor.getPosition()).toEqual(row: 0, column: 1)
expect(editor.getCursorPosition()).toEqual(row: 0, column: 1)
editor.trigger keydownEvent('down')
expect(editor.getPosition()).toEqual(row: 1, column: 1)
expect(editor.getCursorPosition()).toEqual(row: 1, column: 1)
editor.trigger keydownEvent('left')
expect(editor.getPosition()).toEqual(row: 1, column: 0)
expect(editor.getCursorPosition()).toEqual(row: 1, column: 0)
editor.trigger keydownEvent('up')
expect(editor.getPosition()).toEqual(row: 0, column: 0)
expect(editor.getCursorPosition()).toEqual(row: 0, column: 0)
describe "vertical movement", ->
describe "auto-scrolling", ->
@ -60,30 +60,30 @@ describe "Editor", ->
it "scrolls the buffer with the specified scroll margin when cursor approaches the end of the screen", ->
editor.height(editor.lineHeight * 10)
_.times 6, -> editor.moveDown()
_.times 6, -> editor.moveCursorDown()
expect(editor.scrollTop()).toBe(0)
editor.moveDown()
editor.moveCursorDown()
expect(editor.scrollTop()).toBe(editor.lineHeight)
editor.moveDown()
editor.moveCursorDown()
expect(editor.scrollTop()).toBe(editor.lineHeight * 2)
_.times 3, -> editor.moveUp()
_.times 3, -> editor.moveCursorUp()
expect(editor.scrollTop()).toBe(editor.lineHeight * 2)
editor.moveUp()
editor.moveCursorUp()
expect(editor.scrollTop()).toBe(editor.lineHeight)
editor.moveUp()
editor.moveCursorUp()
expect(editor.scrollTop()).toBe(0)
it "reduces scroll margins when there isn't enough height to maintain them and scroll smoothly", ->
editor.height(editor.lineHeight * 5)
_.times 3, -> editor.moveDown()
_.times 3, -> editor.moveCursorDown()
expect(editor.scrollTop()).toBe(editor.lineHeight)
editor.moveUp()
editor.moveCursorUp()
expect(editor.scrollTop()).toBe(0)
describe "goal column retention", ->
@ -97,50 +97,50 @@ describe "Editor", ->
it "retains the goal column when moving up", ->
expect(lineLengths[6]).toBeGreaterThan(32)
editor.setPosition(row: 6, column: 32)
editor.setCursorPosition(row: 6, column: 32)
editor.moveUp()
expect(editor.getPosition().column).toBe lineLengths[5]
editor.moveCursorUp()
expect(editor.getCursorPosition().column).toBe lineLengths[5]
editor.moveUp()
expect(editor.getPosition().column).toBe lineLengths[4]
editor.moveCursorUp()
expect(editor.getCursorPosition().column).toBe lineLengths[4]
editor.moveUp()
expect(editor.getPosition().column).toBe 32
editor.moveCursorUp()
expect(editor.getCursorPosition().column).toBe 32
it "retains the goal column when moving down", ->
editor.setPosition(row: 3, column: lineLengths[3])
editor.setCursorPosition(row: 3, column: lineLengths[3])
editor.moveDown()
expect(editor.getPosition().column).toBe lineLengths[4]
editor.moveCursorDown()
expect(editor.getCursorPosition().column).toBe lineLengths[4]
editor.moveDown()
expect(editor.getPosition().column).toBe lineLengths[5]
editor.moveCursorDown()
expect(editor.getCursorPosition().column).toBe lineLengths[5]
editor.moveDown()
expect(editor.getPosition().column).toBe lineLengths[3]
editor.moveCursorDown()
expect(editor.getCursorPosition().column).toBe lineLengths[3]
it "clears the goal column when the cursor is set", ->
# set a goal column by moving down
editor.setPosition(row: 3, column: lineLengths[3])
editor.moveDown()
expect(editor.getPosition().column).not.toBe 6
editor.setCursorPosition(row: 3, column: lineLengths[3])
editor.moveCursorDown()
expect(editor.getCursorPosition().column).not.toBe 6
# clear the goal column by explicitly setting the cursor position
editor.setColumn(6)
expect(editor.getPosition().column).toBe 6
editor.setCursorColumn(6)
expect(editor.getCursorPosition().column).toBe 6
editor.moveDown()
expect(editor.getPosition().column).toBe 6
editor.moveCursorDown()
expect(editor.getCursorPosition().column).toBe 6
describe "when up is pressed on the first line", ->
it "moves the cursor to the beginning of the line, but retains the goal column", ->
editor.setPosition(row: 0, column: 4)
editor.moveUp()
expect(editor.getPosition()).toEqual(row: 0, column: 0)
editor.setCursorPosition(row: 0, column: 4)
editor.moveCursorUp()
expect(editor.getCursorPosition()).toEqual(row: 0, column: 0)
editor.moveDown()
expect(editor.getPosition()).toEqual(row: 1, column: 4)
editor.moveCursorDown()
expect(editor.getCursorPosition()).toEqual(row: 1, column: 4)
describe "when down is pressed on the last line", ->
it "moves the cursor to the end of line, but retains the goal column", ->
@ -148,43 +148,43 @@ describe "Editor", ->
lastLine = buffer.getLine(lastLineIndex)
expect(lastLine.length).toBeGreaterThan(0)
editor.setPosition(row: lastLineIndex, column: 1)
editor.moveDown()
expect(editor.getPosition()).toEqual(row: lastLineIndex, column: lastLine.length)
editor.setCursorPosition(row: lastLineIndex, column: 1)
editor.moveCursorDown()
expect(editor.getCursorPosition()).toEqual(row: lastLineIndex, column: lastLine.length)
editor.moveUp()
expect(editor.getPosition().column).toBe 1
editor.moveCursorUp()
expect(editor.getCursorPosition().column).toBe 1
it "retains a goal column of 0", ->
lastLineIndex = buffer.getLines().length - 1
lastLine = buffer.getLine(lastLineIndex)
expect(lastLine.length).toBeGreaterThan(0)
editor.setPosition(row: lastLineIndex, column: 0)
editor.moveDown()
editor.moveUp()
expect(editor.getPosition().column).toBe 0
editor.setCursorPosition(row: lastLineIndex, column: 0)
editor.moveCursorDown()
editor.moveCursorUp()
expect(editor.getCursorPosition().column).toBe 0
describe "horizontal movement", ->
describe "when left is pressed on the first column", ->
describe "when there is a previous line", ->
it "wraps to the end of the previous line", ->
editor.setPosition(row: 1, column: 0)
editor.moveLeft()
expect(editor.getPosition()).toEqual(row: 0, column: buffer.getLine(0).length)
editor.setCursorPosition(row: 1, column: 0)
editor.moveCursorLeft()
expect(editor.getCursorPosition()).toEqual(row: 0, column: buffer.getLine(0).length)
describe "when the cursor is on the first line", ->
it "remains in the same position (0,0)", ->
editor.setPosition(row: 0, column: 0)
editor.moveLeft()
expect(editor.getPosition()).toEqual(row: 0, column: 0)
editor.setCursorPosition(row: 0, column: 0)
editor.moveCursorLeft()
expect(editor.getCursorPosition()).toEqual(row: 0, column: 0)
describe "when right is pressed on the last column", ->
describe "when there is a subsequent line", ->
it "wraps to the beginning of the next line", ->
editor.setPosition(row: 0, column: buffer.getLine(0).length)
editor.moveRight()
expect(editor.getPosition()).toEqual(row: 1, column: 0)
editor.setCursorPosition(row: 0, column: buffer.getLine(0).length)
editor.moveCursorRight()
expect(editor.getCursorPosition()).toEqual(row: 1, column: 0)
describe "when the cursor is on the last line", ->
it "remains in the same position", ->
@ -193,14 +193,14 @@ describe "Editor", ->
expect(lastLine.length).toBeGreaterThan(0)
lastPosition = { row: lastLineIndex, column: lastLine.length }
editor.setPosition(lastPosition)
editor.moveRight()
editor.setCursorPosition(lastPosition)
editor.moveCursorRight()
expect(editor.getPosition()).toEqual(lastPosition)
expect(editor.getCursorPosition()).toEqual(lastPosition)
describe "when the editor is attached to the dom", ->
it "updates the pixel position of the cursor", ->
editor.setPosition(row: 2, column: 2)
editor.setCursorPosition(row: 2, column: 2)
editor.attachToDom()
@ -220,29 +220,29 @@ describe "Editor", ->
describe "when text input events are triggered on the hidden input element", ->
it "inserts the typed character at the cursor position, both in the buffer and the pre element", ->
editor.setPosition(row: 1, column: 6)
editor.setCursorPosition(row: 1, column: 6)
expect(editor.getCurrentLine().charAt(6)).not.toBe 'q'
editor.hiddenInput.textInput 'q'
expect(editor.getCurrentLine().charAt(6)).toBe 'q'
expect(editor.getPosition()).toEqual(row: 1, column: 7)
expect(editor.getCursorPosition()).toEqual(row: 1, column: 7)
expect(editor.lines.find('pre:eq(1)')).toHaveText editor.getCurrentLine()
describe "when return is pressed", ->
describe "when the cursor is at the beginning of a line", ->
it "inserts an empty line before it", ->
editor.setPosition(row: 1, column: 0)
editor.setCursorPosition(row: 1, column: 0)
editor.trigger keydownEvent('enter')
expect(editor.lines.find('pre:eq(1)')).toHaveHtml ' '
expect(editor.getPosition()).toEqual(row: 2, column: 0)
expect(editor.getCursorPosition()).toEqual(row: 2, column: 0)
describe "when the cursor is in the middle of a line", ->
it "splits the current line to form a new line", ->
editor.setPosition(row: 1, column: 6)
editor.setCursorPosition(row: 1, column: 6)
originalLine = editor.lines.find('pre:eq(1)').text()
lineBelowOriginalLine = editor.lines.find('pre:eq(2)').text()
@ -251,26 +251,26 @@ describe "Editor", ->
expect(editor.lines.find('pre:eq(1)')).toHaveText originalLine[0...6]
expect(editor.lines.find('pre:eq(2)')).toHaveText originalLine[6..]
expect(editor.lines.find('pre:eq(3)')).toHaveText lineBelowOriginalLine
expect(editor.getPosition()).toEqual(row: 2, column: 0)
expect(editor.getCursorPosition()).toEqual(row: 2, column: 0)
describe "when the cursor is on the end of a line", ->
it "inserts an empty line after it", ->
editor.setPosition(row: 1, column: buffer.getLine(1).length)
editor.setCursorPosition(row: 1, column: buffer.getLine(1).length)
editor.trigger keydownEvent('enter')
expect(editor.lines.find('pre:eq(2)')).toHaveHtml ' '
expect(editor.getPosition()).toEqual(row: 2, column: 0)
expect(editor.getCursorPosition()).toEqual(row: 2, column: 0)
describe "when backspace is pressed", ->
describe "when the cursor is on the middle of the line", ->
it "removes the character before the cursor", ->
editor.setPosition(row: 1, column: 7)
editor.setCursorPosition(row: 1, column: 7)
spyOn(buffer, 'backspace').andCallThrough()
editor.trigger keydownEvent('backspace')
expect(buffer.backspace).toHaveBeenCalledWith(row: 1, column: 7)
expect(editor.lines.find('pre:eq(1)')).toHaveText buffer.getLine(1)
expect(editor.getPosition()).toEqual {row: 1, column: 6}
expect(editor.getCursorPosition()).toEqual {row: 1, column: 6}

View File

@ -34,12 +34,12 @@ class Editor extends Template
enter: 'newline'
backspace: 'backspace'
@on 'move-right', => @moveRight()
@on 'move-left', => @moveLeft()
@on 'move-down', => @moveDown()
@on 'move-up', => @moveUp()
@on 'newline', => @buffer.change({ start: @getPosition(), end: @getPosition() }, "\n")
@on 'backspace', => @buffer.backspace @getPosition()
@on 'move-right', => @moveCursorRight()
@on 'move-left', => @moveCursorLeft()
@on 'move-down', => @moveCursorDown()
@on 'move-up', => @moveCursorUp()
@on 'newline', => @buffer.change({ start: @getCursorPosition(), end: @getCursorPosition() }, "\n")
@on 'backspace', => @buffer.backspace @getCursorPosition()
handleEvents: ->
@on 'focus', =>
@ -47,7 +47,7 @@ class Editor extends Template
false
@hiddenInput.on "textInput", (e) =>
@buffer.change({ start: @getPosition(), end: @getPosition() }, e.originalEvent.data)
@buffer.change({ start: @getCursorPosition(), end: @getCursorPosition() }, e.originalEvent.data)
@one 'attach', =>
@calculateDimensions()
@ -64,7 +64,7 @@ class Editor extends Template
for line in @buffer.getLines()
@lines.append @buildLineElement(line)
@setPosition(row: 0, column: 0)
@setCursorPosition(row: 0, column: 0)
@buffer.on 'change', (e) =>
{ preRange, postRange } = e
@ -121,14 +121,18 @@ class Editor extends Template
else
@scrollTop() + @height()
getCurrentLine: -> @buffer.getLine(@getPosition().row)
getCurrentLine: -> @buffer.getLine(@getCursorRow())
getCursor: -> @selection.cursor
moveUp: -> @selection.moveCursorUp()
moveDown: -> @selection.moveCursorDown()
moveRight: -> @selection.moveCursorRight()
moveLeft: -> @selection.moveCursorLeft()
setPosition: (point) -> @selection.setCursorPosition(point)
getPosition: -> @selection.getCursorPosition()
setColumn: (column) -> @selection.setCursorColumn(column)
moveCursorUp: -> @selection.moveCursorUp()
moveCursorDown: -> @selection.moveCursorDown()
moveCursorRight: -> @selection.moveCursorRight()
moveCursorLeft: -> @selection.moveCursorLeft()
setCursorPosition: (point) -> @selection.setCursorPosition(point)
getCursorPosition: -> @selection.getCursorPosition()
setCursorRow: (row) -> @selection.setCursorRow(row)
getCursorRow: -> @selection.getCursorRow()
setCursorColumn: (column) -> @selection.setCursorColumn(column)
getCursorColumn: -> @selection.getCursorColumn()

View File

@ -23,15 +23,18 @@ class Selection extends Template
getCursorPosition: ->
@cursor.getPosition()
setCursorRow: (row) ->
@cursor.setRow(row)
getCursorRow: ->
@cursor.getRow()
setCursorColumn: (column) ->
@cursor.setColumn(column)
getCursorColumn: ->
@cursor.getColumn()
getCursorRow: ->
@cursor.getRow()
moveCursorUp: ->
@cursor.moveUp()