From 5e815f5e4d6724e2d8783b5e977ecb8d02ced7b1 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Tue, 4 Sep 2012 17:55:29 +0400 Subject: [PATCH] IDEA-19061 Integrate the Rearranger-plugin into core-IDEA Refining API for range markers to survive rearrangement --- .../openapi/editor/ex/DocumentEx.java | 12 ++--- .../openapi/editor/impl/DocumentImpl.java | 45 ++++++++++++++++++- .../injected/editor/DocumentWindowImpl.java | 5 ++- .../src/com/intellij/mock/MockDocument.java | 5 ++- 4 files changed, 55 insertions(+), 12 deletions(-) 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. *

- * The benefit to use this method over usual {@link #replaceString(int, int, CharSequence)} is that - * {@link #createRangeMarker(int, int, boolean) range markers} from the [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