Fix #49777 - Emmet balance In after balance out should go back to initial selection and not first child (#49996)

* Update Emmet - balance.ts

* Cover all cases
This commit is contained in:
Heldenkrieger01
2018-05-30 02:29:30 +02:00
committed by Ramya Rao
parent 0c64d0ddc4
commit 30bcdffcb3
2 changed files with 66 additions and 2 deletions

View File

@@ -7,6 +7,10 @@ import * as vscode from 'vscode';
import { HtmlNode } from 'EmmetNode';
import { getNode, parseDocument, validate } from './util';
let balanceOutStack: Array<vscode.Selection[]> = [];
let lastOut = false;
let lastBalancedSelections: vscode.Selection[] = [];
export function balanceOut() {
balance(true);
}
@@ -32,8 +36,28 @@ function balance(out: boolean) {
newSelections.push(range);
});
editor.selection = newSelections[0];
editor.selections = newSelections;
if (areSameSelections(newSelections, editor.selections)) {
return;
}
if (areSameSelections(lastBalancedSelections, editor.selections)) {
if (out) {
if (!balanceOutStack.length) {
balanceOutStack.push(editor.selections);
}
balanceOutStack.push(newSelections);
} else {
if (lastOut) {
balanceOutStack.pop();
}
newSelections = balanceOutStack.pop() || newSelections;
}
} else {
balanceOutStack = out ? [editor.selections, newSelections] : [];
}
lastOut = out;
lastBalancedSelections = editor.selections = newSelections;
}
function getRangeToBalanceOut(document: vscode.TextDocument, selection: vscode.Selection, rootNode: HtmlNode): vscode.Selection {
@@ -83,3 +107,14 @@ function getRangeToBalanceIn(document: vscode.TextDocument, selection: vscode.Se
}
function areSameSelections(a: vscode.Selection[], b: vscode.Selection[]): boolean {
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (!a[i].isEqual(b[i])) {
return false;
}
}
return true;
}

View File

@@ -211,6 +211,35 @@ suite('Tests for Next/Previous Select/Edit point and Balance actions', () => {
});
});
test('Emmet Balance In using the same stack as Balance out in html file', function (): any {
return withRandomFileEditor(htmlContents, 'html', (editor, doc) => {
editor.selections = [new Selection(15, 6, 15, 10)];
let expectedBalanceOutRanges: [number, number, number, number][] = [
[15, 3, 15, 32], // <li class="item1">Item 2</li>
[13, 23, 16, 2], // inner contents of <ul class="nav main">
[13, 2, 16, 7], // outer contents of <ul class="nav main">
[12, 21, 17, 1], // inner contents of <div class="header">
[12, 1, 17, 7], // outer contents of <div class="header">
[8, 6, 18, 0], // inner contents of <body>
[8, 0, 18, 7], // outer contents of <body>
[2, 16, 19, 0], // inner contents of <html>
[2, 0, 19, 7], // outer contents of <html>
];
expectedBalanceOutRanges.forEach(([linestart, colstart, lineend, colend]) => {
balanceOut();
testSelection(editor.selection, colstart, linestart, colend, lineend);
});
expectedBalanceOutRanges.reverse().forEach(([linestart, colstart, lineend, colend]) => {
testSelection(editor.selection, colstart, linestart, colend, lineend);
balanceIn();
});
return Promise.resolve();
});
});
});
function testSelection(selection: Selection, startChar: number, startline: number, endChar?: number, endLine?: number) {