wez / wezterm

A GPU-accelerated cross-platform terminal emulator and multiplexer written by @wez and implemented in Rust
https://wezfurlong.org/wezterm/
Other
17.78k stars 796 forks source link

WezTerm doesn't use the Nerd Font Symbols fallback when using certain non-default fonts #5404

Closed rowanlovejoy closed 5 months ago

rowanlovejoy commented 6 months ago

What Operating System(s) are you seeing this problem on?

Windows

Which Wayland compositor or X11 Window manager(s) are you using?

No response

WezTerm version

20240509-223025-91a16e52

Did you try the latest nightly build to see if the issue is better (or worse!) than your current version?

Yes, and I updated the version box above to show the version of the nightly that I tried

Describe the bug

If I change the default font used by WezTerm from JetBrains Mono to Fira Code, Consolas, or Cascadia Code (these are fonts I've tried; used the latest versions of all three), WezTerm no longer uses the Nerd Font Symbols fallback. However, I also tried Geist and Geist Mono, and with them WezTerm does appear to use the Nerd Font Symbols fallback. Based on the font fallback section of the docs, I would have expected the fallback to be used in all these cases. Tried using both the font() and font_with_fallback() functions; result is the same with both.

To Reproduce

Edit .wezterm.lua and specify either Fira Code, Consolas, or Cascadia Code as the font and then save the file.

Configuration

local wezterm = require("wezterm")

-- This will hold the configuration.
local config = wezterm.config_builder()

config.font = wezterm.font_with_fallback("Fira Code")

return config

Expected Behavior

The Nerd Font Symbols fallback is used with whatever font I specify.

Logs

No response

Anything else?

No response

wez commented 6 months ago

There's insufficient information to reproduce the issue in this report. Run through https://wezfurlong.org/wezterm/troubleshooting.html#debugging-font-display and share more about the specific text and results that you're experiencing issues with.

rowanlovejoy commented 6 months ago

Hello.

My understanding of WezTerm's font handling is that it will use the Symbols Nerd Font font to render any characters it encounters that are not included in the font I specify. In my .wezterm.lua, I specified “Fira Code” as my font. This font doesn't include any nerd font symbols, so my expectation would be that to render these symbols, WezTerm will fall back to Nerd Font Symbols, which, I think, is what the docs are saying: font fallback section of the docs. Here is my complete .wezterm.lua:

-- Pull in the wezterm API
local wezterm = require 'wezterm'

-- This will hold the configuration.
local config = wezterm.config_builder()

config.font = wezterm.font('Fira Code')

config.default_prog = { 'C:\\Users\\Rowan\\AppData\\Local\\Microsoft\\WindowsApps\\Microsoft.PowerShell_8wekyb3d8bbwe\\pwsh.exe', }

-- and finally, return the configuration to wezterm
return config

But this isn't happening. I am using Oh My Posh to customise the prompt string in my shell (PowerShell 7.4.2). Oh My Posh requires a font with nerd font symbols to display correctly. In WezTerm, if I set my font to FiraCode Nerd Font, my prompt string displays correctly and looks like this: image However, if I set WezTerm to use Fira Code (not the Nerd Fonts version), the symbols do not display correctly, and my prompt string looks like this (note the difference in how the heart is rendered; the Oh My Posh theme I'm using is not supposed to look like that): image

If I run wezterm ls-fonts, it reports what I would expect; it will use my selected font, Fira Code, as my primary font, but will fall back to the Nerd Font Symbols font:

wezterm ls-fonts
Primary font:
wezterm.font_with_fallback({
  -- C:\USERS\ROWAN\APPDATA\LOCAL\MICROSOFT\WINDOWS\FONTS\FIRACODE-REGULAR_0.TTF, DirectWrite
  "Fira Code",

  -- C:\WINDOWS\FONTS\JETBRAINSMONO-REGULAR.TTF, DirectWrite
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  "Noto Color Emoji",

  -- C:\WINDOWS\FONTS\SYMBOLSNERDFONTMONO-REGULAR.TTF, DirectWrite
  "Symbols Nerd Font Mono",

})
...

If I instead specify JetBrains Mono as the font in my .wezterm.lua, my Oh My Posh prompt string displays correctly, even though JetBrains Mono does not include nerd font symbols. Here is what the prompt string looks like in WezTerm when using JetBrains Mono: image Here is my .wezterm.lua specifying JetBrains Mono as the font:

-- Pull in the wezterm API
local wezterm = require 'wezterm'

-- This will hold the configuration.
local config = wezterm.config_builder()

