CamelHumps, PsiReferenceContributor and a long list of fixed keywords

I have implemented a first version of a full Mathematica parser which runs now reasonable well even on larger files.
The most important type of completion I want to provide is to complete (camel-hump) identifier with the help of a large
constant list of possible function names available for Mathematica (about 5000 names). After reading the docs I implemented
and registered a first (very very) basic test class extending CompletionContributor

    public MathematicaFunctionCompletion() {
        extend(CompletionType.BASIC, psiElement().withElementType(MathematicaElementTypes.IDENTIFIER), new CompletionProvider<CompletionParameters>() {
            @Override
            protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result) {
                result.addElement(LookupElementBuilder.create("ListLinePlot"));
                result.addElement(LookupElementBuilder.create("Integrate"));
            }
        }
        );
    }



I have several questions which are hard for me to find out:

1. The added elements in result seem to be filtered automatically. When I type "Li" I don't get the whole list but only the ones that match *and* camel case seems to work already. Basically, I could just add all 5000 keywords to the results in each call of addCompletions which doesn't sound like a good idea. What is the preferred way? Should I create e.g. a final static List<LookupElement> and use result.addAllElements every time or should I myself prefilter the long list?

2. In Java editing I can expand the first suggestion by simply pressing space bar or even better by pressing . or (. I would like to have the same: Pressing space makes "Int" -> "Integrate", pressing "[" makes "Int" -> "Integrate[]" with coursor in the middle. How can I achieve such a behavior?

Cheers
Patrick

2 comments

1. You don't need to prefilter. The completion logic is designed to handle large amounts of items.
2. You need to provide an implementation of the CompletionConfidence interface.

0

Thanks Dmitry for the answer,

there are two three things I don't understand. My CompletionContributor constructor looks currently like this

    public MathematicaFunctionCompletion() {
        extend(CompletionType.BASIC, psiElement().withElementType(MathematicaElementTypes.IDENTIFIER), new CompletionProvider<CompletionParameters>() {
            @Override
            protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result) {
                final LinkedList names = FunctionInformationProvider.getSymbolNames();
                for (int i = 0; i < names.size(); i++) {
                    String n = (String) names.get(i);
                    LookupElementBuilder elm = LookupElementBuilder.create(n).withInsertHandler(MathematicaBracketInsertHandler.getInstance());
                    result.addElement(elm);
                }}});
    }



it gets all possible Mathematica function names from the FunctionInformationProvider and I hacked a MathematicaBracketInsertHandler so that brackets [ ] are inserted automatically (in Java this works only with ()) .

1. Unfortunately, the handleInsert method in MathematicaBracketInsertHandler is not triggered when I press "[". This means, when the completion window pops up, I can press almost all keys like Space, Return, ., ( to expand a completion but the most important [ does not trigger the expansion. Where are the keys registered which complete a suggestion? (SOLVED): please see here for the solution

2. The default matcher which used has one drawback. When I type "xes" it suggests me beside others "AxesEdge", "AxesLabel"... I implemented my own MathematicaCamelHumpMatcher extends PrefixMatcher
and like the PrefixMatcher base class the constructor wants a String prefix. I could plug this in with result.withPrefixMatcher() but then I would have to extract the "prefix" by looking at the current CompletionParameters. Unfortunately, the text of my PsiNamedElement is not updated properly so that the prefix stays the same even when I remove text and enter an different name during editing. And why doesn't the default matcher need the "prefix" argument? Can someone shed some light how this is supposed to be used? (SOLVED)


3. Last question is: How can I achieve that braces or brackets are not closed when I type a closing ] which is already closed? Example: I type Math.ab and expand to Math.abs(|) (cursour at |) when I now type another ) then this is not inserted because it's already there. (SOLVED):
I found the answer by digging in the Erlang Intellij Plugin which is a great resource. It is done by registering a "typedHandler" in plugin.xml

<typedHandler implementation="org.intellij.erlang.editor.ErlangBinaryTypedHandler" id="ErlangBinary"/>


Look at the implementation class and basically you can just copy it.

Cheers and many thanks
Patrick

0

Please sign in to leave a comment.