Karsten's Blog

May 22, 2012

Xtext Content Assist: Filtering keyword proposals

Filed under: Xtext — Tags: — kthoms @ 8:37 PM

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);
  }
}
About these ads

3 Comments »

  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);
    }
    }

    Comment by Christian Dietrich — May 23, 2012 @ 6:21 PM

  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.

    Comment by walk_n_wind — June 4, 2012 @ 9:19 PM

    • Whoops – I misunderstood. This completeKeyword method comes from AbstractJavaBasedContentProposalProvider. It works! Thanks for the post!

      Comment by walk_n_wind — June 5, 2012 @ 3:39 PM


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Silver is the New Black Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 375 other followers

%d bloggers like this: