Skip to content

Commit

Permalink
xsd:enumeration autocomplete don't work for text node
Browse files Browse the repository at this point in the history
  • Loading branch information
angelozerr committed Apr 14, 2020
1 parent 24aee91 commit 24cd010
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,25 @@ public static void placeholders(int index, String text, StringBuilder snippets)
}

/**
* Returns the LSP choices snippets content.
*
* @param index
* @param values
* @param index the snippet index.
* @param values the values for the choice.
* @return the LSP choices snippets content.
*
* @see https://github.com/Microsoft/language-server-protocol/blob/master/snippetSyntax.md#choice
*/
public static String choice(int index, Collection<String> values) {
StringBuilder snippets = new StringBuilder();
choice(index, values, snippets);
return snippets.toString();
}

/**
* Add LSP choices snippets in the given snippets content.
*
* @param index the snippet index.
* @param values the values for the choice.
* @return
*
* @see https://github.com/Microsoft/language-server-protocol/blob/master/snippetSyntax.md#choice
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ default String getName(String prefix) {
*/
Collection<String> getEnumerationValues();

/**
* Returns the documentation for the given enumeration value and null otherwise.
*
* @param value the enumeration value.
* @return the documentation for the given enumeration value and null otherwise.
*/
String getValueDocumentation(String value);

