integral-dw / org-superstar-mode

Make org-mode stars a little more super
GNU General Public License v3.0
506 stars 22 forks source link

Advanced composition for headline and TODO bullets #9

Closed japhir closed 4 years ago

japhir commented 4 years ago

Thanks for the cool package!

I came up with some nice icons for my different TODO states

    (setq org-superstar-todo-bullet-alist '(("NEXT" . ?☐)
                                            ("WAIT" . ?⌛)
                                            ("SOME" . ?☁)
                                            ("DONE" . ?☑)
                                            ("CANC" . ?☒)

However, the font-width of these characters is slightly different. This means that the headlines look a little wonky. Any idea how to fix the width of the bullet icons somehow? 2020-03-26-20:25:05_region

integral-dw commented 4 years ago

Hi, I'm glad you find the package useful!

What you describe appears to be a feature of the font you are using. The most straightforward solution should be to rely on the way composition works in Emacs: You can use a string instead of a character, with the final result being a superposition of all characters in order. In other words, replacing ?⌛ with, say "<some wide space char>⌛" will embed the character in a wider range. This fix works only for graphical displays, however, and is currently not "officially" supported by the package. However, this is exactly how leading bullets are hacked to work for example, so the code is there. Expect official support for string values in the next patch!

Regarding terminal display: That's more difficult, as composing works differently. In that case, the best solution would be a fallback on "guaranteed fixed-width" characters.

integral-dw commented 4 years ago

You can expect the patch to be ready either this or next weekend. To elaborate what I will need to do for the sake of transparency: I got to..

integral-dw commented 4 years ago

Okay, so the way I see it, I would say a reasonable solution for establishing fallbacks would be extending possible values for org-superstar-todo-bullet-alist. That is, instead of just allowing elements of the form (KEYWORD . CHAR), I should also allow (KEYWORD BULLET FALLBACK), where BULLETshould be a string (or char), and FALLBACK the, well, fallback character to use in terminals. Sounds good?

integral-dw commented 4 years ago

You can try out the new feature on the volatile branch, if you want. With that version of Org Superstar loaded, you can widen normally too narrow bullets by providing an appropriate space to compose over, for example:

(setq org-superstar-todo-bullet-alist
      '(("TODO" " ․" ?.)
    ("DONE" . ?☑)))
(setq org-superstar-special-todo-items t)

Now, too narrow symbols are an easy fix. Too wide symbols, sadly not. That would either require choosing a different font size for them (usually making them the right width, but too small) or changing either the font used for that character / the character itself. Of course, one could allow the user to also mess with text properties for each bullet, but that adds a layer of complexity I am not sure is helpful, sadly.

integral-dw commented 4 years ago

I'm sorry for the delay migrating the patch to the main branch. Recent events left me a bit unfocused. I'll try my best to fix up the documentation soon.

EDIT: Just merged everything. If there's anything left to be desired tell me, I'll reopen the Issue!

japhir commented 4 years ago

Hey @integral-dw, no worries! Thanks so much for the fast implementation! Sorry for not testing the volatile branch, I've also been quite busy in these weird times :sweat_smile:.

With the newest version, after looking for icons that are not too wide, I was able to get it working with some quite nice glyphs!

(use-package org-superstar
  :hook
  (org-mode . (lambda () (org-superstar-mode 1)))
  :config
  (setq org-superstar-headline-bullets-list
        '("◉" "●" "○" "♦" "◆" "►" "▸"))
  (setq org-superstar-todo-bullet-alist '(("NEXT" " ☐" ?*)
                                          ("WAIT" " ☕" ?*)
                                          ("SOME" " ☼" ?*)
                                          ("DONE" " ☑" ?*)
                                          ("CANC" " ❌" ?*)))
  (setq org-superstar-special-todo-items t))

it appears that this would have also worked previously, if I'd have chosen these glyphs over the weird ones in my first post. I think I don't understand the syntax for widening certain glyphs fully. Are we basically setting a fallback option behind the ?? In that case, below also works in the terminal, since they are all very basic glyphs now. The space before the special symbol tells it to widen it somehow?

(use-package org-superstar
  :hook
  (org-mode . (lambda () (org-superstar-mode 1)))
  :config
  (setq org-superstar-headline-bullets-list
        '("◉" "●" "○" "♦" "◆" "►" "▸"))
  (setq org-superstar-todo-bullet-alist '(("NEXT" . ?☐)
                                          ("WAIT" . ?*)
                                          ("SOME" . ?☼)
                                          ("DONE" . ?☑)
                                          ("CANC" . ?❌)))
  (setq org-superstar-special-todo-items t))
integral-dw commented 4 years ago

Hello @japhir, you pretty much nailed it. The ? is necessary in elisp to specify a literal character, meaning "a" is a string (iirc a character array), while ?a is a literal character.

The space before the special symbol tells it to widen it somehow?

Yes. The real difference, as suggested by the docs, has something to do with the nitty gritty of Superstar's implementation, in particular the function compose-region from Emacs' composite.el, the same underlying code that makes prettify-symbols tick. Under normal circumstances, it is meant to provide facilites to construct complicated composite characters needed for example for Arabic typesetting, stacking accents and overstriking characters if needed. So, what strings like " ☐" actually do is to tell Emacs to draw the right character on top of the left character as if it were an accent, hence, if the right character (here: ) is thinner than a standard space, the drawn composite is as wide as a space regardless. The two are renderes "stacked" on top of each other. That is also why there is this needed fallback character: Emacs can't interact with the terminal's rendering, so trying to superimpose two characters fails. A single character just visually replaces what was initially there, which is a nice additional property of compose-region.

japhir commented 4 years ago

Oooh great! Thanks for the elaborate reply.

So that means I can compose the icons over the EM SPACE utf-8 symbol, which is wider, and this may allow me to choose some wider icons!

integral-dw commented 4 years ago

That, to my understanding, should work perfectly fine, yep!

japhir commented 4 years ago

Yep, it works very nicely! Except that some emoji appear even wider than the em-space. But for now it's fine.

EDIT: never mind the below, i had to call org-superstar-restart!

obsolete question Is there a way to add this compose-region setting also to the regular `org-superstar-headline-bullets-list` so that the bullets and beginning of text are aligned again? I tried setting it with: ``` (setq org-superstar-headline-bullets-list '((" ◉" ?◉) (" ●" ?●) (" ○" ?○) (" ♦" ?♦) (" ◆" ?◆) (" ►" ?►) (" ▸" ?▸))) ``` but this resets all bullets to the `*`.
integral-dw commented 4 years ago

That is (not yet) supported fully, I do believe however that

 (setq org-superstar-headline-bullets-list
          '(" ◉" " ●" " ○" " ♦" " ◆" " ►" " ▸"))

should work. I have not yet implemented a fallback for that in the API, however. But you've given me a reason to mull it over, especially since this feature is (for that reason) as of yet undocumented.

integral-dw commented 4 years ago

Huh? Alright. I will consider a more detailled fallback and advanced headline bullet support, however.

japhir commented 4 years ago

Ah, double my-bad. It's actually not working but I had accidentally been using regular spaces again, and then it does line up nicely with regular bullets.

japhir commented 4 years ago

I do believe however that[…]

Nope, this displays only a blank em-space and no bullet.

integral-dw commented 4 years ago

Yeah, I still have to get that bit of customization rolling, so it's again a game of

I'll schedule this for version v.1.3.0.

integral-dw commented 4 years ago

Short update: I have settled with a design choice regarding how I will extend the current bullet list. I will try to get things done this weekend.

integral-dw commented 4 years ago

Well, apart from my gruesomely bad estimation skills, the implementation went fairly well. Hey @japhir, I updated the volatile branch. Wanna try it out before I send it off? After some more testing and double checking I am fairly confident this works quite well. Please be sure to notify me should anything break, though.

ykhurshid commented 4 years ago

Not really a breakage of sorts but a feature request: a variable that will toggle hiding the actual keyword in place of the bullet replacement. I'm basically imagining org-mode turning into a convincing facimile of a Bullet Journal.

This feature already is a great step in that direction but I'm still stuck looking at hoards of keywords in place of clean bullets and boxes.

integral-dw commented 4 years ago

That is actually a good point I should most likely address in its own Issue, see #20.