pulsar-edit / pulsar

A Community-led Hyper-Hackable Text Editor
https://pulsar-edit.dev
Other
3.25k stars 136 forks source link

Line wrapping is wrong with proportional fonts. #657

Open matj1 opened 1 year ago

matj1 commented 1 year ago

Thanks in advance for your bug report!

What happened?

If I have Soft Wrap enabled, lines with narrow characters wrap too early, so there is empty space, and lines with wide characters wrap too late, so the text runs out of the view.

Pulsar version

1.107.1

Which OS does this happen on?

🐧 Arch based (Manjaro, Garuda, etc.)

OS details

Arch, GNOME 44.3

Which CPU architecture are you running this on?

64-bit(x86_64)

What steps are needed to reproduce this?

  1. Use a proportional font in the editor.
  2. Enable Soft Wrap.
  3. Write some text with mostly wide characters (like M, W) so it softly wraps.
  4. Notice that the ends of visual lines are hidden.
  5. Write some text with mostly narrow characters (like i, l) so it softly wraps.
  6. Notice that there is unused space at the ends of visual lines.

Additional Information:

It seems that wrapping is based on counting characters in a line, which may be wrong because soft wrapping is supposed to fit the text to the window, and the width of characters is generally not known, so it can't be ensured that the text is fitted to the window.

In this example, the first line is wrapped with the last quarters of the visual lines unoccupied, and the second line is wrapped so the text at the end of every visual line (numbers 14, 15, 27, 28) is hidden: An example showing that some lines wrap too early and some too late

Spiker985 commented 1 year ago

Soft Wrapping wraps based on the Soft Wrap Character Count, which is by default 80

There may be a few different packages that are at play here

matj1 commented 1 year ago

Soft Wrapping wraps based on the Soft Wrap Character Count, which is by default 80

No; it is set to wrap at the edge of the window. If I resize the window, it still wraps wrongly, but at a different width.

savetheclocktower commented 1 year ago

I could be wrong, but I'd be surprised if this ever worked.

If I switch my editor to a proportional font, then basic keyboard-based cursor movement does not function the way you'd expect from a WYSIWYG editor like a word processor. When you move from one line to the next, the cursor doesn't move into the closest equivalent position between letters; it preserves the column from the previous row, even if this results in a major shift to the left or right.

I think there's a strong assumption built into Atom/Pulsar that the user is working with a monospace font, so I don't expect this to get fixed any time soon, if ever.

matj1 commented 1 year ago

I think there's a strong assumption built into Atom/Pulsar that the user is working with a monospace font, so I don't expect this to get fixed any time soon, if ever.

It bothers me that the assumption is not expressed anywhere officially as far as I know while it is a strong one. Working well with proportional fonts is a substantial feature of text editors for me. Pulsar looks like it would work well with proportional fonts, but it doesn't work.

savetheclocktower commented 1 year ago

I looked in the old Atom issues to see if anyone had reported this. I found this issue; it had a decent amount of activity, but no response from anyone official. I find this annoying as well; the Atom team was never the best about issue tracker hygiene.

The issue mentions a package called AtomicChar — apparently it worked at one point, but eventually stopped working. I looked into the source code and I'm not surprised. The way it works is to redefine a bunch of core methods, many of which were internal, so it was bound to break unless the author was very diligent about keeping it up to date.

@matj1, I don't know what you use Pulsar for, but I can say that most people seem to use it for writing code. There are a bunch of reasons why monospace fonts are preferred for writing code; some of them are substantive and some of them are just cultural.

  1. It's a good idea to enforce stylistic standards in coding projects, including line length. Since different contributors can be using different fonts in their editors, measuring line length by character count (rather than optically) is the only workable solution.

  2. Punctuation marks in programming languages are important, even moreso than in prose. If you're reading prose and you fail to notice a comma or a period, no big deal; but if you don't notice a period when you're reading code, you've probably misinterpreted the code's meaning. Monospace fonts make punctuation marks much easier to notice.

  3. Monospace fonts tend to draw sharper contrasts between characters that would ordinarily look very similar in a proportional font: I versus l, O versus 0.

  4. Some coders are very particular about alignment of related lines, on the theory that it aids readability:

    let path        = url.path;
    let queryString = url.queryString;

    You can’t do this sort of alignment with a proportional font.

  5. In general, there are a lot of code alignment strategies that assume that the width of a space character will be equivalent to the width of any other character. Even when tabs are used for indentation, they're usually defined (and rendered) as some multiple of the width of a space character. In proportional fonts, spaces tend to be much narrower than other characters, meaning that each level of indentation translates to a smaller amount of physical space. This can be anticipated and corrected for in an editor, but it takes intentional effort.

Obviously, there’s nothing about Pulsar that prevents you from writing prose. I routinely write prose in Pulsar, including this comment that you’re reading right now. If I want to see it in a proportional font, I can use the builtin markdown-preview package to show a preview — Ctrl + Shift + M is the default keybinding.

Ultimately, the answer to “Why doesn’t Pulsar support proportional fonts?” is that not enough people have requested it, and it would be a large amount of work to make it behave otherwise. @confused-Techie, I’d be in favor of an FAQ entry that answers this question, because @matj1 is right that there’s no mechanism in the editor that explicitly prevents you from using a proportional font, or warns you about the difficulties you might encounter.

confused-Techie commented 1 year ago

@savetheclocktower Thanks for giving me a ping, I'd be more than happy to add this to our FAQ section to ensure it has proper visibility.

Although I do want to ask, I wonder if it may be possible to try and support this? Like you mentioned many other features would break, and for those I am comfortable saying they will never be fixed, but for just wrapping text, I wonder if we could enable a service for wrapping, which could hopefully allow community packages easier access to the functionality, who could then try to implement something that works for only wrapping text. Might be an interesting idea, but obviously not an easy one.

But as you're most familiar between the two of us, if you feel it will likely never be done, then I'm more than happy to support that possibility and make sure that can be written up in our guide officially, and get this closed.

savetheclocktower commented 1 year ago

This class has most of the logic around deciding where a soft-wrap happens and how to convert between screen positions and buffer positions.

It'd be a lot of work even to expose an API that could substitute a package’s soft-wrapping logic for ours. And any substitute logic around soft-wrapping would have to work very hard to be performant, because it'd be a major bottleneck.

I wouldn’t dare say “no, this will never be supported,” but someone would have to care about it a lot to get it through the gauntlet. I think it's fine if anyone wants to take it on as their project — like if @mauricioszabo’s editor core rewrite ever happens — but it'd have to go pretty deep.

matj1 commented 1 year ago

@savetheclocktower

I prefer proportional fonts for coding because they are more readable. I think that using monospaced fonts for code is a relic and hinders code typography.

Points 2 and 3 are not specific to monospaced fonts; they apply to many proportional fonts. Examples are Recursive, Input Sans, iA Writer Quattro, even Verdana.

I usually write my code with my style, and that is compatible with proportional fonts. If I write code for someone else, I follow the else's rules, but, If I can, I do it my way.

There are other possible ways to limit line length, like that the preferred length is at most 80 characters, but 120 is the maximum allowed length. That is applicable with monospaced fonts too because there are lines slightly longer than 80 chars with no reasonable breaking point.

Alignment with proportional fonts is not possible with most text editors, but my attitude is to do it well or not at all. I would like that editors would implement some better alignment strategies like elastic tabstops.

matj1 commented 1 year ago

Anyway, how will this issue continue? Will it be closed as not fixable; will we wait until there is a warning against using proportional fonts and then close it; will it stay open until line breaking is redone?

savetheclocktower commented 1 year ago

I don't mind it staying open as long as it's clear that it may never get fixed. It would take a pretty large refactor to support this, but we're an open-source project and anything is possible.

We can create a separate issue for the task of making it clearer in the FAQ and in Pulsar itself.

confused-Techie commented 1 year ago

I was initially considering to keep this open until it's added to the FAQ then go ahead and close this one, since I'm never a huge fan of keeping issues around that we have to plans to address.

But if we'd rather keep it open by all means we can. But thanks @savetheclocktower for pointing out where the logic is for the softwrap. Honestly any logic that's bundled directly into the text-buffer is very prone to see very little if any change without huge refactors like you mentioned. So simply using the existing system while exposing an API, like you said would be a lot of work, borderline unfeasible.

savetheclocktower commented 1 year ago

But if we'd rather keep it open by all means we can.

No, we can do whatever is prudent for an issue in this situation — I just didn't want to be the one arguing for a ticket's closure when I'm unopposed to the feature being requested.