\input texinfo
@setfilename vm-pcrisis.info
@settitle Personality Crisis for VM
@dircategory Emacs
@direntry
* VM-pcrisis: (vm-pcrisis).             Personality profiles control for VM
@end direntry

@iftex
@finalout
@end iftex
@c @setchapternewpage odd               % For book style double sided manual.
@c      @smallbook
@tex
\overfullrule=0pt
%\global\baselineskip 30pt      % For printing in double spaces
@end tex
@ifinfo
This is the documentation for Personality Crisis, an add-on for the
mail reader VM which allows you to manage personality profiles
automatically when you compose new mail messages or replies.

@table @asis
@item Copyright (C) 1999  Rob Hodges
@item Copyright (C) 2006-2008 Robert Widhopf-Fenk
@item Copyright (C) 2011 Uday S. Reddy
@end table

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@ignore
Permission is granted to process this file through TeX and print the
results, provided the printed document carries copying permission
notice identical to this one except for the removal of this paragraph
(this paragraph not being relevant to the printed manual).

@end ignore
@end ifinfo
@c
@include version.texinfo
@titlepage
@sp 6
@center @titlefont{Personality Crisis for VM}
@sp 4
@center VM Version @value{VERSION}
@sp 5
@page
@vskip 0pt plus 1filll
Copyright @copyright{} 1999  Rob Hodges
Copyright @copyright{} 2006-2008 Robert Widhopf-Fenk
Copyright @copyright{} 2011 Uday S. Reddy

Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
are preserved on all copies.

@end titlepage
@page
@ifnottex
@node Top, Introduction, , (DIR)

This is the documentation for VM Personality Crisis, an add-on for the VM
mail reader allowing you to control personality profiles used in composing
messages. 

It was originally written by Rob Hodges.

This manual corresponds to VM version @value{VERSION}.

@menu
* Introduction::             
* Setting Up::
* Miscellaneous Variables::     
* Debugging::                   
* Version History::         
* Variable Index::
* Function Index::
@end menu
@end ifnottex

The incompete list of Roberts who have been involved in vm-pcrisis:

@itemize @bullet
@item Rob Hodges
@item Robert Widhopf-Fenk
@item Robert P. Goldman
@item Robert Marshall
@end itemize 

@node Introduction, Setting Up, Top, Top
@chapter Introduction

The @strong{Personality Crisis} package is designed to manage multiple
``profiles'' (mail identities or mail accounts) during mail-sending.
It is based on a programmable system of condition-action rules, which is in
fact a lot more general than the management of profiles.  Other
applications of this technology may be developed in future.

Personality Crisis can look at the headers of a message you are replying to
or forwarding, or a message you are composing, and use that information to
customize the message composition.  Common customizations include inserting
particular ``From:'' or ``Reply-To:'' headers, inserting signatures or
boilerplate text in the message composition and choosing a MIME character
set for the outgoing message.  See @ref{Common Uses} below for further
ideas.

The Personality Crisis package is not automatically loaded as part of VM.
To use it, place the following line in your @code{vm-init-file}.

@lisp
(require 'vm-pcrisis)
@end lisp

As a quick start, you can also add a line similar to the following:

@lisp
(vmpc-my-identities "me@@company1.nil" "me@@home.nil" "me@@alterego.nil")
@end lisp

with your own email addresses.  VM-Pcrisis will set up each email address
with a standard action for using it as the ``From'' header. 
Every time you write message to an unknown recipient, it will prompt you
for the action to use, which is nothing but the ``From'' address to use.

This is a completely manual method of choosing mail profiles.
You obtain automation by using the customization features described in the
rest of the manual.

@menu
* Description::                 
@end menu


@node Description, , Introduction , Introduction
@section Description

Personality Crisis can look at the headers of a message you are replying
to or forwarding, or a message you are composing, and use that information
to customize the message composition.  You can also use it to
explicitly choose a profile when composing new messages.

@c ***************************************************************************

@c @node Functionality, Common Uses, Description, Introduction
@unnumberedsubsec Functionality
@anchor{Functionality}

Based on the headers of a message you are replying to, you can get
vm-pcrisis to perform these actions:

@itemize @bullet
@item 
Change or insert any headers you like in your reply.
@item 
Change or insert a signature in your reply.
@item 
Insert some text in the body of your reply.
@item 
Change any header in your reply to the value of some
header in the message you are replying to.
@item 
Call a specified lisp function before VM creates the reply.
@item 
Call a specified lisp function in the reply buffer.
@item 
Prompt you for a personality profile to use, and optionally,
remember to use that profile when sending messages to the same recipient
in the future.
@end itemize

Similar functionality is available when forwarding messages.  

Based on the headers of a message you are composing, it can perform these
actions:

@itemize @bullet
@item 
Change or insert any headers of your choice.
@item 
Change or insert a signature.
@item 
Insert specified text in the message body.
@item 
Call some functions in the message buffer.
@item 
Prompt you for a personality profile to use, and optionally,
remember to use that profile when sending messages to the same recipient
in the future.
@end itemize

If you wish, you can also have vm-pcrisis prompt you for a profile
when composing new mail, which is useful if you need to set up VM
variables for the composition.

If you wish to write your own functions to perform actions beyond the
built-in functionality, vm-pcrisis provides primitive functions for
accessing the contents of headers in the message you are
replying to as well as the message you are composing.

@c ***************************************************************************

@c @node Common Uses, Overview, Specific Abilities, Introduction
@unnumberedsubsec Common Uses
@anchor{Common Uses}

Here are some of the common uses of vm-pcrisis.

@itemize @bullet
@item
People with multiple e-mail addresses can automatically set up
headers such as ``From:'' and ``Reply-To:'', so that, for example, their
work email keeps going to their work account, and their private email to
their private account.

@item
People who like to have different nicknames and signatures for
different lists can do so.  (Well, uh, that's why it is called
Personality Crisis...)  You can select your
personality for new mail messages as well as replies.

@item
When people send you html-formatted email, you can have your reply 
automatically include a form letter explaining why they shouldn't, and
how to turn it off.  (Such a letter is not included with this package;
you'll have to write it yourself.)

@item
People who email in multiple languages can set up the encoding for the
reply, along with the keymap, ispell dictionary, attribution line for
citations, etc, in the reply buffer.

@item 
When you get email from a mailing list that has the ``Reply-To:''
header set for the whole list, automatically change the ``To:'' header in
your reply to point to the original sender instead.  (You can do the
reverse as well.)  VM allows you to do
this, but only if the correct reply address is in the "From" field.  

@item 
Automatically change the signature and various headers, etc, in a
new mail message after typing in the ``To:'' address.

@item 
Automatically remember which personality to use when sending to a
particular address.  

@item 
If you put your imagination to work while reading through this
manual, you'll probably think of other ways that vm-pcrisis can help
you.  Have fun!

@end itemize

@c ***************************************************************************

@node Setting Up, Miscellaneous Variables, Introduction, Top
@chapter Setting Up

When setting up variables for Personality Crisis, you begin by thinking
about what you want it to do when a certain condition occurs, either
when you are replying to or forwarding a message, or in the midst of
writing a message.

You define the condition in @code{vmpc-conditions}, and the action you
want vm-pcrisis to take in @code{vmpc-actions}, giving a name to each.
You then associate the condition with the action in
@code{vmpc-reply-alist} if it's one that relies on the headers of a
message you are replying to, @code{vmpc-forward-alist} if it's a message
you are forwarding, or @code{vmpc-automorph-alist} if it's based on the
headers of your own message.  You may also use
@code{vmpc-newmail-alist} to associate conditions with actions for new
messages, and @code{vmpc-resend-alist} for resending
(bounced) messages.  

If you want to use the @code{vmpc-automorph} function, which takes
actions based on the headers of a message you are composing, 
@ref{Automorph} to decide where you want to hook it in.

The remainder of this manual will provide more information about how to
do all of these things.  

@menu
* Conditions::     Defining conditions that fire actions
* Actions::        Defining actions to be run
* Rules::          Associating conditions with actions
* Automorph::      Running automatic actions for new mail
@end menu


@node Conditions, Actions, Setting Up, Setting Up
@c node-name, next, previous, up
@section Conditions

@c @menu
@c * The vmpc-conditions variable::  
@c * vmpc-conditions examples::    
@c @end menu

@c @node The vmpc-conditions variable, vmpc-conditions examples, vmpc-conditions, vmpc-conditions
@unnumberedsubsec The vmpc-conditions variable
@anchor{vmpc-conditions}

The @code{vmpc-conditions} variable is a list of conditions, each of which
can cause Personality Crisis to take a different action.  You give each
condition a unique, descriptive name.  The format of the list is
something like this:

@lisp
'(   ("condition name"
             (lisp-expression-1) )
     ("another condition name"
             (lisp-expression-2) )   )
@end lisp

The condition names are descriptive names for conditions that you define.
We use strings as names in this manual, but you can also use lisp symbols. 

The lisp-expression can be any expression in lisp that will evaluate to
nil if the condition is to be considered false, and non-nil if true.
(Don't be afraid, non-lispers, examples are coming...)  Personality
Crisis provides some functions which can be used there, in combination
with @code{and}, @code{or}, and @code{vmpc-xor} to produce a
fine-grained control over when your actions will trigger.

@itemize @bullet

@findex vmpc-folder-match
@item @code{vmpc-folder-match}
When doing replies, forwards and resends, this matches against the name of
the folder where the original message is located.

@findex vmpc-folder-account-match
@item @code{vmpc-folder-account-match}
When doing replies, forwards and resends, this matches against POP/IMAP
account name of the folder where the original message is located.  (These
are the account names defined via the variables @code{vm-pop-folder-alist}
and @code{vm-imap-account-alist}.)

@findex vmpc-header-match
@item @code{vmpc-header-match}
When doing replies, forwards and resends, this matches against the contents
of a header in the original message; when using the
@code{vmpc-automorph} function, it matches against a header in the message
you are composing.

@findex vmpc-only-from-match
@item @code{vmpc-only-from-match} 
When doing replies, forwards and resends, this matches against the contents
of the given headers in the original message; it is true only when @emph{all}
email adresses match the given regexp.


@findex vmpc-body-match
@item @code{vmpc-body-match} 
is just like @code{vmpc-header-match} but 
allows you to match against the text in the body of the message.

@findex vmpc-hceck-virtual-selector
@item @code{vmpc-check-virtual-selector}. 
If you are using @code{vm-avirtual.el} you can also use this
to check a virtual folder selector.

@findex vmpc-other-cond
@item @code{vmpc-other-cond} returns true when a specified condition earlier
in the list has been found true.  It's essentially a shortcut for
building more complex conditions from basic ones.

@findex vmpc-none-true-yet
@item @code{vmpc-none-true-yet} returns true if none of the conditions that
come before it in @code{vmpc-conditions} have returned true.  You can
optionally specify exceptions, so that it can act as a
"none-true-yet-except..." condition.  This is a very useful shortcut to
place last in the list, in order to trigger an action prompting you for
a profile to use.
@end itemize

You can also use @code{y-or-n-p} for interactive querying, if you always
want to have a choice in what to do when a certain condition occurs.

We will cover all of these in the examples that follow.  


@c ***************************************************************************

@c @node vmpc-conditions examples,  , The vmpc-conditions variable, vmpc-conditions
@c node-name, next, previous, up
@subsection vmpc-conditions examples
@anchor{vmpc-conditions examples}

Suppose you wanted to set up a condition that triggered when you replied 
to messages that came from a particular mailing list.  Looking at the
headers of these messages, (exposing all of them with @code{t} in VM), you
see that they always have a header like this:

Resent-Sender: foo-list-maintainer@@bar.baz.com

Then, in your ~/.vm file, you would have something like this:

@lisp
(setq vmpc-conditions '(
        ("foo-list messages"
        (vmpc-header-match "Resent-Sender"
                 "foo-list-maintainer@@bar.baz.com"))
))
@end lisp

This gives you a condition called "foo-list messages" which returns true
when the contents of the "Resent-Sender" header include a match for the
regular expression "foo-list-maintainer@@bar.baz.com".

-----------------------------------------------------------------

@subheading Regexp Aside #1:
Usually this will be perfectly adequate.  Of course, since the second
string is a regexp, this will also match
"foo-list-maintainer@@barybaz.com", but the odds that you'll come across
that are pretty low.  However, if the header contents had included
another regexp special character, it might not match at all.  The
easiest way to deal with both these problems is to wrap the string up in
a call to @code{regexp-quote}.  Like this:

@lisp
(setq vmpc-conditions '(
        ("foo-list messages"
        (vmpc-header-match "Resent-Sender"
                (regexp-quote "foo-list-maintainer@@bar.baz.com")))
))
@end lisp

@subheading Regexp Aside #2:
The @code{regexp-opt} function provides a convenient way of producing a
regexp to match against any number of strings.  Suppose the
"Resent-Sender" field could contain either
"foo-list-maintainer@@bar.baz.com" or "foo-list-bot@@bar.baz.com".  Then 
you could use @code{regexp-opt} like this:

@lisp
(setq vmpc-conditions '(
        ("foo-list messages"
        (vmpc-header-match "Resent-Sender"
                (regexp-opt '("foo-list-maintainer@@bar.baz.com"
                                "foo-list-bot@@bar.baz.com"))))
))
@end lisp

@subheading Regexp Aside #3:
If you write your own regular expressions instead of using
@code{regexp-quote} and @code{regexp-opt}, you should keep in mind that
they must be in lisp syntax.  In short, this means that you should use
two backslashes wherever you would usually use one, and if you use a
double-quote (") it should be escaped with a backslash to avoid
prematurely ending the string.  You can learn more about regexps from
your Emacs documentation.

@subheading Regexp Aside #4:
The behaviour of vmpc-header-match is to return true if a match for the
regular expression occurs anywhere in the contents of the header.  If
you want your regexp to only match the entire header contents, it should
begin with a caret (^) and end with a dollar sign ($).

-----------------------------------------------------------------

Alright, enough about regexps!  Let's get on with the example.  

Suppose the next thing you want to do is set up a condition that
triggers when somebody sends you one of those blasted HTML emails.
(When we look at @code{vmpc-actions} you'll see how you can automatically
include a form letter asking them not to do this in your reply.)  Your
setup might now expand to this:

@lisp
(setq vmpc-conditions '(
        ("foo-list messages"
        (vmpc-header-match "Resent-Sender"
                (regexp-quote "foo-list-maintainer@@bar.baz.com")))
        ("html messages"
        (vmpc-header-match "Content-type"
			    "multipart/alternative\\|html"))
))
@end lisp

Let's further suppose that foo-list is set up so that replies go to the
entire list, and that you haven't over-ridden this with
@code{vm-reply-ignored-reply-tos} because it's usually what you want.
But when somebody sends an html message to the list, you now have a
setup which results in your anti-html form letter being included in a
message to the whole list.  You'd rather it went to them personally.
Okay, let's set up some more refined conditions:

@lisp
(setq vmpc-conditions '(
        ("foo-list messages"
          (vmpc-header-match "Resent-Sender"
                (regexp-quote "foo-list-maintainer@@bar.baz.com")))
        ("html messages"
          (vmpc-header-match "Content-type"
			    "multipart/alternative\\|html"))
        ("plaintext messages from foo-list"
          (and (vmpc-other-cond "foo-list messages")
               (not (vmpc-other-cond "html messages"))))
        ("html messages from foo-list"
          (and (vmpc-other-cond "foo-list-messages")
               (vmpc-other-cond "html messages")))
        ("html messages not from foo-list"
          (and (vmpc-other-cond "html messages")
               (not (vmpc-other-cond "foo-list messages"))))
))
@end lisp

All of a sudden you have five conditions, but you'll only associate
the last three of them with actions.  The first two are just building
blocks for the others.  So now you can associate different actions with
each condition:  For html messages from foo-list, you can change the To: 
address in your reply to point to the original sender, as well as
including your anti-html form letter; for html messages not from
foo-list, just include the form letter; and for plaintext messages from
foo-list, set up your desired personality for a normal reply to the
list.  

What if you want a condition that always returns true, so you can
associate it with an action that you want performed every time?  It
would look like this:

