Skip to content

* TODO Display checkbox progress (as virtual text) [2/4] #745

Open
@haikyuu

Description

@haikyuu

Does this feature exist in Emacs orgmode core?

Yes

Orgmode link

https://orgmode.org/manual/Checkboxes.html

Feature value

No response

Additional context

* TODO big task with checkboxes [3/3]
  - [x] Is part of org mode
  - [x] is very useful
  - [x] Should not be hard to implement 

Activity

seflue

seflue commented on Jun 5, 2024

@seflue
Contributor

The feature exist and works. What currently is not working are the cookies for subsequent TODO headlines: #305 . Normal checkboxes just work. But you need to use org_meta_return to update them. And updating the cookie from the headline is also not implemented (but somewhere down on my list).

PriceHiller

PriceHiller commented on May 22, 2025

@PriceHiller
Contributor

I've managed to implement this in my own configuration because I wanted live updates to my cookies. I had to go entirely with virtual text because there's really annoying issues with updating the actual underlying cookie text (I'll get to that).

You can see my implementation in my config here.

Thus far it seems fairly robust and performant, I've largely hammered down most of the bugs from what I've found.

Do note this only supports headline cookies currently, list items cookies took a bit of a backseat (though with the implementation I have it actually isn't too hard to support them with a little bit of refactoring).

If you want to use it, just create a after/plugin/orgcookie.lua file and paste it in there.

Demo

Here's a demo for those who just want to see it in action:

org-cookie-demo.webm

Features

  • Supports both % and / cookies
  • Live updating without needing a keybind to set TODO states, so you can just modify the text like a normal buffer and the virtual cookie should update accordingly (let me know if not)
  • Shows a [???] when we have a cookie but with no items to calculate on (maybe not a feature?)

Highlights

  • @org.cookie.delimiter: The highlight to use for the delimiters (brackets: [ & ])
    • @org.cookie.delimiter.left: A more granular highlight for just the left [ bracket
    • @org.cookie.delimiter.right: A more granular highlight for just the right ] bracket
  • @org.cookie.num: The numbers used in the cookie (50)
    • org.cookie.num.complete: A more granular highlight for the left side of [1/5] (in this case the 1)
    • org.cookie.num.total: A more granular highlight for the right side of [1/5] (in this case the 5)
  • @org.cookie.sign: The sign used in the cookie (e.g. /, %, or ???)
    • @org.cookie.sign.unknown: More granular if there wasn't items to calculate on (???) and you want a different highlight for the unknown sign
    • @org.cookie.sign.div: More granular for the div sign, the / in [1/5]
    • @org.cookie.sign.percent: More granular for the percent sign, the % in [100%]

Caveats

  • Only supports headline cookies, so it doesn't currently support list item cookies, e.g:
    - [ ] Item one [0%]
      - [ ] item
      - [ ] item
    
  • Uses conceal to allow users to modify the cookie, does not hide the virtual cookie when a cursor is on the same line (less of a caveat, more of a preference thing).
    • This is why you see a second cookie pop up on the right of the virtual cookie in the demo when my cursor goes over a headline
  • Since we're using live updates, if you choose not to go through the keybind to toggle status of an item the actual underlying cookie text that the virtual text is concealing may not get updated
    • I tried to not use virtual text at first, but it mangles the undo list pretty badly and requires nasty workarounds for the timing of events. I previously had an entire queue system with a timer for allowing updates at certain intervals so we didn't retrigger an update on the current cookie text being updated. Super messy. Virtual text is much better here.
  • Does not use a decoration provider, you can see a comment in the code as to why (though a decoration provider could be implemented with a little extra work I suppose — it's been performant as is for me though)

Upstreaming

If y'all (maintainers of nvim-orgmode) want this upstreamed, let me know. I'm happy to put in a bit more work in a few days to get this integrated. It may not one-to-one match with Orgmode proper though.

kristijanhusak

kristijanhusak commented on May 27, 2025

@kristijanhusak
Member

@PriceHiller I'd like to upstream this as an opt-in option. Not sure how much that complicates things though.
By default, I'd have it as it is now, and allow user to set something like ui.checkboxes.use_virtual_text = true to use the virtual text. Let me know if that sounds feasible.

PriceHiller

PriceHiller commented on May 27, 2025

@PriceHiller
Contributor

@kristijanhusak I actually have some good news, I did manage to implement updating the underlying text using nvim_buf_set_text along with vim.hl.range for the cookie highlights.

There's two small issues with it though (not deal breakers at all):

  1. Using nvim_buf_set_text causes some marks to get updated which specifically effects undo. When issuing undo/redo the cursor jumps up to the headline with the cursor if it was modifed during that undo state in a cookie update.
  2. If you try to delete only one of the numbers in the cookie (like using x or s with your cursor on the 6 in [6/7]), the cookie will auto update and put the 6 back in place. To remove a cookie you have to do diW or any operation that deletes either one or both of the brackets or deletes the slash (/) or percent (%) signs.

Other than that, it has worked really well for me. If you'd like to mess with it, the updated code is here. Just toss it into a Neovim plugin directory on the runtimepath (e.g. after/plugin/orgcookie/init.lua).

Would you prefer the one that updates the underyling text (the "new" approach) or the entirely virtual text approach (the "old" approach)?

Once I know, I'll get to upstreaming this no later than Sunday most likely (as my schedule permits). Everything there sounds feasible.

kristijanhusak

kristijanhusak commented on May 27, 2025

@kristijanhusak
Member

@PriceHiller I'd prefer the "old" approach with virtual text. I'd like to avoid updating the buffer content with the watcher.

added a commit that references this issue on Jun 2, 2025
linked a pull request that will close this issue on Jun 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @seflue@kristijanhusak@haikyuu@PriceHiller

      Issue actions

        * TODO Display checkbox progress (as virtual text) [2/4] · Issue #745 · nvim-orgmode/orgmode