Preserve relative indentation of pasted lines when auto-indenting

This commit is contained in:
Max Brunsfeld 2015-01-21 08:46:28 -08:00
parent 5cdeb7bc18
commit 528267b7d7
2 changed files with 27 additions and 11 deletions

View File

@ -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", ->

View File

@ -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