2012-05-09 06:20:33 +04:00
|
|
|
RootView = require 'root-view'
|
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'
|
2012-04-19 02:57:58 +04:00
|
|
|
Project = require 'project'
|
2011-12-16 02:13:34 +04:00
|
|
|
$ = require 'jquery'
|
2012-03-13 00:21:00 +04:00
|
|
|
{$$} = require 'space-pen'
|
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-06-05 20:47:45 +04:00
|
|
|
describe "Editor", ->
|
2012-05-10 19:27:04 +04:00
|
|
|
[rootView, buffer, editor, cachedLineHeight] = []
|
|
|
|
|
|
|
|
getLineHeight = ->
|
2012-05-16 23:47:59 +04:00
|
|
|
return cachedLineHeight if cachedLineHeight?
|
2012-05-10 19:27:04 +04:00
|
|
|
editorForMeasurement = new Editor()
|
|
|
|
editorForMeasurement.attachToDom()
|
|
|
|
cachedLineHeight = editorForMeasurement.lineHeight
|
|
|
|
editorForMeasurement.remove()
|
|
|
|
cachedLineHeight
|
2011-12-16 02:13:34 +04:00
|
|
|
|
|
|
|
beforeEach ->
|
2012-05-16 21:35:50 +04:00
|
|
|
rootView = new RootView(require.resolve('fixtures/sample.js'))
|
2012-05-09 06:20:33 +04:00
|
|
|
project = rootView.project
|
|
|
|
editor = rootView.activeEditor()
|
|
|
|
buffer = editor.buffer
|
2012-04-19 02:57:58 +04:00
|
|
|
|
2012-05-10 21:40:16 +04:00
|
|
|
editor.attachToDom = ({ heightInLines } = {}) ->
|
2012-06-01 22:25:58 +04:00
|
|
|
heightInLines ?= this.buffer.getLineCount()
|
2012-05-10 19:27:04 +04:00
|
|
|
this.height(getLineHeight() * heightInLines)
|
|
|
|
$('#jasmine-content').append(this)
|
|
|
|
|
2012-05-27 00:05:25 +04:00
|
|
|
editor.lineOverdraw = 2
|
2012-03-07 04:34:59 +04:00
|
|
|
editor.autoIndent = false
|
2012-01-18 06:13:50 +04:00
|
|
|
editor.enableKeymap()
|
2012-03-19 19:04:39 +04:00
|
|
|
editor.isFocused = true
|
2011-12-16 02:13:34 +04:00
|
|
|
|
2012-03-23 20:50:41 +04:00
|
|
|
describe "construction", ->
|
|
|
|
it "assigns an empty buffer and correctly handles text input (regression coverage)", ->
|
|
|
|
editor = new Editor
|
2012-05-10 05:19:54 +04:00
|
|
|
editor.attachToDom()
|
2012-03-30 22:26:34 +04:00
|
|
|
expect(editor.buffer.getPath()).toBeUndefined()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 1
|
2012-03-23 20:50:41 +04:00
|
|
|
editor.insertText('x')
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 1
|
2012-03-23 20:50:41 +04:00
|
|
|
|
2012-04-13 21:39:16 +04:00
|
|
|
describe ".copy()", ->
|
|
|
|
it "builds a new editor with the same edit sessions, cursor position, and scroll position as the receiver", ->
|
2012-05-12 03:51:47 +04:00
|
|
|
rootView.attachToDom()
|
|
|
|
rootView.height(8 * editor.lineHeight)
|
|
|
|
rootView.width(50 * editor.charWidth)
|
|
|
|
|
|
|
|
editor.setCursorScreenPosition([5, 20])
|
|
|
|
advanceClock()
|
2012-05-16 23:47:59 +04:00
|
|
|
editor.scrollTop(1.5 * editor.lineHeight)
|
2012-05-12 03:51:47 +04:00
|
|
|
editor.scrollView.scrollLeft(44)
|
2012-04-13 21:39:16 +04:00
|
|
|
|
|
|
|
# prove this test covers serialization and deserialization
|
|
|
|
spyOn(editor, 'serialize').andCallThrough()
|
|
|
|
spyOn(Editor, 'deserialize').andCallThrough()
|
|
|
|
|
|
|
|
newEditor = editor.copy()
|
|
|
|
expect(editor.serialize).toHaveBeenCalled()
|
|
|
|
expect(Editor.deserialize).toHaveBeenCalled()
|
2012-05-12 03:51:47 +04:00
|
|
|
|
2012-04-13 21:39:16 +04:00
|
|
|
expect(newEditor.buffer).toBe editor.buffer
|
|
|
|
expect(newEditor.getCursorScreenPosition()).toEqual editor.getCursorScreenPosition()
|
2012-04-14 00:29:58 +04:00
|
|
|
expect(newEditor.editSessions[0]).toEqual(editor.editSessions[0])
|
|
|
|
expect(newEditor.editSessions[0]).not.toBe(editor.editSessions[0])
|
|
|
|
|
2012-05-12 03:51:47 +04:00
|
|
|
newEditor.height(editor.height())
|
|
|
|
newEditor.width(editor.width())
|
|
|
|
rootView.remove()
|
|
|
|
newEditor.attachToDom()
|
2012-06-05 07:57:10 +04:00
|
|
|
expect(newEditor.scrollTop()).toBe editor.scrollTop()
|
2012-05-12 03:51:47 +04:00
|
|
|
expect(newEditor.scrollView.scrollLeft()).toBe 44
|
|
|
|
|
2012-05-10 21:40:16 +04:00
|
|
|
describe ".setBuffer(buffer)", ->
|
2012-05-10 19:58:38 +04:00
|
|
|
it "sets the cursor to the beginning of the file", ->
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
|
|
|
|
|
|
|
it "recalls the cursor position and scroll position when the same buffer is re-assigned", ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.height(editor.lineHeight * 5)
|
|
|
|
editor.width(editor.charWidth * 30)
|
|
|
|
editor.setCursorScreenPosition([8, 28])
|
|
|
|
advanceClock()
|
|
|
|
|
2012-05-11 23:45:57 +04:00
|
|
|
previousScrollTop = editor.verticalScrollbar.scrollTop()
|
2012-05-11 23:42:57 +04:00
|
|
|
previousScrollLeft = editor.scrollView.scrollLeft()
|
2012-05-10 19:58:38 +04:00
|
|
|
|
|
|
|
editor.setBuffer(new Buffer)
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
2012-05-11 23:45:57 +04:00
|
|
|
expect(editor.verticalScrollbar.scrollTop()).toBe 0
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-05-10 19:58:38 +04:00
|
|
|
|
|
|
|
editor.setBuffer(buffer)
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [8, 28]
|
2012-05-11 23:45:57 +04:00
|
|
|
expect(editor.verticalScrollbar.scrollTop()).toBe previousScrollTop
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe previousScrollLeft
|
2012-05-10 19:58:38 +04:00
|
|
|
|
|
|
|
it "recalls the undo history of the buffer when it is re-assigned", ->
|
|
|
|
editor.insertText('xyz')
|
|
|
|
|
|
|
|
otherBuffer = new Buffer
|
|
|
|
editor.setBuffer(otherBuffer)
|
|
|
|
editor.insertText('abc')
|
|
|
|
expect(otherBuffer.lineForRow(0)).toBe 'abc'
|
|
|
|
editor.undo()
|
|
|
|
expect(otherBuffer.lineForRow(0)).toBe ''
|
|
|
|
|
|
|
|
editor.setBuffer(buffer)
|
|
|
|
editor.undo()
|
|
|
|
expect(buffer.lineForRow(0)).toBe 'var quicksort = function () {'
|
|
|
|
editor.redo()
|
|
|
|
expect(buffer.lineForRow(0)).toBe 'xyzvar quicksort = function () {'
|
|
|
|
|
|
|
|
editor.setBuffer(otherBuffer)
|
|
|
|
editor.redo()
|
|
|
|
expect(otherBuffer.lineForRow(0)).toBe 'abc'
|
|
|
|
|
|
|
|
it "fully unsubscribes from the previously assigned buffer", ->
|
|
|
|
otherBuffer = new Buffer
|
|
|
|
previousSubscriptionCount = otherBuffer.subscriptionCount()
|
|
|
|
|
|
|
|
editor.setBuffer(otherBuffer)
|
|
|
|
expect(otherBuffer.subscriptionCount()).toBeGreaterThan previousSubscriptionCount
|
|
|
|
|
|
|
|
editor.setBuffer(buffer)
|
|
|
|
expect(otherBuffer.subscriptionCount()).toBe previousSubscriptionCount
|
|
|
|
|
2012-05-15 21:02:45 +04:00
|
|
|
it "resizes the vertical scrollbar based on the new buffer's height", ->
|
|
|
|
editor.attachToDom(heightInLines: 5)
|
|
|
|
originalHeight = editor.verticalScrollbar.prop('scrollHeight')
|
|
|
|
expect(originalHeight).toBeGreaterThan 0
|
|
|
|
|
|
|
|
editor.setBuffer(new Buffer(require.resolve('fixtures/sample.txt')))
|
|
|
|
expect(editor.verticalScrollbar.prop('scrollHeight')).toBeLessThan originalHeight
|
|
|
|
|
2012-05-10 19:58:38 +04:00
|
|
|
describe ".clipScreenPosition(point)", ->
|
|
|
|
it "selects the nearest valid position to the given point", ->
|
|
|
|
expect(editor.clipScreenPosition(row: 1000, column: 0)).toEqual(row: buffer.getLastRow(), column: buffer.lineForRow(buffer.getLastRow()).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.lineForRow(1).length)
|
|
|
|
expect(editor.clipScreenPosition(row: 1, column: -5)).toEqual(row: 1, column: 0)
|
|
|
|
|
|
|
|
describe ".save()", ->
|
|
|
|
describe "when the current buffer has a path", ->
|
|
|
|
tempFilePath = null
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
tempFilePath = '/tmp/atom-temp.txt'
|
|
|
|
editor.setBuffer new Buffer(tempFilePath)
|
|
|
|
expect(editor.buffer.getPath()).toBe tempFilePath
|
|
|
|
|
|
|
|
afterEach ->
|
|
|
|
expect(fs.remove(tempFilePath))
|
|
|
|
|
|
|
|
it "saves the current buffer to disk", ->
|
|
|
|
editor.buffer.setText 'Edited!'
|
|
|
|
expect(fs.exists(tempFilePath)).toBeFalsy()
|
|
|
|
|
|
|
|
editor.save()
|
|
|
|
|
|
|
|
expect(fs.exists(tempFilePath)).toBeTruthy()
|
|
|
|
expect(fs.read(tempFilePath)).toBe 'Edited!'
|
|
|
|
|
|
|
|
describe "when the current buffer has no path", ->
|
|
|
|
selectedFilePath = null
|
|
|
|
beforeEach ->
|
|
|
|
editor.setBuffer new Buffer()
|
|
|
|
expect(editor.buffer.getPath()).toBeUndefined()
|
|
|
|
editor.buffer.setText 'Save me to a new path'
|
|
|
|
spyOn($native, 'saveDialog').andCallFake -> selectedFilePath
|
|
|
|
|
|
|
|
it "presents a 'save as' dialog", ->
|
|
|
|
editor.save()
|
|
|
|
expect($native.saveDialog).toHaveBeenCalled()
|
|
|
|
|
|
|
|
describe "when a path is chosen", ->
|
|
|
|
it "saves the buffer to the chosen path", ->
|
|
|
|
selectedFilePath = '/tmp/temp.txt'
|
|
|
|
|
|
|
|
editor.save()
|
|
|
|
|
|
|
|
expect(fs.exists(selectedFilePath)).toBeTruthy()
|
|
|
|
expect(fs.read(selectedFilePath)).toBe 'Save me to a new path'
|
|
|
|
|
|
|
|
describe "when dialog is cancelled", ->
|
|
|
|
it "does not save the buffer", ->
|
|
|
|
selectedFilePath = null
|
|
|
|
editor.save()
|
|
|
|
expect(fs.exists(selectedFilePath)).toBeFalsy()
|
|
|
|
|
|
|
|
describe ".spliceLineElements(startRow, rowCount, lineElements)", ->
|
|
|
|
elements = null
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
|
|
|
elements = $$ ->
|
|
|
|
@div "A", class: 'line'
|
|
|
|
@div "B", class: 'line'
|
|
|
|
|
|
|
|
describe "when the start row is 0", ->
|
|
|
|
describe "when the row count is 0", ->
|
|
|
|
it "inserts the given elements before the first row", ->
|
|
|
|
editor.spliceLineElements 0, 0, elements
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(0)').text()).toBe 'A'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(1)').text()).toBe 'B'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(2)').text()).toBe 'var quicksort = function () {'
|
2012-05-10 19:58:38 +04:00
|
|
|
|
|
|
|
describe "when the row count is > 0", ->
|
|
|
|
it "replaces the initial rows with the given elements", ->
|
|
|
|
editor.spliceLineElements 0, 2, elements
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(0)').text()).toBe 'A'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(1)').text()).toBe 'B'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(2)').text()).toBe ' if (items.length <= 1) return items;'
|
2012-05-10 19:58:38 +04:00
|
|
|
|
|
|
|
describe "when the start row is less than the last row", ->
|
|
|
|
describe "when the row count is 0", ->
|
|
|
|
it "inserts the elements at the specified location", ->
|
|
|
|
editor.spliceLineElements 2, 0, elements
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(2)').text()).toBe 'A'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(3)').text()).toBe 'B'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(4)').text()).toBe ' if (items.length <= 1) return items;'
|
2012-05-10 19:58:38 +04:00
|
|
|
|
|
|
|
describe "when the row count is > 0", ->
|
|
|
|
it "replaces the elements at the specified location", ->
|
|
|
|
editor.spliceLineElements 2, 2, elements
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(2)').text()).toBe 'A'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(3)').text()).toBe 'B'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(4)').text()).toBe ' while(items.length > 0) {'
|
2012-05-10 19:58:38 +04:00
|
|
|
|
|
|
|
describe "when the start row is the last row", ->
|
|
|
|
it "appends the elements to the end of the lines", ->
|
|
|
|
editor.spliceLineElements 13, 0, elements
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(12)').text()).toBe '};'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(13)').text()).toBe 'A'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(14)').text()).toBe 'B'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(15)')).not.toExist()
|
2012-05-10 19:58:38 +04:00
|
|
|
|
|
|
|
describe ".loadNextEditSession()", ->
|
|
|
|
it "loads the next editor state and wraps to beginning when end is reached", ->
|
|
|
|
buffer0 = new Buffer("0")
|
|
|
|
buffer1 = new Buffer("1")
|
|
|
|
buffer2 = new Buffer("2")
|
|
|
|
editor = new Editor(buffer: buffer0)
|
|
|
|
editor.setBuffer(buffer1)
|
|
|
|
editor.setBuffer(buffer2)
|
|
|
|
|
|
|
|
expect(editor.buffer.path).toBe "2"
|
|
|
|
editor.loadNextEditSession()
|
|
|
|
expect(editor.buffer.path).toBe "0"
|
|
|
|
editor.loadNextEditSession()
|
|
|
|
expect(editor.buffer.path).toBe "1"
|
|
|
|
editor.loadNextEditSession()
|
|
|
|
expect(editor.buffer.path).toBe "2"
|
|
|
|
|
|
|
|
describe ".loadPreviousEditSession()", ->
|
|
|
|
it "loads the next editor state and wraps to beginning when end is reached", ->
|
|
|
|
buffer0 = new Buffer("0")
|
|
|
|
buffer1 = new Buffer("1")
|
|
|
|
buffer2 = new Buffer("2")
|
|
|
|
editor = new Editor {buffer: buffer0}
|
|
|
|
editor.setBuffer(buffer1)
|
|
|
|
editor.setBuffer(buffer2)
|
|
|
|
|
|
|
|
expect(editor.buffer.path).toBe "2"
|
|
|
|
editor.loadPreviousEditSession()
|
|
|
|
expect(editor.buffer.path).toBe "1"
|
|
|
|
editor.loadPreviousEditSession()
|
|
|
|
expect(editor.buffer.path).toBe "0"
|
|
|
|
editor.loadPreviousEditSession()
|
|
|
|
expect(editor.buffer.path).toBe "2"
|
|
|
|
|
2012-05-17 19:49:03 +04:00
|
|
|
describe ".scrollTop(n)", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom(heightInLines: 5)
|
|
|
|
expect(editor.verticalScrollbar.scrollTop()).toBe 0
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.css('-webkit-tranform')).toBeNull()
|
2012-05-17 19:49:03 +04:00
|
|
|
expect(editor.gutter.lineNumbers.css('-webkit-tranform')).toBeNull()
|
|
|
|
|
|
|
|
describe "when called with a scroll top argument", ->
|
2012-06-01 22:03:21 +04:00
|
|
|
it "sets the scrollTop of the vertical scrollbar and sets scrollTop on the line numbers and lines", ->
|
2012-05-17 19:49:03 +04:00
|
|
|
editor.scrollTop(100)
|
|
|
|
expect(editor.verticalScrollbar.scrollTop()).toBe 100
|
2012-06-01 22:03:21 +04:00
|
|
|
expect(editor.scrollView.scrollTop()).toBe 100
|
|
|
|
expect(editor.gutter.scrollTop()).toBe 100
|
2012-05-17 19:49:03 +04:00
|
|
|
|
2012-06-01 22:03:21 +04:00
|
|
|
editor.scrollTop(120)
|
|
|
|
expect(editor.verticalScrollbar.scrollTop()).toBe 120
|
|
|
|
expect(editor.scrollView.scrollTop()).toBe 120
|
|
|
|
expect(editor.gutter.scrollTop()).toBe 120
|
2012-05-17 19:49:03 +04:00
|
|
|
|
|
|
|
it "does not allow negative scrollTops to be assigned", ->
|
|
|
|
editor.scrollTop(-100)
|
|
|
|
expect(editor.scrollTop()).toBe 0
|
|
|
|
|
|
|
|
it "doesn't do anything if the scrollTop hasn't changed", ->
|
|
|
|
editor.scrollTop(100)
|
|
|
|
spyOn(editor.verticalScrollbar, 'scrollTop')
|
2012-06-05 04:53:58 +04:00
|
|
|
spyOn(editor.renderedLines, 'css')
|
2012-05-17 19:49:03 +04:00
|
|
|
spyOn(editor.gutter.lineNumbers, 'css')
|
|
|
|
|
|
|
|
editor.scrollTop(100)
|
|
|
|
expect(editor.verticalScrollbar.scrollTop).not.toHaveBeenCalled()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.css).not.toHaveBeenCalled()
|
2012-05-17 19:49:03 +04:00
|
|
|
expect(editor.gutter.lineNumbers.css).not.toHaveBeenCalled()
|
|
|
|
|
|
|
|
describe "when the 'adjustVerticalScrollbar' option is false (defaults to true)", ->
|
|
|
|
it "doesn't adjust the scrollTop of the vertical scrollbar", ->
|
|
|
|
editor.scrollTop(100, adjustVerticalScrollbar: false)
|
|
|
|
expect(editor.verticalScrollbar.scrollTop()).toBe 0
|
2012-06-01 22:03:21 +04:00
|
|
|
expect(editor.scrollView.scrollTop()).toBe 100
|
|
|
|
expect(editor.gutter.scrollTop()).toBe 100
|
2012-05-17 19:49:03 +04:00
|
|
|
|
|
|
|
describe "when called with no argument", ->
|
|
|
|
it "returns the last assigned value or 0 if none has been assigned", ->
|
|
|
|
expect(editor.scrollTop()).toBe 0
|
|
|
|
editor.scrollTop(50)
|
|
|
|
expect(editor.scrollTop()).toBe 50
|
|
|
|
|
2012-04-20 04:55:41 +04:00
|
|
|
describe "editor-open event", ->
|
2012-04-20 05:12:55 +04:00
|
|
|
it 'only triggers an editor-open event when it is first added to the DOM', ->
|
2012-04-20 04:55:41 +04:00
|
|
|
openHandler = jasmine.createSpy('openHandler')
|
|
|
|
editor.on 'editor-open', openHandler
|
|
|
|
|
|
|
|
editor.simulateDomAttachment()
|
|
|
|
expect(openHandler).toHaveBeenCalled()
|
|
|
|
[event, eventEditor] = openHandler.argsForCall[0]
|
|
|
|
expect(eventEditor).toBe editor
|
|
|
|
|
2012-04-20 05:12:55 +04:00
|
|
|
openHandler.reset()
|
|
|
|
editor.simulateDomAttachment()
|
|
|
|
expect(openHandler).not.toHaveBeenCalled()
|
|
|
|
|
2012-05-29 23:03:29 +04:00
|
|
|
describe "text rendering", ->
|
2012-05-10 19:27:04 +04:00
|
|
|
describe "when all lines in the buffer are visible on screen", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
2012-06-01 22:25:58 +04:00
|
|
|
expect(editor.height()).toBe buffer.getLineCount() * editor.lineHeight
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
it "creates a line element for each line in the buffer with the html-escaped text of the line", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toEqual(buffer.getLineCount())
|
2012-05-10 19:27:04 +04:00
|
|
|
expect(buffer.lineForRow(2)).toContain('<')
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(2)').html()).toContain '<'
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
# renders empty lines with a non breaking space
|
|
|
|
expect(buffer.lineForRow(10)).toBe ''
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(10)').html()).toBe ' '
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
it "syntax highlights code based on the file type", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
line1 = editor.renderedLines.find('.line:first')
|
2012-05-10 19:27:04 +04:00
|
|
|
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 '='
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
line12 = editor.renderedLines.find('.line:eq(11)')
|
2012-05-10 19:27:04 +04:00
|
|
|
expect(line12.find('span:eq(1)')).toMatchSelector '.keyword'
|
|
|
|
|
|
|
|
describe "when lines are updated in the buffer", ->
|
|
|
|
it "syntax highlights the updated lines", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(0) span:eq(0)')).toMatchSelector '.keyword.definition'
|
2012-05-10 19:27:04 +04:00
|
|
|
buffer.insert([0, 4], "g")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(0) span:eq(0)')).toMatchSelector '.keyword.definition'
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
# verify that re-highlighting can occur below the changed line
|
|
|
|
buffer.insert([5,0], "/* */")
|
|
|
|
buffer.insert([1,0], "/*")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(2) span:eq(0)')).toMatchSelector '.comment'
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
describe "when soft-wrap is enabled", ->
|
|
|
|
beforeEach ->
|
2012-05-17 21:34:54 +04:00
|
|
|
setEditorHeightInLines(editor, 20)
|
2012-05-10 19:27:04 +04:00
|
|
|
setEditorWidthInChars(editor, 50)
|
|
|
|
editor.setSoftWrap(true)
|
2012-06-05 22:38:53 +04:00
|
|
|
expect(editor.renderer.softWrapColumn).toBe 50
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
it "wraps lines that are too long to fit within the editor's width, adjusting cursor positioning accordingly", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 16
|
|
|
|
expect(editor.renderedLines.find('.line:eq(3)').text()).toBe " var pivot = items.shift(), current, left = [], "
|
|
|
|
expect(editor.renderedLines.find('.line:eq(4)').text()).toBe "right = [];"
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
editor.setCursorBufferPosition([3, 51])
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.find('.cursor').offset()).toEqual(editor.renderedLines.find('.line:eq(4)').offset())
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
editor.setCursorBufferPosition([4, 0])
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.find('.cursor').offset()).toEqual(editor.renderedLines.find('.line:eq(5)').offset())
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
editor.getSelection().setBufferRange(new Range([6, 30], [6, 55]))
|
|
|
|
[region1, region2] = editor.getSelection().regions
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(region1.offset().top).toBe(editor.renderedLines.find('.line:eq(7)').offset().top)
|
|
|
|
expect(region2.offset().top).toBe(editor.renderedLines.find('.line:eq(8)').offset().top)
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
it "handles changes to wrapped lines correctly", ->
|
|
|
|
buffer.insert([6, 28], '1234567')
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(7)').text()).toBe ' current < pivot ? left1234567.push(current) '
|
|
|
|
expect(editor.renderedLines.find('.line:eq(8)').text()).toBe ': right.push(current);'
|
|
|
|
expect(editor.renderedLines.find('.line:eq(9)').text()).toBe ' }'
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
it "changes the max line length and repositions the cursor when the window size changes", ->
|
|
|
|
editor.setCursorBufferPosition([3, 60])
|
|
|
|
setEditorWidthInChars(editor, 40)
|
|
|
|
$(window).trigger 'resize'
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 19
|
|
|
|
expect(editor.renderedLines.find('.line:eq(4)').text()).toBe "left = [], right = [];"
|
|
|
|
expect(editor.renderedLines.find('.line:eq(5)').text()).toBe " while(items.length > 0) {"
|
2012-05-10 19:27:04 +04:00
|
|
|
expect(editor.bufferPositionForScreenPosition(editor.getCursorScreenPosition())).toEqual [3, 60]
|
|
|
|
|
|
|
|
it "wraps the lines of any newly assigned buffers", ->
|
|
|
|
otherBuffer = new Buffer
|
|
|
|
otherBuffer.setText([1..100].join(''))
|
|
|
|
editor.setBuffer(otherBuffer)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBeGreaterThan(1)
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
it "unwraps lines and cancels window resize listener when softwrap is disabled", ->
|
|
|
|
editor.toggleSoftWrap()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(3)').text()).toBe ' var pivot = items.shift(), current, left = [], right = [];'
|
2012-05-10 19:27:04 +04:00
|
|
|
|
2012-06-05 22:38:53 +04:00
|
|
|
spyOn(editor, 'setSoftWrapColumn')
|
2012-05-10 19:27:04 +04:00
|
|
|
$(window).trigger 'resize'
|
2012-06-05 22:38:53 +04:00
|
|
|
expect(editor.setSoftWrapColumn).not.toHaveBeenCalled()
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
it "allows the cursor to move down to the last line", ->
|
|
|
|
_.times editor.getLastScreenRow(), -> editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [editor.getLastScreenRow(), 0]
|
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [editor.getLastScreenRow(), 2]
|
|
|
|
|
|
|
|
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-06-05 22:38:53 +04:00
|
|
|
it "calls .setSoftWrapColumn() when the editor is attached because now its dimensions are available to calculate it", ->
|
2012-05-10 19:27:04 +04:00
|
|
|
otherEditor = new Editor()
|
2012-06-05 22:38:53 +04:00
|
|
|
spyOn(otherEditor, 'setSoftWrapColumn')
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
otherEditor.setSoftWrap(true)
|
2012-06-05 22:38:53 +04:00
|
|
|
expect(otherEditor.setSoftWrapColumn).not.toHaveBeenCalled()
|
2012-05-10 19:27:04 +04:00
|
|
|
|
|
|
|
otherEditor.simulateDomAttachment()
|
2012-06-05 22:38:53 +04:00
|
|
|
expect(otherEditor.setSoftWrapColumn).toHaveBeenCalled()
|
2012-05-15 02:18:37 +04:00
|
|
|
|
2012-05-31 20:46:00 +04:00
|
|
|
describe "when some lines at the end of the buffer are not visible on screen", ->
|
2012-02-08 01:43:33 +04:00
|
|
|
beforeEach ->
|
2012-05-10 19:27:04 +04:00
|
|
|
editor.attachToDom(heightInLines: 5.5)
|
|
|
|
|
2012-05-27 00:05:25 +04:00
|
|
|
it "only renders the visible lines plus the overdrawn lines, setting the padding-bottom of the lines element to account for the missing lines", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
2012-06-01 22:25:58 +04:00
|
|
|
expectedPaddingBottom = (buffer.getLineCount() - 8) * editor.lineHeight
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.css('padding-bottom')).toBe "#{expectedPaddingBottom}px"
|
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(7)
|
2012-05-11 02:11:05 +04:00
|
|
|
|
2012-05-31 20:46:00 +04:00
|
|
|
it "renders additional lines when the editor is resized", ->
|
|
|
|
setEditorHeightInLines(editor, 10)
|
|
|
|
$(window).trigger 'resize'
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 12
|
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(11)
|
2012-05-31 20:46:00 +04:00
|
|
|
|
|
|
|
it "renders correctly when scrolling after text is added to the buffer", ->
|
|
|
|
editor.insertText("1\n")
|
|
|
|
_.times 4, -> editor.moveCursorDown()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(2)').text()).toBe editor.buffer.lineForRow(2)
|
|
|
|
expect(editor.renderedLines.find('.line:eq(7)').text()).toBe editor.buffer.lineForRow(7)
|
2012-05-31 20:46:00 +04:00
|
|
|
|
|
|
|
it "renders correctly when scrolling after text is removed from buffer", ->
|
|
|
|
editor.buffer.delete([[0,0],[1,0]])
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(0)').text()).toBe editor.buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find('.line:eq(5)').text()).toBe editor.buffer.lineForRow(5)
|
2012-05-31 20:46:00 +04:00
|
|
|
|
|
|
|
editor.scrollTop(3 * editor.lineHeight)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe editor.buffer.lineForRow(1)
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe editor.buffer.lineForRow(10)
|
2012-05-31 20:46:00 +04:00
|
|
|
|
2012-06-01 03:48:50 +04:00
|
|
|
describe "when creating and destroying folds that are longer than the visible lines", ->
|
|
|
|
describe "when the cursor precedes the fold when it is destroyed", ->
|
|
|
|
it "renders lines and line numbers correctly", ->
|
2012-06-05 20:47:45 +04:00
|
|
|
scrollHeightBeforeFold = editor.scrollView.prop('scrollHeight')
|
2012-06-01 03:48:50 +04:00
|
|
|
fold = editor.createFold(1, 9)
|
|
|
|
fold.destroy()
|
2012-06-05 20:47:45 +04:00
|
|
|
expect(editor.scrollView.prop('scrollHeight')).toBe scrollHeightBeforeFold
|
2012-06-01 03:48:50 +04:00
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(7)
|
2012-06-01 03:48:50 +04:00
|
|
|
|
|
|
|
expect(editor.gutter.find('.line-number').length).toBe 8
|
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe '8'
|
|
|
|
|
|
|
|
editor.scrollTop(4 * editor.lineHeight)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 10
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(11)
|
2012-06-01 03:48:50 +04:00
|
|
|
|
|
|
|
describe "when the cursor follows the fold when it is destroyed", ->
|
|
|
|
it "renders lines and line numbers correctly", ->
|
|
|
|
fold = editor.createFold(1, 9)
|
|
|
|
editor.setCursorBufferPosition([10, 0])
|
|
|
|
fold.destroy()
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(12)
|
2012-06-01 03:48:50 +04:00
|
|
|
|
|
|
|
expect(editor.gutter.find('.line-number').length).toBe 8
|
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe '13'
|
|
|
|
|
|
|
|
editor.scrollTop(4 * editor.lineHeight)
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 10
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(11)
|
2012-06-01 03:48:50 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
describe "when scrolling vertically", ->
|
2012-05-31 20:46:00 +04:00
|
|
|
describe "when scrolling less than the editor's height", ->
|
2012-05-27 00:05:25 +04:00
|
|
|
it "draws new lines and removes old lines when the last visible line will exceed the last rendered line", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
2012-05-27 00:52:48 +04:00
|
|
|
|
2012-05-17 03:28:07 +04:00
|
|
|
editor.scrollTop(editor.lineHeight * 1.5)
|
2012-06-05 06:29:40 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(0)
|
2012-06-05 06:29:40 +04:00
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(7)
|
2012-05-11 02:11:05 +04:00
|
|
|
|
2012-06-05 06:29:40 +04:00
|
|
|
editor.scrollTop(editor.lineHeight * 3.5) # first visible row will be 3, last will be 8
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 10
|
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(1)
|
|
|
|
expect(editor.renderedLines.find('.line:last').html()).toBe ' ' # line 10 is blank
|
2012-05-30 01:12:11 +04:00
|
|
|
expect(editor.gutter.find('.line-number:first').text()).toBe '2'
|
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe '11'
|
|
|
|
|
2012-06-05 04:45:05 +04:00
|
|
|
# here we don't scroll far enough to trigger additional rendering
|
2012-06-05 06:29:40 +04:00
|
|
|
editor.scrollTop(editor.lineHeight * 5.5) # first visible row will be 5, last will be 10
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 10
|
2012-06-05 06:29:40 +04:00
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(1)
|
|
|
|
expect(editor.renderedLines.find('.line:last').html()).toBe ' ' # line 10 is blank
|
|
|
|
expect(editor.gutter.find('.line-number:first').text()).toBe '2'
|
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe '11'
|
|
|
|
|
|
|
|
editor.scrollTop(editor.lineHeight * 7.5) # first visible row is 7, last will be 12
|
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(5)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(12)
|
2012-05-17 03:28:07 +04:00
|
|
|
|
|
|
|
editor.scrollTop(editor.lineHeight * 3.5) # first visible row will be 3, last will be 8
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 10
|
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(1)
|
|
|
|
expect(editor.renderedLines.find('.line:last').html()).toBe ' ' # line 10 is blank
|
2012-05-11 02:11:05 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
editor.scrollTop(0)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(7)
|
2012-05-11 02:11:05 +04:00
|
|
|
|
|
|
|
describe "when scrolling more than the editors height", ->
|
2012-05-27 00:05:25 +04:00
|
|
|
it "removes lines that are offscreen and not in range of the overdraw and builds lines that become visible", ->
|
2012-05-16 23:47:59 +04:00
|
|
|
editor.scrollTop(editor.scrollView.prop('scrollHeight') - editor.scrollView.height())
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(5)
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(12)
|
2012-05-11 02:11:05 +04:00
|
|
|
|
2012-05-11 23:45:57 +04:00
|
|
|
editor.verticalScrollbar.scrollBottom(0)
|
|
|
|
editor.verticalScrollbar.trigger 'scroll'
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
|
|
|
expect(editor.renderedLines.find('.line:first').text()).toBe buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find('.line:last').text()).toBe buffer.lineForRow(7)
|
2012-05-11 02:11:05 +04:00
|
|
|
|
2012-05-27 00:05:25 +04:00
|
|
|
it "adjusts the vertical padding of the lines element to account for non-rendered lines", ->
|
|
|
|
editor.scrollTop(editor.lineHeight * 3)
|
|
|
|
firstVisibleBufferRow = 3
|
|
|
|
expectedPaddingTop = (firstVisibleBufferRow - editor.lineOverdraw) * editor.lineHeight
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.css('padding-top')).toBe "#{expectedPaddingTop}px"
|
2012-05-27 00:05:25 +04:00
|
|
|
|
|
|
|
lastVisibleBufferRow = Math.ceil(3 + 5.5) # scroll top in lines + height in lines
|
|
|
|
lastOverdrawnRow = lastVisibleBufferRow + editor.lineOverdraw
|
2012-06-01 22:25:58 +04:00
|
|
|
expectedPaddingBottom = ((buffer.getLineCount() - lastOverdrawnRow) * editor.lineHeight)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.css('padding-bottom')).toBe "#{expectedPaddingBottom}px"
|
2012-05-11 02:11:05 +04:00
|
|
|
|
2012-05-27 00:05:25 +04:00
|
|
|
editor.scrollToBottom()
|
2012-05-17 03:28:07 +04:00
|
|
|
# scrolled to bottom, first visible row is 5 and first rendered row is 3
|
2012-06-01 22:25:58 +04:00
|
|
|
firstVisibleBufferRow = Math.floor(buffer.getLineCount() - 5.5)
|
2012-05-27 00:05:25 +04:00
|
|
|
firstOverdrawnBufferRow = firstVisibleBufferRow - editor.lineOverdraw
|
|
|
|
expectedPaddingTop = firstOverdrawnBufferRow * editor.lineHeight
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.css('padding-top')).toBe "#{expectedPaddingTop}px"
|
|
|
|
expect(editor.renderedLines.css('padding-bottom')).toBe "0px"
|
2012-05-11 01:15:34 +04:00
|
|
|
|
2012-05-24 22:43:09 +04:00
|
|
|
describe "when lines are added", ->
|
|
|
|
beforeEach ->
|
2012-05-27 00:05:25 +04:00
|
|
|
editor.attachToDom(heightInLines: 5)
|
2012-05-24 22:43:09 +04:00
|
|
|
spyOn(editor, "scrollTo")
|
|
|
|
|
|
|
|
describe "when the change the precedes the first rendered row", ->
|
2012-05-27 00:52:48 +04:00
|
|
|
it "inserts and removes rendered lines to account for upstream change", ->
|
2012-05-27 00:05:25 +04:00
|
|
|
editor.scrollToBottom()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 7
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
|
|
|
buffer.change([[1,0], [3,0]], "1\n2\n3\n")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 8
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(13)
|
2012-05-27 00:05:25 +04:00
|
|
|
|
2012-05-24 22:43:09 +04:00
|
|
|
describe "when the change straddles the first rendered row", ->
|
|
|
|
it "doesn't render rows that were not previously rendered", ->
|
2012-05-29 22:52:39 +04:00
|
|
|
editor.scrollToBottom()
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 7
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
|
|
|
buffer.change([[2,0], [7,0]], "2\n3\n4\n5\n6\n7\n8\n9\n")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 9
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(14)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
2012-05-29 22:52:39 +04:00
|
|
|
describe "when the change straddles the last rendered row", ->
|
2012-05-24 22:43:09 +04:00
|
|
|
it "doesn't render rows that were not previously rendered", ->
|
|
|
|
buffer.change([[2,0], [7,0]], "2\n3\n4\n5\n6\n7\n8\n")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 7
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
|
|
|
describe "when the change the follows the last rendered row", ->
|
|
|
|
it "does not change the rendered lines", ->
|
|
|
|
buffer.change([[12,0], [12,0]], "12\n13\n14\n")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 7
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
|
|
|
describe "when lines are removed", ->
|
|
|
|
beforeEach ->
|
2012-05-29 22:52:39 +04:00
|
|
|
editor.attachToDom(heightInLines: 5)
|
2012-05-24 22:43:09 +04:00
|
|
|
spyOn(editor, "scrollTo")
|
|
|
|
|
|
|
|
describe "when the change the precedes the first rendered row", ->
|
|
|
|
it "removes rendered lines to account for upstream change", ->
|
2012-05-29 22:52:39 +04:00
|
|
|
editor.scrollToBottom()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 7
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
|
|
|
buffer.change([[1,0], [2,0]], "")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 6
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(11)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
|
|
|
describe "when the change straddles the first rendered row", ->
|
|
|
|
it "renders the correct rows", ->
|
2012-05-29 22:52:39 +04:00
|
|
|
editor.scrollToBottom()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 7
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(12)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
|
|
|
buffer.change([[7,0], [11,0]], "1\n2\n")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 5
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(6)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(10)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
2012-05-29 22:52:39 +04:00
|
|
|
describe "when the change straddles the last rendered row", ->
|
2012-05-24 22:43:09 +04:00
|
|
|
it "renders the correct rows", ->
|
|
|
|
buffer.change([[2,0], [7,0]], "")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 7
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
|
|
|
describe "when the change the follows the last rendered row", ->
|
|
|
|
it "does not change the rendered lines", ->
|
2012-05-29 22:52:39 +04:00
|
|
|
buffer.change([[10,0], [12,0]], "")
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBe 7
|
|
|
|
expect(editor.renderedLines.find(".line:first").text()).toBe buffer.lineForRow(0)
|
|
|
|
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
2012-05-24 22:43:09 +04:00
|
|
|
|
2012-06-05 06:45:28 +04:00
|
|
|
describe "when folding leaves less then a screen worth of text (regression)", ->
|
|
|
|
it "renders lines properly", ->
|
|
|
|
editor.lineOverdraw = 1
|
|
|
|
editor.attachToDom(heightInLines: 5)
|
|
|
|
editor.renderer.toggleFoldAtBufferRow(4)
|
|
|
|
editor.renderer.toggleFoldAtBufferRow(0)
|
|
|
|
|
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 1
|
|
|
|
expect(editor.renderedLines.find('.line').text()).toBe buffer.lineForRow(0)
|
|
|
|
|
2012-06-05 07:11:32 +04:00
|
|
|
describe "when autoscrolling at the end of the document", ->
|
2012-06-05 07:57:10 +04:00
|
|
|
it "renders lines properly", ->
|
2012-06-05 07:11:32 +04:00
|
|
|
editor.setBuffer(new Buffer(require.resolve 'fixtures/two-hundred.txt'))
|
|
|
|
editor.attachToDom(heightInLines: 5.5)
|
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
|
|
|
|
|
|
|
editor.moveCursorToBottom()
|
|
|
|
|
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
|
|
|
|
2012-03-03 04:13:05 +04:00
|
|
|
describe "gutter rendering", ->
|
2012-05-14 20:52:57 +04:00
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom(heightInLines: 5.5)
|
2012-03-03 04:23:57 +04:00
|
|
|
|
2012-05-29 23:39:13 +04:00
|
|
|
it "creates a line number element for each visible line, plus overdraw", ->
|
2012-05-30 01:12:11 +04:00
|
|
|
expect(editor.gutter.find('.line-number').length).toBe 8
|
2012-05-14 20:52:57 +04:00
|
|
|
expect(editor.gutter.find('.line-number:first').text()).toBe "1"
|
2012-05-29 23:39:13 +04:00
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe "8"
|
2012-03-03 04:23:57 +04:00
|
|
|
|
2012-05-30 01:12:11 +04:00
|
|
|
# here we don't scroll far enough to trigger additional rendering
|
|
|
|
editor.scrollTop(editor.lineHeight * 1.5)
|
2012-06-05 06:29:40 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 8
|
2012-05-29 23:39:13 +04:00
|
|
|
expect(editor.gutter.find('.line-number:first').text()).toBe "1"
|
2012-06-05 06:29:40 +04:00
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe "8"
|
2012-05-29 23:39:13 +04:00
|
|
|
|
2012-05-30 01:12:11 +04:00
|
|
|
editor.scrollTop(editor.lineHeight * 3.5)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 10
|
2012-05-14 20:52:57 +04:00
|
|
|
expect(editor.gutter.find('.line-number:first').text()).toBe "2"
|
2012-05-29 23:39:13 +04:00
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe "11"
|
2012-03-03 04:23:57 +04:00
|
|
|
|
2012-05-17 21:16:20 +04:00
|
|
|
describe "width", ->
|
|
|
|
it "sets the width based on last line number", ->
|
|
|
|
expect(editor.gutter.lineNumbers.outerWidth()).toBe editor.charWidth * 2
|
|
|
|
|
|
|
|
it "updates the width when total number of lines gains a digit", ->
|
|
|
|
oneHundredLines = [0..100].join("\n")
|
|
|
|
editor.insertText(oneHundredLines)
|
|
|
|
expect(editor.gutter.lineNumbers.outerWidth()).toBe editor.charWidth * 3
|
|
|
|
|
2012-05-30 00:51:19 +04:00
|
|
|
describe "when lines are inserted", ->
|
|
|
|
it "re-renders the correct line number range in the gutter", ->
|
|
|
|
spyOn(editor, 'scrollTo')
|
|
|
|
editor.scrollTop(3 * editor.lineHeight)
|
|
|
|
expect(editor.gutter.find('.line-number:first').text()).toBe '2'
|
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe '11'
|
|
|
|
|
|
|
|
buffer.insert([6, 0], '\n')
|
|
|
|
|
|
|
|
expect(editor.gutter.find('.line-number:first').text()).toBe '2'
|
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe '11'
|
|
|
|
|
2012-05-17 21:17:05 +04:00
|
|
|
describe "when the insertion of lines causes the editor to scroll", ->
|
|
|
|
it "renders line numbers correctly", ->
|
|
|
|
oneHundredLines = [0..100].join("\n")
|
|
|
|
editor.insertText(oneHundredLines)
|
2012-05-29 23:39:13 +04:00
|
|
|
expect(editor.gutter.lineNumbers.find('.line-number').length).toBe 6 + editor.lineOverdraw * 2
|
2012-05-17 21:17:05 +04:00
|
|
|
|
2012-03-03 05:09:45 +04:00
|
|
|
describe "when wrapping is on", ->
|
|
|
|
it "renders a • instead of line number for wrapped portions of lines", ->
|
2012-06-05 22:38:53 +04:00
|
|
|
editor.setSoftWrapColumn(50)
|
2012-05-30 00:51:19 +04:00
|
|
|
expect(editor.gutter.find('.line-number').length).toEqual(8)
|
2012-03-07 23:19:30 +04:00
|
|
|
expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4'
|
|
|
|
expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '•'
|
|
|
|
expect(editor.gutter.find('.line-number:eq(5)').text()).toBe '5'
|
|
|
|
|
|
|
|
describe "when there are folds", ->
|
2012-05-24 22:17:37 +04:00
|
|
|
it "skips line numbers covered by the fold and updates them when the fold changes", ->
|
2012-05-22 01:18:00 +04:00
|
|
|
editor.createFold(3, 5)
|
2012-03-07 23:19:30 +04:00
|
|
|
expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4'
|
|
|
|
expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '7'
|
2012-03-17 02:11:44 +04:00
|
|
|
|
2012-05-24 22:17:37 +04:00
|
|
|
buffer.insert([4,0], "\n\n")
|
|
|
|
expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4'
|
|
|
|
expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '9'
|
|
|
|
|
|
|
|
buffer.delete([[3,0], [6,0]])
|
|
|
|
expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4'
|
|
|
|
expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '6'
|
2012-03-17 02:11:44 +04:00
|
|
|
|
2012-05-31 21:12:59 +04:00
|
|
|
it "redraws gutter numbers when lines are unfolded", ->
|
|
|
|
setEditorHeightInLines(editor, 20)
|
|
|
|
fold = editor.createFold(2, 12)
|
|
|
|
expect(editor.gutter.find('.line-number').length).toBe 3
|
|
|
|
|
|
|
|
fold.destroy()
|
|
|
|
expect(editor.gutter.find('.line-number').length).toBe 13
|
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
describe "when the scrollView is scrolled to the right", ->
|
|
|
|
it "adds a drop shadow to the gutter", ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.width(100)
|
2012-03-14 02:09:11 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.gutter).not.toHaveClass('drop-shadow')
|
2012-03-14 02:09:11 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
editor.scrollView.scrollLeft(10)
|
|
|
|
editor.scrollView.trigger('scroll')
|
2012-03-14 02:09:11 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.gutter).toHaveClass('drop-shadow')
|
2012-03-14 02:09:11 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
editor.scrollView.scrollLeft(0)
|
|
|
|
editor.scrollView.trigger('scroll')
|
2012-03-14 02:09:11 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.gutter).not.toHaveClass('drop-shadow')
|
2012-03-07 23:19:30 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
describe "when the editor is scrolled vertically", ->
|
|
|
|
it "adjusts the padding-top to account for non-rendered line numbers", ->
|
|
|
|
editor.scrollTop(editor.lineHeight * 3.5)
|
2012-05-29 23:07:24 +04:00
|
|
|
expect(editor.gutter.lineNumbers.css('padding-top')).toBe "#{editor.lineHeight * 1}px"
|
|
|
|
expect(editor.gutter.lineNumbers.css('padding-bottom')).toBe "#{editor.lineHeight * 2}px"
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line').length).toBe 10
|
2012-05-29 23:07:24 +04:00
|
|
|
expect(editor.gutter.find('.line-number:first').text()).toBe "2"
|
|
|
|
expect(editor.gutter.find('.line-number:last').text()).toBe "11"
|
2012-05-16 23:47:59 +04:00
|
|
|
|
2012-05-09 18:34:08 +04:00
|
|
|
describe "font size", ->
|
|
|
|
it "sets the initial font size based on the value assigned to the root view", ->
|
|
|
|
rootView.setFontSize(20)
|
|
|
|
rootView.simulateDomAttachment()
|
|
|
|
newEditor = editor.splitRight()
|
|
|
|
expect(editor.css('font-size')).toBe '20px'
|
|
|
|
expect(newEditor.css('font-size')).toBe '20px'
|
|
|
|
|
|
|
|
describe "when the font size changes on the view", ->
|
|
|
|
it "updates the font sizes of editors and recalculates dimensions critical to cursor positioning", ->
|
|
|
|
rootView.attachToDom()
|
2012-06-01 21:52:44 +04:00
|
|
|
rootView.setFontSize(10)
|
2012-05-09 18:34:08 +04:00
|
|
|
lineHeightBefore = editor.lineHeight
|
|
|
|
charWidthBefore = editor.charWidth
|
|
|
|
editor.setCursorScreenPosition [5, 5]
|
|
|
|
|
|
|
|
rootView.setFontSize(30)
|
|
|
|
|
|
|
|
expect(editor.css('font-size')).toBe '30px'
|
|
|
|
expect(editor.lineHeight).toBeGreaterThan lineHeightBefore
|
|
|
|
expect(editor.charWidth).toBeGreaterThan charWidthBefore
|
|
|
|
expect(editor.getCursors()[0].position()).toEqual { top: 5 * editor.lineHeight, left: 5 * editor.charWidth }
|
|
|
|
|
|
|
|
# ensure we clean up font size subscription
|
|
|
|
editor.trigger('close')
|
|
|
|
rootView.setFontSize(22)
|
|
|
|
expect(editor.css('font-size')).toBe '30px'
|
|
|
|
|
2012-05-16 21:58:19 +04:00
|
|
|
it "updates lines if there are unrendered lines", ->
|
|
|
|
editor.attachToDom(heightInLines: 5)
|
2012-06-05 04:53:58 +04:00
|
|
|
originalLineCount = editor.renderedLines.find(".line").length
|
2012-05-16 21:58:19 +04:00
|
|
|
expect(originalLineCount).toBeGreaterThan 0
|
|
|
|
editor.setFontSize(10)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find(".line").length).toBeGreaterThan originalLineCount
|
2012-05-16 21:58:19 +04:00
|
|
|
|
2012-01-18 06:13:50 +04:00
|
|
|
describe "cursor movement", ->
|
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-03-29 00:50:52 +04:00
|
|
|
describe "vertical movement", ->
|
|
|
|
describe "goal column retention", ->
|
|
|
|
lineLengths = null
|
2012-01-24 01:58:26 +04:00
|
|
|
|
2012-03-29 00:50:52 +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-03-29 00:50:52 +04:00
|
|
|
it "retains the goal column when moving up", ->
|
|
|
|
expect(lineLengths[6]).toBeGreaterThan(32)
|
|
|
|
editor.setCursorScreenPosition(row: 6, column: 32)
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[5]
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[4]
|
2012-01-24 01:40:37 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 32
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
it "retains the goal column when moving down", ->
|
|
|
|
editor.setCursorScreenPosition(row: 3, column: lineLengths[3])
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[4]
|
2012-01-24 02:18:34 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[5]
|
2012-01-24 01:40:37 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe lineLengths[3]
|
2012-01-20 02:39:16 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
it "clears the goal column when the cursor is set", ->
|
|
|
|
# set a goal column by moving down
|
|
|
|
editor.setCursorScreenPosition(row: 3, column: lineLengths[3])
|
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition().column).not.toBe 6
|
2012-01-24 02:37:03 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
# clear the goal column by explicitly setting the cursor position
|
|
|
|
editor.setCursorScreenPosition([4,6])
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 6
|
2012-01-24 02:56:30 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 6
|
2012-01-24 02:37:03 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
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.setCursorScreenPosition(row: 0, column: 4)
|
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-01-20 02:39:16 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 1, column: 4)
|
2012-01-20 03:40:26 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
describe "when down is pressed on the last line", ->
|
|
|
|
it "moves the cursor to the end of line, but retains the goal column", ->
|
|
|
|
lastLineIndex = buffer.getLines().length - 1
|
|
|
|
lastLine = buffer.lineForRow(lastLineIndex)
|
|
|
|
expect(lastLine.length).toBeGreaterThan(0)
|
2012-01-20 03:40:26 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.setCursorScreenPosition(row: lastLineIndex, column: 1)
|
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: lastLineIndex, column: lastLine.length)
|
2012-01-20 03:40:26 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 1
|
2012-01-18 06:13:50 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
it "retains a goal column of 0", ->
|
|
|
|
lastLineIndex = buffer.getLines().length - 1
|
|
|
|
lastLine = buffer.lineForRow(lastLineIndex)
|
|
|
|
expect(lastLine.length).toBeGreaterThan(0)
|
2012-01-17 07:23:27 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
editor.setCursorScreenPosition(row: lastLineIndex, column: 0)
|
|
|
|
editor.moveCursorDown()
|
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.getCursorScreenPosition().column).toBe 0
|
2012-01-17 07:23:27 +04:00
|
|
|
|
2012-04-06 22:21:24 +04:00
|
|
|
describe "horizontal movement", ->
|
2012-03-29 00:50:52 +04:00
|
|
|
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.setCursorScreenPosition(row: 1, column: 0)
|
|
|
|
editor.moveCursorLeft()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: buffer.lineForRow(0).length)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
describe "when the cursor is on the first line", ->
|
|
|
|
it "remains in the same position (0,0)", ->
|
|
|
|
editor.setCursorScreenPosition(row: 0, column: 0)
|
|
|
|
editor.moveCursorLeft()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
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.setCursorScreenPosition(row: 0, column: buffer.lineForRow(0).length)
|
|
|
|
editor.moveCursorRight()
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 1, column: 0)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
describe "when the cursor is on the last line", ->
|
|
|
|
it "remains in the same position", ->
|
|
|
|
lastLineIndex = buffer.getLines().length - 1
|
|
|
|
lastLine = buffer.lineForRow(lastLineIndex)
|
|
|
|
expect(lastLine.length).toBeGreaterThan(0)
|
2012-01-25 02:21:43 +04:00
|
|
|
|
2012-03-29 00:50:52 +04:00
|
|
|
lastPosition = { row: lastLineIndex, column: lastLine.length }
|
|
|
|
editor.setCursorScreenPosition(lastPosition)
|
|
|
|
editor.moveCursorRight()
|
|
|
|
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(lastPosition)
|
2012-03-29 04:34:20 +04:00
|
|
|
|
2012-03-29 01:22:53 +04:00
|
|
|
describe "move-to-top ", ->
|
|
|
|
it "moves cusor to the top of the buffer", ->
|
|
|
|
editor.setCursorScreenPosition [11,1]
|
|
|
|
editor.addCursorAtScreenPosition [12,0]
|
|
|
|
editor.trigger 'move-to-top'
|
|
|
|
expect(editor.getCursors().length).toBe 1
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [0,0]
|
|
|
|
|
|
|
|
describe "move-to-bottom", ->
|
|
|
|
it "moves cusor to the bottom of the buffer", ->
|
|
|
|
editor.setCursorScreenPosition [0,0]
|
|
|
|
editor.addCursorAtScreenPosition [1,0]
|
|
|
|
editor.trigger 'move-to-bottom'
|
|
|
|
expect(editor.getCursors().length).toBe 1
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [12,2]
|
|
|
|
|
|
|
|
describe "move-to-beginning-of-line", ->
|
|
|
|
it "moves cursor to the beginning of line", ->
|
|
|
|
editor.setCursorScreenPosition [0,5]
|
|
|
|
editor.addCursorAtScreenPosition [1,7]
|
|
|
|
editor.trigger 'move-to-beginning-of-line'
|
|
|
|
expect(editor.getCursors().length).toBe 2
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,0]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [1,0]
|
|
|
|
|
|
|
|
describe "move-to-end-of-line", ->
|
|
|
|
it "moves cursor to the end of line", ->
|
|
|
|
editor.setCursorScreenPosition [0,0]
|
|
|
|
editor.addCursorAtScreenPosition [1,0]
|
|
|
|
editor.trigger 'move-to-end-of-line'
|
|
|
|
expect(editor.getCursors().length).toBe 2
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,29]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [1,30]
|
|
|
|
|
2012-03-29 02:09:10 +04:00
|
|
|
describe "move-to-first-character-of-line", ->
|
|
|
|
it "moves to the first character of the current line or the beginning of the line if it's already on the first character", ->
|
|
|
|
editor.setCursorScreenPosition [0,5]
|
|
|
|
editor.addCursorAtScreenPosition [1,7]
|
|
|
|
editor.trigger 'move-to-first-character-of-line'
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,0]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [1,2]
|
|
|
|
editor.trigger 'move-to-first-character-of-line'
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,0]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [1,0]
|
|
|
|
|
2012-04-21 04:11:01 +04:00
|
|
|
it "does not throw an exception on an empty line", ->
|
|
|
|
editor.setCursorBufferPosition([10, 0])
|
|
|
|
editor.trigger 'move-to-first-character-of-line'
|
|
|
|
|
2012-03-29 01:22:53 +04:00
|
|
|
describe "move-to-next-word", ->
|
|
|
|
it "moves the cursor to the next word or the end of file if there is no next word", ->
|
|
|
|
editor.setCursorBufferPosition [2, 5]
|
|
|
|
editor.addCursorAtBufferPosition [3, 60]
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
|
|
|
|
editor.trigger 'move-to-next-word'
|
|
|
|
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [2, 7]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [4, 4]
|
|
|
|
|
|
|
|
buffer.insert([12, 2], ' ')
|
|
|
|
cursor1.setBufferPosition([12, 1])
|
|
|
|
editor.trigger 'move-to-next-word'
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [12, 5]
|
|
|
|
|
2012-03-29 04:34:20 +04:00
|
|
|
describe "move-to-beginning-of-word", ->
|
|
|
|
it "moves the cursor to the beginning of the word", ->
|
|
|
|
editor.setCursorBufferPosition [0, 8]
|
|
|
|
editor.addCursorAtBufferPosition [1, 12]
|
|
|
|
editor.addCursorAtBufferPosition [3, 0]
|
|
|
|
[cursor1, cursor2, cursor3] = editor.getCursors()
|
|
|
|
|
|
|
|
editor.trigger 'move-to-beginning-of-word'
|
|
|
|
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0, 4]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [1, 11]
|
|
|
|
expect(cursor3.getBufferPosition()).toEqual [2, 39]
|
2012-03-29 01:36:40 +04:00
|
|
|
|
2012-04-09 23:59:46 +04:00
|
|
|
it "does not fail at position [0, 0]", ->
|
|
|
|
editor.setCursorBufferPosition([0, 0])
|
|
|
|
editor.trigger 'move-to-beginning-of-word'
|
|
|
|
|
2012-03-29 04:34:20 +04:00
|
|
|
describe "move-to-end-of-word", ->
|
|
|
|
it "moves the cursor to the end of the word", ->
|
|
|
|
editor.setCursorBufferPosition [0, 6]
|
|
|
|
editor.addCursorAtBufferPosition [1, 10]
|
|
|
|
editor.addCursorAtBufferPosition [2, 40]
|
|
|
|
[cursor1, cursor2, cursor3] = editor.getCursors()
|
2012-03-29 01:36:40 +04:00
|
|
|
|
2012-03-29 04:34:20 +04:00
|
|
|
editor.trigger 'move-to-end-of-word'
|
2012-03-29 01:36:40 +04:00
|
|
|
|
2012-03-29 04:34:20 +04:00
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0, 13]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [1, 12]
|
|
|
|
expect(cursor3.getBufferPosition()).toEqual [3, 7]
|
2012-03-29 01:36:40 +04:00
|
|
|
|
2012-03-29 01:22:53 +04:00
|
|
|
describe ".setCursorScreenPosition({row, column})", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.setCursorScreenPosition(row: 2, column: 2)
|
|
|
|
|
|
|
|
it "moves the cursor to the character at the given row and column", ->
|
|
|
|
expect(editor.find('.cursor').position()).toEqual(top: 2 * editor.lineHeight, left: 2 * editor.charWidth)
|
|
|
|
|
|
|
|
describe "if soft-wrap is enabled", ->
|
|
|
|
beforeEach ->
|
|
|
|
setEditorWidthInChars(editor, 20)
|
|
|
|
editor.setSoftWrap(true)
|
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-03-01 23:44:26 +04:00
|
|
|
describe "when soft-wrap and is enabled and code is folded", ->
|
2012-02-10 23:35:38 +04:00
|
|
|
beforeEach ->
|
2012-03-03 05:09:45 +04:00
|
|
|
setEditorWidthInChars(editor, 50)
|
2012-02-10 23:35:38 +04:00
|
|
|
editor.setSoftWrap(true)
|
2012-05-22 01:18:00 +04:00
|
|
|
editor.createFold(2, 3)
|
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-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [9, 0])
|
2012-05-22 01:18:00 +04:00
|
|
|
expect(editor.getCursorBufferPosition()).toEqual(row: 8, column: 11)
|
2012-02-03 02:57:05 +04:00
|
|
|
|
2012-03-01 23:44:26 +04:00
|
|
|
describe "when it is a double click", ->
|
|
|
|
it "selects the word under the cursor", ->
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [9, 0], originalEvent: {detail: 1})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [9, 0], originalEvent: {detail: 2})
|
2012-05-22 01:18:00 +04:00
|
|
|
expect(editor.getSelectedText()).toBe "sort"
|
2012-03-01 23:44:26 +04:00
|
|
|
|
|
|
|
describe "when it is clicked more then twice (triple, quadruple, etc...)", ->
|
|
|
|
it "selects the line under the cursor", ->
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
|
|
|
|
|
|
|
# Triple click
|
2012-05-22 01:18:00 +04:00
|
|
|
point = [9, 3]
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 1})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 2})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 3})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-05-22 01:18:00 +04:00
|
|
|
expect(editor.getSelectedText()).toBe " return sort(left).concat(pivot).concat(sort(right));"
|
2012-03-01 23:44:26 +04:00
|
|
|
|
|
|
|
# Quad click
|
2012-05-22 01:18:00 +04:00
|
|
|
point = [12, 3]
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 1})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 2})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 3})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: point, originalEvent: {detail: 4})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-03-01 23:44:26 +04:00
|
|
|
|
2012-05-22 01:18:00 +04:00
|
|
|
expect(editor.getSelectedText()).toBe " return sort(Array.apply(this, arguments));"
|
2012-03-01 23:44:26 +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
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [3, 10])
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 3, column: 10)
|
2012-02-10 23:35:38 +04:00
|
|
|
|
2012-03-08 04:22:13 +04:00
|
|
|
describe "when the lines are scrolled to the right", ->
|
|
|
|
it "re-positions the cursor on the clicked location", ->
|
|
|
|
setEditorWidthInChars(editor, 30)
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 0, column: 0)
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [3, 30]) # scrolls lines to the right
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [3, 50])
|
2012-03-08 04:22:13 +04:00
|
|
|
expect(editor.getCursorBufferPosition()).toEqual(row: 3, column: 50)
|
|
|
|
|
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-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [0, 8], originalEvent: {detail: 1})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [0, 8], originalEvent: {detail: 2})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-02-10 23:35:38 +04:00
|
|
|
expect(editor.getSelectedText()).toBe "quicksort"
|
|
|
|
|
2012-03-01 23:44:26 +04:00
|
|
|
describe "when it is clicked more then twice (triple, quadruple, etc...)", ->
|
2012-02-10 23:35:38 +04:00
|
|
|
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
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [1, 8], originalEvent: {detail: 1})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [1, 8], originalEvent: {detail: 2})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [1, 8], originalEvent: {detail: 3})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-02-10 23:35:38 +04:00
|
|
|
expect(editor.getSelectedText()).toBe " var sort = function(items) {"
|
|
|
|
|
|
|
|
# Quad click
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [2, 3], originalEvent: {detail: 1})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [2, 3], originalEvent: {detail: 2})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [2, 3], originalEvent: {detail: 3})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [2, 3], originalEvent: {detail: 4})
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-02-10 23:35:38 +04:00
|
|
|
expect(editor.getSelectedText()).toBe " if (items.length <= 1) return items;"
|
2012-02-04 01:11:42 +04:00
|
|
|
|
2012-04-04 03:12:04 +04:00
|
|
|
describe "scrolling", ->
|
|
|
|
describe "vertical scrolling", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.focus()
|
|
|
|
editor.vScrollMargin = 3
|
|
|
|
|
|
|
|
it "scrolls the buffer with the specified scroll margin when cursor approaches the end of the screen", ->
|
2012-05-11 21:52:03 +04:00
|
|
|
setEditorHeightInLines(editor, 10)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
_.times 6, -> editor.moveCursorDown()
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.scrollTop()).toBe(0)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.moveCursorDown()
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.moveCursorDown()
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight * 2)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
_.times 3, -> editor.moveCursorUp()
|
|
|
|
|
|
|
|
editor.moveCursorUp()
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.moveCursorUp()
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.scrollTop()).toBe(0)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
it "reduces scroll margins when there isn't enough height to maintain them and scroll smoothly", ->
|
2012-04-21 03:18:07 +04:00
|
|
|
setEditorHeightInLines(editor, 5)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
2012-05-29 23:39:13 +04:00
|
|
|
_.times 3, -> editor.moveCursorDown()
|
2012-04-04 03:12:04 +04:00
|
|
|
|
2012-05-16 23:47:59 +04:00
|
|
|
expect(editor.scrollTop()).toBe(editor.lineHeight)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.moveCursorUp()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollTop()).toBe(0)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
describe "horizontal scrolling", ->
|
|
|
|
charWidth = null
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
|
|
|
{charWidth} = editor
|
|
|
|
editor.hScrollMargin = 5
|
|
|
|
|
|
|
|
it "scrolls horizontally to keep the cursor on screen", ->
|
|
|
|
setEditorWidthInChars(editor, 30)
|
|
|
|
|
|
|
|
# moving right
|
|
|
|
editor.setCursorScreenPosition([2, 24])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 25])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe charWidth
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 28])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe charWidth * 4
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
# moving left
|
|
|
|
editor.setCursorScreenPosition([2, 9])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe charWidth * 4
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 8])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe charWidth * 3
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 5])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
it "reduces scroll margins when there isn't enough width to maintain them and scroll smoothly", ->
|
|
|
|
editor.hScrollMargin = 6
|
|
|
|
setEditorWidthInChars(editor, 7)
|
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 3])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe(0)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 4])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe(charWidth)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 3])
|
|
|
|
window.advanceClock()
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe(0)
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
describe "when soft-wrap is on", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.setSoftWrap(true)
|
|
|
|
|
|
|
|
it "does not scroll the buffer horizontally", ->
|
|
|
|
editor.width(charWidth * 30)
|
|
|
|
|
|
|
|
# moving right
|
|
|
|
editor.setCursorScreenPosition([2, 24])
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 25])
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 28])
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
# moving left
|
|
|
|
editor.setCursorScreenPosition([2, 9])
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 8])
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2, 5])
|
2012-05-11 23:42:57 +04:00
|
|
|
expect(editor.scrollView.scrollLeft()).toBe 0
|
2012-04-04 03:12:04 +04:00
|
|
|
|
|
|
|
describe "when there are multiple cursor", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.focus()
|
|
|
|
editor.vScrollMargin = 2
|
|
|
|
|
|
|
|
it "only attempts to scroll when a cursor is visible", ->
|
|
|
|
setEditorWidthInChars(editor, 20)
|
2012-04-21 03:18:07 +04:00
|
|
|
setEditorHeightInLines(editor, 10)
|
2012-04-04 03:12:04 +04:00
|
|
|
editor.setCursorBufferPosition([11,0])
|
|
|
|
editor.addCursorAtBufferPosition([6,50])
|
2012-04-04 03:34:01 +04:00
|
|
|
editor.addCursorAtBufferPosition([0,0])
|
2012-04-04 03:12:04 +04:00
|
|
|
window.advanceClock()
|
|
|
|
|
|
|
|
scrollHandler = spyOn(editor, 'scrollVertically')
|
|
|
|
|
|
|
|
editor.moveCursorRight()
|
|
|
|
window.advanceClock()
|
|
|
|
position = editor.pixelPositionForScreenPosition([0,1])
|
|
|
|
expect(scrollHandler).toHaveBeenCalledWith(position)
|
|
|
|
|
|
|
|
it "only attempts to scroll once when multiple cursors are visible", ->
|
|
|
|
setEditorWidthInChars(editor, 20)
|
2012-04-21 03:18:07 +04:00
|
|
|
setEditorHeightInLines(editor, 10)
|
2012-04-04 03:12:04 +04:00
|
|
|
editor.setCursorBufferPosition([11,0])
|
|
|
|
editor.addCursorAtBufferPosition([0,0])
|
|
|
|
editor.addCursorAtBufferPosition([6,0])
|
|
|
|
window.advanceClock()
|
|
|
|
|
|
|
|
scrollHandler = spyOn(editor, 'scrollVertically')
|
|
|
|
|
|
|
|
editor.moveCursorRight()
|
|
|
|
window.advanceClock()
|
|
|
|
|
2012-04-04 03:34:01 +04:00
|
|
|
position = editor.pixelPositionForScreenPosition([6,1])
|
2012-04-04 03:12:04 +04:00
|
|
|
expect(scrollHandler).toHaveBeenCalledWith(position)
|
|
|
|
|
2012-03-14 01:50:43 +04:00
|
|
|
describe "when editing a line that spans multiple screen lines", ->
|
2012-03-08 03:22:41 +04:00
|
|
|
beforeEach ->
|
2012-03-14 01:56:24 +04:00
|
|
|
editor.setSoftWrap(true, 50)
|
2012-06-01 04:22:54 +04:00
|
|
|
editor.autoIndent = true
|
2012-03-08 03:22:41 +04:00
|
|
|
|
|
|
|
describe "when newline is inserted", ->
|
|
|
|
it "indents cursor based on the indentation of previous buffer line", ->
|
|
|
|
editor.setCursorBufferPosition([4, 29])
|
|
|
|
editor.insertText("\n")
|
|
|
|
expect(editor.buffer.lineForRow(5)).toEqual(" ")
|
|
|
|
|
2012-06-01 04:22:54 +04:00
|
|
|
describe "when text that closes a scope is entered", ->
|
2012-03-08 03:22:41 +04:00
|
|
|
it "outdents the text", ->
|
|
|
|
editor.setCursorBufferPosition([4, 29])
|
|
|
|
editor.insertText("\n")
|
|
|
|
expect(editor.buffer.lineForRow(5)).toEqual(" ")
|
|
|
|
editor.insertText("}")
|
|
|
|
expect(editor.buffer.lineForRow(5)).toEqual(" }")
|
|
|
|
expect(editor.getCursorBufferPosition().column).toBe 5
|
|
|
|
|
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 ->
|
2012-03-23 02:08:20 +04:00
|
|
|
selection = editor.getSelection()
|
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-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 10])
|
2012-01-29 05:00:59 +04:00
|
|
|
|
|
|
|
# moving changes selection
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [5, 27])
|
2012-01-29 05:00:59 +04:00
|
|
|
|
2012-03-23 02:08:20 +04:00
|
|
|
range = editor.getSelection().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-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [8, 8])
|
2012-02-03 21:55:04 +04:00
|
|
|
|
2012-03-23 02:08:20 +04:00
|
|
|
range = editor.getSelection().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-04-06 03:58:44 +04:00
|
|
|
it "creates a selection from the word underneath an initial double click to mouse's new location ", ->
|
2012-02-03 21:55:04 +04:00
|
|
|
editor.attachToDom()
|
|
|
|
editor.css(position: 'absolute', top: 10, left: 10)
|
|
|
|
|
|
|
|
# double click
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 7], originalEvent: {detail: 1})
|
2012-02-03 21:55:04 +04:00
|
|
|
$(document).trigger 'mouseup'
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 7], originalEvent: {detail: 2})
|
2012-02-03 21:55:04 +04:00
|
|
|
|
|
|
|
# moving changes selection
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [5, 27])
|
2012-02-03 21:55:04 +04:00
|
|
|
|
2012-03-23 02:08:20 +04:00
|
|
|
range = editor.getSelection().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-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [8, 8])
|
2012-01-29 05:00:59 +04:00
|
|
|
|
2012-03-23 02:08:20 +04:00
|
|
|
range = editor.getSelection().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
|
|
|
|
2012-04-06 03:58:44 +04:00
|
|
|
it "creates a selection from the line underneath an initial triple click to mouse's new location ", ->
|
2012-02-04 01:33:22 +04:00
|
|
|
editor.attachToDom()
|
|
|
|
editor.css(position: 'absolute', top: 10, left: 10)
|
|
|
|
|
|
|
|
# double click
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 7], originalEvent: {detail: 1})
|
2012-02-04 01:33:22 +04:00
|
|
|
$(document).trigger 'mouseup'
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 7], originalEvent: {detail: 2})
|
2012-02-04 01:33:22 +04:00
|
|
|
$(document).trigger 'mouseup'
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 7], originalEvent: {detail: 3})
|
2012-02-04 01:33:22 +04:00
|
|
|
|
|
|
|
# moving changes selection
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [5, 27])
|
2012-02-04 01:33:22 +04:00
|
|
|
|
2012-03-23 02:08:20 +04:00
|
|
|
range = editor.getSelection().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
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [8, 8])
|
2012-02-04 01:33:22 +04:00
|
|
|
|
2012-03-23 02:08:20 +04:00
|
|
|
range = editor.getSelection().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-04-06 04:12:48 +04:00
|
|
|
describe "shift-click", ->
|
2012-04-06 05:41:34 +04:00
|
|
|
beforeEach ->
|
2012-04-06 04:12:48 +04:00
|
|
|
editor.attachToDom()
|
|
|
|
editor.css(position: 'absolute', top: 10, left: 10)
|
|
|
|
editor.setCursorScreenPosition([4, 7])
|
|
|
|
|
2012-04-06 05:41:34 +04:00
|
|
|
it "selects from the cursor's current location to the clicked location", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [5, 24], shiftKey: true)
|
2012-04-06 05:41:34 +04:00
|
|
|
expect(editor.getSelection().getScreenRange()).toEqual [[4, 7], [5, 24]]
|
|
|
|
|
|
|
|
describe "when it is a double-click", ->
|
|
|
|
it "expands the selection to include the double-clicked word", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [5, 24], shiftKey: true, originalEvent: { detail: 1 })
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [5, 24], shiftKey: true, originalEvent: { detail: 2 })
|
2012-04-06 05:41:34 +04:00
|
|
|
expect(editor.getSelection().getScreenRange()).toEqual [[4, 7], [5, 27]]
|
2012-04-06 04:12:48 +04:00
|
|
|
|
2012-04-06 21:07:19 +04:00
|
|
|
describe "when it is a triple-click", ->
|
|
|
|
it "expands the selection to include the triple-clicked line", ->
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [5, 24], shiftKey: true, originalEvent: { detail: 1 })
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [5, 24], shiftKey: true, originalEvent: { detail: 2 })
|
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [5, 24], shiftKey: true, originalEvent: { detail: 3 })
|
2012-04-06 21:07:19 +04:00
|
|
|
expect(editor.getSelection().getScreenRange()).toEqual [[4, 7], [5, 30]]
|
|
|
|
|
2012-03-29 00:51:02 +04:00
|
|
|
describe "select-to-top", ->
|
|
|
|
it "selects text from cusor position to the top of the buffer", ->
|
|
|
|
editor.setCursorScreenPosition [11,2]
|
|
|
|
editor.addCursorAtScreenPosition [10,0]
|
|
|
|
editor.trigger 'select-to-top'
|
|
|
|
expect(editor.getCursors().length).toBe 1
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [0,0]
|
|
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[0,0], [11,2]]
|
|
|
|
expect(editor.getSelection().isReversed()).toBeTruthy()
|
|
|
|
|
|
|
|
describe "select-to-bottom", ->
|
|
|
|
it "selects text from cusor position to the bottom of the buffer", ->
|
|
|
|
editor.setCursorScreenPosition [10,0]
|
|
|
|
editor.addCursorAtScreenPosition [9,3]
|
|
|
|
editor.trigger 'select-to-bottom'
|
|
|
|
expect(editor.getCursors().length).toBe 1
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [12,2]
|
|
|
|
expect(editor.getSelection().getBufferRange()).toEqual [[9,3], [12,2]]
|
|
|
|
expect(editor.getSelection().isReversed()).toBeFalsy()
|
|
|
|
|
2012-05-15 02:18:37 +04:00
|
|
|
describe "select-all", ->
|
|
|
|
it "selects the entire buffer", ->
|
|
|
|
editor.trigger 'select-all'
|
|
|
|
expect(editor.getSelection().getBufferRange()).toEqual buffer.getRange()
|
|
|
|
|
2012-03-29 02:07:44 +04:00
|
|
|
describe "select-to-beginning-of-line", ->
|
2012-03-29 20:53:18 +04:00
|
|
|
it "selects text from cusor position to beginning of line", ->
|
2012-03-29 02:07:44 +04:00
|
|
|
editor.setCursorScreenPosition [12,2]
|
|
|
|
editor.addCursorAtScreenPosition [11,3]
|
|
|
|
editor.trigger 'select-to-beginning-of-line'
|
|
|
|
expect(editor.getCursors().length).toBe 2
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [12,0]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [11,0]
|
|
|
|
|
|
|
|
expect(editor.getSelections().length).toBe 2
|
|
|
|
[selection1, selection2] = editor.getSelections()
|
|
|
|
expect(selection1.getBufferRange()).toEqual [[12,0], [12,2]]
|
|
|
|
expect(selection1.isReversed()).toBeTruthy()
|
|
|
|
expect(selection2.getBufferRange()).toEqual [[11,0], [11,3]]
|
|
|
|
expect(selection2.isReversed()).toBeTruthy()
|
|
|
|
|
|
|
|
describe "select-to-end-of-line", ->
|
|
|
|
it "selects text from cusor position to end of line", ->
|
|
|
|
editor.setCursorScreenPosition [12,0]
|
|
|
|
editor.addCursorAtScreenPosition [11,3]
|
|
|
|
editor.trigger 'select-to-end-of-line'
|
|
|
|
expect(editor.getCursors().length).toBe 2
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [12,2]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [11,44]
|
|
|
|
|
|
|
|
expect(editor.getSelections().length).toBe 2
|
|
|
|
[selection1, selection2] = editor.getSelections()
|
|
|
|
expect(selection1.getBufferRange()).toEqual [[12,0], [12,2]]
|
|
|
|
expect(selection1.isReversed()).toBeFalsy()
|
|
|
|
expect(selection2.getBufferRange()).toEqual [[11,3], [11,44]]
|
|
|
|
expect(selection2.isReversed()).toBeFalsy()
|
|
|
|
|
2012-03-29 20:53:18 +04:00
|
|
|
describe "select-to-beginning-of-word", ->
|
|
|
|
it "selects text from cusor position to beginning of word", ->
|
|
|
|
editor.setCursorScreenPosition [0,13]
|
|
|
|
editor.addCursorAtScreenPosition [3,49]
|
|
|
|
editor.trigger 'select-to-beginning-of-word'
|
|
|
|
expect(editor.getCursors().length).toBe 2
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,4]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [3,47]
|
|
|
|
|
|
|
|
expect(editor.getSelections().length).toBe 2
|
|
|
|
[selection1, selection2] = editor.getSelections()
|
|
|
|
expect(selection1.getBufferRange()).toEqual [[0,4], [0,13]]
|
|
|
|
expect(selection1.isReversed()).toBeTruthy()
|
|
|
|
expect(selection2.getBufferRange()).toEqual [[3,47], [3,49]]
|
|
|
|
expect(selection2.isReversed()).toBeTruthy()
|
|
|
|
|
|
|
|
describe "select-to-end-of-word", ->
|
|
|
|
it "selects text from cusor position to end of word", ->
|
|
|
|
editor.setCursorScreenPosition [0,4]
|
|
|
|
editor.addCursorAtScreenPosition [3,48]
|
|
|
|
editor.trigger 'select-to-end-of-word'
|
|
|
|
expect(editor.getCursors().length).toBe 2
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,13]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [3,50]
|
|
|
|
|
|
|
|
expect(editor.getSelections().length).toBe 2
|
|
|
|
[selection1, selection2] = editor.getSelections()
|
|
|
|
expect(selection1.getBufferRange()).toEqual [[0,4], [0,13]]
|
|
|
|
expect(selection1.isReversed()).toBeFalsy()
|
|
|
|
expect(selection2.getBufferRange()).toEqual [[3,48], [3,50]]
|
|
|
|
expect(selection2.isReversed()).toBeFalsy()
|
|
|
|
|
2012-03-27 01:58:52 +04:00
|
|
|
describe "multiple cursors", ->
|
2012-05-16 23:47:59 +04:00
|
|
|
it "places multiple cursors with meta-click", ->
|
2012-03-23 04:10:24 +04:00
|
|
|
editor.attachToDom()
|
2012-04-21 03:18:07 +04:00
|
|
|
setEditorHeightInLines(editor, 5)
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [3, 0])
|
2012-05-16 23:47:59 +04:00
|
|
|
editor.scrollTop(editor.lineHeight * 6)
|
2012-04-05 01:08:21 +04:00
|
|
|
|
|
|
|
spyOn(editor, "scrollTo").andCallThrough()
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [6, 0], metaKey: true)
|
2012-04-05 01:08:21 +04:00
|
|
|
expect(editor.scrollTo.callCount).toBe 1
|
2012-03-23 04:10:24 +04:00
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.find('.cursor').map -> $(this).view()
|
|
|
|
expect(cursor1.position()).toEqual(top: 3 * editor.lineHeight, left: 0)
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 0]
|
|
|
|
expect(cursor2.position()).toEqual(top: 6 * editor.lineHeight, left: 0)
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [6, 0]
|
|
|
|
|
2012-03-24 01:20:54 +04:00
|
|
|
describe "inserting text", ->
|
2012-03-24 02:02:34 +04:00
|
|
|
describe "when cursors are on the same line", ->
|
|
|
|
describe "when inserting newlines", ->
|
|
|
|
it "breaks the line into three lines at the cursor locations", ->
|
|
|
|
editor.setCursorScreenPosition([3, 13])
|
|
|
|
editor.addCursorAtScreenPosition([3, 38])
|
|
|
|
|
|
|
|
editor.insertText('\n')
|
|
|
|
|
|
|
|
expect(editor.lineForBufferRow(3)).toBe " var pivot"
|
|
|
|
expect(editor.lineForBufferRow(4)).toBe " = items.shift(), current"
|
|
|
|
expect(editor.lineForBufferRow(5)).toBe ", left = [], right = [];"
|
|
|
|
expect(editor.lineForBufferRow(6)).toBe " while(items.length > 0) {"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [4, 0]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [5, 0]
|
|
|
|
|
|
|
|
describe "when cursors are on different lines", ->
|
|
|
|
describe "when inserting characters other than newlines", ->
|
|
|
|
it "inserts text for all cursors", ->
|
|
|
|
editor.setCursorScreenPosition([3, 0])
|
|
|
|
editor.addCursorAtScreenPosition([6, 0])
|
|
|
|
|
|
|
|
editor.insertText("abc")
|
|
|
|
expect(editor.lineForBufferRow(3)).toBe "abc var pivot = items.shift(), current, left = [], right = [];"
|
|
|
|
expect(editor.lineForBufferRow(6)).toBe "abc current < pivot ? left.push(current) : right.push(current);"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3,3]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [6,3]
|
|
|
|
|
|
|
|
describe "when inserting newlines", ->
|
|
|
|
it "inserts newlines for all cursors", ->
|
|
|
|
editor.setCursorScreenPosition([3, 0])
|
|
|
|
editor.addCursorAtScreenPosition([6, 0])
|
|
|
|
|
|
|
|
editor.insertText("\n")
|
|
|
|
expect(editor.lineForBufferRow(3)).toBe ""
|
|
|
|
expect(editor.lineForBufferRow(4)).toBe " var pivot = items.shift(), current, left = [], right = [];"
|
|
|
|
expect(editor.lineForBufferRow(5)).toBe " while(items.length > 0) {"
|
|
|
|
expect(editor.lineForBufferRow(6)).toBe " current = items.shift();"
|
|
|
|
expect(editor.lineForBufferRow(7)).toBe ""
|
|
|
|
expect(editor.lineForBufferRow(8)).toBe " current < pivot ? left.push(current) : right.push(current);"
|
|
|
|
expect(editor.lineForBufferRow(9)).toBe " }"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [4,0]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [8,0]
|
2012-03-24 01:20:54 +04:00
|
|
|
|
2012-03-27 04:03:17 +04:00
|
|
|
describe "when selections are on the same line", ->
|
2012-03-27 05:16:55 +04:00
|
|
|
beforeEach ->
|
2012-03-27 04:03:17 +04:00
|
|
|
editor.setSelectionBufferRange([[0,4], [0,13]])
|
|
|
|
editor.addSelectionForBufferRange([[0,22], [0,24]])
|
|
|
|
|
2012-03-27 05:16:55 +04:00
|
|
|
describe "when inserting characters other than newlines", ->
|
|
|
|
it "replaces each selection range with the inserted characters", ->
|
|
|
|
editor.insertText("x")
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
|
|
|
|
expect(cursor1.getScreenPosition()).toEqual [0, 5]
|
|
|
|
expect(cursor2.getScreenPosition()).toEqual [0, 15]
|
|
|
|
expect(selection1.isEmpty()).toBeTruthy()
|
|
|
|
expect(selection2.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
expect(editor.lineForBufferRow(0)).toBe "var x = functix () {"
|
|
|
|
|
|
|
|
describe "when inserting newlines", ->
|
|
|
|
it "replaces all selected ranges with newlines", ->
|
|
|
|
editor.insertText("\n")
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
2012-03-27 04:03:17 +04:00
|
|
|
|
2012-03-27 05:16:55 +04:00
|
|
|
expect(cursor1.getScreenPosition()).toEqual [1, 0]
|
|
|
|
expect(cursor2.getScreenPosition()).toEqual [2, 0]
|
|
|
|
expect(selection1.isEmpty()).toBeTruthy()
|
|
|
|
expect(selection2.isEmpty()).toBeTruthy()
|
2012-03-27 04:03:17 +04:00
|
|
|
|
2012-03-27 05:16:55 +04:00
|
|
|
expect(editor.lineForBufferRow(0)).toBe "var "
|
|
|
|
expect(editor.lineForBufferRow(1)).toBe " = functi"
|
|
|
|
expect(editor.lineForBufferRow(2)).toBe " () {"
|
2012-03-27 04:03:17 +04:00
|
|
|
|
2012-03-24 01:20:54 +04:00
|
|
|
describe "backspace", ->
|
|
|
|
describe "when cursors are on the same line", ->
|
|
|
|
it "removes the characters preceding each cursor", ->
|
|
|
|
editor.setCursorScreenPosition([3, 13])
|
|
|
|
editor.addCursorAtScreenPosition([3, 38])
|
|
|
|
|
|
|
|
editor.backspace()
|
|
|
|
|
|
|
|
expect(editor.lineForBufferRow(3)).toBe " var pivo = items.shift(), curren, left = [], right = [];"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 12]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [3, 36]
|
|
|
|
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
expect(selection1.isEmpty()).toBeTruthy()
|
|
|
|
expect(selection2.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
describe "when cursors are on different lines", ->
|
|
|
|
it "removes the characters preceding each cursor", ->
|
2012-03-24 01:23:02 +04:00
|
|
|
editor.setCursorScreenPosition([3, 13])
|
|
|
|
editor.addCursorAtScreenPosition([4, 10])
|
|
|
|
|
|
|
|
editor.backspace()
|
|
|
|
|
|
|
|
expect(editor.lineForBufferRow(3)).toBe " var pivo = items.shift(), current, left = [], right = [];"
|
|
|
|
expect(editor.lineForBufferRow(4)).toBe " whileitems.length > 0) {"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 12]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [4, 9]
|
|
|
|
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
expect(selection1.isEmpty()).toBeTruthy()
|
|
|
|
expect(selection2.isEmpty()).toBeTruthy()
|
2012-03-24 01:20:54 +04:00
|
|
|
|
|
|
|
describe "when backspacing over newlines", ->
|
|
|
|
it "removes the newlines preceding each cursor", ->
|
|
|
|
editor.setCursorScreenPosition([3, 0])
|
|
|
|
editor.addCursorAtScreenPosition([6, 0])
|
|
|
|
|
|
|
|
editor.backspace()
|
|
|
|
expect(editor.lineForBufferRow(2)).toBe " if (items.length <= 1) return items; var pivot = items.shift(), current, left = [], right = [];"
|
|
|
|
expect(editor.lineForBufferRow(3)).toBe " while(items.length > 0) {"
|
|
|
|
expect(editor.lineForBufferRow(4)).toBe " current = items.shift(); current < pivot ? left.push(current) : right.push(current);"
|
|
|
|
expect(editor.lineForBufferRow(5)).toBe " }"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [2,40]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [4,30]
|
2012-03-23 22:55:55 +04:00
|
|
|
|
2012-03-27 06:39:09 +04:00
|
|
|
describe "when selections are on the same line", ->
|
|
|
|
it "removes all selected text", ->
|
|
|
|
editor.setSelectionBufferRange([[0,4], [0,13]])
|
2012-03-27 20:06:59 +04:00
|
|
|
editor.addSelectionForBufferRange([[0,16], [0,24]])
|
2012-03-27 06:39:09 +04:00
|
|
|
|
|
|
|
editor.backspace()
|
|
|
|
|
2012-03-27 20:06:59 +04:00
|
|
|
expect(editor.lineForBufferRow(0)).toBe 'var = () {'
|
2012-03-27 06:39:09 +04:00
|
|
|
|
|
|
|
describe "delete", ->
|
|
|
|
describe "when cursors are on the same line", ->
|
|
|
|
it "removes the characters following each cursor", ->
|
|
|
|
editor.setCursorScreenPosition([3, 13])
|
|
|
|
editor.addCursorAtScreenPosition([3, 38])
|
|
|
|
|
|
|
|
editor.delete()
|
|
|
|
|
|
|
|
expect(editor.lineForBufferRow(3)).toBe " var pivot= items.shift(), current left = [], right = [];"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 13]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [3, 37]
|
|
|
|
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
expect(selection1.isEmpty()).toBeTruthy()
|
|
|
|
expect(selection2.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
describe "when cursors are on different lines", ->
|
|
|
|
it "removes the characters following each cursor", ->
|
|
|
|
editor.setCursorScreenPosition([3, 13])
|
|
|
|
editor.addCursorAtScreenPosition([4, 10])
|
|
|
|
|
|
|
|
editor.delete()
|
|
|
|
|
|
|
|
expect(editor.lineForBufferRow(3)).toBe " var pivot= items.shift(), current, left = [], right = [];"
|
|
|
|
expect(editor.lineForBufferRow(4)).toBe " while(tems.length > 0) {"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 13]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [4, 10]
|
|
|
|
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
expect(selection1.isEmpty()).toBeTruthy()
|
|
|
|
expect(selection2.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
describe "when deleting over newlines", ->
|
|
|
|
it "removes the newlines following each cursor", ->
|
|
|
|
editor.setCursorScreenPosition([0, 29])
|
|
|
|
editor.addCursorAtScreenPosition([1, 30])
|
|
|
|
|
|
|
|
editor.delete()
|
|
|
|
|
|
|
|
expect(editor.lineForBufferRow(0)).toBe "var quicksort = function () { var sort = function(items) { if (items.length <= 1) return items;"
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,29]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [0,59]
|
|
|
|
|
2012-03-27 20:12:58 +04:00
|
|
|
describe "when selections are on the same line", ->
|
|
|
|
it "removes all selected text", ->
|
|
|
|
editor.setSelectionBufferRange([[0,4], [0,13]])
|
|
|
|
editor.addSelectionForBufferRange([[0,16], [0,24]])
|
|
|
|
|
|
|
|
editor.delete()
|
|
|
|
|
|
|
|
expect(editor.lineForBufferRow(0)).toBe 'var = () {'
|
|
|
|
|
2012-03-26 22:20:09 +04:00
|
|
|
describe "keyboard movement", ->
|
2012-03-24 02:17:04 +04:00
|
|
|
it "moves all cursors", ->
|
|
|
|
editor.setCursorScreenPosition([3, 13])
|
|
|
|
editor.addCursorAtScreenPosition([3, 38])
|
|
|
|
editor.addCursorAtScreenPosition([4, 1])
|
|
|
|
[cursor1, cursor2, cursor3] = editor.compositeCursor.getCursors()
|
|
|
|
|
|
|
|
editor.moveCursorLeft()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 12]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [3, 37]
|
|
|
|
expect(cursor3.getBufferPosition()).toEqual [4, 0]
|
|
|
|
|
|
|
|
editor.moveCursorLeft()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 11]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [3, 36]
|
|
|
|
expect(cursor3.getBufferPosition()).toEqual [3, 62]
|
|
|
|
|
|
|
|
editor.moveCursorRight()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 12]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [3, 37]
|
|
|
|
expect(cursor3.getBufferPosition()).toEqual [4, 0]
|
|
|
|
|
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [4, 12]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [4, 29]
|
|
|
|
expect(cursor3.getBufferPosition()).toEqual [5, 0]
|
|
|
|
|
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [3, 12]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [3, 37]
|
|
|
|
expect(cursor3.getBufferPosition()).toEqual [4, 0]
|
|
|
|
|
2012-03-26 22:20:09 +04:00
|
|
|
describe "selections", ->
|
2012-03-27 22:09:35 +04:00
|
|
|
describe "upon clicking and dragging with the meta-key held down", ->
|
|
|
|
it "adds an additional selection upon clicking and dragging with the meta-key held down", ->
|
|
|
|
editor.attachToDom()
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 10])
|
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [5, 27])
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-03-27 22:09:35 +04:00
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [6, 10], metaKey: true)
|
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [8, 27], metaKey: true)
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-03-27 22:09:35 +04:00
|
|
|
|
|
|
|
selections = editor.compositeSelection.getSelections()
|
|
|
|
expect(selections.length).toBe 2
|
|
|
|
[selection1, selection2] = selections
|
|
|
|
expect(selection1.getScreenRange()).toEqual [[4, 10], [5, 27]]
|
|
|
|
expect(selection2.getScreenRange()).toEqual [[6, 10], [8, 27]]
|
|
|
|
|
2012-03-27 22:52:55 +04:00
|
|
|
it "merges selections when they intersect, maintaining the directionality of the newest selection", ->
|
2012-03-26 23:41:36 +04:00
|
|
|
editor.attachToDom()
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 10])
|
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [5, 27])
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-03-26 23:41:36 +04:00
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [3, 10], metaKey: true)
|
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [6, 27], metaKey: true)
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-03-26 23:41:36 +04:00
|
|
|
|
|
|
|
selections = editor.compositeSelection.getSelections()
|
|
|
|
expect(selections.length).toBe 1
|
|
|
|
[selection1] = selections
|
|
|
|
expect(selection1.getScreenRange()).toEqual [[3, 10], [6, 27]]
|
2012-03-27 22:52:55 +04:00
|
|
|
expect(selection1.isReversed()).toBeFalsy()
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [7, 4], metaKey: true)
|
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [4, 11], metaKey: true)
|
|
|
|
editor.renderedLines.trigger 'mouseup'
|
2012-03-27 22:52:55 +04:00
|
|
|
|
|
|
|
selections = editor.compositeSelection.getSelections()
|
|
|
|
expect(selections.length).toBe 1
|
|
|
|
[selection1] = selections
|
|
|
|
expect(selection1.getScreenRange()).toEqual [[3, 10], [7, 4]]
|
|
|
|
expect(selection1.isReversed()).toBeTruthy()
|
2012-03-26 23:41:36 +04:00
|
|
|
|
2012-03-27 22:09:35 +04:00
|
|
|
describe "upon moving the cursor with the arrow keys with the shift key held down", ->
|
|
|
|
it "resizes all selections", ->
|
|
|
|
editor.setSelectionBufferRange [[0,9], [0,13]]
|
|
|
|
editor.addSelectionForBufferRange [[3,16], [3,21]]
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
|
|
|
|
editor.selectRight()
|
|
|
|
expect(selection1.getBufferRange()).toEqual [[0,9], [0,14]]
|
|
|
|
expect(selection2.getBufferRange()).toEqual [[3,16], [3,22]]
|
|
|
|
|
|
|
|
editor.selectLeft()
|
|
|
|
editor.selectLeft()
|
|
|
|
expect(selection1.getBufferRange()).toEqual [[0,9], [0,12]]
|
|
|
|
expect(selection2.getBufferRange()).toEqual [[3,16], [3,20]]
|
|
|
|
|
|
|
|
editor.selectDown()
|
|
|
|
expect(selection1.getBufferRange()).toEqual [[0,9], [1,12]]
|
|
|
|
expect(selection2.getBufferRange()).toEqual [[3,16], [4,20]]
|
|
|
|
|
|
|
|
editor.selectUp()
|
|
|
|
expect(selection1.getBufferRange()).toEqual [[0,9], [0,12]]
|
|
|
|
expect(selection2.getBufferRange()).toEqual [[3,16], [3,20]]
|
|
|
|
|
|
|
|
it "merges selections when they intersect when moving down", ->
|
|
|
|
editor.setSelectionBufferRange [[0,9], [0,13]]
|
|
|
|
editor.addSelectionForBufferRange [[1,10], [1,20]]
|
|
|
|
editor.addSelectionForBufferRange [[2,15], [3,25]]
|
|
|
|
[selection1, selection2, selection3] = editor.compositeSelection.getSelections()
|
|
|
|
|
|
|
|
editor.selectDown()
|
|
|
|
expect(editor.compositeSelection.getSelections()).toEqual [selection1]
|
|
|
|
expect(selection1.getScreenRange()).toEqual([[0, 9], [4, 25]])
|
2012-03-27 22:26:36 +04:00
|
|
|
expect(selection1.isReversed()).toBeFalsy()
|
2012-03-27 22:09:35 +04:00
|
|
|
expect(selection2.parent()).not.toExist()
|
|
|
|
expect(selection3.parent()).not.toExist()
|
|
|
|
|
|
|
|
it "merges selections when they intersect when moving up", ->
|
|
|
|
editor.setSelectionBufferRange [[0,9], [0,13]], reverse: true
|
|
|
|
editor.addSelectionForBufferRange [[1,10], [1,20]], reverse: true
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
|
|
|
|
editor.selectUp()
|
|
|
|
expect(editor.compositeSelection.getSelections()).toEqual [selection1]
|
|
|
|
expect(selection1.getScreenRange()).toEqual([[0, 0], [1, 20]])
|
2012-03-27 22:26:36 +04:00
|
|
|
expect(selection1.isReversed()).toBeTruthy()
|
2012-03-27 22:09:35 +04:00
|
|
|
expect(selection2.parent()).not.toExist()
|
|
|
|
|
|
|
|
it "merges selections when they intersect when moving left", ->
|
|
|
|
editor.setSelectionBufferRange [[0,9], [0,13]], reverse: true
|
|
|
|
editor.addSelectionForBufferRange [[0,14], [1,20]], reverse: true
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
|
|
|
|
editor.selectLeft()
|
|
|
|
expect(editor.compositeSelection.getSelections()).toEqual [selection1]
|
|
|
|
expect(selection1.getScreenRange()).toEqual([[0, 8], [1, 20]])
|
2012-03-27 22:26:36 +04:00
|
|
|
expect(selection1.isReversed()).toBeTruthy()
|
2012-03-27 22:09:35 +04:00
|
|
|
expect(selection2.parent()).not.toExist()
|
|
|
|
|
|
|
|
it "merges selections when they intersect when moving right", ->
|
|
|
|
editor.setSelectionBufferRange [[0,9], [0,13]]
|
|
|
|
editor.addSelectionForBufferRange [[0,14], [1,20]]
|
|
|
|
[selection1, selection2] = editor.compositeSelection.getSelections()
|
|
|
|
|
|
|
|
editor.selectRight()
|
|
|
|
expect(editor.compositeSelection.getSelections()).toEqual [selection1]
|
|
|
|
expect(selection1.getScreenRange()).toEqual([[0, 9], [1, 21]])
|
2012-03-27 22:26:36 +04:00
|
|
|
expect(selection1.isReversed()).toBeFalsy()
|
2012-03-27 22:09:35 +04:00
|
|
|
expect(selection2.parent()).not.toExist()
|
|
|
|
|
2012-03-26 22:20:09 +04:00
|
|
|
describe "cursor merging", ->
|
|
|
|
it "merges cursors when they overlap due to a buffer change", ->
|
|
|
|
editor.setCursorScreenPosition([0, 0])
|
|
|
|
editor.addCursorAtScreenPosition([0, 1])
|
|
|
|
editor.addCursorAtScreenPosition([1, 1])
|
|
|
|
|
|
|
|
[cursor1, cursor2, cursor3] = editor.compositeCursor.getCursors()
|
|
|
|
expect(editor.compositeCursor.getCursors().length).toBe 3
|
|
|
|
|
|
|
|
editor.backspace()
|
|
|
|
expect(editor.compositeCursor.getCursors().length).toBe 2
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,0]
|
|
|
|
expect(cursor3.getBufferPosition()).toEqual [1,0]
|
|
|
|
expect(cursor2.parent().length).toBe 0
|
|
|
|
|
|
|
|
editor.insertText "x"
|
|
|
|
expect(editor.lineForBufferRow(0)).toBe "xar quicksort = function () {"
|
|
|
|
expect(editor.lineForBufferRow(1)).toBe "x var sort = function(items) {"
|
|
|
|
|
|
|
|
it "merges cursors when they overlap due to movement", ->
|
|
|
|
editor.setCursorScreenPosition([0, 0])
|
|
|
|
editor.addCursorAtScreenPosition([0, 1])
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
editor.moveCursorLeft()
|
|
|
|
expect(editor.compositeCursor.getCursors().length).toBe 1
|
|
|
|
expect(cursor2.parent()).not.toExist()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,0]
|
|
|
|
|
|
|
|
editor.addCursorAtScreenPosition([1, 0])
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
|
|
|
|
editor.moveCursorUp()
|
|
|
|
expect(editor.compositeCursor.getCursors().length).toBe 1
|
|
|
|
expect(cursor2.parent()).not.toExist()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [0,0]
|
|
|
|
|
|
|
|
editor.setCursorScreenPosition([12, 2])
|
|
|
|
editor.addCursorAtScreenPosition([12, 1])
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
|
|
|
|
editor.moveCursorRight()
|
|
|
|
expect(editor.compositeCursor.getCursors().length).toBe 1
|
|
|
|
expect(cursor2.parent()).not.toExist()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [12,2]
|
|
|
|
|
|
|
|
editor.addCursorAtScreenPosition([11, 2])
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
|
|
|
|
|
|
|
editor.moveCursorDown()
|
|
|
|
expect(editor.compositeCursor.getCursors().length).toBe 1
|
|
|
|
expect(cursor2.parent()).not.toExist()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [12,2]
|
|
|
|
|
|
|
|
it "merges cursors when the mouse is clicked without the meta-key", ->
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.setCursorScreenPosition([0, 0])
|
|
|
|
editor.addCursorAtScreenPosition([0, 1])
|
|
|
|
|
|
|
|
[cursor1, cursor2] = editor.compositeCursor.getCursors()
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousedownEvent(editor: editor, point: [4, 7])
|
2012-03-26 22:20:09 +04:00
|
|
|
expect(editor.compositeCursor.getCursors().length).toBe 1
|
|
|
|
expect(cursor2.parent()).not.toExist()
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [4, 7]
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
editor.renderedLines.trigger mousemoveEvent(editor: editor, point: [5, 27])
|
2012-03-26 22:20:09 +04:00
|
|
|
|
|
|
|
selections = editor.compositeSelection.getSelections()
|
|
|
|
expect(selections.length).toBe 1
|
|
|
|
expect(selections[0].getBufferRange()).toEqual [[4,7], [5,27]]
|
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
describe "buffer manipulation", ->
|
2012-05-10 05:19:54 +04:00
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
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
|
|
|
|
2012-03-27 02:31:47 +04:00
|
|
|
expect(buffer.lineForRow(1).charAt(6)).not.toBe 'q'
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
editor.hiddenInput.textInput 'q'
|
|
|
|
|
2012-03-27 02:31:47 +04:00
|
|
|
expect(buffer.lineForRow(1).charAt(6)).toBe 'q'
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual(row: 1, column: 7)
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(1)')).toHaveText buffer.lineForRow(1)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
2012-03-19 19:04:39 +04:00
|
|
|
it "does not update the cursor position if the editor is not focused", ->
|
|
|
|
editor.isFocused = false
|
|
|
|
editor.buffer.insert([5, 0], 'blah')
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, 0]
|
|
|
|
|
2012-02-01 06:28:25 +04:00
|
|
|
describe "when there is a selection", ->
|
|
|
|
it "replaces the selected text with the typed text", ->
|
2012-04-06 03:22:16 +04:00
|
|
|
editor.setSelectionBufferRange(new Range([1, 6], [2, 4]))
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.hiddenInput.textInput 'q'
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(1)).toBe ' var qif (items.length <= 1) return items;'
|
2012-02-01 06:28:25 +04:00
|
|
|
|
2012-04-06 03:22:16 +04:00
|
|
|
it "always places the cursor after the selection", ->
|
|
|
|
editor.setSelectionBufferRange(new Range([1, 6], [2, 4]), reverse: true)
|
|
|
|
editor.hiddenInput.textInput 'q'
|
|
|
|
expect(buffer.lineForRow(1)).toBe ' var qif (items.length <= 1) return items;'
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [1, 7]
|
|
|
|
|
2012-04-06 03:29:42 +04:00
|
|
|
describe "return", ->
|
2012-02-01 06:28:25 +04:00
|
|
|
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-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.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-06-05 04:53:58 +04:00
|
|
|
originalLine = editor.renderedLines.find('.line:eq(1)').text()
|
|
|
|
lineBelowOriginalLine = editor.renderedLines.find('.line:eq(2)').text()
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('enter')
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(1)')).toHaveText originalLine[0...6]
|
|
|
|
expect(editor.renderedLines.find('.line:eq(2)')).toHaveText originalLine[6..]
|
|
|
|
expect(editor.renderedLines.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-03-06 03:06:27 +04:00
|
|
|
editor.setCursorScreenPosition(row: 1, column: buffer.lineForRow(1).length)
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
editor.trigger keydownEvent('enter')
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.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
|
|
|
|
2012-06-05 22:29:40 +04:00
|
|
|
describe "insert-newline-below", ->
|
|
|
|
it "inserts a newline below the cursor, autoindents it, and moves the cursor to the end of the line", ->
|
|
|
|
editor.autoIndent = true
|
|
|
|
editor.trigger "newline-below"
|
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "var quicksort = function () {"
|
|
|
|
expect(editor.buffer.lineForRow(1)).toBe " "
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [1,2]
|
|
|
|
|
2012-04-06 03:29:42 +04:00
|
|
|
describe "backspace", ->
|
2012-02-01 06:28:25 +04:00
|
|
|
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-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(1)).toBe " var sort = function(items) {"
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
editor.trigger keydownEvent('backspace')
|
|
|
|
|
2012-03-06 03:06:27 +04:00
|
|
|
line = buffer.lineForRow(1)
|
2012-02-01 06:28:25 +04:00
|
|
|
expect(line).toBe " var ort = function(items) {"
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.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", ->
|
2012-03-06 03:06:27 +04:00
|
|
|
originalLine0 = buffer.lineForRow(0)
|
2012-02-01 06:28:25 +04:00
|
|
|
expect(originalLine0).toBe "var quicksort = function () {"
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(1)).toBe " var sort = function(items) {"
|
2012-02-01 06:28:25 +04:00
|
|
|
|
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')
|
|
|
|
|
2012-03-06 03:06:27 +04:00
|
|
|
line0 = buffer.lineForRow(0)
|
|
|
|
line1 = buffer.lineForRow(1)
|
2012-02-01 06:28:25 +04:00
|
|
|
expect(line0).toBe "var quicksort = function () { var sort = function(items) {"
|
|
|
|
expect(line1).toBe " if (items.length <= 1) return items;"
|
|
|
|
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(0)')).toHaveText line0
|
|
|
|
expect(editor.renderedLines.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-03-23 02:08:20 +04:00
|
|
|
editor.getSelection().setBufferRange(new Range([0,5], [0,9]))
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('backspace')
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(editor.buffer.lineForRow(0)).toBe 'var qsort = function () {'
|
2012-02-01 06:28:25 +04:00
|
|
|
|
2012-03-29 22:33:15 +04:00
|
|
|
describe "backspace-to-beginning-of-word", ->
|
2012-03-30 02:32:37 +04:00
|
|
|
describe "when no text is selected", ->
|
|
|
|
it "deletes all text between the cursor and the beginning of the word", ->
|
|
|
|
editor.setCursorBufferPosition([1, 24])
|
|
|
|
editor.addCursorAtBufferPosition([2, 5])
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
2012-03-29 22:33:15 +04:00
|
|
|
|
2012-03-30 02:32:37 +04:00
|
|
|
editor.trigger 'backspace-to-beginning-of-word'
|
|
|
|
expect(buffer.lineForRow(1)).toBe ' var sort = function(ems) {'
|
|
|
|
expect(buffer.lineForRow(2)).toBe ' f (items.length <= 1) return items;'
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [1, 22]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [2, 4]
|
2012-03-29 22:33:15 +04:00
|
|
|
|
2012-03-30 02:32:37 +04:00
|
|
|
editor.trigger 'backspace-to-beginning-of-word'
|
|
|
|
expect(buffer.lineForRow(1)).toBe ' var sort = functionems) f (items.length <= 1) return items;'
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [1, 21]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [1, 26]
|
2012-03-29 22:33:15 +04:00
|
|
|
|
|
|
|
describe "when text is selected", ->
|
|
|
|
it "deletes only selected text", ->
|
|
|
|
editor.setSelectionBufferRange([[1, 24], [1, 27]])
|
|
|
|
editor.trigger 'backspace-to-beginning-of-word'
|
|
|
|
expect(buffer.lineForRow(1)).toBe ' var sort = function(it) {'
|
|
|
|
|
2012-04-06 03:29:42 +04:00
|
|
|
describe "delete", ->
|
2012-02-01 06:28:25 +04:00
|
|
|
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')
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(1)).toBe ' var ort = function(items) {'
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when the cursor is on the end of a line", ->
|
|
|
|
it "joins the line with the following line", ->
|
2012-03-06 03:06:27 +04:00
|
|
|
editor.setCursorScreenPosition([1, buffer.lineForRow(1).length])
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('delete')
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(1)).toBe ' var sort = function(items) { if (items.length <= 1) return items;'
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when there is a selection", ->
|
|
|
|
it "deletes the selection, but not the character following it", ->
|
2012-03-23 02:08:20 +04:00
|
|
|
editor.getSelection().setBufferRange(new Range([1,6], [1,8]))
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent 'delete'
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(1)).toBe ' var rt = function(items) {'
|
2012-02-01 06:28:25 +04:00
|
|
|
|
|
|
|
describe "when the cursor is on the last column of the last line", ->
|
|
|
|
it "does nothing, but doesn't raise an error", ->
|
2012-03-06 03:06:27 +04:00
|
|
|
editor.setCursorScreenPosition([12, buffer.lineForRow(12).length])
|
2012-02-01 06:28:25 +04:00
|
|
|
editor.trigger keydownEvent('delete')
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(12)).toBe '};'
|
2012-02-01 06:28:25 +04:00
|
|
|
|
2012-04-06 03:29:42 +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.lineForRow(6))
|
|
|
|
|
2012-03-30 02:32:37 +04:00
|
|
|
describe "delete-to-end-of-word", ->
|
|
|
|
describe "when no text is selected", ->
|
|
|
|
it "deletes to the end of the word", ->
|
|
|
|
editor.setCursorBufferPosition([1, 24])
|
|
|
|
editor.addCursorAtBufferPosition([2, 5])
|
|
|
|
[cursor1, cursor2] = editor.getCursors()
|
|
|
|
|
|
|
|
editor.trigger 'delete-to-end-of-word'
|
|
|
|
expect(buffer.lineForRow(1)).toBe ' var sort = function(it) {'
|
|
|
|
expect(buffer.lineForRow(2)).toBe ' i (items.length <= 1) return items;'
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [1, 24]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [2, 5]
|
|
|
|
|
|
|
|
editor.trigger 'delete-to-end-of-word'
|
|
|
|
expect(buffer.lineForRow(1)).toBe ' var sort = function(it {'
|
|
|
|
expect(buffer.lineForRow(2)).toBe ' iitems.length <= 1) return items;'
|
|
|
|
expect(cursor1.getBufferPosition()).toEqual [1, 24]
|
|
|
|
expect(cursor2.getBufferPosition()).toEqual [2, 5]
|
|
|
|
|
|
|
|
describe "when text is selected", ->
|
|
|
|
it "deletes only selected text", ->
|
|
|
|
editor.setSelectionBufferRange([[1, 24], [1, 27]])
|
|
|
|
editor.trigger 'delete-to-end-of-word'
|
|
|
|
expect(buffer.lineForRow(1)).toBe ' var sort = function(it) {'
|
|
|
|
|
2012-04-09 22:34:30 +04:00
|
|
|
describe "cut-to-end-of-line", ->
|
|
|
|
pasteboard = null
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
spyOn($native, 'writeToPasteboard').andCallFake (text) -> pasteboard = text
|
|
|
|
spyOn($native, 'readFromPasteboard').andCallFake -> pasteboard
|
|
|
|
|
|
|
|
describe "when nothing is selected", ->
|
|
|
|
it "cuts up to the end of the line", ->
|
|
|
|
editor.setCursorBufferPosition([2, 20])
|
|
|
|
editor.addCursorAtBufferPosition([3, 20])
|
|
|
|
editor.trigger 'cut-to-end-of-line'
|
|
|
|
|
|
|
|
expect(buffer.lineForRow(2)).toBe ' if (items.length'
|
|
|
|
expect(buffer.lineForRow(3)).toBe ' var pivot = item'
|
|
|
|
|
|
|
|
expect(pasteboard).toBe ' <= 1) return items;\ns.shift(), current, left = [], right = [];'
|
|
|
|
|
|
|
|
describe "when text is selected", ->
|
|
|
|
it "only cuts the selected text, not to the end of the line", ->
|
|
|
|
editor.setSelectedBufferRanges([[[2,20], [2, 30]], [[3, 20], [3, 20]]])
|
|
|
|
|
|
|
|
editor.trigger 'cut-to-end-of-line'
|
|
|
|
|
|
|
|
expect(buffer.lineForRow(2)).toBe ' if (items.lengthurn items;'
|
|
|
|
expect(buffer.lineForRow(3)).toBe ' var pivot = item'
|
|
|
|
|
|
|
|
expect(pasteboard).toBe ' <= 1) ret\ns.shift(), current, left = [], right = [];'
|
|
|
|
|
2012-04-06 03:39:40 +04:00
|
|
|
describe "tab", ->
|
|
|
|
describe "if editor.softTabs is true (the default)", ->
|
2012-04-06 03:55:15 +04:00
|
|
|
it "inserts editor.tabText into the buffer", ->
|
|
|
|
tabRegex = new RegExp("^#{editor.tabText}")
|
2012-04-06 03:39:40 +04:00
|
|
|
expect(buffer.lineForRow(0)).not.toMatch(tabRegex)
|
|
|
|
editor.trigger 'tab'
|
|
|
|
expect(buffer.lineForRow(0)).toMatch(tabRegex)
|
|
|
|
|
|
|
|
describe "if editor.softTabs is false", ->
|
|
|
|
it "inserts a tab character into the buffer", ->
|
|
|
|
editor.softTabs = false
|
|
|
|
expect(buffer.lineForRow(0)).not.toMatch(/^\t/)
|
|
|
|
editor.trigger 'tab'
|
|
|
|
expect(buffer.lineForRow(0)).toMatch(/^\t/)
|
2012-04-06 23:03:30 +04:00
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [0, 1]
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, editor.tabText.length]
|
2012-04-06 03:39:40 +04:00
|
|
|
|
2012-04-07 01:06:33 +04:00
|
|
|
editor.trigger 'tab'
|
|
|
|
expect(buffer.lineForRow(0)).toMatch(/^\t\t/)
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [0, 2]
|
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [0, editor.tabText.length * 2]
|
|
|
|
|
2012-04-06 03:29:42 +04:00
|
|
|
describe "undo/redo", ->
|
2012-02-07 23:10:14 +04:00
|
|
|
it "undoes/redoes the last change", ->
|
2012-02-07 22:22:19 +04:00
|
|
|
buffer.insert [0, 0], "foo"
|
|
|
|
editor.trigger 'undo'
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(0)).not.toContain "foo"
|
2012-02-07 22:22:19 +04:00
|
|
|
|
2012-02-07 23:10:14 +04:00
|
|
|
editor.trigger 'redo'
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(buffer.lineForRow(0)).toContain "foo"
|
2012-02-07 23:10:14 +04:00
|
|
|
|
2012-04-05 00:21:03 +04:00
|
|
|
it "batches the undo / redo of changes caused by multiple cursors", ->
|
|
|
|
editor.setCursorScreenPosition([0, 0])
|
|
|
|
editor.addCursorAtScreenPosition([1, 0])
|
|
|
|
|
|
|
|
editor.insertText("foo")
|
|
|
|
editor.backspace()
|
|
|
|
|
|
|
|
expect(buffer.lineForRow(0)).toContain "fovar"
|
|
|
|
expect(buffer.lineForRow(1)).toContain "fo "
|
|
|
|
|
|
|
|
editor.trigger 'undo'
|
|
|
|
|
|
|
|
expect(buffer.lineForRow(0)).toContain "foo"
|
|
|
|
expect(buffer.lineForRow(1)).toContain "foo"
|
|
|
|
|
|
|
|
editor.trigger 'undo'
|
|
|
|
|
|
|
|
expect(buffer.lineForRow(0)).not.toContain "foo"
|
|
|
|
expect(buffer.lineForRow(1)).not.toContain "foo"
|
|
|
|
|
2012-04-05 04:04:17 +04:00
|
|
|
it "restores the selected ranges after undo", ->
|
|
|
|
editor.setSelectedBufferRanges([[[1, 6], [1, 10]], [[1, 22], [1, 27]]])
|
|
|
|
editor.delete()
|
|
|
|
editor.delete()
|
|
|
|
|
|
|
|
selections = editor.getSelections()
|
|
|
|
expect(buffer.lineForRow(1)).toBe ' var = function( {'
|
|
|
|
expect(selections[0].getBufferRange()).toEqual [[1, 6], [1, 6]]
|
|
|
|
expect(selections[1].getBufferRange()).toEqual [[1, 17], [1, 17]]
|
|
|
|
|
|
|
|
editor.trigger 'undo'
|
|
|
|
expect(selections[0].getBufferRange()).toEqual [[1, 6], [1, 6]]
|
|
|
|
expect(selections[1].getBufferRange()).toEqual [[1, 18], [1, 18]]
|
|
|
|
|
|
|
|
editor.trigger 'undo'
|
|
|
|
expect(selections[0].getBufferRange()).toEqual [[1, 6], [1, 10]]
|
|
|
|
expect(selections[1].getBufferRange()).toEqual [[1, 22], [1, 27]]
|
|
|
|
|
|
|
|
editor.trigger 'redo'
|
|
|
|
expect(selections[0].getBufferRange()).toEqual [[1, 6], [1, 6]]
|
|
|
|
expect(selections[1].getBufferRange()).toEqual [[1, 18], [1, 18]]
|
2012-04-05 00:21:03 +04:00
|
|
|
|
2012-04-05 04:27:34 +04:00
|
|
|
it "restores the selected ranges after redo", ->
|
|
|
|
editor.setSelectedBufferRanges([[[1, 6], [1, 10]], [[1, 22], [1, 27]]])
|
|
|
|
selections = editor.getSelections()
|
|
|
|
|
|
|
|
editor.insertText("booboo")
|
|
|
|
expect(selections[0].getBufferRange()).toEqual [[1, 12], [1, 12]]
|
|
|
|
expect(selections[1].getBufferRange()).toEqual [[1, 30], [1, 30]]
|
|
|
|
|
|
|
|
editor.undo()
|
|
|
|
editor.redo()
|
|
|
|
|
|
|
|
expect(selections[0].getBufferRange()).toEqual [[1, 12], [1, 12]]
|
|
|
|
expect(selections[1].getBufferRange()).toEqual [[1, 30], [1, 30]]
|
|
|
|
|
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()
|
2012-03-28 21:17:46 +04:00
|
|
|
expect(editor.find('.cursor').offset()).toEqual pagePixelPositionForPoint(editor, [2, 2])
|
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-03-14 05:20:40 +04:00
|
|
|
it "unsubscribes from the buffer when it is removed from the dom", ->
|
|
|
|
buffer = new Buffer
|
|
|
|
previousSubscriptionCount = buffer.subscriptionCount()
|
|
|
|
|
|
|
|
editor.attachToDom()
|
|
|
|
editor.setBuffer(buffer)
|
|
|
|
|
|
|
|
expect(buffer.subscriptionCount()).toBeGreaterThan previousSubscriptionCount
|
|
|
|
expect($('.editor')).toExist()
|
|
|
|
editor.remove()
|
|
|
|
expect(buffer.subscriptionCount()).toBe previousSubscriptionCount
|
|
|
|
expect($('.editor')).not.toExist()
|
|
|
|
|
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-03-19 19:04:39 +04:00
|
|
|
describe "when the hidden input is focused / unfocused", ->
|
2012-03-19 19:31:03 +04:00
|
|
|
it "assigns the isFocused flag on the editor and also adds/removes the .focused css class", ->
|
2012-03-19 19:04:39 +04:00
|
|
|
editor.attachToDom()
|
|
|
|
editor.isFocused = false
|
|
|
|
editor.hiddenInput.focus()
|
|
|
|
expect(editor.isFocused).toBeTruthy()
|
2012-03-19 19:31:03 +04:00
|
|
|
expect(editor).toHaveClass('focused')
|
2012-03-19 19:04:39 +04:00
|
|
|
|
|
|
|
editor.hiddenInput.focusout()
|
|
|
|
expect(editor.isFocused).toBeFalsy()
|
2012-03-19 19:31:03 +04:00
|
|
|
expect(editor).not.toHaveClass('focused')
|
2012-03-19 19:04:39 +04:00
|
|
|
|
2012-02-02 05:46:22 +04:00
|
|
|
describe "cut, copy & paste", ->
|
2012-03-27 03:24:20 +04:00
|
|
|
pasteboard = null
|
2012-02-02 21:35:18 +04:00
|
|
|
beforeEach ->
|
2012-03-27 03:24:20 +04:00
|
|
|
pasteboard = 'first'
|
|
|
|
spyOn($native, 'writeToPasteboard').andCallFake (text) -> pasteboard = text
|
|
|
|
spyOn($native, 'readFromPasteboard').andCallFake -> pasteboard
|
|
|
|
|
|
|
|
describe "with a single selection", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.setSelectionBufferRange([[0, 4], [0, 13]])
|
|
|
|
|
|
|
|
describe "when a cut event is triggered", ->
|
|
|
|
it "removes the selected text from the buffer and places it on the pasteboard", ->
|
|
|
|
editor.trigger "cut"
|
|
|
|
expect(buffer.lineForRow(0)).toBe "var = function () {"
|
|
|
|
expect($native.readFromPasteboard()).toBe 'quicksort'
|
|
|
|
|
|
|
|
describe "when a copy event is triggered", ->
|
|
|
|
it "copies selected text onto the clipboard", ->
|
|
|
|
editor.trigger "copy"
|
|
|
|
expect(buffer.lineForRow(0)).toBe "var quicksort = function () {"
|
|
|
|
expect($native.readFromPasteboard()).toBe 'quicksort'
|
|
|
|
|
|
|
|
describe "when a paste event is triggered", ->
|
|
|
|
it "pastes text into the buffer", ->
|
|
|
|
editor.trigger "paste"
|
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "var first = function () {"
|
|
|
|
|
|
|
|
describe "with multiple selections", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.setSelectionBufferRange([[0, 4], [0, 13]])
|
|
|
|
editor.addSelectionForBufferRange([[1, 6], [1, 10]])
|
|
|
|
|
|
|
|
describe "when a cut event is triggered", ->
|
|
|
|
it "removes the selected text from the buffer and places it on the pasteboard", ->
|
|
|
|
editor.trigger "cut"
|
|
|
|
expect(buffer.lineForRow(0)).toBe "var = function () {"
|
|
|
|
expect(buffer.lineForRow(1)).toBe " var = function(items) {"
|
|
|
|
|
|
|
|
expect($native.readFromPasteboard()).toBe 'quicksort\nsort'
|
|
|
|
|
|
|
|
describe "when a copy event is triggered", ->
|
|
|
|
it "copies selected text onto the clipboard", ->
|
|
|
|
editor.trigger "copy"
|
|
|
|
expect(buffer.lineForRow(0)).toBe "var quicksort = function () {"
|
|
|
|
expect(buffer.lineForRow(1)).toBe " var sort = function(items) {"
|
|
|
|
expect($native.readFromPasteboard()).toBe 'quicksort\nsort'
|
|
|
|
|
|
|
|
describe "when a paste event is triggered", ->
|
|
|
|
it "pastes text into the buffer", ->
|
|
|
|
editor.trigger "paste"
|
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "var first = function () {"
|
|
|
|
expect(buffer.lineForRow(1)).toBe " var first = function(items) {"
|
2012-01-29 05:00:59 +04:00
|
|
|
|
2012-05-31 02:43:21 +04:00
|
|
|
describe "structural folding", ->
|
|
|
|
describe "when a toggle-fold event is triggered", ->
|
|
|
|
it "creates/destroys a structual fold based on cursor position", ->
|
|
|
|
editor.setCursorBufferPosition([1,0])
|
|
|
|
|
|
|
|
editor.trigger "toggle-fold"
|
2012-05-31 03:55:15 +04:00
|
|
|
expect(editor.screenLineForRow(1).fold).toBeDefined()
|
2012-05-31 02:43:21 +04:00
|
|
|
|
|
|
|
editor.trigger "toggle-fold"
|
2012-05-31 03:55:15 +04:00
|
|
|
expect(editor.screenLineForRow(1).fold).toBeUndefined()
|
2012-05-31 02:43:21 +04:00
|
|
|
|
2012-06-04 20:44:20 +04:00
|
|
|
it "creates/destroys the largest fold containing the cursor position", ->
|
|
|
|
editor.trigger "fold-all"
|
|
|
|
editor.setCursorBufferPosition([5,1])
|
|
|
|
|
|
|
|
editor.trigger "toggle-fold"
|
|
|
|
expect(editor.screenLineForRow(0).fold).toBeUndefined()
|
|
|
|
expect(editor.screenLineForRow(1).fold).toBeDefined()
|
|
|
|
|
|
|
|
editor.trigger "toggle-fold"
|
|
|
|
expect(editor.screenLineForRow(0).fold).toBeUndefined()
|
|
|
|
expect(editor.screenLineForRow(1).fold).toBeUndefined()
|
|
|
|
expect(editor.screenLineForRow(4).fold).toBeDefined()
|
|
|
|
|
2012-06-01 21:48:35 +04:00
|
|
|
describe "when a fold-all event is triggered", ->
|
|
|
|
it "creates folds on every line that can be folded", ->
|
|
|
|
editor.setCursorBufferPosition([5,13])
|
|
|
|
|
|
|
|
editor.trigger "fold-all"
|
|
|
|
expect(editor.screenLineForRow(0).fold).toBeDefined()
|
|
|
|
expect(editor.screenLineForRow(1)).toBeUndefined()
|
|
|
|
|
2012-06-04 20:44:20 +04:00
|
|
|
it "maintains cursor buffer position when buffer is created/destroyed", ->
|
|
|
|
editor.setCursorBufferPosition([5,5])
|
|
|
|
editor.trigger "fold-all"
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual([5,5])
|
|
|
|
|
2012-05-31 02:43:21 +04:00
|
|
|
describe "primitive folding", ->
|
2012-05-10 05:19:54 +04:00
|
|
|
beforeEach ->
|
2012-05-19 02:15:44 +04:00
|
|
|
editor.setBuffer(new Buffer(require.resolve('fixtures/two-hundred.txt')))
|
2012-05-10 05:19:54 +04:00
|
|
|
editor.attachToDom()
|
|
|
|
|
2012-02-24 22:30:32 +04:00
|
|
|
describe "when a fold-selection event is triggered", ->
|
2012-05-19 05:22:56 +04:00
|
|
|
it "folds the lines covered by the selection into a single line with a fold class", ->
|
2012-03-23 02:08:20 +04:00
|
|
|
editor.getSelection().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-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(4)')).toHaveClass('fold')
|
|
|
|
expect(editor.renderedLines.find('.line:eq(5)').text()).toBe '8'
|
2012-02-29 06:46:41 +04:00
|
|
|
|
2012-03-23 02:08:20 +04:00
|
|
|
expect(editor.getSelection().isEmpty()).toBeTruthy()
|
2012-05-19 02:15:44 +04:00
|
|
|
expect(editor.getCursorScreenPosition()).toEqual [5, 0]
|
2012-02-24 22:30:32 +04:00
|
|
|
|
2012-05-22 04:55:58 +04:00
|
|
|
describe "when a fold placeholder line is clicked", ->
|
2012-05-22 05:35:51 +04:00
|
|
|
it "removes the associated fold and places the cursor at its beginning", ->
|
2012-05-22 04:55:58 +04:00
|
|
|
editor.getSelection().setBufferRange(new Range([3, 0], [9, 0]))
|
|
|
|
editor.trigger 'fold-selection'
|
2012-02-25 09:08:34 +04:00
|
|
|
|
2012-05-22 04:55:58 +04:00
|
|
|
editor.find('.fold.line').mousedown()
|
2012-02-25 09:08:34 +04:00
|
|
|
|
2012-05-22 04:55:58 +04:00
|
|
|
expect(editor.find('.fold')).not.toExist()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(4)').text()).toMatch /4-+/
|
|
|
|
expect(editor.renderedLines.find('.line:eq(5)').text()).toMatch /5/
|
2012-03-08 00:43:29 +04:00
|
|
|
|
2012-05-22 04:55:58 +04:00
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
2012-02-27 22:22:20 +04:00
|
|
|
|
2012-05-25 23:35:32 +04:00
|
|
|
describe "when the unfold event is triggered when the cursor is on a fold placeholder line", ->
|
2012-02-29 06:53:02 +04:00
|
|
|
it "removes the associated fold and places the cursor at its beginning", ->
|
2012-05-22 20:38:14 +04:00
|
|
|
editor.getSelection().setBufferRange(new Range([3, 0], [9, 0]))
|
2012-02-29 06:46:41 +04:00
|
|
|
editor.trigger 'fold-selection'
|
|
|
|
|
2012-05-22 20:38:14 +04:00
|
|
|
editor.setCursorBufferPosition([3,0])
|
|
|
|
editor.trigger 'unfold'
|
|
|
|
|
|
|
|
expect(editor.find('.fold')).not.toExist()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.line:eq(4)').text()).toMatch /4-+/
|
|
|
|
expect(editor.renderedLines.find('.line:eq(5)').text()).toMatch /5/
|
2012-05-22 20:38:14 +04:00
|
|
|
|
|
|
|
expect(editor.getCursorBufferPosition()).toEqual [3, 0]
|
|
|
|
|
2012-05-25 03:39:14 +04:00
|
|
|
describe "when a selection starts/stops intersecting a fold", ->
|
2012-05-25 23:35:32 +04:00
|
|
|
it "adds/removes the 'selected' class to the fold's line element and hides the cursor if it is on the fold line", ->
|
2012-05-25 03:39:14 +04:00
|
|
|
editor.createFold(2, 4)
|
|
|
|
|
|
|
|
editor.setSelectionBufferRange([[1, 0], [2, 0]], reverse: true)
|
|
|
|
expect(editor.lineElementForScreenRow(2)).toMatchSelector('.fold.selected')
|
|
|
|
|
|
|
|
editor.setSelectionBufferRange([[1, 0], [1, 1]])
|
|
|
|
expect(editor.lineElementForScreenRow(2)).not.toMatchSelector('.fold.selected')
|
|
|
|
|
|
|
|
editor.setSelectionBufferRange([[1, 0], [5, 0]])
|
|
|
|
expect(editor.lineElementForScreenRow(2)).toMatchSelector('.fold.selected')
|
|
|
|
|
|
|
|
editor.setCursorScreenPosition([3,0])
|
|
|
|
expect(editor.lineElementForScreenRow(2)).not.toMatchSelector('.fold.selected')
|
|
|
|
|
|
|
|
editor.setCursorScreenPosition([2,0])
|
|
|
|
expect(editor.lineElementForScreenRow(2)).toMatchSelector('.fold.selected')
|
2012-05-25 23:35:32 +04:00
|
|
|
expect(editor.find('.cursor').css('display')).toBe 'none'
|
|
|
|
|
|
|
|
editor.setCursorScreenPosition([3,0])
|
|
|
|
expect(editor.find('.cursor').css('display')).toBe 'block'
|
2012-05-25 03:39:14 +04:00
|
|
|
|
|
|
|
describe "when a selected fold is scrolled into view (and the fold line was not previously rendered)", ->
|
|
|
|
it "renders the fold's line element with the 'selected' class", ->
|
|
|
|
setEditorHeightInLines(editor, 5)
|
2012-06-05 21:09:40 +04:00
|
|
|
editor.renderLines() # re-render lines so certain lines are not rendered
|
2012-02-29 06:46:41 +04:00
|
|
|
|
2012-05-25 03:39:14 +04:00
|
|
|
editor.createFold(2, 4)
|
|
|
|
editor.setSelectionBufferRange([[1, 0], [5, 0]])
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.fold.selected')).toExist()
|
2012-02-29 06:46:41 +04:00
|
|
|
|
2012-05-25 03:39:14 +04:00
|
|
|
editor.scrollToBottom()
|
2012-06-05 04:53:58 +04:00
|
|
|
expect(editor.renderedLines.find('.fold.selected')).not.toExist()
|
2012-03-08 00:43:29 +04:00
|
|
|
|
2012-05-25 03:39:14 +04:00
|
|
|
editor.scrollTop(0)
|
|
|
|
expect(editor.lineElementForScreenRow(2)).toMatchSelector('.fold.selected')
|
2012-03-08 23:59:38 +04:00
|
|
|
|
2012-04-24 18:51:11 +04:00
|
|
|
describe "editor-path-change event", ->
|
2012-03-31 02:14:59 +04:00
|
|
|
it "emits event when buffer's path is changed", ->
|
2012-04-10 23:04:54 +04:00
|
|
|
editor = new Editor
|
2012-03-31 02:14:59 +04:00
|
|
|
|
|
|
|
eventHandler = jasmine.createSpy('eventHandler')
|
2012-04-24 18:51:11 +04:00
|
|
|
editor.on 'editor-path-change', eventHandler
|
2012-03-31 02:14:59 +04:00
|
|
|
editor.buffer.setPath("moo.text")
|
|
|
|
|
|
|
|
it "emits event when editor receives a new buffer", ->
|
|
|
|
eventHandler = jasmine.createSpy('eventHandler')
|
2012-04-24 18:51:11 +04:00
|
|
|
editor.on 'editor-path-change', eventHandler
|
2012-03-31 02:14:59 +04:00
|
|
|
editor.setBuffer(new Buffer("something.txt"))
|
|
|
|
expect(eventHandler).toHaveBeenCalled()
|
|
|
|
|
|
|
|
it "stops listening to events on previously set buffers", ->
|
|
|
|
eventHandler = jasmine.createSpy('eventHandler')
|
|
|
|
oldBuffer = editor.buffer
|
2012-04-24 18:51:11 +04:00
|
|
|
editor.on 'editor-path-change', eventHandler
|
2012-03-31 02:14:59 +04:00
|
|
|
|
|
|
|
editor.setBuffer(new Buffer("something.txt"))
|
|
|
|
expect(eventHandler).toHaveBeenCalled()
|
|
|
|
|
|
|
|
eventHandler.reset()
|
|
|
|
oldBuffer.setPath("bad.txt")
|
|
|
|
expect(eventHandler).not.toHaveBeenCalled()
|
|
|
|
|
|
|
|
eventHandler.reset()
|
|
|
|
editor.buffer.setPath("new.txt")
|
2012-04-03 21:27:49 +04:00
|
|
|
expect(eventHandler).toHaveBeenCalled()
|
2012-04-12 00:41:19 +04:00
|
|
|
|
2012-04-13 21:40:29 +04:00
|
|
|
describe "split methods", ->
|
|
|
|
describe "when inside a pane", ->
|
|
|
|
fakePane = null
|
|
|
|
beforeEach ->
|
2012-04-13 22:49:59 +04:00
|
|
|
fakePane = { splitUp: jasmine.createSpy('splitUp').andReturn {} }
|
2012-04-13 21:40:29 +04:00
|
|
|
spyOn(editor, 'pane').andReturn(fakePane)
|
|
|
|
|
|
|
|
it "calls the corresponding split method on the containing pane with a copy of the editor", ->
|
|
|
|
editor.splitUp()
|
|
|
|
expect(fakePane.splitUp).toHaveBeenCalled()
|
|
|
|
[editorCopy] = fakePane.splitUp.argsForCall[0]
|
|
|
|
expect(editorCopy.serialize()).toEqual editor.serialize()
|
|
|
|
expect(editorCopy).not.toBe editor
|
|
|
|
|
|
|
|
describe "when not inside a pane", ->
|
|
|
|
it "does not split the editor, but doesn't throw an exception", ->
|
|
|
|
editor.splitUp()
|
|
|
|
editor.splitDown()
|
|
|
|
editor.splitLeft()
|
|
|
|
editor.splitRight()
|
|
|
|
|
2012-04-21 03:52:11 +04:00
|
|
|
describe "when 'close' is triggered", ->
|
|
|
|
it "calls remove on the editor if mini is false", ->
|
|
|
|
expect(editor.mini).toBeFalsy()
|
|
|
|
spyOn(editor, 'remove')
|
|
|
|
editor.trigger 'close'
|
|
|
|
expect(editor.remove).toHaveBeenCalled()
|
|
|
|
|
|
|
|
editor = new Editor(mini: true)
|
|
|
|
spyOn(editor, 'remove')
|
|
|
|
editor.trigger 'close'
|
|
|
|
expect(editor.remove).not.toHaveBeenCalled()
|