bbdb-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Questions on completion


From: Basil L. Contovounesios
Subject: Re: Questions on completion
Date: Wed, 01 Nov 2017 11:22:10 +0000
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (gnu/linux)

On Tue, Oct 31 2017, at 22:19, Roland Winkler <address@hidden> wrote:

>> and advise bbdb-complete-mail to first pass the
>> candidates it offers through bbdb-mua-summary-unify.
>
> How does this go?  Is there a hook I overlooked?
>
> (bbdb-complete-mail is not the most userfriendly piece of
> code if you want to achieve something that is not yet
> implemented as an option.)

My hacky workaround attests to this (I don't use anything as
civilised as a hook :).  Mapping bbdb-mua-summary-unify over
the candidates is fairly simple - I just intercept the
arguments passed from bbdb-complete-mail to
display-completion-list.  What makes me jump through a few
more hoops is replacing the *Completions* buffer with my
preferred minibuffer completion (I tried switching to
in-buffer completion last night before realising the same
issue you describe later in your email).  I include a full
listing of the kludge after my signature for anyone curious.
Note that, for the reasons discussed below, the minibuffer
completion works best with fuzzy frontends.

>> The only missing aspect of this approach is offering
>> Latinised mail-names as completion candidates.
>
> This can be implemented:
>
> mail-name becomes another element of bbdb-completion-list.
> Then these mail names must be hashed in bbdb-hashtable so
> that they become available for completion.
>
> (Please give me some time.)

No rush on my end; thanks for considering this.  :) Perhaps
there will be little difference in supporting mail-name in
particular vs generalising to any xfield?

> The general problem I see is that bbdb-complete-mail (and
> likewise bbdb-completing-read-mails) is not performing
> ordinary completion.  In that sense, you could call these
> function names misnomers.  You can type "Joh" to get John
> Smith's email address in BBDB "address@hidden".  So what
> you type and what you get in the end can be very different
> stories.

Indeed; thanks for explaining this.  I didn't initially
realise this for two reasons: a) I hadn't yet tried to use
completion-in-region myself; and b) the frontends I mention
perform fuzzy completion by generating search regexps on the
fly, which obfuscates the distinction between ordinary
completion and my desired behaviour.

> I am not aware of other emacs functions providing such
> behavior, nor am I aware of other scenarios where such a
> behavior would be useful, nor do I know how such behavior
> could be combined with other completion frontends.  (I do
> not know anything about the frontends you mentioned.)

I am also not aware of any explicitly fuzzy built-in
completion methods, though foo-*-bar completion of Elisp
symbols is not too different.  The usefulness of the fuzzy
frontends I mention lies in their convenient generalisation
and presentation of matching any part of each completion
candidate like this.  I guess this is where "completion"
loses its meaning...

My understanding is that BBDB cannot currently do anything
strikingly different from what it is already offering, and
my desired behaviour is better suited as a BBDB extension to
the frontends I mention.  I will probably return to what
BBDB is doing in more detail in the future.  Thank you once
again for taking the time to explain everything!

-- 
Basil

(defun blc--bbdb-unify (&rest addresses)
  "Map `bbdb-mua-summary-unify' over ADDRESSES.
Return a list of addresses formatted as \"NAME\" <ADDRESS>."
  ;; Match leading mark or absence thereof
  (let ((mark (rx-to-string `(: bos (| (+ space)
                                       ,@(and bbdb-mua-summary-mark
                                              (list bbdb-mua-summary-mark))))
                            t)))
    (mapcar (lambda (addr)
              (format "\"%s\" <%s>"
                      ;; Unify but remove any marks
                      (replace-regexp-in-string
                       mark "" (bbdb-mua-summary-unify addr))
                      (car (mail-header-parse-address addr))))
            addresses)))

(defun blc--completion-base-string ()
  "Return string bound by `completion-base-position'."
  (buffer-substring-no-properties (car completion-base-position)
                                  (or (cadr completion-base-position)
                                      (point))))

(define-advice bbdb-complete-mail (:around (complete &rest args)
                                           blc-completing-read)
  "Replace *Completions* buffer with `completing-read'.
Feed candidates to `bbdb-mua-summary-unify' before completion."
  (let* (cands                             ; Interceptees for closure
         (alice #'display-completion-list) ; Victim
         (eve   (lambda (completions)      ; Interceptor closure
                  (setq cands (apply #'blc--bbdb-unify completions))))
         ;; Kill *Completions* buffer and use minibuffer instead
         (temp-buffer-show-function
          (lambda (buf)
            (kill-buffer buf)
            ;; This is best used with helm/ivy-like frontends
            (choose-completion-string (completing-read
                                       "Address: " cands nil 'confirm
                                       (blc--completion-base-string)
                                       'blc-bbdb-mail-history)
                                      (current-buffer)
                                      completion-base-position))))
    (unwind-protect
        (progn
          (advice-add alice :before eve)
          (apply complete args))
      (advice-remove alice eve))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]