// Copyright 2014 Pants project contributors (see CONTRIBUTORS.md). // Licensed under the Apache License, Version 2.0 (see LICENSE). package com.twitter.intellij.pants.completion; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.psi.PsiFile; import com.intellij.util.ProcessingContext; import com.jetbrains.python.psi.PyReferenceExpression; import com.twitter.intellij.pants.index.PantsBuildFileIndex; import com.twitter.intellij.pants.index.PantsTargetIndex; import com.twitter.intellij.pants.util.PantsUtil; import org.jetbrains.annotations.NotNull; import java.util.Collection; import static com.intellij.patterns.PlatformPatterns.psiElement; /** * todo: remove dirty hack after PyPreferenceCompletionProvider patch is merged in IntelliJ */ public class PantsCompletionContributor extends CompletionContributor { public PantsCompletionContributor() { extend( CompletionType.BASIC, psiElement().withParent(PyReferenceExpression.class), new TargetTypeCompletionProvider() ); extend( CompletionType.BASIC, psiElement(), new AbsoluteAddressesCompletionProvider() ); } /** * A completion provider for absolute addresses. * Given a project with the following structure: * <ul> * <li>some/nested/tool/BUILD</li> * <li>another/far/away/tool/BUILD</li> * </ul> * * This provider will add these two suggestions (regardless of the input): * <ul> * <li>`some/nested/tool`</li> * <li>`another/far/away/tool`</li> * </ul> * Note that the suggestions will be filtered by intellij further down the line. */ private static class AbsoluteAddressesCompletionProvider extends CompletionProvider<CompletionParameters> { @Override protected void addCompletions( @NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet set ) { final PsiFile psiFile = parameters.getOriginalFile(); if (!PantsUtil.isBUILDFileName(psiFile.getName())) { return; } Collection<String> addresses = PantsBuildFileIndex.getFiles(psiFile); for (String address : addresses) { set.addElement(LookupElementBuilder.create(address)); } } } /** * Provides completion for target types such as `java_library`. */ // See PantsCompletionTest#testTargets private static class TargetTypeCompletionProvider extends CompletionProvider<CompletionParameters> { @Override protected void addCompletions( @NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result ) { final PsiFile psiFile = parameters.getOriginalFile(); if (!PantsUtil.isBUILDFileName(psiFile.getName())) { return; } for (String alias : PantsTargetIndex.getTargets(psiFile.getProject())) { result.addElement(LookupElementBuilder.create(alias)); } } } }