Visitar URL original
Add New-VtConsoleSequence, to provide embeddable strings and not require Pansies in distributable code · Issue #19 · PoshCode/Pansies · GitHub
Skip to content

Add New-VtConsoleSequence, to provide embeddable strings and not require Pansies in distributable code #19

Open

Description

@fsackur

Use case: my team has ~200 powershell modules deployed to an enterprise nuget source. Our dependency trees are a little cumbersome. We don't want to add any dependencies if we can avoid it.

We do use ANSI sequences, some of which I have generated with Pansies - ♥ - but I am currently doing some awkward manipulation to create strings which I can embed in our modules.

I would like to use a function New-VtConsoleSequence in development, to create those strings.

It would have a Reset switch in one parameterset, to output an ANSI reset; the other parameterset would accept any valid input to the ctor for RgbColor, e.g. ForestGreen1, ea0016.

I would also like a EscapeAsExpression switch, which would behave as follows:

> New-VtConsoleSequence ea0016 -EscapeAsExpression
$([char]27)[38;2;234;0;22m

> New-VtConsoleSequence -Reset -EscapeAsExpression
$([char]27)[39m

Then my module functions will have code like this:

$DeepSkyBlue = "$([char]27)[38;2;0;191;255m"
$Reset       = "$([char]27)[0m"
Write-Information "$DeepSkyBlue`Stuff possibly relating to other stuff.$Reset"

Activity

  1. fsackur commented on Apr 23, 2021

    @fsackur
    Author

    If we can get an acceptable req, I would PR it. I'd love to contribute.

  2. changed the title [-]Add New-VtConsoleSequence, to provide embeddable strings and not require Pansies in distirbutable code[/-] [+]Add New-VtConsoleSequence, to provide embeddable strings and not require Pansies in distributable code[/+] on Apr 23, 2021
  3. Jaykul commented on Jul 18, 2021

    @Jaykul
    Member

    All you have to do is run the output through -replace "`e",'`e' (or, for PowerShell 5 compatibility -replace "$([char]27)",'$([char]27)')

    (Text ${fg:Aquamarine}Hello) -replace "`e",'`e'
    [rgbColor]::Background("ea0016") -replace "`e",'`e'
    $fg:Tomato -replace "$([char]27)",'$([char]27)'

    Or even:

    (Get-Gradient Tomato Aquamarine -Length 10 | % ToVtEscapeSequence $false) -replace "$([char]27)",'$([char]27)'
  4. Jaykul commented on Jul 18, 2021

    @Jaykul
    Member

    Originally, none of that seemed like a good idea to me. When I started this, there were a lot of places (particularly Windows) where only a subset of colors were supported (e.g. 16 colors, or 256 colors), so one of the best features of PANSIES was the ability to set the mode to whatever your terminal supports. Nowadays that doesn't seem worth worrying about as much, and in many modules, I'd be willing to just hard-code RGB color sequences...

    I think it would definitely be interesting to write something that could be run on PowerShell files (.ps1 and .psm1 and .ps1xml format files) at "build" time to use the AST parser and replace references to the drives (i.e. ${fg:...} and ${bg:...}) with in-line escape sequences.

    In fact, with that in mind, I wouldn't mind adding a PSProvider drive for $emoji named escape sequences and $nf (nerdfonts) to make it easier to use those too. That would mean you could use "${fg:SkyBlue3}Hello${emoji:smile}${fg:Clear}" in your source code, but have it converted at build-time to a less readable version (optionally, with $([char]27) or ```e`` but -- for maximum speed by just embedding the actual escape sequences in the UTF8 files...

  5. Jaykul commented on Jul 15, 2023

    @Jaykul
    Member

    Just to update:

    I never did the drive provider for those others, but I did add them as entities that are handled by Pansies' New-Text and Write-Host commands, so you can for example:

    Write-Host "Hello&smilingfacewithtear;"
    Hello🥲

    I am leaving this open because I do still want to implement something to replace all those &entities; in a file with the actual characters, escape sequences or $([char]###) patterns for shipping

  6. ninmonkey commented on Nov 11, 2025

    @ninmonkey

    @Jaykul : I do still want to implement something to replace all those &entities; in a file with the actual characters, escape sequences or $([char]###) patterns for shipping

    Maybe I could implement this?

    Is the goal to

    • modify source ps1/psm1 files in-place, replacing &entities; substrings with inline expressions
    • inline $( [char]....) expressions are used rather than literals to be compatible with single byte encoded scripts and powershell.exe

    For Example

    '&zombie; needs &brain;' | Write-Host

    Which becomes

    "$( [char]::ConvertFromUtf32( 0x1f9df ) ) needs $( [char]::ConvertFromUtf32( 0x1f9e0 ) )" | Write-Host

    I used [string] Char::ConvertFromUtf32 because the codepoint like [char] 0x1f9df is out of range for many entities

    Alternative inline values

    I'm able to embed the entities as a inline literal string on PS5.1 if the file is encoded as utf8

    '🧟 needs 🧠' | Write-Host

    I think this version could fail even when using utf8 but with an older terminal or host like ISE?

    For cases where the target is pwsh

    # you could replace 
    "$( [char]::ConvertFromUtf32( 0x1f9df ) )..."
    
    # with
    "`u{1f9df}..."

    It's shorter, and still doesn't require non-ascii characters.

  7. Jaykul commented on Nov 12, 2025

    @Jaykul
    Member

    I think I did that already in the branch I'm working on --- I switched everything to drive syntax, and added an Expand-Variable cmdlet. I need to think about whether this meets the full original request for dev purposes or not.

  8. ninmonkey commented on Nov 12, 2025

    @ninmonkey

    @fsackur Are you looking to basically compose templates? Originally I was thinking you wanted to embed strings, so that pansies was not required.

    If you're composing colors/styles, it basically exists with New-Text. You might want some personal sugar that wraps it
    I tested this on PS5.1+

    # to view sequences
    filter ShowEscape { $_ -replace '\x1b', '`e' } 
    # for -EscapeAsExpression
    filter EscapeAsExpression { $_ -replace '\x1b', '$([char]27)' }
    
    $Reset     = "${fg:clear}${bg:clear}"
    $ResetFg = "${fg:clear}"

    Ex 1

    > New-VtConsoleSequence -Reset -EscapeAsExpression
    $([char]27)[39m

    That's equal to

    > "${fg:clear}" | ShowEscape
    # `e[39m

    Ex 2

    > New-VtConsoleSequence ea0016 -EscapeAsExpression
    $([char]27)[38;2;234;0;22m

    Is equal to

    > New-Text -fg '#ea0016' -Obj '' -LeaveColor | ShowEscape
    # `e[38;2;234;0;22m

    Ex 3

    $DeepSkyBlue = "$([char]27)[38;2;0;191;255m"
    $Reset       = "$([char]27)[0m"
    Write-Information "$DeepSkyBlue`Stuff possibly relating to other stuff.$Reset"

    Is equal to

    $DeepSkyBlue = New-Text -fg 'deepskyblue' -Object '' -LeaveColor
    $Reset       = "${fg:clear}${bg:clear}"
    $ResetFg     = "${fg:clear}"
    
    "${DeepSkyBlue}Stuff possibly relating to other stuff.${ResetFg}" | ShowEscape
    # `e[38;2;0;191;255mStuff possibly relating to other stuff.`e[39m

    Ex 4

    "${Reset}${bg:gray30}${fg:23aa99}hi ${fg:orange}world${ResetFg}!${Reset}"| EscapeAsExpression
    # output
    # $([char]27)[39m$([char]27)[49m$([char]27)[48;2;77;77;77m$([char]27)[38;2;35;170;153mhi $([char]27)[38;2;255;165;0mworld$([char]27)[39m!$([char]27)[39m$([char]27)[49m
    
    # At this point, you might want to use ${e} instead of inline $()
    $e = [char] 0x1b
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions