Support mapping foreground/background ConsoleColor values to VT escape sequences (#17938)

This commit is contained in:
Dongbo Wang
2022-08-24 23:11:18 +05:00
committed by GitHub
parent d02c59addc
commit 543f5209c0
4 changed files with 139 additions and 25 deletions
@@ -315,8 +315,8 @@ namespace Microsoft.PowerShell.Commands
/// <returns>The matched line with matched text inverted.</returns>
private string EmphasizeLine()
{
string invertColorsVT100 = VTUtility.GetEscapeSequence(VTUtility.VT.Inverse);
string resetVT100 = VTUtility.GetEscapeSequence(VTUtility.VT.Reset);
string invertColorsVT100 = PSStyle.Instance.Reverse;
string resetVT100 = PSStyle.Instance.Reset;
char[] chars = new char[(_matchIndexes.Count * (invertColorsVT100.Length + resetVT100.Length)) + Line.Length];
int lineIndex = 0;
@@ -816,9 +816,7 @@ namespace System.Management.Automation.Runspaces
$errorColor = $psstyle.Formatting.Error
}
$resetColor = [System.Management.Automation.VTUtility]::GetEscapeSequence(
[System.Management.Automation.VTUtility+VT]::Reset
)
$resetColor = $PSStyle.Reset
}
function Get-VT100Color([ConsoleColor] $color) {
@@ -826,7 +824,7 @@ namespace System.Management.Automation.Runspaces
return ''
}
return [System.Management.Automation.VTUtility]::GetEscapeSequence($color)
return [System.Management.Automation.PSStyle]::MapForegroundColorToEscapeSequence($color)
}
function Show-ErrorRecord($obj, [int]$indent = 0, [int]$depth = 1) {
@@ -1070,9 +1068,7 @@ namespace System.Management.Automation.Runspaces
$resetColor = ''
if ($Host.UI.SupportsVirtualTerminal -and ([string]::IsNullOrEmpty($env:__SuppressAnsiEscapeSequences))) {
$resetColor = [System.Management.Automation.VTUtility]::GetEscapeSequence(
[System.Management.Automation.VTUtility+VT]::Reset
)
$resetColor = $PSStyle.Reset
}
function Get-VT100Color([ConsoleColor] $color) {
@@ -1080,21 +1076,7 @@ namespace System.Management.Automation.Runspaces
return ''
}
return [System.Management.Automation.VTUtility]::GetEscapeSequence($color)
}
# return length of string sans VT100 codes
function Get-RawStringLength($string) {
$vtCodes = ""`e[0m"", ""`e[2;30m"", ""`e[2;31m"", ""`e[2;32m"", ""`e[2;33m"", ""`e[2;34m"",
""`e[2;35m"", ""`e[2;36m"", ""`e[2;37m"", ""`e[1;30m"", ""`e[1;31m"", ""`e[1;32m"",
""`e[1;33m"", ""`e[1;34m"", ""`e[1;35m"", ""`e[1;36m"", ""`e[1;37m""
$newString = $string
foreach ($vtCode in $vtCodes) {
$newString = $newString.Replace($vtCode, '')
}
return $newString.Length
return [System.Management.Automation.PSStyle]::MapForegroundColorToEscapeSequence($color)
}
# returns a string cut to last whitespace
@@ -1217,7 +1199,7 @@ namespace System.Management.Automation.Runspaces
# if rendering line information, break up the message if it's wider than the console
if ($myinv -and $myinv.ScriptName -or $err.CategoryInfo.Category -eq 'ParserError') {
$prefixLength = Get-RawStringLength -string $prefix
$prefixLength = [System.Management.Automation.Internal.StringDecorated]::new($prefix).ContentLength
$prefixVtLength = $prefix.Length - $prefixLength
# replace newlines in message so it lines up correct
@@ -155,6 +155,16 @@ namespace System.Management.Automation
return FromRgb(red, green, blue);
}
/// <summary>
/// Return the VT escape sequence for a foreground color.
/// </summary>
/// <param name="color">The foreground color to be mapped from.</param>
/// <returns>The VT escape sequence representing the foreground color.</returns>
public string FromConsoleColor(ConsoleColor color)
{
return MapForegroundColorToEscapeSequence(color);
}
}
/// <summary>
@@ -270,6 +280,16 @@ namespace System.Management.Automation
return FromRgb(red, green, blue);
}
/// <summary>
/// Return the VT escape sequence for a background color.
/// </summary>
/// <param name="color">The background color to be mapped from.</param>
/// <returns>The VT escape sequence representing the background color.</returns>
public string FromConsoleColor(ConsoleColor color)
{
return MapBackgroundColorToEscapeSequence(color);
}
}
/// <summary>
@@ -722,6 +742,116 @@ namespace System.Management.Automation
return s_psstyle;
}
}
/// <summary>
/// The map of background console colors to escape sequences.
/// </summary>
private static readonly string[] BackgroundColorMap =
{
"\x1b[40m", // Black
"\x1b[44m", // DarkBlue
"\x1b[42m", // DarkGreen
"\x1b[46m", // DarkCyan
"\x1b[41m", // DarkRed
"\x1b[45m", // DarkMagenta
"\x1b[43m", // DarkYellow
"\x1b[47m", // Gray
"\x1b[100m", // DarkGray
"\x1b[104m", // Blue
"\x1b[102m", // Green
"\x1b[106m", // Cyan
"\x1b[101m", // Red
"\x1b[105m", // Magenta
"\x1b[103m", // Yellow
"\x1b[107m", // White
};
/// <summary>
/// The map of foreground console colors to escape sequences.
/// </summary>
private static readonly string[] ForegroundColorMap =
{
"\x1b[30m", // Black
"\x1b[34m", // DarkBlue
"\x1b[32m", // DarkGreen
"\x1b[36m", // DarkCyan
"\x1b[31m", // DarkRed
"\x1b[35m", // DarkMagenta
"\x1b[33m", // DarkYellow
"\x1b[37m", // Gray
"\x1b[90m", // DarkGray
"\x1b[94m", // Blue
"\x1b[92m", // Green
"\x1b[96m", // Cyan
"\x1b[91m", // Red
"\x1b[95m", // Magenta
"\x1b[93m", // Yellow
"\x1b[97m", // White
};
/// <summary>
/// Return the VT escape sequence for a ConsoleColor.
/// </summary>
/// <param name="color">The <see cref="ConsoleColor"/> to be mapped from.</param>
/// <param name="isBackground">Whether or not it's a background color.</param>
/// <returns>The VT escape sequence representing the color.</returns>
internal static string MapColorToEscapeSequence(ConsoleColor color, bool isBackground)
{
int index = (int)color;
if (index < 0 || index >= ForegroundColorMap.Length)
{
throw new ArgumentOutOfRangeException(paramName: nameof(color));
}
return (isBackground ? BackgroundColorMap : ForegroundColorMap)[index];
}
/// <summary>
/// Return the VT escape sequence for a foreground color.
/// </summary>
/// <param name="foregroundColor">The foreground color to be mapped from.</param>
/// <returns>The VT escape sequence representing the foreground color.</returns>
public static string MapForegroundColorToEscapeSequence(ConsoleColor foregroundColor)
=> MapColorToEscapeSequence(foregroundColor, isBackground: false);
/// <summary>
/// Return the VT escape sequence for a background color.
/// </summary>
/// <param name="backgroundColor">The background color to be mapped from.</param>
/// <returns>The VT escape sequence representing the background color.</returns>
public static string MapBackgroundColorToEscapeSequence(ConsoleColor backgroundColor)
=> MapColorToEscapeSequence(backgroundColor, isBackground: true);
/// <summary>
/// Return the VT escape sequence for a pair of foreground and background colors.
/// </summary>
/// <param name="foregroundColor">The foreground color of the color pair.</param>
/// <param name="backgroundColor">The background color of the color pair.</param>
/// <returns>The VT escape sequence representing the foreground and background color pair.</returns>
public static string MapColorPairToEscapeSequence(ConsoleColor foregroundColor, ConsoleColor backgroundColor)
{
int foreIndex = (int)foregroundColor;
int backIndex = (int)backgroundColor;
if (foreIndex < 0 || foreIndex >= ForegroundColorMap.Length)
{
throw new ArgumentOutOfRangeException(paramName: nameof(foregroundColor));
}
if (backIndex < 0 || backIndex >= ForegroundColorMap.Length)
{
throw new ArgumentOutOfRangeException(paramName: nameof(backgroundColor));
}
string foreground = ForegroundColorMap[foreIndex];
string background = BackgroundColorMap[backIndex];
return string.Concat(
foreground.AsSpan(start: 0, length: foreground.Length - 1),
";".AsSpan(),
background.AsSpan(start: 2));
}
}
#endregion PSStyle
}
@@ -1,6 +1,7 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
using System;
using System.Collections.Generic;
namespace System.Management.Automation
@@ -8,6 +9,7 @@ namespace System.Management.Automation
/// <summary>
/// Class to help with VT escape sequences.
/// </summary>
[Obsolete("This class is deprecated. Use 'System.Management.Automation.PSStyle' instead.", error: true)]
public sealed class VTUtility
{
/// <summary>