Terminal-Icons icon indicating copy to clipboard operation
Terminal-Icons copied to clipboard

XML glyph renders with an extra space before filename

Open tillig opened this issue 3 years ago • 12 comments

Expected Behavior

Most of the icons render in a single character width; I expect the XML icon to also render in one character.

Current Behavior

On both Windows (PowerShell 7.1.3 / Windows Terminal) and Mac (PowerShell 7.1.3 / iTerm2) the XML icons appear to insert a leading space before the filename. Other icons don't do that.

Here's JetBrainsMono Nerd Font:

JetBrainsMono Nerd Font

Here's FiraCode Nerd Font:

FiraCode Nerd Font

It doesn't seem to matter about the font or the terminal, there's always that extra space.

Possible Solution

I'm not sure if it's a double-character glyph where the extra space is an artifact or if there's a hidden character in the icon theme I haven't seen yet. Double-wide glyphs can get weird.

Steps to Reproduce (for bugs)

  1. Set up your terminal to use FiraCode Nerd Font or JetBrainsMono Nerd Font. Doesn't seem to matter if it's Mac or Windows.
  2. List a folder with an XML file in it.

Context

New user of the module, just noticed the odd spacing when listing a folder.

Your Environment

  • Module version used: 0.4.0
  • Operating System and PowerShell version: MacOS Big Sur 11.2.3, PowerShell 7.1.3, iTerm2

tillig avatar Apr 19 '21 22:04 tillig

Definitely some weird rendering thing going on with the double-wide glyph. If I copy/paste a listing into VS Code, I can see that the file listing lines up, but you can just make out that the XML glyph is covering one of the two spaces.

Listing in VS Code Editor

Same font and everything, but in the Terminal window of VS Code shows the glyph "pushes" the space over and throws everything off.

VS Code Terminal Window

Unclear why it doesn't have the same effect on the directories, which also appear to be double-wide.

I'm guessing the short-term resolution is to pick a different icon for XML files that's not double-wide and just call it good.

tillig avatar Apr 19 '21 22:04 tillig

Here's a snippet to replace the double-wide XML icon with something single-width. It doesn't appear I can access the actual glyphs.ps1 data so I can't replace nf-mdi-xml with something different at the top level; instead I need to update all the mappings. Not a huge deal, but it might be nice to have a "swap glyph x with glyph y" command for stuff like this.

$fileIcons = (Get-TerminalIconsTheme).Icon.Types.Files
$xmlKeys = $fileIcons.Keys | Where-Object { $fileIcons[$_] -eq "nf-mdi-xml" }
$xmlKeys | %{ $fileIcons[$_] = "nf-mdi-file_xml" }

tillig avatar Apr 19 '21 23:04 tillig

In addition to *.xml files I am observing the same issue with *.log, *.exe, and *.iml files. Tested on "UbuntuMono Nerd Font" and "InconsolataLGCMono Nerd Font".

ShrykeWindgrace avatar Apr 20 '21 13:04 ShrykeWindgrace

Would there be an straightforward way to detect if it's a double-wide glyph? When we write out the name, we add two spaces between the icon and file/folder name. If we can detect a double-wide glyph we can use only one space to things line up.

https://github.com/devblackops/Terminal-Icons/blob/master/Terminal-Icons/Public/Format-TerminalIcons.ps1#L37

devblackops avatar Apr 21 '21 00:04 devblackops

If it's consistent across terminals (which it seems to be) it might be something that could be generated during a build. For example, could you write out a known string, like [$glyph] and then do something with the host RawUI (or similar) to read where the brackets are? I haven't tried it, but since it's a rendering thing it seems like you'd have to interact with a host implementation.

tillig avatar Apr 21 '21 01:04 tillig

I think the simplest solution right now is to not use problematic glyphs so I've switched them out in the theme in https://github.com/devblackops/Terminal-Icons/commit/eb36e628b5429ae0cd14f24d7c5bd24d45072d29.

devblackops avatar Apr 21 '21 04:04 devblackops

v0.5.0 has been released with these changes.

devblackops avatar Apr 21 '21 06:04 devblackops

Sweet, thanks!

tillig avatar Apr 21 '21 13:04 tillig

Here's a script that can be used to calculate the glyph widths.

<#
This script writes all the glyphs to the console and inspects the console buffer
to see if the glyph takes up one or two characters. This works on Windows
Terminal in PowerShell Core but does not work on MacOS + iTerm2 + PowerShell
Core.

The buffer for a single-width glyph looks like:


'' Gray Black Complete ' ' Gray Black Complete

A double-wide, on the other hand, looks like:

謹
'謹' Gray Black Complete '謹' Gray Black Complete

So, basically, we only have to write the glyph and grab two buffer cells to
figure out the width.
#>

$currentPos = $host.UI.RawUI.CursorPosition.Y
$rec = New-Object System.Management.Automation.Host.Rectangle(0, ($currentPos - 1), 1, ($currentPos - 1))

$glyphs = Get-TerminalIconsGlyphs

$widths = @{}
$glyphs.Keys | ForEach-Object {
    $name = $_
    $glyph = $glyphs[$_]
    Write-Host $glyph
    $buffer = $host.UI.RawUI.GetBufferContents($rec)
    $widths[$name] = ($buffer[0, 1].Character -eq $glyph) ? 2 : 1
}

$widths

Running that...

$widths = ./Get-GlyphWidths.ps1
$widths.Keys | Where-Object { $widths[$_] -eq 2 }

...we actually find there are a LOT of double-width glpyhs - 513 if you pipe it through Measure-Object.

It may be worth adding a step to the build to generate the hash table (or doing it manually on a periodic basis if the host doesn't support it in GitHub Actions) of glyph-to-width and then using that original idea - write the associated number of spaces after the glyph.

tillig avatar Apr 21 '21 14:04 tillig

@tillig I'm not sure why, but when I run this all the glyphs show as 1 width, yet when I run the below I can clearly see the double-wide glyphs:

(Get-TerminalIconsGlyphs).Values | % { "$_ test" }

devblackops avatar Apr 24 '21 20:04 devblackops

I tried a couple of things and I think I figured out the difference, at least on Windows:

Under Fira Code Nerd Font all the widths do show up as one. Under Fira Code Nerd Font Mono I see the variations and it correctly reports as two characters instead of one.

So the difference is in the "Mono" font vs. the one not marked "Mono" - the buffer reports differently based on the font used, even if the final rendering looks the same.

tillig avatar Apr 24 '21 21:04 tillig

Yep, I see that with FiraCode NF. I usually use SauceCodePro myself.

devblackops avatar Apr 24 '21 23:04 devblackops