[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21. Customisation

This chapter talks about various topics relevant to adapting the behavior of af in minor ways. All kinds of customisation affect only the particular af session that you do them in. They are completely lost when you kill af, and have no effect on other af sessions you may run later. The only way an af session can affect anything outside of it is by writing a file; in particular, the only way to make a customisation `permanent' is to put something in your `.afrc' file to do the customisation in each session. (see section 21.2 The Startup File, `~/.afrc').

You can easily customise af in several different ways:

Mime Configuration
Af can be customised to handle MIME messages by modifying a set of files, which are in a standard format used by most mail readers.
Setting Variables
Af has many configuration variables, which you can set to alter the behaviour of certain commands. (see section 21.4 Variables).
Keyboard Macros
Keyboard macros allow you to combine af commands to create new ones. Keyboard macros are not very powerful, but they are a very simple way to add new commands to af.
Binding Keys
You can change which commands are bound to which keys, so you can change the effect of a key press.
Afl
You will also eventually be able to write powerful functions in af's extension language afl. This is not yet supported.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.1 Mime Configuration

Af reads it's MIME configuration from three files; the `mailcap' file, which describes how to handle various message content types; the `mime.types' file, which lists the available content types, and the filename suffixes used for files containing that content-type; and the `mime.charsets' file, which lists the character sets af will support.

Af will look for each of these files in a standard set of places. First it looks for the file prefixed with a `.' in your home directory (`.mailcap', `.mime.types', or `.mime.charsets'). Then it looks in the af configuration directory. Then it looks in `/etc', `/usr/etc', and `/usr/local/etc'. All the entries in any files found are merged, with the first entries found taking precedence.

The location of `mailcap' files can be overridden by setting the MAILCAPS environment variable to a colon-separated list of the files to read mailcap entries from.

All these files have a similar format. Blank lines, and lines beginning with `#' are ignored. Each other line describes a single entry. Long lines can be continued by ending them with a `\'.

21.1.1 Mailcap files  How to handle a given content type.
21.1.2 The Mime.types File  The list of known content types.
21.1.3 The Mime.charsets File  The list of known character sets.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.1.1 Mailcap files

The `mailcap' file lists how to handle a body part of a given content-type. Each entry consists, at a minimum, of a content-type and the command to display that type, separated by a semicolon. For example,

 
audio/basic; cat > /dev/audio

would mean that to handle the audio/basic content type, run the command cat > /dev/audio. The subtype of a content type (the part after the `/' may be given as `*', in which case the entry will match any subtype.

The command may include escape sequences, which are handled specially. The most commonly used is %s, which is replaced by the name of a temporary file, where the decoded text of the body part has been stored. If this escape is not used, then the decoded text is written to the standard input of the command.

In addition to this basic format, you can add more optional fields to the entry. These either modify the behaviour of the command, or add new facilities. Each optional field is given either in the form name or name=value, and is separated from the entry or the previous optional field by a `;'.

The commonly-used optional fields are

test=command
The mailcap entry will be ignored if the result of running the command is not success (a return value of 0 on Unix systems).
print=command
The command to print a body part. Any output from the print command will be formatted as if it were text and then sent to the system spool command. If the output of the print command is PostScript text, or any other format that must be sent to the printer as it stands, or if you need to use a special spool command to print the output, then it is safer to make the print command itself write directly to your system's spool command.
desc=text
Gives a description of the content type.
template=format
Allows you to specify a format for the name of the temporary file used in the %s escape in commands. Any %s in format is replaced with characters to make the name unique. This option is most often used to force the file to have a suffix which is required by the display program given in the command.
needsterminal
Indicates that the display command is interactive, and will need to take control of the terminal when it is executed.
copiousoutput
Indicates that the output of the command should be displayed via the pager named in the pager variable.
textualnewlines
Indicates that the content type is essentially textual, even though it may not be a subtype of text.
compose
Gives a program to create content of this type. Af uses this value to create a body part in Compose mode, but it is rarely defined in system mailcap files.
composetyped
Similar to compose, except that the composing program also returns the headers of the body part.
edit
The program to use to edit content of this type; used by af's Compose mode, but rarely defined in system mailcap files.

For example, in the entry

 
text/enriched; richtext -e; print="richtext -e"; copiousoutput

the output would be displayed via a pager because the copiousoutput optional field has been specified.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.1.2 The Mime.types File

The `mime.types' file lists the known MIME content types. In addition, it lists any filename suffixes which will indicate that a file is of that type. So the entry

 
image/jpeg      .jpg .jpeg

