I am having trouble updating the vs code selection after the extension triggers.
const selection = editor.selection;
const text = editor.document.getText(selection);
const modText = "/* " + text + " */";
let edit = new vscode.WorkspaceEdit();
let startPos = new vscode.Position(selection.start.line, selection.start.character);
let endPos = new vscode.Position(selection.start.line + text.split(/\r\n|\r|\n/).length - 1, selection.start.character + text.length);
let range = new vscode.Range(startPos, endPos);
edit.replace(editor.document.uri, range, modText);
return vscode.workspace.applyEdit(edit);
I am selecting everything below.
body {
background: blue;
}
The result after trigger is:
/* body {
background: blue;
} */
but the selection is missing the initial /*
How do I change the selection to include the initial /* ???
Try adding this to the end of your code:
await vscode.workspace.applyEdit(edit); // add the next line
editor.selections = [new vscode.Selection(startPos, new vscode.Position(endPos.line, endPos.character+6))];
See that it adds 6 characters to account for the /*
and */
to a Selection
that should include your entire comment characters and included text.
This code does the same thing and is a little more compact:
editor.selections = [new vscode.Selection(startPos, endPos.translate(0, 6))];
By the way, your code can be simplified to:
const editor = vscode.window.activeTextEditor;
const selection = editor.selection;
const text = editor.document.getText(selection);
const modText = "/* " + text + " */";
let edit = new vscode.WorkspaceEdit();
edit.replace(editor.document.uri, selection, modText);
vscode.workspace.applyEdit(edit);
return editor.selections = [new vscode.Selection(selection.start, selection.end.translate(0, 6))];
With the result you want.
Better is to use an editBuilder
as it handles preserving selections across edits much better than WorkspaceEdit
does. That is why in the original answer you have to manually manipulate the selection after the edit to handle the different length of the new text - 6 characters longer.
But with an editBuilder
you can simply do this:
// make sure this is async so you can use await below
let disposable = vscode.commands.registerCommand('myExtensionID.myCommandName', async (args) => {
const editor = vscode.window.activeTextEditor;
const selection = editor.selection;
const text = editor.document.getText(selection);
const modText = "/* " + text + " */";
await editor.edit(editBuilder => {
editBuilder.replace(selection, modText);
});
return;
}
In a simple scenario, you should be able to use the editBuilder
, but in some more complicated cases it can be difficult to use the editBuilder
approach and then you can use WorkspaceEdit
.