\input texinfo
@c %**start of header
@setfilename vm-pcrisis.info
@settitle Personality Crisis for VM
@c %**end of header
@dircategory Emacs
@direntry
* VM-pcrisis: (vm-pcrisis).                  A personality crisis solver for VM
@end direntry

@paragraphindent asis

@ifnottex
This is the documentation for Personality Crisis, an add-on for the
mail reader VM which allows you to do all sorts of things
automatically when you compose new mail messages or replies.

Copyright @copyright{} 1999  Rob Hodges, 2006 Robert Widhopf-Fenk
@end ifnottex

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

@node Top, Getting Started, (dir), (dir)
@c node-name, next, previous, up
@chapter Personality Crisis for VM

This is the documentation for Personality Crisis 0.9.1

It was written by Rob Hodges <s323140@@student.uq.edu.au>.

It is currently maintained by Robert Widhopf-Fenk <hack@@robf.de>

Please read the docs before sending email about problems you are having.
Most problems are due to incorrect regexps.  That said, if something in
the docs is unclear, I'd like to know so that I can improve them.  And
if you find a bug, I'd definitely like to know.  I hope you enjoy this
package.

@menu
* Getting Started::             
* vmpc-conditions::             
* vmpc-actions::                
* Associating Conditions with Actions::  
* Miscellaneous Variables::     
* Debugging::                   
* New In This Version::         
@end menu

The incompete list of Roberts which have been involved in vm-prisis:

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

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

@node Getting Started, vmpc-conditions, Top, Top
@c node-name, next, previous, up
@chapter Getting Started

@menu
* Installation::                
* Quick start::                 
* Description::                 
* Specific Abilities::          
* Common Uses::                 
* Overview::                    
* Calling Automorph::           
@end menu

@node Installation, Quick start, Getting Started, Getting Started
@section Installation

@enumerate

@item
Load VM if you haven't previously done so in your current Emacs session.

@item 
Byte-compile vm-pcrisis.el, using @code{M-x byte-compile-file}.  You may
get some byte-compiler warnings; ignore them.  (For the curious:
Personality Crisis uses some functions that have different names in FSF
Emacs and XEmacs, automatically detecting which one you are running.  The
byte-compiler isn't smart enough to know this, so it warns of the
functions it doesn't know about, even though they'll never be run.)

@item 
Place the resulting .elc file somewhere in your Emacs load-path.  It
would probably be a good idea to leave the .el file there with it too,
but you don't have to.

@item 
Add the following line to your ~/.vm file:
@lisp
(require 'vm-pcrisis)
@end lisp

@item 
Read the rest of this manual and set up the variables it describes.

@end enumerate

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

@node Quick start, Description, Installation, Getting Started
@section Quick start

You do not want to read a manual but solve your personal crisis now?

Then add the following to your ~/.vm file:

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

Where you add you own email addresses to the call of
@code{vmpc-my-identities}.  This will prompt you for 
the profile to use when first writing an message to a 
unknown email address.

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

@node Description, Specific Abilities, Quick start, Getting Started
@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 you can set it up
to do just about anything based on those.  To get some ideas about how
this might be useful, see @ref{Common Uses}.  You can also use it to
explicitly choose a "personality" when composing new messages.

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

@node Specific Abilities, Common Uses, Description, Getting Started
@section Specific Abilities

Based on the headers of a message you are replying to, you can get
vm-pcrisis to do any number of these things:

@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 any of the
headers in the message you are replying to.
@item Call some functions before VM creates the reply.
@item Call some functions 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 address
in the future.
@end itemize

Similar functionality is available when forwarding messages.  

Based on the headers of a message you are composing, it can do these
things:

@itemize @bullet
@item Change or insert any headers you like.
@item Change or insert a signature.
@item Insert some 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 address
in the future.
@end itemize

If you wish, you can also have vm-pcrisis prompt you for a personality
when composing a new mail, which is useful if you need to set up VM
variables with new mails, or if you prefer to more deliberatly choose
who you are for each message.  

If you write your own functions to do things that vm-pcrisis can't do by
itself, ready-made functions are provided to allow you easy access to
the contents of headers in both the message you are replying to, and
the message you are writing.

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

@node Common Uses, Overview, Specific Abilities, Getting Started
@c node-name, next, previous, up
@section Common Uses

These are some of the common uses for Personality Crisis.

@itemize @bullet
@item People with multiple e-mail addresses can automatically set up
headers such as From: and Reply-To:, so that eg. 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 I called it
Personality Crisis...)  As of version 0.7, 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: field in
your reply to point to the original sender instead.  (You can do the
reverse as well... if you can take the flamage.)  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 Overview, Calling Automorph, Common Uses, Getting Started
@section Overview

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.  As of v0.84, you may also use
@code{vmpc-newmail-alist} to associate conditions with actions for new
messages, and since v0.85, @code{vmpc-resend-alist} for resending
(bouncing) messages.  

