diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java b/platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java index 73571dc50082..6daa2db58134 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/SimpleEditorPreview.java @@ -69,10 +69,11 @@ public class SimpleEditorPreview implements PreviewPanel{ String text = page.getDemoText(); HighlightsExtractor extractant2 = new HighlightsExtractor(page.getAdditionalHighlightingTagToDescriptorMap()); - myHighlightData = extractant2.extractHighlights(text); - + List highlights = new ArrayList(); + String stripped = extractant2.extractHighlights(text, highlights); + myHighlightData = highlights.toArray(new HighlightData[highlights.size()]); int selectedLine = -1; - myEditor = (EditorEx)FontEditorPreview.createPreviewEditor(extractant2.cutDefinedTags(text), 10, 3, selectedLine, myOptions, false); + myEditor = (EditorEx)FontEditorPreview.createPreviewEditor(stripped, 10, 3, selectedLine, myOptions, false); FontEditorPreview.installTrafficLights(myEditor); myBlinkingAlarm = new Alarm().setActivationComponent(myEditor.getComponent()); diff --git a/platform/lang-impl/src/com/intellij/application/options/colors/highlighting/HighlightsExtractor.java b/platform/lang-impl/src/com/intellij/application/options/colors/highlighting/HighlightsExtractor.java index 189578a826ce..ee6325271b7f 100644 --- a/platform/lang-impl/src/com/intellij/application/options/colors/highlighting/HighlightsExtractor.java +++ b/platform/lang-impl/src/com/intellij/application/options/colors/highlighting/HighlightsExtractor.java @@ -20,6 +20,7 @@ package com.intellij.application.options.colors.highlighting; import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.util.TextRange; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.Nullable; @@ -36,20 +37,21 @@ public class HighlightsExtractor { private int mySkippedLen; private int myIndex; private boolean myIsOpeningTag; - private static final HighlightData[] EMPTY_DATA = new HighlightData[0]; + + private List mySkipped = new ArrayList(); public HighlightsExtractor(@Nullable Map tags) { myTags = tags; } - public HighlightData[] extractHighlights(String text) { - if (myTags == null || myTags.isEmpty()) return EMPTY_DATA; + public String extractHighlights(String text, List highlights) { + mySkipped.clear(); + if (myTags == null || myTags.isEmpty()) return text; resetIndices(); - List highlights = new ArrayList(); Stack highlightsStack = new Stack(); while (true) { String tagName = findTagName(text); - if (tagName == null) break; + if (tagName == null || myIndex < 0) break; if (myTags.containsKey(tagName)) { if (myIsOpeningTag) { mySkippedLen += tagName.length() + 2; @@ -64,7 +66,7 @@ public class HighlightsExtractor { } } - return highlights.toArray(new HighlightData[highlights.size()]); + return cutDefinedTags(text); } private String findTagName(String text) { @@ -84,15 +86,26 @@ public class HighlightsExtractor { myIndex = openTag + 1; return ""; } - + int closeTag = text.indexOf('>', openTag + 1); - if (closeTag == -1) return null; + if (closeTag == -1) return null; + int i = text.indexOf('<', openTag + 1); + if (i != -1 && i < closeTag) { + myIndex = i; + return ""; + } final String tagName = text.substring(openTag + 1, closeTag); if (myIsOpeningTag) { myStartOffset = openTag + tagName.length() + 2; + if (myTags.containsKey(tagName)) { + mySkipped.add(TextRange.from(openTag, tagName.length() + 2)); + } } else { myEndOffset = openTag - 1; + if (myTags.containsKey(tagName)) { + mySkipped.add(TextRange.from(openTag - 1, tagName.length() + 3)); + } } myIndex = Math.max(myStartOffset, myEndOffset + 1); return tagName; @@ -102,47 +115,13 @@ public class HighlightsExtractor { return Character.isLetter(c) || c == '_'; } - public String cutDefinedTags(String text) { - if (myTags == null || myTags.isEmpty()) return text; - - StringBuffer sb = new StringBuffer(); - int index = 0; - while (true) { - int from = text.indexOf('<', index); - if (from == -1) { - sb.append(text.substring(index, text.length())); - break; - } - while (text.charAt(from+1) == '<') { - from++; - } - int to = text.indexOf('>', from+1); - if (to == -1) { - sb.append(text.substring(index, text.length())); - break; - } - int tagNameStart = from + 1; - if (text.charAt(tagNameStart) == '/') { - tagNameStart ++; - } - - if (isValidTagFirstChar(text.charAt(tagNameStart))) { - String tag; - tag = text.substring(tagNameStart, to); - if (myTags.containsKey(tag)) { - sb.append(text.substring(index, from)); - index = to + 1; - continue; - } - } - else { - to = from; - } - sb.append(text.substring(index, to + 1)); - index = to + 1; + private String cutDefinedTags(String text) { + StringBuilder builder = new StringBuilder(text); + for (int i = mySkipped.size() - 1; i >= 0; i--) { + TextRange range = mySkipped.get(i); + builder.delete(range.getStartOffset(), range.getEndOffset()); } - - return sb.toString(); + return builder.toString(); } private void resetIndices() { diff --git a/platform/platform-resources-en/src/messages/OptionsBundle.properties b/platform/platform-resources-en/src/messages/OptionsBundle.properties index f92eab50fd5a..b1ff8c4f62a3 100644 --- a/platform/platform-resources-en/src/messages/OptionsBundle.properties +++ b/platform/platform-resources-en/src/messages/OptionsBundle.properties @@ -109,6 +109,7 @@ options.xml.attribute.descriptor.prologue=Prologue options.xml.attribute.descriptor.comment=Comment options.xml.attribute.descriptor.tag=Tag options.xml.attribute.descriptor.tag.name=Tag name +options.xml.attribute.descriptor.namespace.prefix=Namespace prefix options.xml.attribute.descriptor.attribute.name=Attribute name options.xml.attribute.descriptor.attribute.value=Attribute value options.xml.attribute.descriptor.tag.data=Tag data diff --git a/platform/platform-resources/src/META-INF/XmlPlugin.xml b/platform/platform-resources/src/META-INF/XmlPlugin.xml index 13e7e299f361..874f0bba2a76 100644 --- a/platform/platform-resources/src/META-INF/XmlPlugin.xml +++ b/platform/platform-resources/src/META-INF/XmlPlugin.xml @@ -112,6 +112,7 @@ + diff --git a/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlNsPrefixAnnotator.java b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlNsPrefixAnnotator.java new file mode 100644 index 000000000000..bbcef4ec74f0 --- /dev/null +++ b/xml/impl/src/com/intellij/codeInsight/daemon/impl/analysis/XmlNsPrefixAnnotator.java @@ -0,0 +1,49 @@ +/* + * Copyright 2000-2013 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.daemon.impl.analysis; + +import com.intellij.lang.annotation.AnnotationHolder; +import com.intellij.lang.annotation.Annotator; +import com.intellij.openapi.editor.XmlHighlighterColors; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.xml.SchemaPrefixReference; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.containers.FilteringIterator; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dmitry Avdeev + * Date: 25.10.13 + */ +public class XmlNsPrefixAnnotator implements Annotator { + @Override + public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) { + if (element instanceof XmlTag || element instanceof XmlAttribute) { + SchemaPrefixReference reference = + (SchemaPrefixReference)ContainerUtil.find(element.getReferences(), FilteringIterator.instanceOf(SchemaPrefixReference.class)); + if (reference != null) { + TextRange rangeInElement = reference.getRangeInElement(); + if (!rangeInElement.isEmpty()) { + TextRange range = rangeInElement.shiftRight(element.getTextRange().getStartOffset()); + holder.createInfoAnnotation(range, null).setTextAttributes(XmlHighlighterColors.XML_NS_PREFIX); + } + } + } + } +} diff --git a/xml/impl/src/com/intellij/openapi/options/colors/pages/XMLColorsPage.java b/xml/impl/src/com/intellij/openapi/options/colors/pages/XMLColorsPage.java index e968f73d8cb6..383284d0e70a 100644 --- a/xml/impl/src/com/intellij/openapi/options/colors/pages/XMLColorsPage.java +++ b/xml/impl/src/com/intellij/openapi/options/colors/pages/XMLColorsPage.java @@ -24,6 +24,8 @@ import com.intellij.openapi.options.OptionsBundle; import com.intellij.openapi.options.colors.AttributesDescriptor; import com.intellij.openapi.options.colors.ColorDescriptor; import com.intellij.openapi.options.colors.ColorSettingsPage; +import com.intellij.openapi.util.Pair; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -35,6 +37,7 @@ public class XMLColorsPage implements ColorSettingsPage { new AttributesDescriptor(OptionsBundle.message("options.xml.attribute.descriptor.comment"), XmlHighlighterColors.XML_COMMENT), new AttributesDescriptor(OptionsBundle.message("options.xml.attribute.descriptor.tag"), XmlHighlighterColors.XML_TAG), new AttributesDescriptor(OptionsBundle.message("options.xml.attribute.descriptor.tag.name"), XmlHighlighterColors.XML_TAG_NAME), + new AttributesDescriptor(OptionsBundle.message("options.xml.attribute.descriptor.namespace.prefix"), XmlHighlighterColors.XML_NS_PREFIX), new AttributesDescriptor(OptionsBundle.message("options.xml.attribute.descriptor.attribute.name"), XmlHighlighterColors.XML_ATTRIBUTE_NAME), new AttributesDescriptor(OptionsBundle.message("options.xml.attribute.descriptor.attribute.value"), XmlHighlighterColors.XML_ATTRIBUTE_VALUE), new AttributesDescriptor(OptionsBundle.message("options.xml.attribute.descriptor.tag.data"), XmlHighlighterColors.XML_TAG_DATA), @@ -70,17 +73,18 @@ public class XMLColorsPage implements ColorSettingsPage { return "\n" + "\n" + "\n" + - "\n" + + "pf=\"http://test\">\n" + " Main Index\n" + " \n" + " \n" + " \n" + " \n& ·" + - " \n" + + " " + + " <pf:foo pf:bar=\"bar\"/>\n" + ""; } public Map getAdditionalHighlightingTagToDescriptorMap() { - return null; + return ContainerUtil.newHashMap(Pair.create("np", XmlHighlighterColors.XML_NS_PREFIX)); } } \ No newline at end of file diff --git a/xml/openapi/src/com/intellij/openapi/editor/XmlHighlighterColors.java b/xml/openapi/src/com/intellij/openapi/editor/XmlHighlighterColors.java index 30ff8ec38e3e..403dc8b42d31 100644 --- a/xml/openapi/src/com/intellij/openapi/editor/XmlHighlighterColors.java +++ b/xml/openapi/src/com/intellij/openapi/editor/XmlHighlighterColors.java @@ -31,6 +31,8 @@ public class XmlHighlighterColors { TextAttributesKey.createTextAttributesKey("XML_TAG", DefaultLanguageHighlighterColors.MARKUP_TAG); public static final TextAttributesKey XML_TAG_NAME = TextAttributesKey.createTextAttributesKey("XML_TAG_NAME", DefaultLanguageHighlighterColors.KEYWORD); + public static final TextAttributesKey XML_NS_PREFIX = + TextAttributesKey.createTextAttributesKey("XML_NS_PREFIX", DefaultLanguageHighlighterColors.IDENTIFIER); public static final TextAttributesKey XML_ATTRIBUTE_NAME = TextAttributesKey.createTextAttributesKey("XML_ATTRIBUTE_NAME", DefaultLanguageHighlighterColors.MARKUP_ATTRIBUTE); public static final TextAttributesKey XML_ATTRIBUTE_VALUE =