IDEA-19061 Integrate the Rearranger-plugin into core-IDEA

Preserve range markers on arrangement
This commit is contained in:
Denis.Zhdanov
2012-09-11 16:23:18 +04:00
parent 57c79a2ed9
commit d3b1c245f2
3 changed files with 34 additions and 46 deletions
@@ -372,7 +372,8 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx {
assertBounds(srcStart, srcEnd);
ProperTextRange srcRange = new ProperTextRange(srcStart, srcEnd);
if (dstOffset == srcEnd) return;
assert !srcRange.containsOffset(dstOffset);
assert !srcRange.containsOffset(dstOffset) :
String.format("Can't perform text move from range [%d; %d) to offset %d", srcStart, srcEnd, dstOffset);
//CharSequence replacement = getCharsSequence().subSequence(srcStart, srcEnd);
String replacement = getCharsSequence().subSequence(srcStart, srcEnd).toString();
@@ -322,15 +322,12 @@ public class ArrangementEngine {
previous = wrapper;
}
Changer changer;
// TODO den remove
changer = new NormalChanger();
// TODO den uncomment
//if (document instanceof DocumentEx) {
// changer = new RangeMarkerAwareChanger<T>((DocumentEx)document);
//}
//else {
// changer = new NormalChanger();
//}
if (document instanceof DocumentEx) {
changer = new RangeMarkerAwareChanger<T>((DocumentEx)document);
}
else {
changer = new DefaultChanger();
}
return new Context<T>(rearranger, wrappers, document, rules, settings, changer);
}
}
@@ -365,7 +362,7 @@ public class ArrangementEngine {
@NotNull Context<E> context);
}
private static class NormalChanger<E extends ArrangementEntry> implements Changer<E> {
private static class DefaultChanger<E extends ArrangementEntry> implements Changer<E> {
@NotNull private String myParentText;
private int myParentShift;
@@ -463,7 +460,7 @@ public class ArrangementEngine {
private static class RangeMarkerAwareChanger<E extends ArrangementEntry> implements Changer<E> {
@NotNull private final Set<ArrangementEntryWrapper<E>> myNotMoved = new HashSet<ArrangementEntryWrapper<E>>();
@NotNull private final List<ArrangementEntryWrapper<E>> myWrappers = new ArrayList<ArrangementEntryWrapper<E>>();
@NotNull private final DocumentEx myDocument;
RangeMarkerAwareChanger(@NotNull DocumentEx document) {
@@ -472,8 +469,8 @@ public class ArrangementEngine {
@Override
public void prepare(@NotNull List<ArrangementEntryWrapper<E>> toArrange, @NotNull Context<E> context) {
myNotMoved.clear();
myNotMoved.addAll(toArrange);
myWrappers.clear();
myWrappers.addAll(toArrange);
for (ArrangementEntryWrapper<E> wrapper : toArrange) {
wrapper.updateBlankLines(myDocument);
}
@@ -503,28 +500,32 @@ public class ArrangementEngine {
if (oldWrapper.getStartOffset() > newWrapper.getStartOffset()) {
insertionOffset -= newWrapper.getEndOffset() - newWrapper.getStartOffset();
}
myDocument.moveText(newWrapper.getStartOffset(), newWrapper.getEndOffset(), oldWrapper.getStartOffset());
newWrapper.placeBefore(oldWrapper);
myNotMoved.remove(newWrapper);
for (ArrangementEntryWrapper<E> w : myNotMoved) {
if (w.getStartOffset() >= oldWrapper.getStartOffset() && w.getStartOffset() < newWrapper.getStartOffset()) {
w.applyShift(newWrapper.getEndOffset() - newWrapper.getStartOffset());
}
else if (w.getStartOffset() < oldWrapper.getStartOffset() && w.getStartOffset() > newWrapper.getStartOffset()) {
w.applyShift(newWrapper.getStartOffset() - newWrapper.getEndOffset());
if (newWrapper.getStartOffset() != oldWrapper.getStartOffset() || !newWrapper.equals(oldWrapper)) {
myDocument.moveText(newWrapper.getStartOffset(), newWrapper.getEndOffset(), oldWrapper.getStartOffset());
for (int i = myWrappers.size() - 1; i >= 0; i--) {
ArrangementEntryWrapper<E> w = myWrappers.get(i);
if (w == newWrapper) {
continue;
}
if (w.getStartOffset() >= oldWrapper.getStartOffset() && w.getStartOffset() < newWrapper.getStartOffset()) {
w.applyShift(newWrapper.getEndOffset() - newWrapper.getStartOffset());
}
else if (w.getStartOffset() < oldWrapper.getStartOffset() && w.getStartOffset() > newWrapper.getStartOffset()) {
w.applyShift(newWrapper.getStartOffset() - newWrapper.getEndOffset());
}
}
}
if (desiredBlankLinesNumber >= 0 && lineFeedsDiff > 0) {
myDocument.insertString(insertionOffset, StringUtil.repeat("\n", lineFeedsDiff));
shiftOffsets(newWrapper, null, lineFeedsDiff);
shiftOffsets(lineFeedsDiff, insertionOffset);
}
if (desiredBlankLinesNumber >= 0 && lineFeedsDiff < 0) {
// Cut exceeding blank lines.
int replacementStartOffset = getBlankLineOffset(-lineFeedsDiff, insertionOffset);
myDocument.deleteString(replacementStartOffset, insertionOffset);
shiftOffsets(oldWrapper, null, lineFeedsDiff);
shiftOffsets(replacementStartOffset - insertionOffset, insertionOffset);
}
// Update wrapper ranges.
@@ -556,17 +557,18 @@ public class ArrangementEngine {
CharSequence text = myDocument.getCharsSequence();
for (int i = myDocument.getLineStartOffset(startLine - 1) - 1; i >= 0; i = CharArrayUtil.lastIndexOf(text, "\n", i - 1)) {
if (--blankLinesNumber <= 0) {
return i;
return i + 1;
}
}
return 0;
}
private static void shiftOffsets(@Nullable ArrangementEntryWrapper<?> first, @Nullable ArrangementEntryWrapper<?> last, int shift) {
if (first == null) {
return;
}
for (ArrangementEntryWrapper<?> wrapper = first; wrapper != null && wrapper != last; wrapper = wrapper.getNext()) {
private void shiftOffsets(int shift, int changeOffset) {
for (int i = myWrappers.size() - 1; i >= 0; i--) {
ArrangementEntryWrapper<E> wrapper = myWrappers.get(i);
if (wrapper.getStartOffset() < changeOffset) {
break;
}
wrapper.applyShift(shift);
}
}
@@ -113,21 +113,6 @@ public class ArrangementEntryWrapper<E extends ArrangementEntry> {
return myNext;
}
public void placeBefore(@NotNull ArrangementEntryWrapper<E> anchor) {
if (myNext != null) {
myNext.setPrevious(myPrevious);
}
if (myPrevious != null) {
myPrevious.setNext(myNext);
}
setPrevious(anchor.getPrevious());
if (myPrevious != null) {
myPrevious.setNext(this);
}
setNext(anchor);
anchor.setPrevious(this);
}
public int getBlankLinesBefore() {
return myBlankLinesBefore;
}