Fixed: [ Issue 42 ] Add content-assist options for "syntax" https://code.google.com/p/protobuf-dt/issues/detail?id=42
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java index 699bc0a..dab24e0 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
@@ -26,7 +26,7 @@ import com.google.eclipse.protobuf.protobuf.*; import com.google.eclipse.protobuf.protobuf.Enum; import com.google.eclipse.protobuf.scoping.Globals; -import com.google.eclipse.protobuf.ui.grammar.CommonKeyword; +import com.google.eclipse.protobuf.ui.grammar.*; import com.google.eclipse.protobuf.ui.grammar.CompoundElement; import com.google.eclipse.protobuf.ui.labeling.Images; import com.google.eclipse.protobuf.ui.util.*; @@ -40,6 +40,8 @@ */ public class ProtobufProposalProvider extends AbstractProtobufProposalProvider { + private static final String SPACE = " "; + @Inject private ProtobufElementFinder finder; @Inject private Globals globals; @Inject private PluginImageHelper imageHelper; @@ -48,6 +50,22 @@ @Inject private Properties properties; @Inject private Strings strings; + /** {@inheritDoc} */ + @Override public void completeProtobuf_Syntax(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + } + + @Override public void completeSyntax_Name(EObject model, Assignment assignment, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + proposeAndAccept(PROTO2_IN_QUOTES, context, acceptor); + } + + @Override public void complete_Syntax(EObject model, RuleCall ruleCall, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { + String proposal = SYNTAX + SPACE + EQUAL_PROTO2_IN_QUOTES; + proposeAndAccept(proposal, imageHelper.getImage(imageRegistry.imageFor(Syntax.class)), context, acceptor); + } + @Override public void completeOption_Name(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { EObject container = model.eContainer(); @@ -60,7 +78,7 @@ private void proposeCommonFileOptions(ContentAssistContext context, ICompletionProposalAcceptor acceptor) { for (Property fileOption : globals.fileOptions()) { String displayString = fileOption.getName(); - String proposalText = displayString + " " + EQUAL + " "; + String proposalText = displayString + SPACE + EQUAL + SPACE; boolean isStringOption = properties.isString(fileOption); if (isStringOption) proposalText = proposalText + EMPTY_STRING + SEMICOLON; @@ -119,17 +137,17 @@ proposeEmptyString(context, acceptor); return; } - if (model instanceof Option) return; + if (model instanceof Option || model instanceof Syntax) return; + for (AbstractElement element : context.getFirstSetGrammarElements()) { + if (!(element instanceof Assignment)) continue; + Assignment assignment = (Assignment) element; + if (EQUAL.hasValue(assignment.getOperator()) && assignment.getFeature().equals("name")) return; + } super.complete_STRING(model, ruleCall, context, acceptor); } private void proposeEmptyString(ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - ICompletionProposal proposal = createCompletionProposal(EMPTY_STRING, context); - if (proposal instanceof ConfigurableCompletionProposal) { - ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal; - configurable.setCursorPosition(1); - } - acceptor.accept(proposal); + createAndAccept(EMPTY_STRING, 1, context, acceptor); } private boolean isProposalForDefaultValue(ContentAssistContext context) { @@ -155,9 +173,17 @@ } private boolean completeKeyword(String keyword, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - if (isKeywordEqualToPreviousWordInEditor(keyword, context)) return true; - if (TRUE.hasValue(keyword) || FALSE.hasValue(keyword)) { - if (!isBoolProposalValid(context)) return true; + if (isLastWordFromCaretPositionEqualTo(keyword, context)) return true; + if (DEFAULT.hasValue(keyword)) { + proposeDefaultValue(context, acceptor); + return true; + } + if (EQUAL.hasValue(keyword)) { + EObject grammarElement = context.getLastCompleteNode().getGrammarElement(); + if (isKeyword(grammarElement, SYNTAX)) { + proposeEqualProto2(context, acceptor); + return true; + } } if (OPENING_BRACKET.hasValue(keyword)) { return proposeOpenBracket(context, acceptor); @@ -166,20 +192,27 @@ proposePackedOption(context, acceptor); return true; } - if (DEFAULT.hasValue(keyword)) { - proposeDefaultValue(context, acceptor); - return true; + if (TRUE.hasValue(keyword) || FALSE.hasValue(keyword)) { + if (!isBoolProposalValid(context)) return true; } return false; } - private boolean isKeywordEqualToPreviousWordInEditor(String keyword, ContentAssistContext context) { + private void proposeEqualProto2(ContentAssistContext context, ICompletionProposalAcceptor acceptor) { + proposeAndAccept(EQUAL_PROTO2_IN_QUOTES, context, acceptor); + } + + private boolean isKeyword(EObject object, CommonKeyword keyword) { + return object instanceof Keyword && keyword.hasValue(((Keyword)object).getValue()); + } + + private boolean isLastWordFromCaretPositionEqualTo(String word, ContentAssistContext context) { StyledText styledText = context.getViewer().getTextWidget(); - int valueLength = keyword.length(); + int valueLength = word.length(); int start = styledText.getCaretOffset() - valueLength; if (start < 0) return false; String previousWord = styledText.getTextRange(start, valueLength); - return keyword.equals(previousWord); + return word.equals(previousWord); } private boolean isBoolProposalValid(ContentAssistContext context) { @@ -204,12 +237,7 @@ display = DEFAULT_EQUAL_STRING_IN_BRACKETS; cursorPosition++; } - ICompletionProposal proposal = createCompletionProposal(display, context); - if (proposal instanceof ConfigurableCompletionProposal) { - ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal; - configurable.setCursorPosition(cursorPosition); - } - acceptor.accept(proposal); + createAndAccept(display, cursorPosition, context, acceptor); } if (REPEATED.equals(modifier) && properties.isPrimitive(p)) proposeAndAccept(PACKED_EQUAL_TRUE_IN_BRACKETS, context, acceptor); @@ -238,6 +266,11 @@ display = DEFAULT_EQUAL_STRING; cursorPosition++; } + createAndAccept(display, cursorPosition, context, acceptor); + } + + private void createAndAccept(CompoundElement display, int cursorPosition, ContentAssistContext context, + ICompletionProposalAcceptor acceptor) { ICompletionProposal proposal = createCompletionProposal(display, context); if (proposal instanceof ConfigurableCompletionProposal) { ConfigurableCompletionProposal configurable = (ConfigurableCompletionProposal) proposal; @@ -288,7 +321,8 @@ private void proposeAndAccept(String proposalText, Image image, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - ICompletionProposal proposal = createCompletionProposal(proposalText, proposalText, image, context); + String s = addSpaceAtBeginning(proposalText, context); + ICompletionProposal proposal = createCompletionProposal(s, proposalText, image, context); acceptor.accept(proposal); } @@ -322,14 +356,19 @@ } private void proposeAndAccept(String proposalText, ContentAssistContext context, ICompletionProposalAcceptor acceptor) { - ICompletionProposal proposal = createCompletionProposal(proposalText, context); - acceptor.accept(proposal); + String s = addSpaceAtBeginning(proposalText, context); + acceptor.accept(createCompletionProposal(s, context)); } - @Override protected ICompletionProposal createCompletionProposal(String proposal, - ContentAssistContext contentAssistContext) { - return createCompletionProposal(proposal, null, defaultImage(), getPriorityHelper().getDefaultPriority(), - contentAssistContext.getPrefix(), contentAssistContext); + private String addSpaceAtBeginning(String proposal, ContentAssistContext context) { + if (!isLastWordFromCaretPositionEqualTo(SPACE, context)) return SPACE + proposal; + return proposal; + } + + @Override protected ICompletionProposal createCompletionProposal(String proposalText, ContentAssistContext context) { + String s = addSpaceAtBeginning(proposalText, context); + return createCompletionProposal(s, null, defaultImage(), getPriorityHelper().getDefaultPriority(), + context.getPrefix(), context); } private Image defaultImage() {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword.java index ff3cd6a..ea3b266 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CommonKeyword.java
@@ -20,7 +20,7 @@ // implementation anyway. BOOL("bool"), TRUE("true"), FALSE("false"), BYTES("bytes"), OPENING_BRACKET("["), CLOSING_BRACKET("]"), - DEFAULT("default"), EQUAL("="), PACKED("packed"), SEMICOLON(";"), STRING("string"); + DEFAULT("default"), EQUAL("="), PACKED("packed"), SEMICOLON(";"), STRING("string"), SYNTAX("syntax"); private final String value;
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement.java index f12e808..8bfb07a 100644 --- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement.java +++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/CompoundElement.java
@@ -11,19 +11,22 @@ import static com.google.eclipse.protobuf.ui.grammar.CommonKeyword.*; /** - * Element composed of more than one keyword. + * Element composed of one or more keywords. * * @author alruiz@google.com (Alex Ruiz) */ public enum CompoundElement { - DEFAULT_EQUAL(join(DEFAULT, EQUAL, "")), + DEFAULT_EQUAL(joinWithWhitespace(DEFAULT, EQUAL, "")), DEFAULT_EQUAL_IN_BRACKETS(inBrackets(DEFAULT_EQUAL)), - EMPTY_STRING("\"\""), - DEFAULT_EQUAL_STRING(join(DEFAULT_EQUAL, EMPTY_STRING)), + QUOTE("\""), + EMPTY_STRING(join(QUOTE, QUOTE)), + DEFAULT_EQUAL_STRING(joinWithWhitespace(DEFAULT_EQUAL, EMPTY_STRING)), DEFAULT_EQUAL_STRING_IN_BRACKETS(inBrackets(DEFAULT_EQUAL_STRING)), - PACKED_EQUAL_TRUE(join(PACKED, EQUAL, TRUE)), - PACKED_EQUAL_TRUE_IN_BRACKETS(inBrackets(PACKED_EQUAL_TRUE)); + PACKED_EQUAL_TRUE(joinWithWhitespace(PACKED, EQUAL, TRUE)), + PACKED_EQUAL_TRUE_IN_BRACKETS(inBrackets(PACKED_EQUAL_TRUE)), + PROTO2_IN_QUOTES(join(QUOTE, "proto2", QUOTE, SEMICOLON)), + EQUAL_PROTO2_IN_QUOTES(joinWithWhitespace(EQUAL, PROTO2_IN_QUOTES)); private static final String SPACE = " "; @@ -33,6 +36,15 @@ StringBuilder buffer = new StringBuilder(); int count = objects.length; for (int i = 0; i < count; i++) { + buffer.append(objects[i].toString()); + } + return buffer.toString(); + } + + private static String joinWithWhitespace(Object...objects) { + StringBuilder buffer = new StringBuilder(); + int count = objects.length; + for (int i = 0; i < count; i++) { String s = objects[i].toString(); buffer.append(s); if (i < count - 1 && !s.endsWith(SPACE)) buffer.append(SPACE);