Repository: microsoft/vscode (TypeScript)
Date: 2021-07-18 04:00:50+00:00
Task type: Feature

Issue:
Select to Matching Bracket direction should be end position to start position.
<!-- ⚠️⚠️ Do Not Delete This! feature_request_template ⚠️⚠️ -->
<!-- Please read our Rules of Conduct: https://opensource.microsoft.com/codeofconduct/ -->
<!-- Please search existing issues to avoid creating duplicates. -->

<!-- Describe the feature you'd like. -->
When using `editor.emmet.action.balanceOut` or `editor.action.selectToBracket` starting at the end bracket or HTML tag, the selection direction should be start to finish.  That will allow you to use Shift + Up and Shift + Down to expand the selection.  For example, below demonstrates what happens when you select from the ending brace and then try Shift + Up.

## Current
![before](https://user-images.githubusercontent.com/1426848/126055140-51845bf3-3402-45e9-8372-cc10c78f193a.gif)

## Desired
![after](https://user-images.githubusercontent.com/1426848/126055144-eaf18b67-f29b-4dcb-90b2-7abb3d986a92.gif)





Issue discussion:

Solution patch:
diff --git a/extensions/emmet/src/balance.ts b/extensions/emmet/src/balance.ts
--- a/extensions/emmet/src/balance.ts
+++ b/extensions/emmet/src/balance.ts
@@ -67,8 +67,17 @@ function getRangeToBalanceOut(document: vscode.TextDocument, rootNode: HtmlFlatN
 		return offsetRangeToSelection(document, nodeToBalance.start, nodeToBalance.end);
 	}
 
-	const innerSelection = offsetRangeToSelection(document, nodeToBalance.open.end, nodeToBalance.close.start);
-	const outerSelection = offsetRangeToSelection(document, nodeToBalance.open.start, nodeToBalance.close.end);
+	// Set reverse direction if we were in the end tag
+	let innerSelection: vscode.Selection;
+	let outerSelection: vscode.Selection;
+	if (nodeToBalance.close.start <= offset && nodeToBalance.close.end > offset) {
+		innerSelection = offsetRangeToSelection(document, nodeToBalance.close.start, nodeToBalance.open.end);
+		outerSelection = offsetRangeToSelection(document, nodeToBalance.close.end, nodeToBalance.open.start);
+	}
+	else {
+		innerSelection = offsetRangeToSelection(document, nodeToBalance.open.end, nodeToBalance.close.start);
+		outerSelection = offsetRangeToSelection(document, nodeToBalance.open.start, nodeToBalance.close.end);
+	}
 
 	if (innerSelection.contains(selection) && !innerSelection.isEqual(selection)) {
 		return innerSelection;
diff --git a/src/vs/editor/contrib/bracketMatching/bracketMatching.ts b/src/vs/editor/contrib/bracketMatching/bracketMatching.ts
--- a/src/vs/editor/contrib/bracketMatching/bracketMatching.ts
+++ b/src/vs/editor/contrib/bracketMatching/bracketMatching.ts
@@ -235,6 +235,13 @@ export class BracketMatchingController extends Disposable implements IEditorCont
 				const [open, close] = brackets;
 				selectFrom = selectBrackets ? open.getStartPosition() : open.getEndPosition();
 				selectTo = selectBrackets ? close.getEndPosition() : close.getStartPosition();
+
+				if (close.containsPosition(position)) {
+					// select backwards if the cursor was on the closing bracket
+					const tmp = selectFrom;
+					selectFrom = selectTo;
+					selectTo = tmp;
+				}
 			}
 
 			if (selectFrom && selectTo) {


Test patch:
diff --git a/src/vs/editor/contrib/bracketMatching/test/bracketMatching.test.ts b/src/vs/editor/contrib/bracketMatching/test/bracketMatching.test.ts
--- a/src/vs/editor/contrib/bracketMatching/test/bracketMatching.test.ts
+++ b/src/vs/editor/contrib/bracketMatching/test/bracketMatching.test.ts
@@ -112,11 +112,11 @@ suite('bracket matching', () => {
 			assert.deepStrictEqual(editor.getPosition(), new Position(1, 20));
 			assert.deepStrictEqual(editor.getSelection(), new Selection(1, 9, 1, 20));
 
-			// start position in close brackets
+			// start position in close brackets (should select backwards)
 			editor.setPosition(new Position(1, 20));
 			bracketMatchingController.selectToBracket(true);
-			assert.deepStrictEqual(editor.getPosition(), new Position(1, 20));
-			assert.deepStrictEqual(editor.getSelection(), new Selection(1, 9, 1, 20));
+			assert.deepStrictEqual(editor.getPosition(), new Position(1, 9));
+			assert.deepStrictEqual(editor.getSelection(), new Selection(1, 20, 1, 9));
 
 			// start position between brackets
 			editor.setPosition(new Position(1, 16));
@@ -234,9 +234,9 @@ suite('bracket matching', () => {
 			]);
 			bracketMatchingController.selectToBracket(true);
 			assert.deepStrictEqual(editor.getSelections(), [
-				new Selection(1, 1, 1, 5),
-				new Selection(1, 8, 1, 13),
-				new Selection(1, 16, 1, 19)
+				new Selection(1, 5, 1, 1),
+				new Selection(1, 13, 1, 8),
+				new Selection(1, 19, 1, 16)
 			]);
 
 			bracketMatchingController.dispose();