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)

3
  • 1
    get-psreadlineoption, is a function not a (array) variable. To access the properties returned by the function: (get-psreadlineoption).EditMode Commented Jan 4, 2022 at 11:51
  • Cool, thanks. So how can I loop over those attributes? Commented Jan 4, 2022 at 11:58
  • 1
    (get-psreadlineoption).ForEach{ $_ } Commented Jan 4, 2022 at 12:22

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

Comments

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.