jabber.el manual
****************

This manual is for jabber.el, version 0.7.

Copyright © 2004, 2005 Magnus Henoch, Tom Berger.

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

Introduction
************

jabber.el is a Jabber client running under Emacs.  For more information on the open-protocol instant messaging network Jabber, please visit http://www.jabber.org.

As a Jabber client, jabber.el is mostly just a face in the crowd, except that it uses buffers where GUI clients have windows.  There is a roster buffer, and to chat with someone you open a chat buffer, and there are browse buffers (increasingly inexactly named) for interaction with servers and services.  Then again, jabber.el delivers excellent console performance and customizable hooks (if you have speech synthesizer software, hook it up to your presence alerts).

jabber.el does not yet support GPG, sending and receiving roster items, and various other things.

Contact
=======

jabber.el is developed by Tom Berger (e-mail object@intellectronica.net, JID object@jabber.org.uk) and Magnus Henoch (e-mail mange@freemail.hu, JID legoscia@jabber.cd.chalmers.se).  There is a web page at http://intellectronica.net/emacs-jabber/, and a Sourceforge project page at http://sourceforge.net/projects/emacs-jabber.

Basic operation
***************

This chapter is intended as an introduction to basic usage of jabber.el.  If you have used Jabber before and are familiar with the terminology, you might find it a bit too basic --- in that case, just skim it, making sure to pick up the commands mentioned.

There are a handful of global keybindings for common commands.  They start with C-x C-j, and you can get a list of them by typing C-x C-j C-h.

Connecting
==========

I'll assume that you have already successfully installed jabber.el; if not, consult the README file.  Also, make sure you have (require 'jabber) in your .emacs.

Now, type M-x jabber-customize.  This brings up a customize buffer for jabber.el.  The most important variables to customize are jabber-username and jabber-server. (See Connection settings, for other things you might have to change.)  Save your changes, and type M-x jabber-connect to connect.

If you do not yet have a Jabber account, you can register one.  Enter your desired username for jabber-username and the server you wish to use for jabber-server, save, and type C-u M-x jabber-connect or C-u C-x C-j C-c.  If the server supports in-band registration, you will be presented with a registration form to fill out and send.  There the username you chose will be prefilled. Don't change it, otherwise jabber.el will be confused.

If you successfully connect, jabber.el will download your roster and display it in a buffer called *-jabber-*.

By default, you will appear as ``online'' to your contacts.  To change this to e.g. ``away'', type M-x jabber-send-presence. See Presence, for more information.

To disconnect, type M-x jabber-disconnect or C-x C-j C-d.

Chatting
========

There are several ways to open a chat buffer.  The shortest way is to put point over the person you want to chat with in the roster display and hit RET.

You can also use menus to access commands.  In the roster display, you can access several menus through keystrokes or mouse clicks.  You can bring one big menu up by pressing the second mouse button, or you can bring up the ``chat menu'' by typing C-c C-c.  If you do the latter while point is on a roster entry, that entry will be the default value when you are asked for whom to chat with.

You can also use the function jabber-chat-with, which is what the menu item is bound to.  This function is bound to C-x C-j C-j in the global keymap.

Now, try opening a chat with someone.  A buffer named *-jabber-chat-:-PERSON-* will be created and selected. Type your message at the end of the buffer, and hit RET to send it.  To include a newline in your message, use C-j.

Presence
========

``Presence'' is the Jabber term for letting other people know that you are online, and additionally how ``available'' you are.  There are three elements to presence: availability status (called ``show''), status message, and priority.

Your show status may either be empty (meaning simply ``online''), or one of away, xa, dnd and chat, meaning ``away'', ``extended away'' (i.e. away for an extended period), ``do not disturb'', and ``free for chat'', respectively.  This information is available to everyone subscribing to your presence, but technically it does not restrict anyone's actions.  You can chat with people even if you claim to be away.

The status message is a short text complementing your show status, such as ``at home'', ``working'', ``phone'', ``playing games'' or whatever you want.  It is sent to everyone subscribing to your presence, but not all clients prominently display it to the user.

The priority is only interesting if you are running more than one Jabber client at a time accessing the same account.  In that case, messages sent to you without an indication of which client to send to are sent to the client with the highest priority.

To set your presence, use the function jabber-send-presence. It can be called both interactively and in Lisp code.  For the latter case, use something like (jabber-send-presence "away" "idle for 10 minutes" 10).

By default, jabber.el sets your presence when you connect.  If you want it not to do that, remove jabber-send-default-presence from jabber-post-connect-hook.  If you want to change the presence that is sent, change the variables jabber-default-show, jabber-default-status and jabber-default-priority.

With jabber.el, you can set your presence remotely.  See Ad-Hoc Commands.

Presence subscription
=====================

Having permission to view the presence status of a person is called subscribing to his presence.  Presence subscription between two persons can be asymmetric.

When jabber.el receives a presence subscription request, it will present it to you in an alert requiring immediate response, and offer you to send a subscription request back to that person.

To request subscription to someone, type M-x jabber-send-subscription-request.  You will be prompted for the JID to send it to.  This command can also be accessed through the Roster menu, by typing C-c C-r in the roster buffer.  After that, you will probably want to give the contact a more readable name.  The command for that is jabber-roster-change, which is also available in the Roster menu.

The roster buffer
=================

The roster buffer is called *-jabber-*.  It simply contains a list of the contacts on your roster.