If you want to use the @code{vmpc-automorph} function, which takes
actions based on the headers of a message you are composing, you should
read @ref{Calling 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.  

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

@node Calling Automorph,  , Overview, Getting Started
@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 vmpc-conditions, vmpc-actions, Getting Started, Top
@c node-name, next, previous, up
@chapter vmpc-conditions

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

@node The vmpc-conditions variable, vmpc-conditions examples, vmpc-conditions, vmpc-conditions
@section The vmpc-conditions variable

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
'(   ("a descriptive name"
             (lisp-statement-1) )
     ("another descriptive name"
             (lisp-statement-2) )   )
@end lisp

The lisp-statement can be any statement in lisp that will evaluate to
nil if the condition is to be considered false, or 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.

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

@itemize @bullet

@item @code{vmpc-header-match} is of course the main one.  When making
replies or forwards, this matches against the contents of a header in
the message you are replying/forwarding; when using the
@code{vmpc-automorph} function, it matches against a header in the
message you are composing.

@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.

@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.

@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} 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 ***************************************************************************

@node vmpc-conditions examples,  , The vmpc-conditions variable, vmpc-conditions
@c node-name, next, previous, up
@section 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 vmpc-actions, Associating Conditions with Actions, vmpc-conditions, Top
@c node-name, next, previous, up
@chapter vmpc-actions

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

@node The vmpc-actions variable, vmpc-actions examples, vmpc-actions, vmpc-actions
@section The vmpc-actions variable

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

@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.
@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.  
@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.
@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.)
@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.  
@item (vmpc-composition-buffer (foo-function args)) does the
same, but in the composition buffer.  
@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 'always.  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 'always, 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 ***************************************************************************

@node vmpc-actions examples,  , The vmpc-actions variable, vmpc-actions
@c node-name, next, previous, up
@section 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 'always))
@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 Associating Conditions with Actions, Miscellaneous Variables, vmpc-actions, Top
@chapter Associating Conditions with Actions

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

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

@node vmpc-action-alist, vmpc-reply-alist, Associating Conditions with Actions, Associating Conditions with Actions
@c node-name, next, previous, up
@section 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 ***************************************************************************

@node vmpc-reply-alist, vmpc-automorph-alist, vmpc-action-alist, Associating Conditions with Actions
@c node-name, next, previous, up
@section 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 ***************************************************************************

@node vmpc-automorph-alist, vmpc-forward-alist, vmpc-reply-alist, Associating Conditions with Actions
@c node-name, next, previous, up
@section 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 ***************************************************************************
@node vmpc-forward-alist, vmpc-resend-alist, vmpc-automorph-alist, Associating Conditions with Actions
@section 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 ***************************************************************************
@node vmpc-resend-alist, vmpc-newmail-alist, vmpc-forward-alist, Associating Conditions with Actions
@section 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 ***************************************************************************

@node vmpc-newmail-alist,  , vmpc-resend-alist, Associating Conditions with Actions
@section 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 Miscellaneous Variables, Debugging, Associating Conditions with Actions, Top
@c node-name, next, previous, up
@chapter Miscellaneous Variables

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

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

@node vmpc-auto-profiles-file, vmpc-auto-profiles-expunge-days, Miscellaneous Variables, Miscellaneous Variables
@c node-name, next, previous, up
@section 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 an 'always or 'prompt argument (see @ref{The vmpc-actions
variable} and @ref{vmpc-actions examples}).

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

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

@node vmpc-auto-profiles-expunge-days, vmpc-sig-face, vmpc-auto-profiles-file, Miscellaneous Variables
@c node-name, next, previous, up
@section 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 ***************************************************************************

@node vmpc-sig-face, vmpc-pre-sig-face, vmpc-auto-profiles-expunge-days, Miscellaneous Variables
@section 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 ***************************************************************************

@node vmpc-pre-sig-face, vmpc-intangible-sig, vmpc-sig-face, Miscellaneous Variables
@section 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 ***************************************************************************

@node vmpc-intangible-sig, vmpc-intangible-pre-sig, vmpc-pre-sig-face, Miscellaneous Variables
@section 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 ***************************************************************************

@node vmpc-intangible-pre-sig, vmpc-expect-default-signature, vmpc-intangible-sig, Miscellaneous Variables
@section 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 ***************************************************************************

@node vmpc-expect-default-signature,  , vmpc-intangible-pre-sig, Miscellaneous Variables
@section 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, New In This Version, 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 New In This Version,  , Debugging, Top
@c node-name, next, previous, up
@chapter New In This Version

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




@bye