@lisp
        ("condition that's always true"
          't)
@end lisp

-----------------------------------------------------------------

@subheading Aside:
If you want one that always triggers for replies, but not when using
@code{vmpc-automorph}, it would look like this:

@lisp
        ("condition that's always true for replies"
          (eq vmpc-current-state 'reply))
@end lisp

Similarly, for one that always triggers with automorph, but not for
replies, you'd have:

@lisp
        ("condition that's always true for automorph"
          (eq vmpc-current-state 'automorph))
@end lisp

-----------------------------------------------------------------

If you add that condition, and more to deal with other mailing lists and
situations, you might want to be prompted about what action to take when
none of the conditions match (except, of course, the one that's always
true).  This simplest way to produce such a condition (which you can
then associate with a prompting action) is to use
@code{vmpc-none-true-yet}.  So you'd end up with something like:

@lisp
(setq vmpc-conditions '(
        ("condition that's always true"
          't)
        ("foo-list messages"
          (vmpc-header-match "Resent-Sender"
                (regexp-quote "foo-list-maintainer@@bar.baz.com")))
        ("html messages"
          (vmpc-header-match "Content-type"
			    "multipart/alternative\\|html"))
        ("plaintext messages from foo-list"
          (and (vmpc-other-cond "foo-list messages")
               (not (vmpc-other-cond "html messages"))))
        ("html messages from foo-list"
          (and (vmpc-other-cond "foo-list-messages")
               (vmpc-other-cond "html messages")))
        ("html messages not from foo-list"
          (and (vmpc-other-cond "html messages")
               (not (vmpc-other-cond "foo-list messages"))))

        ;; any number of other conditions could go here

        ("unknown sender"
          (vmpc-none-true-yet "condition that's always true"))
))
@end lisp

It's also possible to match against the text in the body of a message
you are replying to, forwarding or composing.  If you wanted to check
whether the phrase "make money fast" appeared in a message, you'd have 
a condition like this:

@lisp
("message from an idiot"
        (vmpc-body-match "make[\n ]+money[\n ]+fast"))
@end lisp

Note how the regexp is constructed in order to take account of the
fact that the phrase may be split over more than one line.  

Both @code{vmpc-header-match} and @code{vmpc-body-match} are affected
by your default value of @code{case-fold-search}.  If you wanted to
force a case-sensitive search in the previous example, you'd re-write
it like this:

@lisp
("message from an idiot using all-caps"
        (let ((case-fold-search nil))
          (vmpc-body-match "MAKE[\n ]+MONEY[\n ]+FAST")))
@end lisp

Similarly, if you wanted to force it to be case-insensitive, you'd do
this:

@lisp
("message from an idiot using any case"
        (let ((case-fold-search t))
          (vmpc-body-match "make[\n ]+money[\n ]+fast")))
@end lisp


You can use @code{vmpc-header-match} to test if a regexp appears in any
header field matching another regexp.  For example, to find out if the
regexp "fire\\|water" appears in any header, you would use something
like 
@lisp
(vmpc-header-match "[^ \t\n:]+:" "fire\\|water" ", ")
@end lisp

Essentially what this does is to take the contents of every header in
the message, put them all together in a gigantic string -- separated
from each other by a comma and a space -- and run 
@lisp
(string-match "fire\\|water" gigantic-string-of-all-headers)
@end lisp

In the event that you want to look for a regexp that includes ", " you
can use a different string as the separator to ensure that a match
doesn't span the contents of different headers.

The above header field regexp checks every single header -- even the
X-VM-v5-Data header.  You could use a more restrictive regular
expression for the header name if you prefer.  For example, to check
only the From: and Apparently-To: headers, you could use
@lisp
(vmpc-header-match "From:\\|Apparently-To:" "fire\\|water" ", ")
@end lisp


What if you have an action that you only want to perform if the message
is from foo-list and doesn't have "bar" in the subject, or the message
is not from foo-list and does have "bar" in the subject, or if the
message has "quux" in the subject, regardless of whether it's from
foo-list or not?  And what if, even then, you only want the action
performed if you answer yes to a prompt?  Here's what the condition
would look like:

@lisp
("a complex condition"
  (and
    (or  (vmpc-xor (vmpc-other-cond "foo-list-messages")
                   (vmpc-header-match "bar"))
         (vmpc-header-match "quux"))
    (y-or-n-p "Perform action for complex condition? ")))
@end lisp

It will only prompt you if the @code{or} part is true, because that's how the 
@code{and} form works in elisp --- it stops evaluating its arguments after the 
first false one it finds.  

Okay, I believe I've gone into much more depth here than the average
user will ever need; the point is that with a little lisp knowledge you
can have as fine a control over the automated actions of vm-pcrisis as you
need.  Even without real lisp knowledge, I hope that you can figure out
enough from these examples to achieve such control.

@c ***************************************************************************

@node Actions, Rules, Conditions, Setting Up
@c node-name, next, previous, up
@section Actions

@c @menu
@c * The vmpc-actions variable::   
@c * vmpc-actions examples::       
@c @end menu

@c @node The vmpc-actions variable, vmpc-actions examples, vmpc-actions, vmpc-actions
@unnumberedsubsec The vmpc-actions variable
@anchor{vmpc-actions}

The @code{vmpc-actions} variable is a list of actions, which can equally
be referred to as "profiles".  You will set up some of them for replies,
some for @code{vmpc-automorph} (if you use it), and some for when you are
prompted for a profile (if you have an action that uses
@code{vmpc-prompt-for-profile}).  Many will be equally applicable in all
three cases, which is why they are all kept in the same place.

Each action is given a unique, descriptive name, and consists of one or
more function calls, so that the format of the list looks something like
this:

@lisp
'(  ("foo"
        (function-1 arg1 arg2)
        (function-2)
        (function-3 arg1))
    ("bar"
        (function-4))  )
@end lisp

This will start making sense with the real examples in the next section.
But first, we'll look at what functions are available here:

@itemize @bullet

@findex vmpc-signature
@item (vmpc-signature "signature-file") will replace the signature in
your message with the contents of the specified file, if it exists;
otherwise the string itself will be used as the signature.

@findex vmpc-pre-signature
@item (vmpc-pre-signature "pre-signature-file") works in the same way,
but specifies a "pre-signature" --- text that is inserted in your message
above the signature.  

@findex vmpc-substitute-header
@item (vmpc-substitute-header "Header-Field" "new header contents") will 
replace the contents of the specified header-field in your message with
the new contents, creating the header field if necessary.

@findex vmpc-substitute-replied-header
@item (vmpc-substitute-replied-header "Dest-Header" "Src-Header") takes
the contents of the Src-Header field in the message you are replying to,
and inserts them as the contents of the Dest-Header field in your
reply, creating the Dest-Header field if necessary.  (If it's contained
in an action which is called when you are not replying to a message, it
does nothing.  The same is true of all of these functions: when they are
called in an inappropriate context, they only do as much as they can.)

@findex vmpc-pre-function
@item (vmpc-pre-function (foo-function args)) evaluates the lisp
expression 
@lisp 
(foo-function args) 
@end lisp 
before VM creates a mail composition buffer.  (This is useful for setting 
VM variables which need to be set at this stage, such as the message
encoding.)  It therefore does nothing in automorph mode.  

@findex vmpc-composition-buffer
@item (vmpc-composition-buffer (foo-function args)) does the
same, but in the composition buffer.  

@findex vmpc-prompt-for-profile
@item (vmpc-prompt-for-profile arg) prompts the user for a profile
(action) to run.  (The user would be well advised not to choose one
which itself contains this function!)  If ARG is present, it should be
set to 'prompt or t.  The presence of ARG indicates that you want
it to check who your message is destined for, and remember to apply the
profile you choose now to messages sent to that person in the future,
instead of prompting you for a profile the next time.  If set to
'prompt, it will ask whether it should remember; if set to t, it
will always remember.  If ARG is not present, it does not remember.

@end itemize

Do not include your own functions in actions directly; call them with
@code{vmpc-pre-function} or @code{vmpc-composition-buffer}
instead -- otherwise they will be called twice, both before and after the
composition buffer is created.

@c ***************************************************************************

@c @node vmpc-actions examples,  , The vmpc-actions variable, vmpc-actions
@c node-name, next, previous, up
@unnumberedsubsec vmpc-actions examples
@anchor{vmpc-actions examples}


In your ~/.vm you'll have something like this:

@lisp
(setq vmpc-actions '(
        ;; actions go here
))
@end lisp

Okay, here come some example actions which you can adapt and place, one
after the other, in the place of the comment above.

Say you wanted two personality profiles from which you could choose when
prompted, and to automatically apply when certain conditions were met
with replies or in automorph mode.  One thing to bear in mind is that
when you are prompted, there will be auto-completion available --- you'll
only need to type enough to uniquely identify a profile (you won't even
need to hit TAB).  Also, the first profile in @code{vmpc-actions} will
be the default at the prompt, so you can just hit RET to use it.
Therefore, the first profile you place in @code{vmpc-actions} should be
the one you expect to use most often, and you should choose names for
profiles which uniquely distinguish themselves at the first or second
character.

Okay, here are a couple of profiles which show how to insert signatures
and change the contents of a header field.  

@lisp
("foo on the hill"
  (vmpc-substitute-header "From" 
        "\"The Foo On The Hill\" <foo@@hill.com>")
  (vmpc-signature "~/.foo-sig"))
("david"
  (vmpc-substitute-header "From"
        "\"David Foo\" <foo@@hill.com>")
  (vmpc-signature ""))
@end lisp

When an empty string is given as the signature, as in the second
profile, vm-pcrisis will actually remove any signature that has been
placed there by other actions.  

Also note that by including a From: header, we override the values of
@code{user-full-name} and @code{user-mail-address}.

We could equally well have chosen to override those values directly
using composition-buffer-functions, like this:

@lisp
("foo on the hill"
  (vmpc-composition-buffer 
     (setq user-full-name "The Foo On The Hill")
     (setq user-mail-address "foo@@hill.com"))
  (vmpc-signature "~/.foo-sig"))
("david"
  (vmpc-composition-buffer 
      (setq user-full-name "David Foo"))
      (setq user-mail-address "foo@@hill.com"))
  (vmpc-signature ""))
@end lisp

If we had two different mailboxes and wanted to direct replies back into
the right one, we would want to also set @code{mail-default-reply-to},
or use @code{vmpc-substitute-header} to insert a Reply-To: header.

-----------------------------------------------------------------

@subheading Aside:
Why did we use @code{vmpc-composition-buffer} rather than
@code{vmpc-pre-function} to set those variables?  Well, their values are
only examined when you actually send your message, so you could equally
well set them with either, but the @code{vmpc-automorph} function does
not run pre-functions, so if we want these profiles to work properly for
automorph, we need to use composition-buffer-functions.

In other cases, such as setting VM's charset variables, you have no
option but to use pre-functions, because they have to be set to
appropriate values before the composition buffer is created.  If anyone
finds a workaround for this, please let me know so I can include it
here.

-----------------------------------------------------------------

Pre-signatures can be specified in the same way as signatures:

@lisp
("insert anti-html form letter"
  (vmpc-pre-signature "~/stuff/formletters/why_html_is_bad.txt"))
@end lisp

Alright, suppose that messages from foo-list have their Reply-To: header
set to point back to the list, with the address of the real sender in
the From: field.  We could override it with
@code{vm-reply-ignored-reply-tos}, but usually we prefer this behaviour.
Only under certain conditions do we want to set our To: field to the
contents of the From: field in the replied message.  The action to do
this would look like this:

@lisp
("set To to From"
  (vmpc-substitute-replied-header "To" "From"))
@end lisp

Let's say we also want an action that can prompt us for a profile, so
we can associate it with an "unknown sender" condition.  Here we go:

@lisp
("prompt for a profile"
  (vmpc-prompt-for-profile))
@end lisp

If we want vm-pcrisis to figure out who our message is destined for and to
remember to use the profile we choose the next time we send to that
address instead of prompting, we would do it like this:

@lisp
("prompt for a profile, and remember it automatically"
  (vmpc-prompt-for-profile t))
@end lisp

The associations between addresses and profiles will be stored in the
file named by @code{vmpc-auto-profiles-file} --- by default, this is
"~/.vmpc-auto-profiles".  If your OS has a shonky filesystem that can
not deal with filenames like that, you might have to change this value.

Keep in mind that the associations stored in this file are only used by
@code{vmpc-prompt-for-profile}.  They do not have the effect of adding
new associations between addresses and profiles in the general operation
of vm-pcrisis; they are simply used by @code{vmpc-prompt-for-profile}
instead of prompting you in the future.

IMPORTANT: When vm-pcrisis decides who your message is destined for, it
does so on the basis of the Reply-To: or From: field of the message
being replied (or in the case of automorph, the To: field of your
message).  This takes account of @code{vm-reply-ignored-reply-tos}, but
DOES NOT take account of any other actions which might change the To:
address in your message.  There is, therefore, a possibility that when
using this feature in both automorph and reply mode, an association made
in one mode may not be properly suited to the other.  The best way to
avoid this problem is to set up your conditions so that the above action
is not run in conjunction with other actions that change the To: field.
This is not really limiting, because the situations in which you are
changing the To: field will generally be ones in which you know which
profile you want to use anyway.

You can also set it up so that after prompting you for a profile, it
will tell you which address it has decided your message is going to, and
prompt you whether to save an association between that profile and that
address.  Like this:

@lisp
("prompt for a profile, and remember it if I say so"
  (vmpc-prompt-for-profile 'prompt))
@end lisp

@c ***************************************************************************

@node Rules, Automorph, Actions, Setting Up
@section Associating Conditions with Actions

@c @menu
@c * vmpc-action-alist::           
@c * vmpc-reply-alist::            
@c * vmpc-automorph-alist::        
@c * vmpc-forward-alist::          
@c * vmpc-resend-alist::           
@c * vmpc-newmail-alist::          
@c @end menu

@c ***************************************************************************

@unnumberedsubsec vmpc-action-alist
@vindex vmpc-action-alist

The @code{vmpc-action-alist} variable controls which actions are
performed if various conditions are met when creating a reply.  Its
format is something like this:

@lisp
'(  ("condition 1" "action 1" "action 2")
    ("condition 2" "action 3")
    ...                         )
@end lisp

If you do not want to set all the other alists then sent this one as it
will be used as a fall back.

@c ***************************************************************************

@unnumberedsubsec vmpc-reply-alist
@vindex vmpc-reply-alist
@anchor{vmpc-reply-alist}

The @code{vmpc-reply-alist} variable controls which actions are
performed if various conditions are met when creating a reply.  Its
format is something like this:

@lisp
'(  ("condition 1" "action 1" "action 2")
    ("condition 2" "action 3")
    ...                         )
@end lisp

If we follow on from our examples in the previous sections, we might
have this in our ~/.vm file:

@lisp
(setq vmpc-reply-alist '(
  ("condition that's always true" "david")
  ("plaintext messages from foo-list" "foo on the hill")
  ("html messages from foo-list" "set To to From" 
                                 "insert anti-html form letter")
  ("html messages not from foo-list" "insert anti-html form letter")
  ("unknown sender" "prompt for a profile, and remember it if I say so")
))
@end lisp

