Skip to content

Commit

Permalink
Add xml-model snippets.
Browse files Browse the repository at this point in the history
Adjust unit tests accordingly.

Fixes eclipse-lemminx#699.

Signed-off-by: Balduin Landolt <balduin.landolt@hotmail.com>
  • Loading branch information
BalduinLandolt authored and angelozerr committed May 31, 2020
1 parent 3342ed0 commit 3a5fe37
Show file tree
Hide file tree
Showing 6 changed files with 169 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*******************************************************************************
* Copyright (c) 2020 Balduin Landolt and others.
* All rights reserved. This program and the accompanying materials
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Balduin Landolt - initial API and implementation
*******************************************************************************/


package org.eclipse.lemminx.services.snippets;

import java.util.Map;

import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMElement;
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lemminx.services.extensions.ICompletionRequest;
import org.eclipse.lemminx.utils.DOMUtils;

/**
* Snippet context used to filter if Processing Instruction Snippets should be triggered or not.
*
*/
public class ProcessingInstructionSnippetContext implements IXMLSnippetContext {

public static IXMLSnippetContext DEFAULT_CONTEXT = new ProcessingInstructionSnippetContext();

@Override
public boolean isMatch(ICompletionRequest request, Map<String, String> model) {
DOMNode node = request.getNode();
int offset = request.getOffset();
if ((node.isComment() || node.isDoctype() || node.isProlog() || node.isProcessingInstruction()) && offset < node.getEnd()) {
// completion was triggered inside comment, doctype, prolog or processing instruction
return false;
}

if (node.getParentNode() != null && node.getParentNode().isDoctype()) {
// completion was triggered after element inside doctype
return false;
}

DOMDocument document = request.getXMLDocument();
DOMElement documentElement = document.getDocumentElement();

if (document.isDTD() || DOMUtils.isXSD(document)) {
// triggered in a DTD or XSD file
return false;
}

if (document.hasProlog() && offset == 0){
// triggered before prolog
return false;
}

if (documentElement != null && documentElement.getTagName() != null) {
return offset <= documentElement.getStart();
}

return true;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public void load(SnippetRegistry registry) throws Exception {
XMLDeclarationSnippetContext.DEFAULT_CONTEXT);
registry.registerSnippets(XMLSnippetRegistryLoader.class.getResourceAsStream("dtdnode-snippets.json"),
DTDNodeSnippetContext.DEFAULT_CONTEXT);
registry.registerSnippets(XMLSnippetRegistryLoader.class.getResourceAsStream("processing-instruction-snippets.json"),
ProcessingInstructionSnippetContext.DEFAULT_CONTEXT);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"Insert XML Model: XSD": {
"prefix": [
"<?xml-model"
],
"suffix": "?>",
"body": [
"<?xml-model href=\"${1:file.xsd}\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>${0}"
],
"label": "Insert XML Schema association",
"description": "Insert XML Model Processing Instruction to Associate XSD Schema"
},
"Insert XML Model: DTD": {
"prefix": [
"<?xml-model"
],
"suffix": "?>",
"body": [
"<?xml-model href=\"${1:file.dtd}\" type=\"application/xml-dtd\"?>${0}"
],
"label": "Insert DTD association",
"description": "Insert XML Model Processing Instruction to Associate Document Type Description (DTD)"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public class XMLAssert {

public static final int XML_DECLARATION_SNIPPETS = 2;

public static final int PROCESSING_INSTRUCTION_SNIPPETS = 2;

public static final int REGION_SNIPPETS = 2;

private static final String FILE_URI = "test.xml";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@

import static org.eclipse.lemminx.XMLAssert.COMMENT_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.DTDNODE_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.CDATA_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.PROCESSING_INSTRUCTION_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.c;
import static org.eclipse.lemminx.XMLAssert.te;

Expand Down Expand Up @@ -216,7 +218,10 @@ public void elementCompletionWithDoctypeSubsetWithNoElements() throws BadLocatio
"<web-app>\r\n" + //
" <display-name>Servlet 2.3 aWeb Application</display-name>\r\n" + //
"</web-app>";
testCompletionFor(xml, false, 76 + 2 /* CDATA and Comments */,
testCompletionFor(xml, false, 76 + //
CDATA_SNIPPETS /* CDATA */ + //
COMMENT_SNIPPETS /* Comments */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction Snippets */,
c("web-app", te(3, 0, 3, 1, "<web-app></web-app>"), "web-app"),
c("auth-constraint", te(3, 0, 3, 1, "<auth-constraint></auth-constraint>"), "auth-constraint"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import static org.eclipse.lemminx.XMLAssert.DOCTYPE_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.NEW_XML_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.NEW_XSD_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.PROCESSING_INSTRUCTION_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.REGION_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.XML_DECLARATION_SNIPPETS;
import static org.eclipse.lemminx.XMLAssert.c;
Expand All @@ -38,6 +39,7 @@ public void emptyXMLContent() throws BadLocationException {
testCompletionFor("|", REGION_SNIPPETS /* #region */ + //
NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
Expand All @@ -47,6 +49,12 @@ public void emptyXMLContent() throws BadLocationException {
c("Insert XML Declaration", //
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>", //
r(0, 0, 0, 0), "<?xml"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(0, 0, 0, 0), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(0, 0, 0, 0), "<?xml-model"),
c("New XML bound with xsi:schemaLocation", //
"<root-element xmlns=\"https://github.com/eclipse/lemminx\"" + lineSeparator() + //
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + lineSeparator() + //
Expand All @@ -68,6 +76,7 @@ public void emptyXMLContent() throws BadLocationException {

testCompletionFor("<|", NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
Expand All @@ -77,12 +86,19 @@ public void emptyXMLContent() throws BadLocationException {
c("Insert XML Declaration", //
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>", //
r(0, 0, 0, 1), "<?xml"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(0, 0, 0, 1), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(0, 0, 0, 1), "<?xml-model"),
c("<!--", //
"<!-- -->", //
r(0, 0, 0, 1), "<!--"));

testCompletionFor("<|>", NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
Expand All @@ -92,12 +108,19 @@ public void emptyXMLContent() throws BadLocationException {
c("Insert XML Declaration", //
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>", //
r(0, 0, 0, 2), "<?xml"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(0, 0, 0, 2), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(0, 0, 0, 2), "<?xml-model"),
c("<!--", //
"<!-- -->", //
r(0, 0, 0, 2), "<!--"));

testCompletionFor("<!|", NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
Expand All @@ -117,12 +140,19 @@ public void emptyXMLContent() throws BadLocationException {
public void afterComment() throws BadLocationException {
testCompletionFor("<!-- -->|", NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
"<root-element>" + lineSeparator() + //
"</root-element>", //
r(0, 8, 0, 8), "<!DOCTYPE"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(0, 8, 0, 8), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(0, 8, 0, 8), "<?xml-model"),
c("<!--", //
"<!-- -->", //
r(0, 8, 0, 8), "<!--"));
Expand All @@ -132,61 +162,96 @@ public void afterComment() throws BadLocationException {
public void afterProlog() throws BadLocationException {
testCompletionFor("<?xml version=\"1.0\" encoding=\"UTF-8\"?>|", //
NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
"<root-element>" + lineSeparator() + //
"</root-element>", //
r(0, 38, 0, 38), "<!DOCTYPE"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(0, 38, 0, 38), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(0, 38, 0, 38), "<?xml-model"),
c("<!--", //
"<!-- -->", //
r(0, 38, 0, 38), "<!--"));

testCompletionFor("<?xml version=\"1.0\" encoding=\"UTF-8\"?><|", //
NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
"<root-element>" + lineSeparator() + //
"</root-element>", //
r(0, 38, 0, 39), "<!DOCTYPE"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(0, 38, 0, 39), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(0, 38, 0, 39), "<?xml-model"),
c("<!--", //
"<!-- -->", //
r(0, 38, 0, 39), "<!--"));

testCompletionFor("<?xml version=\"1.0\" encoding=\"UTF-8\"?><|!", //
NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
"<root-element>" + lineSeparator() + //
"</root-element>", //
r(0, 38, 0, 39), "<!DOCTYPE"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(0, 38, 0, 39), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(0, 38, 0, 39), "<?xml-model"),
c("<!--", //
"<!-- -->", //
r(0, 38, 0, 39), "<!--"));

testCompletionFor("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!|", //
NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
"<root-element>" + lineSeparator() + //
"</root-element>", //
r(0, 38, 0, 40), "<!DOCTYPE"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(0, 38, 0, 40), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(0, 38, 0, 40), "<?xml-model"),
c("<!--", //
"<!-- -->", //
r(0, 38, 0, 40), "<!--"));

testCompletionFor("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n|", //
NEW_XML_SNIPPETS /* DOCTYPE snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
REGION_SNIPPETS /* regions snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("New XML with SYSTEM DOCTYPE", //
"<!DOCTYPE root-element SYSTEM \"file.dtd\">" + lineSeparator() + //
"<root-element>" + lineSeparator() + //
"</root-element>", //
r(1, 0, 1, 0), "<!DOCTYPE"),
c("Insert XML Schema association", //
"<?xml-model href=\"file.xsd\" type=\"application/xml\" schematypens=\"http://www.w3.org/2001/XMLSchema\"?>", //
r(1, 0, 1, 0), "<?xml-model"),
c("Insert DTD association", //
"<?xml-model href=\"file.dtd\" type=\"application/xml-dtd\"?>", //
r(1, 0, 1, 0), "<?xml-model"),
c("<!--", //
"<!-- -->", //
r(1, 0, 1, 0), "<!--"));
Expand Down Expand Up @@ -417,6 +482,7 @@ public void doctype() throws BadLocationException {
testCompletionFor("|<foo>", //
DOCTYPE_SNIPPETS /* DOCTYPE snippets */ + //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("Insert SYSTEM DOCTYPE", //
"<!DOCTYPE foo SYSTEM \"file.dtd\">", //
Expand All @@ -425,6 +491,7 @@ public void doctype() throws BadLocationException {
testCompletionFor("<!-- -->|<foo>", //
DOCTYPE_SNIPPETS /* DOCTYPE snippets */ + //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("Insert SYSTEM DOCTYPE", //
"<!DOCTYPE foo SYSTEM \"file.dtd\">", //
Expand All @@ -435,6 +502,7 @@ public void doctype() throws BadLocationException {
"|<foo>", //
DOCTYPE_SNIPPETS /* DOCTYPE snippets */ + //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("Insert SYSTEM DOCTYPE", //
"<!DOCTYPE foo SYSTEM \"file.dtd\">", //
Expand All @@ -447,6 +515,7 @@ public void doctype() throws BadLocationException {
public void prolog() throws BadLocationException {
testCompletionFor("<?|", //
XML_DECLARATION_SNIPPETS /* XML Declaration snippets */ + //
PROCESSING_INSTRUCTION_SNIPPETS /* Processing Instruction Snippets */ + //
COMMENT_SNIPPETS /* Comment snippets */ , //
c("Insert XML Declaration", //
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>", //
Expand Down

0 comments on commit 3a5fe37

Please sign in to comment.