indicates that the MIME content-type image/jpeg exists, and that files whose names end in .jpg or .jpeg are likely to contain data of type image/jpeg.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.1.3 The Mime.charsets File

The `mime.charsets' file lists the known MIME character sets. If a character set is not viewable, but is listed in the `mime.charsets' file, then af can safely assume that the character set is a superset of ASCII, and that displaying the ASCII characters in the message is safe.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.2 The Startup File, `~/.afrc'

When af is started, it normally loads an afl program from the file `.afrc' in your home directory. We call this file your Startup file because it is read when you start af. You can use the command line switches `-n' and `-l' to tell af whether to load a startup file, and which one (see section 4. Entering Af).

Your site may also have a global startup file; this is named `afrc.afl', if it exists. The af distribution contains no such library; your site may create one for local customisations. If this library exists, it is loaded whenever you start af; and then your own startup file, if any, is loaded.

By far the simplest way to create a startup file is for af to write one for you. The command M-x write-configuration will prompt you for a file name (defaulting to `~/.afrc'), and then write an afl program into that file. When you run that program (by loading the file), it will recreate any changed variables or key bindings, or any new keymaps or named keyboard macros that were in existence when you ran M-x write-configuration.

You can use M-x write-configuration to create a startup file, and then modify that file with an editor; it is a text file. This is also a good way to become familiar with afl.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.3 Emulation

Af can be programmed to emulate (more or less) several other mail readers. The commands to do this are stored in several afl libraries (see section 22. Afl). Note that the only way to turn an emulation off once you've loaded it is to exit af and start again.

The emulations aren't in any way intended to be true emulations of the mail readers. The intent is to let people who are already used to some other mail reader get started with af quickly, by making most of the common keys do what they expect.

To set up af to work like another mail reader there must be an emulation library for the mail reader. To load the library for (as an example) elm, type type M-x load-library RET elm RET.

The available emulations are:

elm
Reconfigures af to do a fairly close emulation of elm.
mush
Not a perfect emulation by any means, but enough to get people used to mush started.
pine
A close enough emulation to satisfy advanced PINE users. Doesn't hold your hand nearly enough for many of PINE's target users.
ream
Not too far from the target, anyone who's used to using ream will probably find this emulation helpful.
vm
Silly though it seems, the VM emulator is quite different from af's normal personality. If you've been using the VM package under Emacs to read mail, then this library may help.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.4 Variables

Af presents two interfaces to its variables: The underlying system which is used by Afl (see section 22. Afl), or a simpler system which af uses to allow users to handle configuration variables.

A variable is a symbol which has a value. The symbol's name is also called the name of the variable. Variable names usually consist of words separated by hyphens. Af's configuration variables can each hold a specified kind of value. Sometimes this is a simple type such as a number, or a string, but sometimes a variable will require a more complex value, such as the formats for the screen display.

To examine the value of a single configuration variable, use C-h v (describe-variable), which reads a variable name using the minibuffer, with completion. It displays both the value of and the documentation for the variable. If you want to see the values of all the configuration variables, then use C-h C-v (list-variables), which lists all the configuration variables and their values to typeout.

The most convenient way to set a specific variable is with C-x a (set-variable). This reads the variable name with the minibuffer (with completion), and then reads a new value using the minibuffer a second time. For example,

 
C-x a ask-cc RET true RET

