From 528267b7d78452a13249033a9788f647f5c0f95d Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 21 Jan 2015 08:46:28 -0800 Subject: [PATCH] Preserve relative indentation of pasted lines when auto-indenting --- spec/text-editor-spec.coffee | 22 +++++++++++++++------- src/selection.coffee | 16 ++++++++++++---- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 5f7c5fabf..fe12d6532 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -2649,12 +2649,20 @@ describe "TextEditor", -> atom.config.set("editor.autoIndentOnPaste", true) describe "when only whitespace precedes the cursor", -> - it "auto-indents the lines spanned by the pasted text", -> - atom.clipboard.write("console.log(x);\nconsole.log(y);\n") - editor.setCursorBufferPosition([5, 2]) + it "auto-indents the lines spanned by the pasted text, based on the first pasted line", -> + expect(editor.indentationForBufferRow(5)).toBe(3) + + atom.clipboard.write("a(x);\n b(x);\n c(x);\n", indentBasis: 0) + editor.setCursorBufferPosition([5, 0]) editor.pasteText() - expect(editor.lineTextForBufferRow(5)).toBe(" console.log(x);") - expect(editor.lineTextForBufferRow(6)).toBe(" console.log(y);") + + # Adjust the indentation of the pasted block + expect(editor.indentationForBufferRow(5)).toBe(3) + expect(editor.indentationForBufferRow(6)).toBe(4) + expect(editor.indentationForBufferRow(7)).toBe(5) + + # Preserve the indentation of the next row + expect(editor.indentationForBufferRow(8)).toBe(3) describe "when non-whitespace characters precede the cursor", -> it "does not auto-indent the first line being pasted", -> @@ -2751,9 +2759,9 @@ describe "TextEditor", -> editor.setSelectedBufferRange([[1, 2], [1, Infinity]]) editor.pasteText() expect(editor.lineTextForBufferRow(1)).toBe(" if (items.length <= 1) return items;") - expect(editor.lineTextForBufferRow(2)).toBe(" ") + expect(editor.lineTextForBufferRow(2)).toBe("") expect(editor.lineTextForBufferRow(3)).toBe(" if (items.length <= 1) return items;") - expect(editor.getCursorBufferPosition()).toEqual([2, 2]) + expect(editor.getCursorBufferPosition()).toEqual([2, 0]) describe "when there is no selection", -> it "pastes the line above the cursor and retains the cursor's column", -> diff --git a/src/selection.coffee b/src/selection.coffee index 8c2b95118..6e190d119 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -362,7 +362,7 @@ class Selection extends Model precedingText = @editor.getTextInRange([[oldBufferRange.start.row, 0], oldBufferRange.start]) startLevel = @editor.indentLevelForLine(precedingText) - if options.indentBasis? and not options.autoIndent + if options.indentBasis? text = @adjustIndent(text, startLevel - options.indentBasis) newBufferRange = @editor.buffer.setTextInRange(oldBufferRange, text, pick(options, 'undo', 'normalizeLineEndings')) @@ -375,8 +375,16 @@ class Selection extends Model if options.autoIndent precedingText = @editor.getTextInBufferRange([[newBufferRange.start.row, 0], newBufferRange.start]) unless NonWhitespaceRegExp.test(precedingText) - @editor.autoIndentBufferRow(newBufferRange.getRows()[0]) - @editor.autoIndentBufferRow(row) for row, i in newBufferRange.getRows() when i > 0 + rowsToIndent = newBufferRange.getRows() + firstRow = rowsToIndent.shift() + rowsToIndent.pop() if text.endsWith("\n") + suggestedIndent = @editor.suggestedIndentForBufferRow(firstRow) + actualIndent = @editor.indentationForBufferRow(firstRow) + @editor.setIndentationForBufferRow(firstRow, suggestedIndent) + indentChange = suggestedIndent - actualIndent + for row in rowsToIndent + newIndent = @editor.indentationForBufferRow(row) + indentChange + @editor.setIndentationForBufferRow(row, newIndent) else if options.autoIndentNewline and text == '\n' currentIndentation = @editor.indentationForBufferRow(newBufferRange.start.row) @editor.autoIndentBufferRow(newBufferRange.end.row, preserveLeadingWhitespace: true, skipBlankLines: false) @@ -600,7 +608,7 @@ class Selection extends Model adjustIndent: (text, indentIncrease) -> lines = text.split('\n') for line, i in lines when i > 0 - if indentIncrease == 0 + if indentIncrease == 0 or line is '' continue else if indentIncrease > 0 lines[i] = @editor.buildIndentString(indentIncrease) + line