diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/editorActions/BlockIndentOnPasteTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/editorActions/BlockIndentOnPasteTest.groovy index f445112993c1..ba85483ca036 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/editorActions/BlockIndentOnPasteTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/editorActions/BlockIndentOnPasteTest.groovy @@ -129,6 +129,35 @@ class Test { doTest(before, toPaste, expected) } + void testPastingBlockEndedByLineFeed() { + def before = '''\ +class Test { + void test() { + if (true) { + } + } +}\ +''' + + def toPaste = + '''\ +int i = 1; +''' + + + def expected = '''\ +class Test { + void test() { + if (true) { + int i = 1; + } + } +}\ +''' + doTest(before, toPaste, expected) + } + + void testPasteAtZeroColumn() { def before = '''\ class Test { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java index bff12d06df89..96bf7a6fe287 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/PasteHandler.java @@ -379,7 +379,51 @@ public class PasteHandler extends EditorActionHandler { CharSequence chars = document.getCharsSequence(); final int firstLine = document.getLineNumber(startOffset); final int firstLineStart = document.getLineStartOffset(firstLine); - final int lastLine = document.getLineNumber(endOffset); + + // There is a possible case that we paste block that ends with new line that is empty or contains only white space symbols. + // We want to preserve indent for the original document line where paste was performed. + // Example: + // Original: + // if (test) { + // } + // + // Pasting: 'int i = 1;\n' + // Expected: + // if (test) { + // int i = 1; + // } + boolean saveLastLineIndent = false; + for (int i = endOffset - 1; i >= startOffset; i--) { + final char c = chars.charAt(i); + if (c == '\n') { + saveLastLineIndent = true; + break; + } + if (c != ' ' && c != '\t') { + break; + } + } + + final int lastLine; + if (saveLastLineIndent) { + lastLine = document.getLineNumber(endOffset) - 1; + // Remove white space symbols at the pasted text if any. + int start = document.getLineStartOffset(lastLine + 1); + if (start < endOffset) { + int i = CharArrayUtil.shiftForward(chars, start, " \t"); + if (i > start) { + i = Math.min(i, endOffset); + document.deleteString(start, i); + } + } + + // Insert white space from the start line of the pasted block. + document.insertString(start, chars.subSequence(firstLineStart, startOffset)); + } + else { + lastLine = document.getLineNumber(endOffset); + } + final int i = CharArrayUtil.shiftBackward(chars, startOffset - 1, " \t"); // Handle situation when pasted block doesn't start new line.