@c ***************************************************************************

@unnumberedsubsec vmpc-automorph-alist
@vindex vmpc-automorph-alist
@anchor{vmpc-automorph-alist}

The @code{vmpc-automorph-alist} variable has the same syntax as
@code{vmpc-reply-alist} and follows the same principles.  (See
@ref{vmpc-reply-alist}.)  The only difference is that it controls
which actions are associated with which conditions when the
@code{vmpc-automorph} function is called.

@c ***************************************************************************
@unnumberedsubsec vmpc-forward-alist
@vindex vmpc-forward-alist

The @code{vmpc-forward-alist} variable has the same syntax as
@code{vmpc-reply-alist} and follows the same principles.  (See
@ref{vmpc-reply-alist}.)  The only difference is that it controls
which actions are associated with which conditions when forwarding
messages.

@c ***************************************************************************
@unnumberedsubsec vmpc-resend-alist
@vindex vmpc-resend-alist

The @code{vmpc-resend-alist} variable has the same syntax as
@code{vmpc-reply-alist} and follows the same principles.  (See
@ref{vmpc-reply-alist}.)  The only difference is that it controls
which actions are associated with which conditions when resending
messages with @code{vm-resend-message}.  


@c ***************************************************************************

@unnumberedsubsec vmpc-newmail-alist
@vindex vmpc-newmail-alist
@anchor{vmpc-newmail-alist}

