From e34eb151ca2e40fae5b9dc184cca592362672a35 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 17 Nov 2014 19:24:37 -0800 Subject: [PATCH] Respect 'normalizeIndentOnPaste even w/ multiple selections --- spec/text-editor-spec.coffee | 34 +++++++++++++++++++++++++++------- src/selection.coffee | 23 ++++++++++++----------- src/text-editor.coffee | 31 +++++++++++++++++-------------- 3 files changed, 56 insertions(+), 32 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index ea61b2b8c..88f0df0fb 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -2631,15 +2631,35 @@ describe "TextEditor", -> describe "when the inserted text contains newlines", -> describe "when the cursor is preceded only by whitespace characters", -> - it "normalizes indented lines to the cursor's current indentation level", -> - copyText(" while (true) {\n foo();\n }\n", {startColumn: 2}) - editor.setCursorBufferPosition([3, 4]) + it "normalizes indented lines to each cursor's current indentation level", -> + editor.setSelectedBufferRanges([ + [[1,2], [3,0]], + [[4,4], [6,0]] + ]) + editor.copySelectedText() + expect(atom.clipboard.read()).toEqual """ + var sort = function(items) { + if (items.length <= 1) return items; + + while(items.length > 0) { + current = items.shift(); + + """ + + editor.setCursorBufferPosition([0,0]) + editor.insertNewlineAbove() + editor.setSelectedBufferRanges([ + [[0,0], [0,0]], + [[1,0], [1,0]] + ]) editor.pasteText() - expect(editor.lineTextForBufferRow(3)).toBe " while (true) {" - expect(editor.lineTextForBufferRow(4)).toBe " foo();" - expect(editor.lineTextForBufferRow(5)).toBe " }" - expect(editor.lineTextForBufferRow(6)).toBe "var pivot = items.shift(), current, left = [], right = [];" + expect(editor.lineTextForBufferRow(0)).toBe "var sort = function(items) {" + console.log JSON.stringify(editor.lineTextForBufferRow(1)) + expect(editor.lineTextForBufferRow(1)).toBe " if (items.length <= 1) return items;" + expect(editor.lineTextForBufferRow(2)).toBe "" + expect(editor.lineTextForBufferRow(3)).toBe "while(items.length > 0) {" + expect(editor.lineTextForBufferRow(4)).toBe " current = items.shift();" describe "when the cursor is preceded by non-whitespace characters", -> it "normalizes the indentation level of all lines based on the level of the existing first line", -> diff --git a/src/selection.coffee b/src/selection.coffee index 39013e996..a7f716726 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -558,20 +558,21 @@ class Selection extends Model # current selection. (default: false) copy: (maintainClipboard=false) -> return if @isEmpty() - text = @editor.buffer.getTextInRange(@getBufferRange()) + selectionText = @editor.buffer.getTextInRange(@getBufferRange()) + selectionIndentation = @editor.indentationForBufferRow(@getBufferRange().start.row) + if maintainClipboard {text: clipboardText, metadata} = atom.clipboard.readWithMetadata() - - if metadata?.selections? - metadata.selections.push(text) - else - metadata = { selections: [clipboardText, text] } - - text = "" + (clipboardText) + "\n" + text + metadata ?= {} + unless metadata.selections? + metadata.selections = [{ + text: clipboardText, + indentBasis: metadata.indentBasis, + }] + metadata.selections.push(text: selectionText, indentBasis: selectionIndentation) + atom.clipboard.write([clipboardText, selectionText].join("\n"), metadata) else - metadata = { indentBasis: @editor.indentationForBufferRow(@getBufferRange().start.row) } - - atom.clipboard.write(text, metadata) + atom.clipboard.write(selectionText, {indentBasis: selectionIndentation}) # Public: Creates a fold containing the current selection. fold: -> diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 063d76a94..e8e8c872f 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2494,21 +2494,24 @@ class TextEditor extends Model # # * `options` (optional) See {Selection::insertText}. pasteText: (options={}) -> - {text, metadata} = atom.clipboard.readWithMetadata() - - if metadata?.selections?.length is @getSelections().length - @mutateSelectedText (selection, index) -> - text = metadata.selections[index] - selection.insertText(text, options) - return - - if metadata?.indentBasis? and atom.config.get(@getLastCursor().getScopeDescriptor(), "editor.normalizeIndentOnPaste") - containsNewlines = text.indexOf('\n') isnt -1 - if containsNewlines or !@getLastCursor().hasPrecedingCharactersOnLine() - options.indentBasis ?= metadata.indentBasis - + {text: clipboardText, metadata} = atom.clipboard.readWithMetadata() + metadata ?= {} options.autoIndent = @shouldAutoIndentOnPaste() - @insertText(text, options) + + @mutateSelectedText (selection, index) => + if metadata.selections?.length is @getSelections().length + {text, indentBasis} = metadata.selections[index] + else + [text, indentBasis] = [clipboardText, metadata.indentBasis] + + delete options.indentBasis + {cursor} = selection + if indentBasis? and atom.config.get(cursor.getScopeDescriptor(), "editor.normalizeIndentOnPaste") + containsNewlines = text.indexOf('\n') isnt -1 + if containsNewlines or !cursor.hasPrecedingCharactersOnLine() + options.indentBasis ?= indentBasis + + selection.insertText(text, options) # Public: For each selection, if the selection is empty, cut all characters # of the containing line following the cursor. Otherwise cut the selected