// Copyright © 2010-2011, Esko Luontola <www.orfjackal.net> // This software is released under the Apache License 2.0. // The license text is at http://www.apache.org/licenses/LICENSE-2.0 package net.orfjackal.sbt.plugin.sbtlang; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.lang.ASTNode; import com.intellij.lang.LanguageWordCompletion; import com.intellij.openapi.project.DumbService; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PlainTextTokenTypes; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.tree.IElementType; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; import java.util.*; import static com.intellij.patterns.StandardPatterns.character; // TODO get completion variants from SBT over a telnet-like interface // TODO target this contributor to the SBT console in a more principled manner (rather than using the getContainingFile.getName == SbtLanguage.INSTACNCE.getID) // Adapted from WordCompletionContributor in IDEA core. public class SbtCompletionContributor extends CompletionContributor { @Override public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { if (parameters.getCompletionType() == CompletionType.BASIC && shouldPerformWordCompletion(parameters)) { addWordCompletionVariants(result, parameters, Collections.<String>emptySet()); } } public static void addWordCompletionVariants(CompletionResultSet result, CompletionParameters parameters, Set<String> excludes) { int startOffset = parameters.getOffset(); PsiElement insertedElement = parameters.getPosition(); // "test-only *A<CTRL-SPACE> -- opta" gives a prefix of "test-only *A" String prefix = insertedElement.getText().substring(0, startOffset); final CompletionResultSet plainResultSet = result.withPrefixMatcher(prefix); List<String> strings = Arrays.asList("compile", "run", "test:compile", "test", "project", "projects", "inspect", "show", "last", "last-grep"); for (String string : strings) { final LookupElement item = LookupElementBuilder.create(string); plainResultSet.addElement(item); } } private static boolean shouldPerformWordCompletion(CompletionParameters parameters) { final PsiElement insertedElement = parameters.getPosition(); final boolean dumb = DumbService.getInstance(insertedElement.getProject()).isDumb(); if (dumb) { return true; } // TODO Hackedy-hack. if (!insertedElement.getContainingFile().getName().equals("SBT")) { return false; } if (parameters.getInvocationCount() == 0) { return false; } final PsiFile file = insertedElement.getContainingFile(); final int startOffset = parameters.getOffset(); final PsiElement element = file.findElementAt(startOffset - 1); ASTNode textContainer = element != null ? element.getNode() : null; while (textContainer != null) { final IElementType elementType = textContainer.getElementType(); if (LanguageWordCompletion.INSTANCE.isEnabledIn(elementType) || elementType == PlainTextTokenTypes.PLAIN_TEXT) { return true; } textContainer = textContainer.getTreeParent(); } return false; } }