Theme.PSReadLine.psm1

using namespace System.Collections.Generic
using namespace System.Management.Automation.Language
#Region '.\Private\ConvertToCssColor.ps1' 0
#using namespace System.Collections.Generic

function ConvertToCssColor {
    [CmdletBinding()]
    param(
        [Parameter(ParameterSetName="PListColorDictionary", Mandatory, Position = 0)]
        [Dictionary[string,object]]$colors,

        [Parameter(ParameterSetName="ColorValue", Mandatory, Position = 0)]
        [string]$color,

        [switch]$Background
    )
    end {
        if ($PSCmdlet.ParameterSetName -eq "PListColorDictionary") {
            [int]$r = 255 * $colors["Red Component"]
            [int]$g = 255 * $colors["Green Component"]
            [int]$b = 255 * $colors["Blue Component"]
            [PoshCode.Pansies.RgbColor]::new($r, $g, $b).ToVtEscapeSequence($Background)
        }
        if ($PSCmdlet.ParameterSetName -eq "ColorValue") {
            $color = $color -replace '^#[0-9a-f]{2}([0-9a-f]{6})$', '#$1'
            [PoshCode.Pansies.RgbColor]::new($color).ToVtEscapeSequence($Background)
        }
    }
}
#EndRegion '.\Private\ConvertToCssColor.ps1' 27
#Region '.\Private\FindVSCodeTheme.ps1' 0
function FindVsCodeTheme {
    [CmdletBinding(DefaultParameterSetName = "Specific")]
    param(
        [Parameter(ParameterSetName = "List")]
        [Parameter(ParameterSetName = "Specific", Mandatory, Position = 0)]
        [string]$Name,

        [Parameter(ParameterSetName = "List", Mandatory)]
        [switch]$List
    )

    $VSCodeExtensions = @(
        # VS Code themes are in one of two places: in the app, or in your profile folder:
        Convert-Path "~\.vscode*\extensions\"
        # If `code` is in your path, we can guess where that is...
        Get-Command Code-Insiders, Code -ErrorAction Ignore |
            Split-Path | Split-Path | Join-Path -ChildPath "resources\app\extensions\"
    )
    $Warnings = @()

    $Themes = @(
        # If they passed a file path that exists, use just that one file
        if (-not $List -and ($Specific = Test-Path -LiteralPath $Name)) {
            $File = Convert-Path $Name
            $(
                if ($File.EndsWith(".json")) {
                    try {
                        # Write-Debug "Parsing json file: $File"
                        ConvertFrom-Json (Get-Content -Path $File -Raw -Encoding utf8) -ErrorAction SilentlyContinue
                    } catch {
                        Write-Error "Couldn't parse '$File'. $(
                        if($PSVersionTable.PSVersion.Major -lt 6) {
                            'You could try again with PowerShell Core, the JSON parser there works much better!'
                        })"

                    }
                } else {
                    # Write-Debug "Parsing PList file: $File"
                    Import-PList -Path $File
                }
            ) | Select-Object @{ Name = "Name"
                                 Expr = {
                                    if ($_.name) {
                                        $_.name
                                    } else {
                                        [IO.Path]::GetFileNameWithoutExtension($File)
                                    }
                                }
                           }, @{ Name = "Path"
                                 Expr = {$File}
                           }
        } else {
            $VSCodeExtensions  = $VSCodeExtensions | Join-Path -ChildPath "\*\package.json" -Resolve
            foreach ($File in $VSCodeExtensions) {
                Write-Debug "Considering VSCode Extention $([IO.Path]::GetFileName([IO.Path]::GetDirectoryName($File)))"
                $JSON = Get-Content -Path $File -Raw -Encoding utf8
                try {
                    $Extension = ConvertFrom-Json $JSON -ErrorAction Stop
                    # if ($Extension.contributes.themes) {
                    # Write-Debug "Found $($Extension.contributes.themes.Count) themes"
                    # }
                    $Extension.contributes.themes |
                        Select-Object @{Name="Name" ; Expr={$_.label}},
                                      @{Name="Style"; Expr={$_.uiTheme}},
                                      @{Name="Path" ; Expr={Join-Path (Split-Path $File) $_.path -resolve}}
                } catch {
                    $Warning = "Couldn't parse some VSCode extensions."
                }
            }
        }
    )

    if ($Themes.Count -eq 0) {
        throw "Could not find any VSCode themes. Please use a full path."
    }

    if ($Specific -and $Themes.Count -eq 1) {
        $Themes
    }

    $Themes = $Themes | Sort-Object Name

    if ($List) {
        Write-Verbose "Found $($Themes.Count) Themes"
        $Themes
        return
    }

    # Make sure we're comparing the name to a name
    $Name = [IO.Path]::GetFileName(($Name -replace "\.json$|\.tmtheme$"))
    Write-Debug "Testing theme names for '$Name'"

    # increasingly fuzzy search: (eq -> like -> match)
    if (!($Theme = $Themes.Where{$_.name -eq $Name})) {
        if (!($Theme = $Themes.Where{$_.name -like $Name})) {
            if (!($Theme = $Themes.Where{$_.name -like "*$Name*"})) {
                foreach($Warning in $Warnings) {
                    Write-Warning $Warning
                }
                Write-Error "Couldn't find the theme '$Name', please try another: $(($Themes.name | Select-Object -Unique) -join ', ')"
            }
        }
    }
    if (@($Theme).Count -gt 1) {
        $Dupes = $(if (@($Theme.Name | Sort-Object -Unique).Count -gt 1) {$Theme.Name} else {$Theme.Path}) -join ", "
        Write-Warning "Found more than one theme for '$Name'. Using '$(@($Theme)[0].Path)', but you could try again for one of: $Dupes)"
    }

    @($Theme)[0]
}
#EndRegion '.\Private\FindVSCodeTheme.ps1' 110
#Region '.\Private\GetColorProperty.ps1' 0
function GetColorProperty{
    <#
        .SYNOPSIS
            Search the colors for a matching theme color name and returns the foreground
    #>

    param(
        # The array of colors
        [Array]$colors,

        # An array of (partial) scope names in priority order
        # The foreground color of the first matching scope in the tokens will be returned
        [string[]]$name,

        [switch]$background
    )
    # Since we loaded the themes in order of prescedence, we take the first match that has a foreground color
    foreach ($pattern in $name) {
        if ($foreground = @($colors.$pattern).Where{ $_ }[0]) {
            if ($pattern -match "Background(Color)?") {
                $background = $true
            }
            ConvertToCssColor $foreground -Background:$background
            return
        }
        if ($key, $property = $pattern -split "\.") {
            if ($foreground = @($colors.$key.$property).Where{ $_ }[0]) {
                if ($property -match "Background(Color)?") {
                    $background = $true
                }
                ConvertToCssColor $foreground -Background:$background
                return
            }
        }
        # Normalize color
    }
}
#EndRegion '.\Private\GetColorProperty.ps1' 37
#Region '.\Private\GetColorScopeForeground.ps1' 0
function GetColorScopeForeground {
    <#
        .SYNOPSIS
            Search the tokens for a scope name with a foreground color
    #>

    param(
        # The array of tokens
        [Array]$tokens,

        # An array of (partial) scope names in priority order
        # The foreground color of the first matching scope in the tokens will be returned
        [string[]]$name
    )
    # Since we loaded the themes in order of prescedence, we take the first match that has a foreground color
    foreach ($pattern in $name) {
        foreach ($token in $tokens) {
            if (($token.scope -split "\s*,\s*" -match $pattern) -and $token.settings.foreground) {
                ConvertToCssColor $token.settings.foreground
                return
            }
        }
    }
}
#EndRegion '.\Private\GetColorScopeForeground.ps1' 24
#Region '.\Private\ImportJsonIncludeLast.ps1' 0
function ImportJsonIncludeLast {
    <#
        .SYNOPSIS
            Import VSCode json themes, including any included themes
    #>

    [CmdletBinding()]
    param([string[]]$Path)

    # take the first
    $themeFile, $Path = $Path
    $theme = Get-Content $themeFile | ConvertFrom-Json

    # Output all the colors or token colors
    if ($theme.colors) {
        $theme.colors
    }
    if ($theme.tokenColors) {
        $theme.tokenColors
    }

    # Recurse includes
    if ($theme.include) {
        $Path += $themeFile | Split-Path | Join-Path -Child $theme.include | convert-path
    }
    if ($Path) {
        ImportJsonIncludeLast $Path
    }
}
#EndRegion '.\Private\ImportJsonIncludeLast.ps1' 29
#Region '.\Private\WriteToken.ps1' 0
function WriteToken {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Language.Token]
        $Token,

        [Parameter(Mandatory)]
        [Text.StringBuilder]
        $StringBuilder,

        $Theme
    )
    $null = switch ($token) {
        { $_ -is [StringExpandableToken] } {
            $startingOffset = $_.Extent.StartOffset
            $lastEndOffset = $startingOffset
            foreach ($nestedToken in $_.NestedTokens) {
                $StringBuilder.Append($Theme.StringColor)
                $StringBuilder.Append($_.Text, $lastEndOffset - $startingOffset, $nestedToken.Extent.StartOffset - $lastEndOffset)

                WriteToken -Token $nestedToken -StringBuilder $StringBuilder -Theme $Theme
                $lastEndOffset = $nestedToken.Extent.EndOffset
            }
            $StringBuilder.Append($Theme.StringColor)
            $StringBuilder.Append($_.Text, $lastEndOffset - $startingOffset, $_.Extent.EndOffset - $lastEndOffset)
            return
        }
        { $_ -is [StringToken] } {
            if ($_.TokenFlags.HasFlag([TokenFlags]::CommandName)) {
                $StringBuilder.Append($Theme.CommandColor)
                break
            }
            $StringBuilder.Append($Theme.StringColor)
            break
        }
        { $_ -is [NumberToken] } { $StringBuilder.Append($Theme.NumberColor); break }
        { $_ -is [ParameterToken] } { $StringBuilder.Append($Theme.ParameterColor); break }
        { $_ -is [VariableToken] } { $StringBuilder.Append($Theme.VariableColor); break }
        { $_.TokenFlags.HasFlag([TokenFlags]::BinaryOperator) } { $StringBuilder.Append($Theme.OperatorColor); break }
        { $_.TokenFlags.HasFlag([TokenFlags]::UnaryOperator) } { $StringBuilder.Append($Theme.OperatorColor); break }
        { $_.TokenFlags.HasFlag([TokenFlags]::CommandName) } { $StringBuilder.Append($Theme.CommandColor); break; }
        { $_.TokenFlags.HasFlag([TokenFlags]::MemberName) } { $StringBuilder.Append($Theme.MemberColor); break; }
        { $_.TokenFlags.HasFlag([TokenFlags]::TypeName) } { $StringBuilder.Append($Theme.TypeColor); break; }
        { $_.TokenFlags.HasFlag([TokenFlags]::Keyword) } { $StringBuilder.Append($Theme.KeywordColor); break; }
        { $_ -is [StringToken] } { $StringBuilder.Append($Theme.StringColor); break }
        default { $StringBuilder.Append($Theme.DefaultTokenColor); break }
    }
    $null = $StringBuilder.Append($token.Text)
}
#EndRegion '.\Private\WriteToken.ps1' 51
#Region '.\Public\Get-PSReadLineTheme.ps1' 0
function Get-PSReadLineTheme {
    <#
        .SYNOPSIS
            Returns a hashtable of the _current_ values that can be splatted to Set-Theme
    #>

    [CmdletBinding()]
    param()
    Get-PSReadLineOption | Select-Object *Color
}
#EndRegion '.\Public\Get-PSReadLineTheme.ps1' 10
#Region '.\Public\Get-VSCodeTheme.ps1' 0
function Get-VSCodeTheme {
    <#
        .SYNOPSIS
            Get a PSReadLine theme from a VS Code Theme that you have installed locally.
        .DESCRIPTION
            Gets PSReadLine colors from a Visual Studio Code Theme. Only works with locally installed Themes, but includes tab-completion for theme names so you can Ctrl+Space to list the ones you have available.
 
            The default output will show a little preview of what PSReadLine will look like. Note that the PSReadLine theme will _not_ set the background color.
 
            You can pipe the output to Set-PSReadLineTheme to import the theme for the PSReadLine module.
 
            Note that you may want to use -Verbose to see details of the import. In some cases, Get-VSCodeTheme will not be able to determine values for all PSReadLine colors, and there is a verbose output showing the colors that get the default value.
        .Example
            Get-VSCodeTheme 'Light+ (default light)'
 
            Gets the default "Dark+" theme from Code and shows you a preview. Note that to use this theme effectively, you need to have your terminal background color set to a light color like the white in the preview.
        .Example
            Get-VSCodeTheme 'Dark+ (default dark)' | Set-PSReadLineTheme
 
            Imports the "Dark+" theme from Code and sets it as your PSReadLine color theme.
        .Link
            Set-PSReadLineTheme
            Get-PSReadLineTheme
    #>

    [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = "ByName")]
    param(
        # The name of (or full path to) a vscode json theme which you have installed
        # E.g. 'Dark+' or 'Monokai'
        [ArgumentCompleter({
            param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
            Get-VSCodeTheme -List | ForEach-Object {
                if ($_.Name -match "[\s'`"]") {
                    "'{0}'" -f ($_.Name -replace "'", "''")
                } else {
                    $_.Name
                }
            } | Where-Object { $_.StartsWith($wordToComplete) }
        })]
        [Alias("PSPath", "Name")]
        [Parameter(ParameterSetName = "ByName", ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0)]
        [string]$Theme,

        # List the VSCode themes available
        [Parameter(ParameterSetName = "ListOnly", Mandatory)]
        [switch]$List
    )
    process {
        if ($List) {
            FindVsCodeTheme -List
            return
        } else {
            $VsCodeTheme = FindVsCodeTheme $Theme -ErrorAction Stop
        }

        if ($PSCmdlet.ShouldProcess($VsCodeTheme.Path, "Import PSReadLine colors from theme")) {
            # Load the theme file and split the output into colors and tokencolors
            if ($VsCodeTheme.Path.endswith(".json")) {
                $colors, $tokens = (ImportJsonIncludeLast $VsCodeTheme.Path).Where({!$_.scope}, 'Split', 2)
            } else {
                $colors, $tokens = (Import-PList $VsCodeTheme.Path).settings.Where({!$_.scope}, 'Split', 2)
                $colors = $colors.settings
            }

            $ThemeOutput = [Ordered]@{
                PSTypeName = 'Selected.Microsoft.PowerShell.PSConsoleReadLineOptions'
                # These should come from the base colors, rather than token scopes
                BackgroundColor         = GetColorProperty $colors 'editor.background', 'background', 'settings.background', 'terminal.background'
                DefaultTokenColor       = GetColorProperty $colors 'editor.foreground', 'foreground', 'settings.foreground', 'terminal.foreground'
                SelectionColor          = GetColorProperty $colors 'editor.selectionBackground', 'editor.selectionHighlightBackground', 'selection' -Background
                ErrorColor              = @(@(GetColorProperty $colors 'errorForeground', 'editorError.foreground') + @(GetColorScopeForeground $tokens 'invalid'))[0]
                # The rest of these come from token scopes
                CommandColor            = GetColorScopeForeground $tokens 'support.function'
                CommentColor            = GetColorScopeForeground $tokens 'comment'
                ContinuationPromptColor = GetColorScopeForeground $tokens 'constant.character'
                EmphasisColor           = GetColorScopeForeground $tokens 'markup.bold', 'markup.italic', 'emphasis', 'strong', 'constant.other.color', 'markup.heading'
                InlinePredictionColor   = GetColorScopeForeground $tokens 'markup.underline',
                KeywordColor            = GetColorScopeForeground $tokens '^keyword.control$', '^keyword$', 'keyword.control', 'keyword'
                MemberColor             = GetColorScopeForeground $tokens 'variable.other.object.property', 'member', 'type.property', 'support.function.any-method', 'entity.name.function'
                NumberColor             = GetColorScopeForeground $tokens 'constant.numeric', 'constant'
                OperatorColor           = GetColorScopeForeground $tokens 'keyword.operator$', 'keyword'
                ParameterColor          = GetColorScopeForeground $tokens 'parameter'
                StringColor             = GetColorScopeForeground $tokens '^string$'
                TypeColor               = GetColorScopeForeground $tokens '^storage.type$', '^support.class$', '^entity.name.type.class$', '^entity.name.type$'
                VariableColor           = GetColorScopeForeground $tokens '^variable$', '^entity.name.variable$', '^variable.other$'
            }

            <# ###### We *COULD* map some colors to other themable modules #####
            # If the VSCode Theme has terminal colors, and you had Theme.Terminal or Theme.WindowsTerminal or Theme.WindowsConsole
            if ($colors.'terminal.ansiBrightYellow') {
                Write-Verbose "Exporting Theme.Terminal"
                $ThemeOutput['Theme.Terminal'] = @(
                        GetColorProperty $colors "terminal.ansiBlack"
                        GetColorProperty $colors "terminal.ansiRed"
                        GetColorProperty $colors "terminal.ansiGreen"
                        GetColorProperty $colors "terminal.ansiYellow"
                        GetColorProperty $colors "terminal.ansiBlue"
                        GetColorProperty $colors "terminal.ansiMagenta"
                        GetColorProperty $colors "terminal.ansiCyan"
                        GetColorProperty $colors "terminal.ansiWhite"
                        GetColorProperty $colors "terminal.ansiBrightBlack"
                        GetColorProperty $colors "terminal.ansiBrightRed"
                        GetColorProperty $colors "terminal.ansiBrightGreen"
                        GetColorProperty $colors "terminal.ansiBrightYellow"
                        GetColorProperty $colors "terminal.ansiBrightBlue"
                        GetColorProperty $colors "terminal.ansiBrightMagenta"
                        GetColorProperty $colors "terminal.ansiBrightCyan"
                        GetColorProperty $colors "terminal.ansiBrightWhite"
                    )
                if ($colors."terminal.background") {
                    $ThemeOutput['Theme.Terminal']['background'] = GetColorProperty $colors "terminal.background"
                }
                if ($colors."terminal.foreground") {
                    $ThemeOutput['Theme.Terminal']['foreground'] = GetColorProperty $colors "terminal.foreground"
                }
            }
 
            # If the VSCode Theme has warning/info colors, and you had Theme.PowerShell
            if (GetColorProperty $colors 'editorWarning.foreground') {
                $ThemeOutput['Theme.PowerShell'] = @{
                    WarningForegroundColor = GetColorProperty $colors 'editorWarning.foreground'
                    ErrorForegroundColor = GetColorProperty $Colors 'editorError.foreground'
                    VerboseForegroundColor = GetColorProperty $Colors 'editorInfo.foreground'
                    ProgressForegroundColor = GetColorProperty $Colors 'notifications.foreground'
                    ProgressBackgroundColor = GetColorProperty $Colors 'notifications.background'
                }
            } #>


            if ($DebugPreference -in "Continue", "Inquire") {
                $global:colors = $colors
                $global:tokens = $tokens
                $global:Theme = $ThemeOutput
                ${function:global:Get-VSColorScope} = ${function:GetColorScopeForeground}
                ${function:global:Get-VSColor} = ${function:GetColorProperty}
                Write-Debug "For debugging, `$Theme, `$Colors, `$Tokens were copied to global variables, and Get-VSColor and Get-VSColorScope exported."
            }

            if ($ThemeOutput.Values -contains $null) {
                [string[]]$missing = @()
                foreach ($kv in @($ThemeOutput.GetEnumerator())) {
                    if ($null -eq $kv.Value) {
                        $missing += $kv.Key
                        $ThemeOutput[$kv.Key] = $ThemeOutput["DefaultToken"]
                    }
                }
                Write-Verbose "Used DefaultTokenColor for some colors: $($missing -join ', ')"
            }

            [PSCustomObject]$ThemeOutput
        }
    }
}
#EndRegion '.\Public\Get-VSCodeTheme.ps1' 152
#Region '.\Public\Set-PSReadLineTheme.ps1' 0
function Set-PSReadLineTheme {
    <#
        .SYNOPSIS
            Set the theme for PSReadLine
            Has parameters for each thing that's themeable
    #>

    [CmdletBinding()]
    param(
        [Parameter(ValueFromPipelineByPropertyName)]
        $CommandColor            = "$([char]27)[93m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $CommentColor            = "$([char]27)[32m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $ContinuationPromptColor = "$([char]27)[97m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $DefaultTokenColor       = "$([char]27)[97m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $EmphasisColor           = "$([char]27)[96m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $ErrorColor              = "$([char]27)[91m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $KeywordColor            = "$([char]27)[92m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $MemberColor             = "$([char]27)[97m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $NumberColor             = "$([char]27)[97m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $OperatorColor           = "$([char]27)[90m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $ParameterColor          = "$([char]27)[90m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $InlinePredictionColor   = "$([char]27)[90m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $SelectionColor          = "$([char]27)[30;107m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $StringColor             = "$([char]27)[36m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $TypeColor               = "$([char]27)[37m",
        [Parameter(ValueFromPipelineByPropertyName)]
        $VariableColor           = "$([char]27)[92m"
    )
    process {
        $ParameterNames = $MyInvocation.MyCommand.Parameters.Keys.Where{
             $_ -notin [System.Management.Automation.PSCmdlet]::CommonParameters
        }

        $Colors = @{}
        foreach ($ParameterName in $ParameterNames) {
            if (($Value = Get-Variable -Scope Local -Name $ParameterName -ValueOnly)) {
                $ColorName = $ParameterName -replace "(token)?color"
                # This is only working when I use the AsEscapeSequence, but the input values are already escape sequences!
                $Colors[$ColorName] = [Microsoft.PowerShell.VTColorUtils]::AsEscapeSequence( $Value )
            }
        }
        Set-PSReadLineOption -Colors $Colors
    }
}
#EndRegion '.\Public\Set-PSReadLineTheme.ps1' 58
#Region '.\Public\Show-Code.ps1' 0
#using namespace System.Management.Automation.Language
function Show-Code {
    [CmdletBinding(DefaultParameterSetName = 'HistoryId')]
    param(
        # A script block or a path to a script file
        [Parameter(Mandatory, ParameterSetName = 'Script', Position = 0)]
        [string]$Script,

        # The history id of the script to show
        [Parameter(Mandatory, ParameterSetName = 'History', Position = 0)]
        [int]$HistoryId,

        # The PSReadLine theme to use. If not specified, the current theme is used.
        # Can be the output of Get-VSCodeTheme or Get-PSReadLineTheme
        $Theme = (Get-PSReadLineTheme)
    )
    if ($HistoryId) {
        $Script = (Get-History -Id $HistoryId).CommandLine
    }

    $ParseErrors = $null
    $Tokens = $null
    $null = if (Test-Path "$Script" -ErrorAction SilentlyContinue) {
        [System.Management.Automation.Language.Parser]::ParseFile((Convert-Path $Script), [ref]$Tokens, [ref]$ParseErrors)
    } else {
        [System.Management.Automation.Language.Parser]::ParseInput([String]$Script, [ref]$Tokens, [ref]$ParseErrors)
    }

    $lastEndOffset = 0
    $StringBuilder = [Text.StringBuilder]::new()

    foreach ($token in $tokens) {
        $null = $StringBuilder.Append([char]' ', ($token.Extent.StartOffset - $lastEndOffset))
        $lastEndOffset = $token.Extent.EndOffset
        $null = WriteToken -Token $token -StringBuilder $StringBuilder -Theme $Theme
    }
    # Reset the colors
    $null = $StringBuilder.Append("$([char]0x1b)[0m$([char]0x1b)[24m$([char]0x1b)[27m")
    $StringBuilder.ToString()
}
#EndRegion '.\Public\Show-Code.ps1' 41
#Region '.\Public\test.ps1' 0
#EndRegion '.\Public\test.ps1' 1
#Region '.\postfix.ps1' 0
if (Get-Module EzTheme -ErrorAction SilentlyContinue) {
    Get-ModuleTheme | Set-PSReadLineTheme
}
#EndRegion '.\postfix.ps1' 4