blob: 3bdfff047cb4f4e0bd9bd7c07ad523ee5fec7c1f [file] [log] [blame]
package org.eclipse.osbp.xtext.basic.ui.contentassist;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.osbp.xtext.basic.ui.BasicDSLDocumentationTranslator;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.common.ui.contentassist.TerminalsProposalProvider;
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal;
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext;
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor;
import org.eclipse.xtext.ui.editor.contentassist.PrefixMatcher;
import org.eclipse.xtext.util.Strings;
/**
*
* @author kraeling
*
* A derivation from the standard xtext (non-OSBP) class TerminalsProposalProvider that allows to add a description to dummy variables of
* a certain type like TRANSLATABLEID.
*/
public class TerminalsProposalProviderWithDescription extends TerminalsProposalProvider {
BasicDSLDocumentationTranslator translator;
public void setDocumentationTranslator(BasicDSLDocumentationTranslator translator)
{
this.translator = translator;
}
@Override
public void complete_ID(EObject model, RuleCall ruleCall, final ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
if (doCreateIdProposals()) {
PrefixMatcher newMatcher = new PrefixMatcher() {
@Override
public boolean isCandidateMatchingPrefix(String name, String prefix) {
String strippedName = name;
if (name.startsWith("^") && !prefix.startsWith("^")) {
strippedName = name.substring(1);
}
return context.getMatcher().isCandidateMatchingPrefix(strippedName, prefix);
}
};
ContentAssistContext myContext = context.copy().setMatcher(newMatcher).toContext();
String feature = getAssignedFeature(ruleCall);
String proposalText = feature != null ? feature : Strings.toFirstUpper(ruleCall.getRule().getName().toLowerCase());
String displayText = proposalText;
if (feature != null)
displayText = proposalText + " - " + ruleCall.getRule().getName();
// Add a description / translation if one exists.
displayText = enrichWithDescription(displayText, model, ruleCall.getRule().getName());
proposalText = getValueConverter().toString(proposalText, ruleCall.getRule().getName());
ICompletionProposal proposal = createCompletionProposal(proposalText, displayText, null, myContext);
if (proposal instanceof ConfigurableCompletionProposal) {
ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
configurable.setSelectionStart(configurable.getReplacementOffset());
configurable.setSelectionLength(proposalText.length());
configurable.setAutoInsertable(false);
configurable.setSimpleLinkedMode(myContext.getViewer(), '\t', ' ');
}
acceptor.accept(proposal);
}
}
private String getAssignedFeature(RuleCall call) {
Assignment ass = GrammarUtil.containingAssignment(call);
if (ass != null) {
String result = ass.getFeature();
if (result.equals(result.toLowerCase()))
result = Strings.toFirstUpper(result);
return result;
}
return null;
}
/**
*
* @param displayText A string with the name (and type) of a dummy variable for which we want a description.
* @param model The model in which the dummy variable is defined.
* @param feature The type of the dummy variable.
* @return The display text with an additional description from the associated i18n file for the model (if one exists).
*/
private String enrichWithDescription(String displayText, EObject model, String feature)
{
String result = displayText;
// The translation key needed for the i18n file can be derived from the translation key of the respective model.
// For example, if the model's translation key is "org.eclipse.osbp.xtext.perspective.Perspective", then
// the translation key of the dummy variable of type TRANSLATABLESTRING is "org.eclipse.osbp.xtext.perspective.TRANSLATABLESTRING"
String modelTranslationKey = BasicDSLDocumentationTranslator.getTranslatorKey(model);
int lastDotIndex = modelTranslationKey.lastIndexOf('.');
if (lastDotIndex > 0)
{
String featureTranslationKey = modelTranslationKey.substring(0, lastDotIndex + 1) + feature;
// Try to find a translation / documentation for the translation key.
if (translator != null)
{
String translated = translator.getDocumentation(featureTranslationKey, true);
if (translated == null) {
translated = "";
} else {
// --- if the documentation contains more than one line, use only
// the first line ---
translated = " - " + (translated.split("<br>"))[0];
}
result = result + translated;
}
}
return result;
}
@Override
public void complete_STRING(EObject model, RuleCall ruleCall, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
if (doCreateStringProposals()) {
String feature = getAssignedFeature(ruleCall);
createStringProposal(context, acceptor, feature, ruleCall);
}
}
private void createStringProposal(ContentAssistContext context, ICompletionProposalAcceptor acceptor,
String feature, RuleCall ruleCall) {
String proposalText = feature != null ? feature : Strings.toFirstUpper(ruleCall.getRule().getName().toLowerCase());
proposalText = getValueConverter().toString(proposalText, ruleCall.getRule().getName());
String displayText = proposalText;
if (feature != null)
displayText = displayText + " - " + ruleCall.getRule().getName();
ICompletionProposal proposal = createCompletionProposal(proposalText, displayText, null, context);
if (proposal instanceof ConfigurableCompletionProposal) {
ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
configurable.setSelectionStart(configurable.getReplacementOffset() + 1);
configurable.setSelectionLength(proposalText.length() - 2);
configurable.setAutoInsertable(false);
configurable.setSimpleLinkedMode(context.getViewer(), proposalText.charAt(0), '\t');
}
acceptor.accept(proposal);
}
@Override
public void complete_INT(EObject model, RuleCall ruleCall, ContentAssistContext context,
ICompletionProposalAcceptor acceptor) {
String feature = getAssignedFeature(ruleCall);
if (doCreateIntProposals()) {
createIntProposal(context, acceptor, ruleCall, feature, 1);
}
}
private void createIntProposal(ContentAssistContext context, ICompletionProposalAcceptor acceptor,
RuleCall ruleCall, String feature, int i) {
String proposalText = getValueConverter().toString(i, ruleCall.getRule().getName());
String displayText = proposalText + " - " + ruleCall.getRule().getName();
if (feature != null)
displayText = proposalText + " - " + feature;
ICompletionProposal proposal = createCompletionProposal(proposalText, displayText, null, context);
if (proposal instanceof ConfigurableCompletionProposal) {
ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal;
configurable.setSelectionStart(configurable.getReplacementOffset());
configurable.setSelectionLength(proposalText.length());
configurable.setAutoInsertable(false);
configurable.setSimpleLinkedMode(context.getViewer(), '\t', ' ');
}
acceptor.accept(proposal);
}
}