Skip to content

bug: custom fontSize + alignMessage causes alignment to break #246

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
lrstanley opened this issue May 17, 2025 · 5 comments
Open

bug: custom fontSize + alignMessage causes alignment to break #246

lrstanley opened this issue May 17, 2025 · 5 comments

Comments

@lrstanley
Copy link

lrstanley commented May 17, 2025

Using the following config:

{
    "errorLens.scrollbarHackEnabled": true,
    "errorLens.enabledDiagnosticLevels": [
        "error",
        "warning"
    ],
    "errorLens.onSave": true,
    "errorLens.fontSize": "-3px",
    "errorLens.alignMessage": {
        "start": 105,
        "end": 0,
        "padding": [
            0,
            1
        ]
    }
}

Causes start alignment to no longer work:

Suspect that the alignment calculation is using the relative font size for the error lens message itself, rather than the editor's font size, thus the skew.

Notes:

  • Yes, the above screenshot is using a monospace font (Comic Sans Mono).
  • The more I lower the font size (relative in my case, so more negative), the more the alignment breaks.
  • The shorter the line that the error is on (characters), the more left it shifts.
  • Removing errorLens.fontSize, and the alignment is functional again.

Not that big of a deal, as I'm not decreasing font size by much, so I will just disable that setting.

@usernamehw
Copy link
Owner

usernamehw commented May 18, 2025

I think errorLens.fontSize setting already has that warning:

"errorLens.fontSize": {
"type": "string",
"default": "",
"markdownDescription": "Font size of inline message ([CSS units](https://developer.mozilla.org/en-US/docs/Web/CSS/length)). Use negative value to have it relative to the editor's fontSize (e.g. `-3px`). May break `#errorLens.alignMessage#`. [demo](https://github.com/usernamehw/vscode-error-lens/blob/master/docs/docs.md#errorlensfontsize)."
},


No VSCode api to align message, so the decoration is using margin: ${...}ch.

@lrstanley
Copy link
Author

lrstanley commented May 18, 2025

Unless I'm misunderstanding, couldn't you use editor.fontSize to do the calculation, and avoid ch when actually creating the alignment? You'd still be able to translate ch -> editor.fontSize, so you could let users provide something in ch while not actually using it for the style that applies the alignment.

Example for when using left alignment -- noting that 1ch == editor.fontSize:

  • editor.fontSize == 14px
  • errorLens.margin == 4ch == 4*14 == 56
  • line-length is 50 chars == 50*14 == 700

Results in a left alignment padding of: 700 + 56 == margin: 756px. I assume this would currently just be calculated as 50 (line-length) + 4 (margin) == margin: 54ch left alignment padding.

This alternative approach means it's not trying to use ch for potentially 2 different font sizes.

@usernamehw
Copy link
Owner

usernamehw commented May 19, 2025

You are welcome to make a Pull Request.

Alignment logic is:

export function getStyleForAlignment({

Getting font size setting value:

const editorFontSize = workspace.getConfiguration('editor').get<number>('fontSize')! || 14;

@usernamehw
Copy link
Owner

usernamehw commented May 20, 2025

I just don't know if it works like that:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div class="box one">
    1
  </div>
  <div class="box two">
    2
  </div>
</body>
</html>
body {
  font-size: 10px;
  font-family: Menlo, Monaco, Consolas, 'Courier New', monospace;
}

.box {
  border: 1px solid gray;
}

.one {
  margin-left: 10ch;
}

.two {
  margin-left: calc(10 * 10px);
}

Image

  • First box margin is 54.980px
  • Second box margin is 100px

@lrstanley
Copy link
Author

Hmm, looks like your right, it takes other things into account behind the scenes. And it ofc looks like VSCode doesn't support any other way of doing that calculation right now (ref: microsoft/vscode#118994).

I was messing around, trying to find ways of making margin use a unit of the parent, and doesn't look like there is any option today to do that with ch. However, this does seem to work. Seems like 0.55rem is a magic number that works for me, regardless of error lens font size, editor font size, multiple monospace fonts, and worked in both VSCode and Cursor. It gets extremely close for 8byte unicode (off by about 1ch over a span of 80 line-width, with 12*8byte characters), but that's not going to be as common. It is still off for non-monospace fonts, but that's to be expected.

Might not be a solid enough solution, but just in case it's something you wanted to look at further:

diff --git a/src/decorations/align.ts b/src/decorations/align.ts
index fa347c8..31a1d89 100644
--- a/src/decorations/align.ts
+++ b/src/decorations/align.ts
@@ -88,7 +88,7 @@ export function getStyleForAlignment({
                        textLine.range.start.line,
                        textLine.range.end.character,
                );
-               styleStr = `margin:0 0 0 ${marginChar >= 0 ? marginChar : 0}ch;padding:${padding[0]}ch ${padding[1]}ch`;
+               styleStr = `margin:0 0 0 calc(${marginChar >= 0 ? marginChar : 0} * 0.55rem);padding:${padding[0]}ch ${padding[1]}ch`;
        }
 
        return {

Essentially 10ch -> calc(10 * 0.55rem)

Haven't tried it on a web version of vscode to see if it still works the same. Not sure if rem is the same in that context, but I'd think so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants