branch: externals/ebdb commit 03594c73081c1cd8f17b3e5c80791c2b8b6f60a8 Author: Eric Abrahamsen <e...@ericabrahamsen.net> Commit: Eric Abrahamsen <e...@ericabrahamsen.net>
Tweak completion support The gist of this is that it provides two kinds of completion support: the `ebdb-dwim-completion-cache' which is simply a list of "name <mail>" strings for use in mail composition buffers, and the `ebdb-record-completion-table', which is a general-purpose completion table for selecting a record. Squashed commit of the following: commit 5f55a397da48d58ff411c509cc0105e1f2b60ac0 Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Thu Mar 7 18:13:55 2019 -0800 Remove option ebdb-wl-use-ebdb-completion * ebdb-wl.el (ebdb-insinuate-wl): We've already got the option ebdb-complete-mail for this. commit 1776b0275e4c2d20713ba3a36ec849d3bb19a936 Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Thu Mar 7 16:50:57 2019 -0800 Arrange for post-completion stuff to be called even with capf * ebdb-message.el (ebdb-message-complete-mail-cleanup): New function that simply passes the correct arguments to `ebdb-complete-mail-cleanup'. (ebdb-insinuate-message): Add the above to a buffer-local value of `choose-completion-string-functions'. commit efaafa1cd438e41bbcab1fd6ed8a3c32922294d0 Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Thu Mar 7 12:02:15 2019 -0800 Docstring fixes commit d234439f97fea6a796f097e96b65da23fbfa867d Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Thu Mar 7 12:01:52 2019 -0800 Update docs about completion options commit 84b8b3d707a02196e71ba447cf7df294a088e285 Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Wed Mar 6 13:41:30 2019 -0800 Make more interesting completion table, remove some functions * ebdb-com.el (ebdb-record-completion-table): This function now uses the string to complete as an actual search. (ebdb-completing-read-record): Simplify this record somewhat; assume that there's only one matching record. (ebdb-completing-read-records): Delete this function, there isn't really a use for it. commit 74e34625d6b9e0db4cd8ae5b00645364a1591f1c Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Thu Jan 17 10:41:51 2019 -0800 WIP on manual updates commit 9892a4401d9c16f50c3f52fdb4dc86550ca4ff9d Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Wed Jan 16 12:21:44 2019 -0800 Turns out the completion functions could be simpler * ebdb-com.el (ebdb-record-completion-table): So *that's* what `complete-with-action' is for. * ebdb.el (ebdb-mail-dwim-collection-function): Here, too. commit 52cbe9e94aa0f4acb4480ec75b87632c85c30ce9 Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Mon Jan 14 13:57:50 2019 -0800 New completion mechanisms, next bit commit 9b2087e494636333c1e66da17eef55cc69b7f121 Author: Eric Abrahamsen <e...@ericabrahamsen.net> Date: Fri Dec 28 13:44:21 2018 -0800 WIP on new completion mechanisms --- ebdb-com.el | 86 ++++++++++--------- ebdb-complete.el | 75 ++++------------- ebdb-message.el | 40 +++++++-- ebdb-wl.el | 13 +-- ebdb.el | 76 +++++++++++++++-- ebdb.info | 253 +++++++++++++++++++++++++++++++++++++------------------ ebdb.org | 93 ++++++++++++++++---- ebdb.texi | 117 ++++++++++++++++++++----- 8 files changed, 504 insertions(+), 249 deletions(-) diff --git a/ebdb-com.el b/ebdb-com.el index efd0798..8277a77 100644 --- a/ebdb-com.el +++ b/ebdb-com.el @@ -2313,9 +2313,9 @@ The search results are displayed in the EBDB buffer using formatter FMT." ;;;###autoload (defun ebdb-search-single-record (record &optional fmt) "Prompt for a single RECORD, and display it." - (interactive (list (ebdb-completing-read-records "Display records: ") + (interactive (list (ebdb-completing-read-record "Display record: ") (ebdb-formatter-prefix))) - (ebdb-display-records record fmt)) + (ebdb-display-records (list record) fmt)) (defun ebdb-search-prog (function &optional fmt) "Search records using FUNCTION. @@ -2424,7 +2424,39 @@ otherwise inline." (ebdb-cite-records records arg)) (pop-to-buffer buf))) -;;; completion +;;; Completion + +(defun ebdb-record-completion-table (str pred action) + "Function used as a completion table for EBDB records. +STR is used to search the database. The return value is the +completed name string." + (let* ((completion-ignore-case ebdb-case-fold-search) + (newstring (concat "^" str)) + ;; Completion searches the database, but we only use "fast + ;; lookup" search clauses which use the hashtable, instead of + ;; cycling over all records one by one. Still pretty slow, + ;; though. Also unfortunate is that EBDB has a broader + ;; concept of "matching string" than the completion + ;; framework, which will later filter out strings that we + ;; consider matching (e.g. according to character folding, or + ;; romanization of non-English scripts). Perhaps we could + ;; make our own completion style to take care of that. + (strings + (mapcar #'ebdb-string + (if (string-empty-p str) + (ebdb-records) + (ebdb-search + (ebdb-records) + (append + (list `(ebdb-field-name ,newstring) + `(ebdb-field-mail ,newstring) + `(ebdb-field-tags ,newstring)) + (mapcar (lambda (f) + (list f newstring)) + ebdb-hash-extra-predicates))))))) + (if (eq action 'metadata) + '(metadata . ((category . ebdb-contact))) + (complete-with-action action strings str pred)))) ;;;###autoload (defun ebdb-completion-predicate (key records) @@ -2441,44 +2473,16 @@ Obey `ebdb-completion-list'." (ebdb-hash-p key record ebdb-completion-list)) nil)))) -(defun ebdb-completing-read-records (prompt &optional omit-records) - "Read and return list of records from the ebdb. -Completion is done according to `ebdb-completion-list', with -prompt PROMPT. If the user just hits return, nil is returned. -Otherwise, a valid response is forced. Optional argument -OMIT-RECORDS is a list of records that should never be returned." - (unless ebdb-record-tracker - (ebdb-load)) - (let* ((completion-ignore-case t) - (string (completing-read prompt ebdb-hashtable - 'ebdb-completion-predicate t))) - (unless (string= "" string) - (let (records) - (dolist (record (gethash string ebdb-hashtable)) - (when (and (not (memq record omit-records)) - (not (memq record records))) - (push record records))) - records)))) - - -(defun ebdb-completing-read-record (prompt &optional omit-records) - "Prompt for and return a single record from the ebdb. -Completion is done according to `ebdb-completion-list', with -prompt PROMPT. If the user just hits return, nil is -returned. Otherwise, a valid response is forced. If OMIT-RECORDS -is non-nil it should be a list of records to dis-allow completion -with." - (let ((records (ebdb-completing-read-records prompt omit-records))) - (cond ((eq (length records) 1) - (car records)) - ((> (length records) 1) - (ebdb-display-records records ebdb-default-oneline-formatter) - (let* ((count (length records)) - (result (completing-read - (format "Which record (1-%s): " count) - (mapcar 'number-to-string (number-sequence 1 count)) - nil t))) - (nth (1- (string-to-number result)) records)))))) +(defun ebdb-completing-read-record (prompt) + "Read and return a record from the EBDB. +PROMPT is used in `completing-read'. Actual completion is done +using the function `ebdb-record-completion-table'." + (let ((string (completing-read + prompt #'ebdb-record-completion-table nil t)) + records) + (unless (string-empty-p string) + (or (car-safe (ebdb-gethash string '(fl-name aka mail))) + (message "No matching records for \"%s\"" string))))) ;;;###autoload (defun ebdb-completing-read-mails (prompt &optional init) diff --git a/ebdb-complete.el b/ebdb-complete.el index e293199..85aee73 100644 --- a/ebdb-complete.el +++ b/ebdb-complete.el @@ -1,8 +1,9 @@ -;;; ebdb-complete.el --- EBDB window as an email-chooser -*- lexical-binding: t; -*- +;;; ebdb-complete.el --- Completion functionality for EBDB -*- lexical-binding: t; -*- ;; Copyright (C) 2017 Free Software Foundation, Inc. ;; Author: Feng Shu <tuma...@163.com> +;; Maintainer: Eric Abrahamsen <e...@ericabrahamsen.net> ;; Keywords: mail, convenience ;; This program is free software; you can redistribute it and/or modify @@ -20,80 +21,35 @@ ;;; Commentary: -;; ## Introduce ## -;; -;; ebdb-complete is a EBDB tool, when in headers (TO: and CC:) of message-mode -;; buffer, Type TAB key will pop up a EBDB window as email-chooser. +;; This file contains the function `ebdb-complete' which pops +;; up a full EBDB window as email-chooser, typically in mail +;; composition buffers. + +;; The simplest installation method is to call: -;; ## Usage ## -;; -;; ### The easiest way ### -;; -;; Add the below line to your emacs config file. -;; -;; ``` -;; (require 'ebdb-complete) ;; (ebdb-complete-enable) -;; ``` -;; -;; ### The manual way ### + +;; This will bind TAB in message-mode and mail-mode to +;; `ebdb-complete', which will pop up a full EBDB buffer as a contact +;; chooser. ;; -;; The function `ebdb-complete-enable' only rebind some key in `ebdb-mode-map', -;; `message-mode-map' and `mail-mode-map', user can do this job by hand, -;; for example: +;; This can also be done manually, e.g.: ;; -;; ``` -;; ;; ebdb-mode ;; (define-key ebdb-mode-map "q" 'ebdb-complete-quit-window) ;; (define-key ebdb-mode-map "\C-c\C-c" 'ebdb-complete-push-mail) ;; (define-key ebdb-mode-map (kbd "RET") 'ebdb-complete-push-mail-and-quit-window) ;; (define-key message-mode-map "\t" 'ebdb-complete-message-tab) ;; (define-key mail-mode-map "\t" 'ebdb-complete-message-tab) -;; ``` ;;; Code: (require 'ebdb-com) (require 'message) (require 'sendmail) -;; Experimental completion-at-point function. I'm not sure this is a -;; good idea yet -- with a large enough EBDB database, nearly any -;; string is completable, meaning the other completion-at-point -;; functions will rarely get a chance. -(defun ebdb-completion-at-point-function () - "Try to find an EBDB completion for the text at point. -For use in `completion-at-point-functions'." - ;; Might consider restricting this to text-mode buffers -- would you - ;; ever want to complete contact names in prog-mode? - (let* ((start (point)) - (chunk (buffer-substring - (save-excursion - ;; First try going back two words. - (forward-word -2) - (setq start (point))) - (point))) - (completions (all-completions (downcase chunk) ebdb-hashtable))) - (unless completions - ;; If that didn't work, try just one word. - (setq chunk (buffer-substring - (save-excursion - (forward-word -1) - (setq start (point))) - (point)) - completions (all-completions (downcase chunk) ebdb-hashtable))) - (when completions - (list start (point) - (mapcar - (lambda (str) - ;; Gross. - (if (string-match-p "@" str) - str - (capitalize str))) - completions) - '(:exclusive no))))) +;;;###autoload (defvar ebdb-complete-info (make-hash-table) - "A hashtable, record buffer, buffer-window and window-point") + "A hashtable recording buffer, buffer-window and window-point") (defun ebdb-complete-push-mail (records &optional _ arg) "Push email-address(es) of `records' to buffer in `ebdb-complete-info'." @@ -154,6 +110,7 @@ Before quit, this command will do some clean jobs." (skip-syntax-backward "w_") (point)))) +;;;###autoload (defun ebdb-complete () "Open EBDB window as an email-address selector, if Word at point is found, EBDB will search this word @@ -233,6 +190,7 @@ when in message body, this command will indent regular text." (define-key ebdb-mode-map "\C-c\C-c" 'ebdb-complete-push-mail) (define-key ebdb-mode-map (kbd "RET") 'ebdb-complete-push-mail-and-quit-window)) +;;;###autoload (defun ebdb-complete-enable () "Enable ebdb-complete, it will rebind TAB key in `message-mode-map'." (interactive) @@ -242,7 +200,6 @@ when in message body, this command will indent regular text." (define-key mail-mode-map "\t" 'ebdb-complete-message-tab) (message "ebdb-complete: Override EBDB keybindings: `q', `C-c C-c' and `RET'")) - (provide 'ebdb-complete) ;; Local Variables: diff --git a/ebdb-message.el b/ebdb-message.el index 1cbecd5..ada381f 100644 --- a/ebdb-message.el +++ b/ebdb-message.el @@ -90,12 +90,30 @@ See Gnus' manual for details." (cl-defmethod ebdb-popup-window (&context (major-mode mail-mode)) (list (get-buffer-window) 0.4)) +(defun ebdb-message-complete-mail-cleanup (str _buffer pos &optional _) + "Call `ebdb-complete-mail-cleanup' after capf completion." + (ebdb-complete-mail-cleanup str pos)) + (defun ebdb-insinuate-message () ;; We don't currently bind the `ebdb-mua-keymap'. - (when ebdb-complete-mail - (cl-pushnew '("^\\(Resent-\\)?\\(To\\|B?Cc\\|Reply-To\\|From\\|Mail-Followup-To\\|Mail-Copies-To\\):" . ebdb-complete-mail) - message-completion-alist - :test #'equal)) + (pcase ebdb-complete-mail + ('capf (progn (add-hook + 'completion-at-point-functions + #'ebdb-mail-dwim-completion-at-point-function nil t) + ;; Kind of hacky way of mimicking + ;; `ebdb-complete-mail' behavior, but for capf. The + ;; completion-string-functions are supposed to be + ;; buffer local, but don't appear to be. + (set + (make-local-variable + 'choose-completion-string-functions) + (push #'ebdb-message-complete-mail-cleanup + choose-completion-string-functions)))) + ('nil nil) + (_ + (cl-pushnew '("^\\(Resent-\\)?\\(To\\|B?Cc\\|Reply-To\\|From\\|Mail-Followup-To\\|Mail-Copies-To\\):" . ebdb-complete-mail) + message-completion-alist + :test #'equal))) ;; Other MUAs clear the EBDB buffer before displaying (in ;; `ebdb-mua-auto-update', the call to `ebdb-display-records' does ;; not pass the "append" flag). Displaying in message-mode does @@ -106,8 +124,18 @@ See Gnus' manual for details." (defun ebdb-insinuate-mail () "Hook EBDB into Mail Mode." ;; We don't currently bind the `ebdb-mua-keymap'. - (if ebdb-complete-mail - (define-key mail-mode-map "\M-\t" 'ebdb-complete-mail)) + (pcase ebdb-complete-mail + ('capf (progn (add-hook + 'completion-at-point-functions + #'ebdb-mail-dwim-completion-at-point-function nil t) + ;; See above. + (set + (make-local-variable + 'choose-completion-string-functions) + (push #'ebdb-message-complete-mail-cleanup + choose-completion-string-functions)))) + ('nil nil) + (_ (define-key mail-mode-map "\M-\t" 'ebdb-complete-mail))) (ebdb-undisplay-records)) (add-hook 'message-mode-hook 'ebdb-insinuate-message) diff --git a/ebdb-wl.el b/ebdb-wl.el index 5c47256..6440f87 100644 --- a/ebdb-wl.el +++ b/ebdb-wl.el @@ -42,17 +42,6 @@ "Options for EBDB's interaction with Wanderlust." :group 'ebdb-mua) -;; This rebinds <TAB> in `wl-draft-mode-map' to `ebdb-complete-mail'. -;; WL has its own completion mechanism that we could hook into, by -;; setting `wl-address-init-function' to our own function that -;; populates `wl-address-completion-list', but that would mean that -;; we're basically duplicating most of the information in the EBDB, -;; and `ebdb-complete-mail' works fine in `wl-draft-mode'. -(defcustom ebdb-wl-use-ebdb-completion nil - "If non-nil, use EBDB mail completion in WL draft mode." - :group 'ebdb-wl - :type 'bool) - (cl-defmethod ebdb-mua-message-header ((header string) &context (major-mode mime-view-mode)) "Extract a message header in Wanderlust." @@ -122,7 +111,7 @@ beginning) of the signature separator." (defun ebdb-insinuate-wl () "Hook EBDB into Wanderlust." (define-key wl-summary-mode-map ";" ebdb-mua-keymap) - (when ebdb-wl-use-ebdb-completion + (when ebdb-complete-mail (define-key wl-draft-mode-map (kbd "TAB") #'ebdb-complete-mail)) (add-hook 'wl-summary-exit-hook #'ebdb-wl-quit-window)) diff --git a/ebdb.el b/ebdb.el index 1408b4a..465340c 100644 --- a/ebdb.el +++ b/ebdb.el @@ -2,7 +2,7 @@ ;; Copyright (C) 2016-2018 Free Software Foundation, Inc. -;; Version: 0.6.5 +;; Version: 0.6.6 ;; Package-Requires: ((emacs "25.1") (cl-lib "0.5") (seq "2.15")) ;; Maintainer: Eric Abrahamsen <e...@ericabrahamsen.net> @@ -96,6 +96,11 @@ You really should not disable debugging. But it will speed things up.")) "Bind this to t to quiet things down - do not set it. See also `ebdb-silent'.") +(defvar ebdb-dwim-completion-cache nil + "A list of strings as returned by `ebdb-dwim-mail'. +As mail field instances are created, a \"dwim\"-style string is +added here, for use in `completion-at-point' in mail buffers.") + ;; Custom groups (defgroup ebdb-eieio nil @@ -646,9 +651,15 @@ name in mail address when same as mail." (const :tag "Avoid redundancy" t))) (defcustom ebdb-complete-mail t - "If t MUA insinuation provides key binding for command `ebdb-complete-mail'." + "If non-nil composition MUAs will complete EBDB contacts. +Completion takes place within mail headers that specify one or +more message recipients. A value of `capf' will add an EBDB +collection to `completion-at-point-functions'. Any other non-nil +value will override \"TAB\" to call `ebdb-complete-mail'." :group 'ebdb-sendmail - :type 'boolean) + :type '(choice (const :tag "Use `ebdb-complete-mail'" t) + (const :tag "Do not complete mail addresses" nil) + (const :tag "Use completion at point" capf))) (defcustom ebdb-completion-list t "Controls the behaviour of function `ebdb-complete-mail'. @@ -672,21 +683,28 @@ If nil, no completion is offered." (const primary) (const mail))))) -(defcustom ebdb-complete-mail-allow-cycling nil - "If non-nil cycle mail addresses when calling function `ebdb-complete-mail'." +(defcustom ebdb-complete-mail-allow-cycling 5 + "If non-nil, cycle mail addresses when completing mails. +If `ebdb-complete-mail' is set to `capf', this option can be set +to an integer number, specifying that completion should take +place when there are that many completion candidates or fewer. +Otherwise, cycling will take place among all a single contact's +email addresses." :group 'ebdb-sendmail - :type 'boolean) + :type '(choice (const :tag "Never cycle" nil) + (const :tag "Always cycle" t) + (number :tag "Cycle for this many candidates or fewer"))) (defcustom ebdb-complete-mail-hook nil - "List of functions called after a sucessful completion." + "List of functions called after a successful completion." :group 'ebdb-sendmail :type 'hook) (defcustom ebdb-mail-abbrev-expand-hook nil ;; Replacement for function `mail-abbrev-expand-hook'. "Function (not hook) run each time an alias is expanded. -The function is called with two args the alias and the list -of corresponding mail addresses." +The function is called with two args: the alias and the list of +corresponding mail addresses." :group 'ebdb-sendmail :type 'function) @@ -1483,6 +1501,8 @@ first one." (with-slots (aka mail) field (ebdb-puthash mail record) (object-add-to-list (ebdb-record-cache record) 'mail-canon mail) + (cl-pushnew (ebdb-dwim-mail record field) ebdb-dwim-completion-cache + :test #'equal) (when aka (ebdb-puthash aka record) (object-add-to-list (ebdb-record-cache record) 'mail-aka aka)))) @@ -1492,6 +1512,8 @@ first one." (when aka (ebdb-remhash aka record) (object-remove-from-list (ebdb-record-cache record) 'mail-aka aka)) + (setq ebdb-dwim-completion-cache (delete (ebdb-dwim-mail record field) + ebdb-dwim-completion-cache)) (ebdb-remhash mail record) (object-remove-from-list (ebdb-record-cache record) 'mail-canon mail)) (cl-call-next-method)) @@ -4297,6 +4319,8 @@ addresses." +;;; Mail and completion stuff. + (defun ebdb-dwim-mail (record &optional mail) ;; Do What I Mean! "Return a string to use as the mail address of RECORD. @@ -4341,6 +4365,40 @@ to use." name mail)) mail))) +(defun ebdb-mail-dwim-completion-at-point-function () + "Complete text at point as a mail \"dwim\" string. +The completed strings are of the form \"Firstname Lastname +<n...@example.org>\". For use in `completion-at-point-functions' +in `message-mode' or `mail-mode'. + +Also see the variable `ebdb-ignore-redundant-mails'." + (when (let ((mail-abbrev-mode-regexp + "^\\(Resent-\\)?\\(To\\|B?Cc\\|Reply-To\\|From\\|Mail-Followup-To\\|Mail-Copies-To\\):")) + (mail-abbrev-in-expansion-header-p)) + (let* ((start + (save-excursion + ;; Headers can be multi-line, but if we've wrapped there + ;; should always be something on the current line. + (re-search-backward ",[[:blank:]]?\\|:[[:blank:]]?" + (line-beginning-position) t) + (match-end 0))) + (end (save-excursion + (goto-char (line-end-position)) + (max start (point))))) + (list start end #'ebdb-mail-dwim-collection-function + (list :exclusive 'no))))) + +(defun ebdb-mail-dwim-collection-function (str pred action) + "Function that pretends to be a completion table." + (let ((completion-ignore-case t)) + (if (eq action 'metadata) + '(metadata . ((category . ebdb-contact))) + (complete-with-action action ebdb-dwim-completion-cache str pred)))) + +(add-to-list 'completion-category-defaults + `(ebdb-contact (styles substring basic) + (cycle . ,ebdb-complete-mail-allow-cycling))) + ;;; Dialing and texting. diff --git a/ebdb.info b/ebdb.info index 59cc362..f34506e 100644 --- a/ebdb.info +++ b/ebdb.info @@ -12,6 +12,7 @@ Copyright © 2016 Free Software Foundation, Inc. (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual.” + INFO-DIR-SECTION Emacs START-INFO-DIR-ENTRY * EBDB: (ebdb). Contact management package. @@ -80,6 +81,7 @@ MUA Interaction * Loading MUA Code:: * Display and Updating:: * EBDB and MUA summary buffers:: +* Mail Address Completion:: Display and Updating @@ -95,6 +97,11 @@ EBDB and MUA summary buffers * Summary buffer marks:: +Mail Address Completion + +* A Note on Completion:: + + Specific MUAs * Gnus:: @@ -181,8 +188,8 @@ variable should point to your current BBDB file; alternately EBDB will look in the default location, found using ‘(locate-user-emacs-file "bbdb" ".bbdb)’. Then set ‘ebdb-sources’ to a non-existent file name, and then run ‘ebdb-load’ (or any of the other EBDB entry commands). -You’ll be prompted to create the new database, and upgrade from BBDB. If -any records could not be upgraded, they will be displayed in an *EBDB +You’ll be prompted to create the new database, and upgrade from BBDB. +If any records could not be upgraded, they will be displayed in an *EBDB Migration Errors* buffer. Migration bug reports are very welcome. You can also call the command ‘ebdb-migrate-from-bbdb’ at any time. @@ -194,7 +201,7 @@ File: ebdb.info, Node: Variables and Options, Prev: Record Migration, Up: Mig --------------------------- Many of the old BBDB customization options have been changed or removed -entirely in EBDB. It’s probably best to put your BBDB customizations +entirely in EBDB. It’s probably best to put your BBDB customizations aside, and set new EBDB options as you come across them. The most important options are detailed in this manual, you can also customize the “EBDB” group to see what’s available. @@ -432,10 +439,10 @@ File: ebdb.info, Node: Field Types, Prev: Deleting Records and Fields, Up: Re Fields can be classed in a few different categories. Some are “plumbing” fields, that are present for all records, but not generally visible or user-editable: these include the creation date, timestamp, -and UUID. You can view these fields by hitting ‘T’ on the record. Other -fields are “built-in”: basic fields that get special treatment. These -include the name, mail, phone, address, and notes fields. EBDB comes -with default classes for these fields: if you would like to use +and UUID. You can view these fields by hitting ‘T’ on the record. +Other fields are “built-in”: basic fields that get special treatment. +These include the name, mail, phone, address, and notes fields. EBDB +comes with default classes for these fields: if you would like to use different defaults, you can create new classes (inheriting from the existing ones) and use those instead. See *note Hacking EBDB:: for more information. @@ -553,6 +560,7 @@ emails. * Loading MUA Code:: * Display and Updating:: * EBDB and MUA summary buffers:: +* Mail Address Completion:: File: ebdb.info, Node: Loading MUA Code, Next: Display and Updating, Up: MUA Interaction @@ -781,7 +789,7 @@ binding, and only specifies the further binding. Ie, press “;:” to call Only display recipients, using all mail addresses from the message. -File: ebdb.info, Node: EBDB and MUA summary buffers, Prev: Display and Updating, Up: MUA Interaction +File: ebdb.info, Node: EBDB and MUA summary buffers, Next: Mail Address Completion, Prev: Display and Updating, Up: MUA Interaction 5.3 EBDB and MUA summary buffers ================================ @@ -856,6 +864,76 @@ string provided by Gnus, and adding the EBDB-specific format code: record. Defaults to “e”. +File: ebdb.info, Node: Mail Address Completion, Prev: EBDB and MUA summary buffers, Up: MUA Interaction + +5.4 Mail Address Completion +=========================== + +Emacs’ two message-composition modes are ‘message-mode’ and ‘mail-mode’, +the former having somewhat obsoleted the latter – EBDB supports both. + + The main use of EBDB in message composition is to complete email +addresses of contacts, obviously. The following options govern this +behavior: + + -- User Option: ebdb-complete-mail + If non-nil, EBDB will provide mail completion in mail composition + buffers. If it is the symbol ‘capf’, EBDB will add it’s own + completion function to the local value of + ‘completion-at-point-functions’. Otherwise, it will clobber the + existing binding of ‘<TAB>’ and replace it with the function + ‘ebdb-complete-mail’. (Technically, in ‘message-mode’, it will + ensure this function is called instead of ‘message-expand-name’.) + + -- User Option: ebdb-mail-avoid-redundancy + If nil, mail completion will always insert a full “First Last + <first.l...@example.com>” string, even when the contact’s name is + deemed to be redundant with the email address itself. If set to + the symbol ‘mail-only’, the name will never be inserted. If any + other non-nil value, the name will be elided if it appears to be + redundant. + + -- User Option: ebdb-complete-mail-allow-cycling + If non-nil, cycle mail addresses when completing mails. The exact + behavior of this setting depends a bit on the value of + ‘ebdb-complete-mail’. If completion at point is being used, this + can be set to an integer N, specifying that cycling may take place + if there are N or fewer candidate completion strings. If the + function ‘ebdb-complete-mail’ is being used, a non-nil value will + allow cycling among all of a single contact’s mail addresses, once + the contact itself has been selected. + + -- User Option: ebdb-completion-display-record + If non-nil, display each newly-completed record in a pop-up *EBDB* + buffer. + + -- User Option: ebdb-complete-mail-hook + A hook run after a successful completion. + + -- User Option: ebdb-mail-abbrev-expand-hook + A single function called each time an alias is expanded in a + composition buffer. The function is called with two arguments: the + alias name, and the list of corresponding mail addresses. + +* Menu: + +* A Note on Completion:: + + +File: ebdb.info, Node: A Note on Completion, Up: Mail Address Completion + +5.4.1 A Note on Completion +-------------------------- + +As mentioned above, EBDB completion can be done either using the +completion at point framework, or its own ‘ebdb-complete-mail’ function. +The two don’t behave exactly the same, however: completion at point +works from a pre-constructed list of strings, while ‘ebdb-complete-mail’ +conducts an actual search of the database. This means that the former +is faster, but the latter will find more records, particularly if search +options like ‘ebdb-case-fold-search’ are in effect. + + File: ebdb.info, Node: Specific MUAs, Next: EBDB Buffers, Prev: MUA Interaction, Up: Top 6 Specific MUAs @@ -1308,25 +1386,18 @@ File: ebdb.info, Node: Completion, Next: Snarfing, Prev: EBDB Buffers, Up: T 8 Completion ************ -There are many Emacs completion frameworks out there, and libraries -exist providing EBDB support for helm, counsel, and company. These -libraries must be loaded from the package repositories, and provide the -commands ‘helm-ebdb’, ‘counsel-ebdb’, and ‘company-ebdb’, respectively. -Counsel and company are made to be hooked into Emacs’ existing -completion frameworks; the helm command must be called explicitly. +There are many Emacs completion frameworks out there, and EBDB provides +custom commands for a few of them: ‘ebdb-helm’, ‘ebdb-counsel’, and +‘ebdb-company’. Counsel and company are made to be hooked into Emacs’ +existing completion frameworks; the helm command must be called +explicitly. For information about completion in mail composition +buffers, see *note Mail Address Completion::. Another built-in library, ‘ebdb-complete’, uses an ephemeral pop-up *EBDB* buffer for record completion. The command ‘ebdb-complete’ provides an interactive entry point, or you can enable it for ‘<TAB>’ in ‘message-mode’ by calling ‘ebdb-complete-enable’. - Several native EBDB commands involve choosing a record, or multiple -records. At present, the completion interface for these commands is a -bit random: several of the commands simply use ‘completing-read’ -directly, which isn’t right. At some point, all EBDB commands that ask -the user to select a record will become aware of the currently-loaded -completion frameworks. - File: ebdb.info, Node: Snarfing, Next: Internationalization, Prev: Completion, Up: Top @@ -1604,7 +1675,7 @@ File: ebdb.info, Node: Field Classes, Next: Writing Internationalization Libra 16.1 Field Classes ================== -It’s fairly easy to create your own custom field classes in EBDB. All +It’s fairly easy to create your own custom field classes in EBDB. All such fields should subclass the ‘ebdb-field-user’ class, which sets up basic behavior. That base class provides for no slots at all, so your class must define the slots where the field data will be held. It @@ -2047,7 +2118,7 @@ separate functions: -- Method: ebdb-make-buffer-name Called with no arguments but the mode specializer, this function should return the string name of the *EBDB* buffer to be associated - with this MUA. Usually the function body will look like: ‘(format + with this MUA. Usually the function body will look like: ‘(format "*%s-<mua>" ebdb-buffer-name)’. -- Method: ebdb-popup-window @@ -2087,8 +2158,8 @@ any). This is done with two generic functions: File: ebdb.info, Node: Index, Prev: Hacking EBDB, Up: Top -Index -***** +17 Index +******** [index ] * Menu: @@ -2173,6 +2244,14 @@ Index * ebdb-cite-records-ebdb: The Basics of ebdb-mode. (line 89) * ebdb-clone-buffer: EBDB Buffers. (line 19) +* ebdb-complete-mail: Mail Address Completion. + (line 13) +* ebdb-complete-mail-allow-cycling: Mail Address Completion. + (line 30) +* ebdb-complete-mail-hook: Mail Address Completion. + (line 44) +* ebdb-completion-display-record: Mail Address Completion. + (line 40) * ebdb-copy-fields-as-kill: The Basics of ebdb-mode. (line 96) * ebdb-copy-mail-as-kill: The Basics of ebdb-mode. @@ -2258,6 +2337,10 @@ Index (line 24) * ebdb-mail: The Basics of ebdb-mode. (line 56) +* ebdb-mail-abbrev-expand-hook: Mail Address Completion. + (line 47) +* ebdb-mail-avoid-redundancy: Mail Address Completion. + (line 22) * ebdb-mail-each: The Basics of ebdb-mode. (line 61) * ebdb-make-buffer-name: Writing Integration For New MUAs. @@ -2432,65 +2515,67 @@ Index Tag Table: -Node: Top806 -Node: Getting Started2526 -Node: Migration from BBDB3181 -Node: Record Migration3392 -Node: Variables and Options4195 -Node: Migration from Org Contacts4681 -Node: The EBDB Database5441 -Node: Creating Records9429 -Node: Record classes10510 -Node: Record names10855 -Node: Record Fields11530 -Node: Inserting New Fields11774 -Node: Editing Existing Fields12570 -Node: Deleting Records and Fields13170 -Node: Field Types13566 -Node: Role fields15853 -Node: Tag field17541 -Node: Mail folder field18185 -Node: MUA Interaction18513 -Node: Loading MUA Code19038 -Node: Display and Updating19751 -Node: Pop-up Buffers20517 -Node: Auto-Updating Records22100 -Node: Noticing and Automatic Rules24500 -Node: Interactive Commands25833 -Node: EBDB and MUA summary buffers28308 -Node: Sender name display28794 -Node: Summary buffer marks30021 -Node: Specific MUAs31200 -Node: Gnus31348 -Node: Posting Styles31570 -Node: EBDB Buffers33145 -Node: Searching34356 -Node: Changing Search Behavior36018 -Node: The Basics of ebdb-mode37265 -Node: Customizing Record Display41574 -Node: Marking45894 -Node: Exporting/Formatting46321 -Node: Completion47270 -Node: Snarfing48468 -Node: Internationalization50485 -Node: Diary Integration53186 -Node: Mail Aliases54051 -Node: vCard Support54765 -Node: Org Integration55264 -Node: Citing Records57162 -Node: Hacking EBDB57920 -Node: Field Classes60237 -Node: Init and Delete Methods63372 -Node: The Labeled Field Class64879 -Node: The Singleton Field Class65733 -Node: Actions66171 -Node: Custom Field Searching66843 -Node: Fast Lookups69710 -Node: Formatting in the EBDB Buffer71520 -Node: Writing Internationalization Libraries73596 -Node: Writing Integration For New MUAs78010 -Node: Article snarfing81457 -Node: Index82175 +Node: Top807 +Node: Getting Started2607 +Node: Migration from BBDB3262 +Node: Record Migration3473 +Node: Variables and Options4276 +Node: Migration from Org Contacts4763 +Node: The EBDB Database5523 +Node: Creating Records9511 +Node: Record classes10592 +Node: Record names10937 +Node: Record Fields11612 +Node: Inserting New Fields11856 +Node: Editing Existing Fields12652 +Node: Deleting Records and Fields13252 +Node: Field Types13648 +Node: Role fields15934 +Node: Tag field17622 +Node: Mail folder field18266 +Node: MUA Interaction18594 +Node: Loading MUA Code19147 +Node: Display and Updating19860 +Node: Pop-up Buffers20626 +Node: Auto-Updating Records22209 +Node: Noticing and Automatic Rules24609 +Node: Interactive Commands25942 +Node: EBDB and MUA summary buffers28417 +Node: Sender name display28935 +Node: Summary buffer marks30162 +Node: Mail Address Completion31341 +Node: A Note on Completion33850 +Node: Specific MUAs34473 +Node: Gnus34621 +Node: Posting Styles34843 +Node: EBDB Buffers36418 +Node: Searching37629 +Node: Changing Search Behavior39291 +Node: The Basics of ebdb-mode40538 +Node: Customizing Record Display44847 +Node: Marking49167 +Node: Exporting/Formatting49594 +Node: Completion50543 +Node: Snarfing51339 +Node: Internationalization53356 +Node: Diary Integration56057 +Node: Mail Aliases56922 +Node: vCard Support57636 +Node: Org Integration58135 +Node: Citing Records60033 +Node: Hacking EBDB60791 +Node: Field Classes63108 +Node: Init and Delete Methods66244 +Node: The Labeled Field Class67751 +Node: The Singleton Field Class68605 +Node: Actions69043 +Node: Custom Field Searching69715 +Node: Fast Lookups72582 +Node: Formatting in the EBDB Buffer74392 +Node: Writing Internationalization Libraries76468 +Node: Writing Integration For New MUAs80882 +Node: Article snarfing84330 +Node: Index85048 End Tag Table diff --git a/ebdb.org b/ebdb.org index 3212a7a..ec0ff9f 100644 --- a/ebdb.org +++ b/ebdb.org @@ -634,7 +634,6 @@ Only display the recipients. #+begin_deffn Only display recipients, using all mail addresses from the message. #+end_deffn - ** EBDB and MUA summary buffers EBDB can affect the way message senders are displayed in your MUA's @@ -703,6 +702,78 @@ string provided by Gnus, and adding the EBDB-specific format code: Format letter to use in the summary buffer format string to mark a record. Defaults to "e". #+END_defopt +** Mail Address Completion +:PROPERTIES: +:ID: f035aefc-53b1-4d05-b980-8ae0ac851275 +:END: +Emacs' two message-composition modes are ~message-mode~ and +~mail-mode~, the former having somewhat obsoleted the latter -- EBDB +supports both. + +The main use of EBDB in message composition is to complete email +addresses of contacts, obviously. The following options govern this +behavior: + +#+ATTR_TEXINFO: :options ebdb-complete-mail +#+BEGIN_defopt +If non-nil, EBDB will provide mail completion in mail composition +buffers. If it is the symbol ~capf~, EBDB will add it's own +completion function to the local value of +~completion-at-point-functions~. Otherwise, it will clobber the +existing binding of {{{kbd(@key{TAB})}}} and replace it with the +function ~ebdb-complete-mail~. (Technically, in ~message-mode~, it +will ensure this function is called instead of ~message-expand-name~.) +#+END_defopt + +#+ATTR_TEXINFO: :options ebdb-mail-avoid-redundancy +#+BEGIN_defopt +If nil, mail completion will always insert a full "First Last +<first.l...@example.com>" string, even when the contact's name is +deemed to be redundant with the email address itself. If set to the +symbol ~mail-only~, the name will never be inserted. If any other +non-nil value, the name will be elided if it appears to be redundant. +#+END_defopt + +#+ATTR_TEXINFO: :options ebdb-complete-mail-allow-cycling +#+BEGIN_defopt +If non-nil, cycle mail addresses when completing mails. The exact +behavior of this setting depends a bit on the value of +~ebdb-complete-mail~. If completion at point is being used, this can +be set to an integer N, specifying that cycling may take place if +there are N or fewer candidate completion strings. If the function +~ebdb-complete-mail~ is being used, a non-nil value will allow cycling +among all of a single contact's mail addresses, once the contact +itself has been selected. +#+END_defopt + +#+ATTR_TEXINFO: :options ebdb-completion-display-record +#+BEGIN_defopt +If non-nil, display each newly-completed record in a pop-up +{{{buf(EBDB)}}} buffer. +#+END_defopt + +#+ATTR_TEXINFO: :options ebdb-complete-mail-hook +#+BEGIN_defopt +A hook run after a successful completion. +#+END_defopt + +#+ATTR_TEXINFO: :options ebdb-mail-abbrev-expand-hook +#+BEGIN_defopt +A single function called each time an alias is expanded in a +composition buffer. The function is called with two arguments: the +alias name, and the list of corresponding mail addresses. +#+END_defopt + +*** A Note on Completion +As mentioned above, EBDB completion can be done either using the +completion at point framework, or its own ~ebdb-complete-mail~ +function. The two don't behave exactly the same, however: completion +at point works from a pre-constructed list of strings, while +~ebdb-complete-mail~ conducts an actual search of the database. This +means that the former is faster, but the latter will find more +records, particularly if search options like ~ebdb-case-fold-search~ +are in effect. + * Specific MUAs ** Gnus EBDB has a little more support for Gnus than the other MUAs, for no @@ -741,7 +812,6 @@ A current limitation of this functionality is that it only works when composing a mail to a single recipient. If you mark several records in a {{{buf(EBDB)}}} buffer and compose a mail to them collectively, the mechanism will be bypassed. - * EBDB Buffers :PROPERTIES: :ID: 877ca77a-06d6-4fbf-87ec-614d03c37e30 @@ -1220,13 +1290,12 @@ imperfect: not all fields can be exported correctly. VCard version It's possible to write new formatters, documentation is forthcoming. * Completion -There are many Emacs completion frameworks out there, and libraries -exist providing EBDB support for helm, counsel, and company. These -libraries must be loaded from the package repositories, and provide -the commands ~helm-ebdb~, ~counsel-ebdb~, and ~company-ebdb~, -respectively. Counsel and company are made to be hooked into Emacs' -existing completion frameworks; the helm command must be called -explicitly. +There are many Emacs completion frameworks out there, and EBDB +provides custom commands for a few of them: ~ebdb-helm~, +~ebdb-counsel~, and ~ebdb-company~. Counsel and company are made to +be hooked into Emacs' existing completion frameworks; the helm command +must be called explicitly. For information about completion in mail +composition buffers, see [[id:f035aefc-53b1-4d05-b980-8ae0ac851275][Mail Address Completion]]. Another built-in library, @@texinfo:@file{@@ebdb-complete@@texinfo:}@@, uses an ephemeral pop-up @@ -1235,12 +1304,6 @@ Another built-in library, it for {{{kbd(@key{TAB})}}} in ~message-mode~ by calling ~ebdb-complete-enable~. -Several native EBDB commands involve choosing a record, or multiple -records. At present, the completion interface for these commands is a -bit random: several of the commands simply use ~completing-read~ -directly, which isn't right. At some point, all EBDB commands that -ask the user to select a record will become aware of the -currently-loaded completion frameworks. * Snarfing #+CINDEX: Snarfing text "Snarfing" refers to scanning free-form text and extracting diff --git a/ebdb.texi b/ebdb.texi index 7f08154..8104981 100644 --- a/ebdb.texi +++ b/ebdb.texi @@ -22,6 +22,7 @@ is included in the section entitled “GNU Free Documentation License.” (a) The FSF’s Back-Cover Text is: “You have the freedom to copy and modify this GNU manual.” + @end quotation @end copying @@ -103,6 +104,7 @@ MUA Interaction * Loading MUA Code:: * Display and Updating:: * EBDB and MUA summary buffers:: +* Mail Address Completion:: Display and Updating @@ -118,6 +120,11 @@ EBDB and MUA summary buffers * Summary buffer marks:: +Mail Address Completion + +* A Note on Completion:: + + Specific MUAs * Gnus:: @@ -200,7 +207,7 @@ alternately EBDB will look in the default location, found using @code{(locate-user-emacs-file "bbdb" ".bbdb)}. Then set @code{ebdb-sources} to a non-existent file name, and then run @code{ebdb-load} (or any of the other EBDB entry commands). You'll be prompted to create the new -database, and upgrade from BBDB. If any records could not be +database, and upgrade from BBDB@. If any records could not be upgraded, they will be displayed in an *EBDB Migration Errors* buffer. Migration bug reports are very welcome. @@ -211,7 +218,7 @@ You can also call the command @code{ebdb-migrate-from-bbdb} at any time. @subsection Variables and Options Many of the old BBDB customization options have been changed or -removed entirely in EBDB. It's probably best to put your BBDB +removed entirely in EBDB@. It's probably best to put your BBDB customizations aside, and set new EBDB options as you come across them. The most important options are detailed in this manual, you can also customize the ``EBDB'' group to see what's available. @@ -469,7 +476,7 @@ a record's main name will instead prompt to delete the whole record. Fields can be classed in a few different categories. Some are ``plumbing'' fields, that are present for all records, but not generally visible or user-editable: these include the creation date, timestamp, -and UUID. You can view these fields by hitting @kbd{T} on the +and UUID@. You can view these fields by hitting @kbd{T} on the record. Other fields are ``built-in'': basic fields that get special treatment. These include the name, mail, phone, address, and notes fields. EBDB comes with default classes for these fields: if you @@ -578,6 +585,7 @@ and receiving emails. * Loading MUA Code:: * Display and Updating:: * EBDB and MUA summary buffers:: +* Mail Address Completion:: @end menu @node Loading MUA Code @@ -611,7 +619,7 @@ the records referenced in that message. It can: Pop up a buffer displaying the records. @item Create new records, or alter existing records, based on information -provided by the MUA. +provided by the MUA@. @item Run automatic rules to edit the records. @item @@ -903,6 +911,77 @@ Format letter to use in the summary buffer format string to mark a record. Defaults to ``e''. @end defopt +@node Mail Address Completion +@section Mail Address Completion + +Emacs' two message-composition modes are @code{message-mode} and +@code{mail-mode}, the former having somewhat obsoleted the latter -- EBDB +supports both. + +The main use of EBDB in message composition is to complete email +addresses of contacts, obviously. The following options govern this +behavior: + +@defopt ebdb-complete-mail +If non-nil, EBDB will provide mail completion in mail composition +buffers. If it is the symbol @code{capf}, EBDB will add it's own +completion function to the local value of +@code{completion-at-point-functions}. Otherwise, it will clobber the +existing binding of @kbd{@key{TAB}} and replace it with the +function @code{ebdb-complete-mail}. (Technically, in @code{message-mode}, it +will ensure this function is called instead of @code{message-expand-name}.) +@end defopt + +@defopt ebdb-mail-avoid-redundancy +If nil, mail completion will always insert a full ``First Last +<first.last@@example.com>'' string, even when the contact's name is +deemed to be redundant with the email address itself. If set to the +symbol @code{mail-only}, the name will never be inserted. If any other +non-nil value, the name will be elided if it appears to be redundant. +@end defopt + +@defopt ebdb-complete-mail-allow-cycling +If non-nil, cycle mail addresses when completing mails. The exact +behavior of this setting depends a bit on the value of +@code{ebdb-complete-mail}. If completion at point is being used, this can +be set to an integer N, specifying that cycling may take place if +there are N or fewer candidate completion strings. If the function +@code{ebdb-complete-mail} is being used, a non-nil value will allow cycling +among all of a single contact's mail addresses, once the contact +itself has been selected. +@end defopt + +@defopt ebdb-completion-display-record +If non-nil, display each newly-completed record in a pop-up +*EBDB* buffer. +@end defopt + +@defopt ebdb-complete-mail-hook +A hook run after a successful completion. +@end defopt + +@defopt ebdb-mail-abbrev-expand-hook +A single function called each time an alias is expanded in a +composition buffer. The function is called with two arguments: the +alias name, and the list of corresponding mail addresses. +@end defopt + +@menu +* A Note on Completion:: +@end menu + +@node A Note on Completion +@subsection A Note on Completion + +As mentioned above, EBDB completion can be done either using the +completion at point framework, or its own @code{ebdb-complete-mail} +function. The two don't behave exactly the same, however: completion +at point works from a pre-constructed list of strings, while +@code{ebdb-complete-mail} conducts an actual search of the database. This +means that the former is faster, but the latter will find more +records, particularly if search options like @code{ebdb-case-fold-search} +are in effect. + @node Specific MUAs @chapter Specific MUAs @@ -1444,13 +1523,12 @@ It's possible to write new formatters, documentation is forthcoming. @node Completion @chapter Completion -There are many Emacs completion frameworks out there, and libraries -exist providing EBDB support for helm, counsel, and company. These -libraries must be loaded from the package repositories, and provide -the commands @code{helm-ebdb}, @code{counsel-ebdb}, and @code{company-ebdb}, -respectively. Counsel and company are made to be hooked into Emacs' -existing completion frameworks; the helm command must be called -explicitly. +There are many Emacs completion frameworks out there, and EBDB +provides custom commands for a few of them: @code{ebdb-helm}, +@code{ebdb-counsel}, and @code{ebdb-company}. Counsel and company are made to +be hooked into Emacs' existing completion frameworks; the helm command +must be called explicitly. For information about completion in mail +composition buffers, see @ref{Mail Address Completion}. Another built-in library, @file{ebdb-complete}, uses an ephemeral pop-up @@ -1459,13 +1537,6 @@ Another built-in library, it for @kbd{@key{TAB}} in @code{message-mode} by calling @code{ebdb-complete-enable}. -Several native EBDB commands involve choosing a record, or multiple -records. At present, the completion interface for these commands is a -bit random: several of the commands simply use @code{completing-read} -directly, which isn't right. At some point, all EBDB commands that -ask the user to select a record will become aware of the -currently-loaded completion frameworks. - @node Snarfing @chapter Snarfing @@ -1487,7 +1558,7 @@ the region is active, this command snarfs the current region, otherwise it snarfs the entire current buffer. Called as a function, it can accept a string as the first argument and snarfs that. The RECS argument, which cannot be passed interactively, is a list of -records that are assumed to be related to snarfable data in STRING. +records that are assumed to be related to snarfable data in STRING@. @end deffn @defopt ebdb-snarf-routines @@ -1536,7 +1607,7 @@ There is currently only one country library written for EBDB, fields. It parses and displays phone numbers and names correctly, and also allows users to search on Chinese names using pinyin. It can be installed from ELPA, and requires the @code{pyim} package, available on -MELPA. +MELPA@. The present dearth of libraries is a result of the author scratching his own itch. Contributions of new libraries are very welcome (see @@ -1745,7 +1816,7 @@ existing objects. This may be addressed in the future. @node Field Classes @section Field Classes -It's fairly easy to create your own custom field classes in EBDB. All +It's fairly easy to create your own custom field classes in EBDB@. All such fields should subclass the @code{ebdb-field-user} class, which sets up basic behavior. That base class provides for no slots at all, so your class must define the slots where the field data will be held. It @@ -2217,7 +2288,7 @@ two separate functions: @deffn Method ebdb-make-buffer-name Called with no arguments but the mode specializer, this function should return the string name of the *EBDB* buffer to be -associated with this MUA. Usually the function body will look like: +associated with this MUA@. Usually the function body will look like: @code{(format "*%s-<mua>" ebdb-buffer-name)}. @end deffn @@ -2259,7 +2330,7 @@ Return the text of the article signature, or nil. @end deffn @node Index -@unnumbered Index +@chapter Index @printindex cp