/**
* Returns the owner document URI where the element is declared.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2018 Angelo ZERR
* Copyright (c) 2018-2020 Angelo ZERR
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -13,6 +13,7 @@
package org.eclipse.lemminx.extensions.contentmodel.participants;

import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

Expand All @@ -35,6 +36,7 @@
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.InsertTextFormat;
import org.eclipse.lsp4j.MarkupContent;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.w3c.dom.Document;
Expand Down Expand Up @@ -334,4 +336,46 @@ private void fillAttributeValuesWithCMAttributeDeclarations(CMElementDeclaration
}
}

@Override
public void onXMLContent(ICompletionRequest request, ICompletionResponse response) throws Exception {
try {
ContentModelManager contentModelManager = request.getComponent(ContentModelManager.class);
DOMElement parentElement = request.getParentElement();
if (parentElement != null) {
CMElementDeclaration elementDeclaration = contentModelManager.findCMElement(parentElement);
Collection<String> values = elementDeclaration != null ? elementDeclaration.getEnumerationValues()
: Collections.emptyList();
if (!values.isEmpty()) {
// Completion for xs:enumeration inside Element Text node
DOMDocument document = parentElement.getOwnerDocument();
int startOffset = parentElement.getStartTagCloseOffset() + 1;
Position start = parentElement.getOwnerDocument().positionAt(startOffset);
Position end = request.getPosition();
int endOffset = parentElement.getEndTagOpenOffset();
if (endOffset > 0) {
end = document.positionAt(endOffset);
}
int completionOffset = request.getOffset();
String tokenStart = StringUtils.getWhitespaces(document.getText(), startOffset,
completionOffset);
Range fullRange = new Range(start, end);
values.forEach(value -> {
CompletionItem item = new CompletionItem();
item.setLabel(value);
String insertText = value; // request.getInsertAttrValue(value);
item.setLabel(value);
item.setKind(CompletionItemKind.Value);
item.setFilterText(tokenStart + insertText);
item.setTextEdit(new TextEdit(fullRange, insertText));
MarkupContent documentation = XMLGenerator.createMarkupContent(elementDeclaration, value,
request);
item.setDocumentation(documentation);
response.addCompletionItem(item);
});
}
}
} catch (CacheResourceDownloadingException e) {
// XML Schema, DTD is loading, ignore this error
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2018 Angelo ZERR
* Copyright (c) 2018-2020 Angelo ZERR
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
Expand All @@ -21,8 +21,8 @@
import org.eclipse.lemminx.extensions.contentmodel.model.CMElementDeclaration;
import org.eclipse.lemminx.settings.XMLFormattingOptions;
import org.eclipse.lemminx.utils.MarkupContentFactory;
import org.eclipse.lemminx.utils.XMLBuilder;
import org.eclipse.lemminx.utils.MarkupContentFactory.IMarkupKindSupport;
import org.eclipse.lemminx.utils.XMLBuilder;
import org.eclipse.lsp4j.MarkupContent;
import org.eclipse.lsp4j.MarkupKind;

Expand Down Expand Up @@ -124,6 +124,20 @@ private int generate(CMElementDeclaration elementDeclaration, String prefix, int
xml.selfCloseElement();
} else {
xml.closeStartElement();
Collection<String> values = elementDeclaration.getEnumerationValues();
if (!values.isEmpty()) {
// The Element Text node has xs:enumeration.
if (canSupportSnippets) {
// Generate LSP choice.
// Ex : <skill>${1|Java,Node,XML|}$2</skill>$0"
snippetIndex++;
xml.addContent(SnippetsBuilder.choice(snippetIndex, values));
} else {
// Generate the first item
// Ex : <skill>Java</skill>"
xml.addContent(values.iterator().next());
}
}
if (canSupportSnippets) {
snippetIndex++;
xml.addContent(SnippetsBuilder.tabstops(snippetIndex));
Expand Down Expand Up @@ -323,4 +337,23 @@ public static MarkupContent createMarkupContent(CMAttributeDeclaration cmAttribu
}
return null;
}

/**
* Returns a markup content for element text documentation and null otherwise.
*
* @param cmElement element declaration.
* @param textContent the text content.
* @param support markup kind support.
*
* @return a markup content for element text documentation and null otherwise.
*/
public static MarkupContent createMarkupContent(CMElementDeclaration cmElement, String textContent,
IMarkupKindSupport support) {
String documentation = XMLGenerator.generateDocumentation(cmElement.getValueDocumentation(textContent),
cmElement.getDocumentURI(), support.canSupportMarkupKind(MarkupKind.MARKDOWN));
if (documentation != null) {
return MarkupContentFactory.createMarkupContent(documentation, MarkupKind.MARKDOWN, support);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,11 @@ public CMElementDeclaration findCMElement(DOMElement element, String namespace)
}

private CMElementDeclaration findElementDeclaration(String tag, String namespace) {
if (tag == null) {
return null;
}
for (CMElementDeclaration cmElement : getElements()) {
if (cmElement.getName().equals(tag)) {
if (tag.equals(cmElement.getName())) {
return cmElement;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;

Expand Down Expand Up @@ -128,6 +129,11 @@ public boolean isEmpty() {

@Override
public Collection<String> getEnumerationValues() {
return Collections.emptyList();
}

@Override
public String getValueDocumentation(String textContent) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ private static int getComplexTypeOffset(XSComplexTypeDefinition complexType, Sch
// - fCTLocators array of locator
// - fComplexTypeDecls array of XSComplexTypeDecl

// As it's not an API, we must use Java Reflection to get thoses 2 arrays
// As it's not an API, we must use Java Reflection to get those 2 arrays
Field f = SchemaGrammar.class.getDeclaredField("fCTLocators");
f.setAccessible(true);
SimpleLocator[] fCTLocators = (SimpleLocator[]) f.get(grammar);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,24 @@ public boolean isEmpty() {
@Override
public Collection<String> getEnumerationValues() {
XSTypeDefinition typeDefinition = elementDeclaration.getTypeDefinition();
if (typeDefinition != null && typeDefinition.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
return CMXSDDocument.getEnumerationValues((XSSimpleTypeDefinition) typeDefinition);
if (typeDefinition != null) {
XSSimpleTypeDefinition simpleDefinition = null;
if (typeDefinition.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE) {
simpleDefinition = (XSSimpleTypeDefinition) typeDefinition;
} else if (typeDefinition.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE) {
simpleDefinition = ((XSComplexTypeDefinition) typeDefinition).getSimpleType();
}
return CMXSDDocument.getEnumerationValues(simpleDefinition);
}
return Collections.emptyList();
}

@Override
public String getValueDocumentation(String value) {
// FIXME: implement xsd:enumeration for Text node.
return null;
}

XSElementDeclaration getElementDeclaration() {
return elementDeclaration;
}
Expand All @@ -416,5 +428,4 @@ public String getDocumentURI() {
SchemaGrammar schemaGrammar = document.getOwnerSchemaGrammar(elementDeclaration);
return CMXSDDocument.getSchemaURI(schemaGrammar);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,21 @@ public static String normalizeSpace(String str) {
* @return the start whitespaces of the given line text.
*/
public static String getStartWhitespaces(String lineText) {
return getWhitespaces(lineText, 0, lineText.length());
}

/**
* Returns the whitespaces from the given range start/end of the given text.
*
* @param start the range start
* @param end the range end
* @param text the text
* @return the whitespaces from the given range start/end of the given text.
*/
public static String getWhitespaces(String text, int start, int end) {
StringBuilder whitespaces = new StringBuilder();
char[] chars = lineText.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
for (int i = start; i < end; i++) {
char c = text.charAt(i);
if (Character.isWhitespace(c)) {
whitespaces.append(c);
} else {
Expand Down Expand Up @@ -266,11 +277,10 @@ public static int getOffsetAfterWhitespace(String text, int endOffset) {
}

/**
* Returns the number of consecutive whitespace characters in front
* of text
* Returns the number of consecutive whitespace characters in front of text
*
* @param text String of interest
* @return the number of consecutive whitespace characters in front
* of text
* @return the number of consecutive whitespace characters in front of text
*/
public static int getFrontWhitespaceLength(String text) {

Expand All @@ -287,14 +297,13 @@ public static int getFrontWhitespaceLength(String text) {
}

/**
* Returns the number of consecutive whitespace characters from
* the end of text
* Returns the number of consecutive whitespace characters from the end of text
*
* @param text String of interest
* @return the number of consecutive whitespace characters from
* the end of text
* @return the number of consecutive whitespace characters from the end of text
*/
public static int getTrailingWhitespaceLength(String text) {

if (StringUtils.isWhitespace(text)) {
return text.length();
}
Expand Down Expand Up @@ -397,7 +406,7 @@ public static int findExprBeforeAt(String text, String expr, int offset) {
}

public static String getString(Object obj) {
if(obj != null) {
if (obj != null) {
return obj.toString();
}
return null;
Expand Down
Loading

0 comments on commit 24cd010

Please sign in to comment.