2012-01-05 23:13:55 +04:00
|
|
|
Buffer = require 'buffer'
|
2011-12-16 02:13:34 +04:00
|
|
|
Editor = require 'editor'
|
2012-01-28 00:42:33 +04:00
|
|
|
Range = require 'range'
|
2011-12-16 02:13:34 +04:00
|
|
|
$ = require 'jquery'
|
2012-01-24 04:45:00 +04:00
|
|
|
_ = require 'underscore'
|
2011-12-17 02:42:38 +04:00
|
|
|
fs = require 'fs'
|
2011-12-16 02:13:34 +04:00
|
|
|
|
2012-01-24 02:37:03 +04:00
|
|
|
describe "Editor", ->
|
2012-01-17 05:17:36 +04:00
|
|
|
buffer = null
|
2011-12-17 04:25:33 +04:00
|
|
|
editor = null
|
2011-12-16 02:13:34 +04:00
|
|
|
|
|
|
|
beforeEach ->
|
2012-01-17 05:17:36 +04:00
|
|
|
buffer = new Buffer(require.resolve('fixtures/sample.js'))
|
2012-02-06 23:12:45 +04:00
|
|
|
editor = new Editor
|
2012-01-18 06:13:50 +04:00
|
|
|
editor.enableKeymap()
|
|
|
|
editor.setBuffer(buffer)
|
2011-12-16 02:13:34 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
describe "text rendering", ->
|
2012-02-28 23:27:35 +04:00
|
|
|
it "creates a line element for each line in the buffer with the html-escaped text of the line", ->
|
|
|
|
expect(editor.lines.find('.line').length).toEqual(buffer.numLines())
|
2012-01-20 07:08:40 +04:00
|
|
|
expect(buffer.getLine(2)).toContain('<')
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(2)').html()).toContain '<'
|
2012-01-20 07:08:40 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
# renders empty lines with a non breaking space
|
2012-01-20 07:08:40 +04:00
|
|
|
expect(buffer.getLine(10)).toBe ''
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(10)').html()).toBe ' '
|
2012-01-11 07:16:46 +04:00
|
|
|
|
2012-02-01 08:59:58 +04:00
|
|
|
it "syntax highlights code based on the file type", ->
|
|
|
|
line1 = editor.lines.find('.line:first')
|
|
|
|
expect(line1.find('span:eq(0)')).toMatchSelector '.keyword.definition'
|
|
|
|
expect(line1.find('span:eq(0)').text()).toBe 'var'
|
|
|
|
expect(line1.find('span:eq(1)')).toMatchSelector '.text'
|
|
|
|
expect(line1.find('span:eq(1)').text()).toBe ' '
|
|
|
|
expect(line1.find('span:eq(2)')).toMatchSelector '.identifier'
|
|
|
|
expect(line1.find('span:eq(2)').text()).toBe 'quicksort'
|
|
|
|
expect(line1.find('span:eq(4)')).toMatchSelector '.operator'
|
|
|
|
expect(line1.find('span:eq(4)').text()).toBe '='
|
|
|
|
|
|
|
|
line12 = editor.lines.find('.line:eq(11)')
|
|
|
|
expect(line12.find('span:eq(1)')).toMatchSelector '.keyword'
|
|
|
|
|
2012-02-03 04:04:37 +04:00
|
|
|
describe "when lines are updated in the buffer", ->
|
|
|
|
it "syntax highlights the updated lines", ->
|
|
|
|
expect(editor.lines.find('.line:eq(0) span:eq(0)')).toMatchSelector '.keyword.definition'
|
|
|
|
buffer.insert([0, 4], "g")
|
|
|
|
expect(editor.lines.find('.line:eq(0) span:eq(0)')).toMatchSelector '.keyword.definition'
|
|
|
|
|
2012-02-03 21:39:13 +04:00
|
|
|
# verify that re-highlighting can occur below the changed line
|
|
|
|
buffer.insert([5,0], "/* */")
|
|
|
|
buffer.insert([1,0], "/*")
|
|
|
|
expect(editor.lines.find('.line:eq(2) span:eq(0)')).toMatchSelector '.comment'
|
|
|
|
|
2012-02-08 23:30:46 +04:00
|
|
|
describe "when soft-wrap is enabled", ->
|
2012-02-08 01:43:33 +04:00
|
|
|
beforeEach ->
|
2012-02-11 02:18:02 +04:00
|
|
|
editor.width(9 * 50)
|
2012-02-08 01:43:33 +04:00
|
|
|
editor.setSoftWrap(true)
|
2012-02-11 02:18:02 +04:00
|
|
|
editor.attachToDom()
|
|
|
|
# this verifies the assumption made above in setting the editor's width
|
|
|
|
# charWidth isn't be calculated until it's the editor is on the DOM, but
|
|
|
|
# we need to ensure that the maxLineLength is recalculated when we attach.
|
|
|
|
expect(editor.charWidth).toBe 9
|
2012-02-08 01:43:33 +04:00
|
|
|
|
2012-02-10 22:39:31 +04:00
|
|
|
it "wraps lines that are too long to fit within the editor's width, adjusting cursor positioning accordingly", ->
|
2012-02-10 21:50:01 +04:00
|
|
|
expect(editor.lines.find('.line').length).toBe 16
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(3)').text()).toBe " var pivot = items.shift(), current, left = [], "
|
|
|
|
expect(editor.lines.find('.line:eq(4)').text()).toBe "right = [];"
|
2012-02-08 05:07:12 +04:00
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.cursor.setBufferPosition([3, 51])
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.cursor.position()).toEqual(editor.lines.find('.line:eq(4)').position())
|
2012-02-08 05:07:12 +04:00
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.cursor.setBufferPosition([4, 0])
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.cursor.position()).toEqual(editor.lines.find('.line:eq(5)').position())
|
2012-02-08 01:43:33 +04:00
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.selection.setBufferRange(new Range([6, 30], [6, 55]))
|
2012-02-10 22:32:46 +04:00
|
|
|
[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)
|
|
|
|
|
2012-02-10 22:15:57 +04:00
|
|
|
# Many more tests for change events in the LineWrapper spec
|
|
|
|
it "handles changes to wrapped lines correctly", ->
|
|
|
|
buffer.insert([6, 28], '1234567')
|
|
|
|
expect(editor.lines.find('.line:eq(7)').text()).toBe ' current < pivot ? left1234567.push(current) '
|
|
|
|
expect(editor.lines.find('.line:eq(8)').text()).toBe ': right.push(current);'
|
|
|
|
expect(editor.lines.find('.line:eq(9)').text()).toBe ' }'
|
|
|
|
|
2012-02-11 00:14:17 +04:00
|
|
|
it "changes the max line length when the window size changes", ->
|
|
|
|
editor.width(editor.charWidth * 40)
|
|
|
|
$(window).trigger 'resize'
|
|
|
|
expect(editor.lines.find('.line').length).toBe 19
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(4)').text()).toBe "left = [], right = [];"
|
|
|
|
expect(editor.lines.find('.line:eq(5)').text()).toBe " while(items.length > 0) {"
|
2012-02-11 00:14:17 +04:00
|
|
|
|
|
|
|
it "unwraps lines and cancels window resize listener when softwrap is disabled", ->
|
2012-02-10 23:52:12 +04:00
|
|
|
editor.toggleSoftWrap()
|
|
|
|
expect(editor.lines.find('.line:eq(3)').text()).toBe ' var pivot = items.shift(), current, left = [], right = [];'
|
2012-02-10 22:15:57 +04:00
|
|
|
|
2012-02-11 00:14:17 +04:00
|
|
|
spyOn(editor, 'setMaxLineLength')
|
|
|
|
$(window).trigger 'resize'
|
|
|
|
expect(editor.setMaxLineLength).not.toHaveBeenCalled()
|
|
|
|
|
2012-02-28 00:07:59 +04:00
|
|
|
it "allows the cursor to move down to the last line", ->
|
|
|
|
_.times editor.lastScreenRow(), -> editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [editor.lastScreenRow(), 0]
|
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [editor.lastScreenRow(), 2]
|
|
|
|
|
2012-02-28 03:56:02 +04:00
|
|
|
it "allows the cursor to move up to a shorter soft wrapped line", ->
|
|
|
|
editor.setCursorScreenPosition([11, 15])
|
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [10, 10]
|
|
|
|
editor.moveCursorUp()
|
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [8, 15]
|
|
|
|
|
|
|
|
it "it allows the cursor to wrap when moving horizontally past the beginning / end of a wrapped line", ->
|
|
|
|
editor.setCursorScreenPosition([11, 0])
|
|
|
|
editor.moveCursorLeft()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [10, 10]
|
|
|
|
|
|
|
|
editor.moveCursorRight()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [11, 0]
|
|
|
|
|
2012-01-18 06:13:50 +04:00
|
|
|
describe "cursor movement", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
describe ".setCursorScreenPosition({row, column})", ->
|
2012-01-31 22:21:08 +04:00
|
|
|
beforeEach ->
|
2012-01-25 02:21:43 +04:00
|
|
|
editor.attachToDom()
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 2, column: 2)
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-31 22:21:08 +04:00
|
|
|
it "moves the cursor to cover the character at the given row and column", ->
|
2012-01-27 01:23:59 +04:00
|
|
|
expect(editor.getCursor().position().top).toBe(2 * editor.lineHeight)
|
|
|
|
expect(editor.getCursor().position().left).toBe(2 * editor.charWidth)
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-31 22:21:08 +04:00
|
|
|
it "moves the hidden input element to the position of the cursor to prevent scrolling misbehavior", ->
|
|
|
|
expect(editor.hiddenInput.position().top).toBe(2 * editor.lineHeight)
|
|
|
|
expect(editor.hiddenInput.position().left).toBe(2 * editor.charWidth)
|
|
|
|
|
2012-01-25 02:21:43 +04:00
|
|
|
describe "when the arrow keys are pressed", ->
|
2012-01-26 00:20:58 +04:00
|
|
|
it "moves the cursor by a single row/column", ->
|
2012-01-25 02:21:43 +04:00
|
|
|
editor.trigger keydownEvent('right')
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 1)
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-25 02:21:43 +04:00
|
|
|
editor.trigger keydownEvent('down')
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 1, column: 1)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
|
|
|
editor.trigger keydownEvent('left')
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 1, column: 0)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
|
|
|
editor.trigger keydownEvent('up')
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-24 02:56:30 +04:00
|
|
|
describe "vertical movement", ->
|
2012-01-25 02:21:43 +04:00
|
|
|
describe "auto-scrolling", ->
|
2012-01-24 05:15:11 +04:00
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.focus()
|
2012-01-28 06:42:20 +04:00
|
|
|
editor.vScrollMargin = 3
|
2012-01-24 04:45:00 +04:00
|
|
|
|
2012-01-24 05:15:11 +04:00
|
|
|
it "scrolls the buffer with the specified scroll margin when cursor approaches the end of the screen", ->
|
|
|
|
editor.height(editor.lineHeight * 10)
|
2012-01-24 04:45:00 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
_.times 6, -> editor.moveCursorDown()
|
2012-01-24 05:15:11 +04:00
|
|
|
expect(editor.scrollTop()).toBe(0)
|
2012-01-24 04:45:00 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-01-24 05:15:11 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight)
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-01-24 05:15:11 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight * 2)
|
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
_.times 3, -> editor.moveCursorUp()
|
2012-01-24 05:15:11 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight * 2)
|
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorUp()
|
2012-01-24 05:15:11 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight)
|
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorUp()
|
2012-01-24 05:15:11 +04:00
|
|
|
expect(editor.scrollTop()).toBe(0)
|
2012-01-24 04:45:00 +04:00
|
|
|
|
2012-01-25 02:21:43 +04:00
|
|
|
it "reduces scroll margins when there isn't enough height to maintain them and scroll smoothly", ->
|
2012-01-24 05:15:11 +04:00
|
|
|
editor.height(editor.lineHeight * 5)
|
2012-01-24 04:45:00 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
_.times 3, -> editor.moveCursorDown()
|
2012-01-24 05:15:11 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight)
|
2012-01-24 04:45:00 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorUp()
|
2012-01-24 05:15:11 +04:00
|
|
|
expect(editor.scrollTop()).toBe(0)
|
2012-01-24 04:45:00 +04:00
|
|
|
|
2012-01-26 00:20:58 +04:00
|
|
|
describe "goal column retention", ->
|
2012-01-24 02:56:30 +04:00
|
|
|
lineLengths = null
|
2012-01-24 01:58:26 +04:00
|
|
|
|
2012-01-24 02:56:30 +04:00
|
|
|
beforeEach ->
|
|
|
|
lineLengths = buffer.getLines().map (line) -> line.length
|
|
|
|
expect(lineLengths[3]).toBeGreaterThan(lineLengths[4])
|
|
|
|
expect(lineLengths[5]).toBeGreaterThan(lineLengths[4])
|
|
|
|
expect(lineLengths[6]).toBeGreaterThan(lineLengths[3])
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-01-26 00:20:58 +04:00
|
|
|
it "retains the goal column when moving up", ->
|
2012-01-24 02:56:30 +04:00
|
|
|
expect(lineLengths[6]).toBeGreaterThan(32)
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 6, column: 32)
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorUp()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[5]
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorUp()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[4]
|
2012-01-24 01:40:37 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorUp()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 32
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-01-26 00:20:58 +04:00
|
|
|
it "retains the goal column when moving down", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 3, column: lineLengths[3])
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[4]
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[5]
|
2012-01-24 01:40:37 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[3]
|
2012-01-20 02:39:16 +04:00
|
|
|
|
2012-01-26 00:20:58 +04:00
|
|
|
it "clears the goal column when the cursor is set", ->
|
|
|
|
# set a goal column by moving down
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 3, column: lineLengths[3])
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).not.toBe 6
|
2012-01-24 02:37:03 +04:00
|
|
|
|
2012-01-26 00:20:58 +04:00
|
|
|
# clear the goal column by explicitly setting the cursor position
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.setCursorColumn(6)
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 6
|
2012-01-24 02:56:30 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 6
|
2012-01-24 02:37:03 +04:00
|
|
|
|
2012-01-25 02:21:43 +04:00
|
|
|
describe "when up is pressed on the first line", ->
|
2012-01-26 00:20:58 +04:00
|
|
|
it "moves the cursor to the beginning of the line, but retains the goal column", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 0, column: 4)
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorUp()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-01-20 02:39:16 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 1, column: 4)
|
2012-01-20 03:40:26 +04:00
|
|
|
|
2012-01-25 02:21:43 +04:00
|
|
|
describe "when down is pressed on the last line", ->
|
2012-01-26 00:20:58 +04:00
|
|
|
it "moves the cursor to the end of line, but retains the goal column", ->
|
2012-01-20 03:40:26 +04:00
|
|
|
lastLineIndex = buffer.getLines().length - 1
|
|
|
|
lastLine = buffer.getLine(lastLineIndex)
|
|
|
|
expect(lastLine.length).toBeGreaterThan(0)
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: lastLineIndex, column: 1)
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: lastLineIndex, column: lastLine.length)
|
2012-01-20 03:40:26 +04:00
|
|
|
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorUp()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 1
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-26 00:20:58 +04:00
|
|
|
it "retains a goal column of 0", ->
|
2012-01-25 02:21:43 +04:00
|
|
|
lastLineIndex = buffer.getLines().length - 1
|
|
|
|
lastLine = buffer.getLine(lastLineIndex)
|
|
|
|
expect(lastLine.length).toBeGreaterThan(0)
|
2012-01-17 07:23:27 +04:00
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: lastLineIndex, column: 0)
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorDown()
|
|
|
|
editor.moveCursorUp()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 0
|
2012-01-17 07:23:27 +04:00
|
|
|
|
2012-01-25 02:21:43 +04:00
|
|
|
describe "horizontal movement", ->
|
2012-01-28 06:42:20 +04:00
|
|
|
describe "auto-scrolling", ->
|
|
|
|
charWidth = null
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
|
|
|
{charWidth} = editor
|
|
|
|
editor.hScrollMargin = 5
|
|
|
|
|
|
|
|
it "scrolls horizontally to keep the cursor on screen", ->
|
|
|
|
editor.width(charWidth * 30)
|
|
|
|
|
|
|
|
# moving right
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 24])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe 0
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 25])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe charWidth
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 28])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe charWidth * 4
|
|
|
|
|
|
|
|
# moving left
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 9])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe charWidth * 4
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 8])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe charWidth * 3
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 5])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe 0
|
|
|
|
|
|
|
|
it "reduces scroll margins when there isn't enough width to maintain them and scroll smoothly", ->
|
|
|
|
editor.hScrollMargin = 6
|
|
|
|
editor.width(charWidth * 7)
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 3])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe(0)
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 4])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe(charWidth)
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([2, 3])
|
2012-01-28 06:42:20 +04:00
|
|
|
expect(editor.scrollLeft()).toBe(0)
|
|
|
|
|
2012-01-26 00:20:58 +04:00
|
|
|
describe "when left is pressed on the first column", ->
|
2012-01-25 02:21:43 +04:00
|
|
|
describe "when there is a previous line", ->
|
|
|
|
it "wraps to the end of the previous line", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: 0)
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorLeft()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: buffer.getLine(0).length)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
|
|
|
describe "when the cursor is on the first line", ->
|
|
|
|
it "remains in the same position (0,0)", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 0, column: 0)
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorLeft()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
2012-01-26 00:20:58 +04:00
|
|
|
describe "when right is pressed on the last column", ->
|
2012-01-25 02:21:43 +04:00
|
|
|
describe "when there is a subsequent line", ->
|
|
|
|
it "wraps to the beginning of the next line", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 0, column: buffer.getLine(0).length)
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorRight()
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 1, column: 0)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
|
|
|
describe "when the cursor is on the last line", ->
|
|
|
|
it "remains in the same position", ->
|
|
|
|
lastLineIndex = buffer.getLines().length - 1
|
|
|
|
lastLine = buffer.getLine(lastLineIndex)
|
|
|
|
expect(lastLine.length).toBeGreaterThan(0)
|
|
|
|
|
2012-01-26 22:16:43 +04:00
|
|
|
lastPosition = { row: lastLineIndex, column: lastLine.length }
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(lastPosition)
|
2012-01-27 01:46:12 +04:00
|
|
|
editor.moveCursorRight()
|
2012-01-25 02:21:43 +04:00
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(lastPosition)
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-29 05:00:59 +04:00
|
|
|
describe "when a mousedown event occurs in the editor", ->
|
2012-02-03 02:57:05 +04:00
|
|
|
beforeEach ->
|
2012-01-29 03:54:01 +04:00
|
|
|
editor.attachToDom()
|
2012-02-03 02:57:05 +04:00
|
|
|
editor.css(position: 'absolute', top: 10, left: 10)
|
2012-01-29 03:54:01 +04:00
|
|
|
|
2012-02-10 23:35:38 +04:00
|
|
|
describe "when soft-wrap is enabled", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.width(editor.charWidth * 50)
|
|
|
|
editor.setSoftWrap(true)
|
2012-01-29 03:54:01 +04:00
|
|
|
|
2012-02-10 23:35:38 +04:00
|
|
|
describe "when it is a single click", ->
|
|
|
|
it "re-positions the cursor from the clicked screen position to the corresponding buffer position", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-02-03 02:57:05 +04:00
|
|
|
|
2012-02-10 23:35:38 +04:00
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [4, 7])
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY})
|
2012-02-25 08:05:12 +04:00
|
|
|
expect(editor.getCursorBufferPosition()).toEqual(row: 3, column: 58)
|
2012-02-03 02:57:05 +04:00
|
|
|
|
2012-02-10 23:35:38 +04:00
|
|
|
describe "when soft-wrap is disabled", ->
|
|
|
|
describe "when it is a single click", ->
|
|
|
|
it "re-positions the cursor to the clicked row / column", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-02-10 23:35:38 +04:00
|
|
|
|
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [3, 10])
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY})
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 3, column: 10)
|
2012-02-10 23:35:38 +04:00
|
|
|
|
|
|
|
describe "when it is a double click", ->
|
|
|
|
it "selects the word under the cursor", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-02-10 23:35:38 +04:00
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [0, 8])
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 1}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 2}})
|
|
|
|
expect(editor.getSelectedText()).toBe "quicksort"
|
|
|
|
|
|
|
|
describe "when it is clicked more then twice (tripple, quadruple, etc...)", ->
|
|
|
|
it "selects the line under the cursor", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-02-04 01:11:42 +04:00
|
|
|
|
2012-02-10 23:35:38 +04:00
|
|
|
# Triple click
|
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [1, 8])
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 1}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 2}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 3}})
|
|
|
|
expect(editor.getSelectedText()).toBe " var sort = function(items) {"
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
|
|
|
|
# Quad click
|
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [2, 3])
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 1}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 2}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 3}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 4}})
|
|
|
|
expect(editor.getSelectedText()).toBe " if (items.length <= 1) return items;"
|
|
|
|
$(document).trigger 'mouseup'
|
2012-02-04 01:11:42 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
describe "selection", ->
|
2012-01-27 03:45:49 +04:00
|
|
|
selection = null
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-27 03:45:49 +04:00
|
|
|
beforeEach ->
|
|
|
|
selection = editor.selection
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-27 03:45:49 +04:00
|
|
|
describe "when the arrow keys are pressed with the shift modifier", ->
|
|
|
|
it "expands the selection up to the cursor's new location", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: 6)
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-01-27 03:45:49 +04:00
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
editor.trigger keydownEvent('right', shiftKey: true)
|
|
|
|
|
|
|
|
expect(selection.isEmpty()).toBeFalsy()
|
2012-02-25 08:05:12 +04:00
|
|
|
range = selection.getScreenRange()
|
2012-01-27 03:45:49 +04:00
|
|
|
expect(range.start).toEqual(row: 1, column: 6)
|
|
|
|
expect(range.end).toEqual(row: 1, column: 7)
|
|
|
|
|
|
|
|
editor.trigger keydownEvent('right', shiftKey: true)
|
2012-02-25 08:05:12 +04:00
|
|
|
range = selection.getScreenRange()
|
2012-01-27 03:45:49 +04:00
|
|
|
expect(range.start).toEqual(row: 1, column: 6)
|
|
|
|
expect(range.end).toEqual(row: 1, column: 8)
|
2012-01-25 05:26:38 +04:00
|
|
|
|
2012-01-28 00:42:33 +04:00
|
|
|
editor.trigger keydownEvent('down', shiftKey: true)
|
2012-02-25 08:05:12 +04:00
|
|
|
range = selection.getScreenRange()
|
2012-01-28 00:42:33 +04:00
|
|
|
expect(range.start).toEqual(row: 1, column: 6)
|
|
|
|
expect(range.end).toEqual(row: 2, column: 8)
|
|
|
|
|
|
|
|
editor.trigger keydownEvent('left', shiftKey: true)
|
2012-02-25 08:05:12 +04:00
|
|
|
range = selection.getScreenRange()
|
2012-01-28 00:42:33 +04:00
|
|
|
expect(range.start).toEqual(row: 1, column: 6)
|
|
|
|
expect(range.end).toEqual(row: 2, column: 7)
|
|
|
|
|
|
|
|
editor.trigger keydownEvent('up', shiftKey: true)
|
2012-02-25 08:05:12 +04:00
|
|
|
range = selection.getScreenRange()
|
2012-01-28 00:42:33 +04:00
|
|
|
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 = ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange(new Range({row: 1, column: 2}, {row: 1, column: 5}))
|
2012-01-28 00:42:33 +04:00
|
|
|
expect(selection.isEmpty()).toBeFalsy()
|
|
|
|
|
|
|
|
it "clears the selection", ->
|
|
|
|
makeNonEmpty()
|
|
|
|
editor.trigger keydownEvent('right')
|
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
makeNonEmpty()
|
|
|
|
editor.trigger keydownEvent('left')
|
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
makeNonEmpty()
|
|
|
|
editor.trigger keydownEvent('up')
|
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
makeNonEmpty()
|
|
|
|
editor.trigger keydownEvent('down')
|
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
2012-01-29 05:00:59 +04:00
|
|
|
describe "when the mouse is dragged across the text", ->
|
|
|
|
it "creates a selection from the initial click to mouse cursor's location ", ->
|
|
|
|
editor.attachToDom()
|
2012-02-03 02:57:05 +04:00
|
|
|
editor.css(position: 'absolute', top: 10, left: 10)
|
2012-01-29 05:00:59 +04:00
|
|
|
|
|
|
|
# start
|
2012-02-02 23:14:50 +04:00
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [4, 10])
|
2012-01-29 05:00:59 +04:00
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY})
|
|
|
|
|
|
|
|
# moving changes selection
|
2012-02-02 23:14:50 +04:00
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [5, 27])
|
2012-01-29 05:00:59 +04:00
|
|
|
editor.lines.trigger mousemoveEvent({pageX, pageY})
|
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
range = editor.selection.getScreenRange()
|
2012-01-29 05:00:59 +04:00
|
|
|
expect(range.start).toEqual({row: 4, column: 10})
|
|
|
|
expect(range.end).toEqual({row: 5, column: 27})
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
|
2012-01-29 05:00:59 +04:00
|
|
|
|
|
|
|
# mouse up may occur outside of editor, but still need to halt selection
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
|
|
|
|
# moving after mouse up should not change selection
|
2012-02-03 21:55:04 +04:00
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [8, 8])
|
|
|
|
editor.lines.trigger mousemoveEvent({pageX, pageY})
|
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
range = editor.selection.getScreenRange()
|
2012-02-03 21:55:04 +04:00
|
|
|
expect(range.start).toEqual({row: 4, column: 10})
|
|
|
|
expect(range.end).toEqual({row: 5, column: 27})
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
|
2012-02-03 21:55:04 +04:00
|
|
|
|
2012-02-04 01:33:22 +04:00
|
|
|
it "creates a selection from word underneath double click to mouse cursor's location ", ->
|
2012-02-03 21:55:04 +04:00
|
|
|
editor.attachToDom()
|
|
|
|
editor.css(position: 'absolute', top: 10, left: 10)
|
|
|
|
|
|
|
|
# double click
|
2012-02-04 01:33:22 +04:00
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [4, 7])
|
2012-02-03 21:55:04 +04:00
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 1}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 2}})
|
|
|
|
|
|
|
|
# moving changes selection
|
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [5, 27])
|
|
|
|
editor.lines.trigger mousemoveEvent({pageX, pageY})
|
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
range = editor.selection.getScreenRange()
|
2012-02-04 01:33:22 +04:00
|
|
|
expect(range.start).toEqual({row: 4, column: 4})
|
2012-02-03 21:55:04 +04:00
|
|
|
expect(range.end).toEqual({row: 5, column: 27})
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
|
2012-02-03 21:55:04 +04:00
|
|
|
|
|
|
|
# mouse up may occur outside of editor, but still need to halt selection
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
|
|
|
|
# moving after mouse up should not change selection
|
2012-02-02 23:14:50 +04:00
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [8, 8])
|
2012-01-29 05:00:59 +04:00
|
|
|
editor.lines.trigger mousemoveEvent({pageX, pageY})
|
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
range = editor.selection.getScreenRange()
|
2012-02-04 01:33:22 +04:00
|
|
|
expect(range.start).toEqual({row: 4, column: 4})
|
|
|
|
expect(range.end).toEqual({row: 5, column: 27})
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
|
2012-02-04 01:33:22 +04:00
|
|
|
|
|
|
|
|
|
|
|
it "creates a selection from line underneath triple click to mouse cursor's location ", ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.css(position: 'absolute', top: 10, left: 10)
|
|
|
|
|
|
|
|
# double click
|
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [4, 7])
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 1}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 2}})
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
editor.lines.trigger mousedownEvent({pageX, pageY, originalEvent: {detail: 3}})
|
|
|
|
|
|
|
|
# moving changes selection
|
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [5, 27])
|
|
|
|
editor.lines.trigger mousemoveEvent({pageX, pageY})
|
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
range = editor.selection.getScreenRange()
|
2012-02-04 01:33:22 +04:00
|
|
|
expect(range.start).toEqual({row: 4, column: 0})
|
|
|
|
expect(range.end).toEqual({row: 5, column: 27})
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
|
2012-02-04 01:33:22 +04:00
|
|
|
|
|
|
|
# mouse up may occur outside of editor, but still need to halt selection
|
|
|
|
$(document).trigger 'mouseup'
|
|
|
|
|
|
|
|
# moving after mouse up should not change selection
|
|
|
|
[pageX, pageY] = window.pixelPositionForPoint(editor, [8, 8])
|
|
|
|
editor.lines.trigger mousemoveEvent({pageX, pageY})
|
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
range = editor.selection.getScreenRange()
|
2012-02-04 01:33:22 +04:00
|
|
|
expect(range.start).toEqual({row: 4, column: 0})
|
2012-01-29 05:00:59 +04:00
|
|
|
expect(range.end).toEqual({row: 5, column: 27})
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 5, column: 27)
|
2012-01-29 05:00:59 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
describe "buffer manipulation", ->
|
|
|
|
describe "when text input events are triggered on the hidden input element", ->
|
|
|
|
describe "when there is no selection", ->
|
|
|
|
it "inserts the typed character at the cursor position, both in the buffer and the pre element", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: 6)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
expect(editor.getCurrentLine().charAt(6)).not.toBe 'q'
|
|
|
|
|
|
|
|
editor.hiddenInput.textInput 'q'
|
|
|
|
|
|
|
|
expect(editor.getCurrentLine().charAt(6)).toBe 'q'
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 1, column: 7)
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(1)')).toHaveText editor.getCurrentLine()
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when there is a selection", ->
|
|
|
|
it "replaces the selected text with the typed text", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.selection.setBufferRange(new Range([1, 6], [2, 4]))
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.hiddenInput.textInput 'q'
|
|
|
|
expect(buffer.getLine(1)).toBe ' var qif (items.length <= 1) return items;'
|
|
|
|
|
|
|
|
describe "when return is pressed", ->
|
|
|
|
describe "when the cursor is at the beginning of a line", ->
|
|
|
|
it "inserts an empty line before it", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: 0)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
editor.trigger keydownEvent('enter')
|
|
|
|
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(1)')).toHaveHtml ' '
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 2, column: 0)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when the cursor is in the middle of a line", ->
|
|
|
|
it "splits the current line to form a new line", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: 6)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
2012-02-28 23:27:35 +04:00
|
|
|
originalLine = editor.lines.find('.line:eq(1)').text()
|
|
|
|
lineBelowOriginalLine = editor.lines.find('.line:eq(2)').text()
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('enter')
|
|
|
|
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(1)')).toHaveText originalLine[0...6]
|
|
|
|
expect(editor.lines.find('.line:eq(2)')).toHaveText originalLine[6..]
|
|
|
|
expect(editor.lines.find('.line:eq(3)')).toHaveText lineBelowOriginalLine
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 2, column: 0)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when the cursor is on the end of a line", ->
|
|
|
|
it "inserts an empty line after it", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: buffer.getLine(1).length)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
editor.trigger keydownEvent('enter')
|
|
|
|
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(2)')).toHaveHtml ' '
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 2, column: 0)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when backspace is pressed", ->
|
|
|
|
describe "when the cursor is on the middle of the line", ->
|
|
|
|
it "removes the character before the cursor", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: 7)
|
2012-02-01 06:28:25 +04:00
|
|
|
expect(buffer.getLine(1)).toBe " var sort = function(items) {"
|
|
|
|
|
|
|
|
editor.trigger keydownEvent('backspace')
|
|
|
|
|
|
|
|
line = buffer.getLine(1)
|
|
|
|
expect(line).toBe " var ort = function(items) {"
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(1)')).toHaveText line
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual {row: 1, column: 6}
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when the cursor is at the beginning of a line", ->
|
|
|
|
it "joins it with the line above", ->
|
|
|
|
originalLine0 = buffer.getLine(0)
|
|
|
|
expect(originalLine0).toBe "var quicksort = function () {"
|
|
|
|
expect(buffer.getLine(1)).toBe " var sort = function(items) {"
|
|
|
|
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: 0)
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('backspace')
|
|
|
|
|
|
|
|
line0 = buffer.getLine(0)
|
|
|
|
line1 = buffer.getLine(1)
|
|
|
|
expect(line0).toBe "var quicksort = function () { var sort = function(items) {"
|
|
|
|
expect(line1).toBe " if (items.length <= 1) return items;"
|
|
|
|
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(0)')).toHaveText line0
|
|
|
|
expect(editor.lines.find('.line:eq(1)')).toHaveText line1
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual {row: 0, column: originalLine0.length}
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when the cursor is at the first column of the first line", ->
|
|
|
|
it "does nothing, but doesn't raise an error", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 0, column: 0)
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('backspace')
|
|
|
|
|
|
|
|
describe "when there is a selection", ->
|
|
|
|
it "deletes the selection, but not the character before it", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.selection.setBufferRange(new Range([0,5], [0,9]))
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('backspace')
|
|
|
|
expect(editor.buffer.getLine(0)).toBe 'var qsort = function () {'
|
|
|
|
|
|
|
|
describe "when delete is pressed", ->
|
|
|
|
describe "when the cursor is on the middle of a line", ->
|
|
|
|
it "deletes the character following the cursor", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([1, 6])
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('delete')
|
|
|
|
expect(buffer.getLine(1)).toBe ' var ort = function(items) {'
|
|
|
|
|
|
|
|
describe "when the cursor is on the end of a line", ->
|
|
|
|
it "joins the line with the following line", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([1, buffer.getLine(1).length])
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('delete')
|
|
|
|
expect(buffer.getLine(1)).toBe ' var sort = function(items) { if (items.length <= 1) return items;'
|
|
|
|
|
|
|
|
describe "when there is a selection", ->
|
|
|
|
it "deletes the selection, but not the character following it", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.selection.setBufferRange(new Range([1,6], [1,8]))
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent 'delete'
|
|
|
|
expect(buffer.getLine(1)).toBe ' var rt = function(items) {'
|
|
|
|
|
|
|
|
describe "when the cursor is on the last column of the last line", ->
|
|
|
|
it "does nothing, but doesn't raise an error", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition([12, buffer.getLine(12).length])
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('delete')
|
|
|
|
expect(buffer.getLine(12)).toBe '};'
|
|
|
|
|
2012-02-07 23:10:14 +04:00
|
|
|
describe "when undo/redo events are triggered on the editor", ->
|
|
|
|
it "undoes/redoes the last change", ->
|
2012-02-07 22:22:19 +04:00
|
|
|
buffer.insert [0, 0], "foo"
|
|
|
|
editor.trigger 'undo'
|
|
|
|
expect(buffer.getLine(0)).not.toContain "foo"
|
|
|
|
|
2012-02-07 23:10:14 +04:00
|
|
|
editor.trigger 'redo'
|
|
|
|
expect(buffer.getLine(0)).toContain "foo"
|
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
describe "when multiple lines are removed from the buffer (regression)", ->
|
|
|
|
it "removes all of them from the dom", ->
|
|
|
|
buffer.change(new Range([6, 24], [12, 0]), '')
|
|
|
|
expect(editor.find('.line').length).toBe 7
|
|
|
|
expect(editor.find('.line:eq(6)').text()).toBe(buffer.getLine(6))
|
2012-01-25 03:27:05 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
describe "when the editor is attached to the dom", ->
|
|
|
|
it "calculates line height and char width and updates the pixel position of the cursor", ->
|
|
|
|
expect(editor.lineHeight).toBeNull()
|
|
|
|
expect(editor.charWidth).toBeNull()
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition(row: 2, column: 2)
|
2012-01-25 03:27:05 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.attachToDom()
|
2012-01-26 01:36:32 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
expect(editor.lineHeight).not.toBeNull()
|
|
|
|
expect(editor.charWidth).not.toBeNull()
|
|
|
|
expect(editor.getCursor().position().top).toBe(2 * editor.lineHeight)
|
|
|
|
expect(editor.getCursor().position().left).toBe(2 * editor.charWidth)
|
2012-01-26 01:36:32 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
it "is focused", ->
|
|
|
|
editor.attachToDom()
|
|
|
|
expect(editor).toMatchSelector ":has(:focus)"
|
2012-01-26 01:36:32 +04:00
|
|
|
|
2012-02-10 23:35:38 +04:00
|
|
|
describe "when the editor recieves focused", ->
|
2012-02-01 06:28:25 +04:00
|
|
|
it "focuses the hidden input", ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.focus()
|
|
|
|
expect(editor).not.toMatchSelector ':focus'
|
|
|
|
expect(editor.hiddenInput).toMatchSelector ':focus'
|
2012-01-26 01:36:32 +04:00
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
describe ".setBuffer(buffer)", ->
|
|
|
|
it "sets the cursor to the beginning of the file", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-01-29 09:05:35 +04:00
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
describe ".clipScreenPosition(point)", ->
|
2012-01-29 05:00:59 +04:00
|
|
|
it "selects the nearest valid position to the given point", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
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)
|
2012-01-29 05:00:59 +04:00
|
|
|
|
2012-02-02 05:46:22 +04:00
|
|
|
describe "cut, copy & paste", ->
|
2012-02-02 21:35:18 +04:00
|
|
|
beforeEach ->
|
|
|
|
atom.native.writeToPasteboard('first')
|
|
|
|
expect(atom.native.readFromPasteboard()).toBe 'first'
|
|
|
|
|
|
|
|
describe "when a cut event is triggered", ->
|
|
|
|
it "removes the selected text from the buffer and places it on the pasteboard", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.getSelection().setBufferRange new Range([0,4], [0,9])
|
2012-02-02 21:35:18 +04:00
|
|
|
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", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.getSelection().setBufferRange new Range([0,4], [0, 13])
|
2012-02-02 21:35:18 +04:00
|
|
|
editor.trigger "copy"
|
|
|
|
expect(atom.native.readFromPasteboard()).toBe 'quicksort'
|
2012-02-02 05:46:22 +04:00
|
|
|
|
2012-02-02 21:35:18 +04:00
|
|
|
describe "when a paste event is triggered", ->
|
2012-02-02 06:00:47 +04:00
|
|
|
it "pastes text into the buffer", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition [0, 4]
|
2012-02-02 06:00:47 +04:00
|
|
|
editor.trigger "paste"
|
|
|
|
expect(editor.buffer.getLine(0)).toBe "var firstquicksort = function () {"
|
|
|
|
|
2012-02-02 21:35:18 +04:00
|
|
|
expect(editor.buffer.getLine(1)).toBe " var sort = function(items) {"
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.getSelection().setBufferRange new Range([1,6], [1,10])
|
2012-02-02 06:00:47 +04:00
|
|
|
editor.trigger "paste"
|
2012-02-02 06:12:49 +04:00
|
|
|
expect(editor.buffer.getLine(1)).toBe " var first = function(items) {"
|
2012-01-29 05:00:59 +04:00
|
|
|
|
2012-02-24 22:30:32 +04:00
|
|
|
describe "folding", ->
|
|
|
|
describe "when a fold-selection event is triggered", ->
|
2012-02-29 06:46:41 +04:00
|
|
|
it "folds the selected text and moves the cursor to just after the placeholder, then treats the placeholder as a single character", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
editor.selection.setBufferRange(new Range([4, 29], [7, 4]))
|
2012-02-24 22:30:32 +04:00
|
|
|
editor.trigger 'fold-selection'
|
2012-02-29 06:46:41 +04:00
|
|
|
|
2012-02-28 23:27:35 +04:00
|
|
|
expect(editor.lines.find('.line:eq(4)').find('.fold-placeholder')).toExist()
|
2012-02-29 06:46:41 +04:00
|
|
|
expect(editor.lines.find('.line:eq(5)').text()).toBe ' return sort(left).concat(pivot).concat(sort(right));'
|
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
expect(editor.selection.isEmpty()).toBeTruthy()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [4, 32]
|
2012-02-24 22:30:32 +04:00
|
|
|
|
2012-02-25 08:56:18 +04:00
|
|
|
editor.setCursorScreenPosition([9, 2])
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [9, 2]
|
2012-02-25 09:08:34 +04:00
|
|
|
|
|
|
|
buffer.insert([9, 4], 'x')
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [6, 5]
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [9, 5]
|
|
|
|
|
2012-02-27 22:22:20 +04:00
|
|
|
editor.setCursorScreenPosition([4, 30])
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [4, 29]
|
|
|
|
editor.moveCursorRight()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [4, 32]
|
|
|
|
|
2012-02-29 06:46:41 +04:00
|
|
|
describe "when a fold placeholder is clicked", ->
|
2012-02-29 06:53:02 +04:00
|
|
|
it "removes the associated fold and places the cursor at its beginning", ->
|
2012-02-29 06:46:41 +04:00
|
|
|
editor.selection.setBufferRange(new Range([4, 29], [7, 4]))
|
|
|
|
editor.trigger 'fold-selection'
|
|
|
|
|
|
|
|
editor.find('.fold-placeholder .ellipsis').mousedown()
|
|
|
|
|
|
|
|
expect(editor.find('.fold-placeholder')).not.toExist()
|
|
|
|
expect(editor.lines.find('.line:eq(5)').text()).toBe ' current = items.shift();'
|
|
|
|
|
2012-02-29 06:53:02 +04:00
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [4, 29]
|
|
|
|
|
2012-02-25 09:08:34 +04:00
|
|
|
|