From 613205a804fd33bad93a24699ce173d5a3a73b2d Mon Sep 17 00:00:00 2001 From: Gregory Shrago Date: Mon, 12 Jul 2010 14:34:44 +0400 Subject: [PATCH] several quickedit (sql in xml) exception fixes --- .../util/containers/ContainerUtil.java | 4 +-- .../inject/quickedit/QuickEditAction.java | 20 +++++++++--- .../impl/manipulators/XmlTextManipulator.java | 31 ++++++++++++++----- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/platform/util/src/com/intellij/util/containers/ContainerUtil.java b/platform/util/src/com/intellij/util/containers/ContainerUtil.java index 99c8b10ffd4d..72747aca1c59 100644 --- a/platform/util/src/com/intellij/util/containers/ContainerUtil.java +++ b/platform/util/src/com/intellij/util/containers/ContainerUtil.java @@ -148,8 +148,8 @@ public class ContainerUtil { return hashMap; } - public static HashMap> classify(Iterator iterator, Convertor keyConvertor) { - HashMap> hashMap = new HashMap>(); + public static Map> classify(Iterator iterator, Convertor keyConvertor) { + Map> hashMap = new LinkedHashMap>(); while (iterator.hasNext()) { V value = iterator.next(); final K key = keyConvertor.convert(value); diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/quickedit/QuickEditAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/quickedit/QuickEditAction.java index 5fb44b4e2647..c94135fc6765 100644 --- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/quickedit/QuickEditAction.java +++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/quickedit/QuickEditAction.java @@ -45,6 +45,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.impl.source.PostprocessReformattingAspect; import com.intellij.psi.impl.source.resolve.FileContextUtil; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.impl.source.tree.injected.Place; @@ -292,7 +293,12 @@ public class QuickEditAction implements IntentionAction { new WriteCommandAction.Simple(myProject, origFile) { @Override protected void run() throws Throwable { - commitToOriginalInner(); + PostprocessReformattingAspect.getInstance(myProject).disablePostprocessFormattingInside(new Runnable() { + @Override + public void run() { + commitToOriginalInner(); + } + }); } }.execute(); } @@ -307,11 +313,14 @@ public class QuickEditAction implements IntentionAction { .classify(myMarkers.entrySet().iterator(), new Convertor>, PsiLanguageInjectionHost>() { public PsiLanguageInjectionHost convert(final Map.Entry> o) { - return (PsiLanguageInjectionHost)o.getKey().getElement(); + final PsiElement element = o.getKey().getElement(); + return (PsiLanguageInjectionHost)element; } }); PsiDocumentManager.getInstance(myProject).commitDocument(myOrigDocument); + int localInsideFileCursor = 0; for (PsiLanguageInjectionHost host : map.keySet()) { + if (host == null) continue; final String hostText = host.getText(); TextRange insideHost = null; final StringBuilder sb = new StringBuilder(); @@ -321,12 +330,13 @@ public class QuickEditAction implements IntentionAction { final TextRange localInsideHost = new TextRange(origMarker.getStartOffset() - hostOffset, origMarker.getEndOffset() - hostOffset); final RangeMarker rangeMarker = entry.getValue().second; - final TextRange localInsideFile = new TextRange(rangeMarker.getStartOffset(), rangeMarker.getEndOffset()); + final TextRange localInsideFile = new TextRange(Math.max(localInsideFileCursor, rangeMarker.getStartOffset()), rangeMarker.getEndOffset()); if (insideHost != null) { + //append unchanged inter-markers fragment sb.append(hostText.substring(insideHost.getEndOffset(), localInsideHost.getStartOffset())); } - sb.append(localInsideFile.getEndOffset() <= text.length()? localInsideFile.substring(text) : ""); - + sb.append(localInsideFile.getEndOffset() <= text.length() && !localInsideFile.isEmpty()? localInsideFile.substring(text) : ""); + localInsideFileCursor = localInsideFile.getEndOffset(); insideHost = insideHost == null ? localInsideHost : insideHost.union(localInsideHost); } assert insideHost != null; diff --git a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlTextManipulator.java b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlTextManipulator.java index 3e734d337b04..6c9e1c444782 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlTextManipulator.java +++ b/xml/impl/src/com/intellij/psi/impl/source/resolve/reference/impl/manipulators/XmlTextManipulator.java @@ -16,8 +16,10 @@ package com.intellij.psi.impl.source.resolve.reference.impl.manipulators; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.psi.AbstractElementManipulator; +import com.intellij.psi.PsiElement; import com.intellij.psi.xml.XmlText; import com.intellij.util.IncorrectOperationException; @@ -27,14 +29,27 @@ import com.intellij.util.IncorrectOperationException; public class XmlTextManipulator extends AbstractElementManipulator { public XmlText handleContentChange(XmlText text, TextRange range, String newContent) throws IncorrectOperationException { - - final StringBuilder replacement = new StringBuilder(text.getValue()); - replacement.replace( - range.getStartOffset(), - range.getEndOffset(), - newContent - ); - text.setValue(replacement.toString()); + final String newValue; + final String value = text.getValue(); + if (range.equals(getRangeInElement(text))) { + newValue = newContent; + } + else { + final StringBuilder replacement = new StringBuilder(value); + replacement.replace( + range.getStartOffset(), + range.getEndOffset(), + newContent + ); + newValue = replacement.toString(); + } + if (Comparing.equal(value, newValue)) return text; + if (newValue.length() > 0) { + text.setValue(newValue); + } + else { + text.deleteChildRange(text.getFirstChild(), text.getLastChild()); + } return text; }