From 6b55cf0b05dc99234ccda00f9b25b3da703dae42 Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Fri, 12 Mar 2010 17:40:00 +0300 Subject: [PATCH] test fix: implement replaceString in DocumentWindow --- .../completion/DummyIdentifierPatcher.java | 5 +- .../injected/editor/DocumentWindowImpl.java | 47 +++++++++++++++++-- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/DummyIdentifierPatcher.java b/platform/lang-api/src/com/intellij/codeInsight/completion/DummyIdentifierPatcher.java index b2d38b8f14b6..5f058270a5fb 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/DummyIdentifierPatcher.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/DummyIdentifierPatcher.java @@ -32,8 +32,9 @@ public class DummyIdentifierPatcher extends FileCopyPatcher { public void patchFileCopy(@NotNull final PsiFile fileCopy, @NotNull final Document document, @NotNull final OffsetMap map) { if (StringUtil.isEmpty(myDummyIdentifier)) return; - document.replaceString(map.getOffset(CompletionInitializationContext.START_OFFSET), map.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET), - myDummyIdentifier); + int startOffset = map.getOffset(CompletionInitializationContext.START_OFFSET); + int endOffset = map.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET); + document.replaceString(startOffset, endOffset, myDummyIdentifier); } @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 df80a4c384e5..7ea0829403ab 100644 --- a/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java +++ b/platform/lang-impl/src/com/intellij/injected/editor/DocumentWindowImpl.java @@ -27,6 +27,7 @@ import com.intellij.openapi.editor.ex.*; import com.intellij.openapi.editor.impl.DocumentImpl; import com.intellij.openapi.editor.markup.MarkupModel; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.ProperTextRange; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.UserDataHolderBase; @@ -40,8 +41,8 @@ import org.jetbrains.annotations.Nullable; import java.beans.PropertyChangeListener; import java.util.ArrayList; -import java.util.List; import java.util.Collections; +import java.util.List; /** * @author Alexey @@ -254,9 +255,47 @@ public class DocumentWindowImpl extends UserDataHolderBase implements Disposable startOffset += perfixLength; endOffset -= suffixLength; s = s.subSequence(perfixLength, s.length() - suffixLength); - - deleteString(startOffset, endOffset); - insertString(startOffset, s); + + doReplaceString(startOffset, endOffset, s); + } + + private void doReplaceString(int startOffset, int endOffset, CharSequence s) { + assert intersectWithEditable(new TextRange(startOffset, startOffset)) != null; + assert intersectWithEditable(new TextRange(endOffset, endOffset)) != null; + + List> hostRangesToModify = new ArrayList>(myShreds.size()); + + int offset = startOffset; + int curRangeStart = 0; + for (int i = 0; i < myShreds.size(); i++) { + PsiLanguageInjectionHost.Shred shred = myShreds.get(i); + curRangeStart += shred.prefix.length(); + if (offset < curRangeStart) offset = curRangeStart; + RangeMarker hostRange = shred.getHostRangeMarker(); + if (!hostRange.isValid()) continue; + int hostRangeLength = hostRange.getEndOffset() - hostRange.getStartOffset(); + TextRange range = TextRange.from(curRangeStart, hostRangeLength); + if (range.contains(offset) || range.getEndOffset() == offset/* in case of inserting at the end*/) { + TextRange rangeToModify = new TextRange(offset, Math.min(range.getEndOffset(), endOffset)); + TextRange hostRangeToModify = rangeToModify.shiftRight(hostRange.getStartOffset() - curRangeStart); + CharSequence toReplace = i == myShreds.size() - 1 ? s : s.subSequence(0, Math.min(hostRangeToModify.getLength(), s.length())); + s = s.subSequence(toReplace.length(), s.length()); + hostRangesToModify.add(Pair.create(hostRangeToModify, toReplace)); + offset = rangeToModify.getEndOffset(); + } + curRangeStart += hostRangeLength; + curRangeStart += shred.suffix.length(); + if (curRangeStart >= endOffset) break; + } + + int delta = 0; + for (Pair pair : hostRangesToModify) { + TextRange hostRange = pair.getFirst(); + CharSequence replace = pair.getSecond(); + + myDelegate.replaceString(hostRange.getStartOffset() + delta, hostRange.getEndOffset() + delta, replace); + delta -= hostRange.getLength() - replace.length(); + } } public boolean isWritable() { -- 2.32.0