minad / org-modern

:unicorn: Modern Org Style
GNU General Public License v3.0
1.54k stars 48 forks source link

Variable line spacing #171

Closed psionic-k closed 9 months ago

psionic-k commented 9 months ago

This PR is not high quality. There is one feature per commit. Commit notes contain reasoning.

minad commented 9 months ago

This PR is not high quality.

Thanks. Could you please at least show me some before and after screenshots, which highlight and explain the motivation for this addition.? ;)

I have reservations against additions which change properties, beyond the ones we already use (wrap-prefix, line-prefix, display, invisible), since this will lead to maintenance problems.

In particular I don't want to adjust default-text-properties. Emacs upstream should instead acquire additional buffer local variables for text alignment, line height and base line adjustment. See also https://github.com/minad/corfu/issues/329.

psionic-k commented 9 months ago

Emacs upstream should instead acquire additional buffer local variables for text alignment, line height and base line adjustment

This is good to know.

image

  (setopt org-modern-line-height 1.5)
  (setopt org-modern-line-spacing 0.5)
  (setopt org-modern-headline-line-height 1.5)
  (setopt org-modern-headline-line-spacing 0.5)
  (setopt org-modern-block-line-height 1.0)
  (setopt org-modern-block-line-spacing 0.0)

My primary motivation was to have extra space around headlines. Especially when using large faces, the extra space makes headlines flow better with paragraph blank lines and reduces the appearance of being just raw markup.

The second goal was to have general line spacing. Line spacing can make reading easier, but it hurts when reading code, so I needed to take away added space for code blocks. Unfortunately in Emacs 29.2, setting the buffer's line-spacing behavior cannot be overridden by the property managed by font lock. This is why I was forced into modifying default-text-properties, to have a baseline I could remove.

I think the headline spacing is much more ready and is very helpful because of how it reduces the dilemma to include hard blank lines or not. While I extended org-modern because I knew it had the font locking boilerplate in place, I think headline spacing is consistent with org modern's feature set, to hide the rough edges of the markup.

Maybe adjusting space between paragraphs could be useful as well. This could be done by font locking blank empty lines to be slightly shorter or taller.

I have reservations against additions which change properties, beyond the ones we already use (wrap-prefix, line-prefix, display, invisible), since this will lead to maintenance problems.

This is a virtue worthy of pursuing. The implementation in this case cannot be done without bringing line-spacing and line-height under management. Incorporating line-spacing alone doesn't provide flexibility to add space above headlines. In the case of headlines, I don't see much likelihood of the Emacs behavior changing.

One other option is overlays, but they will almost assuredly not play well with folding. I have to upstream something to Org so that headlines don't receive paragraph spacing when folded.

minad commented 9 months ago

Thanks. I see. As a naive solution, why not add true newlines after and before headlines? This is what I am using to also get readable markup if prettification is not enabled, at least in buffers which are not just todo lists of headings. Furthermore I use a small value 0.2 for line-spacing in all buffers. This works well in all text and prog buffers.

I don't want to modify default-text-properties here since this will be too intrusive. Regarding styling other elements with line-spacing and line-height - which elements would require such a treatment and could we enable this in general? For headlines folding is a problem, since we probably only want to have the spacing for unfolded headlines. So this seems to require further workarounds?

psionic-k commented 9 months ago

For headlines folding is a problem, since we probably only want to have the spacing for unfolded headlines. So this seems to require further workarounds?

The outline is much more compact than content. Why do we need to compact the folded outline? While this is my opinion, folded headlines without spacing are too dense.

I did look into matching the ellipses. It works in the case of org fold core using text properties. For overlays, it does not, and I don't know a workaround that would be durable if org fold core changes how it does overlays and cleanup after buffer changes.

at least in buffers which are not just todo lists of headings

This can be matched accurately.

As an aside, when using these large headline faces, the TODO and tags are no longer vertically centered. It looks like I needed to modify an org-modern function, but I haven't attempted to read it yet.

why not add true newlines after and before headlines?

There was once a belief that the client should control display and that documents should strive to have a regular structure. Adding extraneous content to control display interferes with clients.

As an example case, I was asked to remove hard indentation from the transient showcase. Extraneous contents that existed to serve my opinion interfered with org-indent-mode.

We should converge on a world where extraneous newlines are also abolished. I have begun removing this opinion-driven extraneous content already. This philosophy maximizes the control of the client, and users who want space or want different space are all equally served. The same is true for hard paragraph filling, which interferes with users who prefer variable pitch faces.

Now that I have made the change, I enjoy never having to fiddle with this extraneous information. The consistency is automatic, and I can't forget which rule I'm using in which document.

psionic-k commented 9 months ago

I need to correct one statement. In Emacs 29.2 and Org master, folding a headline with body text that differs in the spacing property will result in that headline receiving the body's property. I think I mentioned this. I'm going to try to fix this in org because we can use the headline's newline instead of the body's headline.

Actually, according to Yantar, this is fixed in master.

minad commented 9 months ago

There was once a belief that the client should control display and that documents should strive to have a regular structure. Adding extraneous content to control display interferes with clients.

We should converge on a world where extraneous newlines are also abolished. I have begun removing this opinion-driven extraneous content already. This philosophy maximizes the control of the client, and users who want space or want different space are all equally served. The same is true for hard paragraph filling, which interferes with users who prefer variable pitch faces.

I understand why you want this and see that it is a good idea. However these goals are not necessarily aligned with org-modern, which does not attempt to change the way people write Org files. It tries nothing else than prettifying existing syntax and ideally the files are well readable both with and without org-modern.

My suggestion would be to create a separate line-spacing-mode package which can be enabled independently of org-modern, and which could even work in more modes. Other text modes, programming modes, ...

As an aside, when using these large headline faces, the TODO and tags are no longer vertically centered. It looks like I needed to modify an org-modern function, but I haven't attempted to read it yet.

This is what worries me. As I wrote before, I don't want to introduce new features here which create difficulties, interaction issues with existing features or bugs. In particular modifying additional text properties like line-height and line-spacing opens the door for many more interaction issues. Right now org-modern is in a relatively robust state with only few known problems (interaction with org-indent-mode and the lack of pixel-precise table alignment) and I intend to keep it that way. This matters since org-modern-mode is widely used.

Therefore I reject this PR for now. I may revisit this in the future, but my hope is that you agree with me that a separate package is a better solution, at least in the early stage. Such a line-spacing-mode makes it possible to apply context-dependent line-spacing and installs its own separate font lock rules. It could be generic and configured as follows, maybe also with mode-dependent rules.

(defvar line-spacing-rules
  '(("^*+ " :line-spacing 0.5 :line-height 1.5 :mode org-mode)
    ("^#\\+" :line-spacing 0.2 :line-height 1.2 :mode org-mode)
    ("\n\n" :line-spacing 0 :line-height 0.5)))

Furthermore it would be great if we end up with more settings in Emacs upstream which allow for better text alignment. If someone works on this, it would be much appreciated.

psionic-k commented 9 months ago

I disagree with creating an independent package. I don't really want to work on line spacing in every buffer. I also do want to fix the TODO's and tags and consider this an org modern bug. These things are coupled, and it will turn into a situation where people always need the two packages, so there might as well be just one. Turning the feature off is what customize is for.