Enable completion autopopup inside PsiLiteral for my LookupElements Follow
Hello guys,
I have my own completion contributor
class TypeSafeConfCompletionContributor extends CompletionContributor { extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new CompletionProvider[CompletionParameters]() { def addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) { parameters.getPosition.getContext match { case literal: PsiLiteral if literal.getValue.isInstanceOf[String] => val text = literal.getValue.toString.replace(DummyId, "").replace(DummyIdTrimmed, "") val variants = getVariants(text, literal.getProject).map(_.getFirstChild.asInstanceOf[NodeName]).toSet val prefix = if (text.endsWith(".")) "" else if (text.contains(".")) text.split("\\.").last else text variants.foreach(v => resultSet.caseInsensitive().withPrefixMatcher(prefix).addElement(v.toLookup)) case _ => //just ignore } } } ) def getVariants(text: String, project: Project) = { val confFiles = ReferenceUtil.getFilesByType(project, TypeSafeConfFileType()) val nodeParts = (if (text.endsWith(".")) text + DummyIdTrimmed else text).split("\\.").toList val nodes = confFiles.map(_.getFirstChild.getChildren).flatten.toList getNodes(nodeParts.head, nodeParts.tail, nodes) } def getNodes(nodeName: String, nodeNames: List[String], nodes: List[PsiElement]): List[PsiElement] = { val n = filterNodes(nodeName, nodeNames.isEmpty, nodes) if (nodeNames.nonEmpty) getNodes(nodeNames.head, nodeNames.tail, n.map(_.getChildren).flatten) else n } def filterNodes(nodeName: String, lastNode: Boolean, nodes: List[PsiElement]) = { nodes.filter { case n: Node if nodeName == DummyIdTrimmed => true case n: Node if n.getFirstChild.isInstanceOf[NodeName] => if (lastNode) n.getFirstChild.getText startsWith nodeName else n.getFirstChild.getText == nodeName case _ => false } } }
It works fine inside PsiLiteral when I press Ctrl + Space
This is how it looks like inside Idea
My question is how to enable autopopup inside PsiLiteral with my own lookup elements?
Please sign in to leave a comment.
If you mean LookupElements in order to provide Psi Navigation then you shouldn't be using the Contributor API. That API is used within scenarios where you don't have a reference to a specific element, for instance a list of keywords available within a particular context.
You'll want to provide an implementation of PsiReferenceContributor in order to provide LookupElements + resolving support.
As a side note, you can use the intellij patterns for matching Psi Elements rather than Scala's pattern matching, which is useful in more complex scenarios.
Hopefully this answers your question, apologies if i've misunderstood.
Hi Alan,
Thank you very much for your answer and suggestion to use intellij patterns. I will take a look.
But I mean how to enable auto-appearing small window with completion variants instead of clicking Ctrl+Space. Like when in java you wrote object name than enter dot and can see autopopup with all methods. You don't need to press Ctrl+Space, because window appears automatically.
Thanks again!
Unfortunately I do not know the inner-workings of IJ's autocompletion - so I can't fully answer this question.
However, for my plugin this happens automatically when your caret is in a position in which psi reference contribution has successfully been invoked
i.e. I did not explicitly register this intention with the contributor/reference API.
Hopefully someone from JetBrains may be able to answer this question, otherwise you'll have to search through the code to find out the exact scenario in which this behaviour occurs :)
There's CompletionConfidence API (shouldSkipAutopopup method) to control whether to show the autopopup. You can register your own extension there and enable autopopup for your string literals. By default it's disabled by SkipAutopopupInStrings class, so make sure your extension has order="before javaSkipAutopopupInStrings" attribute.
Peter, thank you very much. It works fine for me.