WIP: multiselection cut/copy/paste

This commit is contained in:
Corey Johnson & Nathan Sobo
2012-03-26 16:24:20 -07:00
parent 36177e4520
commit 4d1f7b33e7
4 changed files with 84 additions and 34 deletions

View File

@@ -1263,33 +1263,58 @@ describe "Editor", ->
expect(editor.clipScreenPosition(row: 1, column: -5)).toEqual(row: 1, column: 0)
describe "cut, copy & paste", ->
pasteboard = null
beforeEach ->
$native.writeToPasteboard('first')
expect($native.readFromPasteboard()).toBe 'first'
pasteboard = 'first'
spyOn($native, 'writeToPasteboard').andCallFake (text) -> pasteboard = text
spyOn($native, 'readFromPasteboard').andCallFake -> pasteboard
describe "when a cut event is triggered", ->
it "removes the selected text from the buffer and places it on the pasteboard", ->
editor.getSelection().setBufferRange new Range([0,4], [0,9])
editor.trigger "cut"
expect(editor.buffer.lineForRow(0)).toBe "var sort = function () {"
expect($native.readFromPasteboard()).toBe 'quick'
describe "with a single selection", ->
beforeEach ->
editor.setSelectionBufferRange([[0, 4], [0, 13]])
describe "when a copy event is triggered", ->
it "copies selected text onto the clipboard", ->
editor.getSelection().setBufferRange new Range([0,4], [0, 13])
editor.trigger "copy"
expect($native.readFromPasteboard()).toBe 'quicksort'
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 paste event is triggered", ->
it "pastes text into the buffer", ->
editor.setCursorScreenPosition [0, 4]
editor.trigger "paste"
expect(editor.buffer.lineForRow(0)).toBe "var firstquicksort = function () {"
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'
expect(editor.buffer.lineForRow(1)).toBe " var sort = function(items) {"
editor.getSelection().setBufferRange new Range([1,6], [1,10])
editor.trigger "paste"
expect(editor.buffer.lineForRow(1)).toBe " var first = function(items) {"
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) {"
describe "folding", ->
describe "when a fold-selection event is triggered", ->

View File

@@ -17,6 +17,10 @@ class CompositeSeleciton
@selections.push(selection)
@editor.lines.append(selection)
addSelectionForBufferRange: (bufferRange) ->
cursor = @editor.compositeCursor.addCursor()
@selectionForCursor(cursor).setBufferRange(bufferRange)
removeSelectionForCursor: (cursor) ->
_.remove(@selections, @selectionForCursor(cursor))
@@ -24,7 +28,8 @@ class CompositeSeleciton
_.find @selections, (selection) -> selection.cursor == cursor
insertText: (text) ->
selection.insertText(text) for selection in @selections
@modifySelections (selection) ->
selection.insertText(text)
backspace: ->
for selection in @getSelections()
@@ -54,3 +59,21 @@ class CompositeSeleciton
selection.merge(otherSelection)
@mergeIntersectingSelections()
return
modifySelections: (fn) ->
selection.retainSelection = true for selection in @getSelections()
for selection in @getSelections()
selection.retainSelection = false
fn(selection)
cut: ->
maintainPasteboard = false
@modifySelections (selection) ->
selection.cut(maintainPasteboard)
maintainPasteboard = true
copy: ->
maintainPasteboard = false
for selection in @getSelections()
selection.copy(maintainPasteboard)
maintainPasteboard = true

View File

@@ -348,7 +348,6 @@ class Editor extends View
moveCursorDown: -> @compositeCursor.moveDown()
moveCursorRight: -> @compositeCursor.moveRight()
moveCursorLeft: -> @compositeCursor.moveLeft()
setCursorScreenPosition: (position) -> @compositeCursor.setScreenPosition(position)
getCursorScreenPosition: -> @getCursor().getScreenPosition()
setCursorBufferPosition: (position) -> @compositeCursor.setBufferPosition(position)
@@ -356,6 +355,8 @@ class Editor extends View
getSelection: (index) -> @compositeSelection.getSelection(index)
getSelectedText: -> @compositeSelection.getSelection().getText()
setSelectionBufferRange: (bufferRange) -> @compositeSelection.setBufferRange(bufferRange)
addSelectionForBufferRange: (bufferRange) -> @compositeSelection.addSelectionForBufferRange(bufferRange)
selectRight: -> @compositeSelection.getSelection().selectRight()
selectLeft: -> @compositeSelection.getSelection().selectLeft()
selectUp: -> @compositeSelection.getSelection().selectUp()
@@ -374,8 +375,8 @@ class Editor extends View
insertText: (text) ->
@compositeSelection.insertText(text)
cutSelection: -> @getSelection().cut()
copySelection: -> @getSelection().copy()
cutSelection: -> @compositeSelection.cut()
copySelection: -> @compositeSelection.copy()
paste: -> @insertText($native.readFromPasteboard())
foldSelection: -> @getSelection().fold()

View File

@@ -10,13 +10,13 @@ class Selection extends View
@div()
anchor: null
modifyingSelection: null
retainSelection: null
regions: null
initialize: ({@editor, @cursor}) ->
@regions = []
@cursor.on 'cursor:position-changed', =>
if @modifyingSelection
if @retainSelection
@updateAppearance()
else
@clearSelection()
@@ -109,7 +109,7 @@ class Selection extends View
delete: ->
range = @getBufferRange()
@editor.buffer.change(range, '') unless range.isEmpty()
@editor.buffer.delete(range) unless range.isEmpty()
isEmpty: ->
@getBufferRange().isEmpty()
@@ -127,9 +127,9 @@ class Selection extends View
modifySelection: (fn) ->
@placeAnchor()
@modifyingSelection = true
@retainSelection = true
fn()
@modifyingSelection = false
@retainSelection = false
placeAnchor: ->
return if @anchor
@@ -191,13 +191,14 @@ class Selection extends View
moveCursorToLineStart: ->
@cursor.moveToLineStart()
cut: ->
@copy()
cut: (maintainPasteboard=false) ->
@copy(maintainPasteboard)
@delete()
copy: ->
copy: (maintainPasteboard=false) ->
return if @isEmpty()
text = @editor.buffer.getTextInRange(@getBufferRange())
text = $native.readFromPasteboard() + "\n" + text if maintainPasteboard
$native.writeToPasteboard text
fold: ->