rougier / mu4e-dashboard

A dashboard for mu4e (mu for emacs)
GNU General Public License v3.0
467 stars 43 forks source link

Counts without format #42

Open agenbite opened 2 years ago

agenbite commented 2 years ago

I want to get as close as possible to links like "Inbox: N/M", where N is the unread and M the total. I'm thus not interested in formatting, since I want each number to occupy as much space as needed.

I've tried removing the format string (with and without a spare |), and I've also tried to use %d as a format string. However, it doesn't seem to work, either the whole file fails ("format: Wrong type argument: wholenump, -1") or the numbers are not updated. I only get the actual counts if I use a proper format string and if the link name is filled up with as many characters as indicated by the format string.

Is there a way to get counts without formatting?

rougier commented 2 years ago

The Problem is that we modify the dashboard in place and this can mess up the parsing if we make the field "bigger". But now I realize we could take advantage of the display property such as to not modify the file, which is a better option anyway. What do you think?

agenbite commented 2 years ago

That sounds promising. I was working towards something like that in my notmuch version.

agenbite commented 2 years ago

However I'm not entirely sure what you mean by "the display property". I'm computing lengths before and after the change and moving the point accordingly. Is there a better way?

rougier commented 2 years ago

You can add a 'display property to a string such that it will displayed a different text than the actual content of the buffer:

(insert (propertize "hello" 'display "world"))
agenbite commented 2 years ago

Oh, wow. I didn't know about that and I was pursuing a seemingly more complex line (and I am actually stuck). Maybe with this property things could be easier... Hmmm...

rougier commented 2 years ago

It'll definitely make your life easier because the content of the buffer is not changed.

agenbite commented 2 years ago

I see! I'll chew on it and see where it takes me! Thanks! :)

agenbite commented 2 years ago

I'm not having much luck with the display property (I suspect I need some tweaking to use it inside links: it's as if the link display property overrides it).

However, I did have some fun with regexp and came up with this way to replace the description of all notmuch links with a computed message count:

(defun notmuch-dashboard-query-counts (query)
  "Get the number of unread and total messages for query QUERY.

Both numbers are returned as a string \"X/Y\", where X is the
number of unread messages and Y the total number of messages in
query QUERY."
  (let* ((nomsgs (notmuch-search-count query))
         (nomsgs (string-to-number nomsgs))
         (nonewmsgs (notmuch-search-count (concat query " and tag:unread")))
         (nonewmsgs (string-to-number nonewmsgs)))
    (format "%d/%d" nonewmsgs nomsgs)))

(defun notmuch-dashboard-update-counts ()
  "Get unread and total message counts for all notmuch links with empty
format specification.

Links must be of the form
[[notmuch:query|][description]] (note the '|'). The function replaces the
description of each link with the corresponding unread/total count."
  (interactive)
  (goto-char (point-min))
  (while (re-search-forward
          "\\(?:\\(\\[\\[notmuch:\\([^]|]+\\)|\\]\\[\\(.*\\)]]\\)\\(?:: [0-9]+/[0-9]+\\)*\\)" nil t)
    (replace-match (notmuch-dashboard-query-counts (match-string 2)) t nil nil 3)))

It is a pity not using the org element tree, but the fact that the description is not amongst the properties of a link makes it easier to just regexp-replace it. This approach works for me since I'm not that interested in fixed width, but I guess it'd be easy to add format on top. :)