sets ask-cc to true.

Whenever you use C-x a, the value of the variable will be checked when you enter it. You can't break af by changing variables, although you can make it behave very strangely if you set some variables to odd values.

When a variable's description says that it contains a list of items, then C-x a will expect the items in the list to be separated by colons. If you set the variable by afl of course, then you would use a list object as the value (see section 22. Afl). For example

 
C-x a viewable-charsets RET us-ascii:iso-8859-1 RET

set the value of viewable-charsets to the list containing `us-ascii' and `iso-8859-1'.

It is usually worth using C-h v (describe-variable) to check the on-line help for a variable you intend to change; often the description is far more detailed than is given in this manual.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.5 Keyboard Macros

A keyboard macro is a command defined by the user to stand for another sequence of keys. For example, if you discover that you are about to type C-t t a RET C-n forty times, you can speed your work by defining a keyboard macro to do C-t t a RET C-n and calling it with a repeat count of forty.

C-x (
Start defining a keyboard macro (start-kbd-macro).
C-x )
End the definition of a keyboard macro (end-kbd-macro).
C-x e
Execute the most recent keyboard macro (call-last-kbd-macro).
C-u C-x (
Re-execute last keyboard macro, then add more keys to its definition.
C-x q
When this point is reached during macro execution, ask for confirmation (kbd-macro-query).
M-x name-last-kbd-macro
Give a command name (for the duration of the session) to the most recently defined keyboard macro.

Keyboard macros differ from ordinary af commands in that they are written in the af command language rather than in C or afl. This makes it easier for the novice to write them, and makes them more convenient as temporary hacks. However, the af command language is not powerful enough as a programming language to be useful for writing anything intelligent or general (Neither is afl yet, but that will change).

You define a keyboard macro while executing the commands which are the definition. Put differently, as you define a keyboard macro, the definition is being executed for the first time. This way, you can see what the effects of your commands are, so that you don't have to figure them out in your head. When you are finished, the keyboard macro is defined and also has been, in effect, executed once. You can then do the whole thing over again by invoking the macro.

21.5.1 Basic Use  Defining and running keyboard macros.
21.5.2 Naming Keyboard Macros  Giving keyboard macros names; saving them in files.
21.5.3 Executing Macros with Variations  Keyboard macros that do different things each use.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.5.1 Basic Use

To start defining a keyboard macro, type the C-x ( command (start-kbd-macro). From then on, your keys continue to be executed, but also become part of the definition of the macro. `Def' appears in the mode line to remind you of what is going on. When you are finished, the C-x ) command (end-kbd-macro) terminates the definition (without becoming part of it!). For example,

 
C-x ( M-+ +foobar RET C-n C-x )

defines a macro to save the current message to the folder `+foobar', and then move down a line.

The macro thus defined can be invoked again with the C-x e command (call-last-kbd-macro), which may be given a repeat count as a numeric argument to execute the macro many times. C-x ) can also be given a repeat count as an argument, in which case it repeats the macro that many times right after defining it, but defining the macro counts as the first repetition (since it is executed as you define it). Therefore, giving C-x ) an argument of 4 executes the macro immediately 3 additional times. An argument of zero to C-x e or C-x ) means repeat the macro indefinitely (until it gets an error or you type C-g).

If you wish to repeat an operation at regularly spaced places in the text, define a macro and include as part of the macro the commands to move to the next place you want to use it. For example, if you want to change each line, you should position point at the start of a line, and define a macro to change that line and leave point at the start of the next line. Then repeating the macro will operate on successive lines.

