blob: 8f708b7805f37fa9bdb3d9618d08b74f647e923f [file] [log] [blame]
/*
* 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.
*/
/*
* Created by IntelliJ IDEA.
* User: mike
* Date: Jul 23, 2002
* Time: 3:15:07 PM
* To change template for new class use
* Code Style | Class Templates options (Tools | IDE Options).
*/
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.editorActions.XmlAutoPopupHandler;
import com.intellij.codeInsight.lookup.CharFilter;
import com.intellij.codeInsight.lookup.Lookup;
import com.intellij.lang.Language;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiErrorElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.xml.XmlDocument;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlText;
public class XmlCharFilter extends CharFilter {
public static boolean isInXmlContext(Lookup lookup) {
if (!lookup.isCompletion()) return false;
PsiElement psiElement = lookup.getPsiElement();
PsiFile file = lookup.getPsiFile();
if (!(file instanceof XmlFile) && psiElement != null) {
file = psiElement.getContainingFile();
}
if (file instanceof XmlFile) {
if (psiElement != null) {
PsiElement elementToTest = psiElement;
if (elementToTest instanceof PsiWhiteSpace) {
elementToTest = elementToTest.getParent(); // JSPX has whitespace with language Java
}
final Language language = elementToTest.getLanguage();
if (!(language instanceof XMLLanguage)) {
return false;
}
}
return true;
}
return false;
}
public static boolean isWithinTag(Lookup lookup) {
if (isInXmlContext(lookup)) {
PsiElement psiElement = lookup.getPsiElement();
final PsiElement parentElement = psiElement.getParent() != null ? psiElement.getParent():null;
String s;
return parentElement != null &&
( parentElement instanceof XmlTag ||
( parentElement instanceof PsiErrorElement &&
parentElement.getParent() instanceof XmlDocument
) ||
((parentElement instanceof XmlDocument || parentElement instanceof XmlText) &&
((s = psiElement.getText()).equals("<") || s.equals("\""))));
}
return false;
}
@Override
public Result acceptChar(char c, final int prefixLength, final Lookup lookup) {
if (!isInXmlContext(lookup)) return null;
if (Character.isJavaIdentifierPart(c)) return Result.ADD_TO_PREFIX;
switch(c){
case '-':
case ':':
return Result.ADD_TO_PREFIX;
case '/':
if (isWithinTag(lookup)) {
if (prefixLength > 0) {
return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
}
XmlAutoPopupHandler.autoPopupXmlLookup(lookup.getEditor().getProject(), lookup.getEditor());
return Result.HIDE_LOOKUP;
}
return Result.ADD_TO_PREFIX;
case '>': if (prefixLength > 0) {
return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
}
case '\'':
case '\"':
return Result.SELECT_ITEM_AND_FINISH_LOOKUP;
default:
return null;
}
}
}