Add $env:__SuppressAnsiEscapeSequences
to control whether to… (#10814)
This commit is contained in:
parent
09b5ed3fd0
commit
4ff9924cbf
|
@ -35,6 +35,7 @@ variables:
|
|||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||
# Avoid expensive initialization of dotnet cli, see: https://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
__SuppressAnsiEscapeSequences: 1
|
||||
|
||||
resources:
|
||||
- repo: self
|
||||
|
|
|
@ -37,6 +37,7 @@ variables:
|
|||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
# Turn off Homebrew analytics
|
||||
HOMEBREW_NO_ANALYTICS: 1
|
||||
__SuppressAnsiEscapeSequences: 1
|
||||
|
||||
resources:
|
||||
- repo: self
|
||||
|
|
|
@ -34,6 +34,7 @@ variables:
|
|||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||
# Avoid expensive initialization of dotnet cli, see: https://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
__SuppressAnsiEscapeSequences: 1
|
||||
|
||||
resources:
|
||||
- repo: self
|
||||
|
|
|
@ -34,6 +34,7 @@ variables:
|
|||
POWERSHELL_TELEMETRY_OPTOUT: 1
|
||||
# Avoid expensive initialization of dotnet cli, see: https://donovanbrown.com/post/Stop-wasting-time-during-NET-Core-builds
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
|
||||
__SuppressAnsiEscapeSequences: 1
|
||||
|
||||
resources:
|
||||
- repo: self
|
||||
|
|
|
@ -256,7 +256,7 @@ namespace Microsoft.PowerShell.Commands
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the string representation of the match object with the matched line passed
|
||||
/// Returns the string representation of the match object with the matched line passed
|
||||
/// in as <paramref name="line"/> and trims the path to be relative to
|
||||
/// the<paramref name="directory"/> argument.
|
||||
/// </summary>
|
||||
|
@ -315,10 +315,10 @@ namespace Microsoft.PowerShell.Commands
|
|||
/// <returns>The matched line with matched text inverted.</returns>
|
||||
private string EmphasizeLine()
|
||||
{
|
||||
const string InvertColorsVT100 = "\u001b[7m";
|
||||
const string ResetVT100 = "\u001b[0m";
|
||||
string invertColorsVT100 = VTUtility.GetEscapeSequence(VTUtility.VT.Inverse);
|
||||
string resetVT100 = VTUtility.GetEscapeSequence(VTUtility.VT.Reset);
|
||||
|
||||
char[] chars = new char[(_matchIndexes.Count * (InvertColorsVT100.Length + ResetVT100.Length)) + Line.Length];
|
||||
char[] chars = new char[(_matchIndexes.Count * (invertColorsVT100.Length + resetVT100.Length)) + Line.Length];
|
||||
int lineIndex = 0;
|
||||
int charsIndex = 0;
|
||||
for (int i = 0; i < _matchIndexes.Count; i++)
|
||||
|
@ -329,8 +329,8 @@ namespace Microsoft.PowerShell.Commands
|
|||
lineIndex = _matchIndexes[i];
|
||||
|
||||
// Adds opening vt sequence
|
||||
InvertColorsVT100.CopyTo(0, chars, charsIndex, InvertColorsVT100.Length);
|
||||
charsIndex += InvertColorsVT100.Length;
|
||||
invertColorsVT100.CopyTo(0, chars, charsIndex, invertColorsVT100.Length);
|
||||
charsIndex += invertColorsVT100.Length;
|
||||
|
||||
// Adds characters being emphasized
|
||||
Line.CopyTo(lineIndex, chars, charsIndex, _matchLengths[i]);
|
||||
|
@ -338,8 +338,8 @@ namespace Microsoft.PowerShell.Commands
|
|||
charsIndex += _matchLengths[i];
|
||||
|
||||
// Adds closing vt sequence
|
||||
ResetVT100.CopyTo(0, chars, charsIndex, ResetVT100.Length);
|
||||
charsIndex += ResetVT100.Length;
|
||||
resetVT100.CopyTo(0, chars, charsIndex, resetVT100.Length);
|
||||
charsIndex += resetVT100.Length;
|
||||
}
|
||||
|
||||
// Adds remaining characters in line
|
||||
|
@ -1294,8 +1294,8 @@ namespace Microsoft.PowerShell.Commands
|
|||
private int _postContext = 0;
|
||||
|
||||
// When we are in Raw mode or pre- and postcontext are zero, use the _noContextTracker, since we will not be needing trackedLines.
|
||||
private IContextTracker GetContextTracker() => (Raw || (_preContext == 0 && _postContext == 0))
|
||||
? _noContextTracker
|
||||
private IContextTracker GetContextTracker() => (Raw || (_preContext == 0 && _postContext == 0))
|
||||
? _noContextTracker
|
||||
: new ContextTracker(_preContext, _postContext);
|
||||
|
||||
// This context tracker is only used for strings which are piped
|
||||
|
@ -1322,6 +1322,12 @@ namespace Microsoft.PowerShell.Commands
|
|||
/// </summary>
|
||||
protected override void BeginProcessing()
|
||||
{
|
||||
string suppressVt = Environment.GetEnvironmentVariable("__SuppressAnsiEscapeSequences");
|
||||
if (!string.IsNullOrEmpty(suppressVt))
|
||||
{
|
||||
NoEmphasis = true;
|
||||
}
|
||||
|
||||
if (!SimpleMatch)
|
||||
{
|
||||
RegexOptions regexOptions = CaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase;
|
||||
|
|
|
@ -741,35 +741,18 @@ namespace System.Management.Automation.Runspaces
|
|||
$maxDepth = 10
|
||||
$ellipsis = ""`u{2026}""
|
||||
$resetColor = ''
|
||||
if ($Host.UI.SupportsVirtualTerminal) {
|
||||
$resetColor = ""`e[0m""
|
||||
if ($Host.UI.SupportsVirtualTerminal -and !(Test-Path env:__SuppressAnsiEscapeSequences)) {
|
||||
$resetColor = [System.Management.Automation.VTUtility]::GetEscapeSequence(
|
||||
[System.Management.Automation.VTUtility+VT]::Reset
|
||||
)
|
||||
}
|
||||
|
||||
function Get-VT100Color([string] $color) {
|
||||
if (! $Host.UI.SupportsVirtualTerminal) {
|
||||
function Get-VT100Color([ConsoleColor] $color) {
|
||||
if (!$Host.UI.SupportsVirtualTerminal -or (Test-Path env:__SuppressAnsiEscapeSequences)) {
|
||||
return ''
|
||||
}
|
||||
|
||||
$colors = @{
|
||||
'Black' = ""`e[2;30m""
|
||||
'DarkRed' = ""`e[2;31m""
|
||||
'DarkGreen' = ""`e[2;32m""
|
||||
'DarkYellow' = ""`e[2;33m""
|
||||
'DarkBlue' = ""`e[2;34m""
|
||||
'DarkMagenta' = ""`e[2;35m""
|
||||
'DarkCyan' = ""`e[2;36m""
|
||||
'Gray' = ""`e[2;37m""
|
||||
'DarkGray' = ""`e[1;30m""
|
||||
'Red' = ""`e[1;31m""
|
||||
'Green' = ""`e[1;32m""
|
||||
'Yellow' = ""`e[1;33m""
|
||||
'Blue' = ""`e[1;34m""
|
||||
'Magenta' = ""`e[1;35m""
|
||||
'Cyan' = ""`e[1;36m""
|
||||
'White' = ""`e[1;37m""
|
||||
}
|
||||
|
||||
return $colors[$color]
|
||||
return [System.Management.Automation.VTUtility]::GetEscapeSequence($color)
|
||||
}
|
||||
|
||||
function Show-ErrorRecord($obj, [int]$indent = 0, [int]$depth = 1) {
|
||||
|
@ -981,35 +964,18 @@ namespace System.Management.Automation.Runspaces
|
|||
Set-StrictMode -Off
|
||||
|
||||
$resetColor = ''
|
||||
if ($Host.UI.SupportsVirtualTerminal) {
|
||||
$resetColor = ""`e[0m""
|
||||
if ($Host.UI.SupportsVirtualTerminal -and !(Test-Path env:__SuppressAnsiEscapeSequences)) {
|
||||
$resetColor = [System.Management.Automation.VTUtility]::GetEscapeSequence(
|
||||
[System.Management.Automation.VTUtility+VT]::Reset
|
||||
)
|
||||
}
|
||||
|
||||
function Get-VT100Color([string] $color) {
|
||||
if (! $Host.UI.SupportsVirtualTerminal) {
|
||||
function Get-VT100Color([ConsoleColor] $color) {
|
||||
if (!$Host.UI.SupportsVirtualTerminal -or (Test-Path env:__SuppressAnsiEscapeSequences)) {
|
||||
return ''
|
||||
}
|
||||
|
||||
$colors = @{
|
||||
'Black' = ""`e[2;30m""
|
||||
'DarkRed' = ""`e[2;31m""
|
||||
'DarkGreen' = ""`e[2;32m""
|
||||
'DarkYellow' = ""`e[2;33m""
|
||||
'DarkBlue' = ""`e[2;34m""
|
||||
'DarkMagenta' = ""`e[2;35m""
|
||||
'DarkCyan' = ""`e[2;36m""
|
||||
'Gray' = ""`e[2;37m""
|
||||
'DarkGray' = ""`e[1;30m""
|
||||
'Red' = ""`e[1;31m""
|
||||
'Green' = ""`e[1;32m""
|
||||
'Yellow' = ""`e[1;33m""
|
||||
'Blue' = ""`e[1;34m""
|
||||
'Magenta' = ""`e[1;35m""
|
||||
'Cyan' = ""`e[1;36m""
|
||||
'White' = ""`e[1;37m""
|
||||
}
|
||||
|
||||
return $colors[$color]
|
||||
return [System.Management.Automation.VTUtility]::GetEscapeSequence($color)
|
||||
}
|
||||
|
||||
# return length of string sans VT100 codes
|
||||
|
|
83
src/System.Management.Automation/utils/VTUtils.cs
Normal file
83
src/System.Management.Automation/utils/VTUtils.cs
Normal file
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace System.Management.Automation
|
||||
{
|
||||
/// <summary>
|
||||
/// Class to help with VT escape sequences.
|
||||
/// </summary>
|
||||
public sealed class VTUtility
|
||||
{
|
||||
/// <summary>
|
||||
/// Available VT escape codes other than colors.
|
||||
/// </summary>
|
||||
public enum VT
|
||||
{
|
||||
/// <summary>Reset the text style.</summary>
|
||||
Reset,
|
||||
|
||||
/// <summary>Invert the foreground and background colors.</summary>
|
||||
Inverse
|
||||
}
|
||||
|
||||
private static readonly Dictionary<ConsoleColor, string> ConsoleColors = new Dictionary<ConsoleColor, string>
|
||||
{
|
||||
{ ConsoleColor.Black, "\x1b[2;30m" },
|
||||
{ ConsoleColor.Gray, "\x1b[2;37m" },
|
||||
{ ConsoleColor.Red, "\x1b[1;31m" },
|
||||
{ ConsoleColor.Green, "\x1b[1;32m" },
|
||||
{ ConsoleColor.Yellow, "\x1b[1;33m" },
|
||||
{ ConsoleColor.Blue, "\x1b[1;34m" },
|
||||
{ ConsoleColor.Magenta, "\x1b[1;35m" },
|
||||
{ ConsoleColor.Cyan, "\x1b[1;36m" },
|
||||
{ ConsoleColor.White, "\x1b[1;37m" },
|
||||
{ ConsoleColor.DarkRed, "\x1b[2;31m" },
|
||||
{ ConsoleColor.DarkGreen, "\x1b[2;32m" },
|
||||
{ ConsoleColor.DarkYellow, "\x1b[2;33m" },
|
||||
{ ConsoleColor.DarkBlue, "\x1b[2;34m" },
|
||||
{ ConsoleColor.DarkMagenta, "\x1b[2;35m" },
|
||||
{ ConsoleColor.DarkCyan, "\x1b[2;36m" },
|
||||
{ ConsoleColor.DarkGray, "\x1b[1;30m" },
|
||||
};
|
||||
|
||||
private static readonly Dictionary<VT, string> VTCodes = new Dictionary<VT, string>
|
||||
{
|
||||
{ VT.Reset, "\x1b[0m" },
|
||||
{ VT.Inverse, "\x1b[7m" }
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Return the VT escape sequence for a ConsoleColor.
|
||||
/// </summary>
|
||||
/// <param name="color">
|
||||
/// The ConsoleColor to return the equivalent VT escape sequence.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The requested VT escape sequence.
|
||||
/// </returns>
|
||||
public static string GetEscapeSequence(ConsoleColor color)
|
||||
{
|
||||
string value = string.Empty;
|
||||
ConsoleColors.TryGetValue(color, out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the VT escape sequence for a supported VT enum value.
|
||||
/// </summary>
|
||||
/// <param name="vt">
|
||||
/// The VT code to return the VT escape sequence.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The requested VT escape sequence.
|
||||
/// </returns>
|
||||
public static string GetEscapeSequence(VT vt)
|
||||
{
|
||||
string value = string.Empty;
|
||||
VTCodes.TryGetValue(vt, out value);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
Describe '$env:__SuppressAnsiEscapeSequences tests' -Tag CI {
|
||||
BeforeAll {
|
||||
$originalSuppressPref = $env:__SuppressAnsiEscapeSequences
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
$env:__SuppressAnsiEscapeSequences = $originalSuppressPref
|
||||
}
|
||||
|
||||
|
||||
Context 'Allow Escape Sequences' {
|
||||
BeforeAll {
|
||||
Remove-Item env:__SuppressAnsiEscapeSequences -ErrorAction Ignore
|
||||
}
|
||||
|
||||
It 'Select-String emits VT' {
|
||||
"select this string" | Select-String 'this' | Out-String |Should -BeLikeExactly "*`e*"
|
||||
}
|
||||
|
||||
It 'ConciseView emits VT' {
|
||||
$oldErrorView = $ErrorView
|
||||
|
||||
try {
|
||||
$ErrorView = 'ConciseView'
|
||||
Invoke-Expression '1/d'
|
||||
}
|
||||
catch {
|
||||
$e = $_
|
||||
}
|
||||
finally {
|
||||
$ErrorView = $oldErrorView
|
||||
}
|
||||
|
||||
$e | Out-String | Should -BeLikeExactly "*`e*"
|
||||
}
|
||||
|
||||
It 'Get-Error emits VT' {
|
||||
try {
|
||||
1/0
|
||||
}
|
||||
catch {
|
||||
# ignore
|
||||
}
|
||||
|
||||
Get-Error | Out-String | Should -BeLikeExactly "*`e*"
|
||||
}
|
||||
}
|
||||
|
||||
Context 'No Escape Sequences' {
|
||||
BeforeAll {
|
||||
$env:__SuppressAnsiEscapeSequences = 1
|
||||
}
|
||||
|
||||
It 'Select-String does not emit VT' {
|
||||
"select this string" | Select-String 'this' | Out-String | Should -Not -BeLikeExactly "*`e*"
|
||||
}
|
||||
|
||||
It 'ConciseView does not emit VT' {
|
||||
$oldErrorView = $ErrorView
|
||||
|
||||
try {
|
||||
$ErrorView = 'ConciseView'
|
||||
Invoke-Expression '1/d'
|
||||
}
|
||||
catch {
|
||||
$e = $_
|
||||
}
|
||||
finally {
|
||||
$ErrorView = $oldErrorView
|
||||
}
|
||||
|
||||
$e | Out-String | Should -Not -BeLikeExactly "*`e*"
|
||||
}
|
||||
|
||||
It 'Get-Error does not emit VT' {
|
||||
try {
|
||||
1/0
|
||||
}
|
||||
catch {
|
||||
# ignore
|
||||
}
|
||||
|
||||
Get-Error | Out-String | Should -Not -BeLikeExactly "*`e*"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,10 @@ Describe "Select-String" -Tags "CI" {
|
|||
$currentDirectory = $pwd.Path
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
Push-Location $currentDirectory
|
||||
}
|
||||
|
||||
Context "String actions" {
|
||||
$testinputone = "hello","Hello","goodbye"
|
||||
$testinputtwo = "hello","Hello"
|
||||
|
@ -76,47 +80,47 @@ Describe "Select-String" -Tags "CI" {
|
|||
}
|
||||
|
||||
it "Should output a string with the first match highlighted" {
|
||||
if ($Host.UI.SupportsVirtualTerminal)
|
||||
if ($Host.UI.SupportsVirtualTerminal -and !(Test-Path env:__SuppressAnsiEscapeSequences))
|
||||
{
|
||||
$result = $testinputone | Select-String -Pattern "l" | Out-String
|
||||
$result | Should -Be "`nhe`e[7ml`e[0mlo`nHe`e[7ml`e[0mlo`n`n"
|
||||
$result | Should -Be "${nl}he`e[7ml`e[0mlo${nl}He`e[7ml`e[0mlo${nl}${nl}"
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = $testinputone | Select-String -Pattern "l" | Out-String
|
||||
$result | Should -Be "`nhello`nHello`n`n"
|
||||
$result | Should -Be "${nl}hello${nl}Hello${nl}${nl}"
|
||||
}
|
||||
}
|
||||
|
||||
it "Should output a string with all matches highlighted when AllMatch is used" {
|
||||
if ($Host.UI.SupportsVirtualTerminal)
|
||||
if ($Host.UI.SupportsVirtualTerminal -and !(Test-Path env:__SuppressAnsiEscapeSequences))
|
||||
{
|
||||
$result = $testinputone | Select-String -Pattern "l" -AllMatch | Out-String
|
||||
$result | Should -Be "`nhe`e[7ml`e[0m`e[7ml`e[0mo`nHe`e[7ml`e[0m`e[7ml`e[0mo`n`n"
|
||||
$result | Should -Be "${nl}he`e[7ml`e[0m`e[7ml`e[0mo${nl}He`e[7ml`e[0m`e[7ml`e[0mo${nl}${nl}"
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = $testinputone | Select-String -Pattern "l" -AllMatch | Out-String
|
||||
$result | Should -Be "`nhello`nHello`n`n"
|
||||
$result | Should -Be "${nl}hello${nl}Hello${nl}${nl}"
|
||||
}
|
||||
}
|
||||
|
||||
it "Should output a string with the first match highlighted when SimpleMatch is used" {
|
||||
if ($Host.UI.SupportsVirtualTerminal)
|
||||
if ($Host.UI.SupportsVirtualTerminal -and !(Test-Path env:__SuppressAnsiEscapeSequences))
|
||||
{
|
||||
$result = $testinputone | Select-String -Pattern "l" -SimpleMatch | Out-String
|
||||
$result | Should -Be "`nhe`e[7ml`e[0mlo`nHe`e[7ml`e[0mlo`n`n"
|
||||
$result | Should -Be "${nl}he`e[7ml`e[0mlo${nl}He`e[7ml`e[0mlo${nl}${nl}"
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = $testinputone | Select-String -Pattern "l" -SimpleMatch | Out-String
|
||||
$result | Should -Be "`nhello`nHello`n`n"
|
||||
$result | Should -Be "${nl}hello${nl}Hello${nl}${nl}"
|
||||
}
|
||||
}
|
||||
|
||||
it "Should output a string without highlighting when NoEmphasis is used" {
|
||||
$result = $testinputone | Select-String -Pattern "l" -NoEmphasis | Out-String
|
||||
$result | Should -Be "`nhello`nHello`n`n"
|
||||
$result | Should -Be "${nl}hello${nl}Hello${nl}${nl}"
|
||||
}
|
||||
|
||||
it "Should return an array of matching strings without virtual terminal sequences" {
|
||||
|
@ -247,8 +251,4 @@ Describe "Select-String" -Tags "CI" {
|
|||
Select-String second $testInputFile -Raw -Context 2,2 | Should -BeExactly $expected
|
||||
}
|
||||
}
|
||||
|
||||
AfterAll {
|
||||
Push-Location $currentDirectory
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue