diff options
| author | Stefan Monnier | 2019-12-11 20:17:17 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2019-12-11 20:17:17 -0500 |
| commit | 47a767c24e9cc4323432e29103b0a2cc46f8f3e4 (patch) | |
| tree | 53864b52a54e2812b7a4088e37a4b0d91ffeff47 /lisp | |
| parent | 394c91e4bf0e9244f6b0f41b4ba74c1dbf3097a2 (diff) | |
| download | emacs-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.el | 109 |
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\\):" | 8049 | FUN should be a function that obeys the same rules as those |
| 8050 | . message-expand-name) | 8050 | of `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'. | ||
| 8141 | E.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) |