From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alexander Adolf Newsgroups: gmane.emacs.devel Subject: Re: [PATCH] EUDC email addresses via completion-at-point in message-mode Date: Tue, 26 Apr 2022 16:39:59 +0200 Message-ID: References: Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="15091"; mail-complaints-to="usenet@ciao.gmane.io" To: emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Tue Apr 26 16:40:59 2022 Return-path: Envelope-to: ged-emacs-devel@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1njMN8-0003e3-KP for ged-emacs-devel@m.gmane-mx.org; Tue, 26 Apr 2022 16:40:58 +0200 Original-Received: from localhost ([::1]:38300 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njMN7-0000ZN-CH for ged-emacs-devel@m.gmane-mx.org; Tue, 26 Apr 2022 10:40:57 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:43714) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njMMK-00080l-Ok for emacs-devel@gnu.org; Tue, 26 Apr 2022 10:40:08 -0400 Original-Received: from smtprelay06.ispgateway.de ([80.67.18.29]:2115) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njMMH-0000kA-Dn for emacs-devel@gnu.org; Tue, 26 Apr 2022 10:40:08 -0400 Original-Received: from [46.244.209.134] (helo=condition-alpha.com) by smtprelay06.ispgateway.de with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1njMMD-0007Fd-0u for emacs-devel@gnu.org; Tue, 26 Apr 2022 16:40:01 +0200 In-Reply-To: X-Df-Sender: YWxleGFuZGVyLmFkb2xmQGNvbmRpdGlvbi1hbHBoYS5jb20= Received-SPF: pass client-ip=80.67.18.29; envelope-from=alexander.adolf@condition-alpha.com; helo=smtprelay06.ispgateway.de X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane-mx.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.io gmane.emacs.devel:288894 Archived-At: --=-=-= Content-Type: text/plain Hello, Alexander Adolf writes: > [...] > Browsing through message.el quickly brought me to the sixth of the 21 > FIXMEs in that file, which reads on line 3183: > > ;; FIXME: merge the completion tables from ecomplete/bbdb/...? > ;;(add-hook 'completion-at-point-functions #'message-ecomplete-capf nil t) > (add-hook 'completion-at-point-functions #'message-completion-function nil t) > [...] Thanks to all who cared to share their views, and their suggestions on my proposed patch. I am attaching an updated version that includes the improvements that were suggested: - remove override, and thus respect user's setting of completion-ignore-case (Thomas Fitzsimmons's comment) - do not use ":exclusive 'no" in the completion table (Stefan Monnier's comment) Thanks for pointing these out, and for helping to improve the proposed patch! Then there was a wider discussion on potential, architectural improvements of completion handling in message.el. Before diving into this wider discussion, it would seem worthwhile to me trying to get to a conclusion on the proposed patch. Do we have a consensus, that the proposed, updated patch does not solve all potential issues around email address completion in message mode once and for all, but that it still provides a useful improvement for some users without disturbing others, thus making it seem worthwhile to include the patch? Many thanks and looking forward to your thoughts, --alexander --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-EUDC-email-addresses-via-completion-at-point-in-mess.patch >From 0954a5be3e01283eeb0e56059c6210f0c22037ff Mon Sep 17 00:00:00 2001 From: Alexander Adolf Date: Tue, 26 Apr 2022 15:38:12 +0200 Subject: [PATCH] EUDC email addresses via completion-at-point in message-mode * lisp/net/eudc-capf.el (new file): Add new 'eudc-capf-complete' function. * lisp/gnus/message.el (message-mode): Add 'eudc-capf-complete' to 'completion-at-point-functions' when a 'message-mode' buffer is created, removing the FIXME. * doc/misc/eudc.texi (Inline Query Expansion): Add a new subsection, describing the new 'completion-at-point' mechanism in 'message-mode'. * etc/NEWS (EUDC): Describe the new 'completion-at-point' method. --- doc/misc/eudc.texi | 23 ++++++++ etc/NEWS | 6 ++ lisp/gnus/message.el | 4 +- lisp/net/eudc-capf.el | 127 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 lisp/net/eudc-capf.el diff --git a/doc/misc/eudc.texi b/doc/misc/eudc.texi index d2850282fe..d2a1efeed0 100644 --- a/doc/misc/eudc.texi +++ b/doc/misc/eudc.texi @@ -713,6 +713,7 @@ be passed to the program. @node Inline Query Expansion @section Inline Query Expansion +@subsection Inline Query Expansion Using a Key Binding Inline query expansion is a powerful method to get completion from your directory servers. The most common usage is for expanding names @@ -885,6 +886,28 @@ An error is signaled. The expansion aborts. Default is @code{select} @end defvar +@subsection Inline Query Expansion Using completion-at-point + +In addition to providing a dedicated EUDC function for binding to a +key shortcut (@pxref{Inline Query Expansion Using a Key Binding}), +EUDC also provides a function to contribute search results to the +Emacs in-buffer completion system available via the function +@code{completion-at-point} (@pxref{Identifier +Inquiries,,,maintaining}) in @code{message-mode} buffers +(@pxref{Message}). When using this mechanism, queries are made in the +multi-server query mode of operation (@pxref{Multi-server Queries}). + +When a buffer in @code{message-mode} is created, EUDC's inline +expansion function is automatically added to the variable +@code{completion-at-point-functions}. As a result, whenever +@code{completion-at-point} is invoked in a @code{message-mode} buffer, +EUDC will be queried for email addresses matching the words before +point. Since this will be useful only when editing specific message +header fields that require specifying one or more email addresses, an +additional check is performed whether point is actually in one of +those header fields. Thus, any matching email addresses will be +offered for completion in suitable message header fields only, and not +in other places, like for example the body of the message. @node The Server Hotlist diff --git a/etc/NEWS b/etc/NEWS index dc2e7c616a..1ebbaa76e8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -882,6 +882,12 @@ is called, and the returned values are used to populate the phrase and comment parts (see RFC 5322 for definitions). In both cases, the phrase part will be automatically quoted if necessary. ++++ +*** New function 'eudc-capf-complete' with message-mode integration +EUDC can now contribute email addresses to 'completion-at-point' by +adding the new function 'eudc-capf-complete' to +'completion-at-point-functions' in message-mode. + ** eww/shr +++ diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el index cc994d3ba5..b59ab2c31d 100644 --- a/lisp/gnus/message.el +++ b/lisp/gnus/message.el @@ -51,6 +51,7 @@ (require 'yank-media) (require 'mailcap) (require 'sendmail) +(require 'eudc-capf) (autoload 'mailclient-send-it "mailclient") @@ -3180,8 +3181,7 @@ Like `text-mode', but with these additional commands: (mail-abbrevs-setup)) ((message-mail-alias-type-p 'ecomplete) (ecomplete-setup))) - ;; FIXME: merge the completion tables from ecomplete/bbdb/...? - ;;(add-hook 'completion-at-point-functions #'message-ecomplete-capf nil t) + (add-hook 'completion-at-point-functions #'eudc-capf-complete -1 t) (add-hook 'completion-at-point-functions #'message-completion-function nil t) (unless buffer-file-name (message-set-auto-save-file-name)) diff --git a/lisp/net/eudc-capf.el b/lisp/net/eudc-capf.el new file mode 100644 index 0000000000..b11ef8776b --- /dev/null +++ b/lisp/net/eudc-capf.el @@ -0,0 +1,127 @@ +;;; eudc-capf.el --- EUDC - completion-at-point bindings -*- lexical-binding:t -*- + +;; Copyright (C) 2022 Free Software Foundation, Inc. +;; +;; Author: Alexander Adolf +;; +;; This file is part of GNU Emacs. +;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. +;; +;; GNU Emacs is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Commentary: + +;; This library provides functions to deliver email addresses from +;; EUDC search results to `completion-at-point'. +;; +;; Email address completion will likely be desirable only in +;; situations where designating email recipients plays a role, such +;; as when composing or replying to email messages, or when posting +;; to newsgroups, possibly with copies of the post being emailed. +;; Hence, modes relevant in such contexts, such as for example +;; `message-mode' and `mail-mode', often at least to some extent +;; provide infrastructure for different functions to be called when +;; completing in certain message header fields, or in the body of +;; the message. In other modes for editing email messages or +;; newsgroup posts, which do not provide such infrastructure, any +;; completion function providing email addresses will need to check +;; whether the completion attempt occurs in an appropriate context +;; (that is, in a relevant message header field) before providing +;; completion candidates. Two mechanisms are thus provided by this +;; library. +;; +;; The first mechanism is intended for use by the modes listed in +;; `eudc-capf-modes', and relies on these modes adding +;; `eudc-capf-complete' to `completion-at-point-functions', as +;; would be usually done for any general-purpose completion +;; function. In this mode of operation, and in order to offer +;; email addresses only in contexts where the user would expect +;; them, a check is performed whether point is on a line that is a +;; message header field suitable for email addresses, such as for +;; example "To:", "Cc:", etc. +;; +;; The second mechanism is intended for when the user modifies +;; `message-completion-alist' to replace `message-expand-name' with +;; the function `eudc-capf-message-expand-name'. As a result, +;; minibuffer completion (`completing-read') for email addresses +;; would no longer enabled in `message-mode', but +;; `completion-at-point' (in-buffer completion) only. + +;;; Usage: + +;; (require 'eudc-capf) +;; (add-hook 'completion-at-point-functions #'eudc-capf-complete -1 t) + +;;; Code: + +(require 'eudc) + +(defvar message-email-recipient-header-regexp) +(defvar mail-abbrev-mode-regexp) +(declare-function mail-abbrev-in-expansion-header-p "mailabbrev" ()) + +(defconst eudc-capf-modes '(message-mode) "List of modes in which email \ +address completion is to be attempted.") + +;; completion functions + +;;;###autoload +(defun eudc-capf-complete () + "Email address completion function for `completion-at-point-functions'. + +This function checks whether the current major mode is one of the +modes listed in `eudc-capf-modes', and whether point is on a line +with a message header listing email recipients, that is, a line +whose beginning matches `message-email-recipient-header-regexp', +and, if the check succeeds, searches for records matching the +words before point. + +The return value is either nil when no match is found, or a +completion table as required for functions listed in +`completion-at-point-functions'." + (if (and (seq-some #'derived-mode-p eudc-capf-modes) + (let ((mail-abbrev-mode-regexp message-email-recipient-header-regexp)) + (mail-abbrev-in-expansion-header-p))) + (eudc-capf-message-expand-name) + nil)) + +;;;###autoload +(defun eudc-capf-message-expand-name () + "Email address completion function for `message-completion-alist'. + +When this function is added to `message-completion-alist', +replacing any existing entry for `message-expand-name' there, +with an appropriate regular expression such as for example +`message-email-recipient-header-regexp', then EUDC will be +queried for email addresses, and the results delivered to +`completion-at-point'." + (if (or (and (boundp 'eudc-server) eudc-server) + (and (boundp 'eudc-server-hotlist) eudc-server-hotlist)) + (progn + (setq-local completion-styles '(substring partial-completion)) + (let* ((beg (save-excursion + (if (re-search-backward "\\([:,]\\|^\\)[ \t]*" + (point-at-bol) 'move) + (goto-char (match-end 0))) + (point))) + (end (point)) + (prefix (save-excursion (buffer-substring-no-properties beg end)))) + (list beg end + (completion-table-with-cache + (lambda (_) + (eudc-query-with-words (split-string prefix "[ \t]+") t)) + t)))) + nil)) + +(provide 'eudc-capf) +;;; eudc-capf.el ends here -- 2.36.0 --=-=-=--