package org.jetbrains.plugins.clojure.psi.resolve.completion; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Ref; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; import org.jetbrains.plugins.clojure.psi.api.symbols.ClSymbol; /** * @author Alefas * @since 15.01.13 */ public class ClojureCompletionContributor extends CompletionContributor { @Override public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) { super.fillCompletionVariants(parameters, result); if (parameters.getCompletionType() != CompletionType.BASIC) return; //only basic completion is here result.restartCompletionWhenNothingMatches(); final PsiElement position = parameters.getPosition(); final PsiElement parent = position.getParent(); final boolean isClassName = ClojureClassNameCompletionContributor.shouldRunClassName(parameters, result.getPrefixMatcher(), true); if (parent instanceof ClSymbol) { ClSymbol symbol = (ClSymbol) parent; final Object[] variants = symbol.getVariants(); Ref<Boolean> elementAdded = new Ref<Boolean>(Boolean.FALSE); for (Object variant : variants) { if (variant instanceof ClojureLookupItem) { ClojureLookupItem lookupItem = (ClojureLookupItem) variant; final PsiElement element = lookupItem.getPsiElement(); if (element instanceof PsiClass) { final PsiClass clazz = (PsiClass) element; boolean isExcluded = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() { public Boolean compute() { return JavaCompletionUtil.isInExcludedPackage(clazz, true); } }); if (!isExcluded && !isClassName) { addElement(result, lookupItem, elementAdded); } } else { addElement(result, lookupItem, elementAdded); } } else if (variant instanceof LookupElement) { addElement(result, (LookupElement) variant, elementAdded); } } if (!elementAdded.get() && !isClassName && ClojureClassNameCompletionContributor.shouldRunClassName(parameters, result.getPrefixMatcher(), false)) { ClojureClassNameCompletionContributor.completeClassName(parameters, result); } result.stopHere(); //we want to handle all Clojure completion, so we don't need anything more } } private void addElement(CompletionResultSet result, LookupElement lookupItem, Ref<Boolean> elementAdded) { if (result.getPrefixMatcher().prefixMatches(lookupItem)) { elementAdded.set(Boolean.TRUE); } result.addElement(lookupItem); } }