2012-01-27 06:54:18 +04:00
|
|
|
Buffer = require 'buffer'
|
|
|
|
Editor = require 'editor'
|
|
|
|
Range = require 'range'
|
|
|
|
|
|
|
|
describe "Selection", ->
|
|
|
|
[editor, buffer, selection] = []
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
buffer = new Buffer(require.resolve('fixtures/sample.js'))
|
2012-02-06 23:12:45 +04:00
|
|
|
editor = new Editor
|
2012-01-27 06:54:18 +04:00
|
|
|
editor.enableKeymap()
|
|
|
|
editor.setBuffer(buffer)
|
2012-03-19 19:04:39 +04:00
|
|
|
editor.isFocused = true
|
2012-03-23 02:08:20 +04:00
|
|
|
selection = editor.getSelection()
|
2012-01-27 06:54:18 +04:00
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
describe ".setBufferRange(range)", ->
|
2012-01-27 06:54:18 +04:00
|
|
|
it "places the anchor at the start of the range and the cursor at the end", ->
|
|
|
|
range = new Range({row: 2, column: 7}, {row: 3, column: 18})
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange(range)
|
2012-04-03 19:53:02 +04:00
|
|
|
expect(selection.anchor.getScreenPosition()).toEqual range.start
|
2012-02-24 22:53:18 +04:00
|
|
|
expect(selection.cursor.getScreenPosition()).toEqual range.end
|
2012-01-27 06:54:18 +04:00
|
|
|
|
2012-03-27 06:39:09 +04:00
|
|
|
describe ".deleteSelectedText()", ->
|
2012-02-02 03:57:37 +04:00
|
|
|
describe "when nothing is selected", ->
|
|
|
|
it "deletes nothing", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,3], [0,3])
|
2012-03-27 06:39:09 +04:00
|
|
|
selection.deleteSelectedText()
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "var quicksort = function () {"
|
2012-02-02 03:57:37 +04:00
|
|
|
|
|
|
|
describe "when one line is selected", ->
|
2012-03-27 21:21:26 +04:00
|
|
|
it "deletes selected text and clears the selection", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,4], [0,14])
|
2012-03-27 06:39:09 +04:00
|
|
|
selection.deleteSelectedText()
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "var = function () {"
|
2012-02-02 03:57:37 +04:00
|
|
|
|
2012-03-06 03:06:27 +04:00
|
|
|
endOfLine = editor.buffer.lineForRow(0).length
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,0], [0, endOfLine])
|
2012-03-27 06:39:09 +04:00
|
|
|
selection.deleteSelectedText()
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(editor.buffer.lineForRow(0)).toBe ""
|
2012-02-02 03:57:37 +04:00
|
|
|
|
2012-03-27 21:21:26 +04:00
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
2012-02-02 03:57:37 +04:00
|
|
|
describe "when multiple lines are selected", ->
|
2012-03-27 21:21:26 +04:00
|
|
|
it "deletes selected text and clears the selection", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,1], [2,39])
|
2012-03-27 06:39:09 +04:00
|
|
|
selection.deleteSelectedText()
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "v;"
|
2012-03-27 21:21:26 +04:00
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
describe "when the cursor precedes the anchor", ->
|
|
|
|
it "it deletes selected text and clears the selection", ->
|
|
|
|
editor.attachToDom()
|
|
|
|
selection.cursor.setScreenPosition [0,13]
|
|
|
|
selection.selectToScreenPosition [0,4]
|
|
|
|
|
|
|
|
selection.delete()
|
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "var = function () {"
|
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
|
|
|
expect(selection.find('.selection')).not.toExist()
|
2012-02-02 03:57:37 +04:00
|
|
|
|
2012-01-28 00:42:33 +04:00
|
|
|
describe ".updateAppearence()", ->
|
2012-01-27 06:54:18 +04:00
|
|
|
[charWidth, lineHeight] = []
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
editor.attachToDom()
|
2012-01-31 21:55:17 +04:00
|
|
|
editor.width(500)
|
2012-01-27 06:54:18 +04:00
|
|
|
{ charWidth, lineHeight } = editor
|
|
|
|
|
|
|
|
describe "when the selection is within a single line", ->
|
|
|
|
it "covers the selection's range with a single region", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange(new Range({row: 2, column: 7}, {row: 2, column: 25}))
|
2012-01-27 06:54:18 +04:00
|
|
|
|
|
|
|
expect(selection.regions.length).toBe 1
|
|
|
|
region = selection.regions[0]
|
|
|
|
expect(region.position().top).toBe(2 * lineHeight)
|
2012-03-08 04:10:07 +04:00
|
|
|
expect(region.position().left).toBe(7 * charWidth)
|
2012-01-27 06:54:18 +04:00
|
|
|
expect(region.height()).toBe lineHeight
|
|
|
|
expect(region.width()).toBe((25 - 7) * charWidth)
|
|
|
|
|
|
|
|
describe "when the selection spans 2 lines", ->
|
|
|
|
it "covers the selection's range with 2 regions", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange(new Range({row: 2, column: 7}, {row: 3, column: 25}))
|
2012-01-27 06:54:18 +04:00
|
|
|
|
|
|
|
expect(selection.regions.length).toBe 2
|
|
|
|
|
|
|
|
region1 = selection.regions[0]
|
|
|
|
expect(region1.position().top).toBe(2 * lineHeight)
|
2012-03-08 04:10:07 +04:00
|
|
|
expect(region1.position().left).toBe(7 * charWidth)
|
2012-01-27 06:54:18 +04:00
|
|
|
expect(region1.height()).toBe lineHeight
|
2012-05-17 00:47:09 +04:00
|
|
|
expect(region1.width()).toBe(editor.visibleLines.width() - region1.position().left)
|
2012-01-27 06:54:18 +04:00
|
|
|
|
|
|
|
region2 = selection.regions[1]
|
|
|
|
expect(region2.position().top).toBe(3 * lineHeight)
|
2012-03-08 04:10:07 +04:00
|
|
|
expect(region2.position().left).toBe(0)
|
2012-01-27 06:54:18 +04:00
|
|
|
expect(region2.height()).toBe lineHeight
|
|
|
|
expect(region2.width()).toBe(25 * charWidth)
|
|
|
|
|
|
|
|
describe "when the selection spans more than 2 lines", ->
|
2012-01-31 21:44:10 +04:00
|
|
|
it "covers the selection's range with 3 regions", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange(new Range({row: 2, column: 7}, {row: 6, column: 25}))
|
2012-01-27 06:54:18 +04:00
|
|
|
|
|
|
|
expect(selection.regions.length).toBe 3
|
|
|
|
|
|
|
|
region1 = selection.regions[0]
|
|
|
|
expect(region1.position().top).toBe(2 * lineHeight)
|
2012-03-08 04:10:07 +04:00
|
|
|
expect(region1.position().left).toBe(7 * charWidth)
|
2012-01-27 06:54:18 +04:00
|
|
|
expect(region1.height()).toBe lineHeight
|
2012-05-17 00:47:09 +04:00
|
|
|
expect(region1.width()).toBe(editor.visibleLines.width() - region1.position().left)
|
2012-01-27 06:54:18 +04:00
|
|
|
|
|
|
|
region2 = selection.regions[1]
|
|
|
|
expect(region2.position().top).toBe(3 * lineHeight)
|
2012-03-08 04:10:07 +04:00
|
|
|
expect(region2.position().left).toBe(0)
|
2012-01-31 21:44:10 +04:00
|
|
|
expect(region2.height()).toBe(3 * lineHeight)
|
2012-05-17 00:47:09 +04:00
|
|
|
expect(region2.width()).toBe(editor.visibleLines.width())
|
2012-01-27 06:54:18 +04:00
|
|
|
|
2012-01-31 21:55:17 +04:00
|
|
|
# resizes with the editor
|
|
|
|
expect(editor.width()).toBeLessThan(800)
|
|
|
|
editor.width(800)
|
2012-05-17 00:47:09 +04:00
|
|
|
expect(region2.width()).toBe(editor.visibleLines.width())
|
2012-01-31 21:55:17 +04:00
|
|
|
|
2012-01-27 06:54:18 +04:00
|
|
|
region3 = selection.regions[2]
|
2012-01-31 21:44:10 +04:00
|
|
|
expect(region3.position().top).toBe(6 * lineHeight)
|
2012-03-08 04:10:07 +04:00
|
|
|
expect(region3.position().left).toBe(0)
|
2012-01-27 06:54:18 +04:00
|
|
|
expect(region3.height()).toBe lineHeight
|
|
|
|
expect(region3.width()).toBe(25 * charWidth)
|
|
|
|
|
|
|
|
it "clears previously drawn regions before creating new ones", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange(new Range({row: 2, column: 7}, {row: 4, column: 25}))
|
2012-01-27 06:54:18 +04:00
|
|
|
expect(selection.regions.length).toBe 3
|
|
|
|
expect(selection.find('.selection').length).toBe 3
|
|
|
|
|
|
|
|
selection.updateAppearance()
|
|
|
|
expect(selection.regions.length).toBe 3
|
|
|
|
expect(selection.find('.selection').length).toBe 3
|
|
|
|
|
2012-02-02 21:35:18 +04:00
|
|
|
describe ".cut()", ->
|
|
|
|
beforeEach ->
|
2012-03-02 03:42:41 +04:00
|
|
|
$native.writeToPasteboard('first')
|
|
|
|
expect($native.readFromPasteboard()).toBe 'first'
|
2012-02-02 21:35:18 +04:00
|
|
|
|
|
|
|
it "removes selected text from the buffer and places it on the clipboard", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,4], [0,13])
|
2012-02-02 21:35:18 +04:00
|
|
|
selection.cut()
|
2012-03-02 03:42:41 +04:00
|
|
|
expect($native.readFromPasteboard()).toBe 'quicksort'
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "var = function () {"
|
2012-02-02 21:35:18 +04:00
|
|
|
expect(selection.isEmpty()).toBeTruthy()
|
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([1,6], [3,8])
|
2012-02-02 21:35:18 +04:00
|
|
|
selection.cut()
|
2012-03-02 03:42:41 +04:00
|
|
|
expect($native.readFromPasteboard()).toBe "sort = function(items) {\n if (items.length <= 1) return items;\n var "
|
2012-03-06 03:06:27 +04:00
|
|
|
expect(editor.buffer.lineForRow(1)).toBe " var pivot = items.shift(), current, left = [], right = [];"
|
2012-02-02 21:35:18 +04:00
|
|
|
|
|
|
|
it "places nothing on the clipboard when there is no selection", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,4], [0,4])
|
2012-02-02 21:35:18 +04:00
|
|
|
selection.copy()
|
2012-03-02 03:42:41 +04:00
|
|
|
expect($native.readFromPasteboard()).toBe 'first'
|
2012-02-02 21:35:18 +04:00
|
|
|
|
2012-02-02 05:59:59 +04:00
|
|
|
describe ".copy()", ->
|
2012-01-31 05:46:03 +04:00
|
|
|
beforeEach ->
|
2012-03-02 03:42:41 +04:00
|
|
|
$native.writeToPasteboard('first')
|
|
|
|
expect($native.readFromPasteboard()).toBe 'first'
|
2012-01-31 05:46:03 +04:00
|
|
|
|
|
|
|
it "places selected text on the clipboard", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,4], [0,13])
|
2012-02-02 05:46:22 +04:00
|
|
|
selection.copy()
|
2012-03-02 03:42:41 +04:00
|
|
|
expect($native.readFromPasteboard()).toBe 'quicksort'
|
2012-01-31 05:46:03 +04:00
|
|
|
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,4], [3,13])
|
2012-02-02 05:46:22 +04:00
|
|
|
selection.copy()
|
2012-03-02 03:42:41 +04:00
|
|
|
expect($native.readFromPasteboard()).toBe "quicksort = function () {\n var sort = function(items) {\n if (items.length <= 1) return items;\n var pivot"
|
2012-01-31 22:10:18 +04:00
|
|
|
|
2012-01-31 05:46:03 +04:00
|
|
|
it "places nothing on the clipboard when there is no selection", ->
|
2012-02-25 08:05:12 +04:00
|
|
|
selection.setBufferRange new Range([0,4], [0,4])
|
2012-02-02 05:46:22 +04:00
|
|
|
selection.copy()
|
2012-03-02 03:42:41 +04:00
|
|
|
expect($native.readFromPasteboard()).toBe 'first'
|
2012-02-03 02:13:28 +04:00
|
|
|
|
|
|
|
describe ".selectWord()", ->
|
|
|
|
describe "when the cursor is inside a word", ->
|
|
|
|
it "selects the entire word", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition [0,8]
|
2012-02-03 02:13:28 +04:00
|
|
|
selection.selectWord()
|
|
|
|
expect(selection.getText()).toBe 'quicksort'
|
|
|
|
|
|
|
|
describe "when the cursor is on beginning of a word", ->
|
|
|
|
it "selects the entire word", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition [0,4]
|
2012-02-03 02:13:28 +04:00
|
|
|
selection.selectWord()
|
|
|
|
expect(selection.getText()).toBe 'quicksort'
|
|
|
|
|
|
|
|
describe "when the cursor is at the end of a word", ->
|
|
|
|
it "selects the entire word", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition [0,13]
|
2012-02-03 02:13:28 +04:00
|
|
|
selection.selectWord()
|
|
|
|
expect(selection.getText()).toBe 'quicksort'
|
|
|
|
|
|
|
|
describe "when the cursor is not on a word", ->
|
|
|
|
it "selects nothing", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition [5,2]
|
2012-02-03 02:13:28 +04:00
|
|
|
selection.selectWord()
|
|
|
|
expect(selection.getText()).toBe ''
|
|
|
|
|
2012-02-04 03:03:13 +04:00
|
|
|
describe ".selectLine(row)", ->
|
|
|
|
it "selects the entire line at given row", ->
|
2012-02-24 22:53:18 +04:00
|
|
|
editor.setCursorScreenPosition [0,2]
|
2012-02-04 03:03:13 +04:00
|
|
|
selection.selectLine(1)
|
2012-02-04 01:11:42 +04:00
|
|
|
expect(selection.getText()).toBe " var sort = function(items) {"
|
2012-03-27 22:26:36 +04:00
|
|
|
|
|
|
|
describe ".isReversed()", ->
|
|
|
|
it "returns true if the cursor precedes the anchor", ->
|
|
|
|
selection.cursor.setScreenPosition([0, 20])
|
|
|
|
selection.selectToScreenPosition([0, 10])
|
|
|
|
expect(selection.isReversed()).toBeTruthy()
|
|
|
|
|
|
|
|
selection.selectToScreenPosition([0, 25])
|
|
|
|
expect(selection.isReversed()).toBeFalsy()
|
2012-04-10 20:55:13 +04:00
|
|
|
|
|
|
|
describe ".indentSelectedRows()", ->
|
|
|
|
tabLength = null
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
tabLength = editor.tabText.length
|
|
|
|
|
|
|
|
describe "when nothing is selected", ->
|
2012-04-10 21:18:39 +04:00
|
|
|
it "indents line and retains selection", ->
|
2012-04-10 20:55:13 +04:00
|
|
|
selection.setBufferRange new Range([0,3], [0,3])
|
|
|
|
selection.indentSelectedRows()
|
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "#{editor.tabText}var quicksort = function () {"
|
|
|
|
expect(selection.getBufferRange()).toEqual [[0, 3 + tabLength], [0, 3 + tabLength]]
|
|
|
|
|
|
|
|
describe "when one line is selected", ->
|
2012-04-10 21:18:39 +04:00
|
|
|
it "indents line and retains selection", ->
|
2012-04-10 20:55:13 +04:00
|
|
|
selection.setBufferRange new Range([0,4], [0,14])
|
|
|
|
selection.indentSelectedRows()
|
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "#{editor.tabText}var quicksort = function () {"
|
|
|
|
expect(selection.getBufferRange()).toEqual [[0, 4 + tabLength], [0, 14 + tabLength]]
|
|
|
|
|
|
|
|
describe "when multiple lines are selected", ->
|
2012-04-10 21:18:39 +04:00
|
|
|
it "indents selected lines (that are not empty) and retains selection", ->
|
2012-04-10 20:55:13 +04:00
|
|
|
selection.setBufferRange new Range([9,1], [11,15])
|
|
|
|
selection.indentSelectedRows()
|
|
|
|
expect(editor.buffer.lineForRow(9)).toBe " };"
|
|
|
|
expect(editor.buffer.lineForRow(10)).toBe ""
|
|
|
|
expect(editor.buffer.lineForRow(11)).toBe " return sort(Array.apply(this, arguments));"
|
2012-04-10 21:18:39 +04:00
|
|
|
expect(selection.getBufferRange()).toEqual [[9, 1 + tabLength], [11, 15 + tabLength]]
|
|
|
|
|
|
|
|
describe ".outdentSelectedRows()", ->
|
|
|
|
tabLength = null
|
|
|
|
|
|
|
|
beforeEach ->
|
|
|
|
editor.tabText = " "
|
|
|
|
tabLength = editor.tabText.length
|
|
|
|
|
|
|
|
describe "when nothing is selected", ->
|
|
|
|
it "outdents line and retains selection", ->
|
|
|
|
selection.setBufferRange new Range([1,3], [1,3])
|
|
|
|
selection.outdentSelectedRows()
|
|
|
|
expect(editor.buffer.lineForRow(1)).toBe "var sort = function(items) {"
|
|
|
|
expect(selection.getBufferRange()).toEqual [[1, 3 - tabLength], [1, 3 - tabLength]]
|
|
|
|
|
|
|
|
describe "when one line is selected", ->
|
|
|
|
it "outdents line and retains selection", ->
|
|
|
|
selection.setBufferRange new Range([1,4], [1,14])
|
|
|
|
selection.outdentSelectedRows()
|
|
|
|
expect(editor.buffer.lineForRow(1)).toBe "var sort = function(items) {"
|
|
|
|
expect(selection.getBufferRange()).toEqual [[1, 4 - tabLength], [1, 14 - tabLength]]
|
|
|
|
|
|
|
|
describe "when multiple lines are selected", ->
|
|
|
|
it "outdents selected lines and retains selection", ->
|
|
|
|
selection.setBufferRange new Range([0,1], [3,15])
|
|
|
|
selection.outdentSelectedRows()
|
|
|
|
expect(editor.buffer.lineForRow(0)).toBe "var quicksort = function () {"
|
|
|
|
expect(editor.buffer.lineForRow(1)).toBe "var sort = function(items) {"
|
|
|
|
expect(editor.buffer.lineForRow(2)).toBe " if (items.length <= 1) return items;"
|
|
|
|
expect(selection.getBufferRange()).toEqual [[0, 1], [3, 15 - tabLength]]
|
2012-05-25 00:53:48 +04:00
|
|
|
|
|
|
|
describe "when the selection ends on the begining of a fold line", ->
|
|
|
|
beforeEach ->
|
|
|
|
editor.createFold(2,4)
|
|
|
|
editor.createFold(2,6)
|
|
|
|
|
|
|
|
describe "inserting text", ->
|
|
|
|
it "destroys the fold", ->
|
|
|
|
selection.setBufferRange([[1,0], [2,0]])
|
|
|
|
selection.insertText('holy cow')
|
|
|
|
expect(editor.screenLineForRow(3).text).toBe buffer.lineForRow(3)
|
|
|
|
|
|
|
|
describe "when the selection is empty", ->
|
|
|
|
describe "delete, when the selection is empty", ->
|
|
|
|
it "removes the lines contained by the fold", ->
|
|
|
|
oldLine7 = buffer.lineForRow(7)
|
|
|
|
oldLine8 = buffer.lineForRow(8)
|
|
|
|
|
|
|
|
selection.setBufferRange([[2, 0], [2, 0]])
|
|
|
|
selection.delete()
|
|
|
|
expect(editor.screenLineForRow(2).text).toBe oldLine7
|
|
|
|
expect(editor.screenLineForRow(3).text).toBe oldLine8
|