aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorStefan Monnier2019-12-11 20:17:17 -0500
committerStefan Monnier2019-12-11 20:17:17 -0500
commit47a767c24e9cc4323432e29103b0a2cc46f8f3e4 (patch)
tree53864b52a54e2812b7a4088e37a4b0d91ffeff47 /lisp
parent394c91e4bf0e9244f6b0f41b4ba74c1dbf3097a2 (diff)
downloademacs-47a767c24e9cc4323432e29103b0a2cc46f8f3e4.tar.gz
emacs-47a767c24e9cc4323432e29103b0a2cc46f8f3e4.zip
* lisp/gnus/message.el (message-expand-name-standard-ui): New option
(message--old-style-completion-functions): New var. (message-completion-function): Allow functions on `message-completion-alist` to follow the capf protocol. (message-completion-alist): Adjust docstring accordingly. Simplify regexps and make them apply more liberally. (message-expand-group): Use the capf protocol. (completion-category-defaults): Use 'substring' completion style by default for email addresses. (message--bbdb-query-with-words, message--name-table): New functions. (message-expand-name): Use them to obey `message-expand-name-standard-ui`.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/gnus/message.el109
1 files changed, 95 insertions, 14 deletions
diff --git a/lisp/gnus/message.el b/lisp/gnus/message.el
index 6778f0e661d..f7f5e9dd344 100644
--- a/lisp/gnus/message.el
+++ b/lisp/gnus/message.el
@@ -8043,15 +8043,12 @@ When FORCE, rebuild the tool bar."
8043 :type 'regexp) 8043 :type 'regexp)
8044 8044
8045(defcustom message-completion-alist 8045(defcustom message-completion-alist
8046 ;; FIXME: Make it possible to use the standard completion UI. 8046 `((,message-newgroups-header-regexp . ,#'message-expand-group)
8047 (list (cons message-newgroups-header-regexp 'message-expand-group) 8047 ("^\\([^ :]*-\\)?\\(To\\|B?Cc\\|From\\):" . ,#'message-expand-name))
8048 '("^\\(Resent-\\)?\\(To\\|B?Cc\\):" . message-expand-name) 8048 "Alist of (RE . FUN). Use FUN for completion on header lines matching RE.
8049 '("^\\(Reply-To\\|From\\|Mail-Followup-To\\|Mail-Copies-To\\):" 8049FUN should be a function that obeys the same rules as those
8050 . message-expand-name) 8050of `completion-at-point-functions'."
8051 '("^\\(Disposition-Notification-To\\|Return-Receipt-To\\):" 8051 :version "27.1"
8052 . message-expand-name))
8053 "Alist of (RE . FUN). Use FUN for completion on header lines matching RE."
8054 :version "22.1"
8055 :group 'message 8052 :group 'message
8056 :type '(alist :key-type regexp :value-type function)) 8053 :type '(alist :key-type regexp :value-type function))
8057 8054
@@ -8091,6 +8088,8 @@ regular text mode tabbing command."
8091 8088
8092(defvar mail-abbrev-mode-regexp) 8089(defvar mail-abbrev-mode-regexp)
8093 8090
8091(defvar message--old-style-completion-functions nil)
8092
8094(defun message-completion-function () 8093(defun message-completion-function ()
8095 (let ((alist message-completion-alist)) 8094 (let ((alist message-completion-alist))
8096 (while (and alist 8095 (while (and alist
@@ -8099,9 +8098,22 @@ regular text mode tabbing command."
8099 (setq alist (cdr alist))) 8098 (setq alist (cdr alist)))
8100 (when (cdar alist) 8099 (when (cdar alist)
8101 (let ((fun (cdar alist))) 8100 (let ((fun (cdar alist)))
8102 ;; Even if completion fails, return a non-nil value, so as to avoid 8101 (if (member fun message--old-style-completion-functions)
8103 ;; falling back to message-tab-body-function. 8102 (lambda ()
8104 (lambda () (funcall fun) 'completion-attempted))))) 8103 (funcall fun)
8104 ;; Even if completion fails, return a non-nil value, so as to
8105 ;; avoid falling back to message-tab-body-function.
8106 'completion-attempted)
8107 (let ((ticks-before (buffer-chars-modified-tick))
8108 (data (funcall fun)))
8109 (if (and (eq ticks-before (buffer-chars-modified-tick))
8110 (or (null data)
8111 (integerp (car-safe data))))
8112 data
8113 (push fun message--old-style-completion-functions)
8114 ;; Completion was already performed, so just return a dummy
8115 ;; function that prevents trying any further.
8116 (lambda () 'completion-attempted))))))))
8105 8117
8106(defun message-expand-group () 8118(defun message-expand-group ()
8107 "Expand the group name under point." 8119 "Expand the group name under point."
@@ -8120,10 +8132,27 @@ regular text mode tabbing command."
8120 gnus-active-hashtb) 8132 gnus-active-hashtb)
8121 (hash-table-keys gnus-active-hashtb)))) 8133 (hash-table-keys gnus-active-hashtb))))
8122 (when collection 8134 (when collection
8123 (completion-in-region b e collection)))) 8135 ;; FIXME: Add `category' metadata to the collection, so we can use
8136 ;; substring matching on it.
8137 (list b e collection))))
8138
8139(defcustom message-expand-name-standard-ui nil
8140 "If non-nil, use the standard completion UI in `message-expand-name'.
8141E.g. this means it will obey `completion-styles' and other such settings."
8142 :version "27.1"
8143 :type 'boolean)
8124 8144
8125(defun message-expand-name () 8145(defun message-expand-name ()
8126 (cond ((and (memq 'eudc message-expand-name-databases) 8146 (cond (message-expand-name-standard-ui
8147 (let ((beg (save-excursion
8148 (skip-chars-backward "^\n:,") (skip-chars-forward " \t")
8149 (point)))
8150 (end (save-excursion
8151 (skip-chars-forward "^\n,") (skip-chars-backward " \t")
8152 (point))))
8153 (when (< beg end)
8154 (list beg end (message--name-table (buffer-substring beg end))))))
8155 ((and (memq 'eudc message-expand-name-databases)
8127 (boundp 'eudc-protocol) 8156 (boundp 'eudc-protocol)
8128 eudc-protocol) 8157 eudc-protocol)
8129 (eudc-expand-inline)) 8158 (eudc-expand-inline))
@@ -8138,6 +8167,58 @@ regular text mode tabbing command."
8138 (t 8167 (t
8139 (expand-abbrev)))) 8168 (expand-abbrev))))
8140 8169
8170(add-to-list 'completion-category-defaults '(email (styles substring)))
8171
8172(defun message--bbdb-query-with-words (words)
8173 ;; FIXME: This (or something like this) should live on the BBDB side.
8174 (when (fboundp 'bbdb-records)
8175 (require 'bbdb) ;FIXME: `bbdb-records' is incorrectly autoloaded!
8176 (bbdb-records) ;Make sure BBDB and its database is initialized.
8177 (defvar bbdb-hashtable)
8178 (declare-function bbdb-record-mail "bbdb" (record))
8179 (declare-function bbdb-dwim-mail "bbdb-com" (record &optional mail))
8180 (declare-function bbdb-completion-predicate "bbdb-com" (key records))
8181 (let ((records '())
8182 (responses '()))
8183 (dolist (word words)
8184 (dolist (c (all-completions word bbdb-hashtable
8185 #'bbdb-completion-predicate))
8186 (dolist (record (gethash c bbdb-hashtable))
8187 (cl-pushnew record records))))
8188 (dolist (record records)
8189 (dolist (mail (bbdb-record-mail record))
8190 (push (bbdb-dwim-mail record mail) responses)))
8191 responses)))
8192
8193(defun message--name-table (orig-string)
8194 (let ((orig-words (split-string orig-string "[ \t]+"))
8195 eudc-responses
8196 bbdb-responses)
8197 (lambda (string pred action)
8198 (pcase action
8199 ('metadata '(metadata (category . email)))
8200 ('lambda t)
8201 ((or 'nil 't)
8202 (when orig-words
8203 (when (and (memq 'eudc message-expand-name-databases)
8204 (boundp 'eudc-protocol)
8205 eudc-protocol)
8206 (setq eudc-responses (eudc-query-with-words orig-words)))
8207 (when (memq 'bbdb message-expand-name-databases)
8208 (setq bbdb-responses (message--bbdb-query-with-words orig-words)))
8209 (ecomplete-setup)
8210 (setq orig-words nil))
8211 (let ((candidates
8212 ;; FIXME: Add `expand-abbrev'!
8213 (append (all-completions string eudc-responses pred)
8214 (all-completions string bbdb-responses pred)
8215 (when (and (bound-and-true-p ecomplete-database)
8216 (fboundp 'ecomplete-completion-table))
8217 (all-completions string
8218 (ecomplete-completion-table 'mail)
8219 pred)))))
8220 (if action candidates (try-completion string candidates))))))))
8221
8141;;; Help stuff. 8222;;; Help stuff.
8142 8223
8143(defun message-talkative-question (ask question show &rest text) 8224(defun message-talkative-question (ask question show &rest text)