[91866] Schema-based Content Assist should be stricter - fix to emphasize 'stictly valid' suggestions
diff --git a/bundles/org.eclipse.wst.xml.ui/icons/full/obj16/tag-generic-deemphasized.gif b/bundles/org.eclipse.wst.xml.ui/icons/full/obj16/tag-generic-deemphasized.gif
new file mode 100644
index 0000000..73f47e8
--- /dev/null
+++ b/bundles/org.eclipse.wst.xml.ui/icons/full/obj16/tag-generic-deemphasized.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.xml.ui/icons/full/obj16/tag-generic-emphasized.gif b/bundles/org.eclipse.wst.xml.ui/icons/full/obj16/tag-generic-emphasized.gif
new file mode 100644
index 0000000..bd1ba54
--- /dev/null
+++ b/bundles/org.eclipse.wst.xml.ui/icons/full/obj16/tag-generic-emphasized.gif
Binary files differ
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java
index 2ffc03e..4e5da01 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/AbstractContentAssistProcessor.java
@@ -63,9 +63,11 @@
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.eclipse.wst.xml.ui.internal.Logger;
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
+import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
import org.eclipse.wst.xml.ui.internal.editor.CMImageUtil;
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImages;
+import org.eclipse.wst.xml.ui.internal.preferences.XMLUIPreferenceNames;
import org.eclipse.wst.xml.ui.internal.taginfo.MarkupTagInfoProvider;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
@@ -761,7 +763,6 @@
protected void addTagInsertionProposals(ContentAssistRequest contentAssistRequest, int childPosition) {
List cmnodes = null;
Node parent = contentAssistRequest.getParent();
- List validActions = null;
String error = null;
// CMVC #242943 shouldn't have proposals before XMLPI
@@ -815,10 +816,16 @@
addPCDATAProposal(parentDecl.getNodeName(), contentAssistRequest);
}
else {
- // retrieve the list of children
- validActions = getAvailableChildrenAtIndex((Element) parent, childPosition);
- cmnodes = getValidCMNodes(childPosition, ModelQueryAction.INSERT, validActions);
- Iterator nodeIterator = cmnodes.iterator();
+ // retrieve the list of all possible children within this parent context
+ cmnodes = getAvailableChildElementDeclarations((Element)parent, childPosition, ModelQueryAction.INSERT);
+
+ // retrieve the list of the possible children within this parent context and at this index
+ List strictCMNodeSuggestions = null;
+ if (XMLUIPreferenceNames.SUGGESTION_STRATEGY_VALUE_STRICT.equals(XMLUIPlugin.getInstance().getPreferenceStore().getString(XMLUIPreferenceNames.SUGGESTION_STRATEGY)))
+ {
+ strictCMNodeSuggestions = getValidChildElementDeclarations((Element)parent, childPosition, ModelQueryAction.INSERT);
+ }
+ Iterator nodeIterator = cmnodes.iterator();
if (!nodeIterator.hasNext()) {
if (getCMElementDeclaration(parent) != null)
error = NLS.bind(XMLUIMessages._Has_no_available_child, (new Object[]{parent.getNodeName()}));
@@ -838,9 +845,20 @@
// only add proposals for the child element's that
// begin with the matchstring
String tagname = getRequiredName(parent, elementDecl);
- Image image = CMImageUtil.getImage(elementDecl);
+ boolean isStrictCMNodeSuggestion = strictCMNodeSuggestions != null ? strictCMNodeSuggestions.contains(elementDecl) : false;
+
+ Image image = CMImageUtil.getImage(elementDecl);
+
if (image == null) {
- image = XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC);
+ if (strictCMNodeSuggestions != null) {
+ image = isStrictCMNodeSuggestion ?
+ XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC_EMPHASIZED) :
+ XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC_DEEMPHASIZED);
+ }
+ else {
+ image = XMLEditorPluginImageHelper.getInstance().getImage(XMLEditorPluginImages.IMG_OBJ_TAG_GENERIC);
+ }
+
}
// Account for the < and >. If attributes were
// added, the cursor will be placed
@@ -850,7 +868,8 @@
if (beginsWith(tagname, matchString)) {
String proposedText = getRequiredText(parent, elementDecl);
String proposedInfo = getAdditionalInfo(parentDecl, elementDecl);
- CustomCompletionProposal proposal = new CustomCompletionProposal(proposedText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), markupAdjustment, image, tagname, null, proposedInfo, XMLRelevanceConstants.R_TAG_INSERTION);
+ int relevance = isStrictCMNodeSuggestion ? XMLRelevanceConstants.R_STICTLY_VALID_TAG_INSERTION : XMLRelevanceConstants.R_TAG_INSERTION;
+ CustomCompletionProposal proposal = new CustomCompletionProposal(proposedText, contentAssistRequest.getReplacementBeginPosition(), contentAssistRequest.getReplacementLength(), markupAdjustment, image, tagname, null, proposedInfo, relevance);
contentAssistRequest.addProposal(proposal);
}
}
@@ -913,13 +932,12 @@
List cmnodes = null;
Node parent = contentAssistRequest.getParent();
IDOMNode node = (IDOMNode) contentAssistRequest.getNode();
- List validActions = null;
String error = null;
String matchString = contentAssistRequest.getMatchString();
if (parent.getNodeType() == Node.ELEMENT_NODE) {
// retrieve the list of children
- validActions = getAvailableChildrenAtIndex((Element) parent, childPosition);
- cmnodes = getValidCMNodes(childPosition, ModelQueryAction.INSERT, validActions);
+ //validActions = getAvailableChildrenAtIndex((Element) parent, childPosition);
+ cmnodes = getAvailableChildElementDeclarations((Element)parent, childPosition, ModelQueryAction.INSERT);
Iterator nodeIterator = cmnodes.iterator();
// chop off any leading <'s and whitespace from the matchstring
while ((matchString.length() > 0) && (Character.isWhitespace(matchString.charAt(0)) || beginsWith(matchString, "<"))) //$NON-NLS-1$
@@ -1596,7 +1614,7 @@
}
// returns a list of ModelQueryActions
- protected List getAvailableChildrenAtIndex(Element parent, int index) {
+ protected List getAvailableChildrenAtIndex(Element parent, int index, int validityChecking) {
List list = new ArrayList();
CMElementDeclaration parentDecl = getCMElementDeclaration(parent);
if (parentDecl != null) {
@@ -1605,8 +1623,7 @@
// int editMode = modelQuery.getEditMode();
int editMode = ModelQuery.EDIT_MODE_UNCONSTRAINED;
int ic = (editMode == ModelQuery.EDIT_MODE_CONSTRAINED_STRICT) ? ModelQuery.INCLUDE_CHILD_NODES | ModelQuery.INCLUDE_SEQUENCE_GROUPS : ModelQuery.INCLUDE_CHILD_NODES;
- int vc = (editMode == ModelQuery.EDIT_MODE_CONSTRAINED_STRICT) ? ModelQuery.VALIDITY_STRICT : ModelQuery.VALIDITY_NONE;
- modelQuery.getInsertActions(parent, parentDecl, index, ic, vc, list);
+ modelQuery.getInsertActions(parent, parentDecl, index, ic, validityChecking, list);
}
return list;
}
@@ -2043,7 +2060,18 @@
return name;
}
- protected List getValidCMNodes(int childPosition, int kindOfAction, List modelQueryActions) {
+ // returns a list of CMNodes that are available within this parent context
+ // Given the grammar shown below and a snippet of XML code (where the '|' indicated the cursor position)
+ // the list would return all of the element declarations that are potential child elements of Foo.
+ //
+ // grammar : Foo -> (A, B, C)
+ // snippet : <Foo><A>|
+ // result : {A, B, C}
+ //
+ // TODO cs... do we need to pass in the 'kindOfAction'? Seems to me we could assume it's always an insert.
+ protected List getAvailableChildElementDeclarations(Element parent, int childPosition, int kindOfAction)
+ {
+ List modelQueryActions = getAvailableChildrenAtIndex(parent, childPosition, ModelQuery.VALIDITY_NONE);
Iterator iterator = modelQueryActions.iterator();
List cmnodes = new Vector();
while (iterator.hasNext()) {
@@ -2057,6 +2085,30 @@
return cmnodes;
}
+ // returns a list of CMNodes that can be validly inserted at this childPosition
+ // Given the grammar shown below and a snippet of XML code (where the '|' indicated the cursor position)
+ // the list would return only the element declarations can be inserted while maintaing validity of the content.
+ //
+ // grammar : Foo -> (A, B, C)
+ // snippet : <Foo><A>|
+ // result : {B}
+ //
+ protected List getValidChildElementDeclarations(Element parent, int childPosition, int kindOfAction)
+ {
+ List modelQueryActions = getAvailableChildrenAtIndex(parent, childPosition, ModelQuery.VALIDITY_STRICT);
+ Iterator iterator = modelQueryActions.iterator();
+ List cmnodes = new Vector();
+ while (iterator.hasNext()) {
+ ModelQueryAction action = (ModelQueryAction) iterator.next();
+ if (childPosition < 0 || (action.getStartIndex() <= childPosition && childPosition <= action.getEndIndex()) && action.getKind() == kindOfAction) {
+ CMNode actionCMNode = action.getCMNode();
+ if (actionCMNode != null && !cmnodes.contains(actionCMNode))
+ cmnodes.add(actionCMNode);
+ }
+ }
+ return cmnodes;
+ }
+
/**
* Similar to the call in HTMLContentAssistProcessor. Pass in a node, it
* tells you if the document is XML type.
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLRelevanceConstants.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLRelevanceConstants.java
index 34896ce..ae6dd76 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLRelevanceConstants.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/contentassist/XMLRelevanceConstants.java
@@ -44,6 +44,7 @@
// CMVC 246618
int R_REQUIRED = 10;
int R_TAG_INSERTION = 500;
+ int R_STICTLY_VALID_TAG_INSERTION = 600;
int R_TAG_NAME = 1200;
int R_XML_ATTRIBUTE_NAME = 900;
int R_XML_ATTRIBUTE_VALUE = 800;
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/editor/XMLEditorPluginImages.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/editor/XMLEditorPluginImages.java
index 8160f77..fbb4ad7 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/editor/XMLEditorPluginImages.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/editor/XMLEditorPluginImages.java
@@ -41,7 +41,9 @@
public static final String IMG_OBJ_LOCAL_VARIABLE = "icons/full/obj16/localvariable_obj.gif"; //$NON-NLS-1$
public static final String IMG_OBJ_NOTATION = "icons/full/obj16/notation.gif"; //$NON-NLS-1$
public static final String IMG_OBJ_PROCESSINGINSTRUCTION = "icons/full/obj16/proinst_obj.gif"; //$NON-NLS-1$
- public static final String IMG_OBJ_TAG_GENERIC = "icons/full/obj16/tag-generic.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJ_TAG_GENERIC = "icons/full/obj16/tag-generic.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJ_TAG_GENERIC_DEEMPHASIZED = "icons/full/obj16/tag-generic-deemphasized.gif"; //$NON-NLS-1$
+ public static final String IMG_OBJ_TAG_GENERIC_EMPHASIZED = "icons/full/obj16/tag-generic-emphasized.gif"; //$NON-NLS-1$
public static final String IMG_OBJ_TAG_MACRO = "icons/full/obj16/tag-macro.gif"; //$NON-NLS-1$
public static final String IMG_OBJ_TXTEXT = "icons/full/obj16/text.gif"; //$NON-NLS-1$
public static final String IMG_OBJ_WARNING_OBJ = "icons/full/obj16/warning_obj.gif"; //$NON-NLS-1$
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLSourcePreferencePage.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLSourcePreferencePage.java
index 31a8fdf..4d47b0a 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLSourcePreferencePage.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLSourcePreferencePage.java
@@ -19,6 +19,7 @@
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
@@ -42,6 +43,7 @@
protected Button fAutoPropose;
protected Label fAutoProposeLabel;
protected Text fAutoProposeText;
+ protected Combo fSuggestionStrategyCombo;
protected Button fClearAllBlankLines;
// Formatting
@@ -78,6 +80,12 @@
fAutoProposeLabel = createLabel(contentAssistGroup, XMLUIMessages.Prompt_when_these_characte_UI_);
fAutoProposeText = createTextField(contentAssistGroup);
+
+ createLabel(contentAssistGroup, "Suggestion strategy:");
+ fSuggestionStrategyCombo = new Combo(contentAssistGroup, SWT.READ_ONLY);
+ fSuggestionStrategyCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+ fSuggestionStrategyCombo.add("Lax");
+ fSuggestionStrategyCombo.add("Strict");
}
protected void createContentsForFormattingGroup(Composite parent) {
@@ -156,7 +164,8 @@
protected void initializeValuesForContentAssistGroup() {
// Content Assist
fAutoPropose.setSelection(getPreferenceStore().getBoolean(XMLUIPreferenceNames.AUTO_PROPOSE));
- fAutoProposeText.setText(getPreferenceStore().getString(XMLUIPreferenceNames.AUTO_PROPOSE_CODE));
+ fAutoProposeText.setText(getPreferenceStore().getString(XMLUIPreferenceNames.AUTO_PROPOSE_CODE));
+ fSuggestionStrategyCombo.setText(getPreferenceStore().getString(XMLUIPreferenceNames.SUGGESTION_STRATEGY));
}
protected void initializeValuesForFormattingGroup() {
@@ -195,6 +204,9 @@
// Content Assist
fAutoPropose.setSelection(getPreferenceStore().getDefaultBoolean(XMLUIPreferenceNames.AUTO_PROPOSE));
fAutoProposeText.setText(getPreferenceStore().getDefaultString(XMLUIPreferenceNames.AUTO_PROPOSE_CODE));
+
+ // TODO.. (cs) we need to map the preference value to a translated name
+ fSuggestionStrategyCombo.setText(getPreferenceStore().getDefaultString(XMLUIPreferenceNames.SUGGESTION_STRATEGY));
}
protected void performDefaultsForFormattingGroup() {
@@ -235,6 +247,7 @@
// Content Assist
getPreferenceStore().setValue(XMLUIPreferenceNames.AUTO_PROPOSE, fAutoPropose.getSelection());
getPreferenceStore().setValue(XMLUIPreferenceNames.AUTO_PROPOSE_CODE, fAutoProposeText.getText());
+ getPreferenceStore().setValue(XMLUIPreferenceNames.SUGGESTION_STRATEGY, fSuggestionStrategyCombo.getText());
}
protected void storeValuesForFormattingGroup() {
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLUIPreferenceInitializer.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLUIPreferenceInitializer.java
index 31a9706..fb6253a 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLUIPreferenceInitializer.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLUIPreferenceInitializer.java
@@ -21,7 +21,7 @@
store.setDefault(XMLUIPreferenceNames.AUTO_PROPOSE, true);
store.setDefault(XMLUIPreferenceNames.AUTO_PROPOSE_CODE, "<"); //$NON-NLS-1$
-
+ store.setDefault(XMLUIPreferenceNames.SUGGESTION_STRATEGY, XMLUIPreferenceNames.SUGGESTION_STRATEGY_VALUE_LAX);
store.setDefault(
XMLUIPreferenceNames.USE_INFERRED_GRAMMAR, true);
diff --git a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLUIPreferenceNames.java b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLUIPreferenceNames.java
index a4e1e76..e0bda81 100644
--- a/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLUIPreferenceNames.java
+++ b/bundles/org.eclipse.wst.xml.ui/src/org/eclipse/wst/xml/ui/internal/preferences/XMLUIPreferenceNames.java
@@ -15,6 +15,9 @@
* Preference keys for XML UI
*/
public class XMLUIPreferenceNames {
+
+ public final static String SUGGESTION_STRATEGY_VALUE_LAX = "Lax";
+ public final static String SUGGESTION_STRATEGY_VALUE_STRICT = "Strict";
/**
* A named preference that controls if code assist gets auto activated.
* <p>
@@ -65,4 +68,18 @@
private static String getUseInferredGrammarKey() {
return "useInferredGrammar"; //$NON-NLS-1$
}
+
+ /**
+ * A named preference that holds the characters that auto activate code
+ * assist.
+ * <p>
+ * Value is of type <code>String</code>. All characters that trigger
+ * auto code assist.
+ * </p>
+ */
+ public static final String SUGGESTION_STRATEGY = getSuggestionStrategeyKey();
+
+ private static String getSuggestionStrategeyKey() {
+ return "suggestionStrategy";//$NON-NLS-1$
+ }
}