rougier / mu4e-dashboard

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

Unable to use ] in queries #47

Open dmgerman opened 1 year ago

dmgerman commented 1 year ago

Is there a way to escape ] in the name of a mailbox?

dmgerman commented 1 year ago

I have written code that would reuse bookmarks by name (based on #37).

But instead of adding a new attribute, it would simply reuse the query. The only challenge is that the name of the query cannot contain spaces (as the parsing of the query in the dashboard is very rudimentary).

Would you be interested in merging that code?

I guess there is still a need for a better parser for the queries.

rougier commented 1 year ago

Yes, I think some people would be interested. Can you post your code?

dmgerman commented 1 year ago

The idea is that if a mailbox uses bm, then the name is expanded (e.g. mu:bm:gmail7days)

First my code

#+begin_src emacs-lisp
(defun dmg-find-first (fn ls)
  (car (remove-if-not fn ls)))

(defun dmg-matching-bookmark (it field name)
  (equal (plist-get it field) name))

(defun dmg-get-bookmark (name)
  (dmg-find-first (lambda (a) (dmg-matching-bookmark a :name name)) mu4e-bookmarks))

(defun mu4e-dashboard-expand-bm (q)
  (let* ((bookmark-re "bm:\\(.+\\)$")
         (match (string-match bookmark-re q))
         (nickname (match-string 1 q))
         (bms mu4e-bookmarks )
         (bookmark (if nickname (dmg-get-bookmark nickname) nil))
         (expansion (if bookmark (plist-get bookmark :query) ))  )
    (if expansion  
        (replace-regexp-in-string bookmark-re expansion  q)
      q)))
#+end_src

then the code I had to extract from mu4e-dashboard.el to add a call to mu4e-dashboard-expand-bm:

#+begin_src emacs-lisp
(defun mu4e-dashboard-follow-mu4e-link (path)
  "Process a mu4e link with path PATH.

PATH shall be of the form [[mu4e:query|fmt|limit][(---------)]].
If FMT is not specified or is nil, clicking on the link calls
mu4e with the specified QUERY (with or without the given
LIMIT).  If FMT is specified, the description of the link is
updated with the QUERY count formatted using the provided
format (for example \"%4d\")."

  (let* ((link    (org-element-context))
         (queryname   (string-trim (nth 0 (split-string path "[]|]"))))
         (query   (mu4e-dashboard-expand-bm queryname))
         (fmt     (nth 1 (split-string path "[]|]")))
         (count   (nth 2 (split-string path "[]|]"))))
    (message query)
    (cond
     ;; Regular query without limit
     ((and (not fmt) (not count))
      (progn
        (if (get-buffer-window "*mu4e-headers*" t)
            (switch-to-buffer"*mu4e-headers*"))
        (mu4e-headers-search query)))

     ;; Regular query with limit
     ((and count (> (length count) 0))
      (progn
        (if (get-buffer-window "*mu4e-headers*" t)
            (switch-to-buffer"*mu4e-headers*"))
        (let ((mu4e-headers-results-limit (string-to-number count)))
          (mu4e-headers-search query))))

     ;; Query count and link description update
     ((and fmt (> (length fmt) 0))
       (mu4e-dashboard-update-link link)))))

(defun mu4e-dashboard-update-link (link)
  "Update content of a formatted mu4e LINK.

A formatted link is a link of the form
[[mu4e:query|limit|fmt][(---------)]] where fmt is a non nil
string describing the format.  When a link is cleared, the
description is replaced by a string for the form \"(---)\" and
have the same size as the current description. If the given
format is too big for the current description, description is
replaced with + signs."

  (let* ((path  (org-element-property :path link))
         (queryname (string-trim (nth 0 (split-string path "|"))))
         (query   (mu4e-dashboard-expand-bm queryname))
         (fmt   (nth 1 (split-string path "|")))
         (beg   (org-element-property :contents-begin link))
         (end   (org-element-property :contents-end link))
         (size  (- end beg)))
    (if (and fmt (> (length fmt) 0))
        (let* ((command (format "%s find %s 2> /dev/null | wc -l"
                                mu4e-dashboard-mu-program
                                (shell-quote-argument query)))
               (output (string-to-number (shell-command-to-string command)))
               (output  (format fmt output)))
          (message command)
          (let ((modified (buffer-modified-p))
                (inhibit-read-only t))
            (save-excursion
              (delete-region beg end)
              (goto-char beg)
              (insert (if (<= (length output) size) output
                        (make-string size ?+))))
            (set-buffer-modified-p modified))))))
#+end_src
rougier commented 1 year ago

Documentation for the two modified functions could be updated (to explain you can use mu4e bookmarks) but apart from that it looks good. Or we could also adapt the name to mu4e-dashboard-follow-mu4e-link-or-bookmark, what do you think?

dmgerman commented 1 year ago

Yes, I think a rename would work. I am traveling this week, but I can create a pull request early next week.

I am not sure if my dmg-matching-bookmark function is the best way to do it, though (I'll rename the functions to remove the dmg-from the prefix, or course).