This file documents the Insidious Big Brother Database

This is edition 1.9 of the BBDB User Manual for BBDB version 1.50.

Copyright (c) 1991, 1992, 1993, 1994 Jamie Zawinski <jwz@lucid.com>

BBDB
****

BBDB is a rolodex-like database program for GNU Emacs.  BBDB stands for Insidious Big Brother Database, and is not, repeat, not an obscure reference to the Buck Rogers TV series.

It provides the following features:

  * Tight integration with mail and news readers, with little or no interaction by the user:

       * easy (or automatic) display of the record corresponding to the sender of the current message;

       * automatic creation of records based on the contents of the current message;

       * automatic addition of data to arbitrary fields of the record corresponding to the sender of the current message.

  * Listing all records which match a regular expression;

  * Listing all records which match a regular expression in a particular field (company or notes, for example);

Installation
============

This program consists of eleven files:

          bbdb-Makefile - a makefile for compiling this with unix `make'
          bbdb.texinfo  - the source to this documentation
          bbdb.el       - implementation of the database
          bbdb-com.el   - most of the user-level commands
          bbdb-vm.el    - interface to VM (View Mail)
          bbdb-rmail.el - interface to Rmail
          bbdb-gnus.el  - interface to GNUS
          bbdb-mhe.el   - interface to MH-E (Mail Handler)
          bbdb-hooks.el - other optional functionality
          mail-extr.el  - utilities for parsing RFC-822 email addresses
          defsubst.el   - an inline-function facility (a speed hack)
     		     This file is unnecessary if you have my byte-compiler

Put all of these files in some directory in your load-path, and byte-compile them.  (If you don't compile these files, the BBDB will be so slow as to be virtually unusable.)

You can compile everything with the shell command

     make -f bbdb-Makefile all

but that won't work if you don't have VM.  In that case, you can instead say

     make -f bbdb-Makefile rmail vm mhe gnus

(omitting the names of any packages you don't want to bother with). You will undoubtedly need to change some of the parameters at the top of the Makefile (see the comments there).

Put the following forms in your .emacs file.

     (autoload 'bbdb         "bbdb-com" "Insidious Big Brother Database" t)
     (autoload 'bbdb-name    "bbdb-com" "Insidious Big Brother Database" t)
     (autoload 'bbdb-company "bbdb-com" "Insidious Big Brother Database" t)
     (autoload 'bbdb-net     "bbdb-com" "Insidious Big Brother Database" t)
     (autoload 'bbdb-notes   "bbdb-com" "Insidious Big Brother Database" t)
     (autoload 'bbdb-insinuate-vm       "bbdb-vm"    "Hook BBDB into VM")
     (autoload 'bbdb-insinuate-rmail    "bbdb-rmail" "Hook BBDB into RMAIL")
     (autoload 'bbdb-insinuate-mh       "bbdb-mhe"   "Hook BBDB into MH-E")
     (autoload 'bbdb-insinuate-gnus     "bbdb-gnus"  "Hook BBDB into GNUS")
     (autoload 'bbdb-insinuate-sendmail "bbdb"       "Hook BBDB into sendmail")

If you want to take advantage of the VM features of the BBDB, then add the form (bbdb-insinuate-vm) to your ~/.vm file.

If you want to take advantage of the RMAIL features of the BBDB, then add the following line to your .emacs file:

     (setq rmail-mode-hook 'bbdb-insinuate-rmail)

If you want to take advantage of the MH-E features of the BBDB, then add the following line to your .emacs file:

     (setq mh-folder-mode-hook 'bbdb-insinuate-mh)

If you want to take advantage of the GNUS features of the BBDB, then add one of the following lines to your .emacs file:

     (setq gnus-Startup-hook 'bbdb-insinuate-gnus)	; for GNUS 3.14 or older
     (setq gnus-startup-hook 'bbdb-insinuate-gnus)	; for GNUS 3.15 or newer

If you want to take advantage of send-mail-mode features of the BBDB, then add the following line to your .emacs file:

     (setq mail-setup-hook 'bbdb-insinuate-sendmail)

Introduction
============

The database is a set of records, where each record corresponds to one person or organization.  Each record has several fields.  The built-in fields are:

name
     The name of this person, or none if it's an organization.

AKA
     A list of other names of this person.

company
     The name of this person's organization, or none.

net
     A list of this person's network addresses.

address
     A list of postal (physical) addresses for this person.

phone
     A list of telephone numbers for this person.

notes
     Random commentary.

In addition to these fields, you may define your own field-types, with the bbdb-insert-new-field command.  (see BBDB Mode).

The database itself lives in a file which is named by the variable bbdb-file, defaulting to ~/.bbdb.  The first time you use one of the BBDB commands, this file is read into an emacs buffer, and remains there.  As you make changes to the database, this buffer is changed as well, ensuring that if it is auto-saved, it will be saved in its most current state.

You can list the contents of the database with the command M-x bbdb.  You will be prompted for a regular expression, and all records which match that regexp in the name, company, network address, or any notes fields will be displayed.

A narrower search may be made by using the commands bbdb-name, bbdb-company, bbdb-net, or bbdb-notes instead, which limit their searches to the name, company, email address, and notes fields, respectively.  If these commands are given a prefix argument, the listing displayed will be one line per entry; otherwise, the full db entry will be shown on multiple lines.

The bbdb-notes command will prompt for the notes field to search (RET for all).  In this way you can limit your searches to the contents of one particular user-defined notes field.  (You can add user-defined fields with the bbdb-insert-new-field command; see BBDB Mode.)

There are several ways to add new entries to the Insidious Big Brother Database; the most straightforward is to use M-x bbdb-create, which will prompt you for all relevant information.  However, the easiest way is to allow them to be added automatically by one of the mail or news-reading interfaces (see Interfaces).

BBDB Mode
=========

The *BBDB* buffer is in BBDB mode, which has keybindings for manipulating the database.  Letters no longer insert themselves. Numbers are prefix arguments.  You can move around using the usual cursor motion commands.

e
     (bbdb-edit-current-field)  Edit the field on the current line.  If the cursor is in the middle of a multi-line field, such as an address or comments section, then the entire field is edited, not just the current line.

;
     (bbdb-edit-notes)  A shortcut for editing the NOTES field.

d, C-k
     (bbdb-delete-current-field-or-record) Delete the field on the current line.  If the current line is the first line of a record, then this deletes the entire record from the database (prompting first).

C-o
     (bbdb-insert-new-field) Inserts a new field into the current record, as opposed to editing an existing one.  You are prompted (with completion) for the type of field to insert (phone, address, notes, etc); if the string you type is not a known field type, you will be asked whether to add a new ``note'' field of that type.

     If you are inserting a new phone-number field, you can control whether it is a North American or European phone number by providing a prefix argument.  A prefix arg of ^U means it's to be a euronumber, and any other prefix arg means it's to be a a structured North American number.  Otherwise, which style is used is controlled by the variable bbdb-north-american-phone-numbers-p.

C-x C-t
     (bbdb-transpose-fields) This is like the transpose-lines command, but it is for BBDB fields.  If the cursor is on a field of a BBDB record, that field and the previous field will be transposed.

     With argument ARG, takes previous line and moves it past ARG fields.  With argument 0, interchanges the field that point is in with the field that mark is in.

     Both fields must be in the same record, and must be of the same basic type (that is, you can use this command to change the order in which phone-number fields are listed, but you can't use it to make an address appear before a phone number; the order of field types is fixed.)

n, p
     (bbdb-next-record, bbdb-prev-record)  Move to the next and previous displayed record, respectively.

t
     (bbdb-elide-record) Toggles whether the current record is displayed in a one-line listing, or a full multi-line listing.  With a numeric argument of 0, the current record will unconditionally be made elided; with any other argument, the current record will unconditionally be shown expanded.

     If *t is used instead of simply t, then the state of all records will be changed instead of just the one at point.  In this case, a numeric argument of 0 means that all records will unconditionally be made elided; any other numeric argument means that all of the records will unconditionally be shown expanded; and no numeric argument means that the records are made to be in the opposite state of the record under point.

o
     (bbdb-omit-record) Removes the current record from the display, but does not delete it from the database; it merely makes it seem as if the most recent search had not matched this record.  With a numeric argument, omit the next N records.  With a negative argument, go backwards.

m
     (bbdb-send-mail)  Begin composing mail to the person represented by the current record.  The first email address is used.  Normally, the mail-sending package which is used is determined by which mail-reading package is loaded; that is, if MH-E is loaded, then mh-send will be used; if VM is loaded, then vm-mail is used; otherwise, mail is used.  You can override this by setting the variable bbdb-send-mail-style to one of the symbols vm, mh, or mail.

     If *m is used instead of simply m, then mail will be sent to all of the folks listed in the *BBDB* buffer instead of just the person under point.

s, C-x C-s
     (bbdb-save-db)  Saves the BBDB file to disk.

r
     (bbdb-refile-record)  Merge the current record into some other record; that is, delete the record under point after copying all of the data within it into some other record.  this is useful if you realize that somehow a redundant record has gotten into the database, and you want to merge it with another.

     If both records have names and/or companies, you are asked which to use. Phone numbers, addresses, and network addresses are simply concatenated. The first record is the record under the point; the second is prompted for.  Completion behavior is as dictated by the variable bbdb-completion-type.

M-d
     (bbdb-dial) If you are on a Sun SparcStation with the sound option installed, this command will play the appropriate tones on the builtin speaker to dial the phone number corresponding to the current line.  If the point is at the beginning of a record, dial the first phone number.  This does not dial the extension.  This also does not dial the area code if it is the same as bbdb-default-area-code, unless a prefix argument is given.

     bbdb-dial-local-prefix
          Set this to a string of digits if your phone system requires you to dial some code to access an outside line.

     bbdb-dial-long-distance-prefix
          Set this to a string of digits if your phone system requires you to dial some code before dialing a long-distance number (one not in your local area code.)

f
     (bbdb-finger)  This command ``fingers'' the network address of a BBDB record.  If this command is executed from the *BBDB* buffer, it fingers the network address of the record which is at point; otherwise, it prompts in the minibuffer (with completion) for a user to finger.  With a numeric prefix argument, it fingers the Nth network address of the current record; with a prefix argument of ^U, it fingers all of them. The *finger* buffer is filled asynchronously, meaning that you don't have to wait around for it to finish; but fingering another user before the first finger has finished could have unpredictable results.

     If this command is executed from the *BBDB* buffer, it may be prefixed with * (as in *f instead of simply f), meaning to finger all of the users currently listed instead of just the one under point.  The numeric prefix argument has the same interpretation.

q
     (bbdb-bury-buffer)  Gets the *BBDB* buffer out of your face.

?
     (bbdb-help)  This displays a one-line help message in the minibuffer, showing some of the most common bbdb-mode commands.

i
     (bbdb-info)  This jumps from the *BBDB* buffer to this documentation.  If this documentation is installed in the standard place (the directory named by the variable Info-directory) in a file called bbdb or bbdb.info, then no further configuration is necessary to make this work.

     bbdb-info-file
          If this documentation is not installed in the standard Info directory, then you should set this variable to the name of the texinfo-formatted version of this file; the bbdb-info command will use this file instead.

Interfaces
==========

The BBDB interfaces itself with several message-handling packages, but certain parameters control its behavior depending on whether it is being used from within a mail reader or a news reader.

In all of these packages, two new keybindings will be added:

:
     (show-sender)  Displays the BBDB entry corresponding to the author of the current message.  If there is none, you will be asked whether to create one.

;
     (annotate-sender)  Lets you edit the notes field of the BBDB record corresponding to the sender of the current message.  If there is no record for the current author, you will be asked whether to create one.

It is possible to configure BBDB so that it automatically creates a record when it sees a message from a person who is not in the database. It is also possible to have text automatically added to the notes field of the corresponding record depending on the contents of the message headers.  See Customization Hooks

These keybindings (and several other features) will not be available unless you call the appropriate ``insinuation'' function; see Installation.

Mail Reading Interfaces
-----------------------

There are BBDB interfaces for the following mail readers:

  * RMAIL, from the standard emacs library;

  * MH-E, the Emacs interface to Mail Handler, from the standard emacs library.

  * View Mail, by Kyle Jones, version 5.31 or newer;

News Reading Interfaces
-----------------------

The only news reader which BBDB supports is GNUS, by Masanobu Umeda.  If anyone wants to write a BBDB interface to GNEWS (probably quite easy to do), please send it to me.

Mail Sending Interfaces
-----------------------

When sending mail, the keystroke M-TAB is bound to the function bbdb-complete-name.  This will take the string that you have typed (from point back to the preceding colon, comma, or the beginning of the line) and will complete that against the contents of the database.  What you have typed may be an initial subsequence of a person's full name or network address; if it completes ambiguously, then what you have typed will be replaced with the common portion of the matches.  Typing M-TAB again will show a list of possible completions.  If it completes unambiguously, then an address of the form User Name <email-address> will be inserted.  The variable bbdb-completion-type controls whether completion is done on real names, or network addresses, or both.

You must call the function bbdb-insinuate-sendmail to get this key binding.  See Installation

You can control what ``real name'' is inserted with the mail-alias property: if a record has a mail-alias property, then that is used instead of their name field.

If the variable bbdb-completion-display-record is true (the default) then when you successfully complete an address with M-TAB, the corresponding record will be appended to the *BBDB* buffer.  The buffer will not be displayed if it is not already visible, but the record will be displayed there.

When sending mail, you can use the command bbdb-yank-addresses to CC the current message to the people currently displayed in the *BBDB* buffer.  This is useful if you are in the midst of sending or replying to a message, and you decide to add some recipients. You can use one of the M-x bbdb commands to display the set of people that you want to CC the message to, and then execute this command to add them to the list.

If you are using my mail-abbrevs.el package, which uses the word-abbrev mechanism for mail aliases, then you can store your mail aliases in the BBDB instead of duplicating the information elsewhere.

If you want a mail alias to be defined for a person, simply add a mail-alias field to their record.  You may have multiple aliases for the same person; simply separate them with commas.

If more than one person has the same mail-alias, then that alias expands to the addresses of all of those people; in this way you can maintain mailing lists within the BBDB.

To actually define the aliases which are stored in the BBDB, call the function bbdb-define-all-aliases from your mail-setup-hook. This will search the database, and call define-mail-alias to define each of the resulting aliases.

Options
=======

There are many variables which control the behavior of the Insidious Big Brother Database, and there are many hook-variables which can be used to modify its behavior in more complex ways.  Several pieces of functionality are included which use the hooks in this way.

Customization Parameters
------------------------

bbdb-file
     The name of the file which contains your personal database.  Default: ~/.bbdb.

bbdb-default-area-code
     The default area code to use when prompting for a new phone number. Default: 415.  This must be a number, not a string.

bbdb-north-american-phone-numbers-p
     Whether syntax-checking of phone numbers should be enforced.  Default: t.  This only works for Bell-system phone numbers.  If this is true, then you can't enter invalid phone numbers, and all phone numbers are pretty-printed in the same way.  European phone numbers don't have as strict a syntax, however, so this is a harder problem for them (on which I am punting).

     You can have both styles of phone number in your database by providing a prefix argument to the bbdb-insert-new-field command.

bbdb-electric-p
     Whether bbdb mode should be ``electric'' like electric-buffer-list. Default: t.  Basically this means that when you type space after M-x bbdb, your window configuration will be restored to what it was before you invoked the db list.  (The bbdb-mode commands still work as well.)

     There are some problems with electric modes; for example, keyboard macros and incremental search don't work.  (This is not a bug in BBDB, but in electric.el.)

bbdb-case-fold-search
     Default: the same as case-fold-search.  case-fold-search is bound to this by M-x bbdb and related commands.  This variable lets the case-sensitivity of ^S and of the bbdb searching commands be different.

bbdb/mail-auto-create-p
     If this is t (the default), then VM, MH, and RMAIL will automatically create new bbdb records for people you receive mail from.  If this variable is a function name or lambda expression, then it is called with no arguments to decide whether an entry should be automatically created.  You can use this to, for example, not create records for messages which have reached you through a particular mailing list, or to only create records automatically if the mail has a particular subject.  See the variables bbdb-ignore-most-messages-alist and bbdb-ignore-some-messages-alist (see Predefined Hooks)

bbdb/news-auto-create-p
     If this is t (default: nil), then GNUS will automatically create new BBDB records for people you read messages by.  If this is a function name or lambda expression, then it is called with no arguments to decide whether an entry should be automatically created.  You can use this to, for example, create or not create messages which have a particular subject.  See the variable bbdb-auto-notes-alist (see Predefined Hooks).

     If you want to autocreate messages based on the current newsgroup, it's probably a better idea to set this variable to t or nil from your gnus-select-group-hook instead.

     To automatically remember users in certain groups, you can do something like

          (setq gnus-select-group-hook
            '(lambda ()
               (setq bbdb/news-auto-create-p
                     (or (string= "some.news.group" gnus-newsgroup-name)
                         (string= "other.news.group" gnus-newsgroup-name)))))

bbdb-quiet-about-name-mismatches
     If this is false (the default), then BBDB will prompt you when it notices a name change, that is, when the ``real name'' in a message doesn't correspond to a record already in the database with the same network address.  As in, ``John Smith <jqs@frob.com>'' versus ``John Q. Smith <jqs@frob.com>''.  If this is true, then you will not be asked if you want to change it (and it will not be changed.)

bbdb-use-alternate-names
     If this is false, then the BBDB will not use the AKA field. Otherwise (the default) then the mail and news interfaces will ask you if you want to add an alternate name when a name-change is noticed, and will ask you whether the new name should be made the primary one. Note that if bbdb-quiet-about-name-mismatches is true, you will not be asked any questions about alternate names.

bbdb-readonly-p
     If this is true (default: nil), then nothing will attempt to change the database implicitly, and you will be prevented from doing it explicitly.  If you have more than one emacs running at the same time, you might want to arrange for this to be set to t in all but one of them.

bbdb-auto-revert-p
     If this variable is true (default: nil) and the BBDB file is noticed to have changed on disk, it will be automatically reverted without prompting you first.  Otherwise you will be asked.  (But if the file has changed and you have made changes in memory as well, you will always be asked.)

bbdb-notice-auto-save-file
     If this is true (default: nil), then the BBDB will notice when its auto-save file is newer than the file is was read from, and will offer to revert.

bbdb-use-pop-up
     If true (the default), display a continuously-updating BBDB window while in VM, MH, RMAIL, or GNUS. Each time a new message is selected, the record corresponding to that message's sender will be displayed in another window.  The buffer in this other window will be in bbdb-mode, and all corresponding commands will be available.

     This buffer will be positioned on the screen by finding the tallest of the windows present, and splitting it such that the bottom bbdb-pop-up-target-lines lines of the window display the *BBDB* buffer.  With the default configurations of VM, MH, RMAIL, and GNUS, this means that the bbdb-list buffer will be just below the message-body buffer.

     If this is the symbol horiz, then the BBDB window will be stacked horizontally instead of vertically, if there is room to do that tastefully.

bbdb-pop-up-target-lines
     Desired number of lines in a VM/MH/RMAIL/GNUS pop-up BBDB window, default 5.

bbdb-completion-type
     Controls the behavior of the bbdb-complete-name command.  If nil (the default), completion is done across the set of all full-names and user-ids in the database; if the symbol name, completion is done on real-names only; if the symbol net, completion is done on network addresses only; if it is primary, then completion is done only across the set of primary network addresses (the first address in the list of addresses for a given user).  If it is primary-or-name, completion is done across primaries and real names.

bbdb-user-mail-names
     A regular expression identifying the addresses that belong to you.  If a message from an address matching this is seen, the BBDB record for the To: line will be shown instead of the one for the From: line.  If this is nil, it will default to the value of (user-login-name).

bbdb-always-add-addresses
     If this is t, then whenever the Insidious Big Brother Database notices a new email address corresponding to a person who is in the database, it will add it to the database.  If this is nil (the default), then whenever a new network address is noticed for a person in the database, you will be asked whether to add the address.  If this is the symbol never (really if it is not t and not nil) then new network addresses will never be automatically added.

bbdb-new-nets-always-primary
     If this is t, then when the Insidious Big Brother Database adds a new address to a record, it will always add it to the front of the list of addresses, making it the primary address.  If this is nil (the default), then you will be asked.  If this is the symbol never (really if it is not t and not nil) then new network addresses will always be added to the end of the list.

bbdb-canonicalize-redundant-nets-p
     If this is non-nil, redundant network addresses will be ignored. If a record has an address of the form foo@baz.com, setting this to t will cause subsequently-noticed addresses like foo@bar.baz.com to be ignored (since we already have a more general form of that address.)  This is similar in function to one of the possible uses of the variable bbdb-canonicalize-net-hook but is somewhat more automatic.  (This can't quite be implemented in terms of the canonicalize-net-hook because it needs access to the database to determine whether an address is redundant, and the canonicalize-net-hook is purely a textual manipulation which is performed before any database access.)

bbdb-message-caching-enabled
     Whether caching of the message->bbdb-record association should be used for the interfaces which support it (VM, MH, and RMAIL).  This can speed things up a lot.  One implication of this variable being true (the default) is that the bbdb-notice-hook will not be called each time a message is selected, but only the first time.  Likewise, if selecting a message would generate a question (whether to add an address, change the name, etc) you will only be asked that question the very first time the message is selected.

bbdb-elided-display
     Default: nil.  Set this to t to make the bbdb-display commands default to displaying one line per record instead of a full listing. Set this to a list of some of the symbols '(address phone net notes) to select those fields to be left out of the listing (you can't leave out the name field).

     This is the default state for M-x bbdb and friends.  You can have a different default for when the BBDB buffer is automatically updated by the mail and news interfaces by setting the variable bbdb-pop-up-elided-display.  If that variable is unbound, this variable will be consulted instead.

bbdb-pop-up-elided-display
     Default: unbound.  Set this to t if to make the pop-up BBDB buffer default to displaying one line per record instead of a full listing. Set this to a list of some of the symbols '(address phone net notes) to select those fields to be left out of the listing (you can't leave out the name field).

     The default state for M-x bbdb and friends is controlled by the variable bbdb-elided-display; this variable is the default for when the BBDB buffer is automatically updated by the mail and news interfaces.  If bbdb-pop-up-elided-display is unbound, then bbdb-elided-display the former will be consulted instead by mail and news.

bbdb-offer-save
     If t (the default), then certain actions will cause the BBDB to ask you whether you wish to save the database.  If nil, then the offer to save will never be made.  If not t and not nil, then any time it would ask you, it will just save it without asking.

The following variables apply only to the GNUS interface to BBDB.  To make use of them, you must add this forms to your .emacs file:

     (autoload 'bbdb/gnus-lines-and-from "bbdb-gnus")
     (setq gnus-optional-headers 'bbdb/gnus-lines-and-from)

bbdb/gnus-mark-known-posters
     If t (the default), then the GNUS subject list will contain an indication of those messages posted by people who have entries in the Insidious Big Brother Database (they will be marked with an asterisk.)

     You can change the character used to mark records on a record-by-record basis by adding a mark-char property to the record, whose value is be the string to display (preferably one character.)

bbdb/gnus-header-prefer-real-names
     Default: nil.  if t, then the GNUS subject list will display real names instead of network addresses.

bbdb/gnus-header-show-bbdb-names
     Default: t.  If both this variable and the bbdb/gnus-header-prefer-real-names variable are true, then for news messages from people who are in your database, the name displayed will be the primary name from the database, rather than the one from the From: line of the message.  This doesn't affect the names of people who aren't in the database, of course.

bbdb/gnus-lines-and-from-length
     Default: 18.  The number of characters used to display From: info in GNUS, if you have set gnus-optional-headers to bbdb/gnus-lines-and-from.

Customization Hooks
-------------------

All of the hooks variables described below may be set to a symbol or lambda expression, which will be funcalled; or may be set to a list of symbols or lambda expressions, each of which will be funcalled in turn. Almost all hooks in Emacs work this way.  But notice that some of the hooks described below are called with arguments.

bbdb-list-hook
     Hook or hooks invoked after the bbdb-list-buffer is filled in.  Invoked with no arguments.

bbdb-create-hook
     Hook or hooks invoked each time a new bbdb-record is created.  Invoked with one argument, the new record.  This is called before the record is added to the database.  Note that bbdb-change-hook will be called as well.

bbdb-change-hook
     Hook or hooks invoked each time a bbdb-record is altered.  Invoked with one argument, the record.  This is called before the database buffer is modified.  Note that if a new bbdb record is created, both this hook and bbdb-create-hook will be called.

bbdb-mode-hook
     Hook or hooks invoked when the *BBDB* buffer is created.

bbdb-notice-hook
     Hook or hooks invoked each time a bbdb-record is ``noticed,'' that is, each time it is displayed by the news or mail interfaces. Invoked with one argument, the new record.  The record need not have been modified for this to be called - use bbdb-change-hook for that. You can use this to, for example, add something to the notes field based on the subject of the current message.  It is up to your hook to determine whether it is running in GNUS, VM, MH, or RMAIL, and to act appropriately.

     Also note that bbdb-change-hook will not be called as a result of any modifications you may make to the record inside this hook.

     Beware that if the variable bbdb-message-caching-enabled is true (a good idea) then when you are using VM, MH, or RMAIL, this hook will be called only the first time that message is selected.  (The GNUS interface does not use caching.) When debugging the value of this hook, it is a good idea to set caching-enabled to nil.

bbdb-after-read-db-hook
     Hook or hooks invoked (with no arguments) just after the Insidious Big Brother Database is read in.  Note that this can be called more than once if the BBDB is reverted.  One possible use for this is to rename the .bbdb buffer; for example

          (setq bbdb-after-read-db-hook '(lambda () (rename-buffer " bbdb")))

     will cause the buffer visiting the bbdb-file to be called " bbdb".  The leading space in its name will prevent it from showing up in the buffer list.

bbdb-load-hook
     Hook or hooks invoked (with no arguments) when the Insidious Big Brother Database code is first loaded.

bbdb-canonicalize-net-hook
     If this is non-nil, it should be a function of one argument: a network address string.  (Note that, unlike the other hook-variables described above, this may not be a list of functions.)  Whenever the Insidious Big Brother Database ``notices'' a message, the corresponding network address will be passed to this function first, as a kind of ``filter'' to do whatever transformations upon it you like before it is compared against or added to the database.  For example: it is the case that CS.CMU.EDU is a valid return address for all mail originating at a machine in the .CS.CMU.EDU domain.  So, if you wanted all such addresses to be canonically hashed as user@CS.CMU.EDU, instead of as user@somehost.CS.CMU.EDU, you might set this variable to a function like this:

          (setq bbdb-canonicalize-net-hook
               '(lambda (addr)
                  (cond ((string-match
                           "\\`\\([^@]+@\\).*\\.\\(CS\\.CMU\\.EDU\\)\\'"
                           addr)
                         (concat (substring addr
                                   (match-beginning 1) (match-end 1))
                                 (substring addr
                                   (match-beginning 2) (match-end 2))))
                        (t addr))))

     You could also use this function to rewrite UUCP-style addresses into domain-style addresses, or any number of other things.

     This function will be called repeatedly until it returns a value EQ to the value passed in.  So multiple rewrite rules might apply to a single address.

     There is an example of the use of this variable in the file bbdb-hooks.el: the function sample-bbdb-canonicalize-net-hook.

