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



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
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