Last year I made a conscious decision to jump into VS Code as my primary PowerShell development tool. I had spent years tweaking and customizing the PowerShell ISE so I was a little concerned about the transition. But I knew the only way I'd master VS Code (and I still have a long way to go) would be to use it all the time. One of the features of VSCode that made this possible is PowerShellEditorServices. Much of the functionality is exposed through the $PSEditor object in VS Code, similar to $PSISE in the PowerShell ISE. Unfortunately, there is not a lot of IT Pro friendly material on the topic. So let me add a little bit.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
In my VS Code profile ($profile), I add commands to configure the editor. One of the things I do is use the Register-EditorCommand cmdlet to add custom commands. I can get them by accessing the command palette and selecting PowerShell: Show Additional Commands from PowerShell Modules.
When I select that I get a list of available commands:
These are commands I defined in my VSCode profile and added. Here's how.
I use Open Live Writer to prepare blog posts. My blog uses the Crayon plugin to format code samples. To speed things up, I can insert the necessary HTML code into my local source. In the PowerShell ISE I had a custom menu add-on that would copy selected text, insert the necessary HTML and copy the result to the clipboard where I could paste it into Open Live Writer. I needed to do the same thing for VS Code.
Function ExportAsCrayon { [cmdletbinding()] param ([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) $text = $context.CurrentFile.GetText($context.SelectedRange).Replace(">", ">").Replace("<", "<").Trim() $code = @" <pre class="lang:ps mark:0 decode:true"> $text </pre> "@ $code | Set-clipboard $psEditor.Window.ShowInformationMessage("The selected text has been converted and copied to the clipboard.") }
Most functions you write for VSCode will likely use the $Context parameter. As the name suggests, this tells VSCode where you are and gives you access to some methods and properties. In my function I am using the CurrentFile object and the GetText() method to get the selected text. The tricky thing is that the parameter you need to pass is the SelectedRange property from $Context. This is one of those things that isn't very well documented. The rest of my code is using the Replace() method to escape the angle bracket characters for my HTML. This is plugged into a here string, $code, which is sent to the clipboard.
The last step is to invoke the ShowInformationMessage() which will provide a visual prompt.
You can also use methods like this:
$pseditor.window.ShowErrorMessage("You made a mistake") $pseditor.window.ShowWarningMessage("I wouldn't do that if I were you.")
Once I have the function, I can register it with VS Code.
Register-EditorCommand -Name ExportAsCrayon -DisplayName "Export Code as Crayon" -Function ExportAsCrayon
This is a PowerShell cmdlet so you can read help about it. The Name is the programmatic name and the DisplayName is what you see in the drop down list.
But to access this command takes several keyboard steps. VS Code is full of keyboard shortcuts and bindings. I'd like to create my own.
Unfortunately, there is no way currently to programmatically create or define a keyboard shortcut. Instead you need to go to File – Preferences – Keyboard Shortcuts and then click the link to edit keybindings.json.
The default application settings will be in the left panel and your custom settings will be in the right. To add a new one, insert a comma after the last one but before the closing square bracket. Then enter a set of {}.
You will need to enter a key. I'll use Ctrl+F6. The setting for "command" will be "PowerShell.InvokeRegisteredEditorCommand". The tricky part, and what took me the longest to figure out, is the parameter or argument value. The method is pretty clear about what it is going to do. Create an "args" key with a value that looks like this: "commandName": "ExportAsCrayon"}. Use the short name of your registered command. Optionally, you can add a setting for "when" the keybinding is active. I want mine to be when the editor is active. Here's the complete json entry.
{ "key":"ctrl+f6", "command": "PowerShell.InvokeRegisteredEditorCommand", "args" : {"commandName": "ExportAsCrayon"}, "when": "editorTextFocus" }
Save the file and you are ready to use it. If you don't get the results you expect or errors, check your entry. Json is case sensitive. The args entry must be "commandName". I generally try to follow case based on other key binding entries.
But now I'm all set. The Register-EditorCommand expression is in my VSCode profile and I only have to add the keybinding once. Now I can select text, press Ctrl+F6 and get my Crayon-formatted code copied to the clipboard.
I hope this helps you and saves a little head banging. I think I've done enough of that for all of us.
Hi,
I’ve been looking for this since I tried to use VSCode for my PowerShell scripts!
I just don’t get it how to make that commands persistent when I close the VSCode program.
Can you enlighten me?
Nevermind… I read the $Profile part… lol
Thanks!!!!