1

trying to array slice the get-psreadlineoption command. I want to select all strings containing the word 'Color' and then input those to 'set-psreadline' to set all colors. I do not understand how this all works in powershell. It's an array, right? I can just loop over it like this:

foreach($a in $i) { $i; if ($i -contains 'MemberColor') {$i;} }

But that gives no output. I also cannot access it as an array:

get-psreadlineoption[21..36] get-psreadlineoption['EditMode']

Does not work. Basically what I want to do is:

foreach (get-psreadlines[21..36]) { $array = append(<string that contains 'Color'>) } foreach ($a in $array) { set-psreadline($a, ...)}

How would I go about doing this?

(P.S. I just want to set all those colors to the same color in a concise manner as possible)

Athylus
  • 193
  • 1
  • 1
  • 10

2 Answers2

2

The solution depends on what version of the PSReadLine module you're using:

  • PSReadline v2.x, which ships with PowerShell (Core) 7+.
  • PSReadline v1.x, which Windows PowerShell versions ship with in Windows 10+ / Windows Sever 2016+, although it is possible to install 2.x on demand in Windows PowerShell 5.0 and 5.1 (Install-Module PSReadLine)

Use (Get-Module PSReadLine).Version.ToString() to see which version you're using.


PSReadline v2.x solution:

To get the names of all color properties, via filtering the names by those ending in color (case-insensitively), use reflection, which PowerShell facilitates via the intrinsic .psobject property:

(Get-PSReadLineOption).psobject.Properties.Name -like '*color'

Note:

  • A quick way to print all property names of interest, including their values, is to use
    Get-PSReadLineOption | Select-Object *color. However, the result is a [pscustomobject], not a hashtable, and in order to convert the former to the latter you'd again need the same technique shown below.

  • However, as an alternative to setting colors via Set-PSReadLineOption (as shown below), you may also use the approach described for PSReadLine v1.x in the bottom section (e.g., (Get-PSReadlineOption).CommentColor = 'DarkGray'), in which case you can use the property names shown in the output from Get-PSReadLineOption | Select-Object *color as-is. Note that the property names differ between v2.x and v1.x; also, as with Set-PSReadLineOption -Colors below, setting background colors requires the use of VT escape sequences.

Caveat: These property names require a transformation in order to be usable as the keys of the hashtable you can pass to Set-PSReadLineOption -Colors (as of PSReadLine 2.1.0):

The suffix Color must be removed, and in the case of DefaultTokenColor, the suffix TokenColor, which the following -replace operation does:

(Get-PSReadLineOption).psobject.Properties.Name -like '*color' `
                                                -replace '(Token)?Color$'

This yields the following color key names (as of PSReadLine 2.1.0):

ContinuationPrompt
Default
Comment
Keyword
String
Operator
Variable
Command
Parameter
Type
Number
Member
Emphasis
Error
Selection
InlinePrediction

You can now pass a hashtable that selectively updates colors; e.g. the following sets the Comment (CommentColor) color to dark gray (while leaving all other colors untouched):

Set-PSReadLineOption -Color @{ Comment = 'DarkGray' }

A color value can either be:

  • One of the values of the [ConsoleColor] enumeration type; e.g. [ConsoleColor]::DarkGray, which you may pass as string 'DarkGray', as shown above.

  • A VT (Virtual Terminal) / ANSI escape sequence. Note that use of such sequences is a must if you want to set the background color for a given setting; e.g., the following sets the comment color to dark gray (90) on a white background (47)

    Set-PSReadLineOption -Color @{ Comment = "`e[90;47m" }
    

To create a hashtable comprising all color keys, using the current property values as a starting point, use the following:

$allColors = @{}
(Get-PSReadLineOption).psobject.Properties.
  Where({ $_.Name -like '*color' }).
  ForEach({ $allColors[$_.Name -replace '(Token)?Color$'] = $_.Value })

Note: When you print $allColors, the Value column may appear to be empty, but the values are there, in the form of - themselves invisible - Virtual Terminal (VT) control sequences.


PSReadline v1.x solution (older versions of Windows PowerShell):

Unlike the v2.x version:

  • Set-PSReadlineOption in v1.x uses the combination of the -TokenKind and -ForegroundColor / -BackgroundColor parameters for the various colors and also, for general color settings, individual parameters (e.g. -ErrorForegroundColor) (rather than the single v2.x -Colors parameter that accepts a hashtable); also, all color settings are split into foreground and background values.

  • The color values are limited to the values of the [ConsoleColor] enumeration type, such as 'DarkGray' ([ConsoleColor]::DarkGray)

For a unified approach to setting colors, you may forgo Set-PSReadLineOption and directly set the properties of the Microsoft.PowerShell.PSConsoleReadLineOptions instance that Get-PSReadLineOption returns.

For instance, the following sets the foreground color of comments to dark gray:

(Get-PSReadlineOption).CommentForegroundColor = 'DarkGray'

This is the equivalent of the following v1.x Set-PSReadLineOption call:

Set-PSReadLineOption -TokenKind Comment -ForegroundColor DarkGray

To get the names of all color-relevant properties, use the same approach as for v2.x:

(Get-PSReadLineOption).psobject.Properties.Name -like '*color'

This yields the following color property names:

ContinuationPromptForegroundColor
ContinuationPromptBackgroundColor
DefaultTokenForegroundColor
CommentForegroundColor
KeywordForegroundColor
StringForegroundColor
OperatorForegroundColor
VariableForegroundColor
CommandForegroundColor
ParameterForegroundColor
TypeForegroundColor
NumberForegroundColor
MemberForegroundColor
DefaultTokenBackgroundColor
CommentBackgroundColor
KeywordBackgroundColor
StringBackgroundColor
OperatorBackgroundColor
VariableBackgroundColor
CommandBackgroundColor
ParameterBackgroundColor
TypeBackgroundColor
NumberBackgroundColor
MemberBackgroundColor
EmphasisForegroundColor
EmphasisBackgroundColor
ErrorForegroundColor
ErrorBackgroundColor
mklement0
  • 382,024
  • 64
  • 607
  • 775
1

This is sort of a common question, how to loop through properties Iterate over PSObject properties in PowerShell. You can also use get-member to get the property list. You can also pipe to "select *color".

Get-PSReadLineOption | get-member *color | % name

CommandColor
CommentColor
ContinuationPromptColor
DefaultTokenColor
EmphasisColor
ErrorColor
KeywordColor
MemberColor
NumberColor
OperatorColor
ParameterColor
PredictionColor
SelectionColor
StringColor
TypeColor
VariableColor
js2010
  • 23,033
  • 6
  • 64
  • 66