mu icon indicating copy to clipboard operation
mu copied to clipboard

[mu4e rfe] `mu4e-maildir-shortcuts' :key support string (or support without key)

Open llmII opened this issue 3 years ago • 6 comments

Is your feature request related to a problem? Please describe. I used to be a user of the mu4e-maildirs extension thing. It would list all maildirs. I am trying to use mu4e with it's builtin support for such somewhat now, and I've ran into an issue. I'll describe sort of why it is like that and then explain what I am wanting to do.

Lets say my email address is [email protected] and I run my own email server. Let's say I sign up for facebook. Since I own my email server I actually create an alias to [email protected] that is [email protected]. Now imagine I do this for every place I sign up. Now imagine I have a sieve script that recognizes "hey, this isn't to the main mail address" and takes the user part and automatically creates a folder for that place (now I've got my INBOX, and a facebook folder, and a github folder, and a google folder, and and and...).

So, I would like to list all these folders in the mu4e main view... but I have over 26 folders (we're going to pretend it won't let us use anything but alphabetic keycodes for purpose of the example). I write a bit of code to iterate over all folders each time mu4e finishes processing a mu response and generate an entry in `mu4e-maildir-shortcuts'. Lets say I have folders a maximum of 3 levels deep. Let's also say I have 2 email accounts, say another that is [email protected]. I define them in mbsync as llmII and gmail so they look like "$maildirroot/{llmII,gmail}/*". When I generate the shortcuts, I'd like for the idea was to take the first letter of the maildir root for the account ('l' or 'g'), then for the folder ('g' for github, 'f' for facebook) with a fallback of "try next character in second or 3rd part of path, until fail, then random assign).

Currently I can't do this, I'll have to pick and choose and somewhere I'll lose out on a mailbox I'd like to watch at least for unread/count purposes.

