nix-output-monitor
nix-output-monitor copied to clipboard
Misaligned output
I'm not quite sure why, but the overview section of the nom build output is always misaligned.
This was tested on an M1 MacBook Pro running macOS Ventura.
It looks this way both in the official Terminal app and in iTerm 2. Changing between various fonts, even Nerd ones, also seems to have no effect.
Also spotted in x86-64 WSL.

Not an issue for me on NixOS 22.11.2606.2fb7d749c08 with Pantheon Terminal.

nix-output-monitor 2.0.0.5 nix (Nix) 2.11.1
To be fair, while on my system it’s not that bad as above I am also having misaligned output issues. This is super hard to get right on all platforms simultaneously, the problem is that it’s really hard to predict how many cells a certain emoji is wide in the current font. In kitty, my current terminal of choice, this actually changes during a run of nom (i.e. during a waiting build the hourglass sometimes has width 1 and sometimes width 2 without a discernible pattern …)
This sounds like it's caused in kitty by https://github.com/kovidgoyal/kitty/issues/3998. Kitty has a different behavior for character widths, so the sequence U+23F3 U+FE0E (hourglass + VS15) is rendered with a width of one cell instead of the two cells NOM calculates.
This rendering difference means it's generally impossible to do alignment the "correct" way across all terminal emulators without special casing.
Yes, that is also my fear. But even reliably detecting in which terminal we run seems hard.
I am considering to actually drop all emojis which tend to have an irregular width or at least offer an option to do so …
There is some relevant discussion with Kovid Goyal regarding the default presentations (and thus width in cells) of certain code points: https://github.com/kovidgoyal/kitty/issues/6572#issuecomment-1690889330
TL;DR: if you are explicitly adding the text presentation selector to the output (U+FE0E), you should expect the terminal to draw a single-width glyph, and if you are adding the emoji presentation selector (U+FE0F) you should expect the terminal to draw a double-width glyph. Any terminal that does not do this is exhibiting non-conformant behaviour and you should log an issue with that project.
The trickiness is really only when you're not adding presentation selectors. For code points that have both text and emoji presentations, they each have a default presentation. Technically, which presentation to actually render is up to the environment, but in practice a terminal emulator should stick to the default presentation exactly because there is no explicit way for the program to know which presentation is being used (and thus, how wide the rendered glyph is expected to be).
Interesting. I observed the "stuff changes if there is a whitespace behind it" behavior as well. I think I am consistently using a presentation selector.
This discussion gives me hope, that there is a principled solution to this. Will investigate when I have the time.
Not sure if this provides any insight, but I just noticed this.
I'm on mac and use iTerm. Whenever I use NOM the output is always misaligned (it looks like the picture in initial comment). I'm currently connected to NixOS from the same iTerm on the same Mac and the output looks properly aligned.
So it likely might have to do with how the terminal is initialized, perhaps the selector (mentioned by @zeorin) is set differently on those systems.
I observe this as well under alacritty and the PragmataPro font (with nerdfonts glyphs).
This tool is so awesome! I can't believe it took me this long to try it.
I've noticed that the wcwidth call here frequently returns -1:
https://github.com/maralorn/nix-output-monitor/blob/23d4302bab647e9f0f238ff3566f33b13ed9209e/lib/NOM/Print/Table.hs#L75
The main culprits are these characters:
⏱⏳⏵
However, patching widthFold to return a minimum of 1 doesn't help much.
Another problem is that the output includes variation selectors 15 and 16 to force text and emoji presentation (respectively) of the subsequent codepoint; for some reason, wcwidth thinks these characters are 1 cell wide.
~~Finally, the variation selectors are being used incorrectly; they're supposed to be before the codepoint they're applied to, not after it:~~
EDIT: Thanks @P1n3appl3 for pointing me to the Unicode docs on this, I had this wrong.
https://github.com/maralorn/nix-output-monitor/blob/05d7e3d545888847d59d3bcfdb01903d903417a8/lib/NOM/Print.hs#L66-L67
@amjoseph-nixpkgs Do you mind sharing on which system you encountered this issue? I am getting the impression that wcwidth works correctly on linux but is broken when used on Mac and WSL.
@amjoseph-nixpkgs Do you mind sharing on which system you encountered this issue?
Linux, sway, alacritty, Nixpkgs
I don't run NixOS (no systemd) but I don't think that has much to do with this issue.