Over the last year we have committed to making the PowerShell editing experience in Visual Studio Code a rich and productive cross-platform alternative for the PowerShell ISE. To that end, we have focused on two primary areas: bringing the PSReadLine experience to the Integrated Console, and improving the stability of the extension while editing and debugging. The goal of this blog post is to walk through how we have made efforts in these key areas, and what our next steps are to follow through on these efforts.
Investments in the reliability of PowerShell in Visual Studio Code
Our number one user request for the PowerShell editing experience in Visual Studio Code is to improve the stability of the editor and debugger. Long-standing constraints in the original design of the PowerShell extension made it difficult to improve its robustness through incremental changes. Instead, over the last six months we prioritized work to re-architect the extension with an emphasis on stability.
Using the Omnisharp Project’s Common Language Server Protocol
Based on the maturity of OmniSharp we took advantage of the project’s common language server protocol implementation which is a .NET library. It is important to note that Omnisharp’s common LSP server library is distinct from Omnisharp which is largely synonymous with the C# LSP backend. While we do hope this Omnisharp port will improve your editing experience, do not expect it to provide additional .NET completions. Omnisharp’s architecture is more robust meaning that bugs that might once have been crashes will now be caught and logged. By leveraging this library we were able to greatly simplify our code and are now more compliant with language server protocol.
Ultimately, we believe that these changes will significantly reduce the number crashes of the extension and improve the performance overall. These changes shipped in the November 2019 release of the PowerShell Preview extension and will ship with the January 2020 release of the PowerShell extension.
Other features of the Omnisharp Port
- Asynchronous message handling for increase in performance
- CodeLens requests no longer depend on running PowerShell so IntelliSense hangs should reduce
- Formatting is now handled directly by the language server
PSScriptAnalyser (PSSA) is a static code checker for PowerShell modules and scripts, which provides services like script diagnostics and formatting in the PowerShell extension. In our analysis of the PowerShell extension we found that PSScriptAnalyzer had a major impact on the performance of the extension overall so we have been investing in changes to how PSSA integrates with the PowerShell extension.
In the current architecture, the PowerShell extension must interface with PSSA through its cmdlets, which re-instantiate the PSSA engine on every invocation. Further, because we must use PowerShell cmdlet invocation for this, the PowerShell extension is forced to manage the overhead of PowerShell runspace management and command resolution to run PSSA. In scenarios like real-time diagnostics and formatting, this overhead has become a significant bottleneck for the extension. Instead, since PSSA is .NET code at heart, we are moving toward a model allowing direct hosting of PSSA in .NET, with management and invocation of the PSSA engine performed through a set of suitable public .NET APIs. Work on these APIs has entered into a validation and integration phase and we expect this improvement to ship with the January 2020 release of the PowerShell extension.
PSReadLine support in the Integrated Console
Full PSReadLine support has long been at the top of our list for feature requests. It has also been among our most difficult problems to solve because at its core it also required architectural changes in how the PowerShell extension manages threading and runspaces.
The additional challenge of trying to support both legacy versions of PowerShell and a range of platform distributions has caused this problem to continually be delayed. In January of 2019 we released a Preview version of the PowerShell extension which was built on .NET Standard thereby enabling us to support PSReadLine in the integrated console for Windows users on PowerShell Version 5.1 and above.
With PowerShell 7 delivering a fix in .NET Core 3.0 for the way POSIX terminal APIs are handled when starting new processes, we are finally able to move the PSReadLine support currently available in the PowerShell Preview extension into the stable PowerShell extension with support across platform distributions. We expect to ship this update in the same time frame as PowerShell 7 (targeted for January 2020).
Dropping support for PowerShell Versions 3 and 4
Support for PSReadLine in the PowerShell extension Integrated Console depends on changes made in PSReadLine since it moved to version 2.0, where it dropped support for PowerShell versions 3 and 4. In turn, we also made the difficult decision to no longer support PowerShell 3 and 4 in future updates of the extension. In making this decision we analyzed the use of these PowerShell versions and found that approximately 1% of PowerShell session in VSCode use one of these versions. In order to accommodate these use cases we will ship a final stable version of the extension with PowerShell version 3 and 4 support which can continue to be used. To use this version of the extension the user will still install the PowerShell extension through the VSCode marketplace. They will then need to use the extension settings to select their desired version.