In the roster buffer, any command which requires a JID will default to the JID under point when called.  These commands can be called through either keyboard menus or mouse menus.  To open a menu with the mouse, simply press the second mouse button over the JID in question. (For some reason, mouse menus don't work in XEmacs. Patches welcome.)  This will bring up a menu with all available actions.  The keyboard menus are split into categories: Chat, Roster, Information, MUC (Multi-User Chat, or groupchat) and Services, opened by C-c C-c, C-c C-r, C-c C-i, C-c C-m and C-c C-s, respectively.

A list of keybindings is displayed at the top of the roster buffer. You can turn it off by setting jabber-roster-show-bindings to nil.

You can call jabber-display-roster to redisplay your roster according to changed preferences (see Customizing the roster buffer).  This will not refetch your roster from the server. Refetching the roster is usually not needed, since updates are pushed to clients automatically.

You can choose not to have the roster updated automatically on presence changes (see Presence alerts).  In that case, you need to call jabber-display-roster manually.

Groupchat
*********

The groupchat menu can be accessed by typing C-c C-m in the roster buffer.  You can also type the commands directly, as will be shown here.

To join a groupchat, type M-x jabber-groupchat-join.  You will be prompted for the groupchat to join, and your nickname in the groupchat.  This nickname doesn't need to have any correlation to your JID; in fact, groupchats are usually (but not always) configured such that only moderators can see your JID.  You can change your nickname with M-x jabber-muc-nick.  See Automation, for setting default nicknames.

Groupchat messages will be displayed in a buffer called *-jabber-groupchat-:-GROUPCHAT-*.  It works much like the chat buffer.

To change the topic of a groupchat, type M-x jabber-muc-set-topic. The current topic is shown in the header line.

To leave a groupchat, type M-x jabber-groupchat-leave.

If you are the owner of a groupchat, you can change its configuration by typing M-x jabber-groupchat-get-config.  A configuration form will be rendered in new buffer.

To see which people are in a groupchat, type M-x jabber-muc-names.  This gives a list of nicknames, ``roles'', ``affiliations'', and possibly JIDs.  See MUC Administration, for the meaning of roles and affiliations.

Automation
==========

You can select a default nickname by setting jabber-nickname. Additionally, you can set different nicknames for different groups, by customizing jabber-muc-default-nicknames.  There you specify the JID of the group, and your preferred nickname.

If you want to automatically join certain rooms when connecting, you can set jabber-muc-autojoin to a list containing the JIDs of the rooms you want to enter.  To disable this feature, remove jabber-muc-autojoin from jabber-post-connect-hook.

Invitations
===========

You can invite someone to a groupchat with M-x jabber-muc-invite (also available in the MUC menu).  Pay attention to the order of the arguments --- as both users and rooms are just JIDs, it is technically possible to invite a room to a user, but that's probably not what you want.

When you receive an invitation, it appears in the chat buffer along with two buttons, ``Accept'' and ``Decline''.  Pressing ``Accept'' enters the room, as you would expect.  Pressing ``Decline'' gives you an opportunity to state the reason why you're not joining.

Private messages
================

You can open a private chat with a participant in a chat room with M-x jabber-muc-private (or by using the MUC menu).  This creates a buffer with the name *-jabber-muc-priv-GROUP-NICKNAME-* (customizable by jabber-muc-private-buffer-format), which behaves mostly like an ordinary chat buffer.  This buffer will also be created if someone sends a private message to you.

Private MUC messages use the same alerts as normal chat messages. See Message alerts.

Administration
==============

Administration of a MUC room mostly consists of managing roles and affiliations.  Roles are temporary, and apply until the user leaves the room.  Affiliations are permanent, and based on JIDs.

Roles
-----

If you have moderator privileges, you can change the role of a participant with M-x jabber-muc-set-role.  Kicking means setting the role to ``none''.  Granting and revoking voice are ``participant'' and ``visitor'', respectively.  ``moderator'' gives moderator privileges, obviously.

The possible roles are:

moderator
     Has voice, can change other people's roles.

participant
     Has voice.

visitor
     Doesn't have voice (can't send messages to everyone, but can send private messages)

none
     Not in room.

Affiliations
------------

If you have admin or owner privileges, you can change the affiliation of a user with M-x jabber-muc-set-affiliation.  Affiliation is persistent, and based on JIDs.  Depending of your affiliation and the MUC implementation, you might not be allowed to perform all kinds of changes, and maybe not in one step.

Affiliations are:

owner
     Can destroy room, appoint admins, make people members, ban people.

admin
     Can make people members or ban people.

member
     Can enter the room, and has voice by default.

none
     Rights depend on room configuration.  The room might be members-only, or grant voice only to members.

outcast
     Banned from the room

Services
********

Not every Jabber entity is a physical person.  There are many automatic entities, called servers, services, components, agents, transports and other names.  The use of these is described here.

The functions described in this chapter use browse buffers. Browse buffers are named *-jabber-browse-:-SERVICE-*, sometimes with a numerical suffix.  The different menus have the same keybindings as in the roster buffer, and if you call a function operating on a JID while point is over a JID, that JID will be the default value, so you don't have to type it or copy it yourself.

Service discovery and browsing
==============================

To find services you want to use, you need to discover them first. This can be done with either service discovery or browsing.  Service discovery is the newer and preferred protocol, while browsing is still used by much software.  The use of both is very similar.

The most common use of service discovery is to browse your home server, to see what services are provided locally.  Note, however, that this is no restriction; you can use services from all over the network.

For service discovery there are two commands, jabber-get-disco-items and jabber-get-disco-info, depending on whether you want information about that specific JID or about services related to it, respectively.  To start browsing, type M-x jabber-get-browse and enter the JID you want to browse.

These commands can be accessed from the Info menu, which is opened by typing C-c C-i.

If you think that the interface to service discovery is awkward and should be replaced with something better, you are completely right.

Registering
===========

Some services, in particular user directories and gateways to legacy IM systems, require registration.  To register with such a service, either type M-x jabber-get-register or select it from the Service menu, which is opened by typing C-c C-s.  You have to know the service's JID, possibly from service discovery. (see Service discovery and browsing)

This is also the way to change your registration details, e.g. your password --- just ask to register with that service again.  To change the password of your Jabber account, ask to register with your Jabber server.

Please note that any passwords sent in this way will be sent in cleartext to your Jabber server, unless you have enabled SSL encryption (see Connection settings), and possibly sent in cleartext from your server to the server hosting the service.

jabber.el will then request a registration form from that service.  If for some reason the service does not answer (maybe network problems, or some services neither support registration nor report errors about that) that will be the last thing you saw about it.  jabber.el will not report timeout errors, but rather simply wait until you shut it down.

Once the response arrives, the form will be rendered in a browse buffer.  Just fill out the fields, and hit Submit.  You will receive confirmation of your registration in the echo area.

To cancel an existing registration (and also for cancelling your Jabber account, if you sent a registration request to your server), hit Cancel.  The unregistration will be confirmed in the echo area.

Searching
=========

Some services, notably user directories and gateways to legacy IM systems, allow searching.  Searching in Jabber generally means searching for someone's JID, but the protocol is general enough to support most databases.

To search a service, either type M-x jabber-get-search or select it from the Service menu, which is opened by typing C-c C-s.

Just like with registration, this command sends a request for a search form, and displays it if and when the response arrives.  Enter your search and submit it.  Search results will be displayed in a different browse buffer.

Ad-Hoc Commands
===============

jabber.el supports a subset of JEP-0050, the standard for Ad-Hoc Commands.  As the name implies, this can be used for just about anything.  It has been used for remote-controlling clients (e.g. Psi), and administering services (e.g. PyMSNt).

Currently, jabber.el uses ad-hoc commands for setting presence remotely. If you realize that you forgot to set your client to ``away'' with a low priority, you can do it remotely. (Most Jabber servers also support kicking a client off the net by logging in with another client with exactly the same resource.)

The commands for executing ad-hoc commands are available under the Service menu, which is opened by typing C-c C-s.

