Add $env:__SuppressAnsiEscapeSequences to control whether to… (#10814)

This commit is contained in:
Steve Lee 2019-10-24 12:45:26 -07:00 committed by Travis Plunk
parent 09b5ed3fd0
commit 4ff9924cbf
9 changed files with 220 additions and 72 deletions

View file

@ -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

View file

@ -37,6 +37,7 @@ variables:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
# Turn off Homebrew analytics
HOMEBREW_NO_ANALYTICS: 1
__SuppressAnsiEscapeSequences: 1
resources:
- repo: self

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View 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;
}
}
}

View file

@ -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*"
}
}
}

View file

@ -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
}
}