mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Fix formatting to properly handle the Reset VT sequences that appear in the middle of a string (#26424)
This commit is contained in:
@@ -9,7 +9,6 @@ using System.Globalization;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Internal;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
{
|
||||
@@ -317,6 +316,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
{
|
||||
internal string Word;
|
||||
internal string Delim;
|
||||
internal bool VtResetAdded;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -367,9 +367,19 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
{
|
||||
var vtSpan = s.AsSpan(i, len);
|
||||
sb.Append(vtSpan);
|
||||
vtSeqs.Append(vtSpan);
|
||||
|
||||
wordHasVtSeqs = true;
|
||||
if (vtSpan.SequenceEqual(PSStyle.Instance.Reset))
|
||||
{
|
||||
// The Reset sequence will void all previous VT sequences.
|
||||
vtSeqs.Clear();
|
||||
wordHasVtSeqs = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtSeqs.Append(vtSpan);
|
||||
wordHasVtSeqs = true;
|
||||
}
|
||||
|
||||
i += len - 1;
|
||||
continue;
|
||||
}
|
||||
@@ -390,15 +400,18 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
|
||||
if (delimiter is not null)
|
||||
{
|
||||
bool vtResetAdded = false;
|
||||
if (wordHasVtSeqs && !sb.EndsWith(PSStyle.Instance.Reset))
|
||||
{
|
||||
vtResetAdded = true;
|
||||
sb.Append(PSStyle.Instance.Reset);
|
||||
}
|
||||
|
||||
var result = new GetWordsResult()
|
||||
{
|
||||
Word = sb.ToString(),
|
||||
Delim = delimiter
|
||||
Delim = delimiter,
|
||||
VtResetAdded = vtResetAdded
|
||||
};
|
||||
|
||||
sb.Clear().Append(vtSeqs);
|
||||
@@ -611,7 +624,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
|
||||
if (suffix is not null)
|
||||
{
|
||||
wordToAdd = wordToAdd.EndsWith(resetStr)
|
||||
wordToAdd = word.VtResetAdded
|
||||
? wordToAdd.Insert(wordToAdd.Length - resetStr.Length, suffix)
|
||||
: wordToAdd + suffix;
|
||||
}
|
||||
@@ -760,9 +773,19 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
{
|
||||
var vtSpan = s.AsSpan(i, len);
|
||||
sb.Append(vtSpan);
|
||||
vtSeqs.Append(vtSpan);
|
||||
|
||||
hasVtSeqs = true;
|
||||
if (vtSpan.SequenceEqual(PSStyle.Instance.Reset))
|
||||
{
|
||||
// The Reset sequence will void all previous VT sequences.
|
||||
vtSeqs.Clear();
|
||||
hasVtSeqs = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
vtSeqs.Append(vtSpan);
|
||||
hasVtSeqs = true;
|
||||
}
|
||||
|
||||
i += len - 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
|
||||
_cachedBuilder.Append(headPadding).Append(str);
|
||||
}
|
||||
|
||||
if (str.Contains(ValueStringDecorated.ESC) && !str.EndsWith(reset))
|
||||
if (str.Contains(ValueStringDecorated.ESC) && !str.AsSpan().TrimEnd().EndsWith(reset, StringComparison.Ordinal))
|
||||
{
|
||||
_cachedBuilder.Append(reset);
|
||||
}
|
||||
|
||||
@@ -488,7 +488,7 @@ Billy Bob… Senior DevOps … 13
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Word wrapping for string with escape sequences" {
|
||||
It "Word wrapping for string with escape sequences (1)" {
|
||||
$expected = @"
|
||||
`e[32;1mLongDescription : `e[0m`e[33mPowerShell `e[0m
|
||||
`e[33mscripting `e[0m
|
||||
@@ -501,7 +501,46 @@ Billy Bob… Senior DevOps … 13
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Splitting multi-line string with escape sequences" {
|
||||
It "Word wrapping for string with escape sequences (2)" {
|
||||
$expected = @"
|
||||
`e[32;1mLongDescription : `e[0m`e[33mPowerShell`e[0m
|
||||
scripting
|
||||
language
|
||||
"@
|
||||
$obj = [pscustomobject] @{ LongDescription = "`e[33mPowerShell`e[0m scripting language" }
|
||||
$obj | Format-List | Out-String -Width 35 | Out-File $outFile
|
||||
|
||||
$text = Get-Content $outFile -Raw
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Word wrapping for string with escape sequences (3)" {
|
||||
$expected = @"
|
||||
`e[32;1mLongDescription : `e[0m`e[33mPowerShell`e[0m
|
||||
`e[32mscripting `e[0m
|
||||
`e[32mlanguage`e[0m
|
||||
"@
|
||||
$obj = [pscustomobject] @{ LongDescription = "`e[33mPowerShell`e[0m `e[32mscripting language" }
|
||||
$obj | Format-List | Out-String -Width 35 | Out-File $outFile
|
||||
|
||||
$text = Get-Content $outFile -Raw
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Word wrapping for string with escape sequences (4)" {
|
||||
$expected = @"
|
||||
`e[32;1mLongDescription : `e[0m`e[33mPowerShell`e[0m
|
||||
`e[32mscripting`e[0m
|
||||
language
|
||||
"@
|
||||
$obj = [pscustomobject] @{ LongDescription = "`e[33mPowerShell`e[0m `e[32mscripting`e[0m language" }
|
||||
$obj | Format-List | Out-String -Width 35 | Out-File $outFile
|
||||
|
||||
$text = Get-Content $outFile -Raw
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Splitting multi-line string with escape sequences (1)" {
|
||||
$expected = @"
|
||||
`e[32;1mb : `e[0m`e[33mPowerShell is a task automation and configuration management program from Microsoft,`e[0m
|
||||
`e[33mconsisting of a command-line shell and the associated scripting language`e[0m
|
||||
@@ -513,6 +552,30 @@ Billy Bob… Senior DevOps … 13
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Splitting multi-line string with escape sequences (2)" {
|
||||
$expected = @"
|
||||
`e[32;1mb : `e[0m`e[33mPowerShell is a task automation and configuration management program from Microsoft,`e[0m
|
||||
consisting of a command-line shell and the associated scripting language
|
||||
"@
|
||||
$obj = [pscustomobject] @{ b = "`e[33mPowerShell is a task automation and configuration management program from Microsoft,`e[0m`nconsisting of a command-line shell and the associated scripting language" }
|
||||
$obj | Format-List | Out-File $outFile
|
||||
|
||||
$text = Get-Content $outFile -Raw
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Splitting multi-line string with escape sequences (3)" {
|
||||
$expected = @"
|
||||
`e[32;1mb : `e[0m`e[33mPowerShell is a task automation and configuration management program from Microsoft,`e[0m
|
||||
`e[32mconsisting of a command-line shell and the associated scripting language`e[0m
|
||||
"@
|
||||
$obj = [pscustomobject] @{ b = "`e[33mPowerShell is a task automation and configuration management program from Microsoft,`e[0m`n`e[32mconsisting of a command-line shell and the associated scripting language" }
|
||||
$obj | Format-List | Out-File $outFile
|
||||
|
||||
$text = Get-Content $outFile -Raw
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Wrapping long word with escape sequences" {
|
||||
$expected = @"
|
||||
`e[32;1mb : `e[0m`e[33mC:\repos\PowerShell\src\powershell-w`e[0m
|
||||
@@ -525,4 +588,18 @@ Billy Bob… Senior DevOps … 13
|
||||
$text = Get-Content $outFile -Raw
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
|
||||
It "Format 'MatchInfo' object correctly" {
|
||||
$expected = @"
|
||||
`e[32;1mb : `e[0mmouclass `e[7mMouse`e[0m Class Driver Mouse Class Driver Kernel Manual Running OK TRUE FALSE 12,288 `e[0m
|
||||
32,768 0 C:\WINDOWS\system32\drivers\mouclass.sys 4,096
|
||||
"@
|
||||
|
||||
## This string mimics the VT decorated string for a 'MatchInfo' object that matches the word 'mouse'.
|
||||
$str = "mouclass `e[7mMouse`e[0m Class Driver Mouse Class Driver Kernel Manual Running OK TRUE FALSE 12,288 32,768 0 C:\WINDOWS\system32\drivers\mouclass.sys 4,096"
|
||||
$obj = [pscustomobject] @{ b = $str }
|
||||
$text = $obj | Format-List | Out-String -Width 150
|
||||
|
||||
$text.Trim().Replace("`r", "") | Should -BeExactly $expected.Replace("`r", "")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user