unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Eric Abrahamsen <eric@ericabrahamsen.net>
To: emacs-devel@gnu.org
Subject: Re: [PATCH] EUDC email addresses via completion-at-point in message-mode
Date: Fri, 15 Apr 2022 15:57:18 -0700	[thread overview]
Message-ID: <87a6cmymy9.fsf@ericabrahamsen.net> (raw)
In-Reply-To: dc51ed8dcb5b1d44bf51859758d120ba@condition-alpha.com

Alexander Adolf <alexander.adolf@condition-alpha.com> writes:

> Hello Stefan,
>
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>> [...]
>> Maybe EUDC shouldn't be in charge of providing a CAPF function.
>
> I'd tend to disagree.
>
>> The CAPF function needs to understand the current document's syntax to
>> know where an email address is expected, but that part is completely
>> unrelated to EUDC itself (and related to the major mode instead).
>> [...]
>
> Fully agree.
>
> I think there may be a middle ground. I appreciate you seem to share the
> idea of following "separation of concerns", some also call it
> "one-thing-well mantra" (doe one thing only, do it well), as it
> typically helps keeping code simpler.
>
> A couple of thoughts on completion in message mode:
>
> ---------------------------- Begin Quote -----------------------------
> Variable: completion-at-point-functions
>
>      The value of this abnormal hook should be a list of functions,
>      which are used to compute a completion table (see Basic Completion)
>      for completing the text at point. It can be used by major modes to
>      provide mode-specific completion tables (see Major Mode
>      Conventions).
> ----------------------------- End Quote ------------------------------
>
> But I think there may be a "catch 22" here, though. If the major mode
> provides the completion table(s) itself, fine. But what about completion
> tables contributed by 3rd party packages? I don't think a major mode
> could, or should have an, inevitably incomplete, list of 3rd party
> packages to query for completion tables. IMO it would seem much more
> sensible to reverse responsibilities: any package that is capable of
> providing additional completion tables for certain major modes, should
> register itself with those modes (e.g. by adding itself to
> completion-at-point-functions).
>
> In message-mode (there may be others, too), the in-buffer completion
> will additionally need to figure out the context where completion is
> attempted, i.e. some function will need to be called to determine the
> semantic context of the stuff around point in order to choose one or
> more suitable functions for delivering completion candidates. For
> instance in a programming language buffer, do I need candidates for a
> function, or for a variable? For instance in a message buffer, do I need
> candidates for an email address, or text snippets for the message body?
>
> In the current architecture for completion-at-point, such checks for
> context have to be performed by the functions registered in
> completion-at-point-functions. This seems wasteful, as it means a lot of
> very similar code all over (possibly with subtly different bugs in each
> copy), and an unnecessary runtime burden as completion-at-point may be
> called often (for every keystroke in some situations).
>
> mail-mode and message-mode are sort of half way there by providing
> mail-complete-alist and message-completion-alist, respectively. Both
> variables allow for registering a _single_ function to be called for
> buffer lines matching a regex. This already takes the burden of figuring
> out the completion context away from the function being called, and
> together with the try-all-servers feature recently added to EUDC it
> would already suffice to aggregate email address candidates from more
> than one source in message-mode.
>
> A more generic mechanism could look like this:
>
> 1) Each 3rd party package that wants to provide general purpose
>    completion tables for a given major mode, adds a function to the
>    respective *-mode-hook that adds that package's completion function
>    to completion-at-point-functions (this is current good practice).
>
> 2) Each major mode that wants to allow users to have different
>    completion tables based on the context where the completion happens,
>    offers a *-mode-context-completion-functions-alist variable. The keys
>    in this alist should be symbols describing the completion context or
>    purpose (for example 'email, 'newsgroup, etc.). The values are
>    symbols representing abnormal hook variables. (This is where
>    mail-mode and message-mode are half way there.)
>
> 3) Users (or init code of 3rd party packages) call add-hook to add
>    completion functions to the values of entries in
>    *-mode-context-completion-functions-alist variable(s) as they deem
>    fit. These functions must be "cooperative" in the sense that they
>    should add ":exclusive 'no" to the completion table they return,
>    unless there is a particular reason for claiming exclusive completion
>    "rights".
>
> 4) Each major mode that wants to allow users to have different
>    completion tables based on the context where the completion happens,
>    does the following:
>
>     4.1) After all mode hooks have been run, sample the current value of
> 	 completion-at-point-functions, and store it in a variable.
>
>     4.2) Next, set completion-at-point-functions to a single function,
> 	 which is the mode's completion function.
>
>     4.3) When completion-at-point is called, and hence in the mode's
> 	 completion function:
>
> 	4.3.1) Check whether point is in any of specific completion
> 	       context.
>
> 	4.3.2) If point is in a specific context, consult the
> 	       *-mode-context-completion-functions-alist variable to
> 	       determine the list of functions to call. If that is not
> 	       the case, use the previously sampled value of
> 	       completion-at-point-functions.
>
> 	4.3.3) Do a let-binding setting completion-at-point-functions to
> 	       the value determined in the previous step, and then call
> 	       completion-at-point (recursive) within the let context,
> 	       and return whatever completion-at-point returned. (Can
> 	       completion-at-point be called recursively? I haven't
> 	       tried.)
>
> 5) Job done.
>
>
> Apologies for the lengthy explanation...

