Terminal-Icons
Terminal-Icons copied to clipboard
XML glyph renders with an extra space before filename
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:
Here's 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)
- Set up your terminal to use FiraCode Nerd Font or JetBrainsMono Nerd Font. Doesn't seem to matter if it's Mac or Windows.
- 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
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.
Same font and everything, but in the Terminal window of VS Code shows the glyph "pushes" the space over and throws everything off.
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.
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" }
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".
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
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.
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.
v0.5.0 has been released with these changes.
Sweet, thanks!
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 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" }
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.
Yep, I see that with FiraCode NF. I usually use SauceCodePro myself.