To find which commands are available, run ``Request command-list'' (jabber-ahc-get-list). (This is the same thing as a disco items request to the node http://jabber.org/protocol/commands.)

To run a command from the list, put point over it and run ``Execute command'' (jabber-ahc-execute-command), accepting the defaults for JID and node.  (If you already know those, you could of course enter them yourself)  The form you get should hopefully be self-explanatory.

Personal information
********************

The Jabber way of handling personal information (name, addresses, phone numbers, etc) is ``vCards'' encoded in XML.  You can get information about a user by running M-x jabber-vcard-get, and you can edit your own information by running M-x jabber-vcard-edit.

The form for editing your information can be slightly confusing --- you are allowed to enter any number of addresses, phone numbers and e-mail addresses, each of which has a set of orthogonal properties. You can add and remove items with the [INS] and [DEL] buttons, respectively.

Useful features
***************

jabber.el includes a number of features meant to improve the user interface and do other useful things.

Autoaway
========

It is possible to automatically set your status to ``away'' when you haven't used your computer for a while.  This lets your contacts know that you might not answer immediately.

To activate this feature, add jabber-autoaway-start to jabber-post-connect-hook, e.g:

     (add-hook 'jabber-post-connect-hook 'jabber-autoaway-start)

There are different methods to find how long you have been ``idle''. The method to use is specified by jabber-autoaway-method.  The value of this variable should be a function that returns the number of seconds you have been idle.  Three functions are provided.

If you are running Emacs 22 and thus have the current-idle-time function, it is used by default.  Note that this method only measures the time since you last interacted with Emacs, and thus disregards activity in other programs.

If you are using the X Window System, you can use the xprintidle (http://www.dtek.chalmers.se/~henoch/text/xprintidle.html) program.  Make sure that jabber-xprintidle-program is set to the correct file name.  This uses the same method as XScreensaver to find your idle time.

If you are using Emacs on a GNU/Linux terminal, the function jabber-termatime-get-idle-time is used by default.

Modeline status
===============

By typing M-x jabber-mode-line-mode you toggle display of some status in mode lines.  The information is your own presence status, and some numbers showing the status of your roster contacts.  By default, there are three numbers, for ``online'' (chatty and online), ``away'' (away, extended away and do not disturb) and offline contacts.

If you set jabber-mode-line-compact to nil, you get a complete breakdown of presence status.  That gives you six numbers indicating the number of chatty, online, away, extended away, dnd, and offline contacts, respectively.

Keepalive
=========

Sometimes network connections are lost without you noticing.  This is especially true with Jabber, as it is quite reasonable to keep the connection open for a long time without either sending or receiving any data.

If you want to detect a lost connection earlier, you can use the keepalive functions.  Type M-x jabber-keepalive-start to start it, and M-x jabber-keepalive-stop to stop it.

These functions work by asking your server for the time once in a while (by default every ten minutes), and considering the connection lost if the server doesn't answer within reasonable time (by default 20 seconds).

You can customize the interval and the timeout with the variables jabber-keepalive-interval and jabber-keepalive-timeout, respectively.

Tracking activity
=================

When you're working on something important you might want to delay responding to incoming messages.  However, when you're done working, will you remember them?  If you're anything like me, you'll have a lot of buffers in your Emacs session, and a jabber chat buffer can easily get lost.

When you type M-x jabber-activity-mode Emacs starts keeping track of the buddies which have messaged you since last you visited their buffer, and will display them in mode line.  As soon as you visit their buffer they disappear from the mode line, indicating that you've read their message.

If your mode line fills over because of these notifications, you can customize jabber-activity-make-strings to shorten them to the shortest possibly unambiguous form.

If you try to exit Emacs while you still have unread messages, you will be notified and asked about this.  If you don't like that, set jabber-activity-query-unread to nil.

If you want to display the number of unread buffers in the frame title, set jabber-activity-count-in-title to t.  The format of the number can be changed through jabber-activity-count-in-title-format.

For complete customizability, write a hook function for jabber-activity-update-hook.  From that function, you can take action based on jabber-activity-jids, jabber-activity-mode-string, and jabber-activity-count-string.

Watch buddies
=============

Sometimes you might be waiting for a certain person to come online, and you don't want that occasion to get lost in the noise.  To get an obtrusive message when that happens, type M-x jabber-watch-add and select the person in question.  You can enter a comment, to remember why you added the watch.

You will get a message whenever that person goes from offline to online.  jabber.el will remember this for the rest of your Emacs session (it's not saved to disk, though), but if you want to get rid of it, type M-x jabber-watch-remove.

Spell checking
==============

You can activate spell checking in a chat buffer with M-x flyspell-mode.  It will check only what you are currently writing, not what you receive or what you have already sent.  You may want to add flyspell-mode to jabber-chat-mode-hook.

For more information about Emacs spell checking, see Checking and Correcting Spelling (GNU Emacs Manual).

Message history
***************

If you want a record of messages sent and received, set jabber-history-enabled to t.  By default all messages to will be saved to a global history file specified by jabber-global-history-filename (~/.jabber_global_message_log by default).  If you prefer to store your chats' history in per-contact files, you can set the jabber-use-global-history variable to nil.  When using per-contact history, files are named by the contact JID and saved under the directory specified by the variable jabber-history-dir (default is ~/.emacs-jabber).

There is no facility for reading old messages yet, but just reading the file as text should be enough for many purposes.

When you open a new chat buffer and have entries in your history file, the last few messages you recently exchanged with the contact in question will be inserted.  You can control how many messages with jabber-backlog-number (by default 10), and how old messages with jabber-backlog-days (by default 3 days).

If you worry about your history file(s) size, you can enable history rotation feature by setting the variable jabber-history-enable-rotation to t (default is nil).  This feature ``rotates'' your history files according to the following rule: When jabber-history-size-limit (in kilobytes) is reached, the history file is renamed to <history-file>-<number>, where <number> is 1 or the smallest number after the last rotation.  For example, suppose you set the jabber-history-size-limit variable to 512 and you chat with your buddy foo@jabber.server using the per-contact strategy to store history files.  So, when the history file (foo@jabber-server) reaches 512K bytes, it will be renamed to foo@jabber-server-1 and foo@jabber-server will be set empty. Next time foo@jabber-server grows to 512K bytes, it will be saved as foo@jabber-server-2 and so on.  Although the example was presented with the per-contact history file strategy, history rotation works for both per-contact and global history logging strategies.

Message events
**************

In the status line of the chat buffer, you can sometimes see notifications about the progress of the message you just sent.  These states are possible:

  * Delivered to offline storage (the user will receive it on next logon)

  * Delivered to user's client (but not necessarily displayed)

  * Displayed to user

  * User is composing a reply

The first state is only reported by servers; the other three are reported by clients.  jabber.el can report all three of them, and can display all four; not all clients support all states, though.

If you don't want jabber.el to send out this information about you, set the variables jabber-events-confirm-delivered, jabber-events-confirm-displayed, and/or jabber-events-confirm-composing to nil.  You can make jabber.el not to request such information by customizing jabber-events-request-these.

Roster import and export
************************

Your roster is saved on the Jabber server, and usually not in the client.  However, you might want to save the roster to a file anyway. The most common reason for this is probably to copy it to another account.

To export your roster to a file, type M-x jabber-export-roster. A buffer will appear in which you can edit the data to be exported. Changes done in that buffer will not affect your real roster.

To import your roster from a file, type M-x jabber-import-roster. You will be able to edit the data before importing it.  Items not in the roster will be added; items in the roster will be modified to match imported data.  Subscriptions will be updated.

The format of the roster files is the XML used by roster pushes in the XMPP protocol, in UTF-8 encoding.

XMPP URIs
*********

Many web page authors use links starting with xmpp: for JIDs. Your web browser could be made to pass such links to jabber.el, so that such links are actually useful and not just decoration.  How to do that depends on your operating system and web browser.

Mozilla and Unix
================

If you use a Mozilla-based web browser on a Unix-like operating system, follow these steps.

 1. Make sure you are running the Emacs server.  See Using Emacs as a Server (GNU Emacs Manual).

 2. Note the path of the xmppuri.sh file in the jabber.el distribution, and make sure it is executable.

 3. Set the Mozilla preference network.protocol-handler.app.xmpp to the path of xmppuri.sh.  There are two ways to do this:

       * Go to the URL about:config, right-click in the list, choose ``New string'', and enter network.protocol-handler.app.xmpp and the path in the following dialogs.

       * Open or create the file user.js in your Mozilla profile directory (in the same directory as prefs.js), and add the following line:

               user_pref("network.protocol-handler.app.xmpp", "/PATH/TO/xmppuri.sh");

          Restart Mozilla for this change to take effect.

Other systems
=============

If you know how to pass an XMPP URI from your browser to the function jabber-handle-uri, your contribution for this section would be appreciated.

Customization
*************

jabber.el is intended to be customizable for many tastes.  After all, this is Emacs.  To open a customization buffer for jabber.el, type M-x jabber-customize.

Account settings
================

jabber-username is the username part of your JID.

jabber-server is the JID of your server, i.e. the hostname part of your JID.  This is usually, but not necessarily, the same as the hostname of the server.

jabber-password is your password.  You have the option to set it here, in which case it will be stored in cleartext in your .emacs file.  If this is set to nil, you will be prompted for your password every time you connect.

jabber-resource is the resource you want to log in under.  This only matters if you are connected to the same account from different clients or different computers, since each connection must have a unique resource.  You might want to set this to your hostname.

jabber-default-priority is the default priority sent with your presence.  Regardless of what you have here, you can change your priority during a session with jabber-send-presence. See Presence, for more information on priority.

jabber-nickname is your default nickname for groupchats.

Connection settings
===================

jabber-network-server is the hostname or IP address of your server.  If it is set to nil, jabber.el will use the name in jabber-server.

jabber-port is the TCP port of the server to connect to.  If nil, the default port is selected based on the chosen connection method.

If both jabber-network-server and jabber-port are nil, and a sufficiently modern dns.el is available, jabber.el will use SRV records to find the right hostname and port.

jabber-connection-type specifies what kind of connection to use.  network means normal unencrypted network connection (usually on port 5222), and ssl means encrypted connection through GnuTLS or OpenSSL (port 5223), while starttls will initiate an unencrypted connection and switch to encrypted if offered by the server.  You can change the settings of the encryption program through M-x customize-group RET tls, M-x customize-group RET starttls or M-x customize-group RET ssl, respectively.

By default, GnuTLS will be used if the tls library is available, and if that fails, OpenSSL will be used if the ssl library is available.  You can force the use of either program by setting jabber-connection-ssl-program to gnutls or openssl, respectively.  If you use starttls the library with the same name is required, and it depends on the GnuTLS command line client.

Miscellaneous settings
======================

If you want a Jabber menu on the menu bar with some common commands, type M-x jabber-menu.  You can remove it again with C-u M-x jabber-menu.  Unfortunately, this cannot be changed through Customize settings, so you need to add (jabber-menu) to your .emacs to enable it permanently.

Customizing the roster buffer
=============================

jabber-roster-sort-functions controls how roster items are sorted.  By default, contacts are sorted first by presence, and then alphabetically by displayed name.

jabber-sort-order controls how roster items are sorted by presence.  It is a list containing strings corresponding to show status (see Presence) or nil, which represents offline.

jabber-show-resources controls when your contacts' resources are shown in the roster buffer.  The default is to show resources when a contact has more than one connected resource.

jabber-roster-line-format specifies how the entry for each contact looks.  It is a string where some characters are special if preceded by a percent sign:

%c
     "*" if the contact is connected, or " " if not

%n
     Nickname of contact, or JID if no nickname

%j
     Bare JID of contact (without resource)

%r
     Highest-priority resource of contact

%s
     Availability of contact as string ("Online", "Away" etc)

%S
     Status string specified by contact

jabber-resource-line-format is nearly identical, except that the values correspond to the values of the resource in question, and that the %p escape is available, which inserts the priority of the resource.

jabber-roster-buffer specifies the name of the roster buffer. If you change this, the new name will be used the next time you connect.

jabber-roster-show-bindings controls whether to show a list of keybindings at the top of the roster buffer.  You need to run M-x jabber-display-roster after changing this variable to update the display.

Customizing the chat buffer
===========================

You can customize the look of the prompts in the chat buffer.  There are separate settings for local (i.e. your own messages) and foreign prompts.

jabber-chat-text-local and jabber-chat-text-foreign determine the faces used for chat messages.

jabber-chat-prompt-local and jabber-chat-prompt-foreign determine the faces used for the prompts.

jabber-chat-local-prompt-format and jabber-chat-foreign-prompt-format determine what text is displayed in the prompts.  They are format strings, with the following special sequences defined:

%t
     The time when the message was sent or received

%n
     The nickname of the user.  For the foreign prompt, this is the name of the contact in the roster, or the JID if no name set.  For the local prompt, this is the username part of your JID.

%j
     The bare JID of the user

jabber-chat-time-format defines how %t shows time.  Its format is identical to that passed to format-time-string. See Time Conversion (GNU Emacs Lisp Reference Manual).

jabber-chat-delayed-time-format is used instead of jabber-chat-time-format for delayed messages (messages sent while you were offline, or fetched from history).  This way you can have short timestamps everywhere except where you need long ones.  You can always see the complete timestamp in a tooltip by hovering over the prompt with the mouse.

``rare'' times).  This can be toggled with jabber-print-rare-time.  You can customize the displayed time by setting jabber-rare-time-format.  Rare timestamps will be printed whenever time formatted by that format string would change.

You can also customize the header line of chat buffers, by modifying the variable jabber-chat-header-line-format.  The format of that variable is the same as that of mode-line-format and header-line-format.  See Mode-Line Format (GNU Emacs Lisp Reference Manual).  For MUC buffers, jabber-muc-header-line-format is used instead.

The variable jabber-chat-fill-long-lines controls whether long lines in the chat buffer are filled.

Customizing alerts
==================

When an event happens (currently including presence changes, incoming messages, and completed queries) you will usually want to be notified.  Since tastes in this area vary wildly, these alerts are implemented as hooks, so you can choose which ones you want, or write your own if none fit.

Actually, if you don't want to write your own, stop reading this section and just read Standard alerts.

Many kinds of alerts consist in displaying a text message through a certain mechanism.  This text message is provided by a function which you can rewrite or replace.  If this function returns nil, no message is displayed, and non-textual alerts refrain from action.

If you want to write alert hooks that do nothing except displaying the supplied message in some way, use the macro define-jabber-alert.  For example, if FOO is a function that takes a string as an argument, write

     (define-jabber-alert foo
       "Display a message in a fooish way"
       'foo)

and all details will be taken care of for you.

The hooks take different arguments depending on category.  However, they all have in common that the last argument is the result of the message function.  The message function for each category takes the same arguments as the corresponding hooks, except for that last argument.

Alert hook contributions are very welcome.  You can send them to the mailing list, or to the Sourceforge patch tracker.

Alert hooks are meant for optional UI things, that are subject to varying user tastes, and that can be toggled by simply adding or removing the function from/to the hook.  For other things, there are corresponding general hooks, that are defvars instead of defcustoms, and that are to be managed by Lisp code.  They have the same name as the alert hooks minus the -alert part, i.e. jabber-message-hooks vs jabber-alert-message-hooks, etc.

Standard alerts
---------------

Eight alerts are already written for all four alert categories.  These all obey the result from the corresponding message function.

The beep alerts simply sound the terminal bell by calling ding.  They are disabled by default.

The echo alerts display a message in the echo area by calling message.  They are enabled by default.

The switch alerts switch to the buffer where the event occurred (chat buffer for incoming messages, roster buffer for presence changes, browse buffer for completed queries).  They are disabled by default.  Take care when using them, as they may interrupt your editing.

The display alerts display but do not select the buffer in question, using the function display-buffer.  See Choosing a Window for Display (GNU Emacs Lisp Reference Manual), for information about customizing its behaviour. This is enabled by default for info requests.

The wave alerts play a sound file by calling play-sound-file.  No sound files are provided.  To use this, enter the names of the sound files in jabber-alert-message-wave, jabber-alert-presence-wave and jabber-alert-info-wave, respectively.

The screen alerts send a message through the Screen terminal manager (see http://www.gnu.org/software/screen/).  They do no harm if called when you don't use Screen.

The ratpoison alerts send a message through the Ratpoison window manager (see http://ratpoison.sourceforge.net/).  They do no harm if used when you're not running X, but if you are running X with another window manager, the ratpoison processes will never exit. You can look at them with list-processes.

The sawfish alerts send a message through the Sawfish window manager.

The festival alerts speak the message using the Emacs interface of the Festival speech synthesis system (see http://www.cstr.ed.ac.uk/projects/festival/).

Additionally, for one-to-one and MUC messages, there are scroll alerts (enabled by default), that aim to do the right thing with chat buffers that are visible but not active.  Sometimes you want point to scroll down, and sometimes not.  These functions should do what you mean; if they don't, it's a bug.

Some of these functions are in the jabber-alert.el file, and the others are in their own files.  You can use them as templates or inspiration for your own alerts.

Presence alerts
---------------

Set jabber-alert-presence-message-function to your desired function.  This function should look like:

     (defun FUNCTION (WHO OLDSTATUS NEWSTATUS STATUSTEXT)
        ...
        )

WHO is the JID symbol (see Roster structure), OLDSTATUS and NEWSTATUS are the previous and current stati, respectively, and STATUSTEXT is the status message if provided, otherwise nil.

NEWSTATUS can also be one of "subscribe", "subscribed", "unsubscribe" and "unsubscribed".

The default function, jabber-presence-default-message, returns nil if OLDSTATUS and NEWSTATUS are the same, and in other cases constructs a message from the given data.

All presence alert hooks take the same arguments plus the additional PROPOSED-ALERT, which is the result of the specified message function.  This last argument is usually the only one they use.

Message alerts
--------------

If you don't want message alerts when the chat buffer in question is already the current buffer, set jabber-message-alert-same-buffer to nil.  This affects the behaviour of the default message function, so you'll have to reimplement this functionality if you write your own message function.

Set jabber-alert-message-function to your desired function. (Logically it should be jabber-alert-message-message-function, but that would be really ugly.)  This function should look like:

     (defun FUNCTION (FROM BUFFER TEXT)
        ...
        )

FROM is the JID symbol (see Roster structure), BUFFER is the buffer where the message is displayed, and TEXT is the text of the message.

The default function, jabber-message-default-message, returns ``Message from PERSON'', where PERSON is the name of the person if specified in the roster, otherwise the JID.

All message alert hooks take the same arguments plus the additional PROPOSED-ALERT, which is the result of the specified message function.

MUC alerts
----------

Set jabber-alert-muc-function to your desired function.  This function should look like:

     (defun FUNCTION (NICK GROUP BUFFER TEXT)
        ...
        )

NICK is the nickname, GROUP is the JID of the group, BUFFER is the buffer where the message is displayed, and TEXT is the text of the message.

The default function, jabber-muc-default-message, returns ``Message from NICK in GROUP'' or ``Message in GROUP'', the latter for messages from the room itself.

All MUC alert hooks take the same arguments plus the additional PROPOSED-ALERT, which is the result of the specified message function.

Info alerts
-----------

Info alerts are sadly underdeveloped.  The message function, jabber-alert-info-message-function, takes two arguments, INFOTYPE and BUFFER.  BUFFER is the buffer where something happened, and INFOTYPE is either 'roster for roster updates, or 'browse for anything that uses the browse buffer (basically anything except chatting).

The info alert hooks take an extra argument, as could be expected.

Hooks
=====

jabber.el provides various hooks that you can use for whatever purpose.

jabber-post-connect-hook
     This hook is called after successful connection and authentication. By default it contains jabber-send-default-presence (see Presence).

jabber-lost-connection-hook
     This hook is called when you have been disconnected for unknown reasons.  Usually this isn't noticed for quite a long time.

jabber-pre-disconnect-hook
     This hook is called just before voluntary disconnection.  This might be due to failed authentication, so check *jabber-authenticated* if you want to send a stanza.

jabber-post-disconnect-hook
     This hook is called after disconnection of any kind, possibly just after jabber-lost-connection-hook.

jabber-chat-mode-hook
     This hook is called when a new chat buffer is created.

Debug options
=============

These settings provide a lot of information which is usually not very interesting, but can be useful for debugging various things.

jabber-debug-log-xml activates XML logging.  All XML stanzas sent and received are logged in the buffer *-jabber-xml-log-* in list format.  See XML representation.

Hacking and extending
*********************

This part of the manual is an attempt to explain parts of the source code.  It is not meant to discourage you from reading the code yourself and trying to figure it out, but as a guide on where to look.  Knowledge of Jabber protocols is assumed.

XML representation
==================

The XML representation is the one generated by xml.el in Emacs, namely the following.  Each tag is a list.  The first element of the list is a symbol, the name of which is the name of the tag.  The second element is an alist of attributes, where the keys are the attribute names in symbol form, and the values are strings.  The remaining elements are the tags and data contained within the tag.

For example,

     <foo bar='baz'>
     <frobozz/>Fnord
     </foo>

is represented as

     (foo ((bar . "baz")) (frobozz nil "") "Fnord
     ")

Note the empty string as the third element of the frobozz list.  It is not present in newer (post-21.3) versions of xml.el, but it's probably best to assume it might be there.

If you want to see what an XML tag would look like, use jabber-sexp2xml, which takes a tag and returns a string.  You will usually not need it in your code, as you can use jabber-send-sexp to send away your tags to the server.

Roster structure
================

Roster entries are contained in the list *jabber-roster*.

A roster entry is a symbol.  Its name is the JID, and it is interned in jabber-jid-obarray.  A roster entry can have the following properties:

xml
     The XML tag received from the server on roster update

name
     The name of the roster item (just like the XML attribute)

subscription
     The subscription state (also copied)

ask
     The ask state (copied)

groups
     A list of strings (possibly empty) containing all the groups the contact is in

connected
     Boolean, true if any resource is connected

show
     Presence show status for highest-priority connected resource

status
     Presence status message for highest-priority connected resource

resources
     Alist.  Keys are strings (resource names), values are plists with properties connected, show, status and priority.

Incoming presence information is inserted in resources, and the information from the resource with the highest priority is inserted in show and status by the function jabber-prioritize-resources.

Listening for new requests
==========================

To listen for new IQ requests, add the appropriate entry in jabber-iq-get-xmlns-alist or jabber-iq-set-xmlns-alist. The key is the namespace of the request, and the value is a function that takes one argument, the entire IQ stanza in list format. jabber-process-iq reads these alists to determine which function to call on incoming packets.

For example, the Ad-Hoc Commands module contains the following:

     (add-to-list 'jabber-iq-set-xmlns-alist
     	     (cons "http://jabber.org/protocol/commands" 'jabber-ahc-process))

To send a response to an IQ request, use (jabber-send-iq SENDER "result" QUERY nil nil nil nil ID), where QUERY is the query in list format.  jabber-send-iq will encapsulate the query in an IQ packet with the specified id.

To return an error to the Jabber entity that sent the query, use jabber-signal-error.  The signal is caught by jabber-process-iq, which takes care of sending the error.

Sending new requests
====================

To send an IQ request, use jabber-send-iq.  It will generate an id, and create a mapping for it for use when the response comes.  The syntax is:

     (jabber-send-iq TO TYPE QUERY
                     SUCCESS-CALLBACK SUCCESS-CLOSURE
                     FAILURE-CALLBACK FAILURE-CLOSURE)

Both callbacks take two arguments, the IQ stanza returned and the closure item mentioned here.

Two standard callbacks are provided.  jabber-report-success takes a string as closure item, and reports success or failure in the echo area.  jabber-process-data prepares a browse buffer.  If its closure argument is a function, it calls that function with point in this browse buffer.  If it's a string, it prints that string along with the error message in the IQ response.  If it's anything else (e.g. nil), it just dumps the XML in the browse buffer.

Examples follow.  This is the hypothetical Jabber protocol ``frob'', for which only success report is needed:

     (jabber-send-iq "someone@somewhere.org" "set"
                     '(query ((xmlns . "frob")))
                     'jabber-report-success "Frobbing"
                     'jabber-report-success "Frobbing")

This will print ``Frobbing succeeded'' or ``Frobbing failed: reason'', respectively, in the echo area.

The protocol ``investigate'' needs to parse results and show them in a browse buffer:

     (jabber-send-iq "someone@somewhere.org" "get"
                     '(query ((xmlns . "investigate")))
                     'jabber-process-data 'jabber-process-investigate
                     'jabber-process-data "Investigation failed")

Of course, the previous example could have used jabber-report-success for the error message.  It's a matter of UI taste.

Service discovery
=================

Your new handlers will likely want to advertise their existence through service discovery.

To have an additional feature reported in response to disco info requests, add a string to jabber-advertised-features.

By default, the service discovery functions reject all requests containing a node identifier with an ``Item not found'' error.  To make them respond, add the appropriate entries to jabber-disco-items-nodes and jabber-disco-info-nodes. Both variables work in the same way.  They are alists, where the keys are the node names, and the values are lists of two items.

The first item is the data to return --- either a list or a function taking the entire IQ stanza and returning a list, this list containing the XML nodes to include in the <query/> node in the response.

The second item is the access control function.  An access control function receives the JID as its only argument, and returns non-nil if access is to be granted.  If nil is specified instead of a function, access is always granted.  One such function is provided, jabber-my-jid-p, which grants access for JIDs where the username and server (not necessarily resource) are equal to those of the user.

Chat printers
=============

Chat printers are functions that print a certain aspect of an incoming message in a chat buffer.  Included are functions for printing subjects (jabber-chat-print-subject), bodies (jabber-chat-print-body, and jabber:x:oob-style URLs (jabber-chat-print-url).  The functions in jabber-chat-printers are called in order, with the entire <message/> stanza as argument, and are expected to call insert if they have anything to add.

For MUC, the functions in jabber-muc-printers are prepended to those in jabber-chat-printers.

Body printers are a subgroup of chat printers.  They are exclusive; only one of them applies to any given message.  The idea is that ``higher-quality'' parts of the message override pieces included for backwards compatibility.  Included are jabber-muc-print-invite and jabber-chat-normal-body; functions for XHTML-IM and PGP encrypted messages may be written in the future.  The functions in jabber-body-printers are called in order until one of them returns non-nil.

Stanza chains
=============

If you really need to get under the skin of jabber.el, you can add functions to the lists jabber-message-chain, jabber-iq-chain and jabber-presence-chain.  The functions in these lists will be called in order when an XML stanza of the corresponding type arrives, with the entire XML stanza passed as the only argument.  Earlier functions can modify the stanza to change the behaviour of downstream functions.

Protocol support
****************

These are the protocols currently supported (in full or partially) by jabber.el.

RFC 3920 (XMPP-CORE)
====================

Most of RFC 3920 is supported, with the following exceptions.

SASL is supported only when an external SASL library from FLIM or Gnus is present.  As SASL is an essential part to XMPP, jabber.el will send pre-XMPP stream headers if it is not available.

None of the stringprep profiles are implemented.  jabber.el changes JIDs to lowercase internally; that's all.

jabber.el doesn't interpret namespace prefixes.

The xml:lang attribute is neither interpreted nor generated.

SRV records are used if a modern version of dns.el is installed.

RFC 3921 (XMPP-IM)
==================

Most of RFC 3921 is supported, with the following exceptions.

Messages of type ``headline'' are not treated in any special way.

The <thread/> element is not used or generated.

Neither sending nor receiving ``directed presence'' is supported.

Privacy lists are not supported at all.

jabber.el doesn't support XMPP-E2E or ``im:'' CPIM URIs.

JEP-0004 (Data Forms)
=====================

JEP-0004 support is good enough for many purposes.  Limitations are the following.

Forms in incoming messages are not interpreted.  See each specific protocol for whether forms are accepted in that context.

``Cancel'' messages are probably not consistently generated when they should be.  This is partly a paradigm clash, as jabber.el doesn't use modal dialog boxes but buffers which can easily be buried.

<required/> elements are not enforced.

The field types ``jid-single'', ``jid-multi'' and ``list-multi'' are not implemented, due to programmer laziness.  Let us know if you need them.

JEP-0020 (Feature Negotiation)
==============================

There are no known limitations or bugs in JEP-0020 support.

JEP-0022 (Message Events)
=========================

jabber.el understands all four specified kinds of message events (offline, delivered, displayed, and composing) and by default requests all of them.  It also reports those three events that make sense for clients.

JEP-0030 (Service Discovery)
============================

Service discovery is supported, both as client and server, with the following limitations.  Currently, the client part is not used by any code, but is provided only as a user tool.  The user interface is not appealing.

Publishing items is not supported.

JEP-0045 (Multi-User Chat)
==========================

jabber.el supports parts of JEP-0045.  Entering, leaving and chatting work.  So do invitations and private messages.  Room configuration is supported.  Changing roles of participants (basic moderation) is implemented, as is changing affiliations, but requesting affiliation lists is not yet supported.

JEP-0050 (Ad-Hoc Commands)
==========================

jabber.el is probably the first implementation of JEP-0050 (see post on jdev from 2004-03-10 (http://article.gmane.org/gmane.network.jabber.devel/21413)).  Both the client and server parts are supported.

JEP-0054 (vcard-temp)
=====================

Both displaying other users' vCards and editing your own vCard are supported.  The implementation tries to follow the schema in the JEP accurately.

JEP-0055 (Jabber Search)
========================

JEP-0055 is supported, both with traditional fields and with Data Forms (see JEP-0004 (Data Forms)).  As the traditional fields specified by the JEP is a subset of those allowed in JEP-0077, handling of those two form types are merged.  JEP-0077 (In-Band Registration).

JEP-0065 (SOCKS5 Bytestreams)
=============================

JEP-0065 support seems to work, but it is not yet enabled by default.

Currently jabber.el cannot act as a server, not even on on Emacsen that support server sockets (GNU Emacs 22 and up).  Therefore it relies on proxies.  Proxies have to be entered and queried manually.

Psi's ``fast mode'' (http://delta.affinix.com/specs/stream.html), which gives greater flexibility with regards to NAT, is not implemented.

JEP-0066 (Out of Band Data)
===========================

jabber.el will display URLs sent in message stanzas qualified by the jabber:x:oob namespace, as described in this JEP.  Sending such URLs or doing anything with iq stanzas (using the jabber:iq:oob namespace) is not supported.

JEP-0068 (Field Standardization for Data Forms)
===============================================

JEP-0068 is only used in the context of creating a new Jabber account, to prefill the username field of the registration form.

JEP-0077 (In-Band Registration)
===============================

In-band registration is supported for all purposes.  That means registering a new Jabber account, changing Jabber password, removing a Jabber account, registering with a service, and cancelling registration to a service.  Data forms are supported as well.  URL redirections are not.

jabber.el will not prevent or alert a user trying to change a password over an unencrypted connection.

JEP-0078 (Non-SASL Authentication)
==================================

Non-SASL authentication is supported, both plaintext and digest. Digest is preferred, and a warning is displayed to the user if only plaintext is available.

JEP-0082 (Jabber Date and Time Profiles)
========================================

The DateTime profile of JEP-0082 is supported.  Currently this is only used for file transfer.

JEP-0086 (Error Condition Mappings)
===================================

Legacy errors are interpreted, but never generated.  XMPP style error messages take precedence when errors are reported to the user.

JEP-0091 (Delayed Delivery)
===========================

The time specified on delayed incoming messages is interpreted, and displayed in chat buffers instead of the current time.

JEP-0092 (Software Version)
===========================

The user can request the version of any entity.  jabber.el answers version requests to anyone, giving ``jabber.el'' as name, and the Emacs version as OS.

JEP-0095 (Stream Initiation)
============================

JEP-0095 is supported, both incoming and outgoing, with the following exceptions.  It is not enabled by default, as it hasn't received much testing.

jabber.el doesn't check service discovery results before sending a stream initiation request.

JEP-0096 (File Transfer)
========================

Both sending and receiving files is supported, though not enabled by default.  The following limitations apply.

The hash of a file being sent is not calculated and sent in the request.

Ranged transfers are not supported.

In-band bytestreams are not yet supported, even though JEP-0096 requires them.

JEP-0146 (Remote Controlling Clients)
=====================================

The ``set-status'' command in JEP-0146 is supported.