Skip to content

Commit

Permalink
Prolog completion works for partial 'xml' name, all possible closing …
Browse files Browse the repository at this point in the history
…brackets

Signed-off-by: Nikolas Komonen <[email protected]>
  • Loading branch information
NikolasKomonen committed Oct 15, 2018
1 parent 0d0dbaa commit 4d7a66b
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,11 +207,27 @@ public CompletionList doComplete(XMLDocument xmlDocument, Position position, Com
break;
case StartPrologOrPI: {
try {
boolean isFirstNode;
isFirstNode = xmlDocument.positionAt(scanner.getTokenOffset()).getLine() == 0;

boolean isFirstNode = xmlDocument.positionAt(scanner.getTokenOffset()).getLine() == 0;
if (isFirstNode && offset <= scanner.getTokenEnd()) {
collectPrologSuggestion(scanner.getTokenEnd(), "", completionRequest,
completionResponse);
return completionResponse;
}
} catch (BadLocationException e) {
LOGGER.log(Level.SEVERE, "In XMLCompletions, StartPrologOrPI position error", e);
}
break;
}
case PIName: {
try {

String tagName = scanner.getTokenText();
boolean isFirstNode = xmlDocument.positionAt(scanner.getTokenOffset()).getLine() == 0;
String substringXML = "xml".substring(0, scanner.getTokenText().length());
if (isFirstNode && offset <= scanner.getTokenEnd() && scanner.getTokenText().equals(substringXML)) {
collectPrologSuggestion(scanner.getTokenEnd(), scanner.getTokenText(), completionRequest,
completionResponse, false);
completionResponse, true);
return completionResponse;
}
} catch (BadLocationException e) {
Expand All @@ -221,17 +237,16 @@ public CompletionList doComplete(XMLDocument xmlDocument, Position position, Com
}
case PrologName: {
try {
boolean isFirstNode;
isFirstNode = xmlDocument.positionAt(scanner.getTokenOffset()).getLine() == 0;
boolean isFirstNode = xmlDocument.positionAt(scanner.getTokenOffset()).getLine() == 0;
if (isFirstNode && offset <= scanner.getTokenEnd()) {
collectPrologSuggestion(scanner.getTokenEnd(), scanner.getTokenText(), completionRequest,
completionResponse, true);
completionResponse);
return completionResponse;
}
} catch (BadLocationException e) {
LOGGER.log(Level.SEVERE, "In XMLCompletions, PrologName position error", e);
}
break;
}
break;
}
default:
if (offset <= scanner.getTokenEnd()) {
Expand Down Expand Up @@ -318,6 +333,7 @@ private void collectOpenTagSuggestions(boolean hasOpenBracket, Range replaceRang
int tagNameEnd = document.offsetAt(replaceRange.getEnd());
int newOffset = getOffsetFollowedBy(text, tagNameEnd, ScannerState.WithinEndTag, TokenType.EndTagClose);
if (newOffset != -1) {
newOffset++;
replaceRange.setEnd(document.positionAt(newOffset));
}

Expand Down Expand Up @@ -380,34 +396,56 @@ private void collectOpenTagSuggestions(boolean hasOpenBracket, Range replaceRang
/**
* Collect xml prolog completions.
*
* @param tagNameEnd
* @param startOffset
* @param tag
* @param request
* @param response
*/
private void collectPrologSuggestion(int tagNameEnd, String tag, CompletionRequest request,
CompletionResponse response, boolean includesXML) {


String prologName = includesXML ? "" : "xml";
private void collectPrologSuggestion(int startOffset, String tag, CompletionRequest request,
CompletionResponse response) {
collectPrologSuggestion(startOffset, tag, request, response, false);
}

private void collectPrologSuggestion(int tokenEndOffset, String tag, CompletionRequest request,
CompletionResponse response, boolean inPIState) {
XMLDocument document = request.getXMLDocument();
CompletionItem item = new CompletionItem();
item.setLabel("<?xml ... ?>");
item.setKind(CompletionItemKind.Property);
item.setFilterText(prologName + " version=\"1.0\" encoding=\"UTF-8\"?>");
item.setFilterText("xml version=\"1.0\" encoding=\"UTF-8\"?>");
item.setInsertTextFormat(InsertTextFormat.Snippet);
int closingBracketOffset = getOffsetFollowedBy(document.getText(), tagNameEnd, ScannerState.WithinTag,
TokenType.StartTagClose);
int end = closingBracketOffset != -1 ? closingBracketOffset - 1 : tagNameEnd;
String closeTag = closingBracketOffset != -1 ? "" : ">";
int closingBracketOffset;
if(inPIState) {
closingBracketOffset= getOffsetFollowedBy(document.getText(), tokenEndOffset, ScannerState.WithinPI,
TokenType.PIEnd);
}
else {//prolog state
closingBracketOffset = getOffsetFollowedBy(document.getText(), tokenEndOffset, ScannerState.WithinTag,
TokenType.PrologEnd);
}

if(closingBracketOffset != -1) {
//Include '?>'
closingBracketOffset += 2;
}
else {
closingBracketOffset = getOffsetFollowedBy(document.getText(), tokenEndOffset, ScannerState.WithinTag,
TokenType.StartTagClose);
if(closingBracketOffset == -1) {
closingBracketOffset = tokenEndOffset;
}
else {
closingBracketOffset ++;
}
}
int startOffset = tokenEndOffset - tag.length();
try {
Range editRange = getReplaceRange(tagNameEnd, end, request);
item.setTextEdit(new TextEdit(editRange, prologName + " version=\"1.0\" encoding=\"UTF-8\"?" + closeTag + "$0"));
Range editRange = getReplaceRange(startOffset, closingBracketOffset, request);
item.setTextEdit(new TextEdit(editRange, "xml version=\"1.0\" encoding=\"UTF-8\"?>" + "$0"));
} catch (BadLocationException e) {
LOGGER.log(Level.SEVERE, "While performing getReplaceRange for prolog completion.", e);
}
response.addCompletionItem(item);

}

private void collectCloseTagSuggestions(int afterOpenBracket, boolean inOpenTag, int tagNameEnd,
Expand Down Expand Up @@ -657,13 +695,22 @@ private static boolean isFollowedBy(String s, int offset, ScannerState intialSta
return getOffsetFollowedBy(s, offset, intialState, expectedToken) != -1;
}

/**
* Returns starting offset of 'expectedToken' if it the next non whitespace token after
* 'initialState'
* @param s
* @param offset
* @param intialState
* @param expectedToken
* @return
*/
private static int getOffsetFollowedBy(String s, int offset, ScannerState intialState, TokenType expectedToken) {
Scanner scanner = XMLScanner.createScanner(s, offset, intialState);
TokenType token = scanner.scan();
while (token == TokenType.Whitespace) {
token = scanner.scan();
}
return (token == expectedToken) ? scanner.getTokenOffset() + 1 : -1;
return (token == expectedToken) ? scanner.getTokenOffset() : -1;
}

private static int getWordStart(String s, int offset, int limit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,34 @@ public void testAutoCloseEnabledDisabled() throws BadLocationException {
@Test
public void testAutoCompletionPrologWithXML() throws BadLocationException {
//With 'xml' label
testCompletionFor("<?xml|", false, c("<?xml ... ?>", " version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 5, 0, 5),
" version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?xml|>", true, c("<?xml ... ?>", " version=\"1.0\" encoding=\"UTF-8\"?$0", r(0, 5, 0, 5),
" version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?xml|", false, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 5),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?xml|>", true, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 6),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?xml|?>", true, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 7),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
}

@Test
public void testAutoCompletionPrologWithoutXML() throws BadLocationException {
//No 'xml' label
testCompletionFor("<?|", false, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 2),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?|>", true, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?$0", r(0, 2, 0, 2),
testCompletionFor("<?|>", true, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 3),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?|?>", true, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 4),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
}

@Test
public void testAutoCompletionPrologWithPartialXML() throws BadLocationException {
testCompletionFor("<?x|", false, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 3),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?xm|", false, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 4),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?x|", false, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 3),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
testCompletionFor("<?xm|?>", false, c("<?xml ... ?>", "xml version=\"1.0\" encoding=\"UTF-8\"?>$0", r(0, 2, 0, 6),
"xml version=\"1.0\" encoding=\"UTF-8\"?>"));
}

Expand Down

0 comments on commit 4d7a66b

Please sign in to comment.