Describe the solution you'd like I'd like to have `mu4e-maildir-shortcuts' either have ":key" optional or support using a string of keys.

llmII avatar Aug 24 '21 13:08 llmII

This is a dup of #2010; that one has a bit of discussion on how to implement this outside mu4e.

djcb avatar Aug 24 '21 20:08 djcb

Not a duplicate. #2010 one has a discussion on how to implement a jump table for easy shortcut access sure.

I'm less worried about accessing it as a shortcut and more worried about having it displayed in the main view with unread/count status.

llmII avatar Aug 24 '21 21:08 llmII

That's true, but the short-key part is probably the doable part of this.

djcb avatar Aug 24 '21 21:08 djcb

I'd have to look at the code when I get home but the entire reason for "more keys" is simply to display more maildirs. The key is the display, not the key combos. The other way is to not necessitate key combos at all, make it optional, and then any amount of maildirs could be displayed in the main view. Either way, the entire point is display, the how to get there part is flexible. The idea for keys in #2010 is a great idea if you just need more shortcuts but that is not the aim at all. That all said there may be other ways to achieve the display part besides my 2 immediate ideas on how to go about it.

llmII avatar Aug 24 '21 21:08 llmII

It would appear if :key is set to ?o all is fine, it'll still do the same selection process o is supposed to do. So supposedly I could just set all the keys to 'o' and tolerate the long listing of jumpables that aren't actually jumpable. Not sure if it's worth it to anyone to have it displayed correctly as far as jumpability goes, or the Maildirs listing (keep it from showing "jo" as a key sequence for all those maildirs).

That said, if non-unique keys is a bug, were it ever to get fixed I'd be back up the creek having to figure out a good way to go about this.

I see 2 ways to handle the 2 issues I noted (display, jumpability):

  1. Redefine mu4e~main-maildirs to take care of not displaying a key sequence
  2. Rebinding the binding for mu4e~headers-jump-to-maildir binding to another function (a hydra) that can read the maildir shortcuts itself and generate an actual list of things with keys, and finally an 'o' option for other, with a check for uniqueness, along with a refusal to allow the binding of 'o' to be mapped into the hydra. (All this and maybe it would make better sense to just redo mu4e~headers-jump-to-maildir to be honest.)

The reason a key must be defined is because of the concat operations here in mu4e-main.el. Probably not difficult to have key be either key or a string with one space in it " ".

As for maildir selection, looking at mu4e-utils.el mlist just needs to be built to not include ones without :key or the mapconcat lambda needs to just return an empty string for anything not having a :key. I'm not sure which approach will work (or maybe both will work, in which case the latter I think would work better) due to my lack of expertise in elisp.

llmII avatar Aug 25 '21 13:08 llmII

For reference, reimplemented the functions like so.

  (defun mu4e~main-maildirs ()
    "Return a string of maildirs with their counts."
    (cl-loop with mds = (mu4e~maildirs-with-query)
             with longest = (mu4e~longest-of-maildirs-and-bookmarks)
             with queries = (plist-get mu4e~server-props :queries)
             for m in mds
             for key = (if (plist-get m :key)
                           (string (plist-get m :key))
                         " ")
             for name = (plist-get m :name)
             for query = (plist-get m :query)
             for qcounts = (and (stringp query)
                                (cl-loop for q in queries
                                         when (string=
                                               (decode-coding-string
                                                (plist-get q :query)
                                                'utf-8 t)
                                               query)
                                         collect q))
             for unread = (and qcounts (plist-get (car qcounts) :unread))
             when (not (plist-get m :hide))
             when (not (and mu4e-main-hide-fully-read (eq unread 0)))
             concat (concat
                     ;; menu entry
                     (mu4e~main-action-str
                      (concat "\t* [j" key "] " name)
                      (concat "j" key))
                     ;; append all/unread numbers, if available.
                     (if qcounts
                         (let ((unread (plist-get (car qcounts) :unread))
                               (count  (plist-get (car qcounts) :count)))
                           (format
                            "%s (%s/%s)"
                            (make-string (- longest (string-width name)) ? )
                            (propertize (number-to-string unread)
                                        'face 'mu4e-header-key-face)
                            count))
                       "")
                     "\n")))

    (defun mu4e-ask-maildir (prompt)
      "Ask the user for a shortcut (using PROMPT) as per
(mu4e-maildir-shortcuts), then return the corresponding folder
name. If the special shortcut 'o' (for _o_ther) is used, or if
`(mu4e-maildir-shortcuts)' evaluates to nil, let user choose from
all maildirs under `mu4e-maildir'."
      (let ((prompt (mu4e-format "%s" prompt)))
        (if (not (mu4e-maildir-shortcuts))
            (substring-no-properties
             (funcall mu4e-completing-read-function prompt (mu4e-get-maildirs)))
          (let* ((mlist
                  (append (remove nil (mapcar (lambda (item)
                                        (when (plist-get item :key)
                                          item))
                                              mu4e-maildir-shortcuts))
                          '((:maildir "ther" :key ?o))))
                 (fnames
                  (mapconcat
                   (lambda (item)
                         (concat
                          "["
                          (propertize (make-string 1 (plist-get item :key))
                                      'face 'mu4e-highlight-face)
                          "]"
                          (plist-get item :maildir)))
                   mlist ", "))
                 (kar (read-char (concat prompt fnames))))
            (if (member kar '(?/ ?o)) ;; user chose 'other'?
                (substring-no-properties
                 (funcall mu4e-completing-read-function prompt
                          (mu4e-get-maildirs) nil nil "/"))
              (or (plist-get
                   (cl-find-if (lambda (item) (= kar (plist-get item :key)))
                               (mu4e-maildir-shortcuts)) :maildir)
                  (mu4e-warn "Unknown shortcut '%c'" kar)))))))

Changes are made against version 1.6.3.

llmII avatar Aug 25 '21 14:08 llmII

I've tried allowing keyless maildirs/bookmarks but I don't like it, so I have to decline this, sorry... If even all alphanumeric keys are not enough, note that they don't need to be unique (as you mention).

I might add a "transient" where longer keybindings would be possible, but I'm keeping the existing setup as-is.

(and of course you can use your own hydra or whatever).

djcb avatar Jan 18 '23 22:01 djcb