powershellcolorspsreadline

How to use ANSI escape sequence color codes for PSReadLineOption v2 in Powershell console?


I'm trying to use the built-in PSReadLine (v2) module of Powershell (v5.1) to customize Powershell console text colors.

Previous versions of PSReadLine allowed you to simply specify -Background and -Foreground parameters for any given token type. But that is no longer the case. PSReadLine v2 introduced the use of ANSI escape codes to define color behavior. I gather that this allows for much greater flexibility, but it's extremely complicated for what it's meant to accomplish. Documentation about these codes is all over the place, and highly dependent on the implementation of the host application, which makes it that much harder to find answers.

Simply coloring text foreground is (relatively) easy with something like:

set-psreadlineoption -colors @{
    CommandColor = "`e[93m"
    CommentColor = "`e[32m"
}

However things get more complicated if you want to introduce decoration, such as bold, underline, or of particular interest to me, background color and combinations of these.

The default value for SelectionColor (which highlights selected text with a different background color) is`e[35;43m. But that big hint is still not enough to betray the syntactical secrets I'm searching for.

The doc for Set-PSReadLineOption very matter-of-factly states:

You can specify other escape sequences including:
256 color
24-bit color
Foreground, background, or both
Inverse, bold

... but provides no examples.

How would you go about specifying an escape code that defines both foreground and background color, or any other combination of colors and colored decorations?

Sources I've found helpful in learning about these escape codes are: http://jafrog.com/2013/11/23/colors-in-terminal.html https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters

But I've not been able to fully wrap my head around any of this.

Solved:

Thanks to @LotPings. I was mistakenly assuming that escape codes could only have a set number of options given to them. In truth, I can specify as many as I want (or as many as I need to accomplish my goals). So for example:

$e = [char]0x1b
"$e[38;2;255;128;128;48;2;128;0;255;4mtest$e[0m"

... will result in the word test, which is underlined with a pink foreground and purple background. To break it down:

enter image description here


Solution

  • The code from Jafrog's blog translated to PowerShell

    ## Q:\Test\2019\06\20\SO_56679782.ps1
    
    Get-PSReadLineOption
    
    $Esc=[char]0x1b 
    
    'The following command should print “hello” in bright red underscore text:'
    "$Esc[91;4mHello$Esc[0m"
    
    ForEach($code in 30..37){
    "{0}[{1}mEsc[{1}m{0}[0m  {0}[{1};1mEsc[{1};1m{0}[0m  {0}[{1};3mEsc[{1};3m{0}[0m  {0}[{1};4mEsc[{1};4m{0}[0m  {0}[{2}mEsc[{2}m{0}[0m" -f $Esc,$code,($code+60)
    }
    pause
    foreach($code in 0..255){"{0}[38;5;{1}mESC[38;5;{1}m{0}[0m" -f $Esc,$code}
    

    enter image description here

    Ansi Esc[ sequence (CSI)
                  Foreground     Background
    No Color     normal bright  normal bright
    0  black       30     90      40    100
    1  red         31     91      41    101
    2  green       32     92      42    102
    3  yellow      33     93      43    103
    4  blue        34     94      44    104
    5  violet      35     95      45    105
    6  turqoise    36     96      46    106
    7  grey        37     97      47    107
    

    enter image description here