Xtext Content Assist: Filtering keyword proposals

Sometimes when I introduce template proposals in Xtext editors I want them to be a replacement for a keyword proposal. By default you would get a proposal for the template AND for the keyword. In the following screenshot a template for a “class” concept exists, and a proposal for the “class” keyword, which would be inserted as part of the template at the cursor position.

The key to the solution is to overwrite the completeKeyword() method from your proposal provider class, e.g. like this:

public class SprayProposalProvider extends AbstractSprayProposalProvider {
    private static final Set<String>      FILTERED_KEYWORDS = Sets.newHashSet("text", "line", "class", "behavior", "style", "custom");
    @Override
    public void completeKeyword(Keyword keyword, ContentAssistContext contentAssistContext, ICompletionProposalAcceptor acceptor) {
        if (FILTERED_KEYWORDS.contains(keyword.getValue())) {
            // don't propose keyword
            return;
        }
        super.completeKeyword(keyword, contentAssistContext, acceptor);
    }
}

Christian Dietrich added in a comment how to filter a keyword that may occur more than once in your grammar. If you want to filter specific occurances you need to use the IGrammarAccess of your language:

@Inject MyDslGrammarAccess grammarAccess;

@Override
public void completeKeyword(Keyword keyword,ContentAssistContext contentAssistContext,ICompletionProposalAcceptor acceptor) {
  if (!grammarAccess.getGreetingAccess().getHelloKeyword_0().equals(keyword)) {
    super.completeKeyword(keyword, contentAssistContext, acceptor);
  }
}

4 thoughts on “Xtext Content Assist: Filtering keyword proposals

  1. Very nice. We use this in our project very often (not only to filter stuff proposed by templates but for (optional) default values of enums too)
    There is one remark/addition i have: if you have one keyword more than once and you want to filter it only at a certain place use something like

    @Inject MyDslGrammarAccess grammarAccess;

    @Override
    public void completeKeyword(Keyword keyword,
    ContentAssistContext contentAssistContext,
    ICompletionProposalAcceptor acceptor) {
    if (!grammarAccess.getGreetingAccess().getHelloKeyword_0().equals(keyword)) {
    super.completeKeyword(keyword, contentAssistContext, acceptor);
    }
    }

  2. Thanks for the post – although, my AbstractDSLProposalProvider does not have any methods with the signature,

    public void complete*(Keyword keyword, …)

    I only see:

    public void complete*(EObject model, …)

    And I’m finding it to be a bit of a challenge to filter-out some of the default proposals.

  3. Hi guys .
    The code completion proposal should include some options as non-active options (i.e. cannot click/add them;)
    The options should be in the end of the list and greyed out.
    How can i disable options in content proposal?
    I could not find solution of this area but i guess i should use class ConfigurableCompletionProposal.
    It would be a nice to see some code example.
    Thanks.

Leave a reply to walk_n_wind Cancel reply