The @code{vmpc-newmail-alist} variable has the same syntax as
@code{vmpc-reply-alist} and follows the same principles.  (See
@ref{vmpc-reply-alist}.)  The only difference is that it controls
which actions are associated with which conditions when creating new
messages with vm-mail.  

One strategy for this is to have conditions based on the folder from
which you are sending mail.  You might like to set things this up for
some folders, and have vm-pcrisis prompt you for an action in the other
folders.  Here's how you might do that...

In @code{vmpc-conditions}, you'd have a couple of conditions like this:

@lisp
("mail to foo-list"
 (string-match "^foo" (buffer-name (current-buffer))))
("no cond" 
 (vmpc-none-true-yet))
@end lisp

Then in @code{vmpc-actions}, you'd set up an action for your mail to
foo-list, and another one to prompt you for a profile:

@lisp
("foo profile"
 (vmpc-substitute-header "From" 
			 "\"The Foo King\" <david@@bar.com>")
 (vmpc-signature "~/.foo-sig"))
("prompt"
 (vmpc-prompt-for-profile))
@end lisp

Finally, you'd set up @code{vmpc-newmail-alist} like this:

@lisp
(setq vmpc-newmail-alist
      '(
        ("mail to foo-list" "foo profile")
        ("no cond" "prompt")
        ))
@end lisp

@c ***************************************************************************

@node Automorph, , Rules, Setting Up
@section Calling Automorph

The @code{vmpc-automorph} function automatically sets various things in
a mail message based on what's already present in its headers.
Obviously, you'll need to have entered those headers before it is
called.

You'll have to set up what this function does --- for which, see
@ref{vmpc-conditions}, @ref{vmpc-actions} and
@ref{vmpc-automorph-alist} 
--- but you'll also have to consider when you want it called.

Most people would prefer never to have to call it explicitly; it's
generally nicer to just have it called automatically when you do one
of the other things that you have to do in the course of composing a
message.  Here are a couple of ideas:

@itemize @bullet
@item Hitching a ride on the mail-text function: automorph with C-c C-t.@*
A very good idea if you are in the habit of using this to move from
your headers to the body of your message.