The bbdb-canonicalize-net-hook is powerful in that it allows arbitrary rewriting of addresses, however, in many cases that is overkill.  The function bbdb-delete-redundant-nets can be used as a value of bbdb-change-hook to cause network addresses which appear to be ``redundant'' to be deleted each time a modification is made to a record.

This works as follows: suppose one gets mail from user@foo.bar.com, and then later gets mail from user@bar.com.  At this point, one can generally delete the user@foo.bar.com address, since the user@bar.com address is more general.  (See also the variable `bbdb-canonicalize-redundant-nets-p', which has the effect of ignoring subsequent addresses from user@quux.bar.com if the address user@bar.com is already known.)

VM users can cause their summary buffer to display the name of the message sender according to BBDB data, instead of according to the contents of the current message's headers.  In VM 5.40 or later, use the summary format control %UB" instead of "%F", and the current record name will be shown there if available.  If no entry is found it behaves like "%F".  See the documentation for vm-summary-format for more details.  Warning, this may significantly slow down summary generation for large folders.

Predefined Hooks
----------------

If the variable bbdb-change-hook is set to the symbol bbdb-timestamp-hook, then every record in the database will have a field named timestamp, which will always contain the date and time at which this record was created or last modified.

If the variable bbdb-create-hook is set to the symbol bbdb-creation-date-hook, then every record in the database will have a field named creation-date, which will contain the date and time at which this record was added to the database.

If the variable bbdb/mail-auto-create-p is set to the symbol bbdb-ignore-most-messages-hook, then the variable bbdb-ignore-most-messages-alist will determine which messages should have records automatically created for them.  The format of this alist is

     (( HEADER-NAME . REGEXP ) ... )

for example,

     (("From" . "@.*\\.maximegalon\\.edu")
      ("Subject" . "time travel"))

will cause BBDB entries to be made only for messages sent by people at Maximegalon U., or (that's or) people posting about time travel.

There may be only one entry per header in this alist: that is,

     (("From" . "addr1\\|addr2") ... )

is legal, but

     (("From" . "addr1") ("From" . "addr2") ... )

is not.

If the variable bbdb/mail-auto-create-p is set to the symbol bbdb-ignore-some-messages-hook, then the variable bbdb-ignore-some-messages-alist will determine which messages should have records automatically created for them.  This is the exact inverse of the semantics of the bbdb-ignore-most-messages-alist: the alist specifies which messages should not have records automatically created for them, instead of which should.  For example,

     (("From" . "mailer.daemon")
      ("To" . "mailing-list-1\\|mailing-list-2")
      ("CC" . "mailing-list-1\\|mailing-list-2"))

will cause BBDB entries to not be made for messages from any mailer daemon, or messages sent to or CCed to either of two mailing lists.

The variable bbdb/news-auto-create-p may be set to either of the above-mentioned functions as well, to get this behavior for netnews messages instead of mail messages.

If the variable bbdb-notice-hook is set to the symbol bbdb-auto-notes-hook, then the variable bbdb-auto-notes-alist may be used to automatically add text to the notes fields of the records corresponding to certain messages.  The format of this alist is

     (( HEADER-NAME
        (REGEXP . STRING) ... )
         ... )

for example,

     (("To" ("-vm@" . "VM mailing list"))
      ("Subject" ("sprocket" . "mail about sprockets")
                 ("you bonehead" . "called me a bonehead")))

will cause the text "VM mailing list" to be added to the notes field of the record corresponding to anyone you get mail from via one of the VM mailing lists.  If, that is, bbdb/mail-auto-create-p is set such that the record would have been created, or if the record already existed.

The format of elements of this list may also be

     (REGEXP FIELD-NAME STRING)

or

     (REGEXP FIELD-NAME STRING REPLACE-P)

meaning add the given string to the named field.  The field-name may not be name, aka, address, phone, or net (builtin fields) but must be either notes, company, or the name of a user-defined note-field.

     ("pattern" . "string to add")

is equivalent to

     ("pattern" notes "string to add")

STRING can contain \& or \N escapes like in the function replace-match.  For example, to automatically add the contents of the organization field of a message to the company field of a BBDB record, you can use this:

     ("Organization" (".*" company "\\&"))

(Note you need two \ to get a single \ into a lisp string literal.)

If STRING is an integer N, the Nth matching subexpression is used, so the above example could be written more efficiently as

     ("Organization" (".*" company 0))

If STRING is neither a string or an integer, it should be a function which is called with the contents of the field, and the result of the function call is used.

If the REPLACE-P flag is true, then the string replaces the old contents instead of being appended to it.

If multiple clauses match the message, all of the corresponding strings will be added.

If the string is being appended (REPLACE-P is false or not provided) then the new string is appended to the end of the existing field value, with an intervening newline.  So each piece of text automatically added to this field will go on its own line.

You can control what the separator is by putting a field-separator property on the symbol naming the field.  For example, to make text automatically added to a field named newsgroups be separated by commas, you could do

     (put 'newsgroups 'field-separator "; ")

This variable works for news as well.  You might want to arrange for this to have a different value when in mail as when in news.

There may be only one entry per header in this alist: that is,

      (("Subject" ("\\bfoo\\b" . "Foo!!")
                  ("bar" . "Bar!")))

will work, but

      (("Subject" ("\\bfoo\\b" . "Foo!!"))
       ("Subject" ("bar" . "Bar!")))

will not.

Here's a more complicated example: some people include bitmaps of themselves in their mail messages in an X-Face: header field. You can capture this field into the *BBDB* with the following:

     (setq bbdb-auto-notes-alist
           (append bbdb-auto-notes-alist
                   (list "x-face"
                         (list (concat "[ \t\n]*\\([^ \t\n]*\\)"
                                       "\\([ \t\n]+\\([^ \t\n]+\\)\\)?"
                                       "\\([ \t\n]+\\([^ \t\n]+\\)\\)?"
                                       "\\([ \t\n]+\\([^ \t\n]+\\)\\)?"
                                       )
                               'face
                               "\\1\\3\\5\\7"))))

(The calls to list and concat are just for readability, it could easily be a constant.)  The tricky bit here is that it strips out the newlines and whitespace used for header continuation, which are not actually a part of the face data.  So though the mail message may have the face data on multiple lines, the entry in the *BBDB* will be just one line.

bbdb-auto-notes-ignore is an alist of headers and regexps to ignore in bbdb-auto-notes-hook.  Each element looks like

     (HEADER . REGEXP)

for example,

     ("Organization" . "^Gatewayed from\\|^Source only")

would exclude the phony Organization: headers in GNU mailing-lists gatewayed to the gnu.* newsgroups.  Note that this exclusion applies only to a single field, not to the entire message.  For that, use the variable bbdb-auto-notes-ignore-all.

bbdb-auto-notes-ignore-all is an alist of headers and regexps which cause the entire message to be ignored in bbdb-auto-notes-hook. Each element looks like

     (HEADER . REGEXP)

for example,

     ("From" . "BLAT\\.COM")

would exclude any notes recording for message coming from BLAT.COM. Note that this is different from bbdb-auto-notes-ignore, which applies only to a particular header field, rather than the entire message.

The Mailing List
================

There is a mailing list for discussing BBDB: info-bbdb@lucid.com. To join, send mail to info-bbdb-request@lucid.com (don't forget the -request part or you'll look silly in front of lots of people who have the ability to remember it indefinitely...)

There is also a second mailing list, to which only bug fixes and new version announcements are sent; to be added to it, send mail to bbdb-announce-request@lucid.com.  This is a very low volume list, and if you're using BBDB, you really should be on it.

When joining these lists or reporting bugs, please mention which version you have.  You can find out with M-x bbdb-version.

The Latest Version
==================

The latest version is always available for anonymous FTP from lucid.com:/pub/hacks/bbdb.tar.Z.  It may also be found at archive.cis.ohio-state.edu:/pub/gnu/emacs/elisp-archive/packages/bbdb.tar.Z.

If you are on the bbdb-announce mailing list, you will receive patches as I release new versions.

Todo List
=========

  * Are there enough hooks?

  * Should notice when there are Reply-To: addresses.

  * Should notice Real-Name:, Full-Name:, and Senders-Name: fields.

  * Should have a command for merging together two divergent copies of a .bbdb file (in case you read mail on one machine and news on another, for instance.)

  * The *BBDB* buffer should be resized to exactly fit what it's displaying, even when not in ``electric'' mode.

  * It should be possible to do completion on last names as well as first names.

  * There should be better support for non-American addresses and phone numbers.

  * BBDB should notice the addresses and/or subjects of outgoing mail as well.

  * The interfaces should share more code.

  * Should reimplement ``electric'' mode to not be so broken.

  * Should notice phone numbers in .signatures (that shouldn't be hard; noticing postal addresses is real hard, though.)

  * Should have a command to snarf in the addresses in the CC line, and to search forward from point for an address and snarf that.

  * The bbdb-create-internal function should be more forgiving.

  * The *C-o keystroke should add a field to all displayed records. Perhaps *; should append some text to an arbitrary field of all displayed records.

  * More * commands in general, including *d.

  * The BBDB buffer is left at the top of the stack when GNUS is exited because GNUS runs its exit-hooks too early.  This should be fixed.

  * Should separate out the name and address namespaces.

  * Everybody yell at Kyle until he adds vm-select-message-hook.

  * This documentation should be written in NewSpeak.

Thanks
======

Thanks to everyone on the info-bbdb mailing list for many useful suggestions. This hack would be far less insidious without their input!

And special thanks to Sebastian Kremer, Joe Wells, Todd Kaufmann, Andy Norman, Ivan Vazquez, Stewart Clamen, Roland McGrath, Dave Brennan, Kimball Collins, Dirk Grunwald, Philippe Queinnec, Boris Putanec, Dave Disser, Francois Felix Ingrand, Sean Owens, Guido Bosch, Lance Brown, Tom Emerson, George Hartzell, Luis Miguel Silveira, Kimmo Suominen, Derek Upham, David Zuhn, Rod Whitby, Richard Mlynarik.

_
*

     in.sid.i.ous aj   \in-'sid-e-*s\
        [L insidiosus, fr. insidiae ambush, fr. insidere to sit in, sit on,
           fr. in- + sedere to sit -- more at SIT]
          1  a : awaiting a chance to entrap  TREACHEROUS
             b : harmful but enticing  SEDUCTIVE
          2  a : having a gradual and cumulative effect  SUBTLE
             b of a disease
               : developing so gradually as to be well established before
                 becoming apparent
       in.sid.i.ous.ly av
       in.sid.i.ous.ness n