config.font = wezterm.font('JetBrains Mono')

config.default_prog = { 'C:\\Users\\Rowan\\AppData\\Local\\Microsoft\\WindowsApps\\Microsoft.PowerShell_8wekyb3d8bbwe\\pwsh.exe', }

-- and finally, return the configuration to wezterm
return config

And here is the output of running wezterm ls-fonts:

wezterm ls-fonts
Primary font:
wezterm.font_with_fallback({
  -- C:\WINDOWS\FONTS\JETBRAINSMONO-REGULAR.TTF, DirectWrite
  "JetBrains Mono",

  -- <built-in>, BuiltIn
  -- Assumed to have Emoji Presentation
  "Noto Color Emoji",

  -- C:\WINDOWS\FONTS\SYMBOLSNERDFONTMONO-REGULAR.TTF, DirectWrite
  "Symbols Nerd Font Mono",

})
...
wez commented 6 months ago

I'd recommend running wezterm ls-fonts --text PASTEHEARTHERE to show which font wezterm will use. Note that hearts are unicode symbols that are not usually found in Nerd Fonts fonts, so the discrepancy may just be down to the emoji font or emoji presentation that is in use.

rowanlovejoy commented 5 months ago

I found the exact heart symbol used by my Oh My Posh prompt string on the Nerd Fonts site; it's nf-oct-heart aka. 2665. I checked the code of my Oh My Posh theme, MS365Princess, and this is, indeed, the same symbol it uses for the heart (observe the template value) (source):

{
  "background": "p:teal_blue",
  "foreground": "p:white",
  "properties": {
    "time_format": "15:04"
  },
  "style": "diamond",
  "template": " \u2665 {{ .CurrentDate | date .Format }} ",
  "trailing_diamond": "\ue0b0",
  "type": "time"
}

With WezTerm configured to use Fira Code, when I run wezterm ls-fonts --text ♥ (I copied the heart symbol from the Nerd Fonts website using the copy symbol button), it reports it will use Fira Code and not the Symbols Nerd Font fallback:

wezterm ls-fonts --text ♥
LeftToRight
 0 ♥    \u{2665}     x_adv=10 cells=1  glyph=heart,1311 wezterm.font("Fira Code", {weight="Regular", stretch="Normal", style="Normal"})
                                      C:\USERS\ROWAN\APPDATA\LOCAL\MICROSOFT\WINDOWS\FONTS\FIRACODE-REGULAR_0.TTF, DirectWrite

This suggests, as you did in your comment, that the heart symbol is not present in the Symbols Nerd Font pack. However, if I download the Symbols Nerd Font pack from the Nerd Fonts website (I believe this is the same pack used by WezTerm), and upload it to FontDrop, which displays the symbols in .tff files, I can see the heart symbol, 2665, referenced by my Oh My Posh prompt string, is present: image

And if switch my WezTerm font back to JetBrains Mono (the normal, non-nerd font version) and run wezterm ls-fonts --text ♥ again, it now reports that it will use the Symbols Nerd Font font:

wezterm ls-fonts --text ♥
LeftToRight
 0 ♥    \u{2665}     x_adv=11.764705882352942 cells=1  glyph=heart,8    wezterm.font("Symbols Nerd Font Mono", {weight="Regular", stretch="Normal", style="Normal"})
                                      C:\WINDOWS\FONTS\SYMBOLSNERDFONTMONO-REGULAR.TTF, DirectWrite

My speculation is WezTerm detects that Fira Code, as well as Consolas and Cascadia Code (running wezterm ls-fonts --text ♥ with these fonts reports that it will use those fonts and not the symbols pack, as it does with Fira Code) do include the symbol, and so it's not falling back to the Symbols Nerd Font pack. Could this or something similar be the case?

wez commented 5 months ago

Since your config says to use Fira Code as the primary font, and Fira Code includes that heart symbol, then no fallback is performed for that glyph, because it is immediately found in the primary font.

This is working as intended; wezterm doesn't have a way to mix and match fonts based on arbitrary codepoints. This issue is open as a feature request for that functionality:

rowanlovejoy commented 5 months ago

I didn't occur to me to check the contents of Fira Code. As you say, it contains a heart symbol, with the same code, 2665, but with an entirely different appearance. The Fira Code Nerd Font replaces this symbol with the expected, higher detail version.

I see that WezTerm is working as intended. Apologies for the inconvenience. Thank you for taking the time to answer my questions.

github-actions[bot] commented 4 months ago

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues. If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.