├── EditorCommands ├── Demo1.OpenPowerPoint.ps1 ├── Demo2.OpenPsm1.ps1 ├── Demo3.OpenHelpers.ps1 ├── Demo4.OpenPowerPointScript.ps1 ├── Demo5.OpenProfile.ps1 ├── Demo6.GetProcessOutput.ps1 ├── EditorCommand.NewEditorCommandToClipboard.ps1 ├── EditorCommand.NewEditorCommandToFile.ps1 ├── EditorCommand.NewEditorCommandWithSelectedText.ps1 └── Helpers.ps1 ├── Images └── Demo.gif ├── LICENSE ├── PowerShellEditors.pptx ├── Readme.md ├── VSCodePresentations.ps1 └── VSCodePresentations.psm1 /EditorCommands/Demo1.OpenPowerPoint.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'Demo.OpenPowerPoint' ` 3 | -DisplayName 'Demo 1: Open PowerPoint' ` 4 | -SuppressOutput ` 5 | -ScriptBlock { 6 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 7 | 8 | $Pptx = Get-ChildItem -Path $PSScriptRoot\..\*.pptx 9 | Invoke-Item -Path $Pptx 10 | } -------------------------------------------------------------------------------- /EditorCommands/Demo2.OpenPsm1.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'Demo.OpenPsm1' ` 3 | -DisplayName 'Demo 2: Open Demo Module Psm1' ` 4 | -ScriptBlock { 5 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 6 | 7 | Open-EditorFile "$PSScriptRoot\..\*.psm1" 8 | } -------------------------------------------------------------------------------- /EditorCommands/Demo3.OpenHelpers.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'Demo.OpenHelpers' ` 3 | -DisplayName 'Demo 3: Open Helpers Script' ` 4 | -ScriptBlock { 5 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 6 | 7 | Open-EditorFile "$PSScriptRoot\Helpers.ps1" 8 | } -------------------------------------------------------------------------------- /EditorCommands/Demo4.OpenPowerPointScript.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'Demo.OpenPowerPointScript' ` 3 | -DisplayName 'Demo 4: Open PowerPoint Script' ` 4 | -ScriptBlock { 5 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 6 | 7 | Open-EditorFile "$PSScriptRoot\Demo1.OpenPowerPoint.ps1" 8 | } -------------------------------------------------------------------------------- /EditorCommands/Demo5.OpenProfile.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'Demo.OpenProfile' ` 3 | -DisplayName 'Demo 5: Open Profile' ` 4 | -SuppressOutput ` 5 | -ScriptBlock { 6 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 7 | 8 | $Current = Split-Path -Path $profile -Leaf 9 | $List = @($Current, 'Microsoft.VSCode_profile.ps1', 'Microsoft.PowerShell_profile.ps1', 'Microsoft.PowerShellISE_profile.ps1', 'Profile.ps1') | Select-Object -Unique 10 | $Choices = [System.Management.Automation.Host.ChoiceDescription[]] @($List) 11 | $Selection = ReadChoicePrompt -Prompt "Pl`ease Select a Profile" -Choices $Choices 12 | $Name = $List[$Selection] 13 | 14 | $ProfileDir = Split-Path $Profile -Parent 15 | $ProfileName = Join-Path -Path $ProfileDir -ChildPath $Name 16 | 17 | If (!(Test-Path -Path $ProfileName)) { New-Item -Path $ProfileName -ItemType File } 18 | 19 | $psEditor.Workspace.OpenFile($ProfileName) 20 | } -------------------------------------------------------------------------------- /EditorCommands/Demo6.GetProcessOutput.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'Demo.GetProcessOutput' ` 3 | -DisplayName 'Demo 6: Get-Process Output to Console' ` 4 | -ScriptBlock { 5 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 6 | 7 | Get-Process Code* 8 | } -------------------------------------------------------------------------------- /EditorCommands/EditorCommand.NewEditorCommandToClipboard.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'EditorCommand.NewEditorCommandToClipboard' ` 3 | -DisplayName 'Create Editor Command and copy to Clipboard' ` 4 | -SuppressOutput ` 5 | -ScriptBlock { 6 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 7 | 8 | $Name = ReadInputPrompt 'Please Type the Name of the Editor Command. Ex: Module.Command' 9 | $DisplayName = ReadInputPrompt 'Please Type the DisplayName of the Editor Command' 10 | 11 | $List = @('Yes', 'No') 12 | $Choices = [System.Management.Automation.Host.ChoiceDescription[]] @($List) 13 | $Selection = ReadChoicePrompt -Prompt "Do you want to Suppress Output?" -Choices $Choices 14 | $SuppressOutput = $List[$Selection] 15 | 16 | if ($SuppressOutput -eq 'Yes') 17 | { 18 | $Command = @" 19 | Register-EditorCommand `` 20 | -Name "$Name" `` 21 | -DisplayName "$DisplayName" `` 22 | -SuppressOutput `` 23 | -ScriptBlock { 24 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]`$context) 25 | $Selection 26 | $SuppressOutput 27 | } 28 | "@ 29 | } 30 | else 31 | { 32 | $Command = @" 33 | Register-EditorCommand `` 34 | -Name "$Name" `` 35 | -DisplayName "$DisplayName" `` 36 | -ScriptBlock { 37 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]`$context) 38 | $Selection 39 | $SuppressOutput 40 | } 41 | "@ 42 | } 43 | 44 | $Command | Set-Clipboard 45 | } 46 | -------------------------------------------------------------------------------- /EditorCommands/EditorCommand.NewEditorCommandToFile.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'EditorCommand.NewEditorCommandToFile' ` 3 | -DisplayName 'New Editor Command File' ` 4 | -SuppressOutput ` 5 | -ScriptBlock { 6 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 7 | 8 | $Name = ReadInputPrompt 'Please Type the Name of the Editor Command. Ex: Module.Command' 9 | $DisplayName = ReadInputPrompt 'Please Type the DisplayName of the Editor Command' 10 | 11 | $List = @('Yes', 'No') 12 | $Choices = [System.Management.Automation.Host.ChoiceDescription[]] @($List) 13 | $Selection = ReadChoicePrompt -Prompt "Do you want to Suppress Output?" -Choices $Choices 14 | $SuppressOutput = $List[$Selection] 15 | 16 | if ($SuppressOutput -eq 'Yes') 17 | { 18 | $Command = @" 19 | Register-EditorCommand `` 20 | -Name "$Name" `` 21 | -DisplayName "$DisplayName" `` 22 | -SuppressOutput `` 23 | -ScriptBlock { 24 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]`$context) 25 | 26 | # Enter Code Here 27 | 28 | } 29 | "@ 30 | } 31 | else 32 | { 33 | $Command = @" 34 | Register-EditorCommand `` 35 | -Name "$Name" `` 36 | -DisplayName "$DisplayName" `` 37 | -ScriptBlock { 38 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]`$context) 39 | 40 | # Enter Code Here 41 | 42 | } 43 | "@ 44 | } 45 | 46 | $Command | Out-File -FilePath "$($psEditor.Workspace.path)\EditorCommands\$($Name).ps1" 47 | 48 | Open-EditorFile "$($psEditor.Workspace.path)\EditorCommands\$($Name).ps1" 49 | $context.SetSelection(9,9,9,9) 50 | } 51 | -------------------------------------------------------------------------------- /EditorCommands/EditorCommand.NewEditorCommandWithSelectedText.ps1: -------------------------------------------------------------------------------- 1 | Register-EditorCommand ` 2 | -Name 'EditorCommand.NewEditorCommandWithSelectedText' ` 3 | -DisplayName 'New Editor Command File with Selected Text' ` 4 | -SuppressOutput ` 5 | -ScriptBlock { 6 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) 7 | 8 | $Name = ReadInputPrompt 'Please Type the Name of the Editor Command. Ex: Module.Command' 9 | $DisplayName = ReadInputPrompt 'Please Type the DisplayName of the Editor Command' 10 | 11 | $List = @('Yes', 'No') 12 | $Choices = [System.Management.Automation.Host.ChoiceDescription[]] @($List) 13 | $Selection = ReadChoicePrompt -Prompt "Do you want to Suppress Output?" -Choices $Choices 14 | $SuppressOutput = $List[$Selection] 15 | 16 | $Block = AddIndent -Source $($context.CurrentFile.GetText($context.SelectedRange)) -Amount 8 -ExcludeFirstLine 17 | 18 | if ($SuppressOutput -eq 'Yes') 19 | { 20 | $Command = @" 21 | Register-EditorCommand `` 22 | -Name "$Name" `` 23 | -DisplayName "$DisplayName" `` 24 | -SuppressOutput `` 25 | -ScriptBlock { 26 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]`$context) 27 | 28 | # Enter Code Here 29 | $Block 30 | } 31 | "@ 32 | } 33 | else 34 | { 35 | $Command = @" 36 | Register-EditorCommand `` 37 | -Name "$Name" `` 38 | -DisplayName "$DisplayName" `` 39 | -ScriptBlock { 40 | param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]`$context) 41 | 42 | # Enter Code Here 43 | $Block 44 | } 45 | "@ 46 | } 47 | 48 | $Command | Out-File -FilePath "$($psEditor.Workspace.path)\EditorCommands\$($Name).ps1" 49 | 50 | Open-EditorFile "$($psEditor.Workspace.path)\EditorCommands\$($Name).ps1" 51 | } 52 | 53 | 54 | -------------------------------------------------------------------------------- /EditorCommands/Helpers.ps1: -------------------------------------------------------------------------------- 1 | ## Editor Commands 2 | using namespace Microsoft.PowerShell.EditorServices.Protocol.MessageProtocol 3 | using namespace Microsoft.PowerShell.EditorServices.Protocol.Messages 4 | using namespace Microsoft.PowerShell.EditorServices 5 | 6 | 7 | function ReadInputPrompt 8 | { 9 | param([string]$Prompt) 10 | end 11 | { 12 | $result = $psEditor.Components.Get([IMessageSender]).SendRequest([ShowInputPromptRequest]::Type,[ShowInputPromptRequest]@{ 13 | Name = $Prompt 14 | Label = $Prompt 15 | },$true).Result 16 | 17 | if (-not $result.PromptCanceled) 18 | { 19 | $result.ResponseText 20 | } 21 | } 22 | } 23 | function ReadChoicePrompt 24 | { 25 | param([string]$Prompt, [System.Management.Automation.Host.ChoiceDescription[]]$Choices) 26 | end 27 | { 28 | $choiceIndex = 0 29 | $convertedChoices = $Choices.ForEach{ 30 | $newLabel = '{0} - {1}' -f ($choiceIndex + 1), $_.Label 31 | [ChoiceDetails]::new($newLabel, $_.HelpMessage) 32 | $choiceIndex++ 33 | } -as [ChoiceDetails[]] 34 | 35 | $result = $psEditor.Components.Get([IMessageSender]).SendRequest([ShowChoicePromptRequest]::Type,[ShowChoicePromptRequest]@{ 36 | Caption = $Prompt 37 | Message = $Prompt 38 | Choices = $convertedChoices 39 | DefaultChoices = 0 40 | },$true).Result 41 | 42 | if (-not $result.PromptCanceled) 43 | { 44 | $result.ResponseText | Select-String '^(\d+) - ' | ForEach-Object { $_.Matches.Groups[1].Value - 1 } 45 | } 46 | } 47 | } 48 | 49 | function AddIndent { 50 | [OutputType([string])] 51 | [CmdletBinding()] 52 | param( 53 | [Parameter(Mandatory, ValueFromPipeline)] 54 | [string[]] $Source, 55 | [string] $Indent = ' ', 56 | [int] $Amount = 4, 57 | [switch] $ExcludeFirstLine 58 | ) 59 | begin { 60 | $stringList = [System.Collections.Generic.List[string]]::new() 61 | } 62 | process { 63 | if ($null -eq $Source) { 64 | return 65 | } 66 | 67 | $stringList.AddRange($Source) 68 | } 69 | end { 70 | $sourceText = $stringList -join [Environment]::NewLine 71 | if ($Amount -lt 1) { 72 | return $sourceText 73 | } 74 | 75 | $indentText = $Indent * $Amount 76 | # Preserve new line characters. Only works if not sent a stream. 77 | $newLine = [regex]::Match($sourceText, '\r?\n').Value 78 | $asLines = $sourceText -split '\r?\n' 79 | $first = $true 80 | $indentedLines = foreach ($line in $asLines) { 81 | if ($first) { 82 | $first = $false 83 | if ($ExcludeFirstLine.IsPresent) { 84 | $line 85 | continue 86 | } 87 | } 88 | 89 | # Don't indent blank lines or here-string ending tags 90 | $shouldNotIndent = [string]::IsNullOrWhiteSpace($line) -or 91 | $line.StartsWith("'@") -or 92 | $line.StartsWith('"@') 93 | if ($shouldNotIndent) { 94 | $line 95 | continue 96 | } 97 | 98 | $indentText + $line 99 | } 100 | 101 | return $indentedLines -join $newLine 102 | } 103 | } -------------------------------------------------------------------------------- /Images/Demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gerane/VSCodePresentations/e1c86afc4ad0ae63f6beeb03c71490c30a4ab157/Images/Demo.gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Brandon Padgett 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /PowerShellEditors.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gerane/VSCodePresentations/e1c86afc4ad0ae63f6beeb03c71490c30a4ab157/PowerShellEditors.pptx -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | ## VSCode Presentations 2 | 3 | Many of us in the community want people to migrate away from PowerShell ISE and start using VSCode as their primary editor. There is one problem, many still use ISE for their Demos and Preentations. 4 | 5 | I think back to when I was new to PowerShell. I remember seeing a presentation by [Dave Wyatt](https://twitter.com/MSH_Dave), and he was using [ISESteroids](http://www.powertheshell.com/isesteroids/). It blew me away and I had to have it. I immediately went out and got ISESteroids just simplay by seeing someone like Dave use some of it's advanced features. We need to set this example with VSCode if we want to spread adoption. 6 | 7 | ### VSCode Unique Features 8 | 9 | If I had seen Editor Commands when watching a Demo, I would have dropped what I was doing and gone and got VSCode, similar to how I reacted to ISESteroids. This has to be one of the most useful features that are being underutilized in the VSCode PowerShell Extension. When coupled with things like [Plaster Templates](https://github.com/PowerShell/Plaster) or pipeline tasks, it has become one of my most used tools that I am constantly using throughout the day. 10 | 11 | Editor Commands also can be embedded in modules. You can add a simple piece of code to check for the $PSEditor variable and then dot source your Editor Commands if the exist. You could also put these in your VSCode PowerShell Profile. This also could be used to make Demos and Presentations ditributable via PSGallery. 12 | 13 | ![Demo](https://raw.githubusercontent.com/gerane/VSCodePresentations/master/Images/Demo.gif) 14 | 15 | ### Access Editor Commands 16 | 17 | I set the Keyboard Shortcut **Show Additional Commands from PowerShell Modules** to **Alt+P**. 18 | 19 | ### Demo 1 20 | 21 | This example opens a PowerPoint in your Demo Folder. We often have a PowerPoint in our Demo, so why not open it with style 22 | 23 | ### Demo 2 24 | 25 | This is a simple example of opening a file in the Editor. I open the example psm1 module file to show an example of adding support to your modules. 26 | 27 | ### Demo 3 28 | 29 | This Demo opens the Helpers.ps1 file to show the helper commands for taking input or prompting for choice. When [David Wilson](https://twitter.com/daviwil) released the integrated console support, it broke Editor Commands ability to tie into the Command Palette. Luckily, [Patrick Meinecke](https://twitter.com/SeeminglyScienc) came up with a work around a while back and got it working (You are awesome man!). 30 | 31 | ### Demo 4 32 | 33 | This is just a quick example of using the **Open-EditorFile** to open a file in the Editor. 34 | 35 | ### Demo 5 36 | 37 | This shows how you can use the Helper Commands to prompt for choice. It gives you a selection of your PowerShell Profiles and will open the one you select using the **$PSEditor.Workspace.OpenFile()** Method. 38 | 39 | ### Demo 6 40 | 41 | This is another simple example showing how you can run commands and have the output go to the terminal. 42 | 43 | ## Notes 44 | 45 | I have also been throwing around the idea of making a Plaster Template for VSCode Presentations. There are several ways you could do this, and I would need to play around with it some. I would love some feedback on this, or maybe this could be something the community could work on together. -------------------------------------------------------------------------------- /VSCodePresentations.ps1: -------------------------------------------------------------------------------- 1 | Import-Module .\*.psm1 -------------------------------------------------------------------------------- /VSCodePresentations.psm1: -------------------------------------------------------------------------------- 1 | if ($psEditor) 2 | { 3 | Get-ChildItem $PSScriptRoot\EditorCommands\*.ps1 | Sort-Object -Property name | ForEach-Object { . $_.FullName } 4 | } --------------------------------------------------------------------------------