diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlTagNameSynchronizer.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlTagNameSynchronizer.java index 64ce30213905..284b6bc7f9e5 100644 --- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlTagNameSynchronizer.java +++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlTagNameSynchronizer.java @@ -152,7 +152,6 @@ public class XmlTagNameSynchronizer extends CommandAdapter implements Applicatio if (file == null) return; - final SmartList leaders = new SmartList(); for (Caret caret : myEditor.getCaretModel().getAllCarets()) { final RangeMarker leader = createTagNameMarker(caret); @@ -277,7 +276,7 @@ public class XmlTagNameSynchronizer extends CommandAdapter implements Applicatio private static RangeMarker findSupport(RangeMarker leader, PsiFile file, Document document) { final PsiElement element = file.findElementAt(leader.getStartOffset()); PsiElement support = RenameTagBeginOrEndIntentionAction.findOtherSide(element, false); - support = support == null ? RenameTagBeginOrEndIntentionAction.findOtherSide(element, true) : support; + support = support == null || element == support ? RenameTagBeginOrEndIntentionAction.findOtherSide(element, true) : support; final TextRange range = support != null ? support.getTextRange() : null; return range != null ? document.createRangeMarker(range.getStartOffset(), range.getEndOffset(), true) : null; } diff --git a/xml/tests/src/com/intellij/codeInsight/completion/XmlSyncTagTest.java b/xml/tests/src/com/intellij/codeInsight/completion/XmlSyncTagTest.java new file mode 100644 index 000000000000..85f87a5644eb --- /dev/null +++ b/xml/tests/src/com/intellij/codeInsight/completion/XmlSyncTagTest.java @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.completion; + +import com.intellij.application.options.editor.WebEditorOptions; +import com.intellij.ide.highlighter.XmlFileType; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.actionSystem.DocCommandGroupId; +import com.intellij.testFramework.fixtures.LightPlatformCodeInsightFixtureTestCase; + +/** + * @author Dennis.Ushakov + */ +public class XmlSyncTagTest extends LightPlatformCodeInsightFixtureTestCase { + public void testStartToEnd() { + doTest(">", "v", ""); + } + + public void testEndToStart() { + doTest("
>", "v", ""); + } + + public void testLastCharDeleted() { + doTest(">
", "\b\b\b", "<>"); + } + + public void testSelection() { + doTest("<div>", "b", ""); + } + + public void testMultiCaret() { + doTest(">\n" + + ">\n", "v", + "\n" + + "\n"); + } + + public void testMultiCaretNested() { + doTest(">\n" + + ">\n" + + "", "v", + "\n" + + "\n" + + ""); + } + + public void testSpace() { + doTest(">", " ", "
"); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + WebEditorOptions.getInstance().setSyncTagEditing(true); + } + + @Override + protected void tearDown() throws Exception { + WebEditorOptions.getInstance().setSyncTagEditing(false); + super.tearDown(); + } + + private void doTest(final String text, final String toType, final String result) { + myFixture.configureByText(XmlFileType.INSTANCE, text); + CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + myFixture.type(toType); + } + }); + } + }, "Typing", DocCommandGroupId.noneGroupId(myFixture.getEditor().getDocument()), myFixture.getEditor().getDocument()); + myFixture.checkResult(result); + } + + @Override + protected boolean isWriteActionRequired() { + return false; + } +}