Skip to content

Commit

Permalink
Quickfix to close open tag doesn't deal with attributes
Browse files Browse the repository at this point in the history
Fixes eclipse#646

Signed-off-by: azerr <[email protected]>
  • Loading branch information
angelozerr committed Jun 2, 2020
1 parent 84d2689 commit 366d88e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.xerces.xni.XMLLocator;
import org.eclipse.lemminx.dom.DOMDocument;
import org.eclipse.lemminx.dom.DOMDocumentType;
import org.eclipse.lemminx.dom.DOMNode;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.ETagRequiredCodeAction;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.ElementUnterminatedCodeAction;
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.EqRequiredInAttributeCodeAction;
Expand All @@ -30,6 +31,7 @@
import org.eclipse.lemminx.extensions.contentmodel.participants.codeactions.RootElementTypeMustMatchDoctypedeclCodeAction;
import org.eclipse.lemminx.services.extensions.ICodeActionParticipant;
import org.eclipse.lemminx.services.extensions.diagnostics.IXMLErrorCode;
import org.eclipse.lemminx.utils.StringUtils;
import org.eclipse.lemminx.utils.XMLPositionUtility;
import org.eclipse.lemminx.utils.XMLPositionUtility.EntityReferenceRange;
import org.eclipse.lsp4j.Range;
Expand All @@ -56,8 +58,9 @@ public enum XMLSyntaxErrorCode implements IXMLErrorCode {
the_element_type_lmsg("the-element-type-lmsg"), EqRequiredInXMLDecl, IllegalQName, InvalidCommentStart,
LessthanInAttValue, MarkupEntityMismatch, MarkupNotRecognizedInContent, NameRequiredInReference, OpenQuoteExpected,
PITargetRequired, PseudoAttrNameExpected, QuoteRequiredInXMLDecl, RootElementTypeMustMatchDoctypedecl,
SDDeclInvalid, SemicolonRequiredInReference, SpaceRequiredBeforeEncodingInXMLDecl, SpaceRequiredBeforeStandalone, SpaceRequiredInPI,
VersionInfoRequired, VersionNotSupported, XMLDeclUnterminated, CustomETag, PrematureEOF, DoctypeNotAllowed, NoMorePseudoAttributes;
SDDeclInvalid, SemicolonRequiredInReference, SpaceRequiredBeforeEncodingInXMLDecl, SpaceRequiredBeforeStandalone,
SpaceRequiredInPI, VersionInfoRequired, VersionNotSupported, XMLDeclUnterminated, CustomETag, PrematureEOF,
DoctypeNotAllowed, NoMorePseudoAttributes;

private final String code;

Expand Down Expand Up @@ -108,13 +111,22 @@ public static Range toLSPRange(XMLLocator location, XMLSyntaxErrorCode code, Obj
case SpaceRequiredBeforeEncodingInXMLDecl:
case VersionInfoRequired:
case ElementPrefixUnbound:
case ElementUnterminated:
case RootElementTypeMustMatchDoctypedecl:
return XMLPositionUtility.selectStartTagName(offset, document);
case EqRequiredInAttribute: {
String attrName = getString(arguments[1]);
return XMLPositionUtility.selectAttributeNameFromGivenNameAt(attrName, offset, document);
}
case ElementUnterminated: {
String text = document.getText();
DOMNode element = document.findNodeAt(offset);
int endOffset = offset;
while (Character.isWhitespace(text.charAt(endOffset))) {
endOffset--;
}
endOffset++;
return XMLPositionUtility.createRange(element.getStart() + 1, endOffset, document);
}
case NoMorePseudoAttributes:
case EncodingDeclRequired:
case EqRequiredInXMLDecl:
Expand Down Expand Up @@ -210,7 +222,7 @@ public static Range toLSPRange(XMLLocator location, XMLSyntaxErrorCode code, Obj
}
case DoctypeNotAllowed:
DOMDocumentType docType = document.getDoctype();
return XMLPositionUtility.createRange(docType);
return XMLPositionUtility.createRange(docType);
case PITargetRequired:
// Working
break;
Expand Down Expand Up @@ -238,6 +250,7 @@ public static void registerCodeActionParticipants(Map<String, ICodeActionPartici
codeActions.put(OpenQuoteExpected.getCode(), new OpenQuoteExpectedCodeAction());
codeActions.put(MarkupEntityMismatch.getCode(), new MarkupEntityMismatchCodeAction());
codeActions.put(ETagRequired.getCode(), new ETagRequiredCodeAction());
codeActions.put(RootElementTypeMustMatchDoctypedecl.getCode(), new RootElementTypeMustMatchDoctypedeclCodeAction());
codeActions.put(RootElementTypeMustMatchDoctypedecl.getCode(),
new RootElementTypeMustMatchDoctypedeclCodeAction());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,36 @@ public class ElementUnterminatedCodeAction implements ICodeActionParticipant {
public void doCodeAction(Diagnostic diagnostic, Range range, DOMDocument document, List<CodeAction> codeActions,
SharedSettings sharedSettings, IComponentProvider componentProvider) {
Range diagnosticRange = diagnostic.getRange();
// Close with '/>
CodeAction autoCloseAction = CodeActionFactory.insert("Close with '/>'", diagnosticRange.getEnd(), "/>",
document.getTextDocument(), diagnostic);
codeActions.add(autoCloseAction);

// Close with '>
CodeAction closeAction = CodeActionFactory.insert("Close with '>'", diagnosticRange.getEnd(), ">",
document.getTextDocument(), diagnostic);
codeActions.add(closeAction);

// Close with '$tag>
try {
int offset = document.offsetAt(range.getStart());
DOMNode node = document.findNodeAt(offset);
int startOffset = document.offsetAt(diagnosticRange.getStart());
DOMNode node = document.findNodeAt(startOffset);
if (node != null && node.isElement()) {
String tagName = ((DOMElement) node).getTagName();
if (tagName != null) {
String insertText = "></" + tagName + ">";
CodeAction closeEndTagAction = CodeActionFactory.insert("Close with '" + insertText + "'",
diagnosticRange.getEnd(), insertText, document.getTextDocument(), diagnostic);
codeActions.add(closeEndTagAction);
int endOffset = startOffset
+ (diagnosticRange.getEnd().getCharacter() - diagnosticRange.getStart().getCharacter());
DOMElement element = (DOMElement) node;
char c = document.getText().charAt(endOffset - 1);
if (c != '/') {
// Close with '/>
CodeAction autoCloseAction = CodeActionFactory.insert("Close with '/>'", diagnosticRange.getEnd(),
"/>", document.getTextDocument(), diagnostic);
codeActions.add(autoCloseAction);

String tagName = element.getTagName();
if (tagName != null) {
String insertText = "></" + tagName + ">";
CodeAction closeEndTagAction = CodeActionFactory.insert("Close with '" + insertText + "'",
diagnosticRange.getEnd(), insertText, document.getTextDocument(), diagnostic);
codeActions.add(closeEndTagAction);
}

}
// Close with '>
CodeAction closeAction = CodeActionFactory.insert("Close with '>'", diagnosticRange.getEnd(), ">",
document.getTextDocument(), diagnostic);
codeActions.add(closeAction);

}
} catch (BadLocationException e) {
// do nothing
Expand Down

0 comments on commit 366d88e

Please sign in to comment.