Change:
<!-- Please search existing issues to avoid creating duplicates. --<!-- Also please test using the latest insiders build to make sure your issue has not already been fixed: --<!-- Use Help Report Issue to prefill these. --- VSCode Version: 1.42.0-insider OS Version: macOS Steps to Reproduce: See the following gif: ! I first enter the tag which activates multicursor, then I use the key combi to select and jump to the end of the line, go one back and use "Backspace" to delete the attribute. This is a common operation, but now with mirror cursors it might break the HTML as seen in the gif above. Moreover, if the opening & closing tag are further apart, one might not even notice the HTML is broken. <!-- Launch with to check. --Does this issue occur when all extensions are disabled?: Yes
Also this quite a lot as this is a very common operation. Related to this is ctrl+shift selecting out of the element tag name. I'd like to work on. The fix would be to exit mirror mode if the selection is not empty and we reach a none-matching state.
This also brings up an issue when you try to add an attribute to multiple tags that have none. ! If you click the open tag, it'll select the opening and closing, and usually when you're at the end and you press space to type in the attribute it doesn't add the attributes to the closing tag, but when you're adding more cursors to the tags in other lines, it doesn't act like that anymore and adds the attributes to both tags. I went crazy trying to find this to disable it.
Yeah looking at the current implementation, there's no support at all for multiple cursors. That's gonna take some work for the behavior to work correctly.
This feature doesn't work well with extension vim too, have to shut it down.
The fix will be available in until next month's release.

Discussion:
if (event.selections[0].isEmpty) { matchingTagPositionProvider(event.textEditor.document, event.selections[0].active).then(matchingTagPosition => { if (matchingTagPosition && window.activeTextEditor) { <del> const charBeforeAndAfterPositionsRoughtlyEqual = isCharBeforeAndAfterPositionsRoughtlyEqual( </del> <ins> const charBeforeAndAfterPositionsRoughlyEqual = isCharBeforeAndAfterPositionsRoughlyEqual( </ins> event.textEditor.document, event.selections[0].anchor, new Position(matchingTagPosition.line, matchingTagPosition.character) ); <del> if (charBeforeAndAfterPositionsRoughtlyEqual) { </del> <ins> if (charBeforeAndAfterPositionsRoughlyEqual) { </ins> inMirrorMode = true; const newCursor = new Selection( matchingTagPosition.line,

}; if (cursors.length === 2 && inMirrorMode) { <ins> /** * Both cursors are positions */ </ins> if (event.selections[0].isEmpty && event.selections[1].isEmpty) { if ( prevCursors.length === 2 &&

return; } <del> const charBeforeAndAfterPositionsRoughtlyEqual = isCharBeforeAndAfterPositionsRoughtlyEqual( </del> <ins> const charBeforeAndAfterPositionsRoughlyEqual = isCharBeforeAndAfterPositionsRoughlyEqual( </ins> event.textEditor.document, event.selections[0].anchor, event.selections[1].anchor ); <del> if (!charBeforeAndAfterPositionsRoughtlyEqual) { </del> <ins> if (!charBeforeAndAfterPositionsRoughlyEqual) { </ins> exitMirrorMode(); return; } else {

} } } <ins> /** * Both cursors are selections */ else { const charBeforeAndAfterAnchorPositionsRoughlyEqual = isCharBeforeAndAfterPositionsRoughlyEqual( event.textEditor.document, event.selections[0].anchor, event.selections[1].anchor ); const charBeforeAndAfterActivePositionsRoughlyEqual = isCharBeforeAndAfterPositionsRoughlyEqual( event.textEditor.document, event.selections[0].active, event.selections[1].active ); if (!charBeforeAndAfterAnchorPositionsRoughlyEqual || !charBeforeAndAfterActivePositionsRoughlyEqual) { exitMirrorMode(); } } </ins> } }

} // Check if chars before and after the two positions are equal <del> // For the chars before, `<` and `/` are consiered equal to handle the case of `<|></|>` function isCharBeforeAndAfterPositionsRoughtlyEqual(document: TextDocument, firstPos: Position, secondPos: Position) { </del> <ins> // For the chars before, `<` and `/` are considered equal to handle the case of `<|></|>` function isCharBeforeAndAfterPositionsRoughlyEqual(document: TextDocument, firstPos: Position, secondPos: Position) { </ins> const charBeforePrimarySelection = getCharBefore(document, firstPos); const charAfterPrimarySelection = getCharAfter(document, firstPos); const charBeforeSecondarySelection = getCharBefore(document, secondPos);