# -*- sentence-end-double-space: t -*-
#+TEXINFO_CLASS: info
#+TEXINFO_HEADER: @syncodeindex pg cp
#+AUTHOR: Eric Abrahamsen <eric@ericabrahamsen.net>
#+TITLE: EBDB Manual
#+SUBTITLE: This manual is for version 0.2, updated 29 July, 2017
#+TEXINFO_DIR_CATEGORY: Emacs
#+TEXINFO_DIR_TITLE: EBDB: (ebdb)
#+TEXINFO_DIR_DESC: Contact management package
#+TEXINFO_DEFFN: t
#+OPTIONS: *:nil num:t toc:2 h:4 num:3
#+MACRO: buf \ast{}$1\ast{}

* Copying
:PROPERTIES:
:COPYING:  t
:END:

Copyright \copy 2016 Free Software Foundation, Inc.

#+BEGIN_QUOTE
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
any later version published by the Free Software Foundation; with no
Invariant Sections, with the Front-Cover Texts being “A GNU Manual,”
and with the Back-Cover Texts as in (a) below.  A copy of the license
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_QUOTE
* Getting Started
Assuming you have no records you want to migrate from other contact
management software, it is enough to call the top-level ~ebdb~
command.  This will create a new database at the location specified by
~ebdb-sources~ (see [[id:9a02f8fb-01e2-4cd8-8166-608814a031f7][The EBDB Database]]), prompt you for a search
string, fail to find anything (because you don't have any records
yet), and finally open a {{{buf(EBDB)}}} buffer where you can start to
make new records (see [[id:692cde31-73be-4faf-b436-7eae8a5d02d1][Creating Records]]).
** Migration from BBDB
#+CINDEX: Migrating from BBDB
*** Record Migration
It's possible to migrate records from a BBDB file.  With your BBDB
customizations still in place, 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 {{{buf(EBDB Migration)}}} buffer.  Migration bug
reports are very welcome.
*** 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
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.

* The EBDB Database
:PROPERTIES:
:ID:       9a02f8fb-01e2-4cd8-8166-608814a031f7
:END:
EBDB supports multiple databases, and each database definition is
saved in a file on disk.  The default database class, ~ebdb-db-file~,
stores its contacts in the same file as the database itself, though
other database classes may store contacts elsewhere.

#+CINDEX: Creating a database
- User Option: ebdb-sources

  User option specifying one or more databases to load.  It can be a
  single element, or a list of elements.  Each element can be a
  filename, from which a database is loaded, or it can be an instance
  of a subclass of the ~ebdb-db~ class.  The database at the head of
  the list will be considered the default database.

Databases have a few user-facing settings:

- User Option: read-only

  If t, records can only be read from the database, not edited or
  deleted.

- User Option: auto-save

  Set to nil to prevent auto-saving of the database's records.

- User Option: buffer-char

  Set to a single character that will be displayed next to records in
  the {{{buf(EBDB)}}} buffer, indicating which database they belong
  to.

- User Option: disabled

  When t, the database will essentially be ignored -- no records will
  be read from it.  Setting this to t will only take effect on next
  restart; to disable a database immediately, use
  ~ebdb-disable-database~ below.

- User Option: record-class

  The default record class to use when creating new records in this
  database.  The default is ~ebdb-default-record-class~.

While it's possible to edit database definitions directly in the file,
it's safer to use the customization interface to do so from the
{{{buf(EBDB)}}} buffer.

- Key: d e, ebdb-customize-database db

  Use the customize interface to edit the definition of DB.

Records can be moved or copied from one database to another. It's also
possible for a single record to live in more than one database, though
this functionality is experimental. When a record is loaded from more
than one database, the two copies are compared using the "timestamp"
field, and the older copy is discarded.  In an {{{buf(EBDB)}}} buffer,
the following keys can be used to manipulate databases and their records.

- Key: d m, ebdb-move-record record to-db

  Move RECORD from its existing database to TO-DB.

- Key: d c, ebdb-copy-record record to-db

  Copy RECORD into TO-DB, leaving it in its existing database(s).

Other database-related commands:

- Key: d r, ebdb-reload-database db

  Reload all records from a database.  This also redisplays any of
  those records that were visible in {{{buf(EBDB)}}} buffers.

- Key: d d, ebdb-disable-database db

  This command disables a database, unloading all of its records and
  essentially ignoring it from now on.  The disabled state persists
  between restarts.  To re-enable a database, edit it using
  ~ebdb-customize-database~, set 'disabled to nil, and then reload it
  with ~ebdb-reload-database~.
* Creating Records
:PROPERTIES:
:ID:       692cde31-73be-4faf-b436-7eae8a5d02d1
:END:
#+CINDEX: Creating records
Create a record using "c" (~ebdb-create~) in the {{{buf(EBDB)}}} buffer.
With no prefix arg, this command will create an instance of the
default record class, in the database at the head of ~ebdb-sources~.

- User Option: ebdb-default-record-class

  The default record class to use when creating new records.

Alternately create a record using "C" (~ebdb-create-extended~), which
will prompt for a record class to use, as well as a database to store
the record in, if there is more than one.

You can also tell EBDB which record represents you:

- User Option: ebdb-record-self

  The value of this option should be the UUID of your own record.  You
  can find this by pressing "T" (to show all fields) on your record.

Currently this option's only use is to serve as a source for
~ebdb-user-mail-address-re~.
** Record classes
EBDB comes with two record classes, representing individuals
(~ebdb-record-person~) and organizations (~ebdb-record-organization~).
Records can have "roles" at organizations [[id:1398bd78-b380-4f36-ab05-44ea5ca8632f][Role Fields]].
** Record names
EBDB comes with two classes for name fields: "simple" and "complex".
Simple names are just a single string, complex names are split out
into surname, given names, suffix, etc.  All records have a single
canonical name: person records have a complex name, organization
records have a simple name.

In addition, person records can have one or more "aka" names, and
these akas can be either simple or complex.  When adding fields to a
record, the simple name class is labeled "nickname", and the complex
class is labeled "alt name".
* Record Fields
:PROPERTIES:
:ID:       4170bd36-64bf-44b4-87d0-29fbed968851
:END:
** Inserting New Fields
#+CINDEX: Inserting new fields
Pressing "i" (~ebdb-insert-field~) with point on a record will prompt
for a field type, then field values, and add the field to the record.
See below for more information about the various kinds of fields.

When entering field data, optional data can be skipped by entering a
blank string, or by pressing "C-g".  The first "C-g" will cancel the
current data prompt; the second "C-g" will cancel the creation of the
field altogether.  For instance, when creating address fields, EBDB
will allow you to create an arbitrary number of street lines.  When
you've added enough, either enter a blank string, or hit "C-g".
** Editing Existing Fields
#+CINDEX: Editing fields
Pressing "e" (~ebdb-edit-field~) with point on a field will allow you
to edit an existing field, with the previous values as defaults.

Alternately, press "E" (~ebdb-edit-field-customize~) to edit the
field's values using the Customize interface.  Some fields have slots
that can only be edited this way; other fields have slots that cannot
be edited at all once the field is created.
** Deleting Records and Fields
#+CINDEX: Deleting records and fields
Pressing "C-k" on a field will ask you for confirmation, then delete
the field.  Pressing "C-k" while point is on or before a record's main
name will instead prompt to delete the whole record.
** Field Types
:PROPERTIES:
:ID:       cb2190f4-f2e6-4082-9671-24e11e5cc0c6
:END:
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
different defaults, you can create new classes (inheriting from the
existing ones) and use those instead.  See [[id:a58993a8-0631-459f-8bd6-7155bb6df605][Hacking EBDB]] for more
information.

Besides the "plumbing" and "built-in" fields, all other fields are
"user" fields, and belong to one of two types: ~ebdb-field-user~ and
~ebdb-field-user-simple~.  The former is an abstract class, used to
build fields with more complicated structures.  The latter represents
a simple field with a string label and a string value, and no special
behavior.

When adding fields to a record, EBDB offers up all the known labels of
the simple user field class as possible choices.  Typing in an unknown
string will define a new label, which will be offered as a choice in
the future.

Fields built from ~ebdb-field-user~ will have their own string name.
EBDB comes with classes including "anniversary", "url", "id",
"relation", "role" and more.  Many of these fields have their own list
of labels (for instance, anniversary fields may be labeled "birthday",
"wedding", etc).

Loading secondary libraries may make more field types available.
*** Role Fields
:PROPERTIES:
:ID:       1398bd78-b380-4f36-ab05-44ea5ca8632f
:END:
One type of field worth mentioning in particular is the role field.
EBDB records come in two types at present: person and organization.
People have roles at organizations: jobs, volunteer positions, etc.
People are also likely to have roles at more than one organization.

When adding a role field to a record, you'll be prompted to choose the
relevant organization role, prompted for a string label denoting
eg.@@texinfo:@:@@ a job title, and prompted for a mail address that
belongs only to this role field (ie.@@texinfo:@:@@ an institutional
email address).  If the organization has a "domain" field type, and
the person has an existing mail address that matches that domain,
you'll be prompted to move that address to the role field.

When viewing organization records, the role fields for all related
person records are also displayed as part of the organization record.

If a person's role at an organization later comes to an end, the role
field can be deleted, or marked as "defunct", if record keeping is
desired.  This can only be done using the customize-based editing
interface (the "E" key on the role field).

In fact, in addition to a mail field, role fields can contain an
arbitrary number of other fields, representing metadata about the role
(an employee number, employment start date, etc).  The author has yet
to come up with a good interface for viewing and manipulating these
extra fields, however, so the functionality remains hidden.
Suggestions are very welcome.

Manipulating role fields is generally a little clunky, at present.
This will be addressed in future.

* MUA Interaction
One of EBDB's most important features is the ability to create, update
and display records based on messages received or sent in your mail
user agent(s).  In theory, EBDB can be integrated with any software
package, but it's most common to use it in conjunction with sending
and receiving emails.
** Loading MUA Code

MUA code is activated simply by loading the relevant library.  Keep in
mind that mail-reading clients and mail-sending clients are considered
separate MUAs.  For instance, if you use the Gnus package for reading
mail, and Message for sending it, you'll want two require statements:

#+BEGIN_SRC elisp
(require 'ebdb-gnus)
(require 'ebdb-message)
#+END_SRC

There are other packages that provide other MUA integration: these are
likewise activated simply by requiring the relevant library, named
"ebdb-<MUA>".  MUAs supported by EBDB include gnus, message, mh-e,
mu4e, rmail, and VM.
** Display and Updating

When a message is opened in an MUA, EBDB can do certain things with
the records referenced in that message. It can:

- Pop up a buffer displaying the records.
- Create new records, or alter existing records, based on information
   provided by the MUA.
- Run automatic rules to edit the records.
- Provide keybindings to manually edit the records.

Each of these functionalities is optional, and can be customized
independently of the others.
*** Pop-up Buffers
Each MUA associated with EBDB creates its own pop-up buffer, with a
name like {{{buf(EBDB-Gnus)}}} or {{{(buf(EBDB-Rmail)}}}.  MUAs will
re-use their own buffers, and will not interfere with buffers the user
has created using the ~ebdb~ command, or by cloning or renaming
existing buffers.

- User Option: ebdb-mua-pop-up

  If nil, MUAs will not automatically pop up buffers.  It is still
  possible to manually create the buffer using interactive commands
  (see below).

At present, there are *no* user customization options controlling the
size and layout of MUA pop-up buffers: each MUA creates the pop-up
according to hard-coded rules.  This will likely change in the future:
please complain to the author.
*** Auto-Updating Records
EBDB can automatically update the name and mail addresses of records
based on information in an MUA message. The first and most important
option governing this behavior is:

- User Option: ebdb-mua-auto-update-p

  This option determines how EBDB acts upon mail addresses found in
  incoming messages.  If nil, nothing will happen.  Other options
  include the symbols 'update (only find existing records, and update
  their name and mail fields as necessary), 'query (find existing
  records, and query about the editing and creation of new records),
  and 'create (automatically create new records).  A value of t is
  considered equivalent to 'create.  The option can also be set to a
  function which returns one of the above symbols.

This option only governs what EBDB does automatically, each time a
message is displayed.  The same process can be run interactively using
the commands below.  When updating records either automatically or
interactively, a few more options come into play:

- User Option: ebdb-add-name

  Whether to automatically change record names.  See docstring for
  details.

- User Option: ebdb-add-aka

  Whether to automatically add new names as akas.  See docstring for
  details.

- User Option: ebdb-add-mails

  How to handle apparently new mail addresses.  See docstring for
  details.

There are also options governing whether EBDB will consider a mail
address or not:

- User Option: ebdb-accept-header-alist

  An alist governing which addresses in which headers will be
  accepted.  See docstring for details.

- User Option: ebdb-ignore-header-alist

  An alist governing which addresses in which headers will be ignored.
  See docstring for details.

- User Option: ebdb-user-mail-address-re

  A regular expression matching the user's own mail address(es).  In
  addition to a regexp, this can also be the symbol 'message, in which
  case the value will be copied from ~message-alternative-emails~, or
  the symbol 'self, in which case the value will be constructed from
  the record pointed to by the option ~ebdb-record-self~.

*** Noticing and Automatic Rules

In addition to updating records' name and mail fields, it's possible
to run other arbitrary edits on records when they are referenced in a
message.  This process is called "noticing". Two hooks are run as a
part of noticing:

- User Option: ebdb-notice-record-hook

  This hook is run once per record noticed, with two arguments: the
  record, and one of the symbols 'sender and 'recipient, indicating
  where in the message headers the record was found.

- User Option: ebdb-notice-mail-hook

  This hook is run once per mail message noticed: if multiple
  addresses belong to a single record, it will be called once per
  address.  The hook is run with one argument: the record.

When a record is noticed, it will also call the method
~ebdb-notice-field~ on all of its fields.  Using this method requires
a bit of familiarity with [[info:elisp#Generic%20Functions][Generic Functions]]; suffice it to say that
the first argument is the field instance being noticed, the second
argument is one of the symbols 'sender or 'recipient, and the third
argument is the record being noticed.

*** Interactive Commands
:PROPERTIES:
:ID:       38166454-6750-48e9-a5e5-313ff9264c6d
:END:
Some interactive commands are also provided for operating on the
relevant EBDB records.  In message-reading MUAs, EBDB creates its own
keymap, and binds it to the key ";".  The following list assumes this
binding, and only specifies the further binding.  Ie, press ";:" to
call ~ebdb-mua-display-records~.

- Key: :, ebdb-mua-update-records

  If the option ~ebdb-mua-auto-update-p~ is nil, this command can be
  used to do the same thing, and will behave as if that option were
  set to 'query.

- Key: ;, ebdb-mua-display-all-records

  If the option ~ebdb-mua-pop-up~ is nil, this command can be used to
  do the same thing.

- Key: ', ebdb-mua-edit-sender-notes

  This command allows you to edit the notes field of the message
  sender.

- Key: ", ebdb-mua-in-ebdb-buffer

  This command moves point to the relevant EBDB pop-up buffer (popping
  the buffer up first, if necessary).  You can then issue commands in
  the EBDB buffer as usual, with the exception that "q" will move
  point back to the previously-selected window, rather than quitting
  the EBDB buffer.

- Key: s, ebdb-mua-snarf-article

  This command scans the body text of the current message, and
  attempts to snarf new record information from it.  Email addresses
  and names in the body text will be handled, as will information in
  the headers of forwarded mail, and information in the signature will
  be associated with the sender.  The user is always prompted before
  edits are made.  This functionality is highly unreliable, and
  probably won't work as advertised.

- Command: ebdb-mua-yank-cc

  Prompt for an existing {{{buf(EBDB)}}} buffer, and add addresses for
  all the records displayed there to the CC: line of the message being
  composed.  This command is not bound by default, because the EBDB
  keymap is not bound by default in message composition MUAs.

Other commands that are not bound to any keys by default:

- Command: ebdb-mua-display-sender

  Only display the sender.

- Command: ebdb-mua-display-recipients

  Only display the recipients.

- Command: ebdb-mua-display-all-recipients

  Only display recipients, using all mail addresses from the message.

** EBDB and MUA summary buffers

EBDB can affect the way message senders are displayed in your MUA's
summary buffer.  It can do this in two ways: 1) by changing the way
the contact name is displayed, and 2) by optionally displaying a
one-character mark next to the contact's name.
*** Sender name display
EBDB can "unify" the name displayed for a sender that exists in the
database.  In general, an MUA will display the name part of the From:
header in the mailbox summary buffer.  EBDB can replace that display
name with information from the database.  This only works for Gnus and
VM, which allow for overriding how message senders are displayed.  The
format letter (see below) should be added to
~gnus-summary-line-format~ for Gnus (which see), and
~vm-summary-format~ for VM (ditto).

- User Option: ebdb-message-clean-name-function

  A function used to clean up the name extracted from the headers of a
  message.

- User Option: ebdb-message-mail-as-name

  If non-nil, the mail address will be used as a fallback for new
  record names.

- User Option: ebdb-mua-summary-unification-list

  A list of fields used by ~ebdb-mua-summary-unify~ to return a value
  for unification.  See docstring for details.

- User Option: ebdb-mua-summary-unify-format-letter

  Format letter to use for the EBDB-unified sender name in an Gnus or
  VM summary buffer.  Defaults to "E".

*** Summary buffer marks
EBDB can display a one-character mark next to the name of senders that
are in the database -- at present this is only possible in the Gnus
and VM MUAs.  This can be done in one of three ways.  From most
general to most specific:

- User Option: ebdb-mua-summary-mark

  Set to a single-character string to use for all senders in the EBDB
  database.  Set to nil to not mark senders at all.

- Function: ebdb-mua-make-summary-mark record

  This generic function accepts RECORD as a single argument, and
  returns a single-character string to be used as a mark.

- Field class: ebdb-field-summary-mark

  Give a record an instance of this field class to use a
  specific mark for that record.

Marks are displayed in MUA summary buffers by customizing the format
string provided by Gnus or VM, and adding the EBDB-specific format
code:

- User Option: ebdb-mua-summary-mark-format-letter

  Format letter to use in the summary buffer format string to mark a
  record.  Defaults to "e".
* EBDB Buffers
:PROPERTIES:
:ID:       877ca77a-06d6-4fbf-87ec-614d03c37e30
:END:
EBDB can create several separate buffers for displaying contacts.
Typically, each MUA creates its own buffer, with names like
{{{buf(EBDB-Gnus)}}}, etc.  Users can also create their own buffers
that won't be interfered with by MUA pop-up action.  Calling the
~ebdb~ command directly will create such a "user-owned" buffer; it's
also possible to create more by using the ~ebdb-clone-buffer~ and
~ebdb-rename-buffer~ commands within existing EBDB buffers.

- User Option: ebdb-buffer-name

  The base string that is used to create EBDB buffers, without
  asterisks.  Defaults to "EBDB".

- Key: b c, ebdb-clone-buffer

  Prompt for a buffer name, and create a new EBDB buffer displaying
  the same records as the original buffer.

- Key: b r, ebdb-rename-buffer

  Rename the current EBDB buffer.  If this is done in a MUA pop-up
  buffer, the original buffer will be recreated next time the MUA
  requests another pop up.
** Searching
#+CINDEX: Searching the EBDB
The most general search is performed with "/ /", which searches on
many different record fields and displays the results.

The EBDB major mode provides many keys for searching on specific
record fields.  Most of these keys are used after one of three prefix
keys, which change the behavior of the search: "/" clears the buffer
before displaying the results, "|" searches only among the records
already displayed, and "+" appends the search results to the records
already displayed.

For instance, record name search is on the key "n", meaning you can
use "/ n", "| n", or "+ n".  Search keys that work this way are:

- "n": Search names
- "o": Search organizations
- "p": Search phones
- "a": Search addresses
- "m": Search mails
- "x": Search user fields (prompts for which field to search on)
- "c": Search records that have been modified since last save
- "C": Search by record class
- "D": Prompt for a database and display all records belonging to that
  database

Search commands that currently only work with the "/" prefix are:

- "/ 1": Prompt for a single record, and display it
- "/ d": Search duplicate records

Searches can be inverted:

- Key: !, ebdb-search-invert

  Invert the results of the next search.

Each user-created {{{buf(EBDB)}}} buffer keeps track of search history
in that buffer.  To pop back to previous searches, use:

- Key: ^, ebdb-search-pop
*** Changing Search Behavior

There are three ways to alter the behavior of EBDB searches.

- User Option: ebdb-case-fold-search

  An equivalent to the regular ~case-fold-search~ variable, which
  see.  Defaults to the value of that variable.

- User Option: ebdb-char-fold-search

  Controls whether character folding is used when matching search
  strings against record values.

- User Option: ebdb-search-transform-functions

  A list of functions that can be used to arbitrarily transform search
  strings.  Each function should accept a single string argument, and
  return the transformed string.  If the search criterion is not a
  string (some fields produce sexp search criteria) these functions
  will not be used.

Be careful of potential interaction between character folding and
transform functions.  Character folding works by calling
~char-fold-to-regexp~ on the search string, effectively replacing
foldable characters within the string using regular expressions.  This
process happens /after/ the transform functions have run, so there is
a possibility for unexpected search behavior.
** The Basics of ebdb-mode
EBDB buffers inherit from special-mode, and so the usual special-mode
keybindings apply.

- Key: n, ebdb-next-record

  Move point to the next record.

- Key: p, ebdb-prev-record

  Move point to the previous record.

- Key: N, ebdb-next-field

  Move point to the next field.

- Key: P, ebdb-prev-field

  Move point to the previous field.

- Key: c, ebdb-create-record

  Create a new person record in the primary database.

- Key: C, ebdb-create-record-extended

  Prompt for database and record class, then create a new record.

- Key: i, ebdb-insert-field

  Insert a new field into the record under point, or the marked records.

- Key: e, ebdb-edit-field

  Edit the field under point.

- Key: E, ebdb-edit-field-customize

  Use the extended customize interface to edit the field under point.

- Key: ;, ebdb-edit-foo

  Either insert/edit the record's notes field or, with a prefix arg,
  prompt for an existing field and edit it.

- Key: C-k, ebdb-delete-field-or-record

  With point on a record field, offer to delete that field.  With
  point on a record header, offer to delete the whole record.

- Key: RET, ebdb-record-action

  Run an "action" on the field under point. If multiple actions are
  provided, you'll be prompted to choose one.  Not all fields provide
  actions.  "RET" on a mail field will compose a message to that mail
  address

- Key: m, ebdb-mail

  Begin composing a message to the record under point.  With a prefix
  arg, prompt for the mail address to use; otherwise use the record's
  primary address.

- Key: t, ebdb-toggle-records-format

  Toggle between a multi-line and one-line display.

- Key: T, ebdb-display-records-completely

  Display all of a record's fields.

- Key: r, ebdb-reformat-records

  Redisplay the record under point.

- Key: o, ebdb-omit-records

  Remove the record under point (or marked records) from the buffer
  (does not delete the records).

- Key: I, ebdb-cite-records-ebdb

  Put a "citation" for the record under point (or marked records) onto
  the kill ring.  A "citation" is a name-and-mail string for the
  record.  Prompt for a style, meaning a textual mode.  With a prefix
  arg, arrange citations in a list, otherwise inline.

- Key: w f, ebdb-copy-fields-as-kill

  Copy the string value of the field under point to the kill ring.

- Key: w r, ebdb-copy-records-as-kill

  Copy a string representation of the whole record under point to the
  kill ring.

- Key: w m, ebdb-copy-mail-as-kill

  Copy a name-plus-mail string citation for the record under point to
  the kill ring.  These strings look like "John Q Public
  <john@public.com>".  By default this will use the record's primary
  address; supply a prefix arg to be prompted for which address to
  use.

- Key: g, revert-buffer

  Redisplay all visible records.

- Key: ?, ebdb-help

  Show a very brief help message.

- Key: h, ebdb-info

  Open this manual.

- Key: s, ebdb-save

  Save all databases.

- Key: q, quit-window

  Delete the {{{buf(EBDB)}}} window.

[[id:692cde31-73be-4faf-b436-7eae8a5d02d1][Creating Records]] and [[id:4170bd36-64bf-44b4-87d0-29fbed968851][Record Fields]] for more on record creation and
field manipulation.

** Marking
:PROPERTIES:
:ID:       73462a5d-2ec7-4a83-8b38-f5be8e62b376
:END:
Records can be marked and acted on in bulk.  The "#" key will toggle
the mark of the record under point.  "M-#" will toggle the marks of
all the records in the buffer, and "C-#" will unmark all records in
the buffer.  Many editing commands can act on multiple marked
records.
** Exporting/Formatting
:PROPERTIES:
:ID:       0f72cc06-99e4-45b1-aa32-14e909f0765e
:END:
It is possible to export (referred to as "formatting") records in
various ways.  The most common export format is that of the
{{{buf(EBDB)}}} buffers themselves, but other formats are possible.

At present, the only other supported format is VCard, and support is
imperfect: not all fields can be exported correctly.  VCard version
2.1 is unsupported: the only options are version 3.0 and 4.0.

- Key: f, ebdb-format-to-tmp-buffer

  This command prompts for a formatter, and formats the record under
  point to a temporary buffer.  Use [[id:73462a5d-2ec7-4a83-8b38-f5be8e62b376][marking]] to format multiple
  records.

- Key: F, ebdb-format-all-records

  Export all records in the database (not only those displayed) to a
  different format.

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.  These
libraries 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.

Another built-in library,
@@texinfo:@file{@@ebdb-complete@@texinfo:}@@, uses an ephemeral pop-up
{{{buf(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 selecting 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
information related to EBDB records from it.  For example, calling
~ebdb-snarf~ while the region contains the text "John Doe
<j.doe@email.com>" will find an existing contact or prompt to create a
new one, and then display that contact.

Snarfing is a work in progress: at present, only mail addresses, URLs
and nearby names are acted upon, and it often doesn't work correctly.

- Command: ebdb-snarf &optional string start end recs

  Extract record-related information from a piece of text.  Find,
  update, or create records as necessary, and then display them.  When
  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.

- User Option: ebdb-snarf-routines

  An alist of field class symbols and related regexps.  The regexps
  are used to collect text that is likely parseable by the
  ~ebdb-parse~ method of the field class.

- User Option: ebdb-snarf-name-re

  A list of regular expressions used to recognize names for a snarfed
  contact.  Searching names directly is mostly impossible, so names
  are only looked for in close proximity to other field data.

In MUAs, EBDB can also snarf the body of the article being displayed.
This is separate from the updating process, which only examines the
article headers.

- Command: ebdb-mua-snarf-article

  Snarf the body of the current article.  This will also snarf the
  headers of forwarded emails, and the signature.  With a prefix
  argument, only snarf the signature.
* Internationalization
#+CINDEX: Internationalization
EBDB comes with an internationalization framework that can provide
country- and region-specific behavior for certain fields.  This
functionality is initialized by loading the
@@texinfo:@file{@@ebdb-i18n@@texinfo:}@@ library.  This library does
nothing by itself, it simply provides hooks for other country-specific
libraries.

Country libraries that do not depend on other external libraries may
live within the EBDB codebase, in which case they will be loaded
automatically when ~ebdb-i18n~ is loaded.  Libraries with external
dependencies may be installed from the package repositories.  Because
function autoloading doesn't work with generic methods, you'll need to
require the libraries in addition to simply installing them.

There is currently only one country library written for EBDB,
@@texinfo:@file{@@ebdb-i18n-chn@@texinfo:}@@, for Chinese-related
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 ~pyim~ package, available on
MELPA.

The present dearth of libraries is a result of the author scratching
his own itch.  Contributions of new libraries are very welcome (see
[[id:5446ff9c-78ca-4e12-89cc-6d4ccd9b2b83][Writing Internationalization Libraries]]).  Also welcome, though less
enthusiastically, are requests for new libraries.

Internationalization libraries do not modify the database, and can be
safely unloaded.  They simply alter the way EBDB reads, parses and
displays field values, and can also store extra information
(eg.@@texinfo:@:@@ for searching purposes) in a record's cache.
Loading this library can (depending on country libraries' behavior)
increase database load times, though it should not significantly
affect search or display performance.

Actually, the internationalization library does alter database storage
in one way: address countries can be either stored as a string
(non-international-aware), or a three-letter symbol representing the
country code (international-aware).  EBDB will correctly display the
country name for either type of storage, regardless of whether the
internationalization library is loaded or not.

#+VINDEX: ebdb-i18n-countries
Country names are displayed in English by default, but users can alter
the display of some country names if they choose.

#+TEXINFO: @defopt ebdb-i18n-countries-pref-scripts
This is an alist of conses pairing string country names to symbol
labels---see the value of ~ebdb-i18n-countries~ for how to use it, and
to find the correct symbol label.  Values set in this option will
shadow the values in the variable.
#+TEXINFO: @end defopt

* Diary Integration
#+CINDEX: Diary integration
Some EBDB fields hold dates or anniversaries (most notably the
~ebdb-field-anniversary~ field).  It's possible to integrate this
information with Emacs' diary package (and from there to Org, via the
~org-agenda-include-diary~ option).  At present, you'll need to have
an actual diary file present at the location indicated by
~diary-file~, though the file can be blank.

- User Option: ebdb-use-diary

  If non-nil, EBDB fields with date information will attempt to add
  that information to the diary.

When viewing the calendar, you can use the "d" key to see diary
information for that day.

Support for this feature is rudimentary.  More customization options
are forthcoming.
* Mail Aliases
#+CINDEX: Mail aliases
You can give records a mail alias with the "mail alias" field,
available in the list of choices for inserting new fields.  You'll be
prompted for an alias, and an email address to use for the alias, if
the record has more than one.  If multiple records have the same
alias, then entering that alias in the To: or Cc: field of a message
composition buffer will expand to a comma-separated list of record
addresses.

At present, it's necessary to manually parse existing aliases with the
"A" key in a {{{buf(EBDB)}}} buffer.  This limitation will be removed
in the future.
* vCard Support
EBDB has rudimentary support for exporting to vCard format; this
functionality will be expanded in the future.  After loading the
@@texinfo:@file{@@ebdb-vcard@@texinfo:}@@ library, a vCard formatter
will be available when formatting EBDB records (see
[[id:0f72cc06-99e4-45b1-aa32-14e909f0765e][Exporting/Formatting]]).

Support for importing vCard files is on the EBDB roadmap, as is,
eventually, support for CardDav servers.
* Org Integration
EBDB has standard support for Org functionality: creating links to
EBDB records works as expected with "C-c l", and following a link will
open an {{{buf(EBDB)}}} buffer and display the linked record.

Typically, links are created using the record's UUID field -- these
links are fast and accurate -- but it's also possible to create links
that initiate an EBDB search, and return multiple records.  EBDB links
are of the format "ebdb:<field type>/<search string>".  The "field
type" is typically the name of an EBDB field class (for instance,
"ebdb-field-anniversary"), and opening a link of this sort results in
a search of all records for which <search string> matches the string
value of that particular field type.  For convenience, a few field
type shorthands are recognized: in addition to "uuid", there is
"mail", "phone", "address", "notes" and "tags" (see below).  For
instance, to create a link to all records with a 206 phone area code,
use "ebdb:phone/206", and to create a link to all records who work at
Google, use "ebdb:mail/google.com".

The @@texinfo:@file{@@ebdb-org@@texinfo:}@@ library also contains the
~ebdb-org-field-tags~ field class, allowing users to tag their
contacts with existing Org tags.  Completion is offered as expected.
The field doesn't do much else, at present, but in the future there
will be options for popping up an {{{buf(EBDB)}}} buffer alongside an
Org agenda buffer, etc.
* Citing Records
Often one wants to share contact information into other channels: for
instance, pasting a contact's name and mail address in a message
you're sending to someone else.  EBDB refers to this as "citing", and
provides a general interface to this through:

- Command: ebdb-cite-records

  This command is not bound in any mode, but can be called
  interactively.  It prompts for a record, then inserts a citation for
  the record into the current buffer.  In most text-mode buffers, the
  citation looks like "Some Name <some@email.com>".  In Org buffers,
  it is a link with a "mailto:" prefix.
* Hacking EBDB
:PROPERTIES:
:ID:       a58993a8-0631-459f-8bd6-7155bb6df605
:END:
EBDB is designed to be highly extensible.  In addition to the usual
customization options, it provides for subclassing of the three main
classes -- database, record, and field.  The behavior of EBDB can be
radically changed by creating new classes, or overriding the existing
methods of classes, without touching the original source code.  This
manual won't go into details about Emacs' object-orientation support:
see [[info:eieio#Top][EIEIO]] for information on defining classes, and [[info:elisp#Generic%20Functions][Generic Functions]]
for information on writing generic functions and methods.

The simplest customization involves changing the default classes used
for basic record and field types.

- User Option: ebdb-default-record-class

  The default class used for creating records.  This class will be
  used when creating records with "c" in ebdb-mode, or when
  automatically creating records (ie, from snarfing).  It's always
  possible to create a record of a different class by using "C" in
  ebdb-mode.

- User Option: ebdb-default-name-class

  The default class for complex names.  Simple names (used for
  organizations and nicknames) are always plain strings -- this option
  only governs the class used for articulated names of individuals,
  with separate slots for surname, given names, suffixes, etc.

- User Option: ebdb-default-mail-class

  The default class for mail fields.

- User Option: ebdb-default-phone-class

  The default class for phone fields.

- User Option: ebdb-default-address-class

  The default class for address fields.

- User Option: ebdb-default-notes-class

  The default class for notes fields.

If, for instance, you'd like to create a custom mail field and have
all records use that instead of the built-in one:

#+BEGIN_SRC emacs-lisp
  (defclass my-mail-field (ebdb-field-mail)
    ;; custom slots
    )

  (setq ebdb-default-mail-class my-mail-field)
#+END_SRC

Note that there are currently no facilities for changing the class of
existing objects.  This may be addressed in the future.
** Field Classes
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
should also provide a class option holding a human-readable string for
the class type.  As an example:

#+BEGIN_SRC emacs-lisp
  (defclass ebdb-field-gender (ebdb-field-user)
    ((gender
      :initarg :gender
      :initform unknown
      :type symbol
      :custom (choice
	       (const :tag "Female" female)
	       (const :tag "Male" male)
	       (const :tag "Other" other)
	       (const :tag "Unknown" unknown)
	       (const :tag "None/Not Applicable" none))))
    :human-readable "gender"
    :documentation "A field holding gender information about this record.")
#+END_SRC

Once the class itself is defined, there are three basic methods which
must be provided: ~ebdb-read~, which prompts the user for values used
to create a new field instance, ~ebdb-parse~, which accepts a string
or other data and creates a new field instance from it, and
~ebdb-string~, which returns a string representation of the field
instance.  The simplest field types only need to provide these three
methods.

The ~ebdb-read~ and ~ebdb-parse~ methods are static (class-level)
methods.  Both take an optional "slots" argument, which a plist of
slot values that will eventually be fed to ~make-instance~.  If values
are already present in the plist, these methods should /not/ override
them.  In addition, ~ebdb-read~ takes an optional "obj" argument,
which, if present, is an existing field instance that can be used to
provide default values for the new object.

#+BEGIN_SRC emacs-lisp
  (cl-defmethod ebdb-read ((class (subclass ebdb-field-gender))
                           &optional slots obj)
    (unless (plist-get slots :gender)
      (let ((gender (intern (completing-read
                             "Gender: " '(female male other unknown none)
                             nil t
                             (when obj (symbol-name (slot-value obj :gender)))))))
        (setq slots (plist-put slots :gender gender))))
    (cl-call-next-method class slots obj))

  (cl-defmethod ebdb-parse ((class (subclass ebdb-field-gender))
                            str &optional slots)
    (when (and (null (plist-get slots :gender))
               (member str '("female" "male" "other" "unknown" "none")))
      (setq slots (plist-put slots :gender (intern str)))
    (cl-call-next-method class str slots))

  (cl-defmethod ebdb-string ((field ebdb-field-gender))
    (symbol-name (slot-value field 'gender)))
#+END_SRC
*** Init and Delete Methods
It's also very common to define ~ebdb-init-field~ and
~ebdb-delete-field~ methods for classes.  These methods can be used to
maintain secondary data structures, or set up extra hashing for
records, or do any other supplemental work.  The one restriction is
that they must not change the database: they may not edit records or
their fields.  Both methods are called with the field instance as the
first argument, and the record the instance belongs to as an optional
second argument.  ~ebdb-delete-field~ also accepts an optional third
argument, "unload", which is non-nil when the record is being
unloaded, rather than deleted.

Both methods should always end with a call to ~cl-call-next-method~.

~ebdb-init-field~ is called:

1. When loading for the first time (records call ~ebdb-init-field~ on
   all of their fields after they're loaded).
2. When adding a new field instance to a record.
3. When editing an existing field instance (editing is a
   delete-and-create operation).

~ebdb-delete-field~ is called:

1. When deleting a field instance.
2. When deleting the record owning the field instance.
3. When editing an existing field instance (editing is a
   delete-and-create operation).
4. When unloading a record from the database (the optional third
   "unload" argument will be non-nil).
*** The Labeled Field Class
Many field classes maintain their own list of labels: ie, anniversary
fields can be labeled "birthday", "wedding", etc.  This functionality
can be added to fields by additionally subclassing the
~ebdb-field-labeled~ class, and then defining a variable that will be
used to hold labels, and pointing to it in the class-allocated
"label-list" slot.  Everything else is taken care of automatically.

#+BEGIN_SRC emacs-lisp
  (defvar my-field-label-list '("default1" "default2")
    "A list of labels for the my-labeled-field class.")

  (defclass my-labeled-field (ebdb-field-user ebdb-field-labeled)
    ((label-list :initform my-field-label-list)))
#+END_SRC
*** Actions
All field classes have a class-allocated slot called "actions".  The
value of this slot is a list of conses, for instance: ~("Browse URL"
. ebdb-field-url-browse)~.  Users can trigger these actions by
pressing "RET" while point is on the field in the {{{buf(EBDB)}}}
buffer, using a numeric prefix arg to select from multiple possible
actions, or the 0 prefix arg to be prompted for which action to take.

The functions in this list should accept two arguments, the record and
the field instance under point.
*** Custom Field Searching
In most cases, searching the EBDB database is a matter of prompting
for a regular expression, then matching that regexp against the result
of ~ebdb-string~ called on a field instance.

However, it is possible for field classes to provide more
sophisticated searching behavior, if desired.  When the user calls
~ebdb-search-user-fields~ in the {{{buf(EBDB)}}} buffer, he or she will be
prompted for a field class to search on.  When a field class is
chosen, it has the option to prompt for more complex search criteria.
This is done by overriding two matching methods: ~ebdb-search-read~,
and ~ebdb-field-search~.

~ebdb-search-read~ is a static (class-level) method.  Its only
argument is the field class being searched on.  It should prompt the
user for whatever search criterion it wants, then return that
criterion.  This can be nearly anything, so long as the matching
~ebdb-field-search~ can accept it.

The ~ebdb-field-search~ method accepts a field instance as the first
argument, and the search criterion as the second.  It should return
non-nil if the criterion somehow matches the field.  Note that it's
perfectly possible to write several ~ebdb-field-search~ methods,
dispatching on different criterion types, if that makes things easier.

In addition, fields that subclass ~ebdb-field-labeled~ can accept
search criterion as a cons: ~("label string"
. other-search-criteria)~.  The label string will first be matched
against the label of the instance, and then other-search-criteria will
be passed to the ~ebdb-field-search~ method as usual.
*** Formatting in the EBDB Buffer
Most fields will be displayed in the {{{buf(EBDB)}}} buffer simply using
~ebdb-string~.  It's possible to customize this display by overriding
the ~ebdb-fmt-field~ method.  Without going into too much detail, this
method dispatches on four arguments: the formatter, the field, a
"style" symbol argument (typically 'normal, 'oneline, 'compact',
'collapse or 'expanded), and the record being formatted.

Specify an ebdb formatter for the first argument to target
{{{buf(EBDB)}}} formatting.  Choices are ~ebdb-formatter-ebdb~ (for
all cases), or one of ~ebdb-formatter-ebdb-multiline~ or
~ebdb-formatter-ebdb-oneline~.  Keep in mind that many field classes
are not displayed at all in the oneline format.

An example: most fields are output with style set to 'normal, meaning
that it will use the value of ~ebdb-string~.  By default, formatters
display address fields in the 'collapse style, which is mapped to the
'oneline style, which simply drops everything after the first newline.

Say you still wanted addresses output on a single line, but you wanted
to provide a little more information on that line: the first line of
the street addresses, plus the city, plus the country.  You could
achieve that by overriding the 'collapse style like so:

#+BEGIN_SRC emacs-lisp
  (cl-defmethod ebdb-fmt-field ((_fmt ebdb-formatter)
				(field ebdb-field-address)
				(_style (eql collapse))
				(_record ebdb-record))
    "Give address fields a special 'collapse formatting."
    (with-slots (streets locality country) field
     (format "%s (%s, %s)" (car streets) locality country)))

#+END_SRC

The leading underscores on parameters are there to keep the compiler
quiet: the arguments are necessary for dispatch, but aren't actually
used in the body of the method.

** Writing Internationalization Libraries
:PROPERTIES:
:ID:       5446ff9c-78ca-4e12-89cc-6d4ccd9b2b83
:END:
Writing new internationalization libraries involves using generic
functions. [[info:elisp#Generic%20Functions][Generic Functions]].  It will also require a bit of
familiarity with EBDB's internals.

Internationalization affects three different field types: addresses,
phone numbers, and names.  It works by providing "i18n" versions of
common methods for those three fields:

| Regular method    | Internationalized method |
|-------------------+--------------------------|
| ebdb-read         | ebdb-read-i18n           |
| ebdb-parse        | ebdb-parse-i18n          |
| ebdb-string       | ebdb-string-i18n         |
| ebdb-init-field   | ebdb-init-field-i18n     |
| ebdb-delete-field | ebdb-delete-field-i18n   |

When the "ebdb-i18n" library is loaded and the left-column ("vanilla")
versions of field methods are called, EBDB first checks to see if a
valid "internationalized" (right-column) method exists.  If it does,
that method is used instead of the vanilla one.

What is a "valid internationalized method"?  That depends on the field
type.  Each field type uses a different key or "spec" to determine the
nationality or locality of the field instance.

- Address fields use a three-character symbol derived from the [[https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3][ISO
  316601 alpha 3]] country codes.  These codes can be found in the
  variable ~ebdb-i18n-countries~.
- Phone fields use the phone number's numerical country code as a
  spec.  These codes can be found in the variable
  ~ebdb-i18n-phone-codes~.
- Name fields are keyed to the symbol representing the script used to
  write them. Specifically, the first character CHAR of the name is
  tested in this way: ~(aref char-script-table CHAR)~, which returns a
  symbol.

How are these "specs" used?  Each internationalized version of the
above methods accepts the spec as an additional argument, which it is
able to specialize on.  Every country-specific method should check the
spec to see if it is relevant to that library. If so, it handles the
necessary behavior; if not, it passes by using ~cl-call-next-method~.
See the function signatures of each internationalized method to find
how to handle the extra argument, called SPEC.

Here's a concrete example:

Say we want to make sure all French phone numbers are represented by a
string that looks like "+33 05 12 34 56 79".  This is not how they are
stored in the database, but this is how they should be represented to
the user.  We need to override the ~ebdb-string-i18n~ method for the
phone field class.  This method takes two arguments -- the field
instance, and the country-code spec -- and needs to specialize on both
arguments.  The method signature will look like this:

#+BEGIN_SRC emacs-lisp
  (cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone)
                                  (_cc (eql 33))))
#+END_SRC

See the manual on generic functions for details; suffice it to say
that this method will only run when the first argument is an instance
of the ~ebdb-field-phone~ class (or a subclass), and the second
argument is the number 33.

Now we know that this method will only run for French phone numbers,
so we can format the number correctly:

#+BEGIN_SRC emacs-lisp
  (cl-defmethod ebdb-string-i18n ((phone ebdb-field-phone)
                                  (_cc (eql 33)))
    (with-slots (area-code number extension) phone
      (concat
       "+33 "
       (when area-code
         (format "%02d" area-code))
       (format "%s%s %s%s %s%s %s%s"
               (split-string number "" t))
       (when extension
         (format "X%d" extension)))))
#+END_SRC

Again this only affects the display of numbers, not how they are
stored in the database.

Note that, while phone numbers themselves are stored as strings (they
do not represent a quantity, after all), the country and area codes
are stored as numbers, precisely so that they can be specialized on
using ~eql~.

See the signatures of the other internationalized methods for how to
use them.  The symbol specs for country codes and script names can
also be specialized on with the ~eql~ specializer.
** Writing Integration For New MUAs
Theoretically EBDB can be incorporated into any Emacs package, but
it's most commonly used in conjunction with a mail user agent.  It
comes with support for a few MUAs out of the box, but integration with
a new one can be written fairly easily.

The first step of integration involves hooking the function
~ebdb-mua-auto-update~ somewhere into the MUA's operation.  For most
MUAs, the appropriate place is when a message or article is opened for
viewing by the user.  This allows EBDB to act on the information found
in that message.

The second step requires providing new versions of a handful of
generic functions.  All MUA-specific generic functions specialize on
the current major-mode, using the ~&context~ specializer.  See below
for examples.

When ~ebdb-mua-auto-update~ runs, it scans the headers of the current
article/message for name/mail data, and uses that data to locate,
create, edit, and display records.  It does this by calling the
generic function ~ebdb-mua-message-header~ with the string header name; it
is the responsibility of the MUA to implement this function, and
return the contents of the appropriate header.  For instance, in Gnus:

#+BEGIN_SRC emacs-lisp
  (cl-defmethod ebdb-mua-message-header ((header string)
                                     &context (major-mode gnus-summary-mode))
    "Return value of HEADER for current Gnus message."
    (set-buffer gnus-article-buffer)
    (gnus-fetch-original-field header))

#+END_SRC

The first argument is the string header, and the second is the
specializer on the current major-mode.  Possible header values include
those found in ~ebdb-message-headers~. Note that if you expect this
function to be called in more than one major-mode, you'll have to
provide multiple versions of the function.  The &context specializer
uses ~derived-mode-p~ behind the scenes, though, so if all the modes
derive from a single parent mode (and the behavior should be the same
in all derived modes) it is enough to specialize on the parent mode.

Some MUAs might need to do a bit of work to ensure that the article in
question is opened and set up properly:

- Function: ebdb-mua-prepare-article
  Called with no argument but the mode specializer, this function
  should do whatever is necessary to prepare the article.

Providing {{{buf(EBDB)}}} buffer pop-up support involves implementing
two separate functions:

- Function: ebdb-make-buffer-name
  Called with no arguments but the mode specializer, this function
  should return the string name of the {{{buf(EBDB)}}} buffer to be
  associated with this MUA.  Usually the function body will look like:
  ~(format "*%s-<mua>" ebdb-buffer-name)~.

- Function: ebdb-popup-window
  Called with no arguments but the mode specializer, this function
  should return a list of two elements: the window to be split to make
  room for the {{{buf(EBDB)}}} buffer window, and a float value
  between 0 and 1 indicating the size of the new {{{buf(EBDB)}}}
  buffer window, as a percentage of the window being split.

In addition, it might be nice to bind the ~ebdb-mua-keymap~ in the
MUA's mode-map.  This map provides bindings for some commonly-used
EBDB functions.

*** Article snarfing

EBDB can scan articles or messages for likely field information, and
prompt the user to add the fields to new or existing records---this is
done by the user with the interactive command
~ebdb-mua-snarf-article~.  In order to work, the MUA must be able to
provide that function with the text of the message body, and the text
of the message signature (if any).  This is done with two generic
functions:

- Function: ebdb-mua-article-body
  Return the text of the article body, or nil.

- Function: ebdb-mua-article-signature
  Return the text of the article signature, or nil.
* Index
:PROPERTIES:
:INDEX:    cp
:END:
