mu icon indicating copy to clipboard operation
mu copied to clipboard

[mu4e rfe] Enable users to add more completion-at-point functions to `mu4e-search-read-query`

Open meliache opened this issue 3 years ago • 0 comments

Is your feature request related to a problem? Please describe. I'm using the mu4e-query-fragments which allows me to define fragments like %software which I can use in mu4e-search-read-query. However, there's no completion for those fragments, so I decided to try to write my own completion-at-point function ("capf") for that. That itself was easy, but I couldn't find an easy way to add this completion function, because mu4e-search-read-query is overriding completion-at-point-functions locally via

	(setq-local completion-at-point-functions
		    #'mu4e--search-query-completion-at-point)

So to add further completion-at-point functions, the user needs to either override mu4e--search-query-completion-at-point, which is a private function, or needs to redefine mu4e-search-read-query, which is what I did.

Describe the solution you'd like

I'd prefer a customizable public hook of capfs that the user can add functions to via add-hook, e.g.

  (defcustom mu4e-search-query-capfs nil
    "Completion-at-point functions for mu4e search queries."
    :group 'mu4e
    :type 'hook)
    
  ;; we initialize the hook to `nil' and then add the default value via
  ;; `add-hook' instead of initializing it with the default value so that when
  ;; the user adds his own capfs via `add-hook' before the package is
  ;; loaded, the default is not overridden
  (add-hook 'mu4e-search-query-capfs #'mu4e--search-query-completion-at-point)
  
  (defun mu4e-search-read-query (prompt &optional initial-input)
    "Read a query with completion using PROMPT and INITIAL-INPUT."
    (minibuffer-with-setup-hook
        (lambda ()
	      (setq-local completion-at-point-functions my-mu4e-search-query-capfs)
	      (use-local-map mu4e-minibuffer-search-query-map))
      (read-string prompt initial-input 'mu4e--search-hist)))

Describe alternatives you've considered

I first thought that instead of setq-local, I could just call (add-hook ... 'local) to only add local capfs instead of overriding the variable completely, since the mu4e search query is so specific that it's unlikely that other capfs would make any sense in this context.

Alternatively we could also just make mu4e-search-query-completion-at-point public, then the user could use advices to e.g. override it without fearing his advice breaking in the future.

Of course, I can't think of many users-cases of people wanting to add their own completion to that function.

Additional context

Following this I'll think about opening a PR or issue for adding completions to mu4e-query-fragments. In case anybody is interested, the first draft of my completion function (my first ever) looks like the following:

  (defun my-mu4e-query-fragments-complete ()
    (let ((bounds (bounds-of-thing-at-point 'symbol)))
      (when (and bounds
                 (char-equal (char-after (car bounds)) '?%))
        (list
         (car bounds)
         (cdr bounds)
         (completion-table-dynamic
          (lambda (_)
            (mapcar #'car mu4e-query-fragments-list)))
         :exclusive 'no))))

meliache avatar Jul 28 '22 16:07 meliache