diff --git a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/XMLCompletions.java b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/XMLCompletions.java
index 420b6cbd7..ae593e3c8 100644
--- a/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/XMLCompletions.java
+++ b/org.eclipse.lemminx/src/main/java/org/eclipse/lemminx/services/XMLCompletions.java
@@ -31,6 +31,7 @@
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMElement;
import org.eclipse.lemminx.dom.DOMNode;
+import org.eclipse.lemminx.dom.DOMText;
import org.eclipse.lemminx.dom.DTDDeclParameter;
import org.eclipse.lemminx.dom.parser.Scanner;
import org.eclipse.lemminx.dom.parser.ScannerState;
@@ -53,6 +54,7 @@
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.jsonrpc.CancelChecker;
+import org.w3c.dom.Node;
/**
* XML completions support.
@@ -135,12 +137,11 @@ public CompletionList doComplete(DOMDocument xmlDocument, Position position, Sha
if (DOMNode.isIncluded(systemId, offset)) {
/**
- * Completion invoked within systemId parameter
- * ie, completion offset is at | like so:
- *
+ * Completion invoked within systemId parameter ie, completion offset is at |
+ * like so:
*/
- collectDTDSystemIdSuggestions(systemId.getStart(), systemId.getEnd(),
- completionRequest, completionResponse);
+ collectDTDSystemIdSuggestions(systemId.getStart(), systemId.getEnd(), completionRequest,
+ completionResponse);
return completionResponse;
}
break;
@@ -346,16 +347,16 @@ private static Integer getSuffixIndex(String text, String suffix, final int init
// There is one of character of the suffix
offset++;
if (suffixIndex == suffix.length()) {
- // the suffix index is the last character of the suffix
+ // the suffix index is the last character of the suffix
return offset;
}
// Try to eat the most characters of the suffix
- for (; offset < text.length(); offset++) {
+ for (; offset < text.length(); offset++) {
suffixIndex++;
if (suffixIndex == suffix.length()) {
- // the suffix index is the last character of the suffix
+ // the suffix index is the last character of the suffix
return offset;
- }
+ }
ch = text.charAt(offset);
if (suffix.charAt(suffixIndex) != ch) {
return offset;
@@ -752,6 +753,11 @@ private void collectInsideContent(CompletionRequest request, CompletionResponse
collectOpenTagSuggestions(false, tagNameRange, request, response);
collectCloseTagSuggestions(tagNameRange, true, true, false, request, response);
}
+ // Adjust the range for covering the text node.
+ Range textRange = getTextRangeInsideContent(request.getNode());
+ if (textRange != null) {
+ request.setReplaceRange(textRange);
+ }
// Participant completion on XML content
for (ICompletionParticipant participant : getCompletionParticipants()) {
try {
@@ -763,6 +769,29 @@ private void collectInsideContent(CompletionRequest request, CompletionResponse
collectionRegionProposals(request, response);
}
+ private static Range getTextRangeInsideContent(DOMNode node) {
+ switch (node.getNodeType()) {
+ case Node.ELEMENT_NODE:
+ Node firstChild = node.getFirstChild();
+ if (firstChild == null) {
+ // ex : |
+ DOMElement element = (DOMElement) node;
+ return XMLPositionUtility.createRange(element.getStartTagCloseOffset() + 1,
+ element.getStartTagCloseOffset() + 1, element.getOwnerDocument());
+ }
+ if (firstChild.getNodeType() == Node.TEXT_NODE) {
+ // ex : abcd|
+ return XMLPositionUtility.selectText((DOMText) firstChild);
+ }
+ return null;
+ case Node.TEXT_NODE:
+ // ex : |
+ return XMLPositionUtility.selectText((DOMText) node);
+ }
+ // should never occur
+ return null;
+ }
+
private void collectionRegionProposals(ICompletionRequest request, ICompletionResponse response) {
// Completion for #region
try {
@@ -884,8 +913,10 @@ private void collectAttributeValueSuggestions(int valueStart, int valueEnd, Comp
/**
* Collect completion items for DTD systemId
*
- * @param valueStart the start offset of the systemId value, including quote
- * @param valueEnd the end offset of the systemId value, including quote
+ * @param valueStart the start offset of the systemId value, including
+ * quote
+ * @param valueEnd the end offset of the systemId value, including
+ * quote
* @param completionRequest the completion request
* @param completionResponse the completion response
*/
diff --git a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/extensions/HTMLCompletionExtensionsTest.java b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/extensions/HTMLCompletionExtensionsTest.java
index 5528eca96..52943e4a6 100644
--- a/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/extensions/HTMLCompletionExtensionsTest.java
+++ b/org.eclipse.lemminx/src/test/java/org/eclipse/lemminx/services/extensions/HTMLCompletionExtensionsTest.java
@@ -13,6 +13,7 @@
package org.eclipse.lemminx.services.extensions;
import static org.eclipse.lemminx.XMLAssert.c;
+import static org.eclipse.lemminx.XMLAssert.r;
import org.eclipse.lemminx.XMLAssert;
import org.eclipse.lemminx.commons.BadLocationException;
@@ -20,6 +21,7 @@
import org.eclipse.lsp4j.CompletionItem;
import org.eclipse.lsp4j.CompletionItemKind;
import org.eclipse.lsp4j.InsertTextFormat;
+import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.jsonrpc.messages.Either;
@@ -120,6 +122,20 @@ public void testHTMLAttributeValueCompletion() throws BadLocationException {
c("checkbox", "\"checkbox\"" /* "|", //
+ c("Test replace range", "replacement text", r(0, 7, 0, 7), null));
+ testCompletionFor(" |", //
+ c("Test replace range", "replacement text", r(0, 7, 0, 8), null));
+ testCompletionFor("| ", //
+ c("Test replace range", "replacement text", r(0, 7, 0, 8), null));
+ testCompletionFor("some extisti|ng text", //
+ c("Test replace range", "replacement text", r(0, 7, 0, 26), null));
+ testCompletionFor("some extisti|ng
text", //
+ c("Test replace range", "replacement text", r(0, 7, 0, 22), null));
+ }
+
public static void testCompletionFor(String value, CompletionItem... expectedItems) throws BadLocationException {
XMLAssert.testCompletionFor(new HTMLLanguageService(), value, (String) null, null, null, null, true,
expectedItems);
@@ -180,8 +196,8 @@ public void onAttributeName(boolean generateValue, ICompletionRequest completion
}
@Override
- public void onAttributeValue(String valuePrefix,
- ICompletionRequest completionRequest, ICompletionResponse completionResponse) {
+ public void onAttributeValue(String valuePrefix, ICompletionRequest completionRequest,
+ ICompletionResponse completionResponse) {
String tag = completionRequest.getCurrentTag();
String attributeName = completionRequest.getCurrentAttributeName();
HTMLTag htmlTag = HTMLTag.getHTMLTag(tag);
@@ -201,7 +217,7 @@ public void onAttributeValue(String valuePrefix,
String[] values = HTMLTag.getAttributeValues(attrType);
for (String value : values) {
String insertText = completionRequest.getInsertAttrValue(value);
-
+
CompletionItem item = new CompletionItem();
item.setLabel(value);
item.setFilterText(insertText);
@@ -216,6 +232,16 @@ public void onAttributeValue(String valuePrefix,
}
}
}
+
+ @Override
+ public void onXMLContent(ICompletionRequest request, ICompletionResponse response) {
+ CompletionItem completion = new CompletionItem("Test replace range");
+ TextEdit edit = new TextEdit();
+ edit.setNewText("replacement text");
+ edit.setRange(request.getReplaceRange());
+ completion.setTextEdit(edit);
+ response.addCompletionItem(completion);
+ }
}
}
}