How To Implement Autocompletion Without a Grammar/Parser/Lexer


I currently try to implement a very basic plugin. It should work as a "custom language". It should be active if a file matches a specific file name and should provide basic auto completion in this file. I started with this tutorial. What works so far is that my plugin is automatically associated with the file if the file matches a specific name (I see my custom icon in the editor). That is cool. Now I try to implement the autocompletion. For the time being, the autocompletion should simply suggest the files and folders relative to the file location. Hence, given this structure:


If the file mycustomfile is opened, the autocompletion should suggest "dir1". If one enters "dir1/", it should suggest "dir2" etc.

In my plugin.xml, I added the following code in between the <extensions> tags:

    <completion.contributor language="Mylanguage" implementationClass=""/>

Here is my contribution class:

package; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.patterns.StandardPatterns; import com.intellij.psi.PsiElement; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; public class MylanguageCompletionContributor extends CompletionContributor {     public MylanguageCompletionContributor() {         System.out.println("MylanguageCompletionContributor ----------------------------------------------------------");         extend(CompletionType.BASIC,                 StandardPatterns.instanceOf(PsiElement.class),                 new CompletionProvider<CompletionParameters>() {                     public void addCompletions(@NotNull CompletionParameters parameters,                                                ProcessingContext context,                                                @NotNull CompletionResultSet resultSet) {                         <!-- just to make sure this is called -->                         System.out.println("addCompletions ----------------------------------------------------------");                         <!-- just as a test -->                         resultSet.addElement(LookupElementBuilder.create("Hello"));                     }                 }         );     } }

Unfortunately, my contributor is never called and no auto completion works at all. If I attach the contributor to the "JAVA" language in the plugin.xml, my contributor is called and the element "Hello" is suggested.

I guess the problem is that the elements in my editor are not of type PsiElement, so that the completion is not called. What do I need to do so that auto completion still works? I do not want to write a grammar/parser/lexer. I only want to suggest the folder and file names.

By the way, the gitignore plugin has such a folder/file completion, but I cannot see how it is done in there.

Thanks a lot for any input in advance!

Comment actions Permalink

Please refer to PlainTextParserDefinition in the IntelliJ IDEA Community Edition source code for an example of a minimal parser that parses the entire contents of a file as a single element. You can copy its implementation into your plugin, and it should be enough to get your completion contributor to work.

Comment actions Permalink

Thanks Dmitry! How am I supposed to integrate the PlainTextParserDefinition into my plugin/language? I tried it with the following entry in the plugin.xml, but this did not help:

<lang.parserDefinition language="Mylanguage" implementationClass="com.intellij.openapi.fileTypes.PlainTextParserDefinition"/>
Comment actions Permalink

The implementation is tied to the specific language, so you can't integrate it directly; you need to provide your own class that does the same thing.

Comment actions Permalink

Ah thanks. I did that now, and include it via:

<lang.parserDefinition language="Mylanguage" implementationClass=""/>

But this still does not help - my contributor is not called. Any other idea?

Comment actions Permalink

Do you use your own language in your IFileElementType implementation, and your own token type in your implementation of parseContents()? As I said, the implementation depends on the language. If you simply copy PlainTextParserDefinition, it will parse the contents of your file as an element with plain text language, which is not what you want.

Comment actions Permalink

Okay, indeed, I had to implement and use a few custom classes, so that the implementation is tied to my specific "language". Thanks! For those who are interested in how it is done, the code will be published on GitHub once the main functionality is implemented.

Now I still need to know if there is a standard contributor which can be used to provide completion of paths, but I will open a new thread for that.


Please sign in to leave a comment.