How to implement code completion for Velocity method's parameter?

I have following code:
  $control.setTemplate("<caret>")
I want to implement code completion when Ctrl+Space pressed. I wonder how to implement it? I want to use following code :
   registrar.registerReferenceProvider(filter, referenceProvider)
I don't know which type should be used for ElementPattern. Any idea?

5 comments
Comment actions Permalink

I have following code:
$control.setTemplate("<caret>")
I want to implement code completion when Ctrl+Space pressed. I wonder how to implement it? I want to use following code :
registrar.registerReferenceProvider(filter, referenceProvider)
I don't know which type should be used for ElementPattern. Any idea?


The pattern describes the location in file (see PlatformPatterns). The
PSI element will probably be VtlStringLiteral.

And what do you want to suggest?

0
Comment actions Permalink

Hi Perter,  the following is my plugin code:


public class VelocityTemplateCallFilter implements ElementPattern<VtlLiteralExpressionType.VtlStringLiteral> {
    public boolean accepts(@Nullable Object o) {
        return false;
    }

    public boolean accepts(@Nullable Object o, ProcessingContext processingContext) {
        return false; 
    }

    public ElementPatternCondition<VtlLiteralExpressionType.VtlStringLiteral> getCondition() {
        return new ElementPatternCondition<VtlLiteralExpressionType.VtlStringLiteral>(new InitialPatternCondition<VtlLiteralExpressionType.VtlStringLiteral>(VtlLiteralExpressionType.VtlStringLiteral.class) {
            @Override
            public boolean accepts(@Nullable Object o, ProcessingContext processingContext) {
                return super.accepts(o, processingContext);
            }
        });
    }
}

In the velocity template file:
  $control.setTemplate("<caret>")

I have set two break points in 'accepts' method, and none works.  I make something wrong?





Attachment(s):
velocity_literal.PNG
0
Comment actions Permalink

Don't try to implement ElementPattern, use
PlatformPatterns.psiElement().withParent(VtlLiteralExpressionType.VtlStringLiteral.class)
instead. 'withParent()' is there because the pattern will be applied to
the leaf element which (AFAIR) has string literal composite as its
parent. You have to register this filter in the constructor of your
CompletionContributor, and register the latter in plugin.xml. You can
debug by putting a breakpoint in CompletionService.performCompletion()
method.

Still, what are you completing?

0
Comment actions Permalink

Perter, I have implement code completion in Java for a framework, just like this:
   control.setTemplate("<caret>");
I use PsiLiteralExpression to implement code completion for Java. But in Velocity template, the following code can not work:
  $control.setTemplate("<caret>")
$control has been associated to Java type by @vtlvariable.  I want to implement code completion just like in Java for Velocity template.
The following is my code for contributor, and I has registed in plugin.xml and I found no break point work in PsiReference, and it does not work.


public class VelocityTemplateCallContributor extends PsiReferenceContributor {
    public void registerReferenceProviders(PsiReferenceRegistrar registrar) {
        registrar.registerReferenceProvider(PlatformPatterns.psiElement().withParent(VtlLiteralExpressionType.VtlStringLiteral.class), new BaseReferenceProvider() {
            @NotNull
            @Override
            public PsiReference[] getReferencesByElement(final @NotNull PsiElement element, @NotNull ProcessingContext context) {
                return new PsiReference[]{new PsiReference() {
                    public PsiElement getElement() {
                        return element;  //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public TextRange getRangeInElement() {
                          return new TextRange(1, getElement().getText().length() + 1);
                    }

                    public PsiElement resolve() {
                        return null;  //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public String getCanonicalText() {
                        return null;  //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public PsiElement handleElementRename(String s) throws IncorrectOperationException {
                        return null;  //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public PsiElement bindToElement(@NotNull PsiElement psiElement) throws IncorrectOperationException {
                        return null;  //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public boolean isReferenceTo(PsiElement psiElement) {
                        return false;  //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public Object[] getVariants() {
                        return new Object[0];  //To change body of implemented methods use File | Settings | File Templates.
                    }

                    public boolean isSoft() {
                        return false;  //To change body of implemented methods use File | Settings | File Templates.
                    }
                }};
            }
        });
    }
}





Attachment(s):
velocity_code_completion.PNG
0
Comment actions Permalink

PsiReferences cannot be injected in Velocity string literals, you'll
have to write a CompletionContributor instead, check the correct place
there (via the same pattern) and provide the variants to
CompletionResultSet.

0

Please sign in to leave a comment.