@item Let vm-pcrisis help you: tab between headers.@*
See below for more about this.

@item Pre-empting vm-mail-send-and-exit: automorph with C-c C-c.@*
A rather foolish idea, in my opinion.  You'll never get to see the
results of what automorph does.  If there should happen to be a bug in
Personality Crisis that fails to take into account, say, multi-line
headers, you might end up sending a mail to your boss with an
inappropriate signature that, say, mentions his wife in an
unflattering way, and find yourself all-too-suddenly unemployed.  How
likely is this?  Well, in a previous version, such a bug existed.  I
fixed it, but there could be more like it; I wouldn't risk it.

@item Calling it explicitly with some key combo.@*
Boring but easy.  
@end itemize

The last of these is the easiest --- just bind it to a key in mail
mode.  For example, to bind it to the F7 key, you might put this in
your ~/.vm file:

@lisp
(define-key vm-mail-mode-map [f7] 'vmpc-automorph)
@end lisp

Attaching to other functions is also fairly straightforward.  Just use a
wrapper function.  For example:

@lisp
(defun mail-text-and-automorph ()
   (interactive)
   (mail-text)
   (vmpc-automorph))
@end lisp

Then bind this function to C-c C-t (or whatever keystroke you like to
use).  

But what's this thing about tabbing between headers?  Well, if you just
want to hit TAB to go from the To: field to the Subject: field, and TAB
again to then go to the start of the message body, calling
@code{vmpc-automorph} along the way, you can add this in your ~/.vm
file:

@lisp
(define-key vm-mail-mode-map [tab] 'vmpc-tab-header-or-tab-stop)
@end lisp

If you also want shift-tab to take you back to the previous header, you
should check what keysym is produced by shift-tab on your system, by
doing @code{Ctrl-h k Shift-TAB} -- for me, it produces
@code{iso-left-tab}.  So I add this to my ~/.vm:

@lisp
(define-key vm-mail-mode-map [iso-left-tab] 'vmpc-backward-tab-header-or-tab-stop)
@end lisp

You can use any one or more of these ideas, calling the automorph
function as often as you like.  Because its actions depend on the
headers, and those actions can include the changing of headers, calling
it twice may not have the same effect as calling it once.  It may pay to
bear this in mind when you set up the profiles!

@c ***************************************************************************

@node Miscellaneous Variables, Debugging, Setting Up, Top
@c node-name, next, previous, up
@chapter Miscellaneous Variables

@c @menu
@c * vmpc-auto-profiles-file::     
@c * vmpc-auto-profiles-expunge-days::  
@c * vmpc-sig-face::               
@c * vmpc-pre-sig-face::           
@c * vmpc-intangible-sig::         
@c * vmpc-intangible-pre-sig::     
@c * vmpc-expect-default-signature::  
@c @end menu

@c ***************************************************************************

@unnumberedsubsec vmpc-auto-profiles-file
@vindex vmpc-auto-profiles-file

The variable @code{vmpc-auto-profiles-file} contains the name of the
file used for saving profiles when @code{vmpc-prompt-for-profile} is
used with a non-nil argument (see @ref{vmpc-actions} and @ref{vmpc-actions
examples}). 

By default it is set to "~/.vmpc-auto-profiles".  

@c ***************************************************************************

@unnumberedsubsec vmpc-auto-profiles-expunge-days
@vindex vmpc-auto-profiles-expunge-days

In order to keep vmpc-auto-profiles-file from becoming massive,
Personality Crisis will check the age of profile associations in that
file each time it adds a new one.  Associations that have not been used
in the last number of days given by
@code{vmpc-auto-profiles-expunge-days} will be removed.  This variable
is set to 100 by default.

@c ***************************************************************************

@unnumberedsubsec vmpc-sig-face
@vindex vmpc-sig-face

This is the face used to highlight the signature.  You can use
@code{set-face-foreground}, @code{set-face-background} and
@code{set-face-font} to change the colours and font.  

@c ***************************************************************************

@unnumberedsubsec vmpc-pre-sig-face
@vindex vmpc-pre-sig-face

This is the face used to highlight the pre-signature.  You can use
@code{set-face-foreground}, @code{set-face-background} and
@code{set-face-font} to change the colours and font.

@c ***************************************************************************

@unnumberedsubsec vmpc-intangible-sig
@vindex vmpc-intangible-sig
@anchor{vmpc-intangible-sig}

If @code{vmpc-intangible-sig} is non-nil, movement and mouse commands
will cause your cursor to slide to one side or the other of the
signature, preventing you from actually writing text inside the area
that Personality Crisis calls the signature.  

This is somewhat useful because if automorph replaces the signature, you
probably won't want any text you added to be replaced along with it.  To 
activate this feature, just add the following to your ~/.vm file:

@lisp
(setq vmpc-intangible-sig t)
@end lisp

@c ***************************************************************************

@unnumberedsubsec vmpc-intangible-pre-sig
@vindex vmpc-intangible-pre-sig

The @code{vmpc-intangible-pre-sig} variable works just like
@code{vmpc-intangible-sig}, but affects the pre-signature.  See
@ref{vmpc-intangible-sig}.  

@c ***************************************************************************

@unnumberedsubsec vmpc-expect-default-signature
@vindex vmpc-expect-default-signature

Traditionally, signatures are added to new mail messages using a
signature-insertion function bound to @code{mail-mode-hook} or similar,
so that every message you wrote started off containing a signature.  If
you use the vm-pcrisis signature functions in addition to such a setup,
you should add the following to your ~/.vm file:

(setq vmpc-expect-default-signature t)

This will allow Personality Crisis to properly take account of your
setup, provided that your signature-insertion function uses the standard 
@samp{\n-- \n} signature delimiter.  

@c ***************************************************************************

@node Debugging, Version History, Miscellaneous Variables, Top
@c node-name, next, previous, up
@chapter Debugging 

With a complex setup it can be come hard to understand why vm-pcrisis
is doing a specific thing.  In order to understand what is going on you
should check the value of the following variables:

@itemize @bullet

@item @code{vmpc-true-conditions} is the list of true conditions.

@item @code{vmpc-actions-to-run} is the list of actions to run,
i.e. those actions mapped by a @code{vmpc-*-alist}. 

@item @code{vmpc-saved-headers-alist} the value of headers saved for
substitution. 

@end itemize

If you want to check new contions you can run
@code{vmpc-build-true-conditions-list} interactively.

If you want to check which true conditions are mapped to actions you can
run @code{vmpc-build-actions-to-run-list} interactively.  True
conditions which are not mapped to an action are silently ignored.

If you want to run new actions you can run @code{vmpc-read-actions} and
@code{vmpc-run-actions} interactively.

@c ***************************************************************************


@node Version History, Variable Index , Debugging, Top
@c node-name, next, previous, up
@chapter Version History

Version 0.11:

@itemize @bullet

@item Profiles can now be stored in the BBDB instead of the file
@code{vmpc-auto-profiles-file}.  To enable this and migrate your old
profiles you should call @code{vmpc-migrate-profiles-to-BBDB} once. A
backup of your BBDB will be created first as
@file{~/.bbdb-vmpc-profile-migration-backup} and your old profiles-file
will be moved to @file{~/.vmpc-auto-profiles-migrated-to-BBDB}.

@item Added @code{vmpc-add-header} which allows to create a header
multiple times.  This is useful when having more than one FCC header. 

@item @code{vmpc-prompt-for-profile} finds now all profiles, i.e. before
it stopped at the first match, now it will check all email addresses.
 
@end itemize

Version 0.10:

@itemize @bullet

@item Added support for a list of actions in @code{vmpc-prompt-for-profile}.
Before it was only possible to specify a single action.
 
@end itemize

Version 0.9:

@itemize @bullet

@item The new maintainer is: Robert Widhopf-Fenk <hack@@robf.de>

@item All variables of pcrisis can be customized now.

@item Added new function @code{vmpc-toggle-no-automorph} to disable automorph
for the current buffer.  

@item @code{vmpc-prompt-for-profile} checks all relevant headers
now and will only prompt for a profile if no matches were found.  It
also can be called interactively to correct a existing profile
association.

@item Renamed @code{vmpc-composition-buffer-function} to @code{vmpc-composition-buffer}.

@item @code{vmpc-pre-function} and @code{vmpc-composition-buffer} handle forms
now, not only a single function which must be quoted.

@item Renamed @code{vmpc-replies-alist} to @code{vmpc-reply-alist} and
@code{vmpc-forwards-alist} to @code{vmpc-forward-alist} for consistency.

@item New function @code{vmpc-true-conditions} to test conditions without actually
running some actions.

@item New function @code{vmpc-read-actions} to set actions by hand.

@item @code{vmpc-build-actions-to-run-list} and @code{vmpc-run-actions} are interactive
now.

@item @code{vmpc-prompt-for-profile} will search all headers for a
recipient with an associated profile before prompting for one.

@item When calling @code{vmpc-prompt-for-profile} interactively form a
composition buffer one will get prompted again for a profile.  This
allows to easily fix a bad association. 

@item The state variables become buffer-local now, which should prevent some
bugs, i.e. for saved headers. 

@item Rewrite of unlispish code.

@item @code{M-x checkdoc RET}

@item Several bug fixes and enhancements from Robert P. Goldman.

@item Fixes and updates of the info file. 

@end itemize

Version 0.85:

@itemize @bullet

@item This version adds @code{vmpc-resend-alist}, which should be
especially useful for mailing list maintainers who receive bounced
non-member posts, and anyone else who frequently uses
@code{vm-resend-message}.  

@end itemize

Version 0.84:

@itemize @bullet

@item There is now a @code{vmpc-newmail-alist} in recognition of the fact that
you @strong{can} actually test for useful criteria (such as what folder
you are in when you invoke vm-mail) when creating a brand new message.

@item Due to the above, the @code{vmpc-newmail-prompt-for-profile}
variable is now obsoleted.  Its effect can be duplicated easily enough;
see @ref{vmpc-newmail-alist} for details.  

@end itemize

Older versions:

@itemize @bullet

@item Pre-signatures and signatures are now dealt with in a more
sensible manner.  You might not notice the difference, except that you
can now have them highlighted in @code{vmpc-pre-sig-face} and
@code{vmpc-sig-face}, and you can set up either so that your cursor
skips across them with @code{vmpc-intangible-pre-sig} and
@code{vmpc-intangible-sig}.  However, if you use another signature
package to insert a signature in every mail buffer, you should look at
setting @code{vmpc-expect-default-signature}.

@item You can now use vm-pcrisis in conjunction with the forwarding
functions of VM.  Just set up @code{vmpc-forwards-alist}, which has an
identical format to @code{vmpc-replies-alist}.

@item There is now a @code{vmpc-body-match} function which matches
text in the body of a message you are composing, replying to or
forwarding.  See @ref{vmpc-conditions examples} for more about that.

@item You can now use @code{vmpc-header-match} to test if a regexp appears in 
any header field matching another regexp.  For example, to find out if
the regexp "fire\\|water" appears in any header, you would use
something like
@lisp
(vmpc-header-match "[^ \t\n:]+:" "fire\\|water" ", ")
@end lisp
For further details, again see @ref{vmpc-conditions examples}.

@item @code{vmpc-auto-profiles-expunge-days} can now be set to nil if
you want to never expunge old profile associations.  Associations are
now "touched" each time they are used, so that as long as they are used
more often than @code{vmpc-auto-profiles-expunge-days} they will never
be expunged.  

@end itemize

@node Variable Index, Function Index, Version History, Top
@unnumbered Variable Index
@printindex vr

@node Function Index, , Variable Index, Top
@unnumbered Function Index
@printindex fn



@bye
