Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Emmet - Fixing bug in toggle comment with multi cursor #42857

Merged
merged 6 commits into from
Feb 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
108 changes: 108 additions & 0 deletions extensions/emmet/src/test/toggleComment.test.ts
Expand Up @@ -201,6 +201,52 @@ suite('Tests for Toggle Comment action from Emmet (HTML)', () => {
});
});
});

test('toggle comment with multiple cursors selecting parent and child nodes', () => {
const expectedContents = `
<div class="hello">
<ul>
<li><!--<span>Hello</span>--></li>
<!--<li><span>There</span></li>-->
<div><li><span>Bye</span></li></div>
</ul>
<!--<ul>
<li>Previously Commented Node</li>
<li>Another Node</li>
</ul>-->
<span/>
<!--<style>
.boo {
margin: 10px;
padding: 20px;
}
.hoo {
margin: 10px;
padding: 20px;
}
</style>-->
</div>
`;
return withRandomFileEditor(contents, 'html', (editor, doc) => {
editor.selections = [
new Selection(3, 17, 3, 17), // cursor inside the inner span element
new Selection(4, 5, 4, 5), // two cursors: one inside opening tag
new Selection(4, 17, 4, 17), // and the second inside the inner span element
new Selection(7, 3, 7, 3), // two cursors: one inside open tag of <ul> one of of whose children is already commented
new Selection(9, 10, 9, 10), // and the second inside inner li element, whose parent is selected
new Selection(12, 3, 12, 3), // four nested cursors: one inside the style open tag
new Selection(14, 8, 14, 8), // the second inside the css property inside the style tag
new Selection(18, 3, 18, 3), // the third inside the css rule inside the style tag
new Selection(19, 8, 19, 8) // and the fourth inside the css property inside the style tag
];

return toggleComment().then(() => {
assert.equal(doc.getText(), expectedContents);

return Promise.resolve();
});
});
});
});

suite('Tests for Toggle Comment action from Emmet (CSS)', () => {
Expand Down Expand Up @@ -470,6 +516,68 @@ suite('Tests for Toggle Comment action from Emmet in nested css (SCSS)', () => {
}
}`;

test('toggle comment with multiple cursors selecting nested nodes (SCSS)', () => {
const expectedContents = `
.one {
/*height: 42px;*/

/*.two {
width: 42px;
}*/

.three {
/*padding: 10px;*/
}
}`;
return withRandomFileEditor(contents, 'css', (editor, doc) => {
editor.selections = [
new Selection(2, 5, 2, 5), // cursor inside a property
new Selection(4, 4, 4, 4), // two cursors: one inside a nested rule
new Selection(5, 5, 5, 5), // and the second one inside a nested property
new Selection(9, 5, 9, 5) // cursor inside a property inside a nested rule
];

return toggleComment().then(() => {
assert.equal(doc.getText(), expectedContents);
return toggleComment().then(() => {
assert.equal(doc.getText(), contents);
return Promise.resolve();
});
});
});
});
test('toggle comment with multiple cursors selecting several nested nodes (SCSS)', () => {
const expectedContents = `
/*.one {
height: 42px;

.two {
width: 42px;
}

.three {
padding: 10px;
}
}*/`;
return withRandomFileEditor(contents, 'css', (editor, doc) => {
editor.selections = [
new Selection(1, 3, 1, 3), // cursor in the outside rule. And several cursors inside:
new Selection(2, 5, 2, 5), // cursor inside a property
new Selection(4, 4, 4, 4), // two cursors: one inside a nested rule
new Selection(5, 5, 5, 5), // and the second one inside a nested property
new Selection(9, 5, 9, 5) // cursor inside a property inside a nested rule
];

return toggleComment().then(() => {
assert.equal(doc.getText(), expectedContents);
return toggleComment().then(() => {
assert.equal(doc.getText(), contents);
return Promise.resolve();
});
});
});
});

test('toggle comment with multiple cursors, but no selection (SCSS)', () => {
const expectedContents = `
.one {
Expand Down
23 changes: 20 additions & 3 deletions extensions/emmet/src/toggleComment.ts
Expand Up @@ -33,12 +33,29 @@ export function toggleComment(): Thenable<boolean> | undefined {
}

return editor.edit(editBuilder => {
let allEdits: vscode.TextEdit[][] = [];
editor.selections.reverse().forEach(selection => {
let edits = toggleCommentInternal(editor.document, selection, rootNode!);
edits.forEach(x => {
editBuilder.replace(x.range, x.newText);
});
if (edits.length > 0) {
allEdits.push(edits);
}
});

// Apply edits in order so we can skip nested ones.
allEdits.sort((arr1, arr2) => {
let result = arr1[0].range.start.line - arr2[0].range.start.line;
return result === 0 ? arr1[0].range.start.character - arr2[0].range.start.character : result;
});
let lastEditPosition = new vscode.Position(0, 0);
for (let i = 0; i < allEdits.length; i++) {
const edits = allEdits[i];
if (edits[0].range.end.isAfterOrEqual(lastEditPosition)) {
edits.forEach(x => {
editBuilder.replace(x.range, x.newText);
lastEditPosition = x.range.end;
});
}
}
});
}

Expand Down