After you have terminated the definition of a keyboard macro, you can add to the end of its definition by typing C-u C-x (. This is equivalent to plain C-x ( followed by retyping the whole definition so far. As a consequence it re-executes the macro as previously defined.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.5.2 Naming Keyboard Macros

If you wish to save a keyboard macro for longer than until you define the next one, you must give it a name using M-x name-last-kbd-macro. This reads a name as an argument using the minibuffer and defines that name to execute the macro. Defining the macro in this way makes it a valid command name for calling with M-x or for binding a key to with global-set-key (see section 21.6.1 Keymaps). If you specify a name that has a prior definition other than another keyboard macro, an error message is printed and nothing is changed.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.5.3 Executing Macros with Variations

Using C-x q (kbd-macro-query), you can make a macro ask you each time around whether to make a change. While defining the macro, type C-x q at the point where you want the query to occur. During macro definition, the C-x q does nothing, but when you run the macro later, C-x q asks you interactively whether to continue.

The valid responses are SPC to continue, and RET to skip the rest of this repetition of the macro and start right away with the next repetition. ESC means to skip the rest of this repetition and cancel further repetitions. C-l redraws the screen and asks you again for a character to say what to do.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.6 Customising Key Bindings

This section describes key bindings which map keys to commands, and the keymaps which record key bindings. It also explains how to customise key bindings.

21.6.1 Keymaps  An introduction to keymaps.
21.6.2 Prefix Keymaps  Keymaps for prefix keys.
21.6.3 Local Keymaps  Major modes have their own keymaps.
21.6.4 Changing Key Bindings Interactively  How to redefine one key's meaning.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.6.1 Keymaps

The bindings between key sequences and command functions are recorded in data structures called keymaps. Af has many of these, each used on particular occasions.

Recall that a key sequence (key, for short) is a sequence of key presses that have a meaning as a unit. A key sequence gets its meaning from its binding, which says what command it runs. The function of keymaps is to record these bindings.

The global keymap is the most important keymap because it is always in effect. The global keymap defines keys which are common to most or all of the major modes. Each major mode has its own keymap which overrides the global definitions of some keys.

For example, the key C-n move to the next line because the global keymap binds it to the command next-line. Commands to rebind keys, such as M-x global-set-key, actually work by storing the new binding in the proper place in the keymaps. See section 21.6.4 Changing Key Bindings Interactively.

Meta characters work differently; if the allow-meta-bindings variable is set to true, af will search for a binding for the meta character. If not, or if no binding is found, af translates each Meta character into a pair of characters starting with ESC. When you type the character M-r in a key sequence, af will replace it with ESC r. A meta key comes in as a single key press, but may become two events for purposes of key bindings. The reason for this is historical; most older terminals didn't support a meta key.

A keymap records definitions for single characters. Interpreting a key sequence of multiple characters involves a chain of keymaps. The first keymap gives a definition for the first character; this definition is another keymap, which is used to look up the second character in the sequence, and so on.

You can find out what keymaps are defined in af with the command M-x list-keymaps. This lists the keymaps, with the prefix keys they handle, to typeout.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.6.2 Prefix Keymaps

A prefix key such as C-x or ESC has its own keymap, which holds the definition for the character that immediately follows that prefix.

The definition of a prefix key is usually the keymap to use for looking up the following event. Thus, the binding of C-x is the keymap control-x-prefix, the keymap for C-x commands. The definitions of C-c, C-t, C-x, C-h and ESC as prefix keys appear in the global map, so these prefix keys are always available.

The C-c prefix has been assigned as a "user prefix". By default, nothing will be bound in the C-c keymap; it is reserved for your own key bindings. There is a separate C-c prefix keymap for each of af's major modes. See section 21.6.3 Local Keymaps.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.6.3 Local Keymaps

So far we have explained the ins and outs of the global map. Major modes customise af by providing their own key bindings in local keymaps. For example, minibuffer mode overrides the printable characters to bind them to the command self-insert-command, so that the characters insert themselves into the minibuffer at point.

A local keymap can locally redefine a key as a prefix key by defining it as a prefix keymap. If the key is also defined globally as a prefix, then its local and global definitions (both keymaps) effectively combine: both of them are used to look up the character that follows the prefix key. Thus, if the mode's local keymap defines C-x as another keymap, and that keymap defines C-z as a command, this provides a local meaning for C-x C-z. This does not affect other sequences that start with C-x; if those sequences don't have their own local bindings, their global bindings remain in effect.

Another way to think of this is that af handles a multi-event key sequence by looking in several keymaps, one by one, for a binding of the whole key sequence. First it checks the minor mode keymaps for minor modes that are enabled, then it checks the major mode's keymap, and then it checks the global keymap. This is not precisely how key lookup works, but it's good enough for understanding ordinary circumstances.

Designing af keymaps is made more complicated because several commands will only work in one or two of the major modes. You should be careful using global bindings; local bindings will usually achieve what you want, and are less confusing to work with.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

21.6.4 Changing Key Bindings Interactively

The way to redefine an af key is to change its entry in a keymap. You can change the global keymap, in which case the change is effective in all major modes (except those that have their own overriding local definitions for the same key). Or you can change the current buffer's local map, which affects all buffers using the same major mode.

M-x global-set-key RET key cmd RET
Define key globally to run cmd.
M-x global-unset-key RET key
Make key undefined in the global map.
M-x local-set-key RET key cmd RET
Define key locally (in the major mode now in effect) to run cmd.
M-x local-unset-key RET key
Make key undefined locally (in the major mode now in effect).
M-x typeout-set-key RET key cmd RET
Define key to run cmd in the typeout keymap.
M-x typeout-unset-key RET key
Make key undefined in the typeout map.
M-x minibuffer-set-key RET key cmd RET
Define key to run cmd in the minibuffer keymap.
M-x minibuffer-unset-key RET key
Make key undefined in the minibuffer map.
M-x make-keymap RET map RET
Create a new keymap map, which you can then use to add your own prefix keys.

For example, suppose you like to execute commands in a subshell, instead of suspending af and executing commands in your login shell. Normally, C-z is bound to the function suspend-af, but you can change C-z to invoke a subshell by binding it to shell as follows:

 
M-x global-set-key RET C-z shell RET

global-set-key reads the command name after the key. After you press the key, a message like this appears so that you can confirm that you are binding the key you want:

 
Set key C-z to command: 

You can rebind a key that contains more than one character in the same way. Af keeps reading the key to rebind until it is a complete key (that is, not a prefix key). Thus, if you type C-f for key, that's the end; the minibuffer is entered immediately to read cmd. But if you type C-x, another character is read; if that is 4, another character is read, and so on. For example,

 
M-x global-set-key RET C-x 4 $ scroll-other-window RET

redefines C-x 4 $ to run the command scroll-other-window.

The commands typeout-set-key and minibuffer-set-key are a convenience; they bind keys in the typeout or minibuffer keymaps rather than the global or local maps.

You can remove the global definition of a key with global-unset-key. This makes the key undefined; if you type it, af will just beep. Similarly, local-unset-key makes a key undefined in the current major mode keymap, which makes the global definition (or lack of one) come back into effect in that major mode.

If you have redefined (or undefined) a key and you subsequently wish to retract the change, undefining the key will not do the job--you need to redefine the key with its standard definition. The documentation of keys in this manual also lists their command names.

If you want to define a new prefix key, you will need to create a new keymap to handle the prefix key. To do this, use the command M-x make-keymap, which will prompt you for the name of the keymap to create. If you specify a name that already has a definition an error message is printed and nothing is changed.

There are two variables which can be important when you are binding keys. The variable meta-prefix-char names the character which is used as a prefix when you type a meta character at the keyboard. If you change the binding of ESC, then you should change the value of meta-prefix-char to reflect this. Similarly, the variable quit-char names the character which is used to quit from confirm prompts, and similar; so it should probably reflect the usual binding of keyboard-quit in the keymaps.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Malc Arnold on August, 22 2002 using texi2html