EditorServicesCommandSuite.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
Import-Module $PSScriptRoot/EditorServicesCommandSuite.dll
Import-Module $PSScriptRoot/EditorServicesCommandSuite.RefactorCmdlets.cdxml
Update-FormatData -AppendPath $PSScriptRoot/EditorServicesCommandSuite.format.ps1xml

if ($null -ne $psEditor) {
    if ($PSVersionTable.PSVersion.Major -ge 6) {
        $extensionService = [Microsoft.PowerShell.EditorServices.Extensions.EditorObjectExtensions, Microsoft.PowerShell.EditorServices]::
            GetExtensionServiceProvider($psEditor)

        $assembly = $extensionService.LoadAssemblyInPsesLoadContext((
            Join-Path $PSScriptRoot -ChildPath 'EditorServicesCommandSuite.EditorServices.dll'))

        $type = $assembly.GetType('EditorServicesCommandSuite.EditorServices.Internal.CommandSuite')
    } else {
        Add-Type -Path "$PSScriptRoot/EditorServicesCommandSuite.EditorServices.dll"
        $type = [EditorServicesCommandSuite.EditorServices.Internal.CommandSuite]
    }

    $CommandSuite = $type::GetCommandSuite(
        $psEditor,
        $ExecutionContext,
        $Host)
} else {
    Add-Type -Path "$PSScriptRoot/EditorServicesCommandSuite.PSReadLine.dll"
    $CommandSuite = [EditorServicesCommandSuite.PSReadLine.Internal.CommandSuite]::GetCommandSuite(
        $ExecutionContext,
        $Host)
}

function Import-CommandSuite {
    [CmdletBinding()]
    param()
    end {
        if ($null -eq $psEditor) {
            return
        }

        $registerEditorCommandSplat = @{
            Name        = 'Invoke-DocumentRefactor'
            DisplayName = 'Get Context Specific Refactor Options'
            # Use Ast.GetScriptBlock to strip SessionState affinity so PSCmdlet.SessionState
            # reflects the real caller.
            ScriptBlock = { Invoke-DocumentRefactor }.Ast.GetScriptBlock()
        }

        Register-EditorCommand @registerEditorCommandSplat

        $alreadyLoadedCommands = [System.Collections.Generic.HashSet[string]]::new()
        $psEditor.GetCommands() | ForEach-Object {
            $null = $alreadyLoadedCommands.Add($PSItem.Name)
        }

        Get-RefactorOption | ForEach-Object {
            if ($alreadyLoadedCommands.Contains($PSItem.Id)) {
                return
            }

            $registerEditorCommandSplat = @{
                Name        = $PSItem.Id
                DisplayName = $PSItem.DisplayName
                ScriptBlock = [scriptblock]::Create($PSItem.Id)
            }

            Register-EditorCommand @registerEditorCommandSplat
        }
    }
}

function Invoke-DocumentRefactor {
    [CmdletBinding()]
    param()
    end {
        try {
            $null = $CommandSuite.RequestRefactor($PSCmdlet).
                ConfigureAwait($false).
                GetAwaiter().
                GetResult()
        } catch [OperationCanceledException] {
            # Do nothing. This should only be when a menu selection is cancelled, which I'm
            # equating to ^C
            $null = $null
        } catch {
            $PSCmdlet.WriteError($PSItem)
        }
    }
}

New-Alias -Name Add-CommandToManifest -Value Register-CommandExport -Force

# Allow the user to opt out of automatic editor command registration on module import.
if (1 -ne $env:ESCS_REQUIRE_EXPLICIT_IMPORT) {
    Import-CommandSuite
}

# Export only the functions using PowerShell standard verb-noun naming.
# Be sure to list each exported functions in the FunctionsToExport field of the module manifest file.
# This improves performance of command discovery in PowerShell.
Export-ModuleMember -Function *-* -Cmdlet *-* -Alias Add-CommandToManifest