powershellformatting

How to use ANSI escape color with format-wide in PowerShell


I'm using PowerShell 7.4.5 and I want to customize it.

If I usually use Get-ChildItem, ANSI escape color will be enabled.

But when I try to pipe it to format-wide, it doesn't work well.

In this result, directory highlighting is not working.

I also want to keep $PSStyle.FileInfo adapted when displaying in format-wide.

What should I do?

I tried $PSStyle.OutputRendering = 'Ansi', but it didn't work.


Solution

  • zett42 has provided the right answer in his helpful comment, use NameString as your Format-Wide Property:

    Get-ChildItem | Format-Wide NameString
    

    To provide some context, the NameString property together with LengthString and LastWriteTimeString are the properties used by the default formatter to have the colored or accented output in the TableControl. Essentially, these are the properties that have the injected VT sequences.

    (Get-FormatData System.IO.*Info).FormatViewDefinition |
        Where-Object { $_.Control -is [System.Management.Automation.TableControl] } |
        ForEach-Object { $_.Control.Rows.Columns }
    

    You can also observe this in DefaultFormatters/FileSystem_format_ps1xml.cs#L42-L126. For ListControl and WideControl however they use Name instead of NameString, this is why Format-List and Format-Wide outputs aren't colored.

    Update-FormatData could also be used if you want WideControl to use NameString by default, by changing the PropertyName tag. However this requires more work as the ps1xml obtained from Export-FormatData isn't perfect, it will require some editing in every <View> to make each one of them look like the default.

        <View>
          <Name>children</Name>
          <ViewSelectedBy>
            <TypeName>System.IO.DirectoryInfo</TypeName>
            <TypeName>System.IO.FileInfo</TypeName>
          </ViewSelectedBy>
          <GroupBy>
            <ScriptBlock>
              $_.PSParentPath.Remove(0, 38)
            </ScriptBlock>
            <Label>Directory</Label>
          </GroupBy>
          <WideControl>
            <WideEntries>
              <WideEntry>
                <WideItem>
                  <PropertyName>NameString</PropertyName>
                </WideItem>
              </WideEntry>
            </WideEntries>
          </WideControl>
        </View>