diff --git a/platform/core-impl/src/com/intellij/openapi/editor/ex/DocumentEx.java b/platform/core-impl/src/com/intellij/openapi/editor/ex/DocumentEx.java
index 0a5ab0791241..a90f7f240690 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/ex/DocumentEx.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/ex/DocumentEx.java
@@ -37,18 +37,18 @@ public interface DocumentEx extends Document {
void replaceText(@NotNull CharSequence chars, long newModificationStamp);
/**
- * Replaces [dstStart; dstEnd) range by the text from the [src start; src end) range.
+ * Moves text from the [src start; src end) range to the [dstStart; dstEnd) range.
*
[srcStart; srcEnd) range have
+ * The benefit to use this method over usual {@link #deleteString(int, int)} and {@link #replaceString(int, int, CharSequence)}
+ * is that {@link #createRangeMarker(int, int, boolean) range markers} from the [srcStart; srcEnd) range have
* a chance to be preserved.
*
- * @param srcStart start offset of the text to copy (inclusive)
- * @param srcEnd end offset of the text to copy (exclusive)
+ * @param srcStart start offset of the text to move (inclusive)
+ * @param srcEnd end offset of the text to move (exclusive)
* @param dstStart start offset of the range which text should be replaced (inclusive)
* @param dstEnd end offset of the range which text should be replaced (exclusive)
*/
- void copyText(int srcStart, int srcEnd, int dstStart, int dstEnd);
+ void moveText(int srcStart, int srcEnd, int dstStart, int dstEnd);
int getListenersCount();
diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
index 0049a7c36f80..c206819b06ba 100644
--- a/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
+++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java
@@ -368,8 +368,49 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
}
@Override
- public void copyText(int srcStart, int srcEnd, int dstStart, int dstEnd) {
- replaceString(dstStart, dstEnd, getCharsSequence().subSequence(srcStart, srcEnd));
+ public void moveText(int srcStart, int srcEnd, int dstStart, int dstEnd) {
+ assertBounds(srcStart, srcEnd);
+ assertBounds(dstStart, dstEnd);
+
+ if (srcStart == dstStart && srcEnd == dstEnd) {
+ return;
+ }
+
+ CharSequence replacement = getCharsSequence().subSequence(srcStart, srcEnd);
+
+ // Handle a situation when target ranges don't cross.
+ if (srcEnd <= dstStart || srcStart >= dstEnd) {
+ replaceString(dstStart, dstEnd, replacement);
+ int shift = 0;
+ if (dstStart < srcStart) {
+ shift = (dstEnd - dstStart) - (srcEnd - srcStart);
+ }
+ deleteString(srcStart + shift, srcEnd + shift);
+ return;
+ }
+
+ // _____|__________|__________|________|_____
+ // DstStart SrcStart DstEnd SrcEnd
+ if (dstStart <= srcStart && dstEnd <= srcEnd) {
+ if (dstEnd < srcEnd) {
+ deleteString(dstEnd, srcEnd);
+ }
+ replaceString(dstStart, dstEnd, replacement);
+ }
+ // _____|__________|__________|________|_____
+ // DstStart SrcStart SrcEnd DstEnd
+ // OR
+ // _____|__________|__________|________|_____
+ // SrcStart DstStart DstEnd SrcEnd
+ else if ((dstStart <= srcStart && dstEnd > srcEnd) || (dstStart > srcStart && dstEnd <= srcEnd)) {
+ replaceString(dstStart, dstEnd, replacement);
+ }
+ // _____|__________|__________|________|_____
+ // SrcStart DstStart SrcEnd DstEnd
+ else {
+ replaceString(dstStart, dstEnd, replacement);
+ deleteString(srcStart, dstStart);
+ }
}
@Override
diff --git a/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java b/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java
index 32f43d438160..5599dc3cdcc0 100644
--- a/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java
+++ b/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java
@@ -391,8 +391,9 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable
}
@Override
- public void copyText(int srcStart, int srcEnd, int dstStart, int dstEnd) {
- replaceString(dstStart, dstEnd, getCharsSequence().subSequence(srcStart, srcEnd));
+ public void moveText(int srcStart, int srcEnd, int dstStart, int dstEnd) {
+ // TODO den implement
+ throw new UnsupportedOperationException();
}
@Override
diff --git a/platform/testFramework/src/com/intellij/mock/MockDocument.java b/platform/testFramework/src/com/intellij/mock/MockDocument.java
index 37fb911b34e1..ebe9888f4c86 100644
--- a/platform/testFramework/src/com/intellij/mock/MockDocument.java
+++ b/platform/testFramework/src/com/intellij/mock/MockDocument.java
@@ -127,8 +127,9 @@ public class MockDocument implements DocumentEx {
}
@Override
- public void copyText(int srcStart, int srcEnd, int dstStart, int dstEnd) {
- replaceString(dstStart, dstEnd, getCharsSequence().subSequence(srcStart, srcEnd));
+ public void moveText(int srcStart, int srcEnd, int dstStart, int dstEnd) {
+ // TODO den implement
+ throw new UnsupportedOperationException();
}
@Override