Merge pull request #1971 from abe33/feature_proper_multiselections_copy_paste

Implements multiple selections clipboard paste
This commit is contained in:
Corey Johnson
2014-05-12 11:10:37 -07:00
3 changed files with 56 additions and 6 deletions

View File

@@ -2063,17 +2063,44 @@ describe "Editor", ->
describe ".copySelectedText()", ->
it "copies selected text onto the clipboard", ->
editor.setSelectedBufferRanges([[[0,4], [0,13]], [[1,6], [1, 10]], [[2,8], [2, 13]]])
editor.copySelectedText()
expect(buffer.lineForRow(0)).toBe "var quicksort = function () {"
expect(buffer.lineForRow(1)).toBe " var sort = function(items) {"
expect(clipboard.readText()).toBe 'quicksort\nsort'
expect(buffer.lineForRow(2)).toBe " if (items.length <= 1) return items;"
expect(clipboard.readText()).toBe 'quicksort\nsort\nitems'
expect(atom.clipboard.readWithMetadata().metadata.selections).toEqual([
'quicksort'
'sort'
'items'
])
describe ".pasteText()", ->
it "pastes text into the buffer", ->
atom.clipboard.write('first')
editor.pasteText()
expect(editor.buffer.lineForRow(0)).toBe "var first = function () {"
expect(buffer.lineForRow(1)).toBe " var first = function(items) {"
expect(editor.lineForBufferRow(0)).toBe "var first = function () {"
expect(editor.lineForBufferRow(1)).toBe " var first = function(items) {"
describe 'when the clipboard has many selections', ->
it "pastes each selection separately into the buffer", ->
atom.clipboard.write('first\nsecond', {selections: ['first', 'second'] })
editor.pasteText()
expect(editor.lineForBufferRow(0)).toBe "var first = function () {"
expect(editor.lineForBufferRow(1)).toBe " var second = function(items) {"
describe 'and the selections count does not match', ->
it "pastes the whole text into the buffer", ->
atom.clipboard.write('first\nsecond\nthird', {selections: ['first', 'second', 'third'] })
editor.pasteText()
expect(editor.lineForBufferRow(0)).toBe "var first"
expect(editor.lineForBufferRow(1)).toBe "second"
expect(editor.lineForBufferRow(2)).toBe "third = function () {"
expect(editor.lineForBufferRow(3)).toBe " var first"
expect(editor.lineForBufferRow(4)).toBe "second"
expect(editor.lineForBufferRow(5)).toBe "third = function(items) {"
describe ".indentSelectedRows()", ->
describe "when nothing is selected", ->

View File

@@ -738,13 +738,24 @@ class Editor extends Model
# Public: For each selection, replace the selected text with the contents of
# the clipboard.
#
# If the clipboard contains the same number of selections as the current
# editor, each selection will be replaced with the content of the
# corresponding clipboard selection text.
#
# options - See {Selection::insertText}.
pasteText: (options={}) ->
{text, metadata} = atom.clipboard.readWithMetadata()
containsNewlines = text.indexOf('\n') isnt -1
if atom.config.get('editor.normalizeIndentOnPaste') and metadata
if metadata?.selections? and metadata.selections.length is @getSelections().length
@mutateSelectedText (selection, index) ->
text = metadata.selections[index]
selection.insertText(text, options)
return
else if atom.config.get("editor.normalizeIndentOnPaste") and metadata?.indentBasis?
if !@getCursor().hasPrecedingCharactersOnLine() or containsNewlines
options.indentBasis ?= metadata.indentBasis
@@ -1020,7 +1031,7 @@ class Editor extends Model
#
# fn - A {Function} that will be called with each {Selection}.
mutateSelectedText: (fn) ->
@transact => fn(selection) for selection in @getSelections()
@transact => fn(selection,index) for selection,index in @getSelections()
replaceSelectedText: (options={}, fn) ->
{selectWordIfEmpty} = options

View File

@@ -503,11 +503,23 @@ class Selection extends Model
@delete()
# Public: Copies the current selection to the clipboard.
#
# If the `maintainClipboard` is set to `true`, a specific metadata property
# is created to store each content copied to the clipboard. The clipboard
# `text` still contains the concatenation of the clipboard with the
# current selection.
copy: (maintainClipboard=false) ->
return if @isEmpty()
text = @editor.buffer.getTextInRange(@getBufferRange())
if maintainClipboard
text = "#{atom.clipboard.read()}\n#{text}"
{text: clipboardText, metadata} = atom.clipboard.readWithMetadata()
if metadata?.selections?
metadata.selections.push(text)
else
metadata = { selections: [clipboardText, text] }
text = "" + (clipboardText) + "\n" + text
else
metadata = { indentBasis: @editor.indentationForBufferRow(@getBufferRange().start.row) }