After conducting tests on your code, I have confirmed that my previous comment was accurate regarding the insertion of text at line 2 in a document without pre-existing content.
editBuilder.insert(new vscode.Position(2,3), 'someText');
Unfortunately, the editBuilder
does not create new lines automatically if they do not exist already. Instead, it simply appends the text to the existing line, typically line 1.
To overcome this limitation, there are two alternative approaches:
- Preferred method: Construct your string as a string literal.
let insertString;
// Create the C# string
insertString = `using System;
namespace HelloWorld {
class HelloWorld {
static void Main(string[] args) {
Console.WriteLine("Hello World!");
}
}
}`;
// Utilize one of these for all instances of insertString
await vscode.window.activeTextEditor.edit(editBuilder => {
editBuilder.insert(new vscode.Position(0,0), insertString);
});
This approach works smoothly and allows you to verify the correctness of your string's format and indentation easily.
- Add enough empty lines first before making your edits:
// Convert these into a loop
await vscode.commands.executeCommand('editor.action.insertLineAfter');
await vscode.commands.executeCommand('editor.action.insertLineAfter');
await vscode.commands.executeCommand('editor.action.insertLineAfter');
await vscode.commands.executeCommand('editor.action.insertLineAfter');
await vscode.commands.executeCommand('editor.action.insertLineAfter');
await vscode.commands.executeCommand('editor.action.insertLineAfter');
await vscode.commands.executeCommand('editor.action.insertLineAfter');
await vscode.commands.executeCommand('editor.action.insertLineAfter');
// Adjusted the Position arguments here
// Note that all character Positions are set to 0
await vscode.window.activeTextEditor.edit(editBuilder => {
editBuilder.insert(new vscode.Position(0,0), 'using System;');
editBuilder.insert(new vscode.Position(2,0), 'namespace HelloWorld {');
editBuilder.insert(new vscode.Position(3,0), '\tclass HelloWorld {');
editBuilder.insert(new vscode.Position(4,0), '\t\tstatic void Main(string[] args) {');
editBuilder.insert(new vscode.Position(5,0), '\t\t\tConsole.WriteLine("Hello World!");');
editBuilder.insert(new vscode.Position(6,0), '\t\t}');
editBuilder.insert(new vscode.Position(7,0), '\t}');
editBuilder.insert(new vscode.Position(8,0), '}');
});
Note on Positions: It is important to note that attempting to insert text at a specific character position like
editBuilder.insert(new vscode.Position(6,12)...
will not work on an empty line 6 since there is no character 12 on an empty line. For indentation purposes, zeroing out the Position characters and inserting tabs (\t) is recommended. This further underscores why the first method is more efficient.
Both methods are effective, but the first method is cleaner. Here is a demonstration of both methods working consecutively within the same activate
function:
https://i.sstatic.net/IIHFG.gif
Another useful tip is to select all text and then execute the command editor.action.formatSelection
after setting the languageId for the file (verify if it has not been set by the user):
const editor = vscode.window.activeTextEditor;
await vscode.languages.setTextDocumentLanguage(editor.document, 'javascript');
// Take note that formatting of the insertString is not attempted here
const insertString = `using System;
namespace HelloWorld {
class HelloWorld {
static void Main(string[] args) {
Console.WriteLine("Hello World!");
}
}
}`;
await editor.edit(editBuilder => {
editBuilder.insert(new vscode.Position(10,0), insertString);
});
// Select all text and run formatSelection
await vscode.commands.executeCommand('editor.action.selectAll');
await vscode.commands.executeCommand('editor.action.formatSelection');
await vscode.commands.executeCommand('cancelSelection');
This assumes that the user has a formatter installed for each language.
Demonstration of this formatter:
https://i.sstatic.net/6ko4t.gif