Hi Alexander,

I'll respond here, though I've read your other replies in other
subthreads.

First of all, my apologies for an attempted hijacking of the thread! But
you're right this is something that has irked me for a long time, I just
haven't gotten around to writing code, and it's easier to yell about it
on this thread than go write my own patch :)

While I don't object to EUDC at all (and have a half-written patch
somewhere to adapt EBDB to EUDC, as well), I don't think it's necessary
to funnel all email completion through it. The mechanism already exists
in the completion-at-point code, and if that doesn't work the way we
want it to, I think it should be tweaked until it does, because this is
a common use case.

We already have `message-expand-name-databases', and it is merely a bit
of historical perversity that only two values are allowed in there. It
should accept any appropriate function.

`message-tab' will always be necessary for checking where in the message
buffer we are, and feeding the correct string to the completion tables.

`completion-table-merge' is the only missing piece. It collections all
potential completions from all tables and, as the name suggests, merges
them.

I think that's all we need. Users should certainly be free to only use
EUDC if they want, but then all they have to do is funnel their various
functions into EUDC, and set `message-expand-name-databases' to '(eudc).
I don't see any need to enforce the use of EUDC, and think that
message.el should not (and should not need to) make any mention of
specific contact-management packages at all.

That's my point of view!

Thanks,
Eric




  reply	other threads:[~2022-04-15 22:57 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-09 16:24 [PATCH] EUDC email addresses via completion-at-point in message-mode Alexander Adolf
2022-04-12 21:12 ` Thomas Fitzsimmons
2022-04-13 14:44   ` Alexander Adolf
2022-04-14  0:26     ` Thomas Fitzsimmons
2022-04-15 21:23       ` Alexander Adolf
2022-04-14 13:02     ` Eric S Fraga
2022-04-14 13:27       ` Thomas Fitzsimmons
2022-04-14 13:52         ` Eric S Fraga
2022-04-15 21:39           ` Alexander Adolf
2022-04-17 12:12             ` Eric S Fraga
2022-04-15 21:35       ` Alexander Adolf
2022-04-17 12:20         ` Eric S Fraga
2022-04-17 13:58           ` Thomas Fitzsimmons
2022-04-17 17:21             ` Eric S Fraga
2022-04-14 14:02     ` Stefan Monnier
2022-04-15 21:58       ` Alexander Adolf
2022-04-15 22:57         ` Eric Abrahamsen [this message]
2022-04-14  1:44 ` Eric Abrahamsen
2022-04-14 13:04   ` Eric S Fraga
2022-04-14 15:17     ` Eric Abrahamsen
2022-04-14 15:26       ` Stefan Monnier
2022-04-15 16:31         ` Eric Abrahamsen
2022-04-15 17:17           ` Stefan Monnier
2022-04-15 22:30           ` Alexander Adolf
2022-04-15 22:16   ` Alexander Adolf
2022-04-15 22:58     ` Stefan Monnier
2022-04-26 14:39 ` Alexander Adolf
2022-04-26 18:58   ` Filipp Gunbin
2022-04-28 17:15     ` Alexander Adolf
2022-04-29 14:43       ` Thomas Fitzsimmons
2022-05-02 17:10         ` Alexander Adolf
2022-05-03 18:03           ` Thomas Fitzsimmons
2022-05-05 16:32             ` Alexander Adolf
2022-05-05 16:57               ` Thomas Fitzsimmons
2022-05-10 21:16                 ` Thomas Fitzsimmons
2022-05-16 12:35                   ` Alexander Adolf
2022-04-29 23:04       ` Filipp Gunbin
2022-05-02 21:38         ` Alexander Adolf
2022-05-02 22:32           ` Filipp Gunbin
2022-05-03 16:18             ` Alexander Adolf
2022-05-03 16:22   ` Alexander Adolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87a6cmymy9.fsf@ericabrahamsen.net \
    --to=eric@ericabrahamsen.net \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).