summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>2006-01-29 13:08:58 +0000
committerMiles Bader <miles@gnu.org>2006-01-29 13:08:58 +0000
commite5b5275111b6cdf09e573eb494e139834136b91c (patch)
tree126d410d0f5b787582b9b63ca578362ed498794b
parent436f2a80d425eb47051fd6675f2cc7edf9d01242 (diff)
downloademacs-e5b5275111b6cdf09e573eb494e139834136b91c.tar.gz
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-22
Creator: Michael Olson <mwolson@gnu.org> Install ERC.
-rw-r--r--ChangeLog5
-rw-r--r--Makefile.in6
-rw-r--r--etc/ChangeLog4
-rw-r--r--etc/ERC-NEWS599
-rw-r--r--etc/NEWS11
-rw-r--r--info/dir2
-rw-r--r--lisp/erc/ChangeLog327
-rw-r--r--lisp/erc/ChangeLog.20011042
-rw-r--r--lisp/erc/ChangeLog.20022601
-rw-r--r--lisp/erc/ChangeLog.20032145
-rw-r--r--lisp/erc/ChangeLog.20042074
-rw-r--r--lisp/erc/ChangeLog.20051222
-rw-r--r--lisp/erc/erc-autoaway.el207
-rw-r--r--lisp/erc/erc-autojoin.el139
-rw-r--r--lisp/erc/erc-backend.el1786
-rw-r--r--lisp/erc/erc-button.el504
-rw-r--r--lisp/erc/erc-compat.el207
-rw-r--r--lisp/erc/erc-complete.el222
-rw-r--r--lisp/erc/erc-dcc.el1135
-rw-r--r--lisp/erc/erc-ezbounce.el180
-rw-r--r--lisp/erc/erc-fill.el197
-rw-r--r--lisp/erc/erc-goodies.el522
-rw-r--r--lisp/erc/erc-ibuffer.el184
-rw-r--r--lisp/erc/erc-identd.el87
-rw-r--r--lisp/erc/erc-imenu.el143
-rw-r--r--lisp/erc/erc-lang.el213
-rw-r--r--lisp/erc/erc-list.el396
-rw-r--r--lisp/erc/erc-log.el358
-rw-r--r--lisp/erc/erc-match.el658
-rw-r--r--lisp/erc/erc-menu.el121
-rw-r--r--lisp/erc/erc-nets.el861
-rw-r--r--lisp/erc/erc-netsplit.el212
-rw-r--r--lisp/erc/erc-nicklist.el411
-rw-r--r--lisp/erc/erc-nickserv.el337
-rw-r--r--lisp/erc/erc-notify.el254
-rw-r--r--lisp/erc/erc-page.el108
-rw-r--r--lisp/erc/erc-pcomplete.el275
-rw-r--r--lisp/erc/erc-replace.el93
-rw-r--r--lisp/erc/erc-ring.el148
-rw-r--r--lisp/erc/erc-sound.el149
-rw-r--r--lisp/erc/erc-speedbar.el369
-rw-r--r--lisp/erc/erc-spelling.el93
-rw-r--r--lisp/erc/erc-stamp.el335
-rw-r--r--lisp/erc/erc-track.el839
-rw-r--r--lisp/erc/erc-truncate.el121
-rw-r--r--lisp/erc/erc-viper.el74
-rw-r--r--lisp/erc/erc-xdcc.el130
-rw-r--r--lisp/erc/erc.el6144
-rw-r--r--man/ChangeLog8
-rw-r--r--man/Makefile.in9
-rw-r--r--man/erc.texi624
-rw-r--r--man/faq.texi2
-rw-r--r--man/makefile.w32-in9
53 files changed, 28894 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog
index 267a7622e7b..37e9613c706 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-01-29 Michael Olson <mwolson@gnu.org>
+
+ * Makefile.in (install-arch-indep, uninstall): Add ERC.
+ * info/dir (ERC): New entry.
+
2006-01-29 Eli Zaretskii <eliz@gnu.org>
* info/dir: Fix last change.
diff --git a/Makefile.in b/Makefile.in
index 26b2e291367..8468d13b803 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -497,7 +497,7 @@ install-arch-indep: mkdir info
chmod a+r ${infodir}/dir); \
fi; \
cd ${srcdir}/info ; \
- for f in ada-mode* autotype* calc* ccmode* cl* dired-x* ebrowse* ediff* efaq* eintr* elisp* emacs* emacs-mime* emacs-xtra* eshell* eudc* flymake* forms* gnus* idlwave* info* message* mh-e* newsticker* org* pcl-cvs* pgg* reftex* sc* ses* sieve* speedbar* tramp* vip* widget* woman* smtpmail* url* rcirc*; do \
+ for f in ada-mode* autotype* calc* ccmode* cl* dired-x* ebrowse* ediff* efaq* eintr* elisp* emacs* emacs-mime* emacs-xtra* eshell* eudc* flymake* forms* gnus* idlwave* info* message* mh-e* newsticker* org* pcl-cvs* pgg* reftex* sc* ses* sieve* speedbar* tramp* vip* widget* woman* smtpmail* url* rcirc* erc*; do \
(cd $${thisdir}; \
${INSTALL_DATA} ${srcdir}/info/$$f ${infodir}/$$f; \
chmod a+r ${infodir}/$$f); \
@@ -507,7 +507,7 @@ install-arch-indep: mkdir info
thisdir=`/bin/pwd`; \
if [ `(cd ${srcdir}/info && /bin/pwd)` != `(cd ${infodir} && /bin/pwd)` ]; \
then \
- for f in ada-mode autotype calc ccmode cl dired-x ebrowse ediff efaq elisp eintr emacs emacs-mime emacs-xtra eshell eudc flymake forms gnus idlwave info message mh-e newsticker org pcl-cvs pgg reftex sc ses sieve speedbar tramp vip viper widget woman smtpmail url rcirc; do \
+ for f in ada-mode autotype calc ccmode cl dired-x ebrowse ediff efaq elisp eintr emacs emacs-mime emacs-xtra eshell eudc flymake forms gnus idlwave info message mh-e newsticker org pcl-cvs pgg reftex sc ses sieve speedbar tramp vip viper widget woman smtpmail url rcirc erc; do \
(cd $${thisdir}; \
${INSTALL_INFO} --info-dir=${infodir} ${infodir}/$$f); \
done; \
@@ -573,7 +573,7 @@ uninstall:
done
(cd ${archlibdir} && rm -f fns-*)
-rm -rf ${libexecdir}/emacs/${version}
- (cd ${infodir} && rm -f cl* ada-mode* autotype* calc* ccmode* ebrowse* efaq* eintr elisp* eshell* eudc* idlwave* message* pcl-cvs* reftex* speedbar* tramp* widget* woman* dired-x* ediff* emacs* emacs-xtra* flymake* forms* gnus* info* mh-e* newsticker* org* sc* ses* vip* smtpmail* url* rcirc*)
+ (cd ${infodir} && rm -f cl* ada-mode* autotype* calc* ccmode* ebrowse* efaq* eintr elisp* eshell* eudc* idlwave* message* pcl-cvs* reftex* speedbar* tramp* widget* woman* dired-x* ediff* emacs* emacs-xtra* flymake* forms* gnus* info* mh-e* newsticker* org* sc* ses* vip* smtpmail* url* rcirc* erc*)
(cd ${man1dir} && rm -f emacs${manext} emacsclient${manext} etags${manext} ctags${manext})
(cd ${bindir} && rm -f $(EMACSFULL) $(EMACS))
diff --git a/etc/ChangeLog b/etc/ChangeLog
index 0fd6580dcde..9684dd334ad 100644
--- a/etc/ChangeLog
+++ b/etc/ChangeLog
@@ -1,3 +1,7 @@
+2006-01-29 Michael Olson <mwolson@gnu.org>
+
+ * NEWS: Add entry for ERC.
+
2006-01-27 Chong Yidong <cyd@stupidchicken.com>
* TODO: Make SYNC_INPUT the default.
diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS
new file mode 100644
index 00000000000..fea5497a4a5
--- /dev/null
+++ b/etc/ERC-NEWS
@@ -0,0 +1,599 @@
+ERC NEWS -*- outline -*-
+
+* Changes since ERC 5.0.4
+
+** Improve XEmacs compatibility.
+
+** Namespace changes
+
+*** Now ERC doesn't use global variable space.
+Renamed all variables that didn't start with "erc-".
+
+ o `away' is now `erc-away'
+
+ o `current-nick' is now `erc-server-current-nick'
+
+ o `last-peers' is now `erc-server-last-peers'
+
+ o `last-ping-time' is now `erc-server-last-ping-time'
+
+ o `last-sent-time' is now `erc-server-last-sent-time'
+
+ o `lines-sent' is now `erc-server-lines-sent'
+
+ o `quitting' is now `erc-server-quitting'
+
+*** Remove the `with-erc-channel-buffer' function.
+
+** Bugfixes
+
+*** Don't inadvertently destroy face properties.
+
+*** Load erc scripts in a safer way.
+
+*** Don't insert a timestamp if text at point is invisible.
+
+*** Don't hide messages from those in `erc-fools' by default.
+Color their nicks instead.
+
+*** Use a more foolproof method of encoding and decoding strings
+before sending to a channel.
+
+** Backend changes
+
+*** Renamed some server-specific variables
+
+ o `erc-announced-server-name' is now `erc-server-announced-name'
+
+ o `erc-auto-reconnect' is now `erc-server-auto-reconnect'
+
+ o `erc-connect-function' is now `erc-server-connect-function'
+
+ o `erc-default-coding-system' is now `erc-server-coding-system'
+
+ o `erc-duplicate-timeout' is now `erc-server-duplicate-timeout'
+
+ o `erc-duplicates' is now `erc-server-duplicates'
+
+ o `erc-lag' is now `erc-server-lag'
+
+ o `erc-prevent-duplicates' is now `erc-server-prevent-duplicates'
+
+ o `erc-previous-read' is now `erc-server-filter-data'
+
+ o `erc-process' is now `erc-server-process'
+
+ o `erc-ping-handler' is now `erc-server-send-ping-handler'
+
+ o `erc-ping-interval' is now `erc-server-send-ping-interval'
+
+*** Renamed some functions
+
+ o `erc-connect' is now `erc-server-connect'
+
+ o `erc-process-filter' is now `erc-server-filter-function'
+
+ o `erc-send-command' is now `erc-server-send'
+
+ o `erc-send-single-line' is now `erc-send-input'
+
+ o `erc-setup-periodical-server-ping' is now
+ `erc-server-setup-periodical-server-ping'
+
+ o `erc-split-command is now `erc-split-line'
+
+*** New options
+
+ o erc-server-flood-margin, erc-server-flood-penalty: New options
+ that allow tweaking of flood control.
+
+ o erc-split-line-length: The maximum line length of a single
+ message.
+
+*** New variables
+
+ o erc-server-flood-last-message, erc-server-flood-queue,
+ erc-server-flood-timer: Flood control.
+
+ o erc-server-processing-p: Indicate when we're currently processing
+ a message.
+
+*** Remove some options
+
+ o `erc-flood-limit'
+ o `erc-flood-limit2'
+
+** New customization group `erc-server' for dealing with IRC servers.
+
+** ERC can now be installed by doing `make install' from the command line.
+
+** ERC now has a manual in erc.texi.
+Type `make doc' to generate HTML and Info versions of it.
+
+** ERC no longer depends on cl.el.
+Only the macros in cl-macs.el are used.
+
+** Fix an edge case when quitting as new messages come in.
+
+** Make flood protection toggle-able as on/off, removing the 'strict option.
+
+** If possible, re-use channel buffers when reconnecting to a server.
+
+** Text in ERC buffers is now read-only by default.
+To get the previous behavior,
+
+** Changes and additions to modules
+
+*** Auto-join (erc-autojoin.el)
+
+**** Recognize the Azzurra server.
+
+*** BBDB (erc-bbdb.el)
+
+**** When the user types /WHOIS, ask for a record to merge to.
+
+**** Store the displayed name of a BitlBee contact.
+The new `erc-bbdb-bitlbee-name-field' option specifies the field to use
+to store this information.
+
+**** Don't prompt for a name on /JOIN or /NICK.
+
+*** Button (erc-button.el)
+
+**** Fix customization of `erc-button-alist'
+
+**** New option `erc-button-nickname-face' determines the face to use
+when coloring ERC nicknames.
+
+*** Channel tracking (erc-track.el)
+
+**** Remove channels from the modified channels list if not currently
+connected. This should remove residue from the mode line after
+quitting ERC.
+
+**** Recognize buttonized text
+
+*** Highlighting (erc-match.el)
+
+**** Highlight current nickname by default.
+
+**** Added the option of beeping when certain matches occur.
+Add `erc-beep-on-match' to `erc-text-matched-hook' to enable
+beeping. Set the new variable `erc-beep-match-types' which match
+types that make beeps.
+
+*** Nicklist (erc-nicklist.el)
+
+**** Fix a couple of errors.
+
+**** Make sure a stray mouse click doesn't trigger an error.
+
+**** Insert icons from the /images directory next to nicks.
+This indicates their away status. The location is customizable via
+the new `erc-nicklist-icons-directory' option.
+
+If you do not want these icons, set `erc-nicklist-use-icons' to nil.
+
+*** Nickserv identification (erc-nickserv.el)
+
+**** Recognize Azzurra and OFTC networks.
+
+*** Old completion (erc-complete.el)
+
+**** Disable by default.
+
+*** Programmable completion (erc-pcomplete.el)
+
+**** Enable by default.
+
+*** Timestamps (erc-stamp.el)
+
+**** On Emacs22, align right timestamps perfectly, even if variable-width
+characters are used. If we aren't using Emacs22, move text farther
+away from the right margin when variable-width characters are used.
+It is considered better to misalign the stamp by a bit than to go past
+the right margin.
+
+**** Enable by default
+
+** New modules
+
+*** Spell-checking (erc-spelling.el)
+
+**** Use flyspell in ERC.
+
+*** Viper compatibility (erc-viper.el)
+
+**** Helps ERC work correctly in viper-mode.
+
+* Fixes since ERC 5.0.3
+
+** Fix a problem with undo in channels.
+
+* Fixes since ERC 5.0.2
+
+** Fix typo in the `ctcp-request-to' entry of the English catalog.
+
+** Debugging with edegug has been made easier in all of the
+erc-with-* and with-erc* macros.
+
+** Non-ASCII character sets should be better supported when sending
+and processing messages.
+
+** A load failure with erc-autoaway.el and Emacs21 has been fixed.
+
+** A few XEmacs warnings were fixed.
+
+** Changes and additions to modules
+
+*** Backend (erc-backend.el)
+
+**** Move the check for hidden messages into `erc-display-message'
+so there isn't so much replicated code.
+
+**** Add `definition-name' property to constructed symbols so that
+`find-function' and `find-variable' will be able to locate them.
+
+**** Make sure logs are inserted info the correct channel buffers.
+There was previously an error when using `erc-insert-log-on-open' in
+combination with autojoin to multiple channels.
+
+*** Button (erc-button.el)
+
+**** The layering of `erc-button-face' on other faces in ERC buffers
+has been improved.
+
+*** Channel tracking (erc-track.el)
+
+**** Use optimal amount of whitespace around modified channels
+indicator. Previously, there was an additional unnecessary space.
+
+**** Fix an error that occurred when unchecked buffers existed when
+invoking /QUIT.
+
+* Fixes since ERC 5.0.1
+
+** If a channel key is required for a certain channel, ERC will prompt
+for one if `erc-prompt-for-channel-key' is non-nil.
+
+** ERC doesn't try to reconnect if the network connection is refused
+when using `open-network-stream-nowait' as the `erc-connect-function'.
+
+** Messages from multiple servers will not go to the currently active
+buffer. The messages from each server will be contained in the most
+recently active channel/server buffer that corresponds with the
+server.
+
+** Some text messages were cleaned up slightly.
+
+** Button faces should no longer "cover" other faces.
+
+** Made some XEmacs compatibility fixes.
+
+** Nicknames containing a backslash are now correctly highlighted as
+current-nick and buttonized as nicks.
+
+** `erc-server-select' doesn't offer networks without servers as a
+choice anymore.
+
+** Non-ASCII character support has been improved.
+
+** Changes and additions to modules
+
+*** Menu (erc-menu.el)
+
+**** You can now save logs and truncate buffers from the menu-bar.
+
+* Fixes since ERC 5.0
+
+** Narrowing in ERC buffers no longer causes formatting errors.
+
+** The BBDB module now loads correctly when customizing `erc-modules'.
+
+** The value of `erc-button-face' is now respected.
+
+** Fixed a bug which caused a read-only error during connection.
+
+** Server buffers are now tracked correctly.
+This means that `erc-track-priority-faces-only', `erc-track-exclude',
+and `erc-track-exclude-types' now work with server buffers.
+
+* Changes since ERC 4.0
+
+** Channel members are now stored as a hash-table.
+`erc-server-users' and `erc-channel-users' are now hash-tables, rather
+than alists. This significantly increases performance, especially in
+large channels. Each channel member is stored as an `erc-server-user'
+struct, with additional information about the channels they are on
+stored in an `erc-channel-user' struct. Code using old alist-style
+channel members needs to be updated to work with hash-tables.
+This new code also removes the need for erc-members.el, which has been
+removed.
+
+** The way ERC deals with input from the server has changed.
+All server response code is now in a new file, erc-backend.el. There
+should be no real user visible changes. There are, however, a few
+major changes for implementers, and module writers:
+
+*** The PARSED response that all handlers get called with is
+ no longer a vector, but an `erc-response' struct.
+
+ This means LESS MAGIC NUMBERS in the ERC source code, but a few
+ changes in how you get at parsed responses.
+
+ The sender is accessed via `erc-response.sender'.
+
+ The command is accessed via `erc-response.command'.
+
+ The arguments to the command (everything after the command and
+ before the colon) are accessed via `erc-response.command-args'.
+ This is a /list/ of arguments in the order they appear in the
+ unparsed response.
+
+ The contents of the response is accessed via
+ `erc-response.contents'.
+
+ Should, for some reason, you want to do something with the
+ /unparsed/ response, you can get it via `erc-response.unparsed'.
+
+*** The `erc-server-hook-list' mechanism is gone.
+
+ All server response handlers should be defined with
+ `define-erc-response-handler'. This defines functions and
+ corresponding hook variables.
+
+ The mapping of server commands to hook variables is no longer
+ done via `erc-event-to-hook', but through an #'equal hashtable,
+ `erc-server-responses'. In order to find a hook you do:
+
+ (erc-get-hook command)
+
+ See the docstring of `define-erc-response-handler' for more
+ information.
+
+*** ALL hook variables have been renamed.
+
+ In accordance with recommendations in the Emacs Lisp manual,
+ the hook variables are no longer called `erc-server-FOO-hook',
+ but rather `erc-server-FOO-functions'. This is to indicate
+ that the functions they call take arguments.
+
+ All the modules in ERC have been updated to reflect this change,
+ but external module authors should beware.
+
+** The values of `erc-mode-line-format' and `erc-header-line-format'
+are now defined as strings to be formatted using `format-spec'.
+`erc-mode-line-format' does not replace the whole mode-line anymore,
+only `mode-line-buffer-identification' is set. This way, personal
+mode-line configurations are not modified and all key bindings work as
+expected. The process status (connecting, closed) is now shown in
+`mode-line-process'.
+
+** Customization of ERC variables has been made easier. Variables
+have been split into more groups for better organization.
+
+** New variables
+
+ o `erc-send-whitespace-lines' - Set this to send lines even if they
+ are empty.
+
+ o `erc-manual-set-nick-on-bad-nick-p' - If the nickname you chose is
+ already taken or not allowed, your nick is not changed and you can
+ try again manually if this is non-nil.
+
+ o `erc-mode-line-away-status-format' - You can now set what is shown
+ in the mode-line when you are away.
+
+ o `erc-header-line-uses-help-echo-p' - The header-line now uses the
+ help-echo property. You can set this to nil to disable it.
+
+ o `erc-format-query-as-channel-p' - Set this to nil to have messages
+ in the query buffer formatted like private messages.
+
+ o `erc-show-channel-key-p' - The channel key is now shown with the
+ other channel modes in the header line. Set this to nil if you
+ want it hidden.
+
+ o `erc-prompt-for-channel-key' - Set this if you want to be prompted
+ for the channel key (channel's mode is +k) when you call
+ `erc-join-channel' interactively.
+
+ o `erc-kill-server-buffer-on-quit' - If non-nil, kill the server
+ buffer automatically when you quit.
+
+** New hooks
+
+ o `erc-join-hook' - Called when you join a channel.
+
+ o `erc-kick-hook' - Called when you are kicked from a channel. The
+ channel's buffer is sent as an argument to functions called from
+ this hook.
+
+ o `erc-nick-changed-functions' - Whenever your nickname changes
+ successfully, the functions in this hook are run with the
+ arguments NEW-NICK and OLD-NICK.
+
+** New command /WHOAMI - Do a /WHOIS on your current nickname.
+
+** The key binding for changing channel modes is now C-c C-o.
+
+** Removed variables
+
+ o `erc-echo-notices-in-minibuffer-flag' and
+ `erc-echo-notices-in-current-buffer' - You should use
+ `erc-echo-notice-hook' and `erc-echo-notice-always-hook' instead.
+
+ o `erc-prompt-interactive-input' has been removed (commented out)
+ because nickname completion does not work with it.
+
+ o All INFO buffer-related variables and functions have been removed.
+
+** You can now disable modules by setting `erc-modules' with the
+customization interface.
+
+** Changes and additions to modules
+
+*** Autoaway (erc-autoaway.el)
+
+**** New variable `erc-autoaway-no-auto-back-regexp' - Add text which,
+when you type anything matching it, will not automatically discard
+your away status when `erc-auto-discard-away' is non-nil.
+
+*** Filling (erc-fill.el)
+
+**** New variable `erc-fill-variable-maximum-indentation' - Don't
+indent more than this many characters when indenting a message from a
+user with a long nickname.
+
+*** Goodies (erc-goodies.el)
+
+**** Miscellaneous small modules have been moved from erc.el.
+The functions erc-add-scroll-to-bottom, erc-make-read-only,
+erc-send-distinguish-noncommands, erc-interpret-controls, erc-unmorse,
+erc-smiley, and erc-occur, which were defined in the main erc.el file
+have been moved to erc-goodies.el and have mostly been translated to
+the modules scrolltobottom, readonly, noncommands, irccontrols, smiley
+and unmorse.
+
+**** New variables
+
+ o `erc-input-line-position' - The line number to use with
+ `erc-scroll-to-bottom'.
+
+ o `erc-beep-p' - Beep if there is a \C-g control character in a
+ message.
+
+*** Channel lists (erc-list.el)
+
+**** New variable `erc-chanlist-highlight-face' - A face used for
+highlighting the current line.
+
+*** Highlighting (erc-match.el)
+
+**** `erc-current-nick-highlight-type' has new options: 'keyword and
+'nick-or-keyword.
+
+*** Menu (erc-menu.el)
+
+**** The `IRC' menu is now automatically added to `erc-mode' buffers.
+
+*** Networks (erc-nets.el)
+
+**** The functions for determining current network are in this file.
+There were a couple of functions spread about in different files which
+each had a different way of determining the current network. The
+methods have been combined, and the big list of known networks
+(`erc-networks-alist') is being put to use. You can access the
+network's name by calling the new function `erc-network'. This
+returns the name of the current network as a symbol or 'Unknown if it
+could not determine which network it is.
+
+*** Nicklist (erc-nicklist.el)
+
+**** ERC has a new way of displaying nicknames in a channel.
+The new file erc-nicklist.el defines a new command `erc-nicklist'
+which pops up a small Emacs window showing the nicknames of all
+members of the current channel. The implementation is not complete
+and is rather proof-of-concept for now. The result is something a bit
+like erc-speedbar, but not quite as invasive, and doesn't require use
+of a new frame.
+
+*** Internet services / Nickserv (erc-nickserv.el)
+
+**** Network detection is now taken care of by erc-nets.el.
+The function `erc-current-network' is deprecated, use `erc-network'
+instead. The variable `erc-networks' has been removed, use
+`erc-networks-alist'. The network symbols used in
+`erc-nickserv-alist' now match those in `erc-networks-alist'.
+
+**** New variable `erc-nickserv-identify-mode' - Choose which method
+to use for automatic identification: you can wait for Nickserv to ask
+you to identify (the default), or send an identify message
+automatically after you change your nickname.
+
+*** Speedbar (erc-speedbar.el)
+
+**** New variable `erc-speedbar-sort-users-type' - Sort users in a
+channel by activity, alphabetically, or not at all.
+
+*** Timestamps (erc-stamp.el)
+
+**** `erc-timestamp-only-if-changed-flag' now works when
+`erc-insert-timestamp-function' is set to 'erc-insert-timestamp-left.
+
+**** New variable `erc-timestamp-intangible' - Set this to nil if
+timestamps should not have the 'intangible property.
+
+*** Channel tracking (erc-track.el)
+
+**** Using faces to indicate channel activity in the modeline now works
+in XEmacs.
+
+**** New variables
+
+ o `erc-track-priority-faces-only' - Ignore changes in a channel
+ unless there is a face from the `erc-track-faces-priority-list' in
+ the message.
+
+ o `erc-track-exclude-server-buffer' - Ignore changes in the server
+ buffer.
+
+ o `erc-track-position-in-mode-line' - Set the position in the
+ mode-line where modified channels are shown (only works in GNU
+ Emacs versions above 21.3).
+
+* Changes since ERC 3.0.cvs.20030119
+
+** The module system has again changed a lot. You can now customize
+ the variable `erc-modules' and define once and for all which
+ extension modules you want to use. This unfortunately may require
+ you to change your current erc initialisation code a bit, if you
+ have some existing customsations. On the other hand, this change
+ makes the configuration of extension modules a lot easier for new
+ users. In theory, you should be able to configure all aspects of
+ ERC by using the customize interface, you should no longer really
+ need to write Lisp code for trivial customizations.
+
+ By default, the following modules are now loaded: (pcomplete
+ netsplit fill track ring button autojoin)
+
+ Please use M-x customize-variable RET erc-modules RET to change the
+ default if it does not suite your needs.
+
+** THe symbol used in `erc-nickserv-passwords' for debian.org IRC servers
+ (formerly called OpenProjects, now FreeNode) has changed from
+ openprojects to freenode. You may need to update your configuration
+ for a successful automatic nickserv identification.
+
+* Changes since ERC 2.93.cvs.20020819
+
+** New module erc-dcc:
+
+This finally implements DCC. It requires server sockets to fully work
+in both directions. This feature is currently only available in Emacs
+21.3.50 (CVS). Here is a short list of what should work though.
+
+** Compatibility:
+ * Emacs 21.2, DCC get, and accepting DCC chat offers.
+ * XEmacs 21, Only accepting DCC chat offers.
+
+** erc is switching to global-minor-modes for activation of submodules.
+
+This allows you to customize such a mode and get automatic loading of
+the module. No longer putting a lot of require statments in .emacs.
+At least this is the long-term plan, not all modules are converted
+yet.
+
+** The most important user visible change is that you now need to activate
+erc-completion-mode, to get TAB completion. The new completion code
+is based on pcomplete. To get the old code, manually load
+erc-complete and bind TAB to erc-complete in erc-mode-map.
+
+To activate completion on startup, put (erc-completion-mode 1) in your
+.emacs file.
+
+Same applies to timestamps. You no longer need to (require
+'erc-stamp), you can customize the variable `erc-timestamp-mode', and
+the rest should be automatic.
+
+arch-tag: 2b21b387-6cdc-4192-889c-6743cfffdcb1
diff --git a/etc/NEWS b/etc/NEWS
index 4e5e0be403b..983dd5287e3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1504,6 +1504,17 @@ colors as on X.
* New Modes and Packages in Emacs 22.1
+** ERC is now part of the Emacs distribution.
+
+ERC is a powerful, modular, and extensible IRC client for Emacs.
+
+To see what modules are available, type
+M-x customize-option erc-modules RET.
+
+To start an IRC session, type M-x erc-select, and follow the prompts
+for server, port, and nick.
+
+---
** Rcirc is now part of the Emacs distribution.
Rcirc is an Internet relay chat (IRC) client. It supports
diff --git a/info/dir b/info/dir
index 10309c8a884..035ed6e7319 100644
--- a/info/dir
+++ b/info/dir
@@ -41,6 +41,8 @@ Emacs
* CC mode: (ccmode). Emacs mode for editing C, C++, Objective-C,
Java, Pike, and IDL code.
* Ebrowse: (ebrowse). A C++ class browser for Emacs.
+* ERC: (erc). Powerful, modular, and extensible IRC client
+ for Emacs.
* Flymake: (flymake). An on-the-fly syntax checker for Emacs.
* IDLWAVE: (idlwave). Major mode and shell for IDL and WAVE/CL files.
diff --git a/lisp/erc/ChangeLog b/lisp/erc/ChangeLog
new file mode 100644
index 00000000000..b50ac5a0df2
--- /dev/null
+++ b/lisp/erc/ChangeLog
@@ -0,0 +1,327 @@
+2006-01-28 Michael Olson <mwolson@gnu.org>
+
+ * erc-*.el, erc.texi, NEWS: Add Arch taglines as per Emacs
+ guidelines.
+
+ * erc-*.el: Space out copyright years like the rest of Emacs. Use
+ the Emacs copyright statement. Refer to ourselves as ERC rather
+ than "Emacs IRC Client", since there are now several IRC clients
+ for Emacs.
+
+ * erc-compat.el (erc-emacs-build-time): Define as a variable.
+
+ * erc-log.el (erc-log-setup-logging): Use write-file-functions.
+
+ * erc-ibuffer.el: Require 'erc.
+
+ * erc-stamp.el (erc-insert-aligned): Only use the special text
+ property when window-system is X.
+
+ * erc.texi: Adapt for inclusion in Emacs.
+
+2006-01-28 Johan Bockgård <bojohan@users.sourceforge.net>
+
+ * erc.el (erc-format-message): More `cl' breakage; don't use
+ `oddp'.
+
+2006-01-27 Michael Olson <mwolson@gnu.org>
+
+ * debian/changelog: Update for new release.
+
+ * debian/control (Description): Update.
+
+ * debian/rules: Concatenate ChangeLog for 2005.
+
+ * Makefile (MISC): Include ChangeLog.2005 and erc.texi.
+ (debrelease, release): Copy images directory.
+
+ * NEWS: Spelling fixes. Add items for recent changes.
+
+ * erc.el (erc): Move call to erc-update-modules before the call to
+ erc-mode. This should fix a timestamp display issue.
+ (erc-version-string): Release ERC 5.1.
+
+2006-01-26 Michael Olson <mwolson@gnu.org>
+
+ * erc-stamp.el (erc-insert-aligned): New function that inserts
+ text in an perfectly-aligned way relative to the right margin. It
+ only works well with Emacs22. A sane fallback is provided for
+ other versions of Emacs.
+ (erc-insert-timestamp-right): Use the new function.
+
+2006-01-25 Edward O'Connor <ted@oconnor.cx>
+
+ * erc.el (erc-modules): Ensure that `erc-button-mode' gets enabled
+ before `erc-match-mode'.
+
+ * erc-match.el (match): Append `erc-match-message' to
+ `erc-insert-modify-hook'.
+
+2006-01-25 Michael Olson <mwolson@gnu.org>
+
+ * FOR-RELEASE: Mark last release requirement as done.
+
+ * Makefile (realclean, distclean): Remove docs.
+
+ * erc.texi: Take care of all pre-5.1 items.
+
+ * erc-backend.el (erc-server-send, erc-server-send-queue): Wrap
+ `process-send-string' in `condition-case' to avoid an error when
+ quitting ERC.
+
+ * erc-stamp.el (erc-insert-timestamp-right): Try to deal with
+ variable-width characters in the timestamp and on the same line.
+ The latter is a kludge, but it seems to work with most of the
+ input I've thrown at it so far. It's certainly better than going
+ past the end of line consistently when we have variable-width
+ characters on the same line. When `erc-timestamp-intangible' is
+ non-nil, add intangible properties to the whitespace as well, so
+ that hitting <end> does what you'd expect.
+
+ * erc.el (erc-flood-protect, erc-toggle-flood-control): Update
+ this to only use boolean values for `erc-flood-protect'. Update
+ documentation.
+ (erc-cmd-QUIT): Set the active buffer to be the server buffer, so
+ that any QUIT-related messages go there.
+ (erc): Try to be more clever about re-using channel buffers when
+ automatically re-connecting. Thanks to e1f for noticing.
+
+2006-01-23 Michael Olson <mwolson@gnu.org>
+
+ * ChangeLog.2005: Remove erroneous line.
+
+ * FOR-RELEASE: Make that the Makefile tweaking is complete.
+ (NEWS): Mark as done.
+
+ * Makefile (MANUAL): New option indicating the name of the manual.
+ (PREFIX, ELISPDIR, INFODIR): New options that specify the
+ directories to install lisp code and info manuals to. PREFIX is
+ used only by ELISPDIR and INFODIR.
+ (all): Call `lisp' and create the manual.
+ (lisp): Compile lisp code.
+ (%.info, %.html): New rules that make Info files and HTML files,
+ respectively, from a TexInfo source.
+ (doc): Create both the Info and HTML versions of the manual. This
+ is for the user -- we never call it automatically.
+ (install-info): Install Info files.
+ (install-bin): Install compiled and source Lisp files.
+ (todo): Remove, since it seems pointless.
+
+ * NEWS: Update.
+
+ * README: Add Installation instructions. Tweak layout.
+
+ * erc.texi: Work on some pre-5.1 items.
+
+ * erc-stamp.el, erc-track.el: Move some functions and options in
+ order to get rid of a few compiler warnings.
+
+ * erc.el (erc-modules): Enable readonly by default. This will
+ prevent new users from accidentally removing old messages, which
+ could be disconcerting. Also enable stamp by default, since
+ timestamps are a fairly standard feature among IRC clients.
+
+ * erc-button.el: Munge whitespace.
+
+ * erc-identd.el (erc-identd-start): Instead of throwing an error,
+ just try to use the obsolete function.
+
+2006-01-22 Michael Olson <mwolson@gnu.org>
+
+ * erc-backend.el (erc-decode-string-from-target): Make sure that
+ we have a string as an argument. If not, coerce it to the empty
+ string. Hopefully, this will work painlessly around an edge case
+ related to quitting ERC around the same time a message comes in.
+
+2006-01-22 Johan Bockgård <bojohan@users.sourceforge.net>
+
+ * erc-track.el: Use `(eval-when-compile (require 'cl))' (for
+ `case'). Doc fixes.
+ (erc-find-parsed-property): Simplify.
+ (erc-track-get-active-buffer): Fix logic. Simplify.
+ (erc-track-switch-buffer): Remove unused variable `dir'. Simplify.
+
+ * erc-speak.el: Doc fixes.
+ (erc-speak-region): `propertize' --> `erc-propertize'.
+
+ * erc-dcc.el (erc-dcc-chat-parse-output): `propertize' -->
+ `erc-propertize'.
+
+ * erc-button.el (erc-button-add-button): Take erc-fill-prefix into
+ account when wrapping URLs.
+
+ * erc-bbdb.el (erc-bbdb-elide-display): Doc fix.
+
+ * erc-backend.el (define-erc-response-handler): Doc fix.
+
+2006-01-22 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-update-modules): Use `require' instead of `load',
+ but prevent it from causing errors, in order to preserve the
+ previous behavior.
+
+2006-01-21 Michael Olson <mwolson@gnu.org>
+
+ * FOR-RELEASE (Source): Mark cl task as done.
+
+ * Makefile (erc-auto.el): Call erc-generate-autoloads rather than
+ generate-autoloads.
+ (erc-auto.el, %.elc): Don't show command, just its output.
+
+ * NEWS: Add items from 2005-01-01 to 2005-08-13.
+
+ * debian/copyright (Copyright): Update.
+
+ * erc-auto.in (erc-generate-autoloads): Rename from
+ generate-autoloads.
+
+ * erc.el, erc-autoaway.el, erc-backend.el: Use
+ erc-server-process-alive instead of erc-process-alive.
+
+ * erc.el, erc-backend.el, erc-ezbounce.el, erc-list.el,
+ erc-log.el, erc-match.el, erc-nets.el, erc-netsplit.el,
+ erc-nicklist.el, erc-nickserv.el, erc-notify.el, erc-pcomplete.el:
+ Use (eval-when-compile 'cl), so that compilation doesn't fail.
+
+ * erc-fill.el, erc-truncate.el: Whitespace munging.
+
+ * erc.el: Update copyright notice. Remove eval-after-load code.
+ (erc-with-buffer): Docfix.
+ (erc-once-with-server-event, erc-once-with-server-event-global)
+ (erc-with-buffer, erc-with-all-buffers-of-server): Use erc-gensym
+ instead of gensym.
+ (erc-banlist-update): Use erc-delete-if instead of delete-if.
+ (erc): Call `erc-update-modules' here.
+
+ * erc-backend.el: Require 'erc-compat to minimize compiler
+ warnings.
+ (erc-decode-parsed-server-response): Docfix.
+ (erc-server-process-alive): Move here from erc.el and rename from
+ `erc-process-alive'.
+ (erc-server-send, erc-remove-channel-users): Make sure process is
+ alive before sending data to it.
+
+ * erc-bbdb.el: Update copyright years.
+ (erc-bbdb-whois): Remove overexuberant comment.
+
+ * erc-button.el: Require erc-fill, since we make liberal use of
+ `erc-fill-column'.
+
+ * erc-compat.el (erc-const-expr-p, erc-list*, erc-assert): New
+ functions, the latter of which provides an `assert' equivalent.
+ (erc-remove-if-not): New function that provides a simple
+ implementation of `remove-if-not'.
+ (erc-gensym): New function that provides a simple implementation
+ of `gensym'.
+ (erc-delete-if): New function that provides a simple
+ implementation of `delete-if'.
+ (erc-member-if): New function that provides a simple
+ implementation of `member-if'.
+ (field-end): Remove this, since it is unused, and later versions
+ of XEmacs have this function already.
+ (erc-function-arglist): Moved here from erc.el.
+ (erc-delete-dups): New compatibility function for dealing with
+ XEmacs.
+ (erc-subseq): New function copied from cl-extra.el.
+
+ * erc-dcc.el: Require pcomplete during compilation to avoid
+ compiler warnings.
+ (erc-unpack-int, erc-dcc-send-filter)
+ (erc-dcc-get-filter): Use erc-assert instead of assert.
+ (pcomplete/erc-mode/DCC): Use erc-remove-if-not instead of
+ remove-if-not.
+
+ * erc-match.el (erc-log-matches): Fix compiler warning.
+
+ * erc-nicklist.el: Update copyright notice.
+ (erc-nicklist-menu): Change use of caadr to (car (cadr ...)).
+ (erc-nicklist-bitlbee-connected-p): Remove.
+ (erc-nicklist-insert-medium-name-or-icon): Accept channel
+ argument. Use it to determine whether we are on bitlbee. Now
+ that bitlbee names its channel "&bitlbee", this is trivial.
+ (erc-nicklist-insert-contents): Pass channel as specified above.
+ Don't try to determine whether we are on bitlbee here.
+ (erc-nicklist-channel-users-info): Use erc-remove-if-not instead
+ of remove-if-not.
+ (erc-nicklist-search-for-nick): Use erc-member-if instead of
+ member-if.
+
+ * erc-notify.el (erc-notify-QUIT): Use erc-delete-if with a
+ partially-evaluated lambda expression instead of `delete' and
+ `find'.
+
+ * erc-track.el: Use erc-assert.
+ (erc-track-modified-channels): Remove use of `return'.
+ (erc-track-modified-channels): Use `cadr' instead of `second',
+ since otherwise we would need yet another eval-when-compile line.
+
+2006-01-19 Michael Olson <mwolson@gnu.org>
+
+ * erc-backend.el (erc-process-sentinel-1): Remove attempt to
+ detect SIGPIPE, since it doesn't work.
+
+2006-01-10 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-spelling.el: Updated copyright years.
+ (define-erc-module): Enable/disable `flyspell-mode' for all open
+ ERC buffers as well.
+ (erc-spelling-dictionaries): Reworded customize description.
+
+ * erc.el (erc-command-symbol): New function.
+ (erc-extract-command-from-line): Use `erc-command-symbol'. This
+ fixes a bug where "Symbol's function definition is void:
+ erc-cmd-LIST" would be shown after typing /list at the prompt (the
+ command was interned because erc-menu.el uses it and is enabled by
+ default whereas erc-list.el is not).
+
+ * NEWS: Started a list of renamed variables.
+
+ * erc.el: Reworded the message sent when defining variable
+ aliases.
+ (erc-command-indicator-face): Doc fix.
+ (erc-modules): Enable the match module by default which makes
+ current nickname highlighting on as the default.
+
+ * erc-button.el: Updated copyright years.
+ (erc-button): New face.
+ (erc-button-face): Use `erc-button'.
+ (erc-button-nickname-face): New customizable variable.
+ (erc-button-add-nickname-buttons, erc-button-add-buttons-1): Send
+ new argument to `erc-button-add-button'.
+ (erc-button-add-button): Doc fix. Added new argument to function
+ definition, NICK-P. If it's a nickname, use
+ `erc-button-nickname-face', otherwise use `erc-button-face'. This
+ makes channel tracking and buttons work better together when
+ `erc-button-buttonize-nicks' is enabled, since there is a nickname
+ on just about every line.
+
+ * erc-track.el (erc-track-use-faces): Doc fix.
+ (erc-track-faces-priority-list): Added `erc-button' to list.
+ (erc-track-priority-faces-only): Doc fix.
+
+2006-01-09 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-button.el (erc-button-url-regexp): Use `concat' so the
+ regexp is not one long line.
+ (erc-button-alist): Fixed so that customizing works correctly.
+ Reorganized. Removed lambda functions with more than two lines.
+ Doc fix.
+ (erc-button-describe-symbol, erc-button-beats-to-time): New
+ functions. Moved from `erc-button-alist'.
+
+2006-01-07 Michael Olson <mwolson@gnu.org>
+
+ * erc-backend.el (erc-process-sentinel-1): Don't try to re-open a
+ process if a SIGPIPE occurs. This happens when a new message
+ comes in at the same time a /quit is requested.
+ (erc-process-sentinel): Use string-match rather than string= to do
+ these comparisons. Matching literal newlines makes me nervous.
+
+ * erc-track.el (erc-track-remove-from-mode-line): Handle case
+ where global-mode-string is not a list. Emacs22 permits this.
+
+ Copyright (C) 2006 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted provided the copyright notice and this notice are preserved.
+
+;; arch-tag: 865a75f6-2bcb-46df-bf0c-b514dadf688a
diff --git a/lisp/erc/ChangeLog.2001 b/lisp/erc/ChangeLog.2001
new file mode 100644
index 00000000000..fdf085d2d22
--- /dev/null
+++ b/lisp/erc/ChangeLog.2001
@@ -0,0 +1,1042 @@
+2001-12-18 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.176: * Added missing 747 numreply (banned)
+
+2001-12-15 Gergely Nagy <algernon@debian.org>
+
+ * debian/scripts/install 1.4, debian/rules 1.6:
+ updated to 2.1.cvs.20011215-1
+
+ * debian/changelog 1.12: Debian version 2.1.cvs.20011215-1
+
+2001-12-11 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.175:
+ * applied a nicer version of mhp's patch to remove the last prompt from
+ saved logs
+
+ * erc-replace.el 1.1: * Initial checkin
+
+2001-12-11 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.174:
+ * fixed bug triggered when reuse-buffer was enabled (the default).
+ Another silly port type problem. Maybe we should unify that once and for all sometimes...
+
+2001-12-10 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.173: * erc-message-english: New QUIT and s004 entries.
+ * erc-save-buffer-on-part: New variable.
+ * erc-kill-buffer-on-part: New variable.
+ * (erc-server-PART): Use above variables.
+ * (erc-join-channel): Use DEF argument instead of initial input for completing-read.
+
+2001-12-08 Tijs van Bakel <smoke@wanadoo.nl>
+
+ * erc.el 1.172: added defcustom erc-nick-uniquifier ^ (i prefer _)
+
+2001-12-07 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.11: changelog for version 2.1.cvs.20011208-1
+
+2001-12-07 Tijs van Bakel <smoke@wanadoo.nl>
+
+ * erc.el 1.171:
+ Added erc-scroll-to-bottom as an erc-insert-hook function. It still bugs a bit, so please test it, thanks
+
+2001-12-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.170: * Fixed silly bug in erc-server-TOPIC (thanks mhp)
+
+ * erc-speak.el 1.17:
+ * Fix non-greedy matching bug. That one somehow swallowed text
+
+ * erc.el 1.169:
+ Fix Emacs20 problem. For now, we disable erc-track-modified-channels-minor-mode in emacs20
+
+2001-12-07 Andreas Fuchs <asf@void.at>
+
+ * erc-fill.el 1.5:
+ * Fix another stupid one-off error. This time it really works!
+ (Until I find the next bug. I guess you can hold your breath) (-:
+
+2001-12-06 Andreas Fuchs <asf@void.at>
+
+ * erc-fill.el 1.4: * Fixed static filling:
+ ** No more \ed (continued on next line) lines anymore
+ ** Fixed bug with previous version where longer lines wouldn't get
+ filled correctly (i.e. at all)
+
+2001-12-06 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.10: changelog for 2.1.cvs.20011206-1 added
+
+2001-12-06 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.168:
+ * Don't discard away status when identifying to NickServ
+ * Modify `erc-already-logged-in': check for port, too.
+
+ * erc-fill.el 1.3:
+ * Fix stupid loop non-termination error in erc-fill-static when filling
+ one-line regions.
+ * Make erc-count-lines return meaningful values
+
+2001-12-05 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.167:
+ * (erc-process-input): Make ' /command' work for quoting /commands
+
+ * erc-speak.el 1.16: see changelog
+
+ * erc-fill.el 1.2: see erc.el changelog
+
+ * erc.el 1.166:
+ * erc-insert-hook: Changed strategy completely, no start end parameters any more.
+ We narrow-to-region now, thats much cleaner.
+ * rename erc-fill-region to erc-fill and change the autoload
+ ** You'll probably need to restart Emacs
+
+2001-12-04 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.165:
+ * (erc-send-current-line): Fixed long outstanding bug. XEmacs users with erc-fill-region on erc-insert-hook knew that one a long time.
+
+ * erc.el 1.164: fix order of attack
+
+ * erc.el 1.163: * macroexpanded define-minor-mode for XEmacs
+
+ * erc.el 1.162: First try to make channel tracking mouse sensitive
+
+ * erc.el 1.161: * More erc-message-format conversion.
+ erc-format-message-english-PART as an example on how to use functions to format message
+ * (erc-format-message): Fallback mechanism to use english catalog if variable is not bound
+
+2001-12-03 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.160: * (erc-iswitchb): Rewrite, docfix.
+ Make it use erc-modified-channels as default if available.
+
+ * erc-menu.el 1.2:
+ * Fixage related to erc-track-modified-channels-minor-mode rewrite
+
+ * erc.el 1.159:
+ * erc-track-modified-channels-minor-mode: Use buffer objects instead of erc-default-target return value for internal state keeping.
+
+ * erc.el 1.158: * Made reconnect behave nicer (erc-process-sentinel)
+ * Rewrote erc-modified-channels-tracking completely.
+ Its now a minor mode (erc-track-modified-channels-minor-mode)
+ It uses a list as internal representation now, so all silly string-parsing
+ related bugs should be gone.
+ Use (erc-track-modified-channels-minor-mode t) now to toggle this functionality.
+ Dont set the erc-track-modified-channels-minor-mode variable yourself, use the toggle function
+
+2001-11-29 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.9: final version
+
+2001-11-29 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.157:
+ * (erc-channel-p): Make it work with string and buffer as parameter. buffer.
+ * (erc-format-message): Add a check for functionp. This allows a format-specifier also to be a function name, which gets called with args applied and needs to return the actual format string.
+ * Converted some formats, JOIN, JOIN-you, MODE, ...
+
+2001-11-28 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.156:
+ * (erc-prepare-mode-line-format): Added sanity checks to prevent it from having problems with server buffers where the connection failed
+
+ * erc-bbdb.el 1.7:
+ * (erc-bbdb-JOIN): regexp-quote the fingerhost before searching, some people have really strange characters as their user names
+
+ * erc.el 1.155: Remove a stupid debug like (message ...) call
+
+2001-11-28 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.8: draft of 2.1.cvs.20011128-1
+
+ * debian/rules 1.5: simplify for the all-in-one erc package
+
+ * debian/control 1.3: integrated erc-speak back into erc
+
+ * debian/maint/conffiles 1.3, debian/maint/conffiles.in 1.2, debian/maint/postinst 1.3,
+ debian/maint/postinst.in 1.2, debian/maint/prerm 1.3, debian/maint/prerm.in 1.2,
+ debian/scripts/install 1.3, debian/scripts/install.in 1.3, debian/scripts/remove 1.3,
+ debian/scripts/remove.in 1.2, debian/scripts/startup.erc-speak 1.2:
+ since erc-speak is gone, resurrect the static files, and update them to support the latest erc
+
+2001-11-28 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.154: * (erc-mode): Shouldn't be interactive.
+ * (erc-info-mode): Ditto.
+
+ * erc.el 1.153: * (erc-server-352): Added hopcount parsing.
+ Added call to erc-update-channel-member to fill in channel-members information
+ on /WHO if the channel is joined.
+
+2001-11-27 Mario Lang <mlang@delysid.org>
+
+ * erc-speedbar.el 1.6: *** empty log message ***
+
+ * erc-speedbar.el 1.5: * (erc-speedbar-expand-user): New function.
+ Used when more information than just the nick name is available about a dude.
+
+ * erc.el 1.152: * Fixed stupid edit,checkin,save cycle error :)
+
+ * erc.el 1.151:
+ * (erc-generate-log-file-name-default): Renamed to -long
+ Doc fix.
+ * (erc-generate-log-file-name-old): Renamed to -long
+ Doc fix.
+ * erc-generate-log-file-name-function: Set default to ...-long
+ Doc fixes
+
+ * erc-speedbar.el 1.4: *** empty log message ***
+
+2001-11-26 Mario Lang <mlang@delysid.org>
+
+ * erc-speedbar.el 1.3: * Integrated channel names list
+ what else do we need to replace info buffers???
+ please test that code and comment on erc-ehlp, thanks
+
+ * erc-speedbar.el 1.2:
+ * Added erc-speedbar-goto-buffer and therefore enable switching to the buffers from speedbar
+
+ * erc-speedbar.el 1.1:
+ I had to check this in, it works !! sort of,, megaalphagammaversion, first version. test, play, submit ideas/patches
+
+2001-11-26 Gergely Nagy <algernon@debian.org>
+
+ * erc.el 1.150 (erc-mode): moved erc-last-saved-position here
+ moved buffer naming code from here..
+ (erc): ...to here
+ (erc-generate-log-file-name-old): only prepend target if it exists
+
+ made erc-log-insert-log-on-open a defcustom
+
+2001-11-26 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.149:
+ * Applied antifuchs/mhp patches, the latest on erc-help, unmodified
+ * New variable: erc-reuse-buffers default to t.
+ * Modified erc-generate-new-buffer-name to use it. it checks if server and port are the same,
+ then one can assume thats the same channel/query target again.
+
+2001-11-23 Mario Lang <mlang@delysid.org>
+
+ * erc-bbdb.el 1.6:
+ * new function erc-BBDB-NICK to handle nickname anotation on a nick-change event of a known record
+
+ * erc.el 1.148: * Remove erc-rename-buffer, its no longer necessary
+ * Remove erc-autoop-*. it was broken, and needed rewrite anyway
+ * write erc-already-logged-in in terms of erc-buffer-list and make the duplicate login check work again
+
+ * erc.el 1.147: * Fixed stupid typo
+
+2001-11-22 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.146: * New local variable, erc-announced-server-name
+ * erc-mode-line-format supports a new symbol, target-and/or-server
+ * The mode-line displays the announced server name now (for autojoin later...,
+ greets Adam)
+ * New macro, erc-server-hook-list for a nice way to define the defcustoms of the erc-server-*-hook's
+ Thanks go to the guy from #emacs who helped with that
+ * erc-fill-region is now autoloaded from erc-fill.el
+ * erc-fill.el implements a new fill method, erc-fill-static
+ (setq erc-fill-function 'erc-fill-static)
+ * Some other things I forgot right now
+
+ * erc-bbdb.el 1.5: *** empty log message ***
+
+ * erc-fill.el 1.1: Initial version.
+
+ * erc-complete.el 1.4:
+ Applied antifuchs patch to make completion work with (string= erc-prompt "")
+
+ * erc-complete.el 1.3:
+ added function erc-nick-completion-exclude-myself
+ you can set erc-nick-completion to 'erc-nick-completion-exclude-myself to use it
+
+2001-11-21 Mario Lang <mlang@delysid.org>
+
+ * erc-bbdb.el 1.4:
+ * Changed usage of 'finger-host to bbdb-finger-host-field
+
+ * erc-bbdb.el 1.3:
+ * Changed WHOIS to use finger-host instead of net field.
+ * Added 'visible as option to erc-bbdb-popup-p to only pop-up the bbdb buffer if a join happened in a visible buffer on any visible frame.
+ * Added (regexp-quote ...) for nickname search in erc-bbdb-JOIN
+
+2001-11-20 Mario Lang <mlang@delysid.org>
+
+ * erc-bbdb.el 1.2: * Added JOIN support
+
+2001-11-19 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.145:
+ Initial message catalog code. converted erc-action-format usage to use it
+
+ * erc.el 1.144: * erc-play-sound: Added XEmacs related check
+
+ * erc-bbdb.el 1.1: * Initial version, many thanks to Andreas Fuchs
+
+ * erc.el 1.143: * Fixed silly problem with whois/was handling
+
+ * erc.el 1.142: * Renamed prev-rd to erc-previous-read
+ * Removed erc-next-line-add-newlines and s next-line-add-newlines to nil in defun erc by default
+
+ * erc.el 1.141:
+ fixed xemacs compatibility prob with delete, thanks Adam
+
+2001-11-18 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.140: numreplies 301 & 461
+
+2001-11-13 Tijs van Bakel <smoke@wanadoo.nl>
+
+ * erc.el 1.139:
+ Added code for error reply 421 "Unknown command", to test the new server parsing system.
+ This was really easy! Thanks ZenIRC guys & delysid :-)
+
+2001-11-13 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.138: * Allow connecting to SSL enabled irc servers.
+ Ugly hack, but it works for now. Be sure to use the numeric irc port 994 so that erc can recognize what you want
+ good example is
+ irc server: ircs.segfault.net
+ port: 994
+
+ meet me there, I am still delYsid :)
+
+ * erc.el 1.137: * some more numreply handlers
+ * cleanup in erc-process-away-p
+ * new function erc-display-error-notice
+
+ * erc.el 1.136: * numreply 501 and 221
+
+ * erc.el 1.135:
+ removed obsolete old hook variables. Your functions may break, but it is easy to hook them up to the new hooks.
+ erc-part-hook: use erc-server-PART-hook instead
+ erc-kick-hook: use erc-server-KICK-hook instead
+ and so on
+
+ * erc.el 1.134:
+ fixed serious bug which cause privmsgs vanishing when erc-auto-query was set to nil
+
+ * erc.el 1.133: cleaned up erc-process-filter
+
+ * erc.el 1.132: * 401 and 320 numreplies implemented
+
+ * erc.el 1.131: * Removed old/now obsolete code
+
+ * erc.el 1.130: * Fixed bug in erc-server-MODE
+
+2001-11-12 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.129: fixed it
+
+ * erc.el 1.128:
+ *** We switched over. New server message parsing/handling is running now. Thansk to the zenirc developers for the great ideas I got from the code!!!!! Go and test it, poke at it, bug me on irc about problems
+
+ * erc.el 1.127: *** empty log message ***
+
+2001-11-12 Tijs van Bakel <smoke@wanadoo.nl>
+
+ * erc.el 1.125:
+ Fixed bug in erc-get-buffer, now channel names are compared in
+ a case-insensitive way.
+
+2001-11-12 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.124: erc-server-353
+
+2001-11-12 Tijs van Bakel <smoke@wanadoo.nl>
+
+ * erc.el 1.123: Fixed docstring for erc-get-buffer.
+ Added erc-process to a lot of calls to erc-get-buffer, so
+ that only the local process is searched.
+
+2001-11-12 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.122: * erc-buffer-filter: do it differently
+
+ * erc.el 1.121: ugly but working fix for mhp's query problem
+
+ * erc.el 1.120: * erc-server-PRIVMSG-or-NOTICE
+ Now, all the server word replies are finished. Going to numreplies now
+
+ * erc.el 1.119:
+ * debugging fascilities for the transition. C-x 2 C-x o M-x ielm RET erc-server-vectors RET ; to get a list of all server messages currently not handled in the new code. Feel free to pick one and implement it
+
+ * erc.el 1.118: * erc-server-KICK and erc-server-TOPIC. new functions
+ * erc-server-305-or-306 and erc-server-311-or-314
+
+ * erc.el 1.117:
+ * ported PART and QUIT msgs to the new scheme, many to go. but it is a easy task. does someone wanna try and start with numreplies?
+
+ * erc.el 1.116: * erc-server-JOIN
+
+ * erc.el 1.115: * Ported erc-server-INVITE code
+
+ * erc.el 1.114: * erc-server-ERROR and erc-server-MODE
+
+2001-11-11 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.113: * zen
+
+ * erc.el 1.112: * New variable erc-connect-function.
+
+ * erc.el 1.111:
+ * New function erc-channel-p and use it where appropriate
+
+ * erc.el 1.110: * Removed the variable erc-buffer-list completely now
+ * Moved erc-dbuf around a bit
+
+ * erc.el 1.109: * Fix silly change in quit/rename msg handling
+
+ * erc.el 1.108: thanks mhp, fixed
+
+ * erc.el 1.107: * Tijs van Bakel's work from 10th Nov. merged in
+ * My additions to that idea merged in too
+ Basicly, this is a major rewrite, if you are scared and want avoid problems,
+ stay at your current version. It seems fairly stable though.
+ That changed? erc-buffer-name handling was completely rewritten,
+ and erc-buffer-list local variable handling removed.
+ Simplifies alot of code. Poke at it. read the diff. report bug/send patches!
+
+ * erc.el 1.106: * Added variable listing when /set is used without args
+
+2001-11-10 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.105:
+ * Comment/structure cleanup, removal of unnecessary code
+
+ * erc.el 1.104: only some code beautification
+
+ * erc-imenu.el 1.2:
+ remove add-hook call, thats done in erc.el now for autoloadability
+
+ * erc.el 1.103: * Make erc-imenu autoloadable
+
+ * erc.el 1.102:
+ * The long promised erc-mode-line-format handling rewrite
+ Poke at it, try it, play with it, report bugs
+
+ * erc.el 1.101:
+ some regex-quote fixes, new function erc-cmd-set, and minor things
+
+2001-11-08 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.100:
+ * added second timestamp-format (erc-away-timestamp-format) for marking msgs when being away
+
+ * erc-complete.el 1.2: fixed silly deffun
+
+ * erc.el 1.99: * Rewrote erc-load-irc-script (simplified)
+ * Removed depricated code
+
+ * erc-speak.el 1.15: * reflect changes in erc.el
+
+ * erc.el 1.98:
+ * Moved completion related functions into erc-complete.el
+ placed an autoload instead into erc.el. That quite cool,
+ because erc-complete.el only gets loaded when you use
+ TAB first time in erc.
+
+ * erc-complete.el 1.1: _ Initial checkin
+
+ * erc.el 1.97: * New function: erc-chain-hook-with-args
+ * Changed calls to erc-insert-hook to use it
+
+2001-11-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.96: * Patch from Fabien Penso
+ Make completion case insensitive. try it! its cool
+
+ * erc.el 1.95: * Reduction patch 2
+ This time, we move the input ring handling into erc-ring.el
+ Remember that you need (require 'erc-ring) in your .emacs to get the input handling as a feature
+ And remeber, that you dont need it if you dont use input ring :-)
+
+ * erc-ring.el 1.1: * Initial checkin
+
+ * erc.el 1.94: * The great reduction patch :-)
+ moved relevant function from erc.el to new file erc-menu.el and erc-imenu.el
+
+ * erc-imenu.el 1.1: nitial version
+
+ * erc-menu.el 1.1: * Initial version
+
+ * erc.el 1.93: * wording change suggested by Benjamin Drieu
+
+2001-11-07 Tijs van Bakel <smoke@wanadoo.nl>
+
+ * erc.el 1.92: Added Emacs version to /SV
+
+2001-11-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.91: * Hookification patch, read the diff
+
+ * erc.el 1.90: too tired for a changelog :)
+
+2001-11-06 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.89:
+ * make erc-cmd-op and erc-cmd-deop take multiple nicknames as argument
+
+2001-11-06 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.7: sync
+
+ * debian/rules 1.4: fixed a typo: PKGDIR, not PKIDR
+
+2001-11-06 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.88:
+ * Changed timestamping when away to use erc-timestamp-format and append the timestamp instead of prepending it..
+ * minor cleanup, s/(if (not /(unless/ and thelike
+
+2001-11-06 Tijs van Bakel <smoke@wanadoo.nl>
+
+ * erc.el 1.87: Fixed OP and DEOP commands to return T.
+ Added SV say-version command.
+ Added erc-send-message utility function, but it's not used everywhere yet.
+
+2001-11-05 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.86: stupid delYsid, forgot require 'format-spec. good nite
+
+ * erc.el 1.85:
+ * new variable erc-action-format. Some erc-notice-prefix fixes again
+
+ * erc.el 1.84: * erc-minibuffer-privmsg defaults to t
+
+ * erc.el 1.83:
+ * Small fix in relation to the transition to erc-make-notice
+
+2001-11-05 Tijs van Bakel <smoke@wanadoo.nl>
+
+ * erc.el 1.82:
+ Renamed erc-message-notices to erc-minibuffer-notice, and renamed erc-prevent-minibuffer-privmsg to erc-minibuffer-privmsg, inverting its functionality
+
+ * erc.el 1.81: Added support for channel names starting with & + and !.
+ Also, many changes partially discussed on the mailinglist:
+
+ * erc.el (cl): Add requirement for cl package.
+ (erc-buffer-list): Make this variable global again.
+ (erc-default-face): Fix typo.
+ (erc-timestamp-face): Add face for timestamps.
+ (erc-join-buffer, erc): Add a 'bury option.
+ (erc-send-action): Add timestamp.
+ (erc-command-table): Add /CLEAR, /DEOP, /OP, /Q.
+ (erc-send-current-line): Add timestamp.
+ (erc-send-current-line): Add call to erc-insert-hook.
+ (erc-cmd-clear): New command to clear buffer contents.
+ (erc-cmd-whois): Fix cut'n'paste-o.
+ (erc-cmd-deop): New command to deop a user.
+ (erc-cmd-op): New command to op a user.
+ (erc-make-notice): Moved a lot of duplicate code here. Perhaps
+ this should also be done for erc-highlight-error.
+ (erc-parse-line-from-server): Now NOTICE will also open a new
+ query, just as PRIVMSG.
+ (erc-parse-line-from-server): Call erc-put-text-property on a
+ channel message/notice first, before concatenating nick and
+ timestamp &c.
+ (erc-message-notices): Add option to display notices in
+ minibuffer.
+ (erc-fill-region): No longer strip spaces in front of incoming
+ messages.
+ (erc-parse-current-line): No longer strip spaces in front of text
+ input by user.
+
+ Hopefully I didn't break too much :(
+
+2001-11-05 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.80:
+ * New function erc-nickserv-identify-autodetect for erc-insert-hook. Added by default currently.
+
+ * erc.el 1.79:
+ * Mini-fix in erc-process-num-reply (= n 353): Added @ as prefix character to make certain channels on opn work again nicely
+
+2001-10-31 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.6: updated to reflect changes
+
+ * debian/scripts/install.in 1.2:
+ moved #PKGFLAG# before -f batch-byte-compile
+
+2001-10-29 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.78:
+ Imenu fixed somehow, added IRC services interactive function for indentify to NickServ. Read the diff
+
+2001-10-26 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.5: sigh. -2
+
+2001-10-25 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.4: updated to reflect changes
+
+ * debian/rules 1.3: handle conffiles.in too
+
+ * debian/maint/conffiles.in 1.1: new file
+
+ * debian/maint/conffiles 1.2: superceded by conffiles.in
+
+ * debian/scripts/startup 1.2: superceded by startup.erc
+
+2001-10-25 Mario Lang <mlang@delysid.org>
+
+ * debian/scripts/startup.erc-speak 1.1: * Initial version
+
+ * debian/scripts/startup.erc 1.1: * Added and fixes minimal typo
+
+2001-10-25 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.3: updated to reflect changes
+
+ * debian/rules 1.2:
+ modified to be able to build the erc-speak package too
+
+ * debian/control 1.2: added the new erc-speak package
+
+ * debian/README.erc-speak 1.1, debian/maint/postinst.in 1.1, debian/maint/prerm.in 1.1,
+ debian/scripts/install.in 1.1, debian/scripts/remove.in 1.1:
+ new file
+
+ * debian/maint/postinst 1.2, debian/maint/prerm 1.2, debian/scripts/install 1.2,
+ debian/scripts/remove 1.2:
+ removed, superceded by it's .in counterpart
+
+2001-10-25 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.77: * Fixed some defcustom :type 's
+ * Added erc-before-connect hook which gets called with server port and nick.
+ Use this hook to e.g. setup a tunnel before actually connecting.
+ something like (when (string= server "localhost") ...)
+
+2001-10-24 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.76: * Patch by smoke: fix erc-cmd-* commands and add aliases
+
+2001-10-23 Mario Lang <mlang@delysid.org>
+
+ * erc-speak.el 1.14:
+ * Added a new personality for channel name announcement, This makes streams of flooded channels much easier to listen to,
+ especially if you are on more than one channel simultaniously.
+
+ * erc.el 1.75:
+ * Made the completion postfix customizable through erc-nick-completion-postfix
+
+ * erc-speak.el 1.13, erc.el 1.74:
+ * Added erc-prevent-minibuffer-privmsg
+
+ * erc-speak.el 1.12:
+ * Quickish hack to allow exclusion of timestamps from speaking. see erc-speak-filter-timestamps
+
+2001-10-21 Mario Lang <mlang@delysid.org>
+
+ * erc-speak.el 1.11:
+ * Removed now really obsolete code. Package size reduced by 50%
+
+ * erc-speak.el 1.10:
+ * Very important fix! Now erc-speak is really complete. Messages dont get cut anymore. Be sure to use auditory icons,
+ it's reallllly cool now!!!
+
+ * erc-speak.el 1.9: *** empty log message ***
+
+ * erc-speak.el 1.5: * Major simplification. depends on erc.el,v 1.73
+ * Things removed, read diff
+
+2001-10-21 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.2: oops, silly typo
+
+ * debian/changelog 1.1, debian/control 1.1, debian/copyright 1.1,
+ debian/maint/conffiles 1.1, debian/maint/postinst 1.1, debian/maint/prerm 1.1,
+ debian/rules 1.1, debian/scripts/install 1.1, debian/scripts/remove 1.1,
+ debian/scripts/startup 1.1:
+ initial check-in
+
+2001-10-21 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.73:
+ * Changed erc-insert-hook to get two arguments, START and END of the region
+ which got inserted. CAREFUL! This could break stuff, but it makes the hook
+ much more useable.
+
+ * erc.el 1.72:
+ * Made erc-smiley a new option, currently set to t to showoff this feature. :)
+
+2001-10-20 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.71: * Add missing erc-mode-hook variable
+ * Add smiley-support (preliminary test)
+
+2001-10-20 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.70:
+ Replaced all occurences of put-text-property with a call to
+ erc-put-text-property.
+ (erc-put-text-property): New function.
+ (erc-tracking-modified-channels): Moved to the front of the file such
+ that it is already defined when the menu is being defined.
+ (erc-modified-channel-string): Ditto.
+
+2001-10-18 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.69: Removed some commentary. The wiki page is the place to
+ put such information.
+ (erc-fill-prefix): Doc change.
+ (erc-notice-highlight-type): Doc change, now a user option.
+ (erc-pal-highlight-type): Doc change, now a user option.
+ (erc-fool-highlight-type): New option.
+ (erc-keyword-highlight-type): New option.
+ (erc-dangerous-host-highlight-type): New option.
+ (erc-uncontrol-input-line): Doc change.
+ (erc-interpret-controls-p): Doc change, now a user option.
+ (erc-multiline-input): Doc change.
+ (erc-auto-discard-away): Doc change.
+ (erc-pals): Changed from string to regexp.
+ (erc-fools): New option.
+ (erc-keywords): Renamed from erc-highlight-strings. WATCH OUT:
+ Not backwards compatible change!
+ (erc-dangerous-hosts): Renamed from erc-host-danger-highlight.
+ WATCH OUT: Not backwards compatible change!
+ (erc-menu-definition): Added menu entries for fools, keywords and
+ dangerous hosts.
+ (erc-mode-map): Changed keybindings from C-c <plain ascii> to
+ various C-c <C-ascii> combinations.
+ (erc-dangerous-host-face): Renamed from erc-host-danger-face.
+ WATCH OUT: Not backwards compatible change!
+ (erc-fool-face): New face.
+ (erc-keyword-face): Renamed from erc-highlight-face. WATCH OUT:
+ Not backwards compatible change!
+ (erc-parse-line-from-server): Fixed highlighting in the cases
+ where (equal erc-pal-highlight-type 'all), added code to handle
+ erc-fool-highlight-type, erc-dangerous-host-highlight-type
+ (erc-update-modes): Replaced erc-delete-string with delete.
+ (erc-keywords): Renamed from erc-highlight-strings, handle
+ erc-keyword-highlight-type.
+ (erc-delete-string): Removed.
+ (erc-list-match): New function.
+ (erc-pal-p): Use erc-list-match.
+ (erc-fool-p): New function.
+ (erc-keyword-p): New function.
+ (erc-dangerous-host-p): Renamed from erc-host-danger-p, use
+ erc-list-match.
+ (erc-directed-at-fool-p): New function.
+ (erc-add-entry-to-list): New function.
+ (erc-remove-entry-from-list): New function.
+ (erc-add-pal): Use erc-add-entry-to-list.
+ (erc-delete-pal): Use erc-remove-entry-from-list.
+ (erc-add-fool): New function.
+ (erc-delete-fool): New function.
+ (erc-add-keyword): New function.
+ (erc-delete-keyword): New function.
+ (erc-add-dangerous-host): New function.
+ (erc-delete-dangerous-host): New function.
+
+2001-10-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.68: * irc vs ircd default port fixed
+
+ * erc.el 1.67: * Added topic-change to imenu
+
+ * erc.el 1.66: * More imenu spiffyness
+
+ * erc.el 1.65: * Added imenu support
+
+ * erc.el 1.64:
+ * Fix to /topic to show topic instead of setting it to null :)
+
+2001-10-05 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.63: * First version of erc-rename-buffer
+
+ * erc.el 1.62: * more header-line tricks.
+
+ * erc.el 1.61:
+ * Small fix to do erc-update-mode-line-buffer in erc-update-channel-topic
+
+ * erc.el 1.60: * Added erc-header-line-format
+
+2001-10-04 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.59: * mini-fix, add msgp to auto-query code
+
+ * erc.el 1.58: * Added command-names to completion (erc-command-table)
+ * New variable erc-auto-query. When set, every arriving message to you
+ will open a query buffer for that sender if not already open.
+ * Compatibility function fo non-existing line-beginning|end-position functions in XEmacs.
+
+2001-10-03 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.57:
+ * Removed alot of (progn ...) where they were not necessary
+ * Changed some (if ...) without else part to (when ...)
+ * Some (while ...) to use (dolist ...)
+ * Fix for completion popup generating tracebacks.
+ * New function erc-arrange-session-in-mulptiple-windows
+ * Lots of other stuff, read the diff
+
+2001-10-02 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.56: * Added erc-kill-input and keybinding C-c C-u for it
+
+2001-10-01 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.55: * Another fix to nick-completion
+ * Additional checks in erc-track-modified-channels
+
+2001-09-26 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.54: * Fixed completion (alex)
+ * Now popup buffer doesnt destroy your window configuration.
+ * Fixed away handling (incomplete)
+
+2001-09-24 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.53: Fixed silly quoting-escape error
+
+2001-09-23 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.52: * Added auto-op support (unfinished)
+ * Added erc-latest-version.
+ * Added erc-ediff-latest-version.
+
+2001-09-21 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.51:
+ * Minor menu additions (invite only mode is now a checkbox)
+
+2001-09-20 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.50:
+ * Fix (erc-cmd-names): This should fix C-c C-n too, hoepfully it was the right fix and doesnt break anything else.
+
+ * erc.el 1.49: * Fixes XEmacs easymenu usage (2nd time).
+
+2001-09-19 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.48:
+ * (erc-complete-nick): Add ": " only if one completes directly after the erc-prompt, otherwise, add just one space
+
+ * erc.el 1.47:
+ * Changed menu-definition to use easymenu (hopefully this now works under Xemacs)
+ * Fix for custom problem with :must-match on XEmacs (thanks shapr)
+ * Added /COUNTRY command using (what-domain) from package mail-extr (shapr)
+ * Fix for case-sensitivity problem with pals (they are now all downcased)
+ * Different (erc-version) function which now can take prefix argument to insert the version information into the current buffer,
+ instead of just displaying it in the minibuffer.
+
+2001-09-10 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.46: Updated erc-version-string
+
+ * erc.el 1.45: Version number change and last read-through...
+
+2001-09-04 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.44: Added some asterisks
+
+2001-08-24 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.43:
+ Fixed hidden channel buffer tracking (sort of), now using switch-to-buffer for advice.
+ This version is unofficially named 2.1prebeta1. Please test it and send
+ fixes to various problems you may encounter so that we can eventually
+ release 2.1 soon.
+
+2001-08-14 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.42:
+ Added function erc-bol and keybinding C-c C-a for it (contributed by Benjamin Rutt <brutt@bloomington.in.us)
+
+2001-08-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.41:
+ Checked in lathis code and modified it slightly. Still unsure about set-window-buffer advice, current attempt doesnt seem to work.
+ Removed (nick -> #channel) from mode-line. (CLOSED) and (AWAY...) should still be displayed when appropriate
+
+2001-08-06 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.40:
+ added local-variable channel-list in session-buffers and make /LIST use it.
+ erc-join-channel can now do completion after /LIST was executed
+
+2001-08-05 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.39: Tweaked erc-join-channel and erc-part-from-channel
+
+2001-07-27 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.38: some more defcustom stuff
+
+ * erc.el 1.37: Patch from Henrik Enberg <henrik@enberg.org>:
+ Adds variables erc-frame-alist and erc-frame-dedicated-p.
+
+ * erc.el 1.36: fixed erc-part-from-channel
+
+ * erc.el 1.35:
+ fixed match-string problem and added interactive topic setting function.
+
+ * erc.el 1.34: fixed silly string-match bug
+
+ * erc.el 1.33:
+ Added erc-join-channel and erc-part-from-channel (interactive prompts), as well as keybindings. C-c C-j #emacs RET is now enough :)
+
+2001-07-27 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.32 (erc-display-line-buffer): Simplified filling.
+ (erc-fill-region): New function.
+
+2001-07-27 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.31: Added redundancy check in output
+
+2001-07-26 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.30 (erc-send-action): Add text-property stuff.
+ (erc-input-action): Removed text-property stuff.
+ (erc-command-table): Corrected command for DESCRIBE. Still
+ doesn't work though. No idea what it should do. Looks like a no op.
+ (erc-cmd-me): Doc change.
+
+2001-07-26 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.29:
+ fixed one occurence of a setq with only one argument (XEmacs didnt like that)
+
+ * erc.el 1.28:
+ Added erc-next-line-add-newlines customisation possibility.
+
+ * erc.el 1.27:
+ added erc-fill-prefix for defining your own way of filling and fixed filling somehow
+
+ * erc.el 1.26:
+ fixed small incompatibility in erc-parse-line-from-server at (and (= n 353) regexp
+
+2001-07-25 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.25:
+ Added erc-filling and filling code to erc-display-line-buffer.
+
+2001-07-08 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.24 (try-complete-erc-nick): Make the ": " part of the
+ expansion
+
+ * erc.el 1.23: require ring
+
+2001-07-08 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.22: *** empty log message ***
+
+2001-07-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.21: typo
+
+ * erc.el 1.20: ommit
+ :wq
+
+2001-07-06 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.19 (erc-mode): Call erc-input-ring-setup.
+ (erc-send-current-line): Call erc-add-to-input-ring.
+ (erc-input-ring): New variable. Currently not buffer local.
+ (erc-input-ring-index): New variable. Currently not buffer local.
+ (erc-input-ring-setup): New function.
+ (erc-add-to-input-ring): New function.
+ (erc-previous-command): New function.
+ (erc-next-command): New function.
+ (erc-mode-map): Uncommented keybindings for erc-next-command and
+ erc-previous-command.
+
+2001-07-05 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.18 (erc-highlight-strings): Removed debug message.
+
+ * erc.el 1.17 (erc-join-buffer): Changed default to 'buffer.
+ (erc-join-info-buffer): Changed default to 'disable.
+ (erc-nick-completion): Changed default to 'all.
+
+2001-07-04 uid31117 <uid31117@confusibombus>
+
+ * erc.el 1.16: Resolved...
+
+2001-07-03 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.15 (erc-highlight-strings): New option and new function.
+ (erc-parse-line-from-server): Use it.
+ Various empty lines removed. Various doc strings fixed.
+
+ * erc.el 1.14: Removed more empty lines.
+
+ * erc.el 1.13 (erc-member-string): replaced by plain member
+ Otherwise, lots of deleting of empty lines... I'm not too happy with that
+ but I feel better when the code is "cleaned up".
+
+2001-07-03 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.12: Ugly hack, but looks nicer when giving commands
+
+ * erc-speak.el 1.4: ugly hack, but looks nicer now
+
+2001-07-03 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.11 (try-complete-erc-nick): New function.
+ (erc-try-complete-nick): New function.
+ (erc-nick-completion): New option.
+ (erc-complete): Call hippie-expand such that erc-try-complete-nick
+ will be called eventually. Based on erc-nick-completion
+ try-complete-erc-nick will then complete on the nick at point.
+
+2001-07-02 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.10:
+ Insert (erc-current-nick) instead of (erc-display-prompt). good night :)
+
+ * erc.el 1.9:
+ small, but it was anoying, so I just did it (defcustom for erc-join-buffer and erc-join-info-buffer)
+
+2001-06-29 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.8: Use defface to define all faces.
+ Removed some history from the commentary, as well as some other
+ commentary editing.
+
+2001-06-28 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.7: hmm, defcustom for erc-user-full-name
+
+ * erc-speak.el 1.3, erc.el 1.6: *** empty log message ***
+
+2001-06-27 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.5: typo
+
+ * erc.el 1.4: Some more defcustom
+
+ * erc-speak.el 1.2: nothing, really
+
+2001-06-26 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.3: Some defcustom stuff. Still no defgroup though :)
+
+ * erc.el 1.2:
+ Initial change to erc.el (2.0). Mainly list of ideas and features
+ and syntax-table entries.
+
+ * erc-speak.el 1.1.1.1, erc.el 1.1.1.1: Initial Import
+
+ * erc-speak.el 1.1, erc.el 1.1: New file.
+
+ Copyright (C) 2001 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted provided the copyright notice and this notice are preserved.
+
+;; arch-tag: 306c4b58-f9ae-4f3d-9fd9-db2d743f05a6
diff --git a/lisp/erc/ChangeLog.2002 b/lisp/erc/ChangeLog.2002
new file mode 100644
index 00000000000..2b4a18544a1
--- /dev/null
+++ b/lisp/erc/ChangeLog.2002
@@ -0,0 +1,2601 @@
+2002-12-31 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.398 (erc-split-command):
+ Removed assignment to free variable "continue".
+ (erc-strip-controls): New function. Takes a string, returns the string with
+ all IRC color/bold/underline/etc. control codes stripped out.
+ (erc-interpret-controls): If variable erc-interpret-controls-p is nil, now
+ uses erc-strip-controls to strip control codes.
+ (erc-ctcp-reply-ECHO): Changed reference and assignment to free variable "s"
+ into reference/assignment to "msg", which appears to be the original author's
+ intent.
+
+ * erc-list.el 1.8 (erc-chanlist):
+ Changed to use the new erc-once-with-server-event function
+ instead of the old macro of the same name.
+
+ * erc-notify.el 1.10 (erc-notify-timer):
+ Changed to use the new erc-once-with-server-event function
+ instead of the old macro of the same name. Also fixed a bug were variable
+ erc-last-ison was being read from a non-server buffer (thus giving its default
+ value instead of its per-server value).
+
+ * erc.el 1.397 (erc-once-with-server-event):
+ This is now a function. It was a macro with a
+ bug (the call to gensym happened at byte-compile-time not macro-call-time).
+ (erc-toggle-debug-irc-protocol): Now [return] is bound to this function in
+ the *erc-protocol* buffer.
+
+2002-12-30 Alex Schroeder <alex@gnu.org>
+
+ * erc-autoaway.el 1.10 (erc-autoaway-idletimer): Doc,
+ ref. erc-autoaway-use-emacs-idle.
+ (autoaway): Doc, explain different idle definitions. Reestablish
+ the idletimer only when erc-autoaway-use-emacs-idle is non-nil.
+ (erc-auto-set-away): Doc, ref erc-auto-discard-away.
+ (erc-auto-discard-away): Doc, ref erc-auto-set-away.
+ (erc-autoaway-use-emacs-idle): Doc, ref erc-autoaway-mode, and
+ added a note that this feature is currently broken.
+ (erc-autoaway-reestablish-idletimer): Doc.
+ (erc-autoaway-possibly-set-away): Split test such that
+ erc-time-diff is only computed when necessary, add a comment why
+ erc-process-alive is not necessary.
+ (erc-autoaway-set-away): Test for erc-process-alive.
+
+2002-12-29 Alex Schroeder <alex@gnu.org>
+
+ * erc-autoaway.el 1.9:
+ Changed the order of defcustoms to avoid errors in the :set property
+ of erc-autoaway-idle-seconds.
+
+2002-12-29 Damien Elmes <erc@repose.cx>
+
+ * erc-track.el 1.42:
+ * (erc-track-get-active-buffer): remove superflous (+ arg 0)
+
+2002-12-29 Alex Schroeder <alex@gnu.org>
+
+ * erc-autoaway.el 1.8 (erc-autoaway): Moved the defgroup up to the
+ top, before the define-erc-module call.
+ (autoaway): Extended doc.
+ (erc-autoaway-idle-seconds): Use a :set property to handle
+ erc-autoaway-use-emacs-idle.
+ (erc-auto-set-away): Set default to t. Added doc strings where
+ necessary, reformatted doc strings such that the first line can
+ stand on its own. This is important for the output of M-x
+ apropos.
+
+2002-12-28 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-auto.in 1.3:
+ added (provide 'erc-auto), which is required for (require 'erc-auto) :)
+
+ * erc.el 1.396 (erc-display-prompt):
+ Set the face property of the prompt to
+ everything but the last character.
+
+ * erc.el 1.395 (erc-send-current-line):
+ Check wether point is in the input line. If
+ not, just beep and do nothing.
+
+2002-12-28 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.394 (erc-bol):
+ Fixed bug when there is only a prompt, and no property
+ change.
+
+ * erc.el 1.393 (erc-display-prompt): Rewrote using a save-excursion
+ and erc-propertize. No longer use a field for the prompt, but a
+ plain text property called erc-prompt.
+ (erc-bol): Use the erc-prompt text property instead of a field.
+ Return point instead of t.
+ (erc-parse-current-line): No need to call point here, then, since
+ erc-bol now returns point.
+
+ * Makefile 1.11:
+ make ChangeLog .PHONY, thus forcing it always to be rebuilt.
+
+2002-12-28 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.392 (erc-log-irc-protocol):
+ Removed check wether get-buffer-create
+ returned nil. "The value is never nil", says the docstring.
+
+ * erc.el 1.391: Day Of The Small Changes
+
+ (erc-display-prompt): Make the prompt 'front-sticky, which prevents it
+ from being modified. It *should* also make end-of-line move to the
+ end of the field (i.e. the end of the prompt) when point is at the
+ beginning of the prompt, but it doesn't. Dunno why. :(
+
+2002-12-27 Francis Litterio <franl@users.sourceforge.net>
+
+ * Makefile 1.10:
+ Added "-f" to "rm" command in rule for target "realclean".
+
+ * erc.el 1.390:
+ New function: erc-log-irc-protocol. Consolidates nearly duplicate code
+ from functions erc-send-command and erc-process-filter into one function.
+
+ * erc.el 1.389 (erc-toggle-debug-irc-protocol):
+ Removed unneeded argument PREFIX and code
+ which referenced it at end of function.
+ (erc-send-command): Now we only append a newline to the logged copy
+ of output protocol text if it doesn't have one.
+
+2002-12-27 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.388 (erc-toggle-debug-irc-protocol):
+ Display buffer if it's not shown
+ already, and use view-mode.
+ (erc-toggle-debug-irc-protocol), (erc-send-command),
+ (erc-process-filter): inhibit-only t to insert into the
+ *erc-protocol* buffer (view-mode)
+
+2002-12-27 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.387 (erc-mode-map):
+ Removed keybinding for erc-toggle-debug-irc-protocol.
+ (erc-toggle-debug-irc-protocol): Now used erc-make-notice to propertize the
+ face of the enabled/disabled messages in the *erc-protocol* buffer.
+ (erc-send-command): Now outgoing IRC protocol traffic is logged too.
+
+ * erc.el 1.386:
+ Added user-customizable variable erc-debug-irc-protocol.
+ Added function erc-toggle-debug-irc-protocol.
+ (erc-process-filter): Now supports IRC protocol logging. If variable
+ erc-debug-irc-protocol is non-nil, all IRC protocol traffic is appended
+ to buffer *erc-protocol*, which is created if necessary.
+
+2002-12-27 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.385 (erc-display-prompt):
+ Don't make the prompt intangible; that didn't
+ make things that much better for the user, but confused ispell,
+ which checked the prompt when it should check the first word
+
+2002-12-27 Alex Schroeder <alex@gnu.org>
+
+ * AUTHORS 1.4: fixed resolve's email add
+
+ * AUTHORS 1.3: added damien
+
+ * erc.el 1.384 (erc-truncate-buffer-on-save):
+ Removed documentation that
+ described behaviour now changed. It used to say "When nil, no
+ buffer is ever truncated." This is no longer true; even when
+ buffers are NOT truncated on save, they can be truncated, eg. by
+ adding erc-truncate-buffer to the hook.
+ (erc-logging-enabled): New function.
+ (erc-current-logfile): New function.
+ (erc): Use erc-logging-enabled and erc-current-logfile.
+ (erc-truncate-buffer-to-size): Rewrote it, and made sure to use a
+ (save-restriction (widen) ...) such that the truncation actually
+ runs in the whole buffer, not in the last message only (as
+ erc-insert-post-hook will do!). This should fix rw's
+ out-of-bounds error.
+ (erc-generate-log-file-name-short): Made all but the BUFFER
+ argument optional. Doc: Mention
+ erc-generate-log-file-name-function.
+ (erc-generate-log-file-name-long): Doc: Mention
+ erc-generate-log-file-name-function.
+ (erc-save-buffer-in-logs): Use erc-logging-enabled and
+ erc-current-logfile. Doc: Mention erc-logging-enabbled.
+
+ (erc-encode-string-for-target): Only do the real work when
+ featurep mule; else just return the string unchanged.
+
+2002-12-27 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.383:
+ erc-encoding-default: check for (coding-system-p) for older emacs versions
+
+ * erc.el 1.382 (erc-connect): missing ()s added. "don't commit at 2am"
+
+ * erc.el 1.381 (erc-connect):
+ check if (set-process-coding-system) is available before use
+
+2002-12-27 Alex Schroeder <alex@gnu.org>
+
+ * AUTHORS 1.2: added franl
+
+2002-12-26 Alex Schroeder <alex@gnu.org>
+
+ * erc-pcomplete.el 1.14 (pcomplete-parse-erc-arguments):
+ Reworked, and fixed a bug that had
+ caused completions to corrupt preceding text under some circumstances.
+
+ * erc.el 1.380 (erc-encoding-default): New.
+ (erc-encode-string-for-target): Use it instead of a hard-coded ctext.
+ (erc-encoding-coding-alist): Doc.
+
+2002-12-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.379:
+ Removed fix for bug 658552 recently checked-in, because it doesn't work.
+
+ * erc.el 1.378 (erc-kill-buffer-function):
+ Removed check that connection is up
+ before running erc-kill-server-hook hooks. Those hooks should use
+ erc-process-alive to avoid interacting with the process.
+
+ * erc.el 1.377:
+ Fixed erc-send-current-line so it no longer assigns the free variable "s", and
+ it doesn't move point to end-of-buffer in non-ERC buffers. Fixed
+ erc-kill-buffer-function so it doesn't run the erc-kill-server-hook hooks if the
+ server connection is closed. Fixed bug 658552, which is described in detail at
+ http://sourceforge.net/tracker/index.php?func=detail&aid=658552&group_id=30118&atid=398125
+
+2002-12-26 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.376 (erc-cmd-SMV): Bug, now call erc-version-modules.
+
+ * erc-pcomplete.el 1.13 (erc-pcomplete-version): New.
+
+2002-12-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-pcomplete.el 1.12:
+ Fix for bug where you could not complete a nick when there was text following
+ the nick.
+
+2002-12-25 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.375 (erc-already-logged-in): Use erc-process-alive.
+ (erc-prepare-mode-line-format): Use erc-process-alive.
+ (erc-process-alive): Check erc-process for boundp and processp.
+
+ * erc.el 1.374 (erc-kill-buffer-function):
+ Do not check wether the process is
+ alive before running the hook, because there might be functions on
+ the hook that need to run even when the process is dead. And
+ function that wants to check this, should use (erc-process-alive).
+ (erc-process-alive): New function.
+ (erc-kill-server): Use it.
+ (erc-kill-channel): Use it.
+
+ * erc.el 1.373 (erc-kill-buffer-function):
+ Reverted ignore-error change.
+ ignore-error is dangerous because we might miss bugs in functions
+ on erc-kill-server-hook.
+
+ * erc.el 1.372 (erc-kill-buffer-function): Use memq instead of member
+ when checking process-status. Added doc string with references to
+ the other hooks.
+ (erc-kill-server): Only send the command when the erc-process is
+ still alive. This prevents the error: "Process
+ erc-irc.openprojects.net-6667 not running" when killing the buffer
+ after having used /QUIT.
+
+2002-12-24 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.371 (erc-server-ERROR):
+ Show the error reason, not only the originating host.
+
+ * erc.el 1.370 (erc-kill-buffer-function):
+ (ignore-errors ...) in 'erc-kill-server-hook.
+ When the process for this server does not exist anymore, the hook
+ will cause an error, effectively preventing the buffer from being
+ killed.
+
+2002-12-24 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-notify.el 1.9:
+ Fixed erc-notify-timer so that it passes the correct nick to
+ the functions on erc-notify-signoff-hook.
+
+2002-12-24 Alex Schroeder <alex@gnu.org>
+
+ * erc-track.el 1.41: Doc
+
+ * erc-track.el 1.40 (erc-make-mode-line-buffer-name): Removed a
+ superfluous if construct around erc-track-showcount-string.
+ (erc-track-modified-channels): Use 1+.
+ Plus some doc and comment changes.
+
+2002-12-23 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.369: Fix (erc-version) string
+
+2002-12-23 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.368:
+ Removed unnecessary assignment to free-variable "p" in erc-downcase.
+
+ * erc.el 1.367:
+ Now /PART reason strings are generated the same way /QUIT reason strings
+ are generated (see variable erc-part-reason). Also, when a server buffer
+ is killed, a QUIT command is automatically sent to the server.
+
+ * erc.el 1.366:
+ Changed erc-string-no-properties so that it is more efficient. Now it uses
+ set-text-properties instead of creating and deleting a temporary buffer.
+
+2002-12-21 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.365:
+ erc-kill-input: added a check to prevent a (ding) and an error when
+ there's nothing to kill (thanks to Francis Litterio, franl on IRC)
+
+2002-12-21 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.364:
+ AWAY notice duplication prevention. erc-prevent-duplicates now set to ("301") by default, and timeout to 60
+
+ * erc.el 1.363: erc-prevent-duplicates: New variable, see docstring
+
+2002-12-20 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el 1.39:
+ erc-track-modified-channels: Use cddr of cell for old-face. cdr of
+ cell is '(1 . face-name), i have no idea why :)
+
+2002-12-20 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.362 (erc-current-nick):
+ check the server buffer is active before using
+
+ Also tabified and cleaned up some trailing whitespace
+
+2002-12-15 Mario Lang <mlang@delysid.org>
+
+ * erc-track.el 1.38: erc-track-count patch by az
+
+2002-12-14 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.361:
+ last-peers: initialise to a cons. thanks to Francis Litterio
+ <franl@world.std.com> for the patch
+
+ * erc.el 1.360:
+ erc-kill-channel-hook, erc-kill-buffer-hook, (erc-kill-channel):
+ both hooks now call erc-save-buffer-in-logs, so that query buffers are
+ saved properly now, and not just channel buffers.
+
+2002-12-13 Alex Schroeder <alex@gnu.org>
+
+ * erc-track.el 1.37 (erc-unique-channel-names): Fix another #hurd
+ vs. #hurd-bunny bug.
+
+ * erc-match.el 1.17 (match): No longer modify erc-send-modify-hook,
+ since it does not work without a parsed text property, anyway.
+ (erc-keywords): Allow cons cells.
+ (erc-remove-entry-from-list): Deal with cons cells.
+ (erc-keyword-p): Ditto.
+ (erc-match-message): Ditto.
+
+ Moved nil to the beginning of the list, removed :tags for the
+ -type variables:
+ (erc-current-nick-highlight-type): Ditto.
+ (erc-pal-highlight-type): Ditto.
+ (erc-fool-highlight-type): Ditto.
+ (erc-keyword-highlight-type): Ditto.
+ (erc-dangerous-host-highlight-type): Ditto.
+ (erc-log-matches-flag): Moved nil to the beginning.
+
+2002-12-11 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.359:
+ erc-beg-of-input-line: Don't do (goto-char (beginning-of-line)), since
+ beginning-of-line always moves point and returns nil. Thanks to
+ franl on IRC for noting this.
+
+ * erc-stamp.el 1.20:
+ erc-insert-timestamp-left, erc-insert-timestamp-right: Made the
+ timestamp a 'field named 'erc-timestamp. Now end-of-line and
+ beginning-of-line will move over the timestamp.
+
+2002-12-10 Damien Elmes <erc@repose.cx>
+
+ * erc-button.el 1.34 (erc-button-add-button):
+ make the created button rear-nonsticky, to allow
+ cutting and pasting of buttons without worrying about the button properties
+ being inherited by the text typed afterwards.
+
+ * erc.el 1.358: save logfile when killing buffer
+
+2002-12-09 Alex Schroeder <alex@gnu.org>
+
+ * erc-track.el 1.36 (erc-modified-channels-display): Reworked.
+ (erc-track-face-more-important-p): Removed.
+ (erc-track-find-face): Return only one face.
+ (erc-track-modified-channels): Reworked.
+ (erc-modified-channels-string): Changed from (BUFFER FACE...) to
+ (BUFFER . FACE)
+
+ * erc-stamp.el 1.19 (erc-insert-timestamp-right): Do not assume
+ erc-fill-column is available.
+
+2002-12-09 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.357:
+ erc-ech-notices-in-minibuffer-flag, erc-minibuffer-notice: Clarified
+ the difference in the docstrings.
+
+2002-12-08 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.356: erc-noncommands-list: added erc-cmd-SM and erc-cmd-SMV
+
+2002-12-08 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.355 (erc-cmd-SM): New.
+ (erc-cmd-SMV): New.
+
+ * erc.el 1.354 (erc-modes): New.
+
+2002-12-08 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-compat.el 1.9:
+ field-end: use (not (fboundp 'field-end)) instead of (featurep 'xemacs)
+
+2002-12-08 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.353 (erc-version-modules): New.
+
+2002-12-08 Mario Lang <mlang@delysid.org>
+
+ * debian/changelog 1.19, debian/control 1.7, debian/scripts/startup.erc 1.3:
+ debian release 3.0.cvs.20021208
+
+2002-12-08 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.352 (erc-split-command): Do the right thing with CTCPs.
+
+2002-12-08 Mario Lang <mlang@delysid.org>
+
+ * erc-stamp.el 1.18: Be a bit more functional
+
+2002-12-08 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-compat.el 1.8:
+ XEmacs doesn't seem to have field-end, so we provide our own version here.
+
+2002-12-08 Mario Lang <mlang@delysid.org>
+
+ * Makefile 1.9: Small fixes to debrelease target
+
+2002-12-08 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.351:
+ make-obsolete-variable: xemacs doesn't have the WHEN parameter, remove it.
+
+2002-12-07 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-imenu.el 1.5 (erc-create-imenu-index):
+ Use (forward-line 0) instead of
+ (beginning-of-line) now, sine the latter ignores fields (used in the
+ prompt).
+
+ * erc.el 1.350:
+ Rewrite of the prompt stuff to use a field named 'erc-prompt:
+
+ erc-prompt: Removed getter and setter functions. The properties were
+ already set (and overwritten) in erc-display-prompt.
+ (erc-prompt): Add the trailing space here, not all over the code.
+ (erc-display-prompt): Cleaned up a bit. The text-properties now are
+ valid on the whole prompt. Also, made the prompt 'intangible to
+ avoid confused users.
+ (erc-bol): Now use the field 'erc-prompt for finding the prompt
+ (erc-parse-current-line): Cleaned up considerably. Uses (erc-bol) now.
+ (erc-load-irc-script-lines): Adjusted for the new (erc-prompt).
+ (erc-save-buffer-in-logs): Adjusted for the new (erc-prompt).
+
+ * erc.el 1.349:
+ erc-uncontrol-input-line: The comment said "Consider it deprecated",
+ so I removed it now.
+ erc-prompt-interactive-input: Marked obsolete as of 1.348
+
+ * erc.el 1.348:
+ erc-smiley, erc-unmorse: Put at the end to separate it from the
+ important parts of erc.el.
+
+2002-12-07 Alex Schroeder <alex@gnu.org>
+
+ * erc-stamp.el 1.17 (erc-insert-timestamp-right): New algorithm.
+
+2002-12-07 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.347:
+ last-peers, erc-message: Explained what last-peers is used for.
+
+2002-12-07 Alex Schroeder <alex@gnu.org>
+
+ * erc-page.el 1.3 (erc-cmd-PAGE): New function.
+ (erc-ctcp-query-PAGE): Use the catalog entry for the message, too.
+ (erc-ctcp-query-PAGE-hook): Added custom type.
+ (erc-page-function): Changed custom type from ... function-item to
+ ... function.
+ As well as doc strings.
+
+2002-12-06 Alex Schroeder <alex@gnu.org>
+
+ * erc-page.el 1.2: provide feature at the end
+
+2002-12-06 Brian P Templeton <bpt@tunes.org>
+
+ * erc-nickserv.el 1.10:
+ Added austnet in erc-nickserv.el (thanks to Damien Elmes
+ <resolve@repose.cx>)
+
+2002-12-05 Mario Lang <mlang@delysid.org>
+
+ * erc-complete.el 1.13: Add autoload cookie
+
+ * erc-speak.el 1.24: Small fix to make proper voice-changes
+
+2002-12-05 Alex Schroeder <alex@gnu.org>
+
+ * erc-lang.el 1.1: New
+
+2002-12-03 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.346:
+ erc-mode-map: Put back C-c C-p (PART) and C-c C-q (QUIT)
+
+2002-12-02 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.345:
+ erc-insert-post-hook: Add :options erc-make-read-only, erc-save-buffer-in-logs
+ erc-send-post-hook: Add :options erc-make-read-only
+
+ * erc.el 1.344: erc-insert-hook: Removed ("this hook is obsolescent")
+ erc-insert-post-hook: Added :options '(erc-truncate-buffer)
+
+2002-12-02 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.343: Add missing requires
+
+2002-11-29 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.342 (erc-quit-reason-normal):
+ Remove v before %s so it's "Version ..." not
+ "vVersion ..."
+
+2002-11-26 Alex Schroeder <alex@gnu.org>
+
+ * erc-compat.el 1.7 (erc-encode-coding-string): Add second argument
+ coding-system, and for non-mule xemacsen, use a new defun instead
+ of identity.
+
+ * erc.el 1.341: (define-erc-module): Use the appropriate group.
+ (erc-port): Changed custom type.
+ (erc-insert-hook): Custom group changed to erc-hooks.
+ (erc-after-connect): ditto
+ (erc-before-connect): ditto
+ (erc-disconnected-hook): ditto
+
+ * erc-button.el 1.33 (erc-button): New group, changed all custom groups
+ from erc to erc-button, but left all erc-faces as-is.
+
+ * erc-track.el 1.35 (erc-track): New group, changed all custom groups
+ from erc to erc-track.
+
+2002-11-26 Mario Lang <mlang@delysid.org>
+
+ * erc-macs.el 1.1:
+ Macros for erc-victim handling. Primary idea is to use setf and some fancy things to get nice syntax. have a look
+
+2002-11-26 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.340:
+ pings, erc-cmd-PING, erc-ctcp-reply-PING, catalog entry CTCP-PING:
+ Cleaned up. Removed buffer-local variable pings which stored a list of
+ all sent CTCP PING requests. Now send our full time with the CTCP PING
+ request and interpret the answer.
+
+2002-11-25 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.339: nick-stk: replaced by the local variable current-nick.
+
+2002-11-25 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.338 (erc-send-command): Use erc-encode-string-for-target.
+ (erc-encode-string-for-target): New.
+
+ * erc-compat.el 1.6 (erc-encode-coding-string): Add second argument
+ coding-system, and for non-mule xemacsen, use a new defun instead
+ of identity.
+
+ * erc-nickserv.el 1.9 (erc-nickserv-version): New.
+
+2002-11-25 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * Makefile 1.8:
+ UNCOMPILED: erc-chess.el depends on chess-network.el, which might not
+ be installed. Don't compile it.
+
+ * erc.el 1.337:
+ erc-mode-map: Added C-a as erc-bol (no reason why it shouldn't be),
+ and removed C-c C-p (part channel) and C-c C-q (quite server) as these
+ are a bit drastic in their consequences and easy to mistype.
+
+2002-11-24 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el 1.34: erc-track-faces-priority-list: Extended list
+
+ * erc.el 1.336:
+ channel-members: Updated docstring: We have a VOICE predicate, too.
+
+ * erc-track.el 1.33 (erc-unique-substrings):
+ Don't shorten a single channel to "#", but
+ always give at least 2 chars (except when there are no two chars).
+
+2002-11-23 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-nickserv.el 1.8:
+ support for BrasNET. Thanks to rw on IRC for the settings.
+
+2002-11-23 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.335: (erc-default-recipients, erc-session-user-full-name)
+ (nick-stk, pings, erc-announced-server-name, erc-connected)
+ (channel-user-limit, last-peers, invitation, away, channel-list)
+ (last-sent-time, last-ping-time, last-ctcp-time, erc-lines-sent)
+ (erc-bytes-sent, quitting, bad-nick, erc-logged-in)
+ (erc-default-nicks): Defvars.
+
+ * erc-compat.el 1.5: Switched tests to iso-8859-1 instead of latin-1.
+
+ * erc-compat.el 1.4 (erc-compat-version): New.
+
+2002-11-22 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.334 (smiley): Smileys are a very small module, now.
+
+2002-11-22 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.333:
+ erc-event-to-hook, erc-event-to-hook-name: eval-and-compile these,
+ since we need them in a macro. ERC now compiles again!
+
+ * erc-speak.el 1.23:
+ erc-minibuffer-privmsg: Removed setting this variable to nil, since it
+ was removed from erc.el.
+
+ * erc.el 1.332 (erc-interactive-input-map): Added docstring.
+ (erc-wash-quit-reason): Extended docstring.
+ (erc-server-ERROR): Added docstring.
+ (erc-server-321): buffer-local variable channel-list probably
+ shouldn't be renamed erc-channel-list - removed FIXME.
+
+ * erc.el 1.331: small cleanup.
+ ("was not used anymore" here means "not used in erc/*.el nor in
+ fsbot", thanks to deego for checking that.)
+
+ erc-minibuffer-privmsg: Removed (was not used anymore)
+ (erc-reformat-command): Removed (was not used anymore)
+ (erc-strip-erc-parsed-property): Removed (was not used anymore)
+ (erc-process-ctcp-response): Removed (replaced by ctcp-query-XXX-hook)
+ (erc-send-paragraph): Removed ("Note that this function is obsolete,
+ erc-send-current-line handles multiline input.")
+ (erc-input-hook): Removed ("This hook is obsolete. See
+ `erc-send-pre-hook', `erc-send-modify-hook' and
+ `erc-send-post-hook' instead.")
+ (erc-message-hook): Removed ("This hook is obsolete. See
+ `erc-server-PRIVMSG-hook' and `erc-server-NOTICE-hook'.")
+ (erc-cmd-default-channel): Removed ("FIXME: no clue what this is
+ supposed to do." - it was supposed to prepend the default channel
+ to a command before sending it. E.g. typing "/FOO now!" would send
+ the IRC command "FOO #mycurrentchannel now!")
+
+ * erc.el 1.330:
+ erc-ctcp-query-PING: Send the whole argument back, not just the first
+ number. This is required for many clients (e.g. irssi, BitchX, ...)
+ which send their ping times in two different numbers for microsecond
+ accuracy.
+
+2002-11-22 Alex Schroeder <alex@gnu.org>
+
+ * erc-track.el 1.32 (erc-track-shorten-function): Allow nil.
+
+2002-11-21 Alex Schroeder <alex@gnu.org>
+
+ * erc-track.el 1.31 (erc-unique-channel-names): Fixed bug that appeared
+ if one target name was a substring of another -- eg. #hurd and
+ #hurd-bunny. Added appropriate test.
+
+2002-11-20 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el 1.30:
+ erc-unique-channel-names: Don't take a substring of channel that could
+ be longer than the channel, but at most (min (length candidate)
+ (length channel). (thanks to deego for noticing this)
+
+2002-11-19 Mario Lang <mlang@delysid.org>
+
+ * erc-notify.el 1.8: * (require pcomplete): Only when compiling.
+
+2002-11-19 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el 1.29:
+ erc-track-faces-priority-list: New variable, defines what faces will
+ be shown in the modeline. If set to nil, the old behavior ("all")
+ remains.
+ erc-track-face-more-important-p: new function
+ erc-track-find-face: new function
+
+2002-11-19 Alex Schroeder <alex@gnu.org>
+
+ * erc-fill.el 1.20 (erc-stamp): Require it.
+
+ * erc-match.el 1.16 (away): devar for the compiler.
+
+ * erc-stamp.el 1.16 (stamp): Moved.
+
+ * erc.el 1.329 (erc-version-string): New version.
+
+ * erc-autoaway.el 1.7 (erc-autoaway-idletimer): Moved to the front of
+ the file.
+
+ * erc-auto.in 1.2: (generated-autoload-file, command-line-args-left):
+ Added defvar without value to silence byte compiler.
+
+ * Makefile 1.7 (realclean): renamed fullclean to realclean.
+ (UNCOMPILED): New list, for erc-bbdb.el, erc-ibuffer.el,
+ erc-speak.el.
+ (SOURCE): Do not compile UNCOMPILED.
+ (release): New target.
+ (ChangeLog): New target.
+ (todo): New target.
+
+ * erc-complete.el 1.12 (erc-match): Require it.
+ (hippie-exp): Require it.
+
+ * erc-ezbounce.el 1.3 (erc): Require it.
+
+ * erc-imenu.el 1.4 (imenu): Require it.
+
+ * erc-nickserv.el 1.7 (erc-networks): Moved up.
+
+ * erc-notify.el 1.7 (pcomplete): Require it.
+
+ * erc-replace.el 1.5 (erc): Require it.
+
+ * erc-sound.el 1.3 (sound): Typo -- define-key in erc-mode-map.
+
+ * erc-speedbar.el 1.10 (dframe): Require it.
+ (speedbar): Require it.
+
+ * erc-track.el 1.28 (erc-default-recipients): devar for the compiler.
+
+ * README 1.1: New file.
+
+2002-11-18 Mario Lang <mlang@delysid.org>
+
+ * AUTHORS 1.1: File needed for mkChangeLog
+
+ * mkChangeLog 1.1: Original code by mhp
+
+2002-11-18 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.32 (erc-button-list): Renamed to erc-list and moved
+ to erc.el.
+
+ * erc.el 1.328 (erc-list): New.
+
+ * erc-track.el 1.27 (erc-make-mode-line-buffer-name): Simplified.
+ (erc-modified-channels-display): Simplified. Now works with all
+ faces, and fixes the bug that when two faces where used (bold
+ erc-current-nick-face), then no faces was added.
+
+ * erc-track.el 1.26: Lots of new tests. Moved some defuns around in
+ the file.
+ (erc-all-channel-names): Renamed.
+ (erc-all-buffer-names): New name, now include query buffers as
+ well.
+ (erc-modified-channels-update-inside): New variable.
+ (erc-modified-channels-update): Use it to prevent running display
+ if already inside it. This prevented debugging of
+ `erc-modified-channels-display'.
+ (erc-make-mode-line-buffer-name): Moved.
+ (erc-track-shorten-names): Don't test using erc-channel-p as that
+ failed with query buffers.
+ (erc-unique-substrings): Move setq i + 1 to the end of the while
+ loop, so that start is used as a default value instead of start +
+ 1.
+
+2002-11-18 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el 1.25:
+ erc-unique-substrings: define this before using it in assert
+
+ * erc.el 1.327:
+ with-erc-channel-buffer: Define *before* using this macro. This
+ hopefully fixes a bug noted on IRC.
+
+ * erc-notify.el 1.6:
+ erc-notify-signon-hook, erc-notify-signoff-hook: New hooks. They're
+ even run when their name suggests!
+
+2002-11-18 Alex Schroeder <alex@gnu.org>
+
+ * erc-list.el 1.7: Typo.
+
+ * erc-speedbar.el 1.9: Whitespace only.
+
+ * erc.el 1.326 (define-erc-module): Avoid defining an alias if name and
+ alias are the same.
+
+ * erc-ibuffer.el 1.17: URL
+
+ * erc-imenu.el 1.3 (erc-imenu-version): New constant.
+
+ * erc-ibuffer.el 1.16 (erc-ibuffer-version): New constant.
+
+ * erc-ibuffer.el 1.15: File header, comments.
+
+ * erc-fill.el 1.19 (erc-fill-version): New constant.
+
+ * erc-ezbounce.el 1.2 (erc-ezb-version): New constant.
+
+ * erc-complete.el 1.11 (erc-complete-version): New constant.
+
+ * erc-chess.el 1.21 (erc-chess-version): New constant.
+
+ * erc-chess.el 1.20: Whitespace only.
+
+ * erc-bbdb.el 1.20 (erc-bbdb-version): Typo.
+
+ * erc-bbdb.el 1.19 (erc-bbdb-version): New constant.
+ Lots of whitespace changes. Changes to the header.
+
+ * erc-track.el 1.24 (erc-track-shorten-aggressively): Doc.
+ (erc-all-channel-names): New function.
+ (erc-unique-channel-names): New function.
+ (unique-substrings): Renamed.
+ (erc-unique-substrings): New name
+ (unique-substrings-1): Renamed.
+ (erc-unique-substring-1): New name. Added lots of tests.
+ (erc-track-shorten-names): Call erc-unique-channel-names instead
+
+ * erc-match.el 1.15 (match): Rewrote a as module.
+
+2002-11-17 Alex Schroeder <alex@gnu.org>
+
+ * erc-netsplit.el 1.6 (erc-netsplit-version): New.
+ (netsplit): Defined as a module, replacing erc-netsplit-initialize
+ and erc-netsplit-destroy.
+
+2002-11-17 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el 1.23 (erc-track-switch-buffer):
+ define-erc-module defines erc-track-mode,
+ not erc-track-modified-channels-mode.
+
+ * erc.el 1.325:
+ Variables erc-play-sound, erc-sound-path, erc-default-sound,
+ erc-play-command, erc-ctcp-query-SOUND-hook and functions
+ erc-cmd-SOUND, erc-ctcp-query-SOUND, erc-play-sound, erc-toggle-sound
+ moved to erc-sound.el
+
+ Variables erc-page-function, erc-ctcp-query-PAGE-hook and function
+ erc-ctcp-query-PAGE moved to erc-page.el
+
+ * erc-page.el 1.1:
+ erc-page.el: New file. CTCP PAGE support for ERC, extracted from erc.el.
+
+ * erc-sound.el 1.2:
+ defin-erc-module: Typo. Autoload should do erc-sound-mode and "erc-sound".
+
+ * erc-sound.el 1.1:
+ erc-sound.el: New file. Contains all the CTCP SOUND stuff from erc.el.
+
+ * erc.el 1.324 (erc-process-ctcp-request):
+ Removed (old-style CTCP handling)
+ (erc-join-autogreet): Removed (was broken anyways)
+
+2002-11-17 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.31 (erc-button-version): New constant.
+
+ * erc-button.el 1.30 (button): rewrote as a module.
+
+2002-11-17 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.323: New functions:
+ (erc-event-to-hook), (erc-event-to-hook-name): Convert an event to the
+ corresponding hook. The latter only returns the name, while the former
+ interns the hook symbol and returns it.
+
+2002-11-17 Alex Schroeder <alex@gnu.org>
+
+ * erc-replace.el 1.4:
+ Practically total rewrite. All smiley stuff deleted.
+
+ * erc-track.el 1.22 (track): typo.
+
+ * erc.el 1.322 (define-erc-module): Doc change.
+
+2002-11-17 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-autoaway.el 1.6: Changed to use define-erc-module.
+
+ * erc.el 1.321 (define-erc-module):
+ Make the enable/disable functions interactive.
+
+ * erc.el 1.320 (erc):
+ Don't use switch-to-buffer when we're in the minibuffer,
+ because that does not work. Use display-buffer instead. This leaves
+ two problems: The point does not advance to the end of the buffer for
+ whatever reason, and after leaving the minibuffer, the new window gets
+ buried.
+
+2002-11-17 Alex Schroeder <alex@gnu.org>
+
+ * erc-stamp.el 1.15 (stamp): Doc change.
+
+ * erc-stamp.el 1.14 (erc-stamp-version): New constant.
+ (stamp): downcase alias name of the mode.
+
+ * erc.el 1.319 (define-erc-module): Added defalias option, renamed
+ parameters again.
+
+ * erc-track.el 1.21: erc-track-modified-channels-mode is now only an
+ alias to erc-track-mode. Only erc-track-mode is autoloaded.
+ (track): Rewrote call to define-erc-module.
+
+2002-11-16 Mario Lang <mlang@delysid.org>
+
+ * debian/README.Debian 1.5: * Spelling fix
+
+ * erc-fill.el 1.18: * Fix autoload definition for erc-fill-mode
+
+ * debian/control 1.6, debian/maint/postinst 1.4, debian/maint/prerm 1.4:
+ * Remove /usr/doc -> /usr/share/doc link handling
+
+ * debian/changelog 1.18: * Sync with reality
+
+ * debian/scripts/startup.erc 1.2:
+ * Add /usr/share/emacs/site-lisp/erc/ to load-path
+ * (load "erc-auto")
+
+ * debian/README.Debian 1.4:
+ * Info about the changes since last release updated
+
+ * erc-pcomplete.el 1.11: * Fix emacs/xemacs compatibility
+
+ * debian/scripts/install 1.10: * Dont compile erc-compat, fix ELCDIR
+
+ * debian/control 1.5: * Change maintainer field
+
+ * erc.el 1.318:
+ * (defin-erc-module): Renamed argument mode-name to mname because silly byte-compiler thought we were talking about `mode-name'.
+
+ * Makefile 1.6: * Added debrelease target
+
+ * erc-bbdb.el 1.18, erc-pcomplete.el 1.10, erc-stamp.el 1.13, erc.el 1.317:
+ * (define-erc-module): Added mode-name argument.
+ * Converted erc-bbdb, erc-pcomplete and erc-stamp to new macro.
+ * autoload fixes
+
+ * erc-bbdb.el 1.17:
+ * Create a global-minor-mode (i.e., make it a proper erc-module)
+
+ * erc.el 1.316: * (define-erc-modle): New defmacro
+
+2002-11-16 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-autoaway.el 1.5 (erc-autoaway-idle-seconds):
+ t in docstrings should be non-nil
+
+2002-11-16 Alex Schroeder <alex@gnu.org>
+
+ * erc-autoaway.el 1.4, erc-button.el 1.29, erc-fill.el 1.17, erc-match.el 1.14,
+ erc-menu.el 1.9, erc-ring.el 1.5, erc-track.el 1.20:
+ Cleanup of file headers: copyright years, GPL mumbo-jumbo, commentaries.
+
+ * erc-stamp.el 1.12 (erc-insert-away-timestamp-function):
+ New custom type.
+ (erc-insert-timestamp-function): New custom type.
+
+ * erc-fill.el 1.16 (erc-fill-function): Doc, new custom type.
+ (erc-fill-static): Doc.
+ (erc-fill-enable): New function.
+ (erc-fill-disable): New function.
+ (erc-fill-mode): New function.
+
+ * erc-match.el 1.13 (erc-match-enable): add-hook for both
+ erc-insert-modify-hook and erc-send-modify-hook.
+ (erc-match-disable): remove-hook for both
+ erc-insert-modify-hook and erc-send-modify-hook.
+
+2002-11-15 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-autoaway.el 1.3:
+ - Added a way to use auto-away using emacs idle timers
+ - Renamed erc-set-autoaway to erc-autoaway-possibly-set-away for consistency
+
+2002-11-14 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.315: erc-mode-map: Removed the C-c C-g binding for erc-grab
+
+ * erc.el 1.314:
+ (erc-server-341) Another instance of the channel/chnl problem i didn't
+ see last time
+
+2002-11-14 Alex Schroeder <alex@gnu.org>
+
+ * erc-compat.el 1.3 (erc-decode-coding-string): typo
+
+2002-11-14 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.313 (erc-server-341):
+ variable name should be chnl not channel, as it is
+ used this way in this function, and the other erc-server-[0-9]* use
+ chnl too.
+
+ * erc-autoaway.el 1.2:
+ Set back on all servers, not just the current one, since we're set
+ away on all servers as well.
+
+ * HISTORY 1.2: Fixed typo (ngu.org => gnu.org)
+
+ * erc-autoaway.el 1.1, erc-fill.el 1.15, erc.el 1.312: erc-autoaway.el:
+ * new file
+
+ erc.el:
+ * Removed auto-discard-away facility (now included in erc-autoaway.el)
+ * (erc-away-p): new function
+
+ erc-fill.el:
+ * (erc-fill-variable): Check wether erc-timestamp-format is bound before
+ using it (erc-fill.el does not require erc-stamp).
+
+2002-11-10 Alex Schroeder <alex@gnu.org>
+
+ * TODO 1.4:
+ TODO: moved it to http://www.emacswiki.org/cgi-bin/wiki.pl?ErcTODO
+
+ * erc.el 1.311 (with-erc-channel-buffer): Rudimentary doc string.
+
+2002-11-09 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.28 (erc-nick-popup-alist): Made a defcustom.
+
+ * erc-button.el 1.27 (erc-button-disable): New function.
+ (erc-button-enable): New function, replaces the add-hook calls at top-level.
+ (erc-button-mode): New minor mode.
+
+2002-11-08 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.26 (erc-button-entry): Use erc-button-syntax-table.
+
+ * erc.el 1.310, erc-stamp.el 1.10: Doc changes.
+
+ * erc-match.el 1.12 (erc-match-mode): New function, replacing the
+ add-hook.
+ (erc-match-enable): New function.
+ (erc-match-disable): New function.
+ (erc-current-nick-highlight-type): Changed from 'nickname to 'nick
+ to make it consistent with the others.
+ (erc-match-message): Ditto.
+
+ * erc-button.el 1.25 (erc-button-syntax-table): New variable.
+ (erc-button-add-buttons): Use it.
+
+2002-11-06 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.309:
+ 1) (bug) ERC pops up a new buffer and window when being messaged
+ from an ignored person. fixed
+ 2) (misfeature) ERC notices the user in the minibuffer when it
+ ignores something - this can get very annoying, since the
+ minibuffer is also visible when not looking at ERC buffers.
+ Added a customizeable variable for this, the default is nil.
+ 3) (wishlist) There is no IGNORE or UNIGNORE command.
+ Added.
+ 4) (wishlist) Some IRC clients, notably irssi, allow the user to
+ ignore "replies" to ignored people. A reply is defined as a
+ line starting with "nick:", where nick is the nick of an
+ ignored person. Added that functionaly.
+ Done by Jorgen Schaefer <forcer@forcix.cx>
+
+2002-11-02 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.308 (erc-connect): set-process-coding-system to raw-text.
+
+2002-11-01 Brian P Templeton <bpt@tunes.org>
+
+ * erc-pcomplete.el 1.9, erc-stamp.el 1.9, erc-track.el 1.19:
+ Fixed more autoloads
+
+ * erc-compat.el 1.2: Added autoload for erc-define-minor-mode
+
+2002-11-01 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.307: * (erc-send-command): will break long messages into
+ a bunch of smaller ones, to prevent them from being truncated by the server.
+ The patch also axes some trailing whitespace. :-) <resolve>
+
+2002-10-31 Alex Schroeder <alex@gnu.org>
+
+ * erc-pcomplete.el 1.8 (erc-compat): Require.
+ (erc-completion-mode): Use erc-define-minor-mode.
+
+ * erc-track.el 1.18 (erc-compat): Require.
+ (erc-track-modified-channels-mode): Use erc-define-minor-mode.
+
+ * erc-stamp.el 1.8 (erc-compat): Require.
+ (erc-timestamp-mode): Use erc-define-minor-mode.
+
+ * erc-compat.el 1.1: New file with the code for erc-define-minor-mode,
+ erc-encode-coding-string and erc-decode-coding-string. Essentially
+ all the stuff that cannot be tested for using a simple boundp or
+ fboundp -- eg. because the number of arguments are wrong.
+
+ * erc.el 1.306 (erc-compat): Require.
+ (erc-process-coding-system): Moved to erc-compat.el.
+ (erc-connect): Do not set-process-coding-system.
+ (encode-coding-string): Compatibility code moved to erc-compat.el.
+ (decode-coding-string): Compatibility code moved to erc-compat.el.
+ (erc-encode-coding-string): Compatibility code moved to erc-compat.el.
+ (erc-decode-coding-string): Compatibility code moved to erc-compat.el.
+
+2002-10-27 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.305 (erc-display-line-1): Removed call to
+ erc-decode-coding-string.
+ (erc-parse-line-from-server): Added call to
+ erc-decode-coding-string before anything gets parsed at all.
+ (erc-decode-coding-string): Use undecided coding system.
+
+2002-10-24 Sandra Jean Chua <sacha@free.net.ph>
+
+ * erc-button.el 1.24, erc.el 1.304:
+ Added LASTLOG command and action for nick-button
+
+2002-10-22 Sandra Jean Chua <sacha@free.net.ph>
+
+ * erc-pcomplete.el 1.7:
+ Fixed nopruning bug, added /MODE channel (mode) [nicks...] completion - mode not completed yet.
+
+2002-10-16 Sandra Jean Chua <sacha@free.net.ph>
+
+ * erc-pcomplete.el 1.6:
+ Fixed 'Hi delysid:' bug in SAY completion after realizing that pcomplete on commands already took care of completing the initial nick:
+
+2002-10-15 Mario Lang <mlang@delysid.org>
+
+ * erc-pcomplete.el 1.5: update from sachac
+
+2002-10-13 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.303 (erc-emacs-time-to-erc-time): Catch when tm is nil.
+
+2002-10-11 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.302:
+ * Fixed `erc-scroll-to-bottom' to scroll to the bottom even when
+ in the middle of a line. Might also fix the Magic ECHAN Bug[tm]. (-:
+
+2002-10-11 Mario Lang <mlang@delysid.org>
+
+ * erc-nickserv.el 1.6: Fixed erc-networks for the opn->freenode change
+
+2002-10-08 Mario Lang <mlang@delysid.org>
+
+ * erc-pcomplete.el 1.4:
+ Make erc-completion-mode work interactively with already joined channel buffers
+
+ * erc-chess.el 1.19: Add autoload cookies
+
+ * erc-notify.el 1.5: Add pcomplete support
+
+ * erc.el 1.301:
+ Remove autoload statments, remove autoload cookie from erc-mode and erc-info-mode
+
+ * erc-fill.el 1.14, erc-match.el 1.11: add/remove autoload cookies
+
+2002-10-06 Alex Schroeder <alex@gnu.org>
+
+ * erc-pcomplete.el 1.3 (erc-completion-mode): New global minor mode
+ with autoload cookie.
+ (erc-pcomplete-enable): Renamed erc-pcomplete-initialize.
+ (erc-pcomplete-disable): New function.
+
+ * erc-complete.el 1.10: Doc changes.
+
+ * erc-stamp.el 1.7 (erc-stamp-enable): Renamed erc-stamp-initialize.
+ (erc-stamp-disable): Renamed erc-stamp-destroy.
+ (erc-timestamp-mode): Use new names.
+
+ * erc.el 1.300: Removed autload for erc-complete and
+ erc-track-modified-channels-mode -- the autoload cookie should do
+ that instead.
+ (erc-input-message): Doc string, removed binding for erc-complete.
+ (erc-mode-map): Removed binding for erc-complete.
+
+2002-10-03 Mario Lang <mlang@delysid.org>
+
+ * erc-notify.el 1.4:
+ New functions erc-notify-JOIN and erc-notify-QUIT to catch some common cases (warning, untested)
+
+2002-10-01 Alex Schroeder <alex@gnu.org>
+
+ * erc-stamp.el 1.6 (erc-timestamp-mode): New function. Removed call
+ to erc-stamp-initialize at the end.
+
+2002-09-25 Brian P Templeton <bpt@tunes.org>
+
+ * erc.el 1.299:
+ Added customizable `erc-process-coding-system' variable.
+
+2002-09-22 Brian P Templeton <bpt@tunes.org>
+
+ * erc-fill.el 1.13:
+ `erc-fill-variable' now does the right thing when `erc-hide-timestamps' is non-nil
+
+2002-09-21 Mario Lang <mlang@delysid.org>
+
+ * erc-fill.el 1.12:
+ patch from Peter Solodov <peter@alcor.concordia.ca> (note, its slightly broken still
+
+2002-09-05 Mario Lang <mlang@delysid.org>
+
+ * erc-pcomplete.el 1.2: Added LEAVE as alias for PART
+
+2002-09-04 Mario Lang <mlang@delysid.org>
+
+ * erc-pcomplete.el 1.1:
+ By sachac (good work!) keep up doing such things
+
+2002-08-31 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.298:
+ A fix for Bug#133267: now you can put (erc-save-buffer-in-logs) on erc-insert-post-hook to save *every* incoming message.
+
+2002-08-30 Brian P Templeton <bpt@tunes.org>
+
+ * erc.el 1.297:
+ Changed default value of erc-common-server-suffixes because of the OPN
+ name change
+
+2002-08-28 Mario Lang <mlang@delysid.org>
+
+ * erc-stamp.el 1.5: Try to reactivate isearch in xemacs
+
+ * erc-stamp.el 1.4:
+ fixes issues related to comparative emacsology and a silly bug
+
+2002-08-27 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.296:
+ New hook erc-send-completed-hook (for robot stuff), changed alexanders email address to reflect reality, little fix to erc-auto-query to get a bit of a speedup
+
+2002-08-22 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.23:
+ Fixed case-fold-search (thanks sachac), now lambda works in erc-button-alist, added wardwiki+google+symvar+rfc+itime regexps from the wiki
+
+2002-08-19 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.22:
+ erc-nick-popup-alist: New variable to make erc-nick-popup configurable
+
+2002-08-16 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.21 (erc-recompute-nick-regexp): Fixed regexp.
+
+ * erc-button.el 1.20 (erc-button-buttonize-nicks): Changed custom type
+ to integer.
+ (erc-button-add-buttons): Moved button removal code to new
+ function.
+ (erc-button-remove-old-buttons): New function.
+ (erc-button-add-button): Removed use of overlays and used
+ erc-button-add-face instead.
+ (erc-button-add-face): New function to merge faces as text
+ properties. This should be much faster when lots of buttons
+ appear.
+ (erc-button-list): New helper function.
+
+ * erc.el 1.295 (erc-display-message): Fixed argument list.
+ (erc-display-prompt): Reduced calls to length, use start-open
+ property for XEmacs to prevent a little box of erc-prompt-face at
+ the end of messages other people send.
+ (erc-refresh-channel-members): Fix XEmacs calls to split-string,
+ which may return an empty string at the end of the list. This
+ would cause hangups in erc-button in re-search-forward loops.
+ (erc-get-channel-mode-from-keypress): Replaced control codes with
+ octal escape sequences.
+
+2002-08-14 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.19:
+ Try to be compatible to XEmacs regexp-opt. (Im going to quit this job if I find more of those damn differencies
+
+ * debian/README.Debian 1.3, debian/scripts/install 1.9:
+ * Added info to README.Debian
+ * Finished debian/scripts/install
+
+2002-08-13 Mario Lang <mlang@delysid.org>
+
+ * debian/scripts/install 1.8: First attempt to fix it
+
+ * debian/README.Debian 1.2, debian/changelog 1.17, debian/scripts/install 1.7:
+ changelog: Changed maintainer and added new entry
+ README.Debian: Re-explained the byte-compile issue
+ scripts/install: Exclude erc-bbdb|chess|ibuffer|speedbar from
+ byte-compiling
+
+ * erc-track.el 1.17: Added C-c C-SPC in addition to C-c C-@
+
+ * erc-notify.el 1.3: Little docstring change
+
+2002-08-09 Mario Lang <mlang@delysid.org>
+
+ * erc-stamp.el 1.3:
+ Change one use of set-text-properties to add-text-properties (tnx Lathi)
+
+2002-08-02 Mario Lang <mlang@delysid.org>
+
+ * erc-stamp.el 1.2: added erc-timestamp-only-if-changed-flag
+
+2002-07-22 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.294:
+ Removed timestamp related code and moved into erc-stampe.l
+
+ * erc-stamp.el 1.1:
+ Timestamping code moved out of erc.el. Additional, now we can timestamp either on the left or on the right side
+
+2002-07-16 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.293:
+ * Make ctcp ping return its message in the active buffer, instead of the server buffer
+ * Corrected minimal typo in catalog
+ * Added var and variable as alias for /set
+
+2002-07-08 Mario Lang <mlang@delysid.org>
+
+ * erc-track.el 1.16:
+ * New function erc-track-switch-buffer (by resolve)
+ Bound to C-c C-SPC, enjoy!
+
+2002-07-08 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.16: New snapshot deb
+
+ * debian/scripts/install 1.6: Rewrote in make.
+ Does not byte-compile erc-speak.el at all, and excludes erc-track.el too, if
+ ran for xemacs.
+
+ * debian/control 1.4: Added dependency on make
+
+ * debian/copyright 1.2: Updated copyright info
+
+ * debian/rules 1.10: Use $(wildcard *.el) instead of a hardcoded list
+
+2002-07-03 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el 1.292:
+ erc-iswitchb now works correctly if erc-modified-channels-alist is non-nil
+
+2002-07-01 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-menu.el 1.8:
+ * changed how we check if we should activate "Track hidden channels" and
+ whether it should be selected - fixes a bug Xemacs where whole menu bar
+ does not work if menu is loaded
+
+ * erc-menu.el 1.7:
+ * added "Disconnect from server", only selectable if erc-connected is non-nil
+
+ * topic is allowed to be set by normal users if channel mode is not +t
+
+ * add " ..." after description if arguments needed after selecting menu item
+
+ * only allow selecting of menu points needing a channel if current buffer is
+ a channel buffer - done by testing if channel-members is non-nil
+
+ * put erc-match functions in new group "Pals, fools and other keywords"
+
+ * erc.el 1.291:
+ * moved definition of erc-show-my-nick to GUI variables section
+
+ * erc-connected variable now defined with defvar
+ now set in channel and query buffers, was only in server buffer before
+ upon disconnect, set erc-connected to nil in all the server's buffers
+
+ * added erc-cmd-GQUIT and its alias erc-cmd-GQ - quit all servers at once
+
+ * added interactive function erc-quit-server, bound to C-c C-q
+
+ * added erc-server-WALLOPS
+
+ * added WALLOPS to english catalog, fixed s461 (was showing message twice)
+
+ * typo fixes, spacing change
+
+2002-06-29 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.290: Use pp-to-string in /set (without args)
+
+ * erc-netsplit.el 1.5:
+ Make /set anonymous-lign set erc-anonymous-login, also report
+ which var was set to which val.
+
+2002-06-28 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-menu.el 1.6: added "Customize ERC"
+
+2002-06-25 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.289: New variable: erc-use-info-buffers, defaults to nil.
+ This prevents info-buffers from being created/updated.
+ Set to t if you use :INFO buffers.
+ (by rw)
+ Delete (erc-display-prompt) from reconnect to avoid clutter
+
+2002-06-23 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el 1.288:
+ erc-get-channel-mode-from-keypress is now bound to C-c C-m
+ erc-insert-mode-command is taken care of by this function as well
+
+2002-06-21 Mario Lang <mlang@delysid.org>
+
+ * erc-track.el 1.15:
+ Fixed bug where buffer-names suddenly had text-properties.
+
+2002-06-19 Diane Murray <disumu@x3y2z1.net>
+
+ * Makefile 1.5: changed erc-auto.el to $(SPECIAL) in make fullclean
+
+ * Makefile 1.4: remove erc-auto.el on make fullclean
+
+2002-06-18 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-match.el 1.10: fixed spelling error
+
+ * erc-track.el 1.14, erc-match.el 1.9: * erc-match.el:
+ highlight current nickname in its own face (deactivated by default):
+ - added erc-current-nick-highlight-type, erc-current-nick-face,
+ erc-current-nick-p
+
+ * erc-track.el:
+ added support for erc-current-nick-face
+
+2002-06-17 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el 1.287: * added beginning suport for 005 numerics:
+ - added buffer local variable erc-server-parameters
+ - added erc-server-005, which sets erc-server-parameters if the server has
+ used this code to show its parameters
+
+2002-06-16 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el 1.286:
+ * bugfix: when pasting lines with blank lines in between, remove the blank lines
+ but send the rest
+
+ * since we know the command, use it when checking what's in erc-hide-list
+ added check to erc-server-KICK
+
+ * added some blank lines for better readability
+
+2002-06-16 Alex Schroeder <alex@gnu.org>
+
+ * erc-nickserv.el 1.5 (erc-nickserv-alist): Fixed typo.
+
+2002-06-15 Alex Schroeder <alex@gnu.org>
+
+ * erc-nickserv.el 1.4 (erc-networks): Added doc string.
+ (erc-nickserv-alist): Added doc string.
+
+2002-06-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-ring.el 1.4:
+ fixed bug so that the prompt and command always get put at the end of the buffer
+
+2002-06-10 Mario Lang <mlang@delysid.org>
+
+ * erc-nickserv.el 1.3: Added iip support.
+ Added :type for erc-nickserv-passwords custom.
+ Fixed hook usage.
+
+2002-06-07 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nickserv.el 1.2: * added GalaxyNet
+
+ * erc-nickserv-alist:
+ - sorting networks alphabetically
+ - added two more pieces of information in erc-nickserv-alist:
+ word to use for identification and whether to use the nickname
+
+ * erc-current-network:
+ - made regex case insensitive, downcase server to match
+ - uses the new information
+ - now uses new variable erc-networks instead of doing checking manually
+
+ * added variable erc-networks
+
+ * fixed some indentation, documentation
+
+2002-06-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.285: Fix for kill-buffer hook stuff
+
+2002-06-06 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.284: Added /squery command
+
+2002-06-06 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-menu.el 1.5: * made group Channel modes
+ - moved change mode and invite only mode to here
+ - added secret, moderated, no external send, topic lock, limit, key
+
+ * check that user is in a channel buffer and user is a channel operator
+ for all op-related actions
+
+ * "Identify to nickserv" needs erc-nickserv-identify defined
+
+ * added "Show ERC version"
+
+ * erc.el 1.283:
+ * added erc-set-channel-limit, erc-set-channel-key, erc-toggle-channel-mode
+
+ * added erc-get-channel-mode-from-keypress, which is binded to C-c m
+ sends the next character which is typed to one of the 3 new functions
+ - did not remove erc-invite-only-mode and it's key binding in case
+ people are used to it, although it probably should be removed...
+
+ * in erc-server-MODE:
+ added check if tgt equal to user's nick
+ removed erc-display-line, only using the erc-display-message
+
+ * added s461 to english catalog
+
+ * fixed bug where Xemacs would not quit if erc-quit-reason was
+ set to erc-quit-reason-various and assoc-default was not defined
+
+2002-06-04 Andreas Fuchs <asf@void.at>
+
+ * erc-ezbounce.el 1.1, erc-match.el 1.8:
+ * erc-ezbounce.el: Added. Provides support for ezbouncer; automatic login,
+ session management implemented. I've contacted the author
+ about stuff in EZBounce's logging.
+ * erc-match.el: Fixed a stupid mistake where
+ "*** Your new nick is <foo>" would trigger an error.
+
+2002-06-04 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nickserv.el 1.1, erc.el 1.282: * added erc-nickserv.el
+ * moved nickserv identification variables and functions to the new file
+ (require 'erc-nickserv) is now necessary for this to work
+
+ * erc.el 1.281:
+ * results of /COUNTRY now formatted as notice; errors are ignored,
+ fixing
+ bug which made prompt disappear
+
+ * added undefined-ctcp error message to english catalog
+
+ * changed some (when (not erc-disable-ctcp-replies) to use unless instead
+ and some if's without else statments to use when or use
+
+ * CTCP replies now use erc-display-message, formatted as notices
+
+ * added following to english catalog:
+ - undefined-ctcp
+ - CTCP-CLIENTINFO, CTCP-ECHO, CTCP-FINGER, CTCP-PAGE, CTCP-PING,
+ CTCP-SOUND, CTCP-TIME, CTCP-UNKNOWN, CTCP-VERSION
+ - s303, s305, s306, s353
+
+ * split erc-server-305-or-306 into erc-server-305 and erc-server-306
+
+ * KICK already had buffer set, using it
+
+ * erc.el 1.280:
+ * erc-format-timestamp now only called from erc-display-message and
+ erc-send-current-line
+
+ * all instances of erc-display-line with erc-highlight-error
+ changed to use erc-display-message
+
+ * added following error messages to english catalog:
+ bad-ping-response, bad-syntax, cannot-find-file, cannot-read-file,
+ ctcp-request, flood-ctcp-off, flood-strict-mode, no-default-channel,
+ no-target, variable-not-bound
+
+ * added following server related messages to english catalog:
+ s324, s329, s331, s332, s333, s341, s406, KICK, KICK-you, KICK-by-you, MODE-nick
+
+ * ignoring server codes 315, 369
+
+ * added erc-server-341, erc-server-406
+
+ * channel topic and mode notices displayed in respective channel buffers if they
+ exist
+
+ * erc-server-KICK: display the message before removing this channel so that we
+ can track the kick
+
+ * send parsed to erc-ctcp-query-ACTION-hook so that actions can be checked
+ by erc-match
+
+ * fixed bug where nil was shown if no reason was given by users on /PART
+
+2002-06-03 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-match.el 1.7:
+ * fixed bug where erc-log-matches produced an error when the value of
+ (erc-default-target) was not a channel
+ * use erc-format-timestamp, if it's non-nil, for %t in erc-log-match-format
+
+2002-06-01 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-button.el 1.18:
+ * made action case insensitive in erc-nick-popup and added a more descriptive
+ error message
+
+2002-05-30 Brian P Templeton <bpt@tunes.org>
+
+ * erc.el 1.279:
+ Removed multiple calls of `erc-prompt' in `erc-display-prompt'
+
+2002-05-29 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.278:
+ First step timestampkiller cleanup. I'm tired, do the rest tomorrow.
+
+ * erc.el 1.277:
+ New functionality: Catch channel/server buffer kills through kill-buffer-hook.
+ Currently, it only does a PART if you kill a channel buffer.
+
+2002-05-28 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.276:
+ defvar'ed some buffer-local variables to make elint at least a bit more happy.
+ Moved comments into docstrings.
+ Changed some instances of member to memq.
+
+ * erc-track.el 1.13, erc.el 1.275:
+ erc.el: (erc-message-type-member): New function, used to test
+ for message type. Require erc-parsed text-property.
+ erc-track.el: erc-track-exclude-types: New variable. Defaults to ("JOIN" "PART") right now for testing, it should eventually set to nil soon again.
+ (erc-track-modified-channels): Use above fun and var to optionally exclude certain message types from channel tracking.
+
+2002-05-28 Diane Murray <disumu@x3y2z1.net>
+
+ * CREDITS 1.5: added myself, vain as it sounds ;)
+
+2002-05-25 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.274: * Some small docstring fixes
+ * (erc-display-line): Now takes also a process object in the buffer argument.
+ Used for easy sending to the server buffer.
+ * Several places: Just pass proc, not (process-buffer proc)
+
+2002-05-24 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.273: Mostly docstring fixes/additions
+
+ * erc-netsplit.el 1.4: Doc fixes, and a new netjoin-done message.
+
+ * erc-fill.el 1.11: Doc fixes, erc-fill custom group, autoloads.
+
+ * erc-netsplit.el 1.3: Fix to erc-netsplit-timer.
+
+ * erc-netsplit.el 1.2: Fixed a silly typo
+
+ * erc-maint.el 1.1: is this really necessary?
+
+ * erc.el 1.272: Added new variable erc-hide-list.
+ It affects erc globally right now, and is used to hide certain IRC type messages like JOIN and PART.
+
+ * Makefile 1.3: Doh, I should really test this before checkin :)
+
+ * Makefile 1.2: Silly cut&paste bug fixed
+
+ * erc-list.el 1.6: Added autoload cookie
+
+ * erc-match.el 1.6: Added missing require erc.
+
+ * erc-notify.el 1.2: Autoload cookies and a -initialize function.
+
+ * erc-chess.el 1.18: Added autoload cookies
+
+ * Makefile 1.1: Finally, we have a Makefile.
+ Primarily used for autoload definition generation right now.
+
+ * erc-auto.in 1.1: First version.
+
+ * erc-track.el 1.12: Added autoload cookie
+
+ * erc-netsplit.el 1.1:
+ New module, used to autodetect and hide netsplits.
+ (Untested, no netsplit happened yet :) )
+
+ * erc-nets.el 1.3: Added some old code I once worked on.
+ Added autoload cookie
+
+2002-05-24 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-fill.el 1.10:
+ removed reference in documentation to old variable, changed it to the new one
+
+ * erc.el 1.271:
+ * added new function erc-connection-established which is called after receiving
+ end of MOTD (does nothing if it's been called before)
+
+ * added new hook erc-after-connect which is called from
+ erc-connection-established with the arguments server (the announced server)
+ and nick - which other arguments should be sent??
+
+ * added buffer variable erc-connected which is set to t the first time
+ erc-connection-established is called, set to nil again if we've been
+ disconnected
+
+ * set initial user mode
+ - added custom variable erc-user-mode which can be a string or a function
+ which returns a string
+ - new function erc-set-initial-user-mode gets called from
+ erc-connection-established
+
+2002-05-22 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el 1.270: fixed bug where prompt was missing after reconnect
+
+2002-05-21 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el 1.269:
+ in erc-nickserv-identify: if network is unknown, just use "Nickserv"
+
+ * erc.el 1.268: * fixed some typos
+
+ * timestamping
+ - ctcp request messages and replies now have timestamp
+ - timestamps in front of error messages now in timestamp face
+ - added timestamp to more error messages
+
+ * ctcp reply messages, server ping message updated
+
+ * added variable erc-verbose-server-ping - check this instead of erc-paranoid
+
+ * added whowas on no such nick:
+ - added variable erc-whowas-on-nosuchnick
+ - in erc-server-401 do WHOWAS if erc-whowas-on-nosuchnick is non-nil
+
+ * erc.el 1.267: forgot documentaion for erc-nickserv-alist
+
+ * erc.el 1.266: NickServ identification changed and enhanced:
+ - erc-nickserv-identify-autodetect now called from erc-server-NOTICE-hook
+ - now possible to identify automatically without prompt:
+ - added custom variables erc-prompt-for-nickserv-password and
+ erc-nickserv-passwords
+ - added erc-nickserv-alist containing the different networks' nickserv details
+ - added function erc-current-network to determine the network symbol
+ - fixed bug where identification on dalnet didn't work, because they now
+ require NickServ@services.dal.net
+ now sends to all NickServ with nick@server where possible
+
+2002-05-17 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-fill.el 1.9:
+ * filling with erc-fill-variable now works with custom defined fill width:
+ - changed erc-fill-column from defvar to defcustom
+ - in erc-fill-variable: set fill-column to value of erc-fill-column
+
+ * erc.el 1.265: erc.el:
+ * fixed bug where topic wasn't being set when chanel name was provided
+
+ erc-fill.el:
+ * filling with erc-fill-variable now works with custom defined fill width:
+ - changed erc-fill-column from defvar to defcustom
+ - in erc-fill-variable: set fill-column to value of erc-fill-column
+
+2002-05-16 John Wiegley <johnw@gnu.org>
+
+ * erc.el 1.264: whitespace fix
+
+2002-05-15 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el 1.263:
+ * added explanation of empty string working in erc-quit-reason-various-alist
+ * removed the text property from erc-send-message, it caused problems
+ with /SV (as noticed by gbvb on IRC) and is obviously not needed
+ * when receiving a ctcp query, convert type to uppercase to allow for
+ "/ctcp nick time" and not just "/ctcp nick TIME"
+ * timestamp in front of server notices now shown in the timestamp face
+
+2002-05-13 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el 1.262:
+ - in erc-format-privmessage: `erc-format-timestamp' added to message after
+ message's text properties are applied so that it doesn't lose its face
+
+ - /quit without reason now works when `erc-quit-reason' is set to
+ `erc-quit-reason-various' and the empty string "" is defined in
+ `erc-quit-reason-various-alist'
+
+2002-05-13 Andreas Fuchs <asf@void.at>
+
+ * erc-bbdb.el 1.16:
+ * Applied Drewies patch to pop-up on nick changes when -popup-type is 'visible
+
+2002-05-12 Andreas Fuchs <asf@void.at>
+
+ * erc-bbdb.el 1.15, erc.el 1.261:
+ * erc-bbdb.el: pop up the buffer on /whois when erc-bbdb-popup-type is 'visible
+ * erc.el: fix for empty quit reason problem by drewie.
+
+2002-05-12 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.260: disumu nick patch
+ - added erc-show-my-nick (default t)
+ if t, show nickname like <nickname>
+ if nil, only show a > character before the message
+ - added faces erc-nick-default-face and erc-nick-msg-face
+ - nicknames (channel, msgs, notices) are now in bold face by default
+ - the msg face matches the erc-direct-msg-face color
+
+2002-05-10 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.259 (erc-send-pre-hook): Doc change.
+
+ * CREDITS 1.4: Alexander L. Belikoff is confirmed original author.
+
+2002-05-10 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.258:
+ timestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumu
+
+2002-05-09 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.257: *** empty log message ***
+
+2002-05-06 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.256:
+ New var: erc-echo-notices-in-minibuffer-flag. defaults to t.
+
+2002-05-04 John Wiegley <johnw@gnu.org>
+
+ * TODO 1.3: *** empty log message ***
+
+2002-05-03 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.255: Copyright notice, version string updates.
+
+2002-05-02 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.254: Comment: dme is David Edmondson
+
+2002-05-01 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.253 (erc-warn-about-blank-lines): New option.
+ (erc-send-current-line): Use it.
+ (erc-quit-reason-various-alist): New option.
+ (erc-quit-reason): New option.
+ (erc-quit-reason-normal): New function.
+ (erc-quit-reason-zippy): New function.
+ (erc-quit-reason-various): New function.
+ (erc-cmd-QUIT): Use them.
+
+2002-04-30 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.252: Version 2.92
+
+ * erc.el 1.251 (erc-send-modify-hook): Default value is nil.
+
+2002-04-27 John Wiegley <johnw@gnu.org>
+
+ * erc.el 1.250:
+ Don't redisplay the prompt if the ERC buffer is no longer alive.
+
+2002-04-26 John Wiegley <johnw@gnu.org>
+
+ * erc.el 1.249:
+ Don't call `set-buffer' on old-buf unless the buffer is valid. It's
+ often not when separate frames are being used.
+
+2002-04-23 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.17: fixed up erc-nick-regexp
+
+2002-04-22 Brian P Templeton <bpt@tunes.org>
+
+ * erc.el 1.248:
+ `erc-prompt' may now be a function that returns a string (which is
+ used as the prompt). I don't use Customize but I think customization
+ of it may be broken if it's not a string.
+
+ There is a new `erc-prompt' function that returns the prompt as a
+ string (e.g., returning either the result of `(funcall erc-prompt)' or
+ `erc-prompt').
+
+ This allows for dynamic prompts, such as a LispWorks-like prompt, or
+ one containing simply the current channel name. It was requested by
+ Mojo Nichols (nick michols) in #emacs today, 21-Apr-2002; cf. the
+ #emacs logs at <URL:http://www.tunes.org/~nef/logs/emacs/02.04.21.
+
+2002-04-17 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.247:
+ fix erc-send-current-line to work on empty lines again (without sending the prompt)
+ Fix C-c C-t to not include the nick/time info
+ (both from antifuchs)
+
+ * erc-complete.el 1.9: Fix for xemacs elt behaviour
+
+2002-04-17 John Wiegley <johnw@gnu.org>
+
+ * erc-chess.el 1.17:
+ Added a missing arg in a call to erc-chess-handler.
+
+2002-04-15 John Wiegley <johnw@gnu.org>
+
+ * erc-chess.el 1.16: *** empty log message ***
+
+2002-04-14 John Wiegley <johnw@gnu.org>
+
+ * erc-chess.el 1.15: *** empty log message ***
+
+2002-04-12 John Wiegley <johnw@gnu.org>
+
+ * erc-chess.el 1.14: *** empty log message ***
+
+ * erc-chess.el 1.12: bug fixes
+
+ * erc-chess.el 1.11: *** empty log message ***
+
+2002-04-12 Mario Lang <mlang@delysid.org>
+
+ * erc-chess.el 1.6: change order.
+
+ * erc-chess.el 1.5: more fixing.
+
+ Now, the 'match question works. It sends an accept back.
+ But display popup doesnt work..
+
+ * erc-chess.el 1.4: fixup (still far from working)
+
+2002-04-11 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.246:
+ * Added :options entry for erc-mode-hook (erc-add-scroll-to-bottom)
+
+2002-04-11 John Wiegley <johnw@gnu.org>
+
+ * erc.el 1.245: remove trailing \n from any sent text
+
+ * servers.pl 1.2, erc-bbdb.el 1.14, erc-button.el 1.16, erc-chess.el 1.3,
+ erc-complete.el 1.8, erc-fill.el 1.8, erc-ibuffer.el 1.14, erc-list.el 1.5,
+ erc-match.el 1.5, erc-menu.el 1.4, erc-nets.el 1.2, erc-replace.el 1.3,
+ erc-speak.el 1.22, erc-speedbar.el 1.8, erc-track.el 1.11, erc.el 1.244:
+ clean whitespace
+
+ * erc.el 1.243: Replaced erc-scroll-to-bottom.
+
+2002-04-11 Mario Lang <mlang@delysid.org>
+
+ * erc-track.el 1.10:
+ try to fix behaviour when used with different frames.
+
+2002-04-09 Mario Lang <mlang@delysid.org>
+
+ * erc-chess.el 1.2:
+ fixup release, far from ready for real usage, but it appears to work.
+
+ * erc.el 1.242:
+ speed improvments based on elp-instrument-package RET erc- RET results
+
+ * erc-chess.el 1.1: initial version.
+ please test it
+ Get chess.el from johnw's cvs:
+ cvs -d:pserver:anonymous@alice.dynodns.net:/usr/local/cvsroot login
+ cvs -d:pserver:anonymous@alice.dynodns.net:/usr/local/cvsroot co chess
+
+ (as usual, blank password)
+
+ Add the resulting dir to your load-path and reqire erc-chess.
+
+ Usage: Just do /chess nickname
+ The remote end much use erc, as no other irc client I know of supports this ...
+
+ See erc-chess-default-display and maybe set it to chess-images or chess-ics1 if you prefer those over chess-plain.
+ Also, see erc-chess-user-full-name to set the name you use in chess games.
+
+2002-04-04 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.241: New hackery latenightwise
+
+ * erc.el 1.240: upupadowndowncase
+
+2002-04-04 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.15: Updated for the new snapshot
+
+ * debian/rules 1.9: Install README.Debian into the package
+
+ * debian/README.Debian 1.1: Initial check-in
+
+2002-04-04 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.239:
+ Fixed that /me in query buffers ended up in server buffer
+
+ * erc.el 1.238: * Implemented joining +k channels
+
+2002-03-14 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.237: New utility function: erc-channel-list
+ minor fix to erc-get-buffer. hopefully that helps shapr
+
+2002-03-12 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.236:
+ New /command: /QUOTE for sending directly to the IRC server
+ Removed erc-fill from erc-insert-modify-hook. To activate filling, simply customize that var.
+
+2002-03-09 Brian P Templeton <bpt@tunes.org>
+
+ * CREDITS 1.3: *** empty log message ***
+
+2002-03-09 Mario Lang <mlang@delysid.org>
+
+ * erc-complete.el 1.7:
+ New variable: erc-nick-completion-ignore-case. Defaults to t.
+
+ * erc-track.el 1.9:
+ * erc-track-shorten-name-function can now be set to nil to avoid treating of channel names at all.
+
+2002-03-06 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.14, debian/rules 1.8: update to new snapshot
+
+2002-03-06 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.235:
+ Fixed nasty bug which prevented channel limit from correctly display/handling
+
+ * erc-track.el 1.8: Made shortening code highly customizable.
+ Now, there is the variable erc-track-shorten-function which holds
+ a function which gets called with one argument, CHANNEL-NAMES, which is a list
+ of strings of the channel names.
+ It needs to return a list of strings of the same length with the modified values...
+
+ * erc-track.el 1.7:
+ Added erc-track-shorten-aggressively, default to nil
+ if it is set to t, erc will shorten a bit more.
+ if nil, erc will shorten the name only if it would get shorter than just
+ one char...
+
+ * erc-speak.el 1.21: added iirc to the abbreviation expansion list.
+
+ * erc-track.el 1.6:
+ Added customization variable: erc-track-use-faces. defaults to t.
+
+ * erc-track.el 1.5: *** empty log message ***
+
+ * erc-track.el 1.4:
+ experimental: Added face support to mode-line channel activity tracker.
+ Currently we use the faces used for indicating in the buffer (erc-pal-face for channels with pal acitivity...)
+
+2002-03-05 Mario Lang <mlang@delysid.org>
+
+ * erc-complete.el 1.6: * added docfixes (thanks ore)
+
+ * erc-track.el 1.3: Fixed channel-name reduction.
+ thanks again alex.
+ Renamed the vars to erc-track-opt-start and erc-track-opt-cutoff.
+
+ * erc.el 1.234: fixed another silly error
+
+ * erc-track.el 1.2: Implemented channel name shortening.
+ Vars erc-track-cutoff says: all channel names longer than this will be shortened.
+ Var erc-track-minimum-channel-length says: dont make names shorten than this.
+ (Thanks go out to kensanata for the nice unique-substrings utility function).
+
+ * erc.el 1.233: silly typo corrected
+
+ * erc.el 1.232: * erc.el 1.232: * New varialbe: erc-common-server-name-suffixes
+ This alist can be used to change the server names displayed in mode-line
+ to a shorter version..
+ * New function: erc-shorten-server-name (uses var above)
+ * Changed erc-prepare-mode-line to use erc-shorten-server-name.
+
+2002-02-25 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.231:
+ CTCP handling rewritten. Seems to work. please test and report probs.
+
+2002-02-24 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.230:
+ Fixed emacs20 backward compatibility (new defun/alias: erc-propertize)
+
+2002-02-22 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.15: *** empty log message ***
+
+2002-02-21 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.14, erc.el 1.229:
+ minor fixup related to read-only prompts and command renaming.
+
+2002-02-21 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.228: * modify `erc-remove-text-properties-region' to work.
+ Could even be a little faster now. (-:
+
+2002-02-21 Mario Lang <mlang@delysid.org>
+
+ * erc-ring.el 1.3:
+ fixed erc-replace-command to behave right when text is read-only.
+ Also, use erc-insert-marker and (point-max) now.
+
+ * erc.el 1.227: * Made erc-prompt read-only
+ * new function: erc-make-read-only. Can be used on erc-insert-post-hook and erc-send-post-hook to ensure read-only buffer text too
+
+2002-02-19 Mario Lang <mlang@delysid.org>
+
+ * erc-list.el 1.4: added comment to docstring
+
+ * erc-speak.el 1.20: minor updates, use erc-nick-regexp now
+
+ * erc.el 1.226:
+ ensure that erc-timer-hook is called inside the server-buffer.
+
+2002-02-19 Andreas Fuchs <asf@void.at>
+
+ * erc-match.el 1.4:
+ * Probably fixed the "number-char-or-marker-p: nil" bug.
+
+2002-02-19 Mario Lang <mlang@delysid.org>
+
+ * erc-notify.el 1.1: Initial release.
+
+ * erc.el 1.225: added #303 handling
+ moved timer and added an arg (erc-current-time)
+
+ * erc-list.el 1.3, erc.el 1.224:
+ slightly changed the erc-once-with-server-event macro
+
+ * erc-button.el 1.13: erc-button-alist: doc fix and custom type fix
+
+2002-02-18 Mario Lang <mlang@delysid.org>
+
+ * erc-list.el 1.2, erc.el 1.223: new macro: erc-once-with-server-event
+ erc-list.el: use it
+
+ * erc-match.el 1.3:
+ Minor fix related to hook call method change (-until-seccess now)
+
+ * erc.el 1.222: fixed ctcp behaviour abit (with auto-query on)
+
+ * erc-list.el 1.1: ChanList mode.
+ Load it, and type M-x erc-chanlist RET
+ Demonstrates how the new hook system can be nicely used.
+
+ * erc.el 1.221:
+ new hook: erc-default-server-hook. This one gets called if we dont have anything defined for a certain IRC server message.
+ New function: erc-default-server-handler. (used by above hook).
+ New function: erc-debug-missing-hooks: Used by above hook to save a list of unimplemented server messages.
+ New function: erc-server-buffer, erc-server-buffer-p.
+ Various places: use it.
+ Minor fixup.
+
+ * erc-button.el 1.12: fix regexp to not buttonize ~user@host hostnames
+
+2002-02-17 Mario Lang <mlang@delysid.org>
+
+ * erc-complete.el 1.5, erc.el 1.220: Eliminated erc-command-table
+ Upcased the command defuns (erc-cmd-join is now erc-cmd-JOIN)
+ Fixed erc-complete to not require erc-command-table.
+ Implemented erc-cmd-HELP
+ (You have to try that, its tooo coool!)
+ e.g. /help auto-q
+ fixed autoloads for erc-add-pal and so on to be interactive.
+
+2002-02-17 Andreas Fuchs <asf@void.at>
+
+ * erc-match.el 1.2:
+ * Fix unfunctional code in `erc-get-parsed-vector-type'.
+
+ * erc-bbdb.el 1.13, erc-button.el 1.11, erc-match.el 1.1, erc.el 1.219:
+ * Be careful: MANY changes ahead. I won't go into too much details.
+
+ * erc.el, new file erc-match.el: split out all pattern-matching code.
+ * erc.el: removed all defcusts for erc-{...}-highlight-props. They are
+ quite useless, anyway.
+ * moved erc-add-entry-to-list and -remove- over to erc-match. changed
+ their arg list.
+ * erc.el: add autoloads for erc-{add,delete}-{keyword,pal,fool,dangerous-host}
+ * erc.el: erc-server-PRIVMSG-or-NOTICE:
+ - remove all the highlighting crap
+ - add a (when (eq s nil) ...) so that untreated CTCP messages don't
+ get misdisplayed.
+ * erc.el: erc-mark-message: removed this function, it's useless
+ * erc.el: minor bugfixes.
+
+ * erc-match.el: first checkin. This file now contains all the pattern
+ matching stuff. there is now another defcust group, erc-match,
+ containing all match related stuff (erc-keywords, ...)
+ * erc-match.el: added functionality to log matching lines. Quite
+ customizable, check out the docstring of defun erc-log-matches
+ * erc-match.el: added functionality to make foolish messages
+ invisible/intangible. This could replace erc-ignore-list
+ sometime. it's more powerful right now, anyway.
+ * erc-match.el erc-text-matched-hook: new hook. run when Text matches
+ anything (pal, fool, etc.).
+
+ * erc-button.el: Make nick buttonization customizable.
+ * erc-button.el: Give nick buttonization a lower priority so that it
+ does not break url buttons.
+
+ * erc-bbdb.el: Add \n to the separators by which we split nicknames.
+
+2002-02-17 Mario Lang <mlang@delysid.org>
+
+ * TODO 1.2: Added item
+
+2002-02-17 Brian P Templeton <bpt@tunes.org>
+
+ * CREDITS 1.2, erc.el 1.218: Added invisible timestamp support.
+
+2002-02-16 Gergely Nagy <algernon@debian.org>
+
+ * debian/changelog 1.13, debian/rules 1.7, debian/scripts/install 1.5:
+ updated to new snapshot
+
+2002-02-16 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.217:
+ Fixed channel limit format overflow in mode-line display.
+ (Having to use floats if integers are to large is quite strange, isn't it?)
+
+ * TODO 1.1: TODO list created.
+ Add comments and expand it.
+
+ * erc.el 1.216:
+ Fixed bug in query buffer handling (only happend in mixed-case situations)
+
+ * erc.el 1.215: shapr checkdoc patch #1
+ massive docfixes! yay, keep going!
+
+2002-02-15 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.214: various other fixes
+ make s301 a catalog entry
+
+2002-02-15 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.213: * erc-server-NICK and erc-server-INVITE: fixed to use
+ `erc-display-message'. These I missed in the first checkin. I
+ didn't say it in the last log message, but please test these.
+
+ * erc-fill.el 1.7, erc.el 1.212:
+ * erc.el: updated many functions to use `erc-display-message'. Now, we
+ should go for getting highlighting out of
+ erc-server-PRIVMSG-or-NOTICE. The part I want to attack has been
+ marked.
+ * erc-fill.el: updated static filling to leave the erc-parsed property alone.
+
+2002-02-15 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.211:
+ first step, new function: erc-display-message
+
+ * erc.el 1.210: added numreply 379 and 405.
+
+ * erc.el 1.209: stupid typo fixed
+
+ * erc.el 1.208:
+ Finally renamed erc-frame-dedicated-p to erc-frame-dedicated-flag
+ Removed usage of erc-interpret-controls from info buffer drawing (major speedup)
+ Other speedups based on the results from elp.
+ ERC is now about 300%-500% faster in some situations with very full channels!!!!!
+
+2002-02-14 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.207:
+ * erc-downcase now downcases {}|^ with []\~ -- 'stolen' from zenirc.
+ * various checkdoc fixes. Just the upper third of the file, but that
+ should help a little, too. (-: Again, if you have any writing
+ skills, take out that dusty keyboard and tap it to the beat of M-x
+ checkdoc!
+
+2002-02-14 Gergely Nagy <algernon@debian.org>
+
+ * erc.el 1.206 (erc-format-privmessage):
+ fix it, so timestamp-coloring works again (patch from antifuchs)
+
+2002-02-14 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.205: Many fixes based on M-x checkdoc RET.
+ If you have write access, and some english knowledge, help document erc too!
+ M-x checkdoc RET, and follow the instructions.
+
+ * erc-button.el 1.10, erc-ibuffer.el 1.13: minor fixes
+
+ * erc.el 1.204: Use nreverse instead of reverse.
+ Use eq instead of equal where possible.
+ Rewrote erc-get-buffer to not use find-if (find-if does very deep function-call nesting, which isnt good ina defun which is called so often)
+
+2002-02-13 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.9, erc.el 1.203:
+ In erc.el, new hook: erc-channel-members-changed-hook.
+ erc-button.el: Now highlight all nicknames. uses regexp-opt.
+
+2002-02-04 Mario Lang <mlang@delysid.org>
+
+ * erc-nets.el 1.1:
+ Database of irc networks. Use erc-server-select to interactively select one.
+
+ * erc.el 1.202: * erc-format-nick-function: New variable.
+ * (erc-format-nick): The default for above var. Just return the nick.
+ * (erc-format-@nick): Prefix NICK with @ or + if OP or VOICE.
+ * Removed erc-track-modified-channels related code and moved into erc-tracke.l
+ Its auto-loaded now
+
+ * erc-track.el 1.1: Split code from erc.el
+
+2002-02-01 Mario Lang <mlang@delysid.org>
+
+ * erc-ibuffer.el 1.12:
+ * erc-target now uses erc-port-to-string
+
+ * servers.pl 1.1:
+ Script to convert mircs servers.ini to a elisp salist kind of thing.
+ (development tool, it doesnt help you much as a user)
+
+ * erc.el 1.201:
+ * erc-display-line-buffer: renamed to erc-display-line-1
+ * erc-port-equal: New function.
+ * erc-normalize-port: Used by erc-port-equal
+ * minor docstring fixes
+
+2002-02-01 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.200:
+ * erc-already-logged-in-p: compare ports is more robust now.
+
+ * erc-button.el 1.8: * Add buttonization to erc-send-modify-hook, too
+
+2002-01-31 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.199:
+ Use insert-before-markers instead of insert in erc-display-line-buffer
+ This fixed point@column 0 problem and gives us some speedup! yay
+
+ * erc-ibuffer.el 1.11, erc.el 1.198: minor fixes
+
+ * erc.el 1.197:
+ * (erc-line-beginning-position): Renamed to erc-beg-of-input-line.
+ * (erc-line-end-position): Renamed to erc-end-of-input-line.
+ * erc-multiline-input-p: Variable removed.
+
+ * erc.el 1.196:
+ Minor docstring fixes (using M-x checkdoc-current-buffer)
+ If you find time, and you are native english speaker, do that too!!
+
+ * erc.el 1.195: fixed macro-invokation
+
+2002-01-31 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.194: * erc-with-all-buffers-of-server: use erc-list-buffers
+ * erc-process-away, erc-{save,kill}-query-buffers: use it.
+ * erc-cmd-away-all: new command. Set away/back on all servers.
+
+ * erc.el 1.193:
+ * Fix last multiline bug in erc-send-distinguish-noncommands.
+
+2002-01-31 Mario Lang <mlang@delysid.org>
+
+ * erc-ibuffer.el 1.10, erc.el 1.192: minor fixes
+
+2002-01-30 Mario Lang <mlang@delysid.org>
+
+ * erc-ibuffer.el 1.9, erc-menu.el 1.3, erc-speak.el 1.19, erc.el 1.191:
+ Renamed erc-track-modified-channels-minor-mode to erc-track-modified-channels-mode (at least, its a bit shorter)
+ Added docstring to erc-server-hooks (through the macro)
+ Minor docfix in obsolete hook
+
+2002-01-30 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.190:
+ * erc-send-current-line: fix behaviour where buffer changes.
+ * erc-mark-message: fix stupid face bug. highlighting of pals should work now.
+
+ * erc-ring.el 1.2, erc.el 1.189:
+ * new hooks: erc-send-pre-hook, erc-send-modify-hook, erc-send-post-hook
+ * erc-send-this: new variable
+ * erc-noncommands-list: new constant.
+ * erc-send-distinguish-noncommands: use it. (First filter function for sending! yay!)
+ * erc-send-current-line: nearly completely rewritten.
+ - now handles multiline input. (yay!)
+ - now uses the three hooks from above.
+ * erc-process-line: new arg, no-command: don't process this line as a command.
+
+2002-01-30 Mario Lang <mlang@delysid.org>
+
+ * erc-bbdb.el 1.12, erc-button.el 1.7, erc-speak.el 1.18, erc.el 1.188:
+ hook handling rewrite phase 1.
+
+2002-01-30 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.187: * Rework erc-server-PRIVMSG-or-NOTICE
+ * New function: erc-is-message-ctcp-p
+ * New function: erc-format-privmessage
+ * New function: erc-mark-message
+ * erc-server-PRIVMSG-or-NOTICE: use them.
+
+2002-01-30 Mario Lang <mlang@delysid.org>
+
+ * CREDITS 1.1, HISTORY 1.1:
+ Initial checkin.
+
+2002-01-29 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.186: * erc-put-text-properties: make OBJECT optional
+ * erc-put-text-property: same
+ * erc-server-PRIVMSG-or-NOTICE: use them.
+ * Make erc-display-line-buffer: add the "\n" even when the string would be invisible.
+ * same: make the \n invisible, too (:
+
+2002-01-29 Mario Lang <mlang@delysid.org>
+
+ * erc-ibuffer.el 1.8, erc.el 1.185:
+ Rewrote channel tracking using window-configuration-change-hook instead of defadvices.
+
+2002-01-28 Andreas Fuchs <asf@void.at>
+
+ * erc-fill.el 1.6, erc.el 1.184:
+ * Macro define-erc-highlight-customization: Ease up defining
+ erc-{fool,pal,..}-highlight-props defcusts.
+ * defcusts:
+ - erc-fool-highlight-props
+ - erc-pal-highlight-props
+ - erc-dangerous-host-highlight-props
+ - erc-keyword-highlight-props
+
+ Customizable to either nil or "Hide message".
+ * erc-string-invisible-p: check for invisible chars in string
+ * erc-display-line-buffer: use it.
+ * erc-put-text-properties: put a list of props into a piece of text.
+ * erc-server-PRIVMSG-or-NOTICE: use it; set appropriate
+ highlight-props for entire incoming message. This set of changes
+ allows you to e.g. auto-ignore fools.
+
+2002-01-28 Mario Lang <mlang@delysid.org>
+
+ * erc-ibuffer.el 1.7:
+ Added highlight detection support to the Mark column.
+ Now p, k, f, and d indicate pal, keyword, fool and dangerous-host related activity.
+
+ * erc.el 1.183:
+ Highlight tracking finished. All necessary info should now be in erc-modified-channels.
+
+ * erc.el 1.182, erc-ibuffer.el 1.6, erc-speedbar.el 1.7:
+ Added highlight tracking to track-modified-channels
+ no display code yet, the info is just kept in erc-modified-channels
+ Added erc-modified column to ibuffer
+ speedbar update
+
+ * erc-ibuffer.el 1.5: Added erc-members column
+
+ * erc-ibuffer.el 1.4: *** empty log message ***
+
+2002-01-28 Andreas Fuchs <asf@void.at>
+
+ * erc-bbdb.el 1.11:
+ * Fix a slight typo. The hook function should be called in
+ erc-server-376-hook (-:
+
+2002-01-28 Mario Lang <mlang@delysid.org>
+
+ * erc-ibuffer.el 1.3: *** empty log message ***
+
+2002-01-27 Mario Lang <mlang@delysid.org>
+
+ * erc-ibuffer.el 1.2: Fixup, it sort of works now. Try it
+
+ * erc-ibuffer.el 1.1: Initial version
+
+2002-01-26 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.181: *** empty log message ***
+
+2002-01-25 Andreas Fuchs <asf@void.at>
+
+ * erc-bbdb.el 1.10: * fix two bad things:
+ - fix the "proc trick": pass proc as an arg through
+ ...-insinuate-... to ...-show-entry
+ - hook highlighting into the 376 hook. This one is bound to get
+ called (-:
+ * We now only append to hooks only.
+ * Highlighting of changing records gets updated automatically.
+
+2002-01-25 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.180: *** empty log message ***
+
+2002-01-25 Andreas Fuchs <asf@void.at>
+
+ * erc-bbdb.el 1.9: * nearly complete rewrite of erc-bbdb:
+ - Removed code duplication in erc-bbdb-NICK and -JOIN.
+ - Made erc-bbdb-show-entry more general and intelligent.
+ - erc-bbdb-insinuate-entry is now erc-bbdb-insinuate-and-show-entry
+ (note the different arglist!):
+ - erc-search-name-and-create now creates "John Doe" users if name
+ is not specified.
+ - No sign of "mail" anywhere anymore. It's all finger-host. (-:
+ - erc-bbdb-popup-p is now called erc-bbdb-popup-type.
+ - New customize values:
+ . erc-bbdb-irc-channel-field channel field name
+ . erc-bbdb-irc-highlight-field (see below)
+ . erc-bbdb-auto-create-on-nick-p auto-create record on join
+
+ * Highlighting based on BBDB is now here! Specify which type of
+ highlighting a person in the BBDB (whose nick you know) and have
+ fun! Read help to erc-bbdb-init-highlighting for details. Changes:
+ - new function erc-bbdb-init-highlighting: gets called on server
+ connect.
+ - new function erc-bbdb-highlight-record: highlights a person's
+ nick names.
+
+2002-01-24 Andreas Fuchs <asf@void.at>
+
+ * erc-button.el 1.6:
+ * Fix the erc-button-alist regexp for EmacsWiki stuff. delYsid's version
+ is better (-:
+
+ * erc-button.el 1.5: * Added an Ewiki: specifier to the url-regexp.
+ <nickname> EmacsWiki: EmacsIRCClient tells you <bla>
+ should highlight "EmacsWiki: EmacsIRCClient" and allow you to
+ browse to the wiki when the button is activated.
+ * new custom: erc-emacswiki-url.
+ * new function: erc-browse-emacswiki: use it.
+
+2002-01-23 Mario Lang <mlang@delysid.org>
+
+ * erc-bbdb.el 1.8:
+ erc-bbdb-NICK: Added regexp-quote around fingerhost search.
+
+2002-01-10 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.179:
+ * Channel saving/killing on quit from server implemented:
+ - defcust erc-save-queries-on-quit: Save server's channel buffers on quitting from server
+ - defcust erc-kill-queries-on-quit: Kill server's channel buffers on quitting from server
+ - Macro erc-with-all-buffers-of-server: Run a form inside all the server's query buffers
+ - Functions erc-{kill,save}-query-buffers: use it.
+ * Added indent-tabs-mode: t to Local Variables section.
+
+2002-01-07 Andreas Fuchs <asf@void.at>
+
+ * erc-replace.el 1.2: * fix stupid documentation errors.
+
+2002-01-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.178:
+ * (toplevel): Revert previous change. This resulted ina recursive load...
+ You have to put (require 'erc-button) into your .emacs for now
+
+2002-01-05 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.177:
+ * Added require for erc-button. This is devel. so I need testers :)
+
+ * erc-button.el 1.4: * Added proper file headers (GPL).
+
+2002-01-04 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.3: * erc-button-alist: Added entry for finger
+
+ * erc-button.el 1.2: * Removed bogus usage of :button-keymap.
+ P
+ Does anyone know what this was supposed to do anyway?
+
+ * erc-button.el 1.1: * Initial version.
+ * This module allows a way of buttonizing text in IRC buffers.
+ Default it is used for URLs, but other things could be added.
+ see if you can find another use, erc-button-alist
+
+ Copyright (C) 2002 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted provided the copyright notice and this notice are preserved.
+
+;; arch-tag: a6779d5e-99fa-442b-98cf-90e73eb2c272
diff --git a/lisp/erc/ChangeLog.2003 b/lisp/erc/ChangeLog.2003
new file mode 100644
index 00000000000..39d5e150da6
--- /dev/null
+++ b/lisp/erc/ChangeLog.2003
@@ -0,0 +1,2145 @@
+2003-12-30 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.595 (erc-cmd-HELP):
+ Changed to prefer giving help for erc-cmd-* functions over
+ similarly-named Elisp functions (e.g., erc-cmd-LIST vs. list).
+
+2003-12-28 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.594 (erc-query-buffer-p): Added this function.
+
+2003-12-28 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.593 (erc-cmd-SV): Use erc-emacs-build-time.
+
+ * erc-compat.el 1.15: erc-emacs-build-time: New variable.
+
+ * erc.el 1.592 (erc-cmd-SAY):
+ Reintroduced the feature where the spaces between
+ "/SAY" and the rest of the line were being sent with the message.
+
+2003-12-28 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.591 (erc-server-buffer-p):
+ Fixed a bug where this function sometimes would return
+ nil when it should return t.
+
+2003-12-27 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.590 (erc-generate-new-buffer-name):
+ Really fixed a bug where ERC would reuse
+ a connected server buffer when erc-reuse-buffers is non-nil.
+ (erc-cmd-JOIN): Now we tell the user when he attempts to join the same
+ channel twice on the same server.
+
+ * erc.el 1.589 (erc-generate-new-buffer-name):
+ Fixed a bug where ERC would reuse a connected server buffer when erc-reuse-buffers is non-nil.
+
+ * erc.el 1.588 (erc-cmd-SAY):
+ Fixed a bug where the spaces between "/SAY" and the rest of the
+ line were being sent with the message.
+
+ * erc-list.el 1.15: Fixed another typo.
+
+ * erc-list.el 1.14: Fixed a typo.
+
+ * erc-list.el 1.13:
+ Added text to the top of the channel list buffer describing the keybinding for
+ function erc-chanlist-join-channel.
+
+ * erc-list.el 1.12: Minor appearance changes. No functional change.
+
+ * erc-list.el 1.11:
+ Implemented function erc-chanlist-join-channel. Added variable
+ erc-chanlist-channel-line-regexp. Got rid of function
+ erc-chanlist-pre-command-hook. Changed the logic for how channel lines are
+ highlighted.
+
+2003-12-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-list.el 1.10:
+ Removed a bunch of unused code. No semantic change.
+
+ * erc-list.el 1.9: Added lots of functionality.
+
+2003-12-15 Mario Lang <mlang@delysid.org>
+
+ * erc-track.el 1.58, erc.el 1.587:
+ New custom type erc-message-type, use it in erc-hide-list and erc-track-exclude-types
+
+2003-12-14 Alex Schroeder <alex@gnu.org>
+
+ * erc-track.el 1.57 (track-when-inactive): New module.
+ (erc-track-visibility): New option.
+ (erc-buffer-activity): New variable.
+ (erc-buffer-activity-timeout): New variable.
+ (erc-user-is-active): New function.
+ (erc-buffer-visible): New function.
+ (erc-modified-channels-update): Replace get-buffer-window call
+ with call to erc-buffer-visible.
+ (erc-track-modified-channels): Ditto.
+
+2003-12-14 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-track.el 1.56 (erc-modified-channels-update):
+ Force update of modeline. Makes sure
+ that the tracked channels disappear in other buffers too.
+
+2003-12-06 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el 1.586 (define-erc-module):
+ New optional argument LOCAL-P. If non-nil, then
+ mode will be created as buffer-local rather than a global mode.
+ (erc-cmd-CTCP): Fix indentation from last commit.
+
+ * erc-compat.el 1.14 (erc-define-minor-mode):
+ Deal with :global and :group keywords.
+
+ * erc-nickserv.el 1.13 (erc-current-network):
+ Make server regex more permissive.
+
+ * erc.el 1.585 (erc-cmd-CTCP):
+ Don't add a space to end of command when ARGS are
+ empty. This fixes a bug whereby requests of the form "VERSION " were
+ being sent, and ignored.
+
+2003-11-27 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-log.el 1.9: From Adrian Aichner <adrian@xemacs.org>
+ * erc-log.el (erc-log-file-coding-system): Use 'binary
+ coding-system under XEmacs (instead of 'emacs-mule).
+ * erc-log.el (erc-w32-invalid-file-characters): Removed as no
+ longer needed.
+ * erc-log.el (erc-generate-log-file-name-long): Use
+ `convert-standard-filename', which exists in XEmacs too.
+
+2003-11-16 Mario Lang <mlang@delysid.org>
+
+ * erc-identd.el 1.1: Code provided by johnw, thanks!
+
+2003-11-09 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el 1.584 (erc-latest-version): Clean up docstring.
+ Remove requirement for w3, wrap REQUIRE statement in IGNORE-ERRORS.
+ Update viewcvs url to correct location.
+ (erc-ediff-latest-version): Make sure that we find the uncompiled
+ erc.el, error if not.
+
+2003-11-07 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.583: Add more info to /sv
+
+2003-11-06 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.582: Added optional argument BUFFER to erc-server-buffer-p.
+
+2003-11-04 Mario Lang <mlang@delysid.org>
+
+ * AUTHORS 1.6: Add sachac
+
+2003-11-02 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el 1.581 (erc-server-366):
+ chnl is 4th element of parsed, not fifth.
+ (erc-channel-end-receiving-names): Pass correct number of arguments
+ to delete-if-not.
+
+ * erc.el 1.580 (erc-update-current-channel-member):
+ Use erc-downcase when comparing
+ nick entries. Cleanup indentation.
+
+2003-11-01 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-sound.el 1.4: Added a (provide 'erc-sound) line.
+
+ * erc.el 1.579 (erc-cmd-NAMES): send to TGT, not CHANNEL.
+
+2003-10-29 Sandra Jean Chua <sacha@free.net.ph>
+
+ * erc-pcomplete.el 1.21, erc.el 1.578, CREDITS 1.6:
+ Merged Jeremy Maitin-Shepard's patch for time-sensitive nick completion.
+
+2003-10-27 Mario Lang <mlang@delysid.org>
+
+ * Makefile 1.19, debian/changelog 1.24:
+ New Debian package 4.0.cvs.20031027
+
+2003-10-25 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.577: Fix typo tuncate->rruncate
+
+2003-10-24 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.80: From Stephan Stahl <stl@isogmbh.de>:
+ * (erc-dcc-send-block): Kill buffer if transfer completed correctly.
+
+2003-10-22 Mario Lang <mlang@delysid.org>
+
+ * erc-track.el 1.55 (erc-track-disable):
+ Do not deactivate all advices for `switch-to-buffer',
+ just disable the erc specific one. (Bug#217022).
+
+2003-10-18 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-log.el 1.8 (erc-log-file-coding-system): New variable.
+ (erc-save-buffer-in-logs): Use it.
+
+2003-10-17 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.576 (erc-interpret-mirc-color): New boolean defcustom
+
+ * erc.el 1.575: Do not use -nowait on darwin (thanks johnw)
+
+2003-10-15 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el 1.574 (define-erc-module):
+ Set erc-FOO-mode appropriately in erc-FOO-enable
+ and erc-FOO-disable.
+
+2003-10-12 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-autoaway.el 1.12 (erc-mode):
+ Reset idletime on connect. Fixes an annoying bug which
+ flooded the server with aways on reconnect.
+ (erc-autoway-reset-idletime): Accept optional args so we can hook it
+ onto erc-server-001-hook.
+
+2003-10-10 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.573 (erc-hide-list): Add a nice defcustom type
+
+2003-10-08 Mario Lang <mlang@delysid.org>
+
+ * Makefile 1.18, debian/changelog 1.23, debian/control 1.8:
+ Debian snapshot 20031008
+
+ * erc-speedbar.el 1.11:
+ Patch from Eric M. Ludlam <eric@siege-engine.com>:
+ - (erc-install-speedbar-variables): Add functions list (needs new speedbar?)
+ - (erc-speedbar-buttons): Add doc. Clear the buffer
+ - (erc-speedbar-sort-channel-members): New function.
+ - (erc-speedbar-expand-channel): Call new sort function. Change some visuals.
+ - (erc-speedbar-insert-user): Change some visuals based on channel data.
+ - (erc-speedbar-line-text, erc-speedbar-item-info): New functions
+ Add proper elisp file header.
+
+2003-10-02 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-match.el 1.22 (erc-match-syntax-table): New variable.
+ (erc-match-current-nick-p): Use it.
+
+ * erc.el 1.572 (erc-quit-reason-zippy, erc-part-reason-zippy): Use
+ `erc-replace-regexp-in-string' rather than
+ `replace-regexp-in-string'.
+ (erc-command-indicator-face): New face, used to show commands if
+ `erc-hide-prompt' is nil and `erc-command-indicator' is non-nil.
+ (erc-command-indicator): Clean up doc-string.
+ (erc-display-prompt): New optional argument FACE, use this rather
+ than `erc-prompt-face' to fontify the prompt if non-nil.
+ (erc-send-current-line): Pass in `erc-command-indicator-face' to
+ `erc-display-prompt'.
+
+ * erc-compat.el 1.13 (erc-replace-regexp-in-string): New function.
+ Alias for `replace-regexp-in-string' on Emacs 21.
+ Argument massaging for `replace-in-string' for XEmacs.
+
+2003-09-28 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.571 (erc-keywords): Removed. Wasn't used by anything.
+
+2003-09-25 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el 1.570: ERC-HIDE-PROMPT: add custom group
+ ERC-COMMAND-INDICATOR: new variable.
+ ERC-COMMAND-INDICATOR: new function.
+ ERC-DISPLAY-PROMPT: new argument, PROMPT, used to override default
+ prompt.
+ ERC-SEND-CURRENT-LINE: pass ERC-COMMAND-INDICATOR to ERC-DISPLAY-PROMPT.
+
+2003-09-24 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.569 (erc-parse-line-from-server):
+ Ignore empty lines as required by RFC.
+
+2003-09-17 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.568: Add lag time calculation
+
+2003-09-13 Mario Lang <mlang@delysid.org>
+
+ * Makefile 1.17, debian/README.Debian 1.7, debian/changelog 1.22:
+ New debian release
+
+ * erc-notify.el 1.22:
+ Call erc-notify-install-message-catalogs on load, not on module init
+
+ * erc.el 1.567 (erc-update-modules):
+ Use `load' instead of `require'. XEmacs appears
+ to have the NOERROR arg only sometimes... Strange
+
+ * erc.el 1.566: No fboundp if we have a defvar
+
+ * erc.el 1.565: Properly defvar erc-ping-handler
+
+2003-09-11 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.564 (erc-setup-periodical-server-ping):
+ check if erc-ping-handler is
+ bound before referencing it
+
+2003-09-10 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.563 (erc-cmd-NICK):
+ Warn about exceeded NICKLEN if we know it.
+
+ * erc.el 1.562: Make erc-server-PONG obey erc-verbose-server-ping.
+ Cancel old `erc-ping-handler' timer when restablishing connection in the same
+ buffer.
+
+ * debian/changelog 1.21, Makefile 1.16: New debian snapshot
+
+ * erc-dcc.el 1.79, erc-xdcc.el 1.6:
+ Use new function erc-dcc-file-to-name to convert spaces to underscores
+
+ * erc-xdcc.el 1.5: Add autoload for erc-xdcc-add-file
+
+2003-09-08 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.78: indent fixes and copyright update
+
+ * erc.el 1.561:
+ erc-send-ping-interval: New defcustom which defaults to 60.
+ Every 60 seconds, we send PING now.
+ This should fix the "connection silently lost" bug.
+ Please test this change extensively, and report problems.
+
+2003-09-07 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.560 (erc-default-coding-system):
+ Test for undecided and utf-8
+ before setting.
+
+2003-09-01 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.559 (erc-modules): Add some more symbols to the set
+
+ * erc.el 1.558 (erc-modules): * erc.el 1.558 (erc-modules): Add :greedy t to the set in
+
+ * erc-dcc.el 1.77:
+ More autoloads which make dcc autoload upon ctcp dcc query received.
+
+ * erc-dcc.el 1.76 (erc-cmd-DCC): Add Autoload.
+ (pcomplete/erc-mode/DCC): Ditto, makes DCC autoloadable just by using
+ completion.
+ Also only offer "send" if fboundp make-network-process.
+
+ * erc-autojoin.el 1.6: Update copyright
+
+ * erc-autojoin.el 1.5 (erc-autojoin-add):
+ Only add the channel if it is not already there.
+
+ * erc-notify.el 1.21:
+ Use `define-erc-module' instead of old `erc-notify-initialize'.
+ Now defines the global minor mode erc-notify-mode, and should also
+ be controllable via `erc-modules' with symbol `notify'.
+
+ * erc.el 1.557 (erc-modules):
+ Fix paren-in-column-zero bug in docstring.
+ Add a sort of bogus, but still better :type.
+ Add autojoin and netsplit by default.
+ (erc-update-modules): Dont barf with an error if `require' fails.
+ We can still error out if the mode is not defined.
+
+2003-08-31 Andreas Fuchs <asf@void.at>
+
+ * erc.el 1.556:
+ * make 353 (NAMES reply) output go into the appropriate channel buffer
+ (if it exists) or into the active erc buffer (if not).
+
+2003-08-29 mtoledo <mtoledo@confusibombus>
+
+ * erc.el 1.555:
+ Added the variable erc-echo-notices-in-current-buffer to make possible display notices in the current buffer (queries to nickserv/chanserv/memoserv). Defaults to nil so nothing changes from what we have today.
+
+2003-08-29 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.554: Fix typo in varname which led to a compiler warning
+
+ * AUTHORS 1.5: Added lawrence
+
+2003-08-27 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.75:
+ Set process and file-coding system to 'binary (for Windows)
+
+ * erc-stamp.el 1.30: Rename custom group erc-timestamp to erc-stamp.
+
+2003-08-07 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-fill.el 1.23 (erc-fill-disable):
+ Remove erc-fill, not erc-fill-static from
+ erc-insert-modify-hook.
+
+2003-08-05 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.553 (erc-send-current-line):
+ Now we display the prompt for previously entered commands
+ based on the value of customization variable erc-hide-prompt. This change is
+ closely related to revision 1.552 by wencem.
+
+2003-08-04 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el 1.552 (erc-send-current-line):
+ If we're sending a command, don't display
+ the prompt.
+
+2003-08-04 Damien Elmes <erc@repose.cx>
+
+ * erc-track.el 1.54: patch from David Edmondson (dme AT dme DOT org)
+
+ This patch makes button 3 on the erc-track buffer names in the
+ modeline show the selected buffer in another window. It's analogous to
+ button 2 which shows the buffer in the current window.
+
+2003-07-31 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.551 (erc-display-line-1):
+ Fixed bad indentation on one line. No semantic change.
+
+2003-07-29 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-match.el 1.21:
+ Quote open paren in docstring of erc-text-matched-hook
+
+ * erc.el 1.550: Anchor match only at beginning in erc-ignored-user-p.
+
+ * erc-button.el 1.47: New variable erc-button-wrap-long-urls.
+ Modified erc-button-add-buttons:
+ New optional argument REGEXP.
+ If we're buttonising a URL and erc-button-wrap-long-urls is
+ non-nil, try and wrap them
+
+ Modified erc-button-add-buttons-1:
+ Pass regexp to erc-button-add-buttons.
+
+2003-07-28 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.549 (erc-network-name):
+ Improved docstring. Removed an unnecessary call to erc-server-buffer.
+
+2003-07-28 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.548: By lawrence:
+ (erc-ignored-user-p): Use anchored regexp.
+ (smiley): Fix missing quote in `remove-hook' call.
+
+2003-07-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-nets.el 1.4, erc-nickserv.el 1.12, erc.el 1.547:
+ Changed all references to Openprojects into references to Freenode.
+
+2003-07-25 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.546:
+ Now variable erc-debug-irc-protocol is defvar'ed instead of defcustom'ed.
+ Made the docstring clearer too.
+
+ * erc.el 1.545: Fixed a wrong-type-argument error from window-live-p.
+
+2003-07-15 Damien Elmes <erc@repose.cx>
+
+ * erc-log.el 1.7 (erc-log-setup-logging):
+ set buffer-file-name to "", as (basic-save-buffer)
+ will prompt for a buffer name before invoking hooks. the buffer-file-name
+ will be overridden by (erc-save-buffer-in-logs) anyway - the main danger
+ of doing this is write-file-contents hooks. Let's see if anyone complains.
+ (erc-save-buffer-in-logs): return t, so that further write hooks are not run
+
+2003-07-09 Damien Elmes <erc@repose.cx>
+
+ * erc-dcc.el 1.74 (erc-dcc-open-network-stream):
+ -nowait still crashes emacs cvs - disable for now
+
+2003-07-02 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.544 (erc): Minor docstring modification.
+
+2003-07-01 Damien Elmes <erc@repose.cx>
+
+ * erc-match.el 1.20 (erc-match-current-nick-p):
+ match only on word boundaries
+
+ * erc-log.el 1.6 (erc-log-setup-logging):
+ not sure how this crept in again - make sure we set
+ buffer-file-name to nil, since otherwise it is not possible to open
+ previous correspondence in another buffer while a conversation is open
+
+2003-06-28 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.543 (erc-network-name):
+ Now makes some intelligent guesses if the server didn't tell
+ us the network name.
+
+2003-06-28 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.542 (erc-default-coding-system): Use utf-8 as the default
+ encoding for outgoing stuff and undecided as the default for
+ incoming stuff.
+ (erc-coding-sytem-for-target): New.
+ (erc-encode-string-for-target): Use it.
+ (erc-decode-string-from-target): Use it. Removed the flet
+ erc-default-target hack and documented the dynamically bound
+ variable `target' instead.
+
+2003-06-25 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.541 (erc-log-irc-protocol):
+ Now we keep point on the bottom line of the window
+ displaying the *erc-protocol* buffer if it is at the end of the
+ *erc-protocol* buffer.
+
+ * erc.el 1.540:
+ Added some text to the docstring for variable erc-debug-irc-protocol.
+
+2003-06-23 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-dcc.el 1.73 (erc-dcc-auto-mask-p):
+ Fixed a docstring typo that caused a load-time error.
+
+ * erc-dcc.el 1.72 (erc-dcc-auto-mask-p):
+ Changed reference to undefined variable erc-dcc-auto-mask-list
+ to erc-dcc-auto-masks.
+ Changed default value of variable erc-dcc-auto-masks to nil and added text to its
+ docstring.
+
+ * erc-notify.el 1.20 (erc-notify-timer and erc-notify-QUIT):
+ Added network name to notify_off message.
+
+ * erc.el 1.539 (erc-network-name):
+ Now returns the name of the IRC server if the network name
+ cannot be determined.
+
+ * erc-notify.el 1.19 (erc-notify-JOIN and erc-notify-NICK):
+ Added argument ?m to call to erc-display-message.
+
+ * erc-dcc.el 1.71 (erc-dcc-do-LIST-command):
+ Fixed a bug where I assumed (plist-get elt :type)
+ returns a string -- it really returns a symbol.
+
+ * erc-notify.el 1.18 (erc-notify-timer):
+ Now we include the network name in the notify_on message.
+
+ * erc.el 1.538:
+ New function: erc-network-name. Returns the name of the network that the
+ current buffer is associate with. Not every server sends the 005 messages
+ that enable the network name to be known. If the network name is
+ not known, the string "UNKNOWN" is returned.
+
+ * erc-dcc.el 1.70 (erc-dcc-chat-setup):
+ Added a comment. Fixed a bug where a DCC CHAT buffer has no
+ prompt when it first appears.
+
+ * erc-dcc.el 1.69 (erc-dcc-chat-parse-output):
+ Now a DCC chat buffer displays the nick using
+ erc-nick-default-face just like in a channel buffer.
+
+2003-06-22 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.537 (erc-display-prompt):
+ Fixed incorrect indentation. No semantic change.
+
+ * erc.el 1.536 (erc-strip-controls):
+ Minor change to regexp that matches IRC color control
+ codes. I was seeing usage as follows: ^C07colored text^C^C04other color.
+ Now we strip a ^C followed by zero, one, or two digits. Before this change,
+ we stripped a ^C followed by one or two digits.
+
+ * erc-dcc.el 1.68 (erc-dcc-do-LIST-command):
+ Improved format of output of /DCC LIST. Now the
+ "Size" column for a DCC GET includes the percentage of the file that has
+ been retrieved.
+ (erc-dcc-do-GET-command): Now it works if erc-dcc-default-directory is set.
+
+2003-06-19 Damien Elmes <erc@repose.cx>
+
+ * erc-log.el 1.5:
+ * added quickstart information to the comments up the top
+
+2003-06-16 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.535:
+ Default to open-network-stream on MS Windows. (thanks lawrence)
+
+2003-06-11 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.534 (erc-process-input-line):
+ refactor so that wrong-number-of-arguments is
+ caught when using do-not-parse-args - this lets do-not-parse-args
+ commands display help messages on incorrect syntax in a uniform manner.
+ This no longer raises a bad-syntax error - was this a catch-all to stop a
+ backtrace? Does it belong?
+ (erc-cmd-APPENDTOPIC): the correct way to display help when you want to
+ accept an abitrary string is to (signal 'wrong-number-of-arguments nil).
+ This fixes a bug where people could not /at topics with a space in them.
+
+2003-06-09 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.533:
+ Re-add the last few changes which weren't merged for some reason.
+
+ * erc.el 1.532 (erc-cmd-APPENDTOPIC): show help when given no arguments
+
+ Patch from MrBump. Fixes problem with erc-set-topic inserting ^C characters
+ into the topic. Also removes dependency on CL.
+
+2003-06-08 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.531:
+ Added comment to explain (eval-after-load "erc" '(erc-update-modules)).
+
+2003-06-01 Mario Lang <mlang@delysid.org>
+
+ * erc-pcomplete.el 1.20: Add completion for /unignore
+
+2003-05-31 Alex Schroeder <alex@gnu.org>
+
+ * erc-compat.el 1.12 (erc-encode-coding-string): The default binding,
+ if encode-coding-string was not available, must be a defun that
+ takes multiple arguments. Did that.
+
+2003-05-30 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.530:
+ Add handlers for 313 and 330 (by arne@rfc2549.org, thanks)
+
+2003-05-30 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.529:
+ patch from MrBump to make /mode #foo +b work again (erc-cmd-BANLIST only
+ temporarily changes them now)
+
+2003-05-29 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.528 (erc-select):
+ server is now defaulted with erc-compute-server.
+ A few cosmetic fixes.
+ (erc-default-coding-system): Renamed from erc-encoding-default.
+ (erc-encoding-default): Renamed to erc-default-coding-system.
+ (erc-encoding-coding-alist): Documentation updated to cover regexps.
+ (erc-encode-string-for-target): Now considers keys of
+ erc-encoding-coding-alist to be regexps. Rely on erc-compat
+ wrt. MULE support.
+ (erc-decode-string-from-target): New function.
+ (erc-send-current-line): eq -> char-equal fix.
+ (erc-server-TOPIC): topic is now decoded with
+ erc-decode-string-from-target.
+ (erc-parse-line-from-server): Line from server is no longer decoded
+ here.
+ (erc-server-PRIVMSG-or-NOTICE): Message from a user is decoded here,
+ sspec -> sender-spec for clarity. Cosmetic if -> when fix.
+ (erc-server-TOPIC): sspec -> sender-spec
+ (erc-server-WALLOPS): Ditto.
+
+ * erc-compat.el 1.11 (erc-decode-coding-string):
+ Now requires coding-system as an argument.
+
+2003-05-15 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.527:
+ erc-part|quit-hook is only run on a part|quit directed to our nick, reflect that in the docstring to avoid confusion
+
+2003-05-01 Andreas Fuchs <asf@void.at>
+
+ * erc-truncate.el 1.3:
+ * erc-truncate-buffer-to-size: use fboundp. Scheme takes its toll...
+
+2003-05-01 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-truncate.el 1.2: remove require of erc-log
+ (erc-truncate-buffer-to-size): use erc-save-buffer-in-logs when it's
+ there, else, dont.
+
+2003-04-29 Andreas Fuchs <asf@void.at>
+
+ * erc-log.el 1.4, erc-truncate.el 1.1, erc.el 1.526: erc.el:
+ * erc-cmd-QUIT: Remove references to code in erc-log.el, to
+ not force autoloading of erc-log.el
+ * erc-server-PART: ditto.
+ * erc-quit-hook: new hook, run when /quit command is
+ processed.
+ * erc-cmd-QUIT: use it.
+ * erc-part-hook: new hook, run then PART message is
+ processed.
+ * erc-cmd-PART: use it.
+ * erc-connect-pre-hook: new hook, run before connection to IRC
+ server is started.
+ * erc: use it.
+ * erc-max-buffer-size: Move truncation variables and functions
+ to erc-truncate.el
+ * erc-truncate-buffer-on-save: moved to erc-log.el
+ * erc-initialize-log-marker: new function.
+ erc-log.el:
+ * erc-truncate-buffer-on-save: New defcust here; from erc.el
+ * erc-truncate-buffer-on-save: Put it in group `erc-log'
+ * erc-log-channels-directory: Remove trailing slash from
+ default value.
+ * Add functions to erc-connect-pre-hook, erc-part-hook and
+ erc-quit-hook to avoid getting autoloaded.
+
+ erc-truncate.el:
+ * Contains the truncation functions and defcusts from erc.el.
+ * define-erc-module clause added; new erc-truncate-mode.
+
+2003-04-29 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.525 (erc):
+ Check wether erc-save-buffer-in-logs is bound, too
+
+ * erc.el 1.524 (erc):
+ Check wether erc-logging-enabled is bound before using it - not
+ everyone is using erc-log.el!
+
+2003-04-28 Andreas Fuchs <asf@void.at>
+
+ * erc-log.el 1.3:
+ * while we're at it, remove the (declare (ignore ignore)) statements.
+
+ * erc-log.el 1.2:
+ * add autoload statement for erc-log-mode/etc. Sorry for the delay.
+
+ * erc-log.el 1.1, erc.el 1.523: * erc.el:
+ - move variables and functions to erc-log.el:
+ defgroup `erc-log'
+ defcustom `erc-log-channels-directory'
+ defcustom `erc-log-insert-log-on-open'
+ defcustom `erc-generate-log-file-name-function'
+ defun `erc-save-buffer-in-logs' (autoloads from erc-log.el)
+ defuns `erc-generate-log-file-name-*'
+ defun `erc-current-logfile'
+ defun `erc-logging-enabled' (autoloads from erc-log.el)
+ - erc-truncate-buffer-to-size: fix for double-saving bug when
+ writing out truncated buffer contents. Thanks, lawrence mitchell <wence@gmx.li>!
+ - erc-remove-text-properties-region: Fix case for read-only text.
+ - erc-send-current-line: update insert-marker before calling the hooks.
+ also, wrap (erc-display-prompt) so that it doesn't toggle
+ buffer-modified-p.
+ - erc-interpret-controls: remove /very/ old commented-out function
+ - erc-last-saved-position: make it a marker
+ - erc: use it.
+
+ * erc-log.el: (thanks, lawrence mitchell <wence@gmx.li>!)
+ - Move logging code from erc.el here
+ - define-erc-module log: add; minor mode erc-log-mode is the
+ same as adding the `erc-save-buffer-in-logs' to
+ erc-send-post-hook and `erc-insert-post-hook'.
+ - erc-w32-invalid-file-characters: add.
+ - erc-enable-logging: add.
+ - erc-logging-enabled: use it.
+ - erc-logging-enabled: autoload.
+ - erc-save-buffer-in-logs: fix for truncating saved buffer with read-only text.
+ - erc-save-buffer-in-logs: use erc-last-saved-position.
+ - erc-save-buffer-in-logs: fix saving half-written messages on
+ the prompt when saving the log file. (simply uses
+ erc-insert-marker as an upper bound for saving).
+
+2003-04-27 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.522: * erc.el 1.522: erc-modules: added
+
+2003-04-27 Alex Schroeder <alex@gnu.org>
+
+ * Makefile 1.15 (UNCOMPILED): Added erc-compat.el.
+ (clean): Remove .elc files, too.
+ Patch by Hynek Schlawack <hynek+erc@hys.in-berlin.de>
+
+2003-04-22 Damien Elmes <erc@repose.cx>
+
+ * erc-button.el 1.46:
+ erc-button-keymap: set the parent keymap to erc-mode-map
+
+2003-04-20 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.521:
+ erc-official-location: shouldn't the official location be the base URL of erc?
+
+ * erc.el 1.520:
+ erc-modules: updated the docstring to make the semantics clearer
+
+2003-04-19 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.519:
+ Fix problem where % in NOTICE produced errors (from mmc)
+
+2003-04-18 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.518 (erc-toggle-debug-irc-protocol):
+ moved a reference to 'buf' inside the let
+ statement which defines it. it's difficult to tell what the original
+ intentions were here - at the moment the debug window is displayed when
+ toggling either way.
+
+ * README 1.3, erc.el 1.517:
+ (erc-update-modules: added a condition in for erc-nickserv -> erc-services
+
+ * erc-pcomplete.el 1.19:
+ - that change to erc-update-modules making it require the modules first means
+ we don't need any special case handling here, so i reverted the previous
+ change
+
+ * erc.el 1.516:
+ - don't require 'erc-auto, since windows users don't have access to make.
+ instead, we handle it in (erc-update-modules)
+
+2003-04-17 Damien Elmes <erc@repose.cx>
+
+ * README 1.2, Makefile 1.14:
+ Updated Makefile and documentation to reflect the new release
+
+ * erc.el 1.515:
+ - note the previous change also updated the release number to erc 4.0!
+ (erc-connect): fix a bug introduced by the previous release
+
+ * erc.el 1.514:
+ fixed about 20 instances of (message (format ...)) which will break if the
+ format returns a string with %s in it
+
+ * erc.el 1.513: erc-error-face: make it red, not pink
+
+ * erc-pcomplete.el 1.18:
+ since pcomplete is autoloaded via erc-completion-mode, and completion is in
+ erc-modules by default, we remove completion when pcomplete is added
+
+ * erc.el 1.512 (define-erc-module): no need for delete, use delq
+
+ * erc-members.el 1.5 (erc-nick-channels):
+ (erc-person-channels) takes one arg
+ (erc-format-user): again, they all take an arg
+
+ * erc.el 1.511:
+ - require erc-auto when loading, so the default `erc-modules' can be loaded.
+ this makes erc-auto no longer a convenience but a necessity - all the name
+ of user friendliness.
+ (define-erc-module): the enable and disable routines now update erc-modules
+ accordingly
+ erc-modules: new variable controllig the modules which erc has loaded/will
+ load. when customising, it will automatically enable modules. it won't
+ automatically disable modules which are removed, yet.
+ (erc-update-modules): enable all modules in `erc-modules'
+
+ * erc-dcc.el 1.67 (erc-dcc-open-network-stream):
+ use the -nowait equiv if available
+ erc-dcc-server-port: removed
+ erc-dcc-port-range: allows a range of values, so you can have more than one
+ dcc
+ (erc-dcc-server): support erc-dcc-port-range
+ (erc-dcc-chat): use OCHAT for outgoing chat for now. we need to fix the
+ issues with allowing more than one chat with the same person
+
+ * erc.el 1.510:
+ erc-log-channels: removed; set the directory to start logging
+ (erc-directory-writeable-p): create directory if it doesn't exist, check if
+ it's writeable
+ (erc-logging-enabled): don't reference erc-log-channels
+
+2003-04-07 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.509 (erc):
+ but when inserting the contents of a previous logfile, use the logfile
+ name, not ""!
+
+ * erc.el 1.508 (erc):
+ set buffer-file-name to "", since we have a custom saving function and
+ it's not needed. this enables one to open a log file with previous
+ correspondence, while talking to the person at the same time
+
+2003-03-29 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.507 (erc-prepare-mode-line-format):
+ Now strips all text properties from the target before
+ putting it in the mode line. Keeps the mode line looking consistent.
+ (erc-channel-p): Improved docstring.
+
+2003-03-28 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.506 (erc-generate-log-file-name-with-date): New function.
+ (erc-generate-log-file-name-function): Make it available.
+
+2003-03-24 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.505:
+ Fix erc-prompt and erc-user-mode custom :type (Closes: #185794)
+
+2003-03-20 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.504:
+ erc-server-hook-list: correct documentation of ordering of (proc parsed)
+
+2003-03-16 Alex Schroeder <alex@gnu.org>
+
+ * erc-track.el 1.53 (erc-modified-channels-string):
+ Make it a risky-local-variable.
+
+2003-03-16 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el 1.52 (erc-track-modified-channels):
+ Use (point-min) if we don't find a
+ parsed-property, so it won't error out with nil...
+
+2003-03-16 Damien Elmes <erc@repose.cx>
+
+ * erc-track.el 1.51 (erc-track-switch-buffer):
+ removed call to erc-modified-channels-update, as
+ this is done correctly on buffer switching in both emacs and xemacs now
+
+2003-03-15 Damien Elmes <erc@repose.cx>
+
+ * erc-track.el 1.50 (erc-find-parsed-property):
+ simplified a little, so it shouldn't return nil anymore
+
+ * erc.el 1.503: erc-send-post-hook: document narrowing which occurs
+
+2003-03-14 Alex Schroeder <alex@gnu.org>
+
+ * erc-track.el 1.49 (erc-find-parsed-property): New function.
+ (erc-track-modified-channels): Use it instead of relying on
+ point-min.
+
+2003-03-12 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.502:
+ Fix erc-set-topic to accept a channel name as first word
+
+2003-03-11 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-dcc.el 1.66:
+ Small patch (<10 lines, also slightly modified by Jorgen Schäfer) from
+ David Spreen <netzwurm@debian.org> to add hostmask-authentication to
+ DCC auto-accept.
+
+ erc-dcc-auto-mask-list: New variable
+ (erc-dcc-handle-ctcp-send): Check erc-dcc-auto-mask-list
+ (erc-dcc-auto-mask-p): New function
+ erc-dcc-send-request: Docstring now mentions erc-dcc-auto-mask-list
+
+2003-03-10 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-ring.el 1.11 (erc-clear-input-ring):
+ New function. Erases the contents of the input ring for
+ the current ERC buffer.
+
+2003-03-08 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.501:
+ (erc-display-line-1) and (erc-send-current-line): Now these functions reset erc-insert-this
+ to t as soon as possible after consuming the value of that variable. See the comments in
+ the code for the strange symptom this fixes.
+ (erc-bol): Changed to call point-at-eol instead of line-end-position. This increases XEmacs
+ portability, since XEmacs doesn't have line-end-position. Patch suggested by Scott Evans
+ on the ERC mailing list.
+
+2003-03-04 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.500: banlist*: patch from mrbump to avoid using cl packages
+
+2003-03-04 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.499:
+ Changed erc-noncommands-list from a constant to variable, so that users can
+ add their own erc-cmd-* functions to the list. Improved the docstring too.
+
+2003-03-02 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.498 (erc-server-353):
+ Now the output of "/NAMES #channel" appears in the currently
+ active ERC buffer, even if the user is not a member of #channel.
+
+ * erc.el 1.497 (erc-cmd-DEOP):
+ Fixed a syntax error: invalid read syntax ")" caused by my last change.
+
+2003-03-01 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.496 (erc-cmd-DEOP):
+ Fixed a wrong-type-argument error caused by calling split-string
+ on a list instead of on a string. Removed the call to split-string entirely,
+ because it wasn't needed.
+
+ * erc.el 1.495 (erc-cmd-HELP):
+ Changed to use intern-soft instead of intern. Now "/HELP floob"
+ doesn't create a void function symbol erc-cmd-FLOOB.
+
+2003-02-25 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.494 (erc-cmd-SERVER):
+ remove erroneous references to line, use server instead
+
+2003-02-23 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.493 (erc-toggle-debug-irc-protocol):
+ Fixed a bug where the global value of
+ kill-buffer-hook was being modified instead of the buffer-local value.
+
+2003-02-22 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.492 (erc-cmd-KICK):
+ Now supports any number of words in the REASON string. Examples
+ of the /KICK command are:
+ /KICK franl You don't belong here
+ /KICK franl Bye
+ /KICK franl
+ /KICK #channel franl Go away now
+ /KICK #channel franl Bye
+ /KICK #channel franl
+
+2003-02-16 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-stamp.el 1.29 (erc-insert-timestamp-right):
+ Make the timestamp rear-nonsticky, so
+ C-e works at the beginning of the next line.
+
+2003-02-16 Andreas Fuchs <asf@void.at>
+
+ * erc-stamp.el 1.28:
+ * s/choose/choice/ in customize options, as kensanata requested.
+
+2003-02-15 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.491 (erc-toggle-debug-irc-protocol):
+ Now if the *erc-protocol* buffer is killed,
+ logging is turned off. Prior to this change, the buffer would come back
+ into existence (generally unbeknownst to the user) after being killed.
+
+2003-02-11 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.490 (erc-send-current-line):
+ we can't inhibit everything here when not connected,
+ as the user will expect commands like /server still to work. the
+ erc-cmd-handler should recover from errors instead
+
+2003-02-10 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.489:
+ * we now run erc-after-connect on 422 (no motd) messages as well as the motd
+ messages
+ (erc-login): revert the previous change
+
+ * erc.el 1.488 (erc-login): register that we're connected
+
+2003-02-10 Mario Lang <mlang@delysid.org>
+
+ * erc-members.el 1.4: * Provide erc-members
+ * Fix excessive )
+ * Comment out broken self-tests
+
+2003-02-07 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.487 (erc-connect):
+ notify the user we're trying to connect when using asych
+ connections
+
+ * erc.el 1.486 (erc-connect): support an asyncronous connection
+ (erc-process-sentinel): ditto
+
+ * erc-track.el 1.48:
+ * advise switch-to-buffer in the case of xemacs, since it doesn't have
+ window-configuration-change-hook
+
+ * erc.el 1.485 (erc-send-current-line):
+ if not connected, refuse to send either a message or
+ a command
+
+ * erc.el 1.484: (erc-save-buffer-in-logs):
+ - check for a sensibile region before saving the buffer. if the
+ connection process is killed early on, there is not a sensible region
+ to save
+ - don't set buffer-file-name on save. we don't need it, and it means we
+ can now find-file a log while an existing query is open with that
+ user
+
+ * erc.el 1.483 (erc-process-input-line):
+ when displaying the help for a function, if no
+ documentation exists, don't fall over
+ (erc-cmd-SAY): new function for quoting lines begining with /
+ (erc-server-NICK):
+ - fix a bug where the "is now known as" message doesn't appear on newly
+ created /query buffers
+ - when a user changes their nick, update the query to point to the new
+ nick
+
+ * erc.el 1.482 (erc-send-current-command):
+ don't reject multi-line commands. since
+ multiline-p is used as the no-command arg to erc-process-current-line,
+ multi-line text is never interpreted as a command. i believe this is the
+ correct behavior - it allows people to post the output of things like df
+ (sans header). if you want to change this, please provide a rationale
+ in the changelog
+
+ * erc.el 1.481 (erc-send-current-line):
+ only match the first line when determining if a
+ multi-line command is allowed
+
+2003-02-07 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-bbdb.el 1.21 (erc-bbdb-highlight-record):
+ Use alternate strings, not character
+ classes to split the nick-field.
+
+2003-02-06 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.479 (erc-process-sentinel):
+ Now we set erc-connected to nil every time we disconnect
+ from a server, not just when an unexpected disconnect happens.
+
+ * erc.el 1.478 (erc-connected):
+ Removed redundant defvar of this variable. Improved the
+ docstring.
+ (erc-login): Changed to send a correct RFC2812 USER message (see section
+ 3.1.3 of RFC2812 for the documentation of the semantics of each argument
+ of the USER message.
+
+2003-02-02 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.477 (erc-cmd-NOTICE): fix from mrbump
+
+2003-01-31 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.476 (erc-cmd-JOIN):
+ Now we only send one JOIN command to the server when a channel
+ key is provided.
+
+2003-01-30 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.475 (erc-remove-channel-member):
+ Fixed so that it runs erc-channel-members-changed-hook
+ with the channel buffer current, as is documented in the docstring for variable
+ erc-channel-members-changed-hook: "The buffer where the change happened is
+ current while this hook is called."
+
+2003-01-28 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.474:
+ (erc-ignored-user-p),(erc-cmd-IGNORE),(erc-cmd-UNIGNORE): Now nicks are ignored
+ on a per-server basis. Now, erc-ignore-list is only valid in server
+ buffers! Do not reference it in channel buffers.
+
+ * erc.el 1.473 (erc-cmd-IGNORE):
+ Now says "Ignore list is empty" if it erc-ignore-list is empty
+ instead of showing an empty list.
+
+2003-01-25 Alex Schroeder <alex@gnu.org>
+
+ * erc-nickserv.el 1.11 (services): Defined a module
+
+2003-01-25 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.472 (erc-process-ctcp-query):
+ Display recipient of CTCP query if it's not
+ our current nick.
+
+ * erc.el 1.471 (erc-cmd-WHOIS):
+ Accept an optional second argument SERVER.
+
+2003-01-25 Alex Schroeder <alex@gnu.org>
+
+ * erc-stamp.el 1.27 (stamp): erc-add-timestamp must always be added
+ with the APPEND parameter -- not only when adding it on the right.
+
+2003-01-24 Alex Schroeder <alex@gnu.org>
+
+ * erc-members.el 1.3 (erc-channel-members-changed-hook): Obsolete, use
+ erc-members-changed-hook instead. When it is set, add its content
+ to erc-members-changed-hook.
+ (erc-update-channel-member): Obsolete, use erc-update-member
+ instead. Defalias to that effect.
+ (erc-remove-channel-member): New and already obsolete. Use
+ erc-remove-nick-from-channel instead.
+ (erc-update-channel-info-buffer): Obsolete, use ignore instead.
+ Yes, these have to go.
+ (erc-channel-member-to-user-spec): Obsolete, use erc-format-user
+ instead.
+ (erc-format-user): New.
+ (erc-ignored-reply-p): New, use it.
+
+ * erc-members.el 1.2:
+ Further along the way. Any function from erc.el that uses
+ channel-members should end up in this file, rewritten to use
+ erc-members.
+
+ (erc-person): Call erc-downcase before getting
+ something from the hash.
+ (erc-nick-in-channel): Checking wether erc-process must be used is
+ unnecessary -- this will be done in erc-person.
+ (erc-nick-channels): New.
+ (erc-add-nick-to-channel, erc-update-member): Call erc-downcase
+ before putting something into the hash.
+ (erc-buffer-list-with-nick): New.
+ (erc-format-nick, erc-format-@nick): New, backwards incompatible.
+ Must check for other places that call these!
+ (erc-server-PRIVMSG-or-NOTICE): Use the new version.
+
+ * erc-compat.el 1.10 (view-mode-enter): defalias to view-mode, if
+ view-mode-enter is not fboundp and view-mode is -- as is the case
+ in XEmacs. We need view-mode-enter in erc-match.el.
+
+2003-01-23 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.470 (erc-default-server-handler):
+ Minor performance improvement: allow the lambda
+ expression to be byte-compiled.
+
+2003-01-23 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.469 (erc-cmd-BANLIST):
+ in the absence of a fill-column, use the screen width
+
+2003-01-22 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.468:
+ patch from MrBump to delay fetching the banlist until /bl is run, so we don't
+ fetch it when joining a channel anymore
+
+ * erc-ring.el 1.10:
+ * instead of adjusting hooks when loaded, provide (erc-ring-mode). you'll
+ need to run (erc-ring-mode 1) now to get the ring
+ * (erc-previous-command), (erc-next-command):
+ - check if the ring exists and create it if necessary
+ - don't do anything if the ring is empty
+
+ * erc-pcomplete.el 1.17:
+ Put "how to use" documentation in the comments up the top
+
+2003-01-21 Alex Schroeder <alex@gnu.org>
+
+ * erc-autojoin.el 1.4 (erc-autojoin-version): New.
+
+ * erc-autojoin.el 1.3 (erc-autojoin-add): Added body.
+ (erc-autojoin-remove): Added body.
+ (erc-autojoin): Provide it.
+
+2003-01-21 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.467: erc-cmd-*: removed a bunch of references to force
+
+2003-01-21 Alex Schroeder <alex@gnu.org>
+
+ * erc-autojoin.el 1.2 (erc-autojoin-channels-alist): More doc.
+
+2003-01-20 Alex Schroeder <alex@gnu.org>
+
+ * erc-autojoin.el 1.1:
+ new, based on resolve's mail, and the stuff on the wiki
+
+ * erc-members.el 1.1: new
+
+2003-01-19 Mario Lang <mlang@delysid.org>
+
+ * debian/README.Debian 1.6, debian/changelog 1.20, debian/scripts/install 1.11,
+ debian/scripts/startup.erc 1.4, Makefile 1.13:
+ Prepare for 20030119 debian package
+
+ * erc-dcc.el 1.65: <rant>
+ * (erc-decimal-to-ip): Since XEmacs decides that return a completely
+ and utterly wrong number from string-to-number if it is larger than
+ the integer boundary, instead of sanely converting the thing to
+ a float, we now (concat dec ".0").
+ </rant>
+
+ * erc.el 1.466:
+ * (erc-log-irc-protocol): Use erc-propertize, not propertize
+
+2003-01-19 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.45 (erc-button-add-buttons): Added regexp-quote for
+ the list case, too.
+
+2003-01-19 Damien Elmes <erc@repose.cx>
+
+ * erc-dcc.el 1.64 (erc-dcc-member): fix for case where a prop is nil
+
+ * erc-dcc.el 1.63 (erc-dcc-member):
+ fix for xemacs's version of plist-member
+
+2003-01-19 Mario Lang <mlang@delysid.org>
+
+ * erc-notify.el 1.17: Delete empty strings from the ison-list
+
+ * erc-track.el 1.47:
+ * (erc-track-switch-buffer): Call erc-modified-channels-update here.
+
+ * erc-track.el 1.46: * toplevel: require 'erc-match
+
+ * erc-track.el 1.45: * (erc-track-mode): Make autoload interactive
+
+ * erc-button.el 1.44: * (button): Make the autoload interactive
+
+ * erc.el 1.465:
+ * (erc-mode): Comment out the case-table stuff, breaks xemacs
+ * (erc-downcase): Revert.
+
+ * erc-dcc.el 1.62:
+ * (erc-dcc-handle-ctcp-send): Use erc-decimal-to-ip on the ip we get...
+
+ * erc-speak.el 1.25:
+ Eliminate reference to erc-nick-regexp, which no longer exists
+
+2003-01-19 Alex Schroeder <alex@gnu.org>
+
+ * erc-stamp.el 1.26 (erc-timestamp-right-column): New, default nil.
+ (erc-insert-timestamp-right): Use it, if non-nil. Verbose
+ doc string.
+
+2003-01-18 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.464 (erc-downcase): Use the old behavior in non-CVS Emacs.
+
+ * erc.el 1.463 (erc-cmd-QUIT): Remove &rest. The correct fix follows.
+ (erc-cmd-GQUIT): Pass "" to erc-cmd-QUIT.
+ (erc-mode): Use the case-table only in CVS Emacs. See comment.
+
+ * erc.el 1.462 (erc-cmd-QUIT): make reason optional.
+
+ * erc.el 1.461 (erc-cmd-GQUIT): Fixed typo.
+
+2003-01-17 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.460:
+ * (erc-current-logfile): call expand-file-name, so that downcase doesn't mess up ~
+
+ * erc.el 1.459: * (erc-mode): Define a proper case-table.
+ * (erc-downcase): just call downcase for now, lets see if the case-table is portable, if yes, we'll remove all erc-downcase references anyway...
+
+ * erc-button.el 1.43: * (erc-button-add-buttons): regex-quote the nick
+
+2003-01-17 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.42 (button): erc-channel-members-changed-hook no
+ longer has erc-recompute-nick-regexp.
+ (erc-button-alist): Use channel-members instead of
+ erc-nick-regexp.
+ (erc-button-add-buttons): Split some code into
+ erc-button-add-buttons-1, and now handle strings, lists, and
+ alists. Regular expressions in lists and alists are enclosed in
+ < and >.
+ (erc-button-add-buttons-1): New.
+ (erc-nick-regexp): Deleted.
+ (erc-recompute-nick-regexp): Deleted.
+
+ * erc-button.el 1.41: Remove require cl again.
+ (erc-mode-map): No longer bind widget-backward and widget-forward.
+ (erc-button-alist): Explain why byte-compiling makes no sense, and
+ remove all calls to byte-compile.
+ (erc-button-keymap): Define it the standard way, without exposing
+ the list nature of the keymap.
+ (erc-button-marker-list): Deleted.
+ (erc-button-add-buttons): Simplify. In particular, create the
+ button using the real callback, instead of using the intermediate
+ erc-button-push, and only store the data as described for
+ erc-button-alist.
+ (erc-button-remove-old-buttons): Simplify. No more list munging.
+ Instead, just remove all the properties that we add in
+ erc-button-add-button.
+ (erc-widget-press-button): Deleted.
+ (erc-button-click-button): New, for mouse clicks. Moves point to
+ where the mouse is, and calls erc-button-push.
+ (erc-button-push): Instead of matching again, just use the
+ erc-callback and erc-data properties at point to do the right
+ thing.
+ (erc-button-entry): Deleted.
+ (erc-button-next): Use error instead of the beep plus message
+ combo.
+
+2003-01-17 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-autoaway.el 1.11 (erc-autoaway-set-back):
+ Don't pass a force argument to erc-cmd-GAWAY.
+
+ * erc.el 1.458 (erc-cmd-AWAY): Removed usage of the force variable.
+
+2003-01-17 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.40 (button):
+ erc-recompute-nick-regexp is no longer added to
+ erc-channel-members-changed-hook unconditionally, but only if
+ erc-button-mode is enabled, and if it is disabled, it is removed
+ again.
+ (erc): Require cl for delete-if.
+ (erc-button-remove-old-buttons): Rewrote using delete-if to
+ prevent exceesive consing. Having the marker list is still ugly,
+ so another solution needs to be found.
+
+2003-01-17 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.457 (erc-banlist-store):
+ Don't assume there's always a setter in the banlist reply.
+
+2003-01-17 Alex Schroeder <alex@gnu.org>
+
+ * erc-button.el 1.39 (erc-button-url-regexp): Changed regexp according
+ to a suggestion by Max Froumentin <mf@w3.org>.
+
+2003-01-17 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.456:
+ fix erc-remove-channel-member again to not error out on nil as first arg...
+
+ * erc.el 1.455: * (erc-occur): New function
+
+2003-01-17 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.454: erc-banlist-*: return nil so further hooks are called
+
+ * erc.el 1.453 (erc-server-368):
+ supress "end of ban list" messages - use /listbans now
+
+ * erc.el 1.452 (erc-send-current-line):
+ removed the check for leading whitespace again - the
+ only time we want to prohibit multi-line commands is if / is the first
+ thing on the line
+ (erc-get-arglist): new defun for reading a function's arglist which should
+ work with older copies of emacs. we use help-function-arglist if it's
+ available, though, since that has support for reading subrs, etc
+
+ * erc.el 1.451 (erc-cmd-JOIN): fixed (again)
+
+ * erc.el 1.450: * fixed call to erc-cmd-NICK when connecting
+ * support for listing bans and mass unbanning, again thanks to MrBump
+
+ * erc.el 1.449 (erc-set-topic):
+ patch from MrBump (Mark Triggs, mst@dishvelled.net) to strip
+ control chars and topic attribution in C-c C-t
+
+2003-01-16 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.448:
+ * (erc-remove-channel-member): Do not use delq, modify the list using setcdr like delq does.
+ In theory, this should be way faster since the list doesnt get traverse two times.
+ Measurement didn't show any real difference though :(, this system is flawed for channels with >300 users it seems...
+ Also moved some defcustoms up.
+
+2003-01-16 Brian P Templeton <bpt@tunes.org>
+
+ * erc.el 1.447: moved misplaced paren
+
+2003-01-16 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.446 (erc-cmd-UNIGNORE):
+ reference argument directly - no string matching
+
+ * erc.el 1.445 (erc-extract-command-from-line):
+ hmm, thinko in the canonicalisation. should
+ be fixed
+
+2003-01-16 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.444 (erc-send-current-line):
+ Changed the regexp used to match /COMMANDs so that leading
+ whitespace is taken into account.
+
+2003-01-16 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.61: * (erc-dcc-do-SEND-command): Fix it
+
+ * erc-ezbounce.el 1.4, erc-lang.el 1.2: Arglist changes...
+
+ * erc.el 1.443: Various docstring fixes and additions.
+
+ * erc-notify.el 1.16:
+ * (erc-cmd-NOTIFY): Change the function arglist to (&rest args)
+
+ * erc-netsplit.el 1.8: * (erc-cmd-WHOLEFT): Has no args...
+
+2003-01-16 Damien Elmes <erc@repose.cx>
+
+ * erc-fill.el 1.22:
+ erc-fill-column: default to 78, so things like docstrings don't get wrapped
+ in an ugly manner
+
+2003-01-16 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.442:
+ * (erc-cmd-default): Take a substring, now /mode works again.
+ * (erc-cmd-AWAY): Put do-not-parse-args t
+ * (erc-cmd-GAWAY): Ditto, and fix it.
+ * (erc-cmd-CTCP): Switch to argument system.
+ * (erc-cmd-KICK): Do the same.
+
+2003-01-15 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.60:
+ * (erc-cmd-DCC): Fixed for the new scheme, simplified.
+ * (erc-dcc-do-CHAT-command): Ditto.
+ * (erc-dcc-do-CLOSE-command): Ditto.
+ * (erc-dcc-do-LIST-command): Ditto.
+
+2003-01-15 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.441:
+ erc-error-face: setting a background doesn't work so well with multi-line
+ messages, so we don't. fg colour is negotiable ;-)
+ (erc-cmd-QUERY): fixed, new doco, supress (erc-delete-query) until we fix it
+ (erc-send-current-line): allow multi-line messages provided they don't start
+ with a slash - there's no need to prohibit them if the slash isn't the
+ first character
+
+ * erc.el 1.440: * bad-syntax now reports like incorrect-args
+ * bunch of extra cmds fixed, nick, sv etc.
+
+ * erc.el 1.439 (erc-cmd-HELP): fixed
+ (erc-extract-command-from-line): when deterimining canon-defun, make sure we
+ have a valid symbol
+ (erc-cmd-KICK): fixed
+
+ * erc.el 1.438:
+ * removed duplicate do-no-parse-args properties for the defaliased defuns
+ (erc-process-input-line): show function signature when incorrect args
+ (erc-extract-command-from-line): canonicalise defaliases before extracting
+ plist
+ (erc-cmd-CLEAR): fixed
+ (erc-cmd-UNIGNORE): fixed again
+
+ * erc.el 1.437 (erc-cmd-SET): fixed
+ (erc-cmd-UNIGNORE): fixed
+ (erc-process-input-line): report when incorrect arguments are provided to a
+ command, and show the command's docstring
+
+ * erc.el 1.436 (erc-cmd-APPENDTOPIC): fixed
+ (erc-process-input-line): more informative error message than 'bad syntax'
+
+2003-01-15 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.435: * (erc-cmd-IGNORE): fixed
+
+ * erc.el 1.434: * (erc-cmd-NAMES): fixed
+
+ * erc.el 1.433:
+ * (erc-cmd-CLEARTOPIC): Simplify, fix doc, make interactive
+
+2003-01-15 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.432 (erc-cmd-JOIN):
+ correct invite behavior, and document it.
+
+2003-01-15 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.431: * (erc-cmd-PART): Put 'do-not-parse-args t
+
+2003-01-15 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.430 (erc-cmd-JOIN): new cmd argument syntax
+ (erc-process-input-line): check if (erc-extract-command-from-line) returned a
+ list, and apply if that's the case
+
+ * erc.el 1.429:
+ erc-cmd-*: remove optional force and references to `force' in the code
+ (erc-cmd-AMSG): call erc-trim-string, not trim-string
+
+2003-01-15 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.428:
+ * (erc-cmd-CLEARTOPIC): LINE is now ARGS and already parsed.
+ Set erc-cmd-TOPIC to 'do-not-parse-args for now.
+ (comment: I think we should have 'first, so that only first word is parsed...
+ Or we could autodetect erc-channel-p in the parser before that somehow...)
+
+ * erc.el 1.427: * (erc-cmd-OP): LINE is PEOPLE now, and already parsed.
+
+ * erc-notify.el 1.15:
+ * (erc-cmd-NOTIFY): Arg LINE is now ARGS, and already parsed.
+
+2003-01-15 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-stamp.el 1.25 (erc-insert-timestamp-right):
+ Prefer erc-fill-column to window-width,
+ because on wide screens the timestamp could wander off too far to the
+ right.
+
+2003-01-15 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.426: This is the "everything is suddenly broken!" release
+ You know, this is CVS, you can still go back, and wait until the transition
+ is finished, but here is patch one, which basicly breaks every command
+ which is typed on the prompt.
+ Hit me, we can still revert, but something needs to be done about this.
+ * (erc-extract-command-from-line): intern-soft the function here.
+ If the function symbol has a property 'do-not-parse-args, operate as before,
+ otherwise, split the arguments prior to calling the command handler.
+ * (erc-process-input-line): Updated to accomodate the change above.
+ * (erc-send-distinguish-noncommands): Ditto.
+ * (erc-cmd-NAMES): Ditto.
+ * (erc-cmd-ME): Put 'do-not-parse-args property.
+
+ * erc-dcc.el 1.59:nick: * erc-dcc.el 1.59: * erc-dcc-list: Renamed
+ * (erc-dcc-member). Treat :nick as either a nick!user@host or nick,
+ do appropriate comparisons, simplified.
+ * (erc-dcc-list-add): New functions
+ various callers of (cons (list ...) erc-dcc-list) updated.
+ Other stuff I'm to bored to document now
+
+2003-01-15 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-stamp.el 1.24 (erc-insert-timestamp-right):
+ Removed redundant code that overrid the
+ window-width. Now substracts (length string) from every found
+ indentation positions.
+
+2003-01-14 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.425:
+ * (erc-cmd-AMSG): Remove useless call to erc-display-message.
+
+ * erc-dcc.el 1.58:
+ * erc-dcc-chat/send-request: New variables, control how to treat
+ incoming dcc chat or send requests. Can be set to 'ask, which behaves
+ like it did before, 'auto, which accepts automatically, and
+ 'ignore, which ignores those type of requests completely.
+ * (erc-cmd-CREQ): New user-level command.
+ * (erc-cmd-SREQ): Ditto.
+
+ * erc.el 1.424: * (erc-cmd-AMSG). New command.
+
+ * erc-xdcc.el 1.4: * (erc-xdcc): delete empty strings from ARGS
+
+ * erc-dcc.el 1.57: * erc-dcc-ipv4-regexp: New constant
+ * (erc-ip-to-decimal): Use it.
+ * erc-dcc-host:valid-regexp erc-dcc-ipv4-regexp: * erc-dcc-host: :type
+ * (pcomplete/erc-mode/DCC): Add completion for GET and CLOSE.
+ * Some docstring/comment fixes.
+
+ * erc-stamp.el 1.23:
+ * (erc-insert-timestamp-right): Subtract (length string) from
+ POS in any case, otherwise, linewrap occurs.
+
+ * erc-dcc.el 1.56:
+ * Fixed the unibyte-multibyte problem (now a dcc get buffer is (set-buffer-multibyte nil),
+ and saves correctly (tried with 21.3.50). Thanks to Eli for suggesting it!
+ * Added :start-time plist property/value to GET handling so that we can calculate elapsed-time.
+ * Some (unwind-protect (progn (set-buffer ...) ...)) constructs replaced with (with-current-buffer ...)
+
+2003-01-13 Mario Lang <mlang@delysid.org>
+
+ * erc-xdcc.el 1.3:
+ * erc-xdcc-help-text: New variable which makes replies to the originator
+ much more flexible.
+ * erc-xdcc-help-format: Removed.
+ * (erc-xdcc-help): Handle the new variable.
+ * (erc-xdcc): Simplified
+
+ * erc-xdcc.el 1.2: * erc-xdcc-handler-alist: New variable.
+ * (erc-xdcc): Move code for list and send sub-commands into
+ * (erc-xdcc-help): New function.
+ * (erc-xdcc-list): New function.
+ * (erc-xdcc-send): New function.
+
+2003-01-12 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.423 (erc-server-JOIN):
+ Oops, send MODE command only when *we* joined a channel.
+
+ * erc.el 1.422:
+ Fixing ERCs behavior wrt IRCnet's !channels have a different name for
+ JOIN than in reality (e.g. you can join !forcertest or !!forcertest
+ and really get to !ABCDEforcertest)
+
+ (erc-cmd-JOIN): Removed erc-send-command MODE.
+ (erc-server-JOIN): Ask for MODE now.
+
+2003-01-12 Damien Elmes <erc@repose.cx>
+
+ * erc-dcc.el 1.55:
+ (erc-dcc-get-filter), (erc-dcc-get-file): store size as a string, not an
+ integer. check size > 0 for the case where a size wasn't provided, since
+ string-to-int will return 0 on an empty string
+
+2003-01-12 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.54: * Use RAWFILE arg with find-file-noselect
+ * Fix alist/plist conversion left-over
+ * Add verbose-info about sending blocks.
+
+2003-01-11 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.53: * (pcomplete-erc-mode/DCC): Fixes
+
+ * erc-xdcc.el 1.1: Initial version.
+
+ * erc-pcomplete.el 1.16:
+ * (erc-pcomplete): Fix so that cycle-completion works again.
+ * (pcomplete-parse-erc-arguments): If there is a space after the last word
+ before point, we need to return a "" arg, and it's position.
+
+ * erc-dcc.el 1.52: Fix to pcomplete/erc-mode/DCC
+
+ * erc-dcc.el 1.51: * (pcomplete/erc-mode/DCC): New function
+
+ * erc-dcc.el 1.50: *** empty log message ***
+
+ * erc-dcc.el 1.49: Move code around, just basic changes
+
+2003-01-11 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-stamp.el 1.22 (erc-insert-timestamp-right):
+ Check wether erc-fill-column is
+ available before using it. Else default to fill-column or if
+ everything else fails, the window width of the current window. For the
+ fill-columns, use them directly as the starting position for the
+ timestamp.
+
+2003-01-11 Andreas Fuchs <asf@void.at>
+
+ * erc-stamp.el 1.21:
+ erc-insert-timestamp-right: use correct window's window-width. If
+ buffer is not in a window, use erc-fill-column.
+
+2003-01-11 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.48: * erc-dcc.el 1.48: * (erc-dcc-do-LIST-command): Fix
+
+ * erc-dcc.el 1.47:
+ * buffer-local variables erc-dcc-sent-marker and erc-dcc-send-confirmed marker removed
+ Keep This info in erc-dcc-member :sent and :confirmed plist values
+ * : * :buffer plist for :type 'SEND removed, since we can get this with (marker-buffer
+ * erc-dcc-send-connect-hook: New hook, defaults to erc-dcc-send-block and erc-dcc-send-conntected, which now prints a msg...
+
+ * erc-dcc.el 1.46:
+ * (erc-dcc-chat-accept): Renamed from erc-dcc-chat. Callers updated.
+ * (erc-dcc-chat): Renamed from erc-dcc-chat-request.
+ Callers updated, and interactive form added.
+ * (erc-dcc-server-accept): No longer do any type-specific stuff.
+ * (erc-dcc-chat-sentinel): Call erc-dcc-chat-setup if event is "open from "
+ from here, otherwise call erc-dcc-chat-close.
+
+ * (
+
+ * erc-dcc.el 1.45: *** empty log message ***
+
+ * erc-dcc.el 1.43: Moved some functions around.
+ Doc string fixes.
+ "/dcc send nick filename" works now
+
+2003-01-11 Alex Schroeder <alex@gnu.org>
+
+ * erc.el 1.421 (erc-send-command): Fixed flood protect message.
+
+ * erc-button.el 1.38 (erc-button-syntax-table): Make `-' a legal nick
+ constituent.
+
+2003-01-10 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.42: Some more steps toward dcc send.
+
+2003-01-10 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-notify.el 1.14 (erc-notify-timer):
+ Changed to make it IRC-case-insensitive when comparing nicks.
+ (erc-notify-JOIN): Changed to make it IRC-case-insensitive when comparing nicks.
+ (erc-notify-NICK): Changed to make it IRC-case-insensitive when comparing nicks.
+ (erc-notify-QUIT): Changed to make it IRC-case-insensitive when comparing nicks.
+ (erc-cmd-NOTIFY): Now "/notify -l" lists the nicks on your notify list. Now
+ when you remove a nick from your notify list, you no longer recieve a spurious
+ signoff notification for that nick. Changed to make it IRC-case-insensitive when
+ comparing nicks.
+
+ * erc.el 1.420 (erc-ison-p):
+ Fixed so it calls erc-member-ignore-case instead of member.
+
+ * erc.el 1.419 (erc-member-ignore-case):
+ New function. Just like member-ignore-case, but obeys
+ the IRC protocol case matching rules.
+
+2003-01-10 Damien Elmes <erc@repose.cx>
+
+ * erc-dcc.el 1.41:
+ (erc-dcc-do-GET-command), (erc-dcc-get-file): use the plist syntax, this
+ fixes dcc get again
+
+2003-01-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.418: erc-complete-functions: New variable.
+ erc-mode-map: Bind \t to 'erc-complete-word
+ erc-complete-word: New function.
+
+ * erc-pcomplete.el 1.15 (erc-pcomplete-mode):
+ Use new erc-complete-functions
+ (erc-pcomplete): Check that we're in the input line, else return nil.
+
+ * erc-button.el 1.37 (erc-button-mode): Use new erc-complete-functions
+ erc-button-old-tab-command: Removed.
+ (erc-button-next-or-old): Removed
+ (erc-button-next): check that we're not in the input line, else just return nil.
+
+2003-01-10 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.40: cleanup
+
+ * erc-dcc.el 1.39:
+ * (erc-dcc-chat-request): No longer use erc-send-ctcp-message.
+
+ * erc-dcc.el 1.38:
+ * (erc-dcc-no-such-nick): Also call delete-process if we have a peer already
+
+ * erc-dcc.el 1.37:
+ * (erc-dcc-no-such-nick): New function, server event handler for event 401.
+ If we send a CTCP message requesting something dcc related, we set up an
+ entry in erc-dcc-list before sending the request (for the server proc object
+ for listening conns for example). But if that nick does not exist
+ on that server, we now nicely cleanup erc-dcc-list again.
+
+2003-01-09 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.36: Moved code around a bit, and doc fixes
+
+ * erc-dcc.el 1.35: *** empty log message ***
+
+ * erc-dcc.el 1.34: Rename erc-dcc-plist to erc-dcc-list
+
+2003-01-09 Damien Elmes <erc@repose.cx>
+
+ * erc-dcc.el 1.33 (erc-dcc-server (erc-dcc-chat-setup):
+ use erc's (erc-setup-buffer) to determine how to
+ display new DCC windows
+ (erc-dcc-chat-buffer-killed): buffer-local hook for DCC buffers to close the
+ process
+ (erc-dcc-chat-close): code common to a killed buffer or a disconnection from
+ the other side
+ (erc-dcc-chat-sentinel): use (erc-dcc-chat-close)
+ (erc-dcc-server-accept): use (erc-log) instead of (message)
+
+ * erc.el 1.417:
+ (erc), (erc-setup-buffer): factor out window generation code so DCC can use
+ it too
+
+ * erc-dcc.el 1.32:
+ (erc-dcc-do-CLOSE-command), (erc-dcc-do-LIST-command): work with erc-dcc-plist
+
+ * erc-dcc.el 1.31:
+ erc-dcc-alist: became erc-dcc-plist, so we can more easily grab particular
+ properties
+ dcc catalog: unify use of DCC: and [dcc] (either's fine, but let's be
+ consistent)
+ (erc-dcc-member): takes an arbitrary list of constraints now
+ (erc-dcc-proc-member): removed, as (erc-dcc-member) can be used for this
+ (erc-dcc-do-CHAT-command): use the catalog to show the user what's going on
+ (erc-dcc-chat-server): removed
+ (erc-dcc-server): takes name sentinel and filter arguments, can be used for
+ both send and chat now
+
+ .. this release means all send/get support is broken until we fix up the
+ things that still expect to be using an alist. this include /dcc list, /dcc
+ close
+
+2003-01-09 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-ring.el 1.9 (erc-previous-command):
+ If you have a partially typed input line and press M-p,
+ you lose what you typed. Now we save it so you can come back to it.
+
+2003-01-09 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-ring.el 1.8 (erc-add-to-input-ring): s/nullp/null/
+
+2003-01-09 Damien Elmes <erc@repose.cx>
+
+ * erc-ring.el 1.7 (erc-add-to-input-ring):
+ set up the ring if it's not already setup
+
+ * erc-dcc.el 1.30 (erc-dcc-member): case insensitive match of nicknames
+ (erc-dcc-do-CHAT-command): echo what we're doing (at least for now)
+
+2003-01-09 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.29: (temporarily) fix erc-process setting...
+
+ * erc-dcc.el 1.28: * (erc-dcc-chat-send-line): Removed
+
+ * erc.el 1.416:
+ Check if target is stringp (we can now also have 'dcc as value...)
+
+ * erc-dcc.el 1.27 (erc-dcc-chat-send-input-line):
+ New function, used for
+ erc-send-input-line-function.
+ Use erc-send-current-line now.
+
+ * erc-dcc.el 1.26: evt to elt...
+
+ * erc-dcc.el 1.25: Remove () from a var (how silly!)
+
+ * erc-dcc.el 1.24: * (erc-dcc-get-host): Use format-network-address.
+ * (erc-dcc-host): Change semantic. If erc-dcc-host is set, use it.
+ Otherwise, try to figure out the host by calling erc-dcc-get-host.
+ * (erc-dcc-server-port): New variable.
+ * erc-dcc-chat-log: Renamed to erc-dcc-server-accept
+
+ * erc-dcc.el 1.23 (erc-dcc-do-CHAT-command):
+ Change arg of call to erc-dcc-chat-request from elt to nick
+
+2003-01-09 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.415 (erc-send-current-line):
+ Now rejects multi-line commands (i.e., lines that
+ start with "/" and contain newlines).
+
+2003-01-09 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-button.el 1.36:
+ Functionality to use TAB to jump to the next button:
+
+ (erc-button-next-or-old): New function.
+ (erc-button-next): New function.
+ erc-button-keymap: added erc-button-next
+ erc-button-old-tab-command: New variable.
+ define-erc-module button: Add and remove 'erc-button-next-or-old as
+ appropriate.
+
+2003-01-09 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.414:
+ New variable: erc-auto-reconnect (defaults to t). If non-nil, ERC will
+ automatically reconnect to a server after an unexpected disconnection.
+ (erc-process-sentinel): Changed to refer to variable erc-auto-reconnect.
+
+2003-01-08 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.413:
+ * erc-send-input-line-function: New variable, used for dispatch...
+
+2003-01-08 Damien Elmes <erc@repose.cx>
+
+ * erc-dcc.el 1.22 (erc-dcc-chat-sentinel):
+ check event type before killing process
+ (erc-dcc-chat-log): new, handles the setup of dcc chats for incoming
+ connections
+ (erc-dcc-chat): use (erc-dcc-chat-setup)
+ (erc-dcc-chat-setup): code common to incoming and outgoing DCC chats
+ (erc-dcc-chat-request): request a DCC chat with another user
+ (erc-dcc-proc-member): locate a member in erc-dcc-alist by process
+
+ The very first ERC to ERC DCC chat was held between delysid and resolve today!
+
+2003-01-08 Mario Lang <mlang@delysid.org>
+
+ * erc-track.el 1.44 (erc-all-buffer-names):
+ Check for erc-dcc-chat-mode too
+
+2003-01-08 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-ring.el 1.6, erc.el 1.412 (erc-kill-input):
+ Resets erc-input-ring-index to nil, so that invoking this
+ command conceptually puts you after your most recent input in the input
+ history.
+ (erc-previous-command and erc-next-command): Changed so that history movement
+ is more intuitive. Also preserves the blank input line that marks the
+ place after the newest command in the history ring (i.e., you'll see a
+ blank command once every trip around the ring in either direction).
+
+2003-01-08 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.21 (erc-dcc-chat): Add docstring
+ Add self-test.
+ Fix error if /dcc chat nick doesnt find the nick
+
+2003-01-08 Francis Litterio <franl@users.sourceforge.net>
+
+ * Makefile 1.12:
+ Changed so that "make" works correctly under Cygwin. Before this change, the
+ pathname passed to Emacs on the command line under Cygwin had the form
+ "/cygwin/c/...", which prevented emacs from finding the file. Now the pathname
+ has the form "c:/...". This works for any drive letter.
+
+2003-01-08 Mario Lang <mlang@delysid.org>
+
+ * erc-button.el 1.35: reindent some code, and add TODO to comments
+
+ * erc-dcc.el 1.20: *** empty log message ***
+
+ * erc-dcc.el 1.19: Make dcc-chat-ended a notice
+ Remove now bogus comment
+
+2003-01-08 Damien Elmes <erc@repose.cx>
+
+ * erc-dcc.el 1.18 (erc-pack-int): from erc-packed-int
+ (erc-unpack-int): new
+
+ * erc-dcc.el 1.17 (erc-unpack-str): added
+
+2003-01-08 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.411 (erc-server-482):
+ New handler, handles KICK reply if you're not channel-op
+
+ * erc-dcc.el 1.16: Document SEND in erc-dcc-alist.
+ Move sproc, parent-proc and file into erc-dcc-alist
+
+ * erc-dcc.el 1.15: stubs
+
+ * erc-dcc.el 1.14 (erc-dcc-get-host):
+ Change :iface to :local since Kim committed it now to CVS emacs
+
+ * erc-dcc.el 1.13 (erc-dcc-get-host):
+ New function, requires the not-yet-in-CVS-emacs local-address.patch to process.c.
+ Some other minor additions
+
+2003-01-08 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.410 (erc-cmd-IGNORE):
+ Now returns t to prevent "Bad syntax" error.
+ (erc-cmd-UNIGNORE): Now returns t to prevent "Bad syntax" error.
+ (erc-server-PRIVMSG-or-NOTICE): Capitalized first word in message to user.
+
+ * erc.el 1.409 (erc-scroll-to-bottom):
+ Temporarilly bind resize-mini-windows to nil so that
+ users who have it set to a non-nil value will not suffer from premature
+ minibuffer shrinkage due to the below recenter call. I have no idea why
+ this works, but it solves the problem, and has no negative side effects.
+
+2003-01-07 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-dcc.el 1.12:
+ erc-dcc-ctcp-query-chat-regexp: The IP is not really an IP, but a
+ number (no . allowed there).
+ (erc-dcc-send-ctcp-string): use let* here to avoid cluttering up the
+ match data.
+ Also, use erc-decimal-to-ip to get the IP.
+ (erc-ip-to-decimal): Removed some pasted ERC timestamps
+ (erc-decimal-to-ip): New function.
+ erc-dcc-chat-mode-map: Return map in the initialization.
+
+2003-01-07 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-match.el 1.19 (erc-match-fool-p):
+ Changed to call erc-match-directed-at-fool-p instead of
+ erc-directed-at-fool-p.
+
+2003-01-07 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.11 (erc-cmd-DCC):
+ Change (cond ... (t nil)) to (when ...)
+
+ * erc-dcc.el 1.10: Use erc-current-nick-p
+
+2003-01-07 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.408:
+ erc-join-buffer: Added 'window-noselect to docstring and :type.
+ erc-auto-query: Added 'window-noselect to :type.
+ (erc): Treat erc-join-buffer being 'window-noselect appropriately.
+
+ * erc.el 1.407 (erc-current-nick-p): New function.
+ (erc-nick-equal-p): New function.
+ (erc-already-logged-in), (erc-server-JOIN), (erc-auto-query),
+ (erc-server-PRIVMSG-or-NOTICE): Use erc-current-nick-p.
+ (erc-update-channel-member): Use erc-nick-equal-p.
+
+ * erc-match.el 1.18 (erc-match-current-nick-p):
+ Renamed from erc-current-nick-p
+ (erc-match-pal-p): Renamed from erc-pal-p
+ (erc-match-fool-p): Renamed from erc-fool-p
+ (erc-match-keyword-p): Renamed from erc-keyword-p
+ (erc-match-dangerous-host-p): Renamed from erc-dangerous-host-p
+ (erc-match-directed-at-fool-p): Renamed from erc-directed-at-fool-p
+ (erc-match-message): Use erc-match-TYPE-p instead of erc-TYPE-p
+
+ * erc.el 1.406:
+ Support for IRCnets' "nick/channel temporarily unavailable"
+
+ (erc-nickname-in-use): New function (mostly copied from erc-server-433).
+ (erc-server-433): Use erc-nickname-in-use
+ (erc-server-437): New function.
+ erc-server-hook-list: Added (437 erc-server-437).
+
+2003-01-07 Mario Lang <mlang@delysid.org>
+
+ * erc-fill.el 1.21: Add autoload cookie
+
+ * erc-notify.el 1.13:
+ Now also pass SERVER argument to signon/off hooks, and provide a erc-notify-signon/off function for echo-area printing
+
+ * erc-notify.el 1.12 (erc-notiy-QUIT):
+ Change use of delq to delete, delq does not work with strings
+
+2003-01-06 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.405 (erc-ctcp-query-VERSION):
+ v%s -> %s, so we are no longer vVersion...
+
+2003-01-06 Mario Lang <mlang@delysid.org>
+
+ * erc.el 1.404: Small change to erc-ison-p, and fixme tag
+
+2003-01-06 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el 1.403 (erc):
+ Fixed bug where variable "away" would be nil in new channel buffers
+ even if the user is away when joining the channel.
+ (erc-strip-controls): Fixed a bug where erc-strip-controls accidentally
+ removed all text properties from the string.
+
+2003-01-06 Mario Lang <mlang@delysid.org>
+
+ * erc-dcc.el 1.9:
+ Some stub functions, some code, nothing really works yet
+
+ * erc.el 1.402 (erc-ison-p): New function
+
+ * erc-dcc.el 1.8: Some functions which will be needed for dcc send
+
+ * erc-dcc.el 1.7 (erc-ip-address-to-decimal):
+ New function, thanks lawrence
+
+ * erc-dcc.el 1.6: Again, simplify code, fix stuff, DCC CHAT works now
+
+ * erc-dcc.el 1.5: Many fixes, chat nearly works now
+
+ * erc-netsplit.el 1.7: Also detect fast netsplit/joins
+
+ * erc-dcc.el 1.4: some more fixes
+
+ * erc-dcc.el 1.3: Fixup stage 1, now dcc get works
+
+ * erc-dcc.el 1.2: make /dcc LIST work
+
+ * erc-dcc.el 1.1:
+ Initial checkin, dont use it! its really far from complete. Hackers: help!
+
+ * erc-notify.el 1.11:
+ New function erc-notify-NICK, and added signon/off hooks which were missing
+
+2003-01-05 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el 1.401 (erc-truncate-buffer-to-size):
+ set inhibit-read-only to t for the
+ deletion. This is usually done by the function calling the hook, but
+ not if it's called interactively. Also, rewrote some weird if/if
+ combination.
+
+ * erc-track.el 1.43 (erc-track-shortennames):
+ Documentation fix (erc-all-buffers is really
+ erc-all-buffer-names)
+
+ These changes make server buffers be tracked as well, as there are
+ quite a few interesting things going on there (e.g. CTCP etc.)
+ (erc-all-buffer-names): Check for (eq major-mode 'erc-mode) instead of
+ erc-default-recipients.
+ (erc-track-modified-channels): Don't require a default target (e.g.,
+ this-channel being non-nil)
+
+2003-01-03 Damien Elmes <erc@repose.cx>
+
+ * erc.el 1.400:
+ erc-auto-query: can now be set to a symbol to control how new messages should
+ be popped up (or not popped up, as the case may be)
+ (erc-query): new function which handles the bulk of what (erc-cmd-QUERY) did
+ previously
+ (erc-cmd-QUERY): use (erc-query)
+ (erc-auto-query): use (erc-query)
+
+ * erc.el 1.399 (erc-current-logfile):
+ Downcase result of log generation function, as IRC is
+ case insensitive. Fixes problems where "/query user" results in a different
+ log file to a query from "User". Avoided adding an extra flag to control this
+ behavior - if you think this was the wrong decision, please correct it and
+ I'll remember it for next time.
+
+ Copyright (C) 2003 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted provided the copyright notice and this notice are preserved.
+
+;; arch-tag: 808865e1-3cce-4c5b-9997-95a8b7a9d384
diff --git a/lisp/erc/ChangeLog.2004 b/lisp/erc/ChangeLog.2004
new file mode 100644
index 00000000000..e45652d0daf
--- /dev/null
+++ b/lisp/erc/ChangeLog.2004
@@ -0,0 +1,2074 @@
+2004-12-29 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-goodies.el (erc-interpret-controls-p): Changed docstring to
+ reflect the new meaning if this is set to 'remove.
+ (erc-controls-interpret): Rephrased docstring to be more accurate.
+ (erc-controls-strip): New function that behaves like the
+ recently-removed erc-strip-controls -- it removes all IRC color
+ and highlighting control characters.
+ (erc-controls-highlight): Changed to support the new 'remove value
+ that variable erc-interpret-controls-p might have.
+
+2004-12-28 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-ibuffer.el, erc-list.el, erc-page.el, erc-speedbar.el:
+ Changed all calls to erc-interpret-controls (which no longer
+ exists) to call erc-controls-interpret (the new name of the same
+ function).
+
+2004-12-28 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-goodies.el (erc-controls-interpret): Added this function to
+ replace the recently-removed erc-interpret-controls. Also added
+ a (require 'erc) to solve a byte-compile problem.
+
+2004-12-28 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-controls-interpret): Added this function to replace
+ the recently-removed erc-interpret-controls.
+
+2004-12-27 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-truncate.el (erc-truncate-buffer-to-size): Check for
+ logging even better (via lawrence).
+
+2004-12-26 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-truncate.el (erc-truncate-buffer-to-size): Much saner
+ logging detection (via lawrence).
+
+2004-12-25 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-goodies.el (erc-controls-highlight): Treat single C-c
+ correctly.
+
+2004-12-24 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-goodies.el, erc.el: Deleted IRC control character processing
+ and implemented a sane version in erc-goodies.el as a module.
+
+ * erc.el (erc-merge-controls, erc-interpret-controls,
+ erc-decode-controls, erc-strip-controls, erc-make-property-list,
+ erc-prepend-properties): Removed.
+
+ (erc-interpret-controls-p, erc-interpret-mirc-color, erc-bold-face
+ erc-inverse-face, erc-underline-face, fg:erc-color-face0,
+ fg:erc-color-face1, fg:erc-color-face2, fg:erc-color-face3,
+ fg:erc-color-face4, fg:erc-color-face5, fg:erc-color-face6,
+ fg:erc-color-face7, fg:erc-color-face8, fg:erc-color-face9,
+ fg:erc-color-face10, fg:erc-color-face11, fg:erc-color-face2,
+ fg:erc-color-face13, fg:erc-color-face14, fg:erc-color-face15,
+ bg:erc-color-face1, bg:erc-color-face2, bg:erc-color-face3,
+ bg:erc-color-face4, bg:erc-color-face5, bg:erc-color-face6,
+ bg:erc-color-face7, bg:erc-color-face8, bg:erc-color-face9,
+ bg:erc-color-face10, bg:erc-color-face11, bg:erc-color-face2,
+ bg:erc-color-face13, bg:erc-color-face14, bg:erc-color-face15,
+ erc-get-bg-color-face, erc-get-fg-color-face,
+ erc-toggle-interpret-controls): Moved.
+
+ * erc-goodies.el (erc-beep-p, irccontrols, erc-controls-highlight,
+ erc-controls-propertize): New.
+
+2004-12-24 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-goodies.el, erc.el: The Small Extraction of Stuff[tm] commit.
+ Moved some functions from erc.el to erc-goodies.el, and
+ transformed them to erc modules in the process.
+ - imenu autoload stuff moved. I don't know why it is here at all.
+ - Moved: scroll-to-bottom, make-read-only, distinguish-noncommands,
+ smiley, unmorse, erc-occur (the last isn't a module, but still
+ moved)
+ (erc-input-line-position, erc-add-scroll-to-bottom,
+ erc-scroll-to-bottom, erc-make-read-only, erc-noncommands-list,
+ erc-send-distinguish-noncommands, erc-smiley, erc-unmorse,
+ erc-occur): Moved from erc.el to erc-goodies.el.
+ (smiley): Module moved from erc.el to erc-goodies.el.
+ (scrolltobottom, readonly, noncommands, unmorse): New modules.
+
+2004-12-20 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: (erc-format-away-status): Use `a', not `away' - that's
+ why it's there.
+ (erc-update-mode-line-buffer): The values of `mode-line-process'
+ and `mode-line-buffer-identification' are normally lists.
+ Conform.
+
+2004-12-18 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: (erc-process-ctcp-query, erc-process-ctcp-reply): Display
+ message in the active window, not the server window.
+
+2004-12-16 Edward O'Connor <ted@oconnor.cx>
+
+ * erc-track.el (erc-track-position-in-mode-line): Check for
+ 'erc-track-mode variable with boundp. From Adrian Aichner
+ <adrian@xemacs.org>.
+
+2004-12-16 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-upcase-first-word): New function. The old way used
+ in erc-send-ctcp-message would eat consecutive whitespace etc.
+ (erc-send-ctcp-message, erc-send-ctcp-notice): Use it.
+
+2004-12-15 Edward O'Connor <ted@oconnor.cx>
+
+ * erc.el (erc-send-ctcp-message): Fix braino with my previous
+ patch. It always helps to C-x C-s before `cvs commit'.
+
+2004-12-15 Edward O'Connor <ted@oconnor.cx>
+
+ * erc.el (erc-send-ctcp-message): Only upcase the ctcp command,
+ and not the entire message. Revision 1.707 had broken /me.
+ Shouting is bad! :)
+
+2004-12-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nets.el (erc-networks-alist): Change undernet to Undernet as
+ is used in `erc-server-alist', so that completion works when using
+ `erc-server-select'. This should fix Debian bug #282003 (erc:
+ cannot connect to Undernet).
+
+2004-12-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-backend.el: (def-edebug-spec): Only run this if 'edebug is
+ available.
+
+2004-12-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: The last change to `erc-mode-line-format' introduced a
+ bug in Xemacs - it can't handle the #(" "...) strings at all. The
+ following changes fix the bug and simplify the mode-line handling
+ considerably. (erc-mode-line-format): Now defined as a string
+ which will be formatted using `format-spec' and take the place of
+ `mode-line-buffer-identification' in the mode line.
+ (erc-header-line-format): Now defined as a string to be formatted
+ using `format-spec'.
+ (erc-prepare-mode-line-format): Removed.
+ (erc-format-target, erc-format-target-and/or-server,
+ erc-format-away-status, erc-format-channel-modes): New functions.
+ Basically the old `erc-prepare-mode-line-format' split apart.
+ (erc-update-mode-line-buffer): Set
+ `mode-line-buffer-identification' to the formatted
+ `erc-mode-line-format', set `mode-line-process' to ": CLOSED" if
+ the connection has been terminated, and set `header-line-format'
+ (if it is bound) to the formatted `erc-header-line-format', then
+ do a `force-mode-line-update'.
+
+2004-12-12 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-modules): Disable modules removed with `customize'.
+ (erc-update-modules): Try to give a more descriptive error
+ message.
+
+2004-12-12 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-complete.el, erc.el, erc-list.el, erc-nets.el,
+ erc-nicklist.el, erc-pcomplete.el, erc-replace.el, erc-speak.el,
+ erc-truncate.el: (erc-buffers, erc-coding-systems, erc-display,
+ erc-mode-line-and-header, erc-ignore, erc-query,
+ erc-quit-and-part, erc-paranoia, erc-scripts, erc-old-complete,
+ erc-list, erc-networks, erc-nicklist, erc-pcomplete, erc-replace,
+ erc-truncate): New customization groups. (erc-join-buffer,
+ erc-frame-alist, erc-frame-dedicated-flag, erc-reuse-buffers): Use
+ 'erc-buffers as `:group'. (erc-default-coding-system,
+ erc-encoding-coding-alist): Use 'erc-coding-systems as `:group'.
+ (erc-hide-prompt, erc-show-my-nick, erc-prompt,
+ erc-input-line-position, erc-command-indicator, erc-notice-prefix,
+ erc-notice-highlight-type, erc-interpret-controls-p,
+ erc-interpret-mirc-color, erc-minibuffer-notice,
+ erc-format-nick-function): Use 'erc-display as `:group'.
+ (erc-mode-line-format, erc-header-line-format,
+ erc-header-line-uses-help-echo-p, erc-common-server-suffixes,
+ erc-mode-line-away-status-format): Use 'erc-mode-line-and-header
+ as `:group'.
+ (erc-hide-list, erc-ignore-list, erc-ignore-reply-list,
+ erc-minibuffer-ignored): Use 'erc-ignore as `:group'.
+ (erc-auto-query, erc-query-on-unjoined-chan-privmsg,
+ erc-format-query-as-channel-p): Use 'erc-query as `:group'.
+ (erc-kill-buffer-on-part, erc-kill-queries-on-quit,
+ erc-kill-server-buffer-on-quit, erc-quit-reason-various-alist,
+ erc-part-reason-various-alist, erc-quit-reason, erc-part-reason):
+ Use 'erc-quit-and-part as `:group'.
+ (erc-verbose-server-ping, erc-paranoid, erc-disable-ctcp-replies,
+ erc-anonymous-login, erc-show-channel-key-p): Use 'erc-paranoia as
+ `:group'.
+ (erc-startup-file-list, erc-script-path, erc-script-echo): Use
+ 'erc-scripts as `:group'.
+ (erc-nick-completion, erc-nick-completion-ignore-case,
+ erc-nick-completion-postfix): Use 'erc-old-complete as `:group'.
+ (erc-chanlist-progress-message, erc-no-list-networks,
+ erc-chanlist-frame-parameters, erc-chanlist-hide-modeline,
+ erc-chanlist-mode-hook): Use 'erc-list as `:group'.
+ (erc-server-alist, erc-networks-alist): Use 'erc-networks as
+ `:group'.
+ (erc-settings): Use `defvar' instead of `defcustom' since this is
+ only a draft which doesn't work.
+ (erc-nicklist-window-size): Use 'erc-nicklist as `:group'.
+ (erc-pcomplete-nick-postfix,
+ erc-pcomplete-order-nickname-completions): Use 'erc-pcomplete as
+ `:group'.
+ (erc-replace-alist): Use 'erc-replace as `:group'.
+ (erc-speak-filter-timestamp): Use 'erc-speak as `:group'.
+ (erc-max-buffer-size): Use 'erc-truncate as `:group'.
+
+2004-12-12 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-scroll-to-bottom): Go to the end of the buffer
+ before recentering. This allows editing multiple lines more
+ conveniently in CVS Emacs. This also undos a change by antifuchs
+ who said this goto-char would mess up redisplay. Extensive testing
+ couldn't reproduce that problem.
+
+2004-12-12 Brian Palmer <bpalmer@gmail.com>
+
+ * erc.el (erc-send-ctcp-message): upcase the ctcp message (so that
+ version becomes VERSION, for example).
+ (erc-iswitchb): Make the argument optional in non-interactive
+ invocation, so erc-iswitchb can be substituted directly for
+ iswitchb in code.
+
+2004-12-11 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-track.el (erc-track-position-in-mode-line): Allow for the
+ fact that `erc-track-mode' isn't bound when file is loaded.
+
+2004-12-11 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-track.el (erc-track-position-in-mode-line): New customizable
+ variable. (erc-track-remove-from-mode-line): New function.
+ Remove `erc-modified-channels-string' from the mode-line.
+ (erc-track-add-to-mode-line): New function. Add
+ `erc-modified-channels-string' to the mode-line using the value of
+ `erc-track-position-in-mode-line' to determine whether to add it
+ to the beginning or the end of `mode-line-modes' (only available
+ with GNU Emacs versions above 21.3) or to the end of
+ `global-mode-string'.
+ (erc-track-mode, erc-track-when-inactive-mode): Use the new
+ functions.
+
+2004-12-11 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: (erc-cmd-BANLIST): Use (buffer-name) and not
+ (erc-default-target) for the buffer name - buffer names are case
+ sensitive.
+
+2004-12-11 Brian Palmer <bpalmer@gmail.com>
+
+ * erc.el (erc-message-type): Added the message "MODE" to the known
+ erc-message-type widget, so that (for example) people can tell
+ erc-track-exclude-types to ignore mode changes. The others tag
+ also needed to be made an inline list, so that it's merged with
+ the given constants, instead of being inserted as a list.
+
+2004-12-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el, erc.el: Update to get ERC look nicely in CVS Emacs.
+
+ * erc.el (erc-mode-line-format): When on CVS emacs, use the new
+ format.
+
+ * erc-track.el (track module): When on CVS emacs, modify
+ mode-line-modes instead of global-mode-string. The latter is way
+ to far too the right.
+
+2004-11-18 Mario Lang <mlang@delysid.org>
+
+ * Makefile, debian/changelog: debian release 20041118-1
+
+2004-11-03 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-button.el (erc-button-buttonize-nicks): Set default value to
+ `t'. Updated documentation and customization `:type' to reflect
+ usage.
+
+2004-10-29 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * AUTHORS: Added self.
+
+2004-10-17 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-list.el: Added local variables for this file.
+ (erc-list-version): New.
+ (erc-cmd-LIST): Take &rest rather than &optional arguments, as was
+ done in revision 1.21. Allow for input when called interactively.
+ (erc-prettify-channel-list, erc-chanlist-toggle-sort-state): Use
+ `unless' instead of when not.
+
+2004-10-17 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-backend.el (erc-handle-unknown-server-response): Fixed so
+ that the contents are only shown once. (MOTD): Display lines in
+ the server buffer if it's the first MOTD sent upon connection.
+ This is to avoid the problem of having the MOTD of one server
+ showing up in another server's buffer if it took a while to get
+ connected.
+ (004): Fixed to show the user modes and channel modes correctly.
+ (303): Now displays the nicknames returned by ISON instead of the
+ user's nickname.
+ (367, 368): Moved up into 300's section of the code. Added
+ documentation. Use `multiple-value-bind' to set variables in 367.
+ (391): Fixed so that the server name is shown correctly.
+
+2004-10-17 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-process-sentinel): Use CPROC instead of
+ `erc-process' in debug message. Should fix a bug where an error
+ saying "Buffer *scratch* has no process" would occur when
+ disconnected.
+ (erc-cmd-SV): Check for X toolkit after checking for more specific
+ features. (erc--kill-server): Set `quitting' to non-nil so that
+ we don't automatically reconnect.
+
+2004-10-05 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: (erc-ignored-user-p): Don't require regexes to match the
+ beginning.
+
+2004-09-11 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: group erc: Moved to 'applications (patch by bojohan)
+
+2004-09-08 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-button.el: (erc-button-remove-old-buttons): Remove 'keymap
+ not 'local-map.
+
+2004-09-03 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-backend.el: JOIN response handler: Typo fix of the last
+ commit.
+
+2004-09-03 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-backend.el: JOIN response handler: Run `erc-join-hook'
+ without arguments as specified in the docstring.
+
+2004-08-27 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-send-current-line): Removed unused variable SENTP.
+
+2004-08-19 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: ERC-SEND-COMPLETED-HOOK used to be run when the prompt
+ was already displayed. We restore this behavior (thanks to bojohan
+ and TerryP for noticing). We also fix the docstring of
+ ERC-SEND-COMPLETED-HOOK, since the hook is (and used to be) called
+ even if nothing was sent to the server.
+ (erc-send-completed-hook): Fixed docstring.
+ (erc-send-current-line): Add incantation for
+ erc-send-completed-hook.
+ (erc-send-input): Remove incantation for erc-send-completed-hook.
+
+2004-08-18 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-backend.el: response-handler 368: Use s368, not s367.
+
+2004-08-17 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-scroll-to-bottom): Don't scroll when we're not
+ connected anymore.
+
+2004-08-17 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-backend.el, erc.el: Handle /mode #emacs b output without
+ errors and such. First, handle unknown format specs gracefully
+ (that is, give a useful error). Then, provide handlers for the
+ banlist replies.
+
+ * erc-backend.el: New handler for 367 and 368. Removed from default
+ handler.
+
+ * erc.el: Provide english catalog for s367 and s368.
+ (erc-format-message): Give an error message when we don't find an
+ entry.
+
+2004-08-17 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-fill.el: erc-fill-variable could be confused about really
+ long nicks. We put an upper limit on the length of the fill prefix.
+ (erc-fill-variable): Adjust fill-prefix.
+ erc-fill-variable-maximum-indentation: New variable.
+
+2004-08-17 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-send-input): Fixed a bug where this function
+ referenced variable "input" instead of variable "str".
+
+2004-08-16 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-list.el (erc-chanlist-highlight-line): Fixed a bug where
+ this function failed to set the correct face for highlighting the
+ current line.
+
+2004-08-14 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-fill.el (erc-fill-variable): Don't fuck up when the
+ looking-at didn't work.
+
+2004-08-14 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-send-single-line): Call the hooks to change the
+ appearance for something only if we actually inserted something,
+ doh.
+ (erc-display-command): Display the prompt outside of the area that
+ set the text properties on.
+
+2004-08-14 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: Refactored erc-send-current-line. This should fix some
+ dormant bugs, and make the whole thing actually readable. Yay.
+ Some changes in behavior were made. Whitespace at the end of lines
+ sent is not removed anymore, but that shouldn't bother anyone.
+ Additionally, errors in commands or hooks shouldn't prevent the
+ prompt from showing up again now.
+ (erc-parse-current-line): Removed.
+ (erc-send-current-line): Refactored.
+ (erc-send-input): New function.
+ (erc-send-single-line): New function.
+ (erc-display-command): New function.
+ (erc-display-msg): New function.
+ (erc-user-input): New function.
+
+2004-08-13 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-cmd-SERVER): Use newer keyword call interface to
+ erc-select, and handle the error if it can't resolve the host.
+
+2004-08-11 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-backend.el, erc.el: erc-backend.el (404 response handler):
+ New function. We now support "cannot send to channel".
+
+ * erc.el (erc-define-catalog call): Added s404. erc.el
+ (erc-ctcp-ECHO-reply, erc-ctcp-CLIENTINFO-reply,
+ erc-ctcp-FINGER-reply, erc-ctcp-PING-reply, erc-ctcp-TIME-reply,
+ erc-ctcp-VERSION-reply): Display reply in the active window, not
+ the server window.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-with-all-buffers-of-server): Actually make it left
+ to right, doh.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-with-all-buffers-of-server): Evaluate left-to-right
+ so we don't surprise a user.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-process-input-line): Parentophobia! Another
+ paren-fix.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-backend.el: PRIVMSG NOTICE response handler: Killed one paren
+ too much. Poor paren. Got resurrected.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-track.el: Make server buffers showing up in the mode line
+ optional. Thanks to Daniel Knapp on the EmacsWiki for this patch.
+
+ erc-track-exclude-server-buffer: New variable.
+ (erc-track-modified-channels): Return a server buffer only if
+ erc-track-exclude-server-buffer is nil.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: (erc-cmd-DESCRIBE): Don't parse arguments.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-truncate.el: (erc-truncate-buffer-to-size): Use
+ erc-insert-marker, not (point-max), to decide the length of the
+ buffer. A long input line shouldn't make the buffer smaller.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-macs.el, erc-members.el: The change to hashes for channel
+ members has been made some time ago. Clean up the various tries to
+ do this in the past.
+
+ erc-macs.el: Removed. erc-members.el: Removed.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-backend.el, erc-ibuffer.el, erc-members.el, erc.el: Nothing
+ big changed here. Really. Uhm, maybe the info-buffers are gone or
+ so. Can't really remember. Don't worry, nothing important is
+ missing.
+
+ erc-speedbar.el looks nice btw, did you know?
+
+ Adjusted various places in erc.el, erc-backend.el, erc-ibuffer.el
+ and erc-members.el - too numerous to list here, sorry.
+
+ * erc.el: erc-use-info-buffers: Removed. erc-info-mode-map:
+ Removed.
+ (erc-info-mode): Removed.
+ (erc-find-channel-info-buffer): Removed.
+ (erc-update-channel-info-buffer): Removed.
+ (erc-update-channel-info-buffers): Removed.
+
+ * erc-members.el: erc-update-member renamed to
+ erc-update-channel-member for better clarity.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: This change improves the help output on a bogus command
+ invocation. We display the command as it would be typed by the
+ user, not as it is seen by Emacs.
+
+ (erc-get-arglist): Is now called erc-function-arglist, and returns
+ now an arglist without the enclosing parens.
+ (erc-command-name): New function.
+ (erc-process-input-line): Pass the command name, not the function
+ name.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: (erc-process-input-line): Fix bug when the command
+ doesn't have an arglist or no documentation. Thanks bojohan again
+ :)
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-match.el: (erc-add-entry-to-list),
+ (erc-remove-entry-from-list): Update docstring, a TEST argument is
+ not given.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-with-buffer): Really fix this docstring.
+
+2004-08-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-with-buffer): Fix double evaluation in macro, and
+ fix docstring.
+
+2004-08-10 Brian Palmer <bpalmer@gmail.com>
+
+ * erc.el (erc-cmd-JOIN): Use erc-member-ignore-case instead of
+ member-ignore-case.
+
+2004-08-09 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-backend.el: Define an "Edebug specification" for the
+ `define-erc-response-handler' macro. This means that one can step
+ through response handlers defined by this macro with edebug. Maybe
+ more macros would benefit from this?
+
+2004-08-09 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-pcomplete.el (pcomplete/erc-mode/CTCP): New function.
+ Completion for the /CTCP command. (erc-pcomplete-ctcp-commands):
+ New variable. List of ctcp commands.
+
+2004-08-09 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-list.el: Clean up docstrings.
+ (erc-prettify-channel-list): Extend properties to cover the entire
+ line, including the newline, to make it look
+ better.
+ (erc-chanlist-highlight-line): Ditto.
+ (erc-chanlist-mode-hook): Make it a defcustom.
+
+2004-08-09 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-compute-full-name): Typo fix, should be full-name,
+ not name.
+
+2004-08-09 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc): Setup the buffer to be shown in a window at the
+ end of this function. This enables 'window-noselect to work
+ properly.
+ (erc, erc-send-current-line): Fix some
+ goto-char/open-line/goto-char to goto-char/insert.
+
+2004-08-08 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-parse-user): Live with bogus info from bouncers.
+
+2004-07-31 Brian Palmer <bpalmer@gmail.com>
+
+ * erc.el (erc-select): Change the docstring to reflect the new
+ arguments; include the arguments in the docstring for non-cvs
+ emacs. Change the parameters to call erc-compute-* instead of
+ using the erc-* variables directly.
+ (erc-compute-server): Made argument optional.
+ (erc-compute-nick): ditto.
+ (erc-compute-full-name): ditto. (erc-compute-port): ditto.
+
+2004-07-30 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el: (erc-cmd-BANLIST): Fixed a bug where channel-banlist was
+ not reset to nil before fetching an updated banlist from the
+ server.
+
+2004-07-30 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el: (erc-cmd-BANLIST): Fixed a bug where the
+ 'received-from-server property on variable channel-banlist was not
+ being reset to nil. This fixes the symptom where one types
+ /BANLIST and sees "No bans for channel: #whatever" when you know
+ there are bans.
+
+2004-07-23 Brian Palmer <bpalmer@gmail.com>
+
+ * erc.el: (erc-select-read-args): Use erc-compute-nick to
+ calculate the default nickname
+
+2004-07-20 Brian Palmer <bpalmer@gmail.com>
+
+ * erc.el: (erc-process-sentinel-1): New function. This is an
+ auxiliary function refactored out of erc-process-sentinel to
+ decide a server buffer's fate (whether it should be killed, and
+ whether erc should attempt to auto-reconnect). Michael Olson
+ <mwolson@gnu.org> helped with this.
+ (erc-kill-server-buffer-on-quit): New variable. Used in
+ erc-process-sentinel-1 to decide whether to kill a server buffer
+ when the user quit normally.
+ (erc-process-sentinel): Auxiliary function erc-process-sentinel-1
+ split out. The function body has `with-current-buffer' wrapped
+ around it, to ensure separation of messages if multiple
+ connections were being made. Use `if' instead of `cond' in places
+ where the decision is binary. The last (useless, since the server
+ connection is closed) prompt in the server buffer is removed.
+ Color "erc terminated" and "erc finished" messages with
+ erc-error-face. Mark the buffer unmodified so that, if not killed
+ automatically, the user is not prompted to save it.
+
+2004-07-16 Brian Palmer <bpalmer@gmail.com>
+
+ * erc.el (erc-select-read-args): New function. Prompts the user
+ for arguments to pass to erc-select and erc-select-ssl.
+ (erc-select): Use (erc-select-read-args) when called interactively
+ to get its arguments. When non-interactively, use keyword
+ arguments.
+ (erc-select-ssl): Ditto.
+ (erc-compute-port): New function. Parallel to erc-compute-server,
+ but comes up with a default value for an IRC server's port.
+
+2004-07-16 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-match.el (erc-match-message): Quote the current nickname.
+
+2004-07-12 Brian Palmer <bpalmer@gmail.com>
+
+ * erc-list.el (erc-chanlist-mode): Remove explicit invocation of
+ erc-chanlist-mode-hook, since it's automatically invoked by
+ define-derived-mode
+
+2004-07-03 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-match.el (erc-match-current-nick-p): Quote current nick for
+ regexp parsing.
+
+2004-06-27 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-nickserv.el (erc-nickserv-identify-mode): Fix erroneous
+ parentheses in call to `completing-read'.
+
+2004-06-23 Alex Schroeder <alex@gnu.org>
+
+ * Makefile (release): Depend on autoloads, and copy erc-auto.el
+ into the tarball.
+
+2004-06-14 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-log-irc-protocol): Fixed minor bug where each line
+ received from a server was logged as two lines (one with text and
+ one blank).
+
+2004-06-08 Brian Palmer <bpalmer@gmail.com>
+
+ * erc-list.el (erc-chanlist-frame-parameters): Made customizable.
+ (erc-chanlist-header-face): Changed to use defface with some
+ reasonable defaults instead of make-face, and removed the
+ associated -face variable.
+ (erc-chanlist-odd-line-face): Ditto.
+ (erc-chanlist-even-line-face): Ditto.
+ (erc-chanlist-highlight-face): New variable. Holds a face used for
+ highlighting the current line.
+ (erc-cmd-LIST): Use erc-member-ignore-case instead of
+ member-ignore-case.
+ (erc-chanlist-post-command-hook): Change to move the highlight
+ overlay instead of refontifying the entire buffer.
+ (erc-chanlist-dehighlight-line): Added to detach the highlight
+ overlay from the buffer.
+
+2004-05-31 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: erc-mode-line-format: Add column numbers.
+
+2004-05-31 Adrian Aichner <adrian@xemacs.org>
+
+ * erc-autojoin.el: Typo fix.
+
+ * erc-dcc.el (erc-dcc-do-GET-command): Use expand-file-name.
+ (erc-dcc-get-file): XEmacs set-buffer-multibyte compatibility.
+
+ * erc-log.el: Append `erc-log-setup-logging' to
+ `erc-connect-pre-hook' so that `erc-initialize-log-marker' is run
+ first (markers are needed by `erc-log-setup-logging').
+ (erc-enable-logging): Docstring fix.
+ (erc-log-setup-logging): Move `erc-log-insert-log-on-open' to (1-
+ (point-max)) when doing `erc-log-insert-log-on-open'. Modified
+ version of a patch by Lawrence Mitchell.
+ (erc-log-all-but-server-buffers): Do `save-excursion' as well.
+ (erc-current-logfile): Pass buffer name as target
+ argument to `erc-generate-log-file-name-function' if
+ `erc-default-target' is nil.
+ (erc-generate-log-file-name-with-date): Use expand-file-name.
+ (erc-generate-log-file-name-short): Ditto.
+ (erc-save-buffer-in-logs): Do `save-excursion' and test whether
+ erc-last-saved-position is a marker.
+
+ * erc-members.el: Avoid miscompiling macro `erc-log' and
+ `with-erc-channel-buffer' by requiring 'erc at compile time.
+
+ * erc-sound.el: Use expand-file-name.
+
+ * erc.el (erc-debug-log-file): Ditto.
+ (erc-find-file): Ditto.
+
+2004-05-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el, erc-backend.el (erc-cmd-BANLIST): Added a missing "'"
+ that was preventing /BANLIST from working. In erc-backend.el,
+ added server repsonse handler for 367 and 368 reponses to get
+ /BANLIST working.
+
+2004-05-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el: Removed an eval-when-compile that was preventing the
+ byte-compiled version of this file from loading.
+
+2004-05-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el: Undid part of my last change. I suspect it was wrong.
+
+2004-05-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el: Silenced several byte-compiler warnings.
+
+2004-05-26 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-log-irc-protocol): Fixed problem where this function
+ misformatted IRC protocol text if multiple lines were received from
+ the server at one time.
+
+2004-05-25 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-toggle-debug-irc-protocol): Cosmetic changes to the
+ informational text in the *erc-protocol* buffer.
+
+2004-05-24 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-log-irc-protocol, erc-process-filter): Now the lines
+ inserted in the *erc-protocol* buffer are prefixed with the name
+ of the network to/from which the data is going/coming. This makes
+ reading the *erc-protocol* buffer much easier when connected to
+ multiple networks.
+
+2004-05-23 Jeremy Bertram Maitin-Shepard <jbms@gentoo.org>
+
+ * erc-backend.el: Fixes server message parsing so that command
+ arguments specified after the colon are not treated specially. All
+ arguments are added to the `command-args' field, and the
+ `contents' points to the last element in the `command-args' list.
+ This allows ERC to connect to networks such as Undernet. Although
+ keeping `contents' allows many of the response handlers to
+ continue to work as-is, many other are probably broken by this
+ patch.
+
+2004-05-20 Lawrence Mitchell <wence@gmx.li>
+
+ * HACKING: Add comment that C-c C-a can be useful if you write
+ ChangeLog entries using Emacs' standard functions.
+
+2004-05-17 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-speedbar.el: Ignore errors when attempting to require dframe
+ (there are a couple implementations of speedbar, one of which uses
+ of dframe).
+ (erc-speedbar-version): New.
+ (erc-speedbar-goto-buffer): Use dframe functions if dframe is
+ available.
+
+2004-05-17 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-autojoin.el: Added local variables for this file.
+ (erc-autojoin-add): The channel name is in `erc-response.contents'.
+
+2004-05-17 Mario Lang <mlang@delysid.org>
+
+ * erc-log.el: Dont autoload a define-key statement, erc-mode-map
+ might not be known yet
+
+2004-05-16 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-backend.el (erc-parse-server-response): Revert to original
+ `erc-parse-line-from-server' version, since new version breaks for
+ a number of edge cases.
+
+2004-05-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-backend.el (erc-handle-unknown-server-response): New
+ function. Added to `erc-default-server-functions'. Display
+ unknown responses to the user.
+ (221): Don't show nickname in modes list.
+ (254): Fixed to use 's254.
+ (303): Added docstring.
+ (315, 318, 323, 369): Ignored responses grouped together.
+ (391): New.
+ (406, 432): Use ?n, not ?c in `erc-display-message'.
+ (431, 445, 446, 451, 462, 463, 464, 465, 481, 483, 485, 491, 501,
+ 502): All error responsess with no arguments grouped together.
+
+2004-05-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-message-type-member): Use `erc-response.command'.
+ `erc-track-exclude-types' should be respected again.
+ (erc-cmd-TIME): Fixed to work with and without server given as
+ argument.
+ (erc-define-catalog): Added, s391, s431, s445, s446, s451, s462,
+ s463, s464, s465, s483, s484, s485, s491, s501, s502.
+
+2004-05-14 Lawrence Mitchell <wence@gmx.li>
+
+ * HACKING: Typo fix.
+
+2004-05-14 Lawrence Mitchell <wence@gmx.li>
+
+ * Makefile (erc-auto.el): Pass -f flag to rm so that we don't fail
+ if erc-auto.elc doesn't exist.
+
+2004-05-14 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-backend.el (erc-with-buffer): Autoload.
+ (erc-parse-server-response): XEmacs' `replace-match' only replaces
+ subexpressions when operating on buffers, not strings, work around
+ it.
+ (461): Command with invalid arguments is `second', not `third'.
+
+2004-05-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-notify.el (erc-notify-NICK): Use `erc-response.contents' to
+ get nickname.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-track.el: Indentation fixes.
+ (track-when-inactive): Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-notify.el (notify): Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+ (erc-notify-timer, erc-notify-JOIN, erc-notify-NICK)
+ (erc-notify-QUIT): Use new accessors for PARSED argument.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-nickserv.el (services, erc-nickserv-identify-mode): Use
+ `erc-server-FOO-functions', not `erc-server-FOO-hook.
+ (erc-nickserv-identify-autodetect): Use new accessors for PARSED
+ argument.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-netsplit.el (netsplit): Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+ (erc-netsplit-JOIN, erc-netsplit-MODE, erc-netsplit-QUIT): Use new
+ accessors for PARSED argument.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-nets.el: Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-menu.el (erc-menu-definition): Only allow listing of
+ channels if `erc-cmd-LIST' is fboundp.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-match.el: Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+ (erc-get-parsed-vector-nick, erc-get-parsed-vector-type): Use new
+ accessors for PARSED argument.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-list.el (erc-chanlist, erc-chanlist-322): Use new accessors
+ for PARSED argument. Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-ezbounce.el (erc-ezb-notice-autodetect): Use new accessors
+ for PARSED argument.
+ (erc-ezb-initialize): Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-dcc.el: Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+ (erc-dcc-no-such-nick): Use new accessors for PARSED argument.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-bbdb.el (erc-bbdb-whois, erc-bbdb-JOIN, erc-bbdb-NICK): Use
+ new accessors for PARSED argument.
+ (BBDB): Use `erc-server-FOO-functions', not `erc-server-FOO-hook.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-autojoin.el (autojoin): Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+ (erc-autojoin-add, erc-autojoin-remove): Use new accessors for
+ PARSED argument.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-autoaway.el (autoaway): Use `erc-server-FOO-functions', not
+ `erc-server-FOO-hook.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-backend): Require.
+ (erc-disconnected-hook, erc-join-hook, erc-quit-hook)
+ (erc-part-hook, erc-kick-hook): Docstring fix, we now use
+ `erc-server-FOO-functions', rather than `erc-server-FOO-hook'.
+ (erc-event-to-hook-name, erc-event-to-hook): Remove.
+ (erc-once-with-server-event)
+ (erc-once-with-server-event-global): Use `erc-get-hook'
+ (erc-process-filter): Use `erc-parse-server-response'.
+ (erc-cmd-IDLE, erc-cmd-BANLIST, erc-cmd-MASSUNBAN): New accessors
+ for PARSED argument. Rename all `erc-server-FOO-hook' to
+ `erc-server-FOO-functions'.
+ (erc-server-364-hook, erc-server-365-hook, erc-server-367-hook)
+ (erc-server-368-hook, erc-server-KILL-hook)
+ (erc-server-PONG-hook, erc-server-200-hook, erc-server-201-hook)
+ (erc-server-202-hook, erc-server-203-hook, erc-server-204-hook)
+ (erc-server-205-hook, erc-server-206-hook, erc-server-208-hook)
+ (erc-server-209-hook, erc-server-211-hook, erc-server-212-hook)
+ (erc-server-213-hook, erc-server-214-hook, erc-server-215-hook)
+ (erc-server-216-hook, erc-server-217-hook, erc-server-218-hook)
+ (erc-server-219-hook, erc-server-241-hook, erc-server-242-hook)
+ (erc-server-243-hook, erc-server-244-hook, erc-server-249-hook)
+ (erc-server-261-hook, erc-server-262-hook, erc-server-302-hook)
+ (erc-server-323-hook, erc-server-342-hook, erc-server-351-hook)
+ (erc-server-381-hook, erc-server-382-hook, erc-server-391-hook)
+ (erc-server-392-hook, erc-server-393-hook, erc-server-394-hook)
+ (erc-server-395-hook, erc-server-402-hook, erc-server-404-hook)
+ (erc-server-407-hook, erc-server-409-hook, erc-server-411-hook)
+ (erc-server-413-hook, erc-server-414-hook, erc-server-415-hook)
+ (erc-server-422-hook, erc-server-423-hook, erc-server-424-hook)
+ (erc-server-431-hook, erc-server-436-hook, erc-server-437-hook)
+ (erc-server-441-hook, erc-server-443-hook, erc-server-444-hook)
+ (erc-server-445-hook, erc-server-446-hook, erc-server-451-hook)
+ (erc-server-462-hook, erc-server-463-hook, erc-server-464-hook)
+ (erc-server-465-hook, erc-server-467-hook, erc-server-471-hook)
+ (erc-server-472-hook, erc-server-473-hook, erc-server-483-hook)
+ (erc-server-491-hook, erc-server-502-hook): Remove.
+ (erc-call-hooks, erc-parse-line-from-server): Remove
+ (erc-server-hook-list): Remove. Remove top-level call too.
+ (erc-server-ERROR, erc-server-INVITE, erc-server-JOIN)
+ (erc-server-KICK, erc-server-MODE, erc-server-NICK)
+ (erc-server-PART, erc-server-PING, erc-server-PONG)
+ (erc-server-PRIVMSG-or-NOTICE, erc-server-QUIT)
+ (erc-server-TOPIC, erc-server-WALLOPS, erc-server-001)
+ (erc-server-004, erc-server-005, erc-server-221, erc-server-252)
+ (erc-server-253, erc-server-254, erc-server-301, erc-server-303)
+ (erc-server-305, erc-server-306, erc-server-311-or-314)
+ (erc-server-312, erc-server-313, erc-server-317, erc-server-319)
+ (erc-server-320, erc-server-321, erc-server-322, erc-server-324)
+ (erc-server-329, erc-server-330, erc-server-331, erc-server-332)
+ (erc-server-333, erc-server-341, erc-server-352, erc-server-353)
+ (erc-server-366, erc-server-MOTD, erc-server-379)
+ (erc-server-401, erc-server-403, erc-server-405, erc-server-406)
+ (erc-server-412, erc-server-421, erc-server-432, erc-server-433)
+ (erc-server-437, erc-server-442, erc-server-461, erc-server-474)
+ (erc-server-475, erc-server-477, erc-server-481, erc-server-482)
+ (erc-server-501): Move to erc-backend.el
+ (erc-auto-query, erc-banlist-store, erc-banlist-finished)
+ (erc-banlist-update, erc-connection-established)
+ (erc-process-ctcp-query, erc-display-server-message): Use new
+ accessors for PARSED argument.
+
+2004-05-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-backend.el: (erc-parse-server-response)
+ (erc-handle-parsed-server-response, erc-get-hook)
+ (define-erc-response-handler): New functions.
+ (erc-response): New struct for server responses.
+ (erc-server-responses): New variable.
+ (erc-call-hooks): Move from erc.el and rework.
+ (ERROR, INVITE, JOIN, KICK, MODE, NICK, PART, PING, PONG)
+ (PRIVMSG, NOTICE, QUIT, TOPIC, WALLOPS, 001, MOTD, 376, 004)
+ (252, 253, 254, 250, 301, 303, 305, 306, 311, 312, 313, 315)
+ (317, 318, 319, 320, 321, 322, 324, 329, 330, 331, 332, 333)
+ (341, 352, 353, 366, 369, 379, 401, 403, 405, 406, 412, 421)
+ (432, 433, 437, 442, 461, 474, 477, 481, 482, 501, 323, 221)
+ (002, 003, 371, 372, 374, 375, 422, 251, 255, 256, 257, 258)
+ (259, 265, 266, 377, 378, 314, 475, 364, 365, 367, 368, 381)
+ (382, 391, 392, 393, 394, 395, 200, 201, 202, 203, 204, 205)
+ (206, 208, 209, 211, 212, 213, 214, 215, 216, 217, 218, 219)
+ (241, 242, 243, 244, 249, 261, 262, 302, 342, 351, 402, 404)
+ (407, 409, 411, 413, 414, 415, 423, 424, 431, 436, 441, 443)
+ (444, 445, 446, 451, 462, 463, 464, 465, 467, 471, 472, 473)
+ (483, 491, 502, 005, KILL): Move from erc.el and rework using
+ `define-erc-response-handler' and erc-response struct.
+
+2004-05-12 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: A few bug fixes to avoid errors after disconnect,
+ including the "Selecting deleted buffer" bug.
+ (erc-channel-user-op-p, erc-channel-user-voice-p): Make sure NICK
+ is non-nil (`erc-current-nick' can return nil).
+ (erc-server-buffer): Make sure the buffer isn't a #<killed
+ buffer>.
+ (erc-server-buffer-live-p): New function.
+ (erc-display-line, erc-join-channel, erc-prepare-mode-line-format,
+ erc-away-p): Use `erc-server-buffer-live-p' to make sure process
+ buffer exists.
+ (erc-send-current-line): If there is no server buffer, let the
+ user know.
+
+2004-05-12 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el, erc-log.el: C-c C-l keybinding now defined in
+ erc-log.el.
+ (erc-log-version): New.
+ (erc-cmd-JOIN): Fix applied for bug where /join -invite causes
+ errors when there's no `invitation'.
+
+2004-05-11 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: (erc-cmd-JOIN): Make sure `chnl' is non-nil before trying
+ to join anything (chnl is not set if /join -invite is used but
+ there's no `invitation').
+
+2004-05-10 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-log.el: Define C-c C-l keybinding outside of `erc-log-mode',
+ making it available all the time; autoload definition.
+ (erc-log-version): New.
+
+2004-05-09 Diane Murray <disumu@x3y2z1.net>
+
+ * AUTHORS, CREDITS, Makefile, erc-autoaway.el, erc-autojoin.el,
+ erc-button.el, erc-chess.el, erc-dcc.el, erc-ezbounce.el,
+ erc-fill.el, erc-ibuffer.el, erc-imenu.el, erc-lang.el,
+ erc-list.el, erc-log.el, erc-macs.el, erc-match.el, erc-members.el,
+ erc-menu.el, erc-nets.el, erc-netsplit.el, erc-nickserv.el,
+ erc-notify.el, erc-page.el, erc-ring.el, erc-speak.el,
+ erc-speedbar.el, erc-stamp.el, erc-track.el, erc-truncate.el,
+ erc-xdcc.el, erc.el: Applied all relevant bug fixes and code
+ cleanup made between the time of the ERC_4_0_RELEASE tag until now.
+
+2004-05-09 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-menu.el: Updated copyright years.
+
+2004-05-09 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-update-channel-info-buffer): Correct bug in sorting
+ of channel users. Tiny change from Andreas Schwab
+ <schwab@suse.de>.
+
+2004-05-09 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-fill.el (erc-fill-variable): Fix docstring.
+
+2004-05-09 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-button.el (erc-button-add-button): Use 'keymap
+ text-property, rather than 'local-map, since it's cross-emacs
+ compatible. Pass :mouse-down-action into `widget-convert-button'
+ as 'erc-button-click-button, to make XEmacs happy. Replace bogus
+ reference to erc-widget-press-button with erc-button-press-button.
+ (erc-button-click-button): New (ignored) first argument, to make
+ XEmacs behave when pressing buttons.
+ (erc-button-press-button): New (ignored) &rest argument.
+
+2004-05-09 Adrian Aichner <adrian@xemacs.org>
+
+ * erc-log.el (erc-conditional-save-buffer): Fix docstring
+ reference to erc-save-queries-on-quit.
+ (erc-conditional-save-queries): Ditto.
+
+2004-05-06 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-speedbar.el: Updated copyright years. Added local variables
+ for this file; fixed indenting.
+ (erc-speedbar): New group.
+ (erc-speedbar-sort-users-type): New variable.
+ (erc-speedbar-buttons): Handle query buffers (fixes a bug where an
+ error would be thrown if the current buffer was a query). Ignore
+ unknown buffers.
+ (erc-speedbar-expand-channel): Show limit and key with channel
+ modes. Sort users according to `erc-speedbar-sort-users-type'.
+ (erc-speedbar-insert-user): Fixed bug where only nicks with more
+ info were being listed, and those were shown twice.
+ (erc-speedbar-goto-buffer): Don't use dframe functions, as dframe
+ isn't available with the default speedbar.
+
+2004-05-06 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: (erc-sort-channel-users-alphabetically): New function.
+ (erc-server-412, erc-server-432, erc-server-475): New functions.
+ (erc-server-412-hook, erc-server-432-hook, erc-server-475-hook):
+ Use them.
+ (erc-server-401, erc-server-403, erc-server-405)
+ (erc-server-421, erc-server-474, erc-server-481): Use catalog
+ messages.
+ (erc-define-catalog): Added s401, s403, s405, s412, s421, s432,
+ s474, s475, and s481.
+
+2004-05-06 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nickserv.el: Added documentation to Commentary, Usage.
+ Removed `outline-mode' from file local variables.
+ (erc-services-mode): Use `erc-nickserv-identify-mode' to add
+ hooks.
+ (erc-nickserv-identify-mode): New function.
+ (erc-nickserv-identify-mode): New variable.
+ (erc-prompt-for-nickserv-password, erc-nickserv-passwords):
+ Changed docstring.
+ (erc-nickserv-identify-autodetect): Use
+ `erc-nickserv-call-identify-function'. Docstring change.
+ (erc-nickserv-identify-on-connect,
+ erc-nickserv-identify-on-nick-change,
+ erc-nickserv-call-identify-function): New functions.
+ (erc-nickserv-identify): PASSWORD is not optional. Autoload
+ function.
+
+2004-05-05 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-join-hook, erc-quit-hook, erc-part-hook,
+ erc-kick-hook, erc-connect-pre-hook): Now customizable.
+ (erc-nick-changed-functions): New hook.
+ (erc-server-NICK): Run `erc-nick-changed-functions' with the
+ arguments NEW-NICK and OLD-NICK.
+ (erc-channel-user-voice-p, erc-channel-user-voice-p): Shortened
+ docstring.
+
+2004-05-05 Lawrence Mitchell <wence@gmx.li>
+
+ * HACKING: New section on function/variable naming and coding
+ conventions.
+
+2004-05-05 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-wash-quit-reason): Quote regexp special characters
+ in NICK, LOGIN and HOST.
+
+2004-05-04 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-server-parameters): Typo fix in docstring.
+ (erc-input-line-position): `:type' is now a choice between integer
+ and nil. (erc-mode-map): Bind `erc-get-channel-mode-from-keypress'
+ to C-c C-o instead of C-c RET (C-c C-m). (erc-cmd-GQUIT): Use
+ REASON as argument when calling `erc-cmd-QUIT'.
+
+2004-05-03 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-nicklist.el: Initial version.
+
+2004-04-28 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-menu.el: Added local variables for file, fixed indenting.
+ (erc-menu-version): New variable.
+ (erc-menu-definition): "List channels": New. "Join channel": Use
+ `erc-connected' as test. "Start a query": New. "List channel
+ operators": New. "Input action": Moved up. "Set topic": Fixed
+ test so it's only active in channels. "Leave this channel": Moved
+ down. "Track hidden channel buffers": Removed. "Enable/Disable
+ ERC Modules": New.
+
+2004-04-28 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-mode-map): Removed binding for
+ `erc-save-buffer-in-logs' (moved to erc-log.el).
+ (erc-cmd-QUERY, erc-cmd-OPS): Now interactive.
+
+2004-04-28 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-log.el: Added local variables for this file.
+ (erc-log-channels-directory): Added directory as a choice in
+ `:type'.
+ (define-erc-module): Define and undefine key binding (C-c
+ C-l) for `erc-save-buffer-in-logs' here.
+
+2004-04-28 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nets.el: Added local variables for this file.
+ (erc-networks-alist): Fixed `:type' to work better in
+ customization.
+
+2004-04-28 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-match.el: Added local variables for file. (erc-keywords):
+ Use `list' instead of `cons' in `:type'. Fixes bug where mismatch
+ was shown in customization. (erc-current-nick-highlight-type):
+ Escape parentheses in docstring. Added keyword, nick-or-keyword as
+ options in `:type'.
+
+2004-04-28 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-stamp.el: Added local variables for file.
+ (erc-away-timestamp-format): Allow nil as a choice in `:type'.
+ (erc-timestamp-intangible): Changed `:type' to boolean.
+ (erc-timestamp-right-column): Added `:group' and `:type'.
+
+2004-04-28 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-modules): Added bbdb, log, match, sound, and stamp
+ as `:type' options; changed documentation for autojoin, fill,
+ pcomplete, track. (erc-prompt-for-channel-key): New variable.
+ (erc-join-channel): Only prompt for key if
+ `erc-prompt-for-channel-key' is non-nil. (erc-format-my-nick): New
+ function. (erc-send-message, erc-send-current-line): Use it.
+
+2004-04-24 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-track.el: (erc-track-modified-channels): Fix indentation.
+
+2004-04-24 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-match.el: (erc-hide-fools): Docstring fix.
+ (erc-log-matches-types-alist): Added `current-nick' to valid
+ choices.
+
+2004-04-20 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-page.el, erc-ezbounce.el, erc-speak.el, erc-match.el,
+ erc-track.el (erc-ezbounce, erc-page, erc-speak): Groups defined.
+ (erc-match, erc-track): `erc' is parent group.
+ (erc-ezb-regexp, erc-ezb-login-alist): Added `:group'.
+
+2004-04-20 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-fill.el: Fixed erc-fill-static so it breaks the lines at the
+ right column and respects timestamps. Patch by Simon Siegler
+ <simon@trz-kril.de>
+ (erc-fill-static): Major rewrite and split up into some functions.
+ (erc-count-lines): Removed.
+ (erc-fill-regarding-timestamp): New function.
+ (erc-timestamp-offset): New function.
+ (erc-restore-text-properties): New function.
+ (erc-fill-variable): Respect leftbound timestamp. This is still
+ broken if someone has both erc-timestamp-only-if-changed-flag set
+ and erc-insert-timestamp-function set to
+ 'erc-insert-timestamp-left, but otherwise it works now.
+
+2004-04-20 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: (erc-cmd-SV): Show features gtk, mac-carbon, multi-tty.
+ Fixed so that arguments fit the format (build date was not being
+ shown).
+
+2004-04-19 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el: (erc-update-channel-topic); Error if `channel-topic' is
+ unbound. Remove %-sign substitution.
+ (erc-update-mode-line-buffer): Escape %-signs in `channel-topic'
+ here.
+
+2004-04-19 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: (erc-send-action, erc-ctcp-query-ACTION,
+ erc-ctcp-reply-ECHO-hook): Let `erc-display-message-highlight'
+ propertize the message.
+ (erc-display-message-highlight): Allow for any erc-TYPE-face.
+ (erc-cmd-JOIN): Display error message instead of throwing an error
+ if there's no `invitation'.
+ (erc-cmd-PART): Allow for no reason if channel is provided. Fixes
+ bug where user would part the current channel with the other
+ channel's name as reason when no reason was given.
+ (erc-server-vectors, erc-debug-missing-hooks): Added docstring.
+ (erc-server-JOIN): Moved `erc-join-hook' to JOIN-you section.
+ `erc-join-hook' called by `run-hook-with-args', sending the ARGS
+ `chnl' and the channel's buffer. Changed an instance of if
+ without else to when.
+ (erc-server-477): New function.
+ (erc-server-477-hook): Use `erc-server-477'.
+ (erc-define-catalog): Added `no-invitation'.
+
+2004-04-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nickserv.el: Local variables for file added.
+ (erc-nickserv-passwords): Customization: Network symbols updated
+ to reflect `erc-nickserv-alist'. Allow user to type in network
+ symbol.
+ (erc-nickserv-alist): Now customizable variable.
+
+2004-04-09 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-autoaway.el (erc-autoaway-reset-idletime): Make sure `line'
+ is a string to avoid errors upon startup.
+
+2004-04-06 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-autoaway.el (erc-autoaway-version): New variable.
+ (erc-auto-discard-away): Updated docstring.
+ (erc-autoaway-no-auto-back-regexp): New variable.
+ (erc-autoaway-reset-idletime): Use it. Hopefully a better solution
+ which allows for aliases to "/away" and any other text that the
+ user wants to ignore when `erc-auto-discard-away' is non-nil.
+
+2004-04-06 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-autoaway.el (erc-autoaway-reset-idletime): Forgot /gaway in
+ regexp.
+
+2004-04-06 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-autoaway.el (erc-autoaway-reset-idletime): If the user sends
+ an "/away" command, don't call `erc-autoaway-set-back', fixes bug
+ where ERC would send "/away" when user was already away and sent an
+ "/away reason". Changed `l' to `line' for better understanding.
+ (erc-autoaway-set-back): Changed `l' to `line' for better
+ understanding.
+
+2004-04-05 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-set-channel-key): Now able to remove key.
+ (erc-set-channel-limit): Now able to remove limit.
+ (erc-get-channel-mode-from-keypress): Fixed docstring.
+
+2004-04-04 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-join-channel): Allow for optional channel key.
+ (erc-set-modes): Need to set `channel-key' to nil in case of mode
+ changes during split.
+ (erc-show-channel-key-p): New variable.
+ (erc-prepare-mode-line-format): Only show key if
+ `erc-show-channel-key-p' is non-nil.
+
+2004-04-04 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (channel-key): New variable.
+ (erc-update-channel-key): New function.
+ (erc-set-modes, erc-parse-modes, erc-update-modes, erc,
+ erc-update-channel-info-buffer): Deal with channel keys.
+ (erc-prepare-mode-line-format): Show channel key in header-line.
+ (erc-server-NICK): Show nick change in server buffer as well.
+ (erc, erc-send-command, erc-banlist-store, erc-banlist-update,
+ erc-load-irc-script-lines,
+ erc-arrange-session-in-multiple-windows, erc-handle-login,
+ erc-find-channel-info-buffer): Changed when not to unless.
+ (erc-server-MODE): Changed if without else to when.
+
+2004-03-27 Adrian Aichner <adrian@xemacs.org>
+
+ * erc.el: (erc-cmd-BANLIST): Use `truncate-string-to-width'
+ instead of `truncate-string' alias.
+ (erc-nickname-in-use): Ditto.
+
+2004-03-27 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-list.el (erc-cmd-list): Fixed error caused by erc-cmd-LIST
+ passing a non-sequence to erc-chanlist.
+
+2004-03-22 Jeremy Bertram Maitin-Shepard <jbms@gentoo.org>
+
+ * erc.el: Add new hook `erc-join-hook', which is run when we join a
+ channel.
+
+2004-03-22 Jeremy Bertram Maitin-Shepard <jbms@gentoo.org>
+
+ * erc.el: Replaced existing notice user notification system and
+ the configuration options, which consisted of
+ `erc-echo-notices-in-minibuffer-flag' and
+ `erc-echo-notices-in-current-buffer' with two new hooks,
+ `erc-echo-notice-hook' and `erc-echo-notice-always-hook'.
+
+ When user notification is needed, `erc-echo-notice-always-hook' is
+ first run using `run-hook-with-args', then `erc-echo-notice-hook'
+ is run using `run-hook-with-args-until-success'.
+
+ In addition to these hooks, a large number of functions, which are
+ described in the documentation strings of those hooks, were added
+ which can be used to achieve a large variety of different
+ behaviors.
+
+ The current default behavior, which is identical to the existing
+ default behavior, is for `erc-echo-notice-always-hook' to be set to
+ `(erc-echo-notice-in-default-buffer).
+
+2004-03-21 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-track.el: (erc-modified-channels-display): Added a space
+ before opening bracket.
+
+2004-03-21 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: (erc-format-query-as-channel-p): New variable.
+ (erc-server-PRIVMSG-or-NOTICE): If `erc-format-query-as-channel-p'
+ is nil, messages in the query buffer are formatted like private
+ messages.
+
+ (erc-server-252-hook, erc-server-253-hook, erc-server-254-hook,
+ erc-server-256-hook, erc-server-257-hook, erc-server-258-hook,
+ erc-server-259-hook, erc-server-371-hook, erc-server-372-hook,
+ erc-server-374-hook, erc-server-374-hook, erc-server-442-hook,
+ erc-server-477-hook): Removed, now defined in
+ `erc-server-hook-list'.
+ (erc-display-server-message): New function.
+ (erc-server-252, erc-server-253, erc-server-254, erc-server-442):
+ New functions.
+ (erc-server-hook-list): Added 250, 256, 257, 258, 259, 265, 266,
+ 377, 378, 477 - using `erc-display-server-message'. 251, 255 now
+ use `erc-display-server-message'. Added 252, 253, 254, 442 -
+ using respective erc-server-* functions. 371, 372, 374, 375 now
+ defined here.
+ (erc-define-catalog): Added s252, s253, s254, s442.
+ (erc-server-001, erc-server-004, erc-server-005): Fixed
+ documentation.
+
+2004-03-20 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-stamp.el: Commentary: Changed `erc-stamp-mode' to
+ `erc-timestamp-mode'.
+ (erc-insert-timestamp-left): Use `erc-timestamp-face' on filler
+ spaces as well.
+
+2004-03-19 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-send-action): Use `erc-input-face'.
+ (erc-display-message-highlight): If the requested highlighting
+ type doesn't match, just display the string with no highlighting
+ and warn about it with `erc-log'.. (erc-cmd-JOIN): If user is
+ already on the requested channel, switch to that channel's buffer.
+ (erc-ctcp-query-ACTION): Use `erc-action-face' for nick as well.
+ (erc-header-line-use-help-echo-p): New variable.
+ (erc-update-mode-line-buffer): Use `help-echo' for header-line if
+ `erc-header-line-use-help-echo-p' is non-nil.
+
+2004-03-18 Adrian Aichner <adrian@xemacs.org>
+
+ * erc-nets.el: Use two arguments version of `make-obsolete', if
+ third argument is not supported (for XEmacs).
+
+2004-03-18 Andreas Fuchs <asf@void.at>
+
+ * CREDITS: added CREDITS entry for Adrian Aichner
+
+2004-03-18 Andreas Fuchs <asf@void.at>
+
+ * erc-xdcc.el, erc.el, erc-autoaway.el, erc-autojoin.el,
+ erc-button.el, erc-dcc.el, erc-ezbounce.el, erc-imenu.el,
+ erc-list.el, erc-log.el, erc-match.el, erc-members.el,
+ erc-menu.el, erc-netsplit.el, erc-notify.el, erc-speedbar.el,
+ erc-stamp.el, erc-track.el, erc-truncate.el:
+ (erc-coding-sytem-for-target): Removed.
+ (erc-coding-system-for-target): New.
+ (erc-autoaway-use-emacs-idle): Typo fix.
+ (erc-auto-set-away): Ditto.
+ (erc-auto-discard-away): Ditto.
+ (autojoin): Ditto.
+ (erc-button-alist): Ditto.
+ (erc-dcc-auto-masks): Ditto.
+ (erc-dcc-chat-send-input-line): Ditto.
+ (erc-ezb-get-login): Ditto.
+ (erc-unfill-notice): Ditto.
+ (erc-save-buffer-in-logs): Ditto.
+ (match): Ditto.
+ (erc-log-matches-types-alist): Ditto.
+ (erc-match-directed-at-fool-p): Ditto.
+ (erc-match-message): Ditto.
+ (erc-update-member): Ditto.
+ (erc-ignored-reply-p): Ditto.
+ (erc-menu-definition): Ditto.
+ (erc-netsplit-QUIT): Ditto.
+ (erc-notify-list): Ditto.
+ (erc-speedbar-update-channel): Ditto.
+ (erc-speedbar-item-info): Ditto.
+ (erc-stamp): Ditto.
+ (erc-timestamp-intangible): Ditto.
+ (erc-add-timestamp): Ditto.
+ (erc-timestamp-only-if-changed-flag): Ditto.
+ (erc-show-timestamps): Ditto.
+ (erc-track-priority-faces-only): Ditto.
+ (erc-modified-channels-alist): Ditto.
+ (erc-unique-substrings): Ditto.
+ (erc-find-parsed-property): Ditto.
+ (erc-track-switch-direction): Ditto.
+ (erc-truncate-buffer-to-size): Ditto.
+ (erc-xdcc): Ditto.
+ (erc-auto-reconnect): Ditto.
+ (erc-startup-file-list): Ditto.
+ (erc-once-with-server-event): Ditto.
+ (erc-once-with-server-event-global): Ditto.
+ (erc-mode): Ditto.
+ (erc-generate-new-buffer-name): Ditto.
+ (erc): Ditto.
+ (erc-open-ssl-stream): Ditto.
+ (erc-default-coding-system): Ditto.
+ (erc-encode-string-for-target): Ditto.
+ (erc-decode-string-from-target): Ditto.
+ (erc-scroll-to-bottom): Ditto.
+ (erc-decode-controls): Ditto.
+ (erc-channel-members-changed-hook): Ditto.
+ (erc-put-text-property): Ditto.
+ (erc-add-default-channel): Ditto.
+
+2004-03-17 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-process-sentinel): Cancel ping timer upon
+ disconnect.
+ (erc-cmd-PART): Use same regexp as `erc-cmd-QUIT' when no #channel
+ is provided.
+ (erc-nick-uniquifier, erc-manual-set-nick-on-bad-nick-p): `:group'
+ was missing, added.
+ (erc-part-reason-zippy, erc-part-reason-zippy): Removed FIXME
+ comments. I see no problem allowing typed in reasons.
+
+2004-03-16 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-stamp.el: (erc-insert-timestamp-left): Added support for
+ `erc-timestamp-only-if-changed-flag' and added docstring.
+ (erc-timestamp-only-if-changed-flag): Updated documentation.
+
+2004-03-13 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-nets.el (erc-network-name): No longer marked as obsolete.
+ Why was this function made obsolete? There is no other function
+ that performs this task. Some of us use these functions in our
+ personal ERC configs.
+
+2004-03-12 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-buffer-filter): Use `with-current-buffer'.
+ (erc-process-input-line): Append newline to documentation. Fixes a
+ bug whereby the prompt would be put on the same line as the output.
+ (erc-cmd-GQUIT): Only try and send QUIT if the process is alive.
+
+2004-03-12 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-log.el: Only add top-level hooks if `erc-enable-logging' is
+ non-nil.
+
+2004-03-10 Damien Elmes <erc@repose.cx>
+
+ * erc-nets.el: From Adrian Aichner (adrian /at/ xemacs /dot/ org)
+ * erc-nets.el: XEmacs make-obsolete only takes two arguments.
+
+2004-03-10 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nets.el (erc-determine-network): Use `erc-session-server' if
+ `erc-announced-server' is nil to avoid error if server does not
+ send 004 (RPL_MYINFO) message.
+
+2004-03-10 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-nets.el (erc-server-alistm erc-settings): Use lowercase
+ "freenode", as in `erc-networks-alist'.
+
+2004-03-10 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-nickserv.el (erc-nickserv-alist): Use lowercase "freenode",
+ as in `erc-networks-alist'.
+
+2004-03-10 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-dcc.el (pcomplete/erc-mode/DCC): Append "send" as a list.
+
+2004-03-10 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-nets.el (erc-networks-alist): Changed "Freenode" to
+ "freenode".
+
+2004-03-10 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-list.el (erc-cmd-LIST): Improved the docstring. Made
+ message to user more accurate depending on whether a single
+ channel is being listed or not.
+
+2004-03-10 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-nets.el (erc-determine-network): Make matching logic simpler
+ (suggested by Damian Elmes).
+ (erc-current-network, erc-network-name): Add `make-obsolete' form.
+ (erc-set-network-name): Indentation fix.
+ (erc-ports-list): Add docstring. Rework function body to use
+ `nconc'.
+
+2004-03-09 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-list.el, erc-notify.el: (require 'erc-nets): added
+
+2004-03-08 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-network-name): Function definition moved to
+ erc-nets.el. The functions `erc-determine-network' and
+ `èrc-network' in erc-nets.el do what this did before. Deprecated.
+ Use (erc-network) instead.
+
+2004-03-08 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nickserv.el: Changed copyright notice. Now require
+ erc-nets. erc-nets.el now takes care of network-related functions
+ and variables.
+ (erc-nickserv-alist): Changed network symbols to match those in
+ `erc-networks-alist' in erc-nets.el.
+ (erc-nickserv-identify-autodetect): Use `erc-network'.
+ (erc-nickserv-identify): Use `erc-network'. Changed wording for
+ interactive use, now shows current nick.
+ (erc-networks): Removed. Use `erc-networks-alist' as defined in
+ erc-nets.el.
+ (erc-current-network): Function definition moved to erc-nets.el.
+ The functions `erc-determine-network' and `èrc-network' in
+ erc-nets.el do what this did before. Deprecated. Use
+ (erc-network) instead.
+
+2004-03-08 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-nets.el: Added commentary, `erc-nets-version'.
+ (erc-server-alist): Changed Brasnet to BRASnet.
+ (erc-networks-alist): All networks (except EFnet and IRCnet) now
+ have a MATCHER. (erc-network): New variable.
+ (erc-determine-network): New function. Determine the network the
+ user is on. Use the server parameter NETWORK, if provided, else
+ parse the server name and search for a match (regexp and loop by
+ wencem) in `erc-networks-alist'. Return the name of the network
+ or "Unknown" as a symbol.
+ (erc-network): New function. Returns value of `erc-network'. Use
+ this when the current buffer is not the server process buffer.
+ (erc-current-network): Returns the value of `erc-network' as
+ expected by users who used the function as it was defined in
+ erc-nickserv.el. Deprecated.
+ (erc-network-name): Returns the value of `erc-network' as expected
+ by users who used the function as it was defined in erc.el.
+ Deprecated.
+ (erc-set-network-name): New function. Added to
+ `erc-server-375-hook' and `erc-server-422-hook'.
+ (erc-unset-network-name): New function. Added to
+ `erc-disconnected-hook'.
+ (erc-server-select): Small documentation word change.
+
+2004-03-07 Diane Murray <disumu@x3y2z1.net>
+
+ * AUTHORS, CREDITS: disumu info updated
+
+2004-03-06 Lawrence Mitchell <wence@gmx.li>
+
+ * erc-list.el (erc-cmd-LIST): Take &rest rather than &optional
+ arguments.
+ (erc-chanlist): Construct correct LIST command from list of
+ channels.
+
+2004-03-06 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-update-mode-line-buffer): Add 'help-echo property to
+ header-line text. This allows header lines longer than the width
+ of the current window to be seen.
+
+2004-03-06 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-match.el (erc-match-directed-at-fool-p): Also check for
+ "FOOL, "
+
+2004-03-06 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-match.el (erc-match-message): Only use nick-or-keyword if
+ we're matching our nick.
+
+2004-03-06 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-match.el: The highlight type for the current nickname can
+ now also be 'nick-or-keyword, to highlight the nick of the sender
+ if that is available, but fall back to highlighting your nickname
+ in the whole message otherwise.
+ (erc-current-nick-highlight-type): Adapted docstring accordingly.
+ (erc-match-message): Added new condition. Also added some comments
+ to this monster of a function.
+
+2004-03-06 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-is-valid-nick-p): Don't check for length less or
+ equal to 9.
+
+2004-03-06 Damien Elmes <erc@repose.cx>
+
+ * erc-nickserv.el (erc-current-network): the last change resulted
+ in this function failing when a network identifies itself as
+ anything other than var.netname.com, so for instance
+ 'vic.au.austnet.org' fails. This version is only a marginal
+ improvement over the original, but if we want to be more flexible
+ we'll probably have to do the iteration ourselves instead of using
+ assoc.
+
+2004-03-05 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el: Added erc-server-001 which runs when the server sends
+ its welcome message. It sets the current-nick to reflect the
+ server's settings. This fixes a bug where nicks that were too long
+ and got truncated by ther server were still set to the old value.
+ (nickname-in-use): If user wants to try again manually, let user
+ know that the nick is taken. If not, go through erc-default-nicks
+ until none are left, and then try one last time with
+ erc-nick-uniquifier. If it's still a bad-nick, make the user
+ change nick manually. When applying uniquifier, use NICKLEN if
+ it's in the server parameters, otherwise use what RFC 2812 says is
+ the max nick length (9 chars). Added custom variable
+ erc-manual-set-nick-on-bad-nick-p, which is set to nil and
+ erc-nick-change-attempt-count. Reset erc-default-nicks and
+ erc-nick-change-attempt-count when the nick has been changed
+ successfully. This fixes the bug where ERC would get caught in a
+ neverending loop of trying to set the same nick if the nick was
+ too long and the uniquified nick was not available.
+
+ * added erc-cmd-WHOAMI
+
+ * added custom variable erc-mode-line-away-status-format, use this
+ instead of the previous hard-coded setting
+
+ * erc-server-315|318|369-hook defvar lines removed - they're
+ already defined in erc-server-hook-list
+
+2004-03-04 Lawrence Mitchell <wence@gmx.li>
+
+ * HACKING: Initial commit. Some thoughts on coding standards.
+
+2004-03-03 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-track.el: added the variable erc-track-priority-faces-only
+ which adds the option to ignore changes in a channel unless there
+ are faces from the erc-track-faces-priority-list in the message
+ options are nil, 'all, or a list of channel name strings
+
+2004-03-01 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el, erc-ibuffer.el, erc-menu.el: Changed erc-is-channel-op
+ and erc-is-channel-voice to erc-channel-user-op-p and
+ erc-channel-user-voice-p to better match erc-channel-user
+ structure (and emacs lisp usage)
+
+2004-03-01 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el, erc-ibuffer.el, erc-menu.el:
+ erc-track-modified-channels-mode is now erc-track-mode
+
+2004-02-29 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-match.el: Added 'keyword option to
+ erc-current-nick-highlight-type highlights all instances of
+ current-nick in the message ('nickname option in cvs revisions 1.9
+ - 1.11 had same effect)
+
+2004-02-28 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-button.el: Add Lisp: prefix for the EmacsWiki Elisp area.
+ (erc-button-alist): Added Lisp: prefix.
+ (erc-emacswiki-lisp-url): New variable.
+ (erc-browse-emacswiki-lisp): New function.
+
+2004-02-27 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-get-arglist): Use `substitute-command-keys', rather
+ than hard-coding C-h f for `describe-function'.
+
+2004-02-26 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-log.el (erc-save-buffer-in-logs): bind `inhibit-read-only'
+ to t around call to `erase-buffer'.
+
+2004-02-23 Edward O'Connor <ted@oconnor.cx>
+
+ * erc-chess.el, erc-dcc.el, erc-ezbounce.el, erc-list.el,
+ erc-macs.el, erc-ring.el, erc-stamp.el, erc.el: Normalized buffer
+ local variable creation.
+
+2004-02-17 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-scroll-to-bottom, erc-add-scroll-to-bottom): Mention
+ `erc-input-line-position' in docstring.
+
+2004-02-13 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-kick-hook): Typo fix.
+
+2004-02-13 Jeremy Bertram Maitin-Shepard <jbms@gentoo.org>
+
+ * erc.el: Added `erc-kick-hook', which is called when the local
+ user is kicked from a channel. Fixed a bug in `erc-cmd-OPS', such
+ that the command now works. Added `erc-remove-channel-users', in
+ order to fix a number of significant bugs relating to channel
+ parting.
+
+2004-02-12 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-display-prompt): Remove last change. This caused a
+ lot of trouble :(
+
+2004-02-12 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-display-prompt): Also set 'field property, so C-j
+ works on an empty prompt.
+
+2004-02-12 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-update-channel-topic): Ensure that `channel-topic'
+ does not contain any bare format controls.
+
+2004-02-10 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc-stamp.el (erc-timestamp-intangible): New variable (user
+ feature request)
+ (erc-format-timestamp): Use erc-timestamp-intangible.
+
+2004-02-07 Jeremy Bertram Maitin-Shepard <jbms@gentoo.org>
+
+ * erc-button.el: Fixed bug related to nickname buttonizing and text
+ fields due to erc-stamp.
+
+2004-02-07 Jeremy Bertram Maitin-Shepard <jbms@gentoo.org>
+
+ * CREDITS: Added mention of my change of ERC to use hash tables.
+
+2004-02-07 Jeremy Bertram Maitin-Shepard <jbms@gentoo.org>
+
+ * AUTHORS: Added myself to the list.
+
+2004-02-05 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el: From Jeremy Maitin-Shepard <jbms@attbi.com>:
+ (erc-remove-channel-user): Use `delq' not `delete'.
+ (erc-get-buffer): Pass PROC through to `erc-buffer-filter'.
+ (erc-process-sentinel): Use `erc' rather than `erc-reconnect' for
+ auto-reconnection.
+
+2004-02-02 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el: (erc-buffer-list-with-nick): Apply `erc-downcase' NICK.
+
+2004-01-30 Alex Schroeder <alex@gnu.org>
+
+ * erc.el: (erc-get-buffer): Use erc-buffer-filter.
+
+2004-01-30 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc.el: From jbms: (erc-get-channel-nickname-list): New function.
+ (erc-get-server-nickname-list): New function.
+ (erc-get-server-nickname-alist): New function.
+ (erc-get-channel-nickname-alist): New function.
+
+2004-01-30 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-match.el: (erc-add-entry-to-list,
+ erc-remove-entry-from-list): Use `erc-member-ignore-case' to
+ compare entries.
+ (erc-add-pal, erc-add-fool): Fix type bug. Use
+ `erc-get-server-nickname-alist'.
+
+2004-01-29 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc.el: From jbms: Adds xemacs compatibility to hash table
+ channel-members patch.
+
+2004-01-29 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc.el: (erc-update-undo-list): Rewritten. Update
+ buffer-undo-list in place. Deal with XEmacsesque
+ entries (extents) in the list.
+ (erc-channel-users): Fix unescaped open-paren in left column in
+ docstring.
+
+2004-01-29 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-ring.el: (erc-replace-current-command): Exclude the prompt
+ from the deleted region and don't redisplay the prompt (because
+ `erc-display-prompt' flushes `buffer-undo-list').
+
+2004-01-29 Johan Bockgard <bojohan@users.sourceforge.net>
+
+ * erc-match.el: (erc-add-entry-to-list): Use `symbol-value' instead
+ of `eval'.
+
+2004-01-28 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: (erc-kill-buffer-function): maphash was missing an
+ argument.
+
+2004-01-28 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * Makefile, erc-autoaway.el, erc-button.el, erc-ibuffer.el,
+ erc-lang.el, erc-list.el, erc-match.el, erc-menu.el, erc-page.el,
+ erc-pcomplete.el, erc-speedbar.el, erc.el: HUGE change by jbms.
+ This makes channel-members a hash, erc-channel-users.
+
+ Modified files: Makefile erc-autoaway.el erc-button.el
+ erc-ibuffer.el erc-lang.el erc-list.el erc-match.el erc-menu.el
+ erc-page.el erc-pcomplete.el erc-speedbar.el erc.el
+
+ The changes are too numerous to document properly. Have fun with
+ the breakage.
+
+2004-01-27 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: (erc-send-input-line): Add a space to empty lines so the
+ server likes them.
+
+2004-01-25 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: erc-send-whitespace-lines: New variable.
+ (erc-send-current-line): Use erc-send-whitespace-lines. Also,
+ removed superflous test for empty line in the mapc, since the
+ blank line test should find all. I do like to be able to send an
+ empty line when i want to!
+ (erc-send-current-line): Check for point being in input line
+ before checking for blank lines.
+
+2004-01-21 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el: (erc-display-line-1): Move `erc-update-undo-list' outside
+ `save-restriction'. Removing need for temporary variable.
+ (erc-send-current-line): Fix bug introduced by last change, remove
+ complement in blank line regexp.
+
+2004-01-20 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el: (erc-update-undo-list): Add logic to catch the case when
+ `buffer-undo-list' is t, indentation cleanup.
+ (erc-send-current-line): Reverse logic for matching blank lines.
+
+2004-01-20 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-input-line-position): New variable. If non-nil,
+ specifies the argument to `recenter' in `erc-scroll-to-bottom'.
+ (erc-scroll-to-bottom): Use it.
+
+2004-01-20 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el: From Johan Bockgård <bojohan+news@dd.chalmers.se>:
+ (erc-update-undo-list): New function. Update `buffer-undo-list'
+ so that calling `undo' in an ERC buffer doesn't mess up the
+ existing text.
+ (erc-display-line-1): Use it.
+
+2004-01-19 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-beg-of-input-line): Use `forward-line' rather than
+ `beginning-of-line'. Docstring fix.
+ (erc-end-of-input-line): Docstring fix.
+
+2004-01-13 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-display-prompt): Remove the undo list after
+ displaying the prompt, so the user can't undo ERC changes, which
+ breaks some stuff anyways. This way the user can still undo his
+ editing, but not ours.
+
+2004-01-12 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-scroll-to-bottom): Should recenter on the bottom
+ line, not the second-to-last one.
+
+2004-01-12 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el: (erc-bol): Fix bug introduced in revision 1.601.
+
+2004-01-12 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el: From Brian Palmer <bpalmer@gmail.com>
+ (erc-cmd-JOIN): Use `erc-member-ignore-case', rather than
+ `member-ignore-case'.
+
+2004-01-12 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el: There was an inconsistency where the values of op and
+ voice in channel-names could be 'on or 'off after an update, t and
+ nil before. The intended version was to have t or nil, so i fixed
+ it to do so.
+ (channel-names): Updated docstring.
+ (erc-update-current-channel-member): Clarified docstring, fixed so
+ it sets t or nil on an update as well, not only on an add.
+ (erc-cmd-OPS): Updated not to check for 'on (the only function that
+ did this!)
+
+2004-01-12 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-part-reason-various-alist,
+ erc-update-mode-line-buffer): Fix docstring
+
+2004-01-11 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-update-mode-line): Fix typo.
+
+2004-01-11 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-prompt-interactive-input): Removed.
+ (erc-display-prompt): Removed `erc-prompt-interactive-input'
+ option. (erc-interactive-input-map): Removed.
+
+ Major docstring fixes.
+
+2004-01-07 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-cmd-OPS): Added this function.
+ (erc-cmd-IDLE): Switched from using erc-display-message-highlight
+ to erc-make-notice.
+
+2004-01-07 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-list.el (erc-cmd-LIST): Switched from using
+ erc-display-message-highlight to erc-make-notice.
+
+2004-01-07 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-once-with-server-event): Added a sentence to the
+ docstring. Now returns the uninterned symbol that is added to the
+ server hook.
+ (erc-cmd-IDLE): Changed to use erc-once-with-server-event instead
+ of erc-once-with-server-event-global.
+
+2004-01-06 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-list.el (erc-chanlist-hide-modeline): New variable.
+ (erc-chanlist): Now displays message as a notice. Also hides the
+ modeline if erc-chanlist-hide-modeline is non-nil.
+
+2004-01-05 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-server-PRIVMSG-or-NOTICE): Now nicks appear as
+ <nick> in query buffers, instead of as *nick*.
+
+2004-01-03 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-once-with-server-event-global): Changed to return
+ the uninterned symbol that it creates.
+ (erc-cmd-LIST): Changed to clean up hooks that don't run.
+
+2004-01-03 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-pcomplete.el (pcomplete/erc-mode/IDLE): Added to support new
+ /IDLE command.
+
+2004-01-03 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc.el (erc-once-with-server-event-global): New function. Like
+ erc-once-with-server-event, except it modifies the global value of
+ the event hook.
+ (erc-cmd-IDLE): New function. Implements the new /IDLE command.
+ Usage: /IDLE NICK (erc-seconds-to-string): New function. Converts
+ a number of seconds to an Engligh phrase.
+
+2004-01-02 Francis Litterio <franl@users.sourceforge.net>
+
+ * erc-list.el: Added variable erc-chanlist-mode-hook.
+
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted provided the copyright notice and this notice are preserved.
+
+;; arch-tag: cc606d2d-635b-4b36-829b-a50e3c51e2d1
diff --git a/lisp/erc/ChangeLog.2005 b/lisp/erc/ChangeLog.2005
new file mode 100644
index 00000000000..90ea87a1b0a
--- /dev/null
+++ b/lisp/erc/ChangeLog.2005
@@ -0,0 +1,1222 @@
+2005-11-23 Johan Bockgård <bojohan@users.sourceforge.net>
+
+ * erc.el (erc-cmd-SAY): Strip leading space in input line.
+
+2005-10-29 Michael Olson <mwolson@gnu.org>
+
+ * FOR-RELEASE: Add stuff that needs to be done before the 5.1
+ release. Longer-term items can be added to the 5.2 section.
+
+ * Makefile (SITEFLAG): New variable that indicates what variant of
+ "--site-flag" to use. XEmacs needs "-site-flag".
+ (INSTALLINFO): New variable indicating how we should call
+ install-info when installing documentation.
+ (erc-auto.el, .elc.el): Use $(SITEFLAG).
+
+ * NEWS: Note that last release was 5.0.4.
+
+ * erc.texi: Initial and incomplete draft of ERC documentation.
+ Commence collaborate-documentation-hack-mode :^) .
+
+2005-10-29 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-ring.el (erc-replace-current-command): Revert last change
+ since it made the prompt disappear when using `erc-next-command'
+ and `erc-previous-command'.
+
+2005-10-28 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-input-marker): New variable that indicates the
+ position where text from the user begins, after the prompt.
+ (erc-mode-map): Bind <HOME> to erc-bol, just like C-a.
+ (erc): Initialize erc-input-marker.
+ (erc-display-prompt): Even in case where no prompt is desired by
+ the user, clear the undo buffer and set the input marker.
+ (erc-bol, erc-user-input): Simplify by using erc-input-marker.
+
+ * erc-pcomplete.el (pcomplete-parse-erc-arguments): Use
+ erc-insert-marker.
+
+ * erc-ring.el (erc-previous-command)
+ (erc-replace-current-command): Use erc-insert-marker.
+
+ * erc-spelling.el (erc-spelling-init): Make sure that even Emacs21
+ obeys erc-spelling-flyspell-verify.
+ (erc-spelling-flyspell-verify): Use erc-input-marker. This should
+ make it considerably faster when switching to a buffer that has
+ seen a lot of activity since last viewed.
+
+2005-10-25 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-backend.el (erc-server-version, 004): Re-added setting of
+ `erc-server-version'. It doesn't hurt to set, and it could be
+ used in modules or users' settings.
+
+ * NEWS: Added descriptions of some new features.
+
+2005-10-20 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-match.el (erc-current-nick-highlight-type): Set to `keyword'
+ as default.
+ (erc-beep-match-types): New variable.
+ (erc-text-matched-hook): Doc fix. Added `erc-beep-on-match' to
+ customization options.
+ (erc-beep-on-match): New function. If the MATCH-TYPE is found in
+ `erc-beep-match-types', beep.
+
+ * erc-compat.el (erc-make-obsolete, erc-make-obsolete-variable):
+ New functions to deal with the difference in the number of
+ arguments accepted by `make-obsolete' and `make-obsolete-variable'
+ in Emacs and XEmacs.
+
+ * erc.el, erc-nets.el: Use `erc-make-obsolete' and
+ `erc-make-obsolete-variable'.
+
+ * erc-compat.el (erc-make-obsolete, erc-make-obsolete-variable):
+ Handle `wrong-number-of-arguments' error instead of checking for
+ xemacs feature as future versions of XEmacs might accept three
+ arguments.
+
+2005-10-18 Edward O'Connor <ted@oconnor.cx>
+
+ * erc.el: Tell emacs-lisp-mode how to font-lock define-erc-module
+ docstrings.
+
+2005-10-08 Diane Murray <disumu@x3y2z1.net>
+
+ * AUTHORS, CREDITS, ChangeLog, ChangeLog.2002, ChangeLog.2004:
+ Updated my email address.
+
+2005-10-06 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-send-input-line, erc-cmd-KICK, erc-cmd-PART)
+ (erc-cmd-QUIT, erc-cmd-TOPIC, erc-kill-server, erc-kill-channel):
+ Adapt to new TARGET parameter of erc-server-send.
+
+ * erc-backend.el (erc-server-connect): Don't specify encoding for
+ erc-server-process, since we set this each time we send a line to
+ the server.
+ (erc-encode-string-for-target): Remove.
+ (erc-server-send): Allow TARGET to be specified. This was how it
+ used to be before my more-backend work. Set encoding of server
+ process just before sending text to it. Associate encoding with
+ text if we are using the queue.
+ (erc-server-send-queue): Pull encoding from queue.
+ (erc-message, erc-send-ctcp-message, erc-send-ctcp-notice): Adapt
+ to new TARGET parameter of erc-server-send.
+
+2005-10-05 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-toggle-debug-irc-protocol): Use erc-view-mode-enter
+ rather than view-mode.
+
+ * erc-backend.el (erc-encode-string-for-target): If given a nil or
+ empty string, return "".
+ (erc-server-send-queue): XEmacs fix: Use erc-cancel-timer rather
+ than cancel-timer.
+
+ * erc-compat.el (erc-view-mode-enter): New function that is
+ aliased to the correct way of entering view-mode.
+
+ * erc-match.el (erc-log-matches-make-buffer): Use
+ erc-view-mode-enter rather than view-mode-enter.
+
+2005-10-05 Edward O'Connor <ted@oconnor.cx>
+
+ * erc-backend.el (erc-encode-string-for-target): If str is nil,
+ pass the empty string to erc-encode-coding-string instead, which
+ allows one to /part and /quit without providing a reason again.
+
+2005-10-03 Michael Olson <mwolson@gnu.org>
+
+ * erc-backend.el (erc-message, erc-send-ctcp-message)
+ (erc-send-ctcp-notice): Encode string for target before sending.
+
+ * erc.el (erc-cmd-KICK, erc-cmd-PART, erc-cmd-QUIT, erc-cmd-TOPIC)
+ (erc-kill-server, erc-kill-channel): Ditto.
+
+2005-09-05 Johan Bockgård <bojohan@users.sourceforge.net>
+
+ * erc-page.el (erc-ctcp-query-PAGE): (message text) -> (message
+ "%s" text).
+ (erc-cmd-PAGE): Simplify regexp. Put `do-not-parse-args' t.
+
+2005-09-05 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-flood-limit, erc-flood-limit2): Remove since they
+ are no longer needed.
+ (erc-send-input): Detect whether we want flood control to be
+ active. The previous behavior was to always force the message.
+ (erc-toggle-flood-control): Adapt to new flood control method. No
+ more 'strict.
+ (erc-cmd-SV): Use concat rather than
+ format-time-string.
+ (erc-format-target, erc-format-target-and/or-server): Shorten
+ logic statements.
+
+ * erc-compat.el (erc-emacs-build-time): Use a string
+ representation rather than trying to coerce a time out of a string
+ on XEmacs.
+
+ * erc-identd.el (erc-identd-start): Use make-network-process
+ instead of open-network-stream. Error out if this is not defined.
+
+ * erc-backend.el (erc-send-line): New command that sends a line
+ using flood control, using a callback for display. It isn't used
+ yet.
+
+2005-09-04 Michael Olson <mwolson@gnu.org>
+
+ * erc.el: Add defvaralias and make-obsolete-variable for
+ erc-default-coding-system.
+ (channel-topic, channel-modes, channel-user-limit, channel-key,
+ invitation, away, channel-list, bad-nick): Rename globally to
+ erc-{name-of-variable}.
+
+2005-09-03 Johan Bockgård <bojohan@users.sourceforge.net>
+
+ * erc.el (erc-message): Simplify regexp.
+ (erc-cmd-DEOP, erc-cmd-OP): Simplify.
+
+2005-08-29 Michael Olson <mwolson@gnu.org>
+
+ * erc.el: Alias erc-send-command to erc-server-send. ErBot needs
+ this to work without modification. Add defvaralias for
+ erc-process. Make this and the other backwards-compatibility
+ functions and variables be marked obsolete as of ERC 5.1.
+
+ * erc-backend.el: Add autoload for erc-log macro.
+ (erc-server-connect): Set some variables before defining process
+ handlers. It probably doesn't make any difference.
+
+2005-08-26 Michael Olson <mwolson@gnu.org>
+
+ * erc.el: Add defvaralias for erc-announced-server-name, since
+ this seems to be widely used.
+
+2005-08-17 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc): Remove unnecessary boundp check.
+
+ * erc-autoaway.el: Fix compiler warning.
+
+ * erc-backend.el (erc-server-version): Since this isn't used by
+ any code, and isn't generally useful, remove it.
+ (erc-server-send-queue): Use erc-current-time rather than
+ float-time.
+ (004): Don't set erc-server-version.
+
+ * erc-dcc.el (erc-dcc-chat-request, erc-dcc-get-parent): Move to
+ fix a compiler warning.
+
+ * erc-ibuffer.el (erc-server): Remove unnecessary boundp check.
+
+ * erc-identd.el (erc-identd-start): Use read-string instead of
+ read-input.
+
+ * erc-imenu.el (erc-unfill-notice): Use a while loop instead of
+ replace-regexp.
+
+ * erc-nicklist.el: Add conditional dependency on erc-bbdb.
+ (erc-nicklist-insert-contents): Tighten some regexps.
+
+ * erc-notify.el (erc-notify-list): Docfix.
+
+ * erc-spelling.el (erc-spelling-dictionaries): Add :type and
+ :group to silence a compiler warning.
+
+2005-08-14 Michael Olson <mwolson@gnu.org>
+
+ * erc-backend.el (erc-session-server, erc-session-port)
+ (erc-announced-server-name, erc-server-version)
+ (erc-server-parameters): Moved here from erc.el.
+ (erc-server-last-peers): Moved, renamed from last-peers.
+ (erc-server-lag): Moved, renamed from erc-lag.
+ (erc-server-duplicates): Moved, renamed from erc-duplicates.
+ (erc-server-duplicate-timeout): Moved, renamed from
+ erc-duplicate-timeout.
+ (erc-server): New customization group hosting all options from
+ this file.
+ (erc-server-prevent-duplicates): Moved, renamed from
+ erc-prevent-duplicates.
+ (erc-server-duplicate-timeout): Moved, renamed from
+ erc-duplicate-timeout.
+ (erc-server-auto-reconnect, erc-split-line-length)
+ (erc-server-coding-system, erc-encoding-coding-alist)
+ (erc-server-connect-function, erc-server-flood-margin)
+ (erc-server-flood-penalty): Change group to 'erc-server.
+ (erc-server-send-ping-interval): Moved, renamed from
+ erc-ping-interval.
+ (erc-server-ping-handler): Moved, renamed from erc-ping-handler.
+ (erc-server-setup-periodical-server-ping): Moved, renamed from
+ erc-setup-periodical-server-ping.
+ (erc-server-connect): Add to docstring. Move more initialization
+ here.
+ (erc-server-processing-p): Docfix.
+ (erc-server-connect): Use 'raw-text like in the original version.
+ (erc-server-filter-function): Don't reset process coding system.
+
+ * erc-stamp.el (erc-add-timestamp): If the text at point is
+ invisible, don't insert a timestamp. Thanks to Pascal
+ J. Bourguignon for the suggestion.
+
+ * erc-match.el (erc-text-matched-hook): Don't hide fools by
+ default, but include it in the available options.
+
+2005-08-13 Michael Olson <mwolson@gnu.org>
+
+ * erc-*.el: s/erc-send-command/erc-server-send/g.
+ s/erc-process/erc-server-process/g (sort of). Occasional
+ whitespace and indentation fixes.
+
+ * erc-backend.el: Specify a few local variables for indentation.
+ Take one item off of the TODO list.
+ (erc-server-filter-data): Renamed from erc-previous-read. From
+ circe.
+ (erc-server-processing-p): New variable that indicates when we're
+ currently processing a message. From circe.
+ (erc-split-line-length): New option that gives the maximum line
+ length of a single message. From circe.
+ (erc-default-coding-system): Moved here from erc.el.
+ (erc-split-line): Renamed from erc-split-command and taken from
+ circe.
+ (erc-connect-function, erc-connect, erc-process-sentinel-1)
+ (erc-process-sentinel, erc-flood-exceeded-p, erc-send-command)
+ (erc-message, erc-upcase-first-word, erc-send-ctcp-message)
+ (erc-send-ctcp-notice): Moved here from erc.el.
+ (erc-server-filter-function): Renamed from erc-process-filter.
+ From circe.
+ (erc-server-process): Renamed from `erc-process' and moved here
+ from erc.el.
+ (erc-server-coding-system): Renamed from
+ `erc-default-coding-system'.
+ (erc-encoding-coding-alist): Moved here from erc.el.
+ (erc-server-flood-margin, erc-server-flood-penalty):
+ (erc-server-flood-last-message, erc-server-flood-queue):
+ (erc-server-flood-timer): New options from circe that allow
+ tweaking of flood control.
+ (erc-server-connect-function): Renamed from erc-connect-function.
+ (erc-flood-exceeded-p): Removed.
+ (erc-coding-system-for-target)
+ (erc-encode-string-for-target, erc-decode-string-from-target):
+ Moved here from erc.el
+ (erc-server-send): Renamed from erc-send-command. Adapted from
+ the circe function by the same name.
+ (erc-server-send-queue): New function from circe that implements
+ handling of a flood queue.
+ (erc-server-current-nick): Renamed from current-nick.
+ (erc-server-quitting): Renamed from `quitting'.
+ (erc-server-last-sent-time): Renamed from `last-sent-time'.
+ (erc-server-last-ping-time): Renamed from `last-ping-time'.
+ (erc-server-lines-sent): Renamed from `lines-sent'.
+ (erc-server-auto-reconnect): Renamed from `erc-auto-reconnect'.
+ (erc-server-coding-system): Docfix.
+ (erc-server-connect): Renamed from `erc-connect'. Require SERVER
+ and PORT parameters. Initialize several variables here. Don't
+ set `erc-insert-marker'. Use a per-server coding system via
+ erc-server-default-encoding.
+
+ * erc.el (erc-version-string): Changed to indicate we are running
+ the `more-backend' branch.
+ (erc-send-single-line): Implement flood control using
+ erc-split-line.
+ (erc-send-input): Move functionality of erc-send-single-line in
+ here.
+ (erc-send-single-line): Assimilated!
+ (erc-display-command, erc-display-msg): Handle display hooks.
+ (erc-auto-reconnect, current-nick, last-sent-time)
+ (last-ping-time, last-ctcp-time, erc-lines-sent, erc-bytes-sent)
+ (quitting): Moved to erc-backend.el.
+ (erc): Docfix. Don't initialize quite so many things here.
+
+2005-08-10 Michael Olson <mwolson@gnu.org>
+
+ * debian/copyright (Copyright): Remove notices for 4 people, since
+ they didn't contribute legally-significant changes, or have had
+ these changes overwritten.
+
+ * erc-log.el: Remove copyright notice.
+
+ * erc.el: Remove 3 copyright notices.
+
+2005-08-09 Michael Olson <mwolson@gnu.org>
+
+ * debian/changelog: Create 5.0.4-3 package. This doesn't serve
+ any purpose other than to thank Romain Francoise for some advice.
+
+ * Makefile (debrelease): Allow last upload and extra build options
+ to be specified.
+
+2005-08-08 Michael Olson <mwolson@gnu.org>
+
+ * debian/changelog: Create 5.0.4-2 package.
+
+ * debian/control (Uploaders): Add Romain Francoise.
+ (Standards-Version): Update to 3.6.2.
+ (Depends): Add `emacsen'.
+
+ * debian/scripts/startup.erc (load-path): Minor whitespace fixup.
+
+ * Makefile (clean): Split target from realclean and make it remove
+ files that aren't packaged in releases.
+ (clean, release): Minor cleanups.
+ (debrelease): Use debuild rather than dpkg-buildpackage since the
+ former calls lintian. Minor cleanups.
+ (debrelease-mwolson): New target that removes old Debian packages,
+ calls debrelease, and copies the resulting package to my dist dir.
+ (upload): New target that automates the process of uploading an
+ ERC release to sourceforge.
+
+ * erc.el (erc-mode): Use `make-local-variable' instead of
+ `make-variable-buffer-local'.
+
+2005-07-12 Michael Olson <mwolson@gnu.org>
+
+ * debian/changelog: Build 5.0.4-1.
+
+ * Makefile (release): Prepare zip file in addition to tarball.
+
+ * NEWS: Add item for the undo fix.
+
+2005-07-09 Michael Olson <mwolson@gnu.org>
+
+ * erc-nicklist.el (erc-nicklist-insert-contents): Check
+ erc-announced-name before erc-session-server. Make sure that we
+ can never get a stringp (nil) error.
+ (erc-nicklist-call-erc-command): If given no command, do nothing.
+ This fixes an error that used to occur when a stray mouse click
+ was made outside of the popup window, but on the erc-nicklist
+ menu.
+
+ * erc-bbdb.el (erc-bbdb-search-name-and-create): Get rid of the
+ infinite input loop when you want to create a new record. Replace
+ most of that with a completing read of existing nicks. If no nick
+ is chosen, create a new John Doe record. The net effect of this
+ is that the old behavior is re-instated, with the addition of one
+ completing read that happens when you do a /whois.
+
+2005-07-09 Johan Bockgård <bojohan@users.sourceforge.net>
+
+ * erc.el (erc-process-input-line): Docfix.
+ (erc-update-mode-line-buffer): Use `erc-propertize' instead of
+ `propertize'.
+ (erc-propertize): Move to erc-compat.el.
+
+ * erc-compat.el (erc-propertize): Move here from erc.el. Always
+ return a copy of the string (like `propertize' in GNU Emacs).
+
+ * erc-nicklist.el (erc-nicklist-icons-directory)
+ (erc-nicklist-voiced-position)
+ (erc-nicklist-insert-medium-name-or-icon): Docfix.
+ (erc-nicklist-insert-contents): Simplify.
+ (erc-nicklist-mode-map): Bind RET instead of `return'. Bind
+ `down-mouse-3' instead of `mouse-3'.
+ (erc-nicklist-kbd-cmd-QUERY): Cleanup regexp.
+ (erc-nicklist-channel-users-info): Docfix. Simplify.
+
+2005-07-02 Michael Olson <mwolson@gnu.org>
+
+ * images: New directory containing the images that are used by
+ erc-nicklist.el. These are from Gaim, and are thought to be
+ available under the terms of the GPL.
+
+ * erc-bbdb.el: Add local variables section to preserve tabs, since
+ that is the style used throughout this file. Apply patch from
+ Edgar Gonçalves as follows.
+ (erc-bbdb-bitlbee-name-field): New variable that indicates the
+ field name to use for annotating the "displayed name" of a bitlbee
+ contact.
+ (erc-bbdb-irc-highlight-field): Docfix.
+ (erc-bbdb-search-name-and-create): Prompt the user for the name of
+ a contact if none was found. Merge the new entries into the
+ specified contact. If new arg SILENT is non-nil, do not prompt
+ the user for a name or offer to merge the new entry.
+ (erc-bbdb-insinuate-and-show-entry): New arg SILENT is accepted,
+ which is passed on to erc-bbdb-search-name-and-create.
+ (erc-bbdb-whois): Tell erc-bbdb-search-name-and-create to prompt
+ for name if necessary.
+ (erc-bbdb-JOIN, erb-bbdb-NICK): Forbid
+ erc-bbdb-search-name-and-create from prompting for a name.
+
+ * erc-nicklist.el: Add local variables section to preserve tabs,
+ since that is the style used throughout this file. Apply patch
+ from Edgar Gonçalves as follows.
+ (erc-nicklist-use-icons): New option; if non-nil, display an icon
+ instead of the name of the chat medium.
+ (erc-nicklist-icons-directory): New option indicating the path to
+ the PNG files that are used for chat icons.
+ (erc-nicklist-use-icons): New option indicating whether to put
+ voiced nicks on top, bottom, or not to differentiate them. The
+ default is to put them on the bottom.
+ (erc-nicklist-bitlbee-connected-p): New variable that indicates
+ whether or not we are currently using bitlbee. An attempt will be
+ made to auto-detect the proper value. This is bound in the
+ `erc-nicklist-insert-contents' function.
+ (erc-nicklist-nicklist-images-alist): New variable that maps a
+ host type to its icon. This is set by `erc-nicklist'.
+ (erc-nicklist-insert-medium-name-or-icon): New function that
+ inserts an icon or string that identifies the current host type.
+ (erc-nicklist-search-for-nick): New function that attempts to find
+ a BBDB record that corresponds with this contact given its
+ finger-host. If found, return its bitlbee-nick field.
+ (erc-nicklist-insert-contents): New function that inserts the
+ contents of the nick list, including text properties and images.
+ (erc-nicklist): Populate `erc-nicklist-images-alist'. Move
+ nicklist content generation code to
+ `erc-nicklist-insert-contents'.
+ (erc-nicklist-mode-map): Map C-j to erc-nicklist-kbd-menu and RET
+ to erc-nicklist-kbd-cmd-QUERY.
+ (erc-nicklist-call-erc-command): Make use of
+ `switch-to-buffer-other-window'.
+ (erc-nicklist-cmd-QUERY): New function that opens a query buffer
+ for the given contact.
+ (erc-nicklist-kbd-cmd-QUERY): Ditto; contains most of the code.
+ (erc-nicklist-kbd-menu): New function that shows the nicklist
+ action menu.
+ (erc-nicklist-channel-users-info): Renamed from
+ `erc-nicklist-channel-nicks'. Implement sorting voiced users.
+
+2005-06-29 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc-nickserv.el (erc-nickserv-alist): Fix regexp for Azzurra.
+
+2005-06-26 Michael Olson <mwolson@gnu.org>
+
+ * erc-autojoin.el (erc-autojoin-add, erc-autojoin-remove): Use
+ `erc-session-server' if `erc-announced-server-name' is nil. This
+ happens when servers don't send a 004 message.
+
+ * erc.el (erc-quit-server): Ditto.
+
+ * erc-ibuffer.el (erc-server, erc-server-name): Ditto.
+
+ * erc-notify.el (erc-notify-JOIN, erc-notify-NICK)
+ (erc-notify-QUIT): Ditto.
+
+2005-06-24 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc.el (erc-default-coding-system)
+ (erc-handle-user-status-change): Docstring fix.
+ (with-erc-channel-buffer): Removed.
+ (erc-ignored-reply-p): Replace `with-erc-channel-buffer' with
+ `erc-with-buffer'.
+ (erc-display-line-1): Revision 1.730 broke undo. Fix it.
+
+2005-06-23 Michael Olson <mwolson@gnu.org>
+
+ * CREDITS: Add entries for Luigi Panzeri and Andreas Schwab.
+
+ * erc-nickserv.el (erc-nickserv-alist): Add entries for Azzurra
+ and OFTC. Thanks to Luigi Panzeri and Andreas Schwab for
+ providing these.
+
+2005-06-16 Michael Olson <mwolson@gnu.org>
+
+ * CREDITS: Add John Paul Wallington.
+
+ * erc.el: Thanks to John Paul Wallington for the following.
+ (erc-nickname-in-use): Use `string-to-number' instead of
+ `string-to-int'.
+
+ * erc-dcc.el (erc-dcc-handle-ctcp-send)
+ (erc-dcc-handle-ctcp-chat, erc-dcc-get-file)
+ (erc-dcc-chat-accept): Ditto.
+
+ * erc-identd.el (erc-identd-start): Ditto.
+
+2005-06-16 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc.el (erc-mode-map): Suppress `font-lock-fontify-block' key
+ binding since it destroys face properties.
+
+2005-06-08 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-cmd-UNIGNORE): Use `erc-member-ignore-case' instead
+ of `member-ignore-case'. Thanks to bpalmer for the heads up.
+
+2005-06-06 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-modules): Fix a mistake I made when editing this a
+ few days ago. Modes should now be disabled properly.
+ (erc-cmd-BANLIST, erc-cmd-MASSUNBAN): Remove unnecessary call to
+ `format'. Thanks to Andreas Schwab for reporting this.
+
+ * debian/changelog: Close "README file missing" bug.
+
+ * debian/rules (binary-erc): Install README file.
+
+2005-06-03 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-with-buffer): Set `lisp-indent-function' so Emacs
+ Lisp mode knows how to indent erc-with-buffer blocks.
+ (with-erc-channel-buffer): Ditto.
+ (erc-with-all-buffers-of-server): Ditto.
+ (erc-modules): Use pcomplete by default, not completion, since
+ erc-complete.el is deprecated. Use `fboundp' instead of
+ `symbol-value' to check for existence of a function before calling
+ it. This was causing an error when untoggling the `completion'
+ option and trying to save via the customize interface.
+
+ * erc-track.el (erc-modified-channels-update): If a buffer is not
+ currently connected, remove it from the modified channels list.
+ This should fix the problem where residue was left on the mode
+ line after quitting ERC.
+
+ * erc-list.el (erc-prettify-channel-list): Docfix; thanks to John
+ Paul Wallington for reporting this.
+
+2005-05-31 Michael Olson <mwolson@gnu.org>
+
+ * debian/changelog: First draft of entries for the 5.0.3 release.
+
+ * debian/README.Debian: Note that ERC will now install correctly
+ on versions of Emacs or XEmacs that do not have the `format-spec'
+ library. Correct some grammar and prune the content a bit.
+
+ * debian/scripts/install (emacs20): Remove line since we no longer
+ need to deal with format-spec.el.
+
+ * NEWS: Add entries for the upcoming 5.0.3 release.
+
+ * erc.el: Don't require format-spec since this is provided in
+ erc-compat.el now.
+ (erc-process-sentinel, erc-setup-periodical-server-ping): Use
+ `erc-cancel-timer' instead of `cancel-timer'.
+ (erc-version-string): Update to 5.0.3.
+
+ * erc-autoaway.el (autoaway, erc-autoaway-reestablish-idletimer):
+ Use `erc-cancel-timer' instead of `cancel-timer'.
+
+ * erc-compat.el (format-spec, format-spec-make): If we cannot load
+ the `format-spec' library, provide versions of these functions.
+ This should keep problems from surfacing with Emacs21 Debian
+ builds.
+ (erc-cancel-timer): New function created to take the place of
+ `cancel-timer' since XEmacs calls it something else.
+
+ * erc-track.el (erc-modified-channels-update): Accept any number
+ of arguments, which are ignored. This allows it to be run from
+ `erc-disconnected-hook' without extra bother.
+ (track): Add `erc-modified-channels-update' to
+ `erc-disconnected-hook' so that the indicators are removed
+ correctly in some edge cases.
+ (erc-modified-channels-display): Make sure that we never pass nil
+ to the function in `erc-track-shorten-function'. This happens
+ when we have deleted buffers in `erc-modified-channels-alist'.
+ Also, make sure that the buffer has a non-nil short-name before
+ adding it to the string list. This should fix some XEmacs
+ warnings when running /quit with unchecked buffers, as well as get
+ rid of a stray buffer problem (or so it is hoped).
+
+2005-05-31 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc-replace.el, erc-speak.el: Clean up comment formatting.
+
+ * erc-ring.el (ring, erc-input-ring-index, erc-clear-input-ring):
+ Clean up docstring formatting.
+
+2005-05-30 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc.el (erc-cmd-BANLIST, erc-cmd-MASSUNBAN): Delete superfluous
+ arg to `format'.
+ (erc-load-irc-script): Use `insert-file-contents' instead of
+ `insert-file'. Simplify.
+
+2005-05-29 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-version-string): Move this up so that it is
+ evaluated before the `require' statements. Not a major change.
+
+2005-04-27 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc.el (erc-complete-word): Simplify.
+
+2005-04-27 Michael Olson <mwolson@gnu.org>
+
+ * Makefile (debrelease): Use a slightly different approach when
+ removing CVS and Arch cruft.
+
+ * debian/changelog: Update for 5.0.2-1 package.
+
+2005-04-25 Michael Olson <mwolson@gnu.org>
+
+ * erc-autoaway.el (erc-autoaway-reestablish-idletimer): Move code
+ block higher in file to fix a load failure when using Emacs21.
+ Thanks to Daniel Brockman for the report and fix.
+
+2005-04-24 Adrian Aichner <adrian@xemacs.org>
+
+ * erc-backend.el (JOIN): save-excursion so that
+ `erc-current-logfile' inserts into the correct channel buffers
+ when using erc-log-insert-log-on-open in combination with autojoin
+ to multiple channels.
+
+2005-04-17 Adrian Aichner <adrian@xemacs.org>
+
+ * erc-log.el: Remove stray whitespace.
+ * erc.el: Ditto.
+
+2005-04-09 Aidan Kehoe <kehoea@parhasard.net>
+
+ * erc.el: autoload erc-select-read-args, which, because it parses
+ erc-select's args, can be called before erc.el is loaded.
+
+2005-04-07 Edward O'Connor <ted@oconnor.cx>
+
+ * erc-viper.el: Remove final newlines from previously-existing ERC
+ buffers. (Minor bug fix.)
+
+2005-04-06 Michael Olson <mwolson@gnu.org>
+
+ * Makefile (debrelease): Ignore errors from deleting Arch and CVS
+ metadata.
+
+2005-04-05 Michael Olson <mwolson@gnu.org>
+
+ * ChangeLog, CREDITS, AUTHORS: Correct name and email address of
+ Marcelo Toledo.
+
+2005-04-04 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-modules): Add entry for spelling module.
+
+ * erc-spelling.el: Add autoload line.
+
+ * erc-backend.el: Apply latest non-ascii patch from Kai Fan.
+ (erc-decode-parsed-server-response): Search
+ erc-response.command-args for channel name. Decode the
+ erc-response struct using this channel name as key according to
+ the `erc-encoding-coding-alist'.
+
+ * erc-track.el: Apply patch from Henrik Enberg.
+ (erc-modified-channels-object): Use optimal amount of whitespace
+ around modified channels indicator.
+
+2005-04-02 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc.el (define-erc-module, erc-with-buffer)
+ (erc-with-all-buffers-of-server, with-erc-channel-buffer): Add
+ edebug-form-spec.
+
+ * erc-compat (erc-define-minor-mode): Ditto.
+
+2005-03-29 Jorgen Schaefer <forcer@forcix.cx>
+
+ * erc-spelling.el: New file.
+
+2005-03-24 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc-backend.el (define-erc-response-handler): Add
+ `definition-name' property to constructed symbols so that
+ find-function and find-variable will find them.
+
+2005-03-21 Michael Olson <mwolson@gnu.org>
+
+ * erc-dcc.el, erc-goodies.el, erc-list.el, erc-notify.el,
+ erc-ring.el, erc.el: Copyright assignment occurred.
+
+ * debian/scripts/install: Make a shell wrapper around the original
+ Makefile and inline the Makefile. The problem is that Debian
+ passes all the Emacs variants at once, rotating them at every
+ invocation of the install script, which happens once per variant.
+ This caused each installation to happen N-1 times more often than
+ it should have. As a result, we need to only deal with the first
+ argument.
+ (ELFILES): Only add format-spec.el if we are compiling for
+ emacs21. Don't filter out erc-compat.el.
+ (SITEFLAG): New variable that indicates that the "nosite" option
+ should look like.
+ (.DEFAULT): Use $(FLAVOUR) instead of $@ for clarity.
+
+ * debian/rules: Install NEWS file and compress it.
+
+ * debian/maint/postinst: Be more cautious about configuration
+ step.
+
+ * debian/copyright (Copyright): Another assignment came in.
+
+ * debian/control (Standards-Version): Update to a newer version as
+ recommended by lintian.
+
+ * debian/changelog: Changes made for the Debian package.
+
+ * debian/README.Debian: Keep only the General Notes section.
+
+ * NEWS: Move old history items here from debian/README.Debian.
+
+ * Makefile (SNAPSHOTDATE): Deprecate this option since we hope to
+ release more often.
+
+2005-03-20 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-define-catalog, `ctcp-request-to'): Fix typo (%: ->
+ %t:).
+
+2005-03-01 Michael Olson <mwolson@gnu.org>
+
+ * erc-log.el (erc-save-buffer-in-logs): Replace tabs with spaces
+ in code indentation.
+
+2005-02-28 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-display-message): Apply corrected patch from Henrik
+ Enberg.
+
+2005-02-27 Michael Olson <mwolson@gnu.org>
+
+ * erc.el (erc-display-message): Apply patch from Henrik Enberg.
+ Check here to see if a message should be hidden, rather than
+ relying on code in each individual command.
+ (erc-version-string): Add "(CVS)" to the version string for
+ clarity.
+
+ * erc-backend.el (JOIN, KICK, MODE, NICK, PART, QUIT, TOPIC):
+ Don't check `erc-hide-list' here.
+
+ * erc-list.el, erc-match.el, erc.el, debian/copyright: Update
+ copyright information as a few more people have assignments
+ registered.
+
+2005-02-06 Michael Olson <mwolson@gnu.org>
+
+ * erc-backend.el: Apply patch from Kai Fan for non-ASCII character
+ support.
+ (erc-parse-server-response): Add call to
+ `erc-decode-parsed-server-response'.
+ (erc-decode-parsed-server-response): New function that decodes a
+ pre-parsed server response before it can be handled.
+ (PRIVMSG): Comment out call to `erc-decode-string-from-target'.
+ (TOPIC): Ditto.
+
+2005-02-01 Jorgen Schaefer <forcer@users.sourceforge.net>
+
+ * erc.el (erc-process-sentinel-1): Don't reconnect on connection
+ refused. This error is reported differently when using
+ open-network-stream-nowait.
+
+2005-01-26 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-cmd-APPENDTOPIC, erc-set-topic): The control
+ character in `channel-topic' was changed to \C-o - replaced \C-c
+ with \C-o so that these functions work as expected again.
+ (erc-get-channel-mode-from-keypress): Doc fix.
+
+2005-01-25 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el, erc-button.el, erc-compat.el, erc-goodies.el,
+ erc-match.el, erc-nets.el, ChangeLog, NEWS: Merged bug fixes made
+ on release_5_0_branch since 5.0.1 release.
+
+2005-01-24 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc.el (erc-input-action): Quote `erc-action-history-list' so
+ that input history actually works.
+ (erc-process-ctcp-query): Fix and simplify logic.
+ (erc-get-channel-mode-from-keypress): Use `C-' string syntax.
+ (erc-load-irc-script-lines): Use `erc-command-indicator' instead
+ of `erc-prompt'.
+
+2005-01-23 Edward O'Connor <ted@oconnor.cx>
+
+ * erc-viper.el: Ensure that `viper-comint-mode-hook' runs in
+ buffers whose `erc-mode-hook' has already run when this file is
+ loaded.
+ Explicitly `require' erc.el.
+
+2005-01-22 Edward O'Connor <ted@oconnor.cx>
+
+ * erc.el (erc-mode): Remove frobbing of `require-final-newline'.
+
+ * erc-log.el (erc-save-buffer-in-logs): Remove frobbing of
+ `require-final-newline'.
+
+ * erc-viper.el: New file. This is where all ERC/Viper
+ compatiibilty code should live. When and if ERC is bundled with
+ Emacs, some of the hacks in this file should be merged into Viper
+ itself.
+
+2005-01-21 Edward O'Connor <ted@oconnor.cx>
+
+ * erc.el (erc-mode): Set `require-final-newline' to nil in ERC
+ buffers. This prevents a Viper misfeature whereby extraneous
+ newlines are inserted into the ERC buffer when switching between
+ viper states.
+
+ * erc-log.el (erc-save-buffer-in-logs): Bind `require-final-newline'
+ to t when calling `write-region' to ensure that further log
+ entries start on fresh lines.
+
+2005-01-21 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-button.el (erc-button-add-face): Reverted my change to the
+ order faces since it had the unwanted effect of putting the button
+ face after all others.
+ (erc-button-face-has-priority): Removed this variable as it is not
+ necessary anymore - it was used to compensate for the above
+ mentioned change.
+
+ * NEWS: Added the latest fixes.
+
+2005-01-20 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-button.el, erc-match.el:
+ (erc-button-syntax-table, erc-match-syntax-table): Added \ as a
+ legal character for nicknames.
+
+ * erc-nets.el (erc-server-select): Fixed so that only networks
+ with servers found in `erc-server-alist' are available as choices.
+
+ * erc.el, erc-compat.el, erc-goodies.el:
+ (erc-replace-match-subexpression-in-string): New function. Needed
+ because `replace-match' in XEmacs doesn't replace regular
+ expression subexpressions in strings, only in buffers.
+ (erc-seconds-to-string, erc-controls-interpret): Use the new
+ function.
+
+ * erc-button.el (erc-button-add-button): Use the `:button-face'
+ key combined with an `erc-mode' local `widget-button-face' set to
+ nil to get the widget overlay face suppressed in XEmacs.
+
+2005-01-19 Francis Litterio <franl@world.std.com>
+
+ * erc-button.el (erc-button-add-face): The face added by this
+ function is more important than the existing text's face, so we
+ now prepend erc-button-face to the list of existing faces when
+ adding a button. To instead append erc-button-face to existing
+ faces, set variable `erc-button-face-has-priority' to nil.
+ (erc-button-face-has-priority): New variable to control how
+ erc-button-add-face adds erc-button-face to existing faces.
+ (erc-button-press-button): Silenced a byte-compiler warning about
+ too few arguments in a call to `error'.
+
+2005-01-19 Diane Murray <disumu@x3y2z1.net>
+
+ * NEWS: Added list of 5.0.1 fixes.
+
+2005-01-19 Michael Olson <mwolson@gnu.org>
+
+ * AUTHORS: Move to format that cscvs can understand. As an added
+ perk, entries line up nicer.
+
+ * erc.el, erc-fill.el, erc-pcomplete.el, debian/copyright: Merge a
+ few more copyright lines thanks to Alex Schroeder's BBDB file.
+
+ * Makefile: Change version to correspond with our new scheme.
+
+2005-01-18 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-list.el (erc-chanlist-channel-line-regexp): Now matches
+ private channels, the channels `#' and `&', and channels with
+ names including non-ascii characters.
+ (erc-chanlist-join-channel): Don't attempt to join private
+ channels since the channel name is unknown.
+
+ * erc-goodies.el (erc-make-read-only): Add `rear-nonsticky'
+ property to avoid `Text is read-only' errors during connection.
+ `front-nonsticky' does not exist, changed to `front-sticky'.
+ (erc-controls-interpret, erc-controls-strip): Just work on the
+ string, don't open a temporary buffer.
+ (erc-controls-propertize): Now accepts optional argument STR.
+
+2005-01-17 Michael Olson <mwolson@gnu.org>
+
+ * Makefile: Version is 5.01, but only in the Makefile. It has not
+ been released yet.
+
+ * erc-auto.in, erc-autojoin.el, erc-bbdb.el, erc-button.el,
+ erc-chess.el, erc-complete.el, erc-dcc.el, erc-fill.el,
+ erc-goodies.el, erc-ibuffer.el, erc-identd.el, erc-imenu.el,
+ erc-list.el, erc-match.el, erc-menu.el, erc-nets.el,
+ erc-netsplit.el, erc-nickserv.el, erc-notify.el, erc-pcomplete.el,
+ erc-ring.el, erc-speak.el, erc-speedbar.el, erc-stamp.el,
+ erc-track.el, erc-xdcc.el, erc.el, debian/copyright: Update
+ copyright notices. If anyone has signed papers for Emacs in
+ general, merge them with the FSF's entry.
+
+2005-01-16 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc): `erc-set-active-buffer' was being called before
+ `erc-process' was set, so that channels weren't being marked
+ active correctly upon join; fixed.
+
+2005-01-15 Johan Bockgård <bojohan+sf@dd.chalmers.se>
+
+ * erc-backend.el (def-edebug-spec): This macro caused problems (in
+ XEmacs). Use its expansion directly.
+
+2005-01-15 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-button.el (erc-button-add-button): Reverted previous change
+ since `:suppress-face' doesn't seem to be checked for a certain
+ face.
+ (erc-button-add-face): FACE is now appended to the `old' face.
+ This should fix the problem of faces being "covered" by
+ `erc-button-face'.
+
+2005-01-14 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el, erc-backend.el (erc-cmd-OPS, erc-cmd-COUNTRY,
+ erc-cmd-NICK, erc-process-ctcp-query, ERROR, PONG, 311, 312, 313,
+ 314, 317, 319, 320, 321, 322, 330, 352): Use catalog entries
+ instead of hard-coded text messages.
+ (english): Added new catalog entries `country', `country-unknown',
+ `ctcp-empty', `ctcp-request-to', `ctcp-too-many', `nick-too-long',
+ `ops', `ops-none', `ERROR', `PONG', `s311', `s312', `s313',
+ `s314', `s317', `s317-on-since', `s319', `s320', `s321', `s322',
+ `s330', and `s352'.
+ (erc-send-current-line): Use `erc-set-active-buffer' (change was
+ lost in previous bug fix).
+
+2005-01-14 Francis Litterio <franl@world.std.com>
+
+ * erc-button.el (erc-button-add-button): Fixed a bug where the
+ overlay created by widget-convert-button has a `face' property
+ that hides the `face' property set on the underlying button text.
+
+ * erc-goodies.el: Docstring fix.
+
+ * erc-button.el: Improved docstring for variable erc-button-face.
+
+2005-01-13 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-menu.el (erc-menu-definition): "Topic set by channel
+ operator": Small word change. "Identify to NickServ...": Check
+ that we're connected to the server. Added "Save buffer in log"
+ and "Truncate buffer".
+
+2005-01-13 Lawrence Mitchell <wence@gmx.li>
+
+ * erc.el (erc-display-line-1): Widen before we try to insert
+ anything, this makes sure input isn't broken when the buffer is
+ narrowed by the user.
+ (erc-beg-of-input-line): Simplify, just return the position of
+ `erc-insert-marker' or error if does not exist.
+ (erc-send-current-line): Widen before trying to send anything.
+
+2005-01-13 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el, erc-backend.el, erc-list.el:
+ (erc-update-mode-line-buffer): Strip controls characters from
+ `channel-topic' since we add our own control character to it.
+ (TOPIC, 332): Use \C-o instead of \C-c to force an end of IRC
+ control characters as it also ends bold, underline, and inverse -
+ \C-c only ends colors.
+ (erc-chanlist-322): Strip control characters from channel and
+ topic. No need to interpret controls when we're applying overlays
+ to the lines.
+
+ * erc.el, erc-backend.el, erc-button.el, erc-netsplit.el,
+ erc-nicklist.el: Fixed so that each server has an active buffer.
+ (erc-active-buffer): Now a buffer-local variable.
+ (erc-active-buffer, erc-set-active-buffer): New functions.
+ (erc-display-line, erc-echo-notice-in-active-non-server-buffer,
+ erc-process-away, MODE): Call `erc-active-buffer' to get the
+ active buffer for the current server.
+ (erc, erc-process-sentinel-1, erc-grab-region, erc-input-action,
+ erc-send-current-line, erc-invite-only-mode,
+ erc-toggle-channel-mode, erc-channel-names, MODE, erc-nick-popup,
+ erc-nicklist-call-erc-command): Use `erc-set-active-buffer' to set
+ the active buffer for the current server.
+ (erc-cmd-WHOLEFT): Use 'active as BUFFER in `erc-display-message'.
+
+ * erc-track.el (erc-track-modified-channels): Server buffers are
+ now treated the same as channels and queries. This means that
+ `erc-track-priority-faces-only', `erc-track-exclude', and
+ `erc-track-exclude-types' now work with server buffers.
+
+2005-01-12 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-backend.el (475): Prompt for the channel's key if
+ `erc-prompt-for-channel-key' is non-nil. Send a new JOIN message
+ with the key if a key is provided.
+
+ * erc.el (erc-command-indicator): Fixed customization choices so
+ that there's no `mismatch' message when nil is the value.
+
+2005-01-11 Michael Olson <mwolson@gnu.org>
+
+ * erc-bbdb.el (bbdb): Lowercase the name of the module. This
+ fixes a bug which caused an error to occur when trying to enable
+ the module using the customization interface.
+
+2005-01-08 Edward O'Connor <ted@oconnor.cx>
+
+ * erc-track.el: Support using faces to indicate channel activity
+ in the modeline under XEmacs.
+ (erc-modified-channels-object): New function.
+ (erc-modified-channels-display): Use it.
+ `erc-modified-channels-string' renamed to
+ `erc-modified-channels-object' (because it's no longer a string on
+ XEmacs). The new function `erc-modified-channels-object' is used
+ to generate updated values for the same-named variable.
+
+2005-01-08 Diane Murray <disumu@x3y2z1.net>
+
+ * ChangeLog.2002: Changed instances of my sourceforge username and
+ email address to real name and email.
+
+ * erc.el (erc-modules): Changed customization tag descriptions, so
+ that they all start with a verb; added new modules to choices.
+
+2005-01-08 Mario Lang <mlang@delysid.org>
+
+ * debian/rules: Introduce new variable DOCDIR to simplify stuff a
+ bit.
+
+2005-01-08 Michael Olson <mwolson@gnu.org>
+
+ * AUTHORS, ChangeLog.2004: Change bpalmer's email address as
+ requested.
+
+ * CREDITS: Add everyone who is mentioned in the ChangeLogs.
+
+ * debian/copyright (Copyright): Add last few people. This can now
+ be considered a complete list, as far as CVS entries are
+ concerned. If people have assigned copyright to the FSF, merge
+ them with the entry for the FSF.
+
+ * debian/README.Debian: Add entry for XEmacs-related change in
+ `erc-track.el'.
+
+ * erc.el (erc-cmd-MODE): New command that changes or displays the
+ mode for a channel or user. The functionality was present before
+ this change, but there was no documentation for it.
+
+ * erc-auto.in, erc-*.el: Fully investigate copyright headers and
+ change them appropriately. If a file has been pulled off of
+ erc.el at one time, keep track of copyright from the time of
+ separation, but not before. If a file has been derived from a
+ work outside of erc, keep copyright statements in place.
+
+ * Makefile (VERSION): Change to 5.0! :^) Congrats on all the great
+ work. I'll wait until hober commits his XEmacs compatibility
+ patch to erc-track.el, and then release.
+ (distclean): Alias for `realclean' target.
+
+2005-01-07 Michael Olson <mwolson@gnu.org>
+
+ * AUTHORS: Add Marcelo Toledo, who has CVS access to this project.
+
+ * ChangeLog.2004: Add my name to my one contribution to erc last
+ year.
+
+ * CREDITS: Add people that were discovered while scouring
+ ChangeLogs.
+
+ * debian/copyright: Add everyone from `AUTHORS' to Upstream
+ Authors. Anyone who has contributed 15 or more lines of
+ code (according to ChangeLogs) is listed in Copyright section.
+ Accurate years are included.
+
+ * debian/README.Debian: Paste content of NEWS and reformat
+ slightly.
+
+ * debian/rules: Concatenate the ChangeLogs during the Debian
+ install process and then gzip them.
+
+ * Makefile (MISC): Add ChangeLog.yyyy files to list.
+ (ChangeLog): Remove rule since we do not dynamically generate the
+ ChangeLog anymore.
+
+ * MkChangeLog: Removed since we do not use it to generate the
+ ChangeLog anymore. cvs2cl does a much better job anyway.
+
+ * NEWS: Use 3rd level heading instead of bullets for lists that
+ contain descriptions.
+
+2005-01-07 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-list.el: Require 'sort.
+ (erc-chanlist): Disable undo in the channel list buffer.
+
+ * erc.el, erc-menu.el: The `IRC' menu is now automatically added
+ to the menu-bar. Add the call to `easy-menu-add' to
+ `erc-mode-hook' when running in XEmacs (without this the menu
+ doesn't appear).
+
+ * NEWS: Added the information from
+ http://emacswiki.org/cgi-bin/wiki/ErcCvsFeatures and the newer
+ changes which weren't yet documented on that page.
+
+2005-01-06 Hoan Ton-That <hoan@ton-that.org>
+
+ * erc-log.el (erc-current-logfile): Only downcase the logfile
+ name, not the whole filename. Also expand relative to
+ `erc-log-channels-directory'.
+ (erc-generate-log-file-name-with-date)
+ (erc-generate-log-file-name-short)
+ (erc-generate-log-file-name-long): Don't expand filename, done in
+ `erc-current-logfile'.
+
+2005-01-06 Lawrence Mitchell <wence@gmx.li>
+
+ * NEWS: New file, details user visible changes from version to
+ version.
+
+ * HACKING (NEWS entries): Mention NEWS file, and what its purpose
+ is.
+
+2005-01-05 Michael Olson <mwolson@gnu.org>
+
+ * FOR-RELEASE: New file containing the list of release-critical
+ tasks. Feel free to add to it.
+
+ * debian/rules (binary-erc): Add ChangeLog files.
+
+2005-01-04 Michael Olson <mwolson@gnu.org>
+
+ * ChangeLog.2001, ChangeLog.2002, ChangeLog.2003, ChangeLog.2004:
+ ChangeLog entries from previous years.
+
+ * ChangeLog: New file containing ChangeLog entries for the current
+ year. Please update this file manually whenever a change is
+ committed. This is a new policy.
+
+ * AUTHORS: Add myself to list. Some entries were space-delimited
+ instead of TAB-delimited, and since the latter seemed to be the
+ default, make the other entries conform.
+
+ * HACKING (ChangeLog Entries): Update section to reflect new
+ policy toward ChangeLog entries, which is that they should be
+ manually updated whenever a change is committed.
+
+2005-01-04 Diane Murray <disumu@x3y2z1.net>
+
+ * erc.el (erc-connection-established, erc-login): Update the
+ mode-line.
+ (erc-update-mode-line-buffer): If `erc-current-nick' returns nil,
+ use an empty string for ?n character in format spec. Set
+ `mode-line-process' to ":connecting" while the connection is being
+ established.
+
+2005-01-04 Lawrence Mitchell <wence@gmx.li>
+
+ * AUTHORS: Update list of authors.
+
+2005-01-02 Diane Murray <disumu@x3y2z1.net>
+
+ * erc-goodies.el (erc-control-characters): New customization
+ group.
+ (erc-interpret-controls-p): Small fix, addition to
+ documentation. Updated customization to allow 'remove as a value.
+ Use 'erc-control-characters as `:group'.
+ (erc-interpret-mirc-color): Use 'erc-control-characters as
+ `:group'.
+ (erc-beep-p): Updated documentation. Use 'erc-control-characters
+ as `:group'.
+ (define-erc-module irccontrols): Add `erc-controls-highlight' to
+ `erc-insert-modify-hook' and `erc-send-modify-hook' since it
+ changes the text's appearance.
+ (erc-controls-remove-regexp, erc-controls-interpret-regexp): New
+ variables.
+ (erc-controls-highlight): Fixed so that highlighting works even if
+ there is no following control character. Fixed mirc color
+ highlighting; now respecting `erc-interpret-mirc-color'. Fixed a
+ bug where emacs would get stuck in a loop when \C-g was in a
+ message and `erc-beep-p' was set to nil (default setting).
+
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Copying and distribution of this file, with or without modification,
+ are permitted provided the copyright notice and this notice are preserved.
+
+;; arch-tag: 70f1733a-3e2f-43c2-91c3-d9ace93f82ba
diff --git a/lisp/erc/erc-autoaway.el b/lisp/erc/erc-autoaway.el
new file mode 100644
index 00000000000..41c16b82cb1
--- /dev/null
+++ b/lisp/erc/erc-autoaway.el
@@ -0,0 +1,207 @@
+;;; erc-autoaway.el --- Provides autoaway for ERC
+
+;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcAutoAway
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; TODO:
+;; - Legacy names: erc-auto-discard-away, erc-auto-set-away
+
+;;; Code:
+
+(require 'erc)
+
+(defgroup erc-autoaway nil
+ "Set yourself automatically away after some idletime and set
+yourself back when you type something."
+ :group 'erc)
+
+(defvar erc-autoaway-idletimer nil
+ "The Emacs idletimer.
+This is only used when `erc-autoaway-use-emacs-idle' is non-nil.")
+
+(defcustom erc-autoaway-use-emacs-idle nil
+ "*If non-nil, the idle time refers to idletime in Emacs.
+If nil, the idle time refers to idletime on IRC only.
+The time itself is specified by `erc-autoaway-idle-seconds'.
+See `erc-autoaway-mode' for more information on the various
+definitions of being idle.
+
+Note that using Emacs idletime is currently broken for most versions,
+since process activity (as happens all the time on IRC) makes Emacs
+non-idle. Emacs idle-time and user idle-time are just not the same."
+ :group 'erc-autoaway
+ :type 'boolean)
+
+;;;###autoload (autoload 'erc-autoaway-mode "erc-autoaway")
+(define-erc-module autoaway nil
+ "In ERC autoaway mode, you can be set away automatically.
+If `erc-auto-set-away' is set, then you will be set away after
+the number of seconds specified in `erc-autoaway-idle-seconds'.
+
+There are several kinds of being idle:
+
+IRC idle time measures how long since you last sent something (see
+`erc-autoaway-last-sent-time'). This is the default.
+
+Emacs idle time measures how long Emacs has been idle. This is
+currently not useful, since Emacs is non-idle when it handles
+ping-pong with IRC servers. See `erc-autoaway-use-emacs-idle' for
+more information.
+
+User idle time measures how long you have not been sending any
+commands to Emacs, or to your system. Emacs currently provides no way
+to measure user idle time.
+
+If `erc-auto-discard-away' is set, then typing anything, will
+set you no longer away.
+
+Related variables: `erc-public-away-p' and `erc-away-nickname'."
+ ;; Enable:
+ ((add-hook 'erc-send-completed-hook 'erc-autoaway-reset-idletime)
+ (add-hook 'erc-server-001-functions 'erc-autoaway-reset-idletime)
+ (add-hook 'erc-timer-hook 'erc-autoaway-possibly-set-away)
+ (when erc-autoaway-use-emacs-idle
+ (erc-autoaway-reestablish-idletimer)))
+ ;; Disable:
+ ((remove-hook 'erc-send-completed-hook 'erc-autoaway-reset-idletime)
+ (remove-hook 'erc-server-001-functions 'erc-autoaway-reset-idletime)
+ (remove-hook 'erc-timer-hook 'erc-autoaway-possibly-set-away)
+ (when erc-autoaway-idletimer
+ (erc-cancel-timer erc-autoaway-idletimer)
+ (setq erc-autoaway-idletimer nil))))
+
+(defcustom erc-auto-set-away t
+ "*If non-nil, set away after `erc-autoaway-idle-seconds' seconds of idling.
+ERC autoaway mode can set you away when you idle, and set you no
+longer away when you type something. This variable controls whether
+you will be set away when you idle. See `erc-auto-discard-away' for
+the other half."
+ :group 'erc-autoaway
+ :type 'boolean)
+
+(defcustom erc-auto-discard-away t
+ "*If non-nil, sending anything when away automatically discards away state.
+ERC autoaway mode can set you away when you idle, and set you no
+longer away when you type something. This variable controls whether
+you will be set no longer away when you type something. See
+`erc-auto-set-away' for the other half.
+See also `erc-autoaway-no-auto-discard-regexp'."
+ :group 'erc-autoaway
+ :type 'boolean)
+
+(defcustom erc-autoaway-no-auto-discard-regexp "^/g?away.*$"
+ "*Input that matches this will not automatically discard away status.
+See `erc-auto-discard-away'."
+ :group 'erc-autoaway
+ :type 'regexp)
+
+(eval-when-compile (defvar erc-autoaway-idle-seconds))
+
+(defun erc-autoaway-reestablish-idletimer ()
+ "Reestablish the emacs idletimer.
+You have to call this function each time you change
+`erc-autoaway-idle-seconds', if `erc-autoaway-use-emacs-idle' is set."
+ (interactive)
+ (when erc-autoaway-idletimer
+ (erc-cancel-timer erc-autoaway-idletimer))
+ (setq erc-autoaway-idletimer
+ (run-with-idle-timer erc-autoaway-idle-seconds
+ t
+ 'erc-autoaway-set-away
+ erc-autoaway-idle-seconds)))
+
+(defcustom erc-autoaway-idle-seconds 1800
+ "*Number of seconds after which ERC will set you automatically away.
+If you are changing this variable using lisp instead of customizing it,
+you have to run `erc-autoaway-reestablish-idletimer' afterwards."
+ :group 'erc-autoaway
+ :set (lambda (sym val)
+ (set-default sym val)
+ (when erc-autoaway-use-emacs-idle
+ (erc-autoaway-reestablish-idletimer)))
+ :type 'number)
+
+(defcustom erc-autoaway-message
+ "I'm gone (autoaway after %i seconds of idletime)"
+ "*Message ERC will use when he sets you automatically away.
+It is used as a `format' string with the argument of the idletime in
+seconds."
+ :group 'erc-autoaway
+ :type 'string)
+
+(defvar erc-autoaway-last-sent-time (erc-current-time)
+ "The last time the user sent something.")
+
+(defun erc-autoaway-reset-idletime (line &rest stuff)
+ "Reset the stored idletime for the user.
+This is one global variable since a user talking on one net can talk
+on another net too."
+ (when (and erc-auto-discard-away
+ (stringp line)
+ (not (string-match erc-autoaway-no-auto-discard-regexp line)))
+ (erc-autoaway-set-back line))
+ (setq erc-autoaway-last-sent-time (erc-current-time)))
+
+(defun erc-autoaway-set-back (line)
+ "Discard the away state globally."
+ (when (erc-away-p)
+ (setq erc-autoaway-last-sent-time (erc-current-time))
+ (erc-cmd-GAWAY "")))
+
+(defun erc-autoaway-possibly-set-away (current-time)
+ "Set autoaway when `erc-auto-set-away' is true and the idletime is
+exceeds `erc-autoaway-idle-seconds'."
+ ;; A test for (erc-server-process-alive) is not necessary, because
+ ;; this function is called from `erc-timer-hook', which is called
+ ;; whenever the server sends something to the client.
+ (when (and erc-auto-set-away
+ (not (erc-away-p)))
+ (let ((idle-time (erc-time-diff erc-autoaway-last-sent-time
+ current-time)))
+ (when (>= idle-time erc-autoaway-idle-seconds)
+ (erc-display-message
+ nil 'notice nil
+ (format "Setting automatically away after %i seconds of idle-time"
+ idle-time))
+ (erc-autoaway-set-away idle-time)))))
+
+(defun erc-autoaway-set-away (idle-time)
+ "Set the away state globally."
+ ;; Note that the idle timer runs, even when Emacs is inactive. In
+ ;; order to prevent flooding when we connect, we test for an
+ ;; existing process.
+ (when (and (erc-server-process-alive)
+ (not (erc-away-p)))
+ (erc-cmd-GAWAY (format erc-autoaway-message idle-time))))
+
+(provide 'erc-autoaway)
+
+;;; erc-autoaway.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 16fc241e-8358-4b56-9fe2-116bdd0ba3bc
diff --git a/lisp/erc/erc-autojoin.el b/lisp/erc/erc-autojoin.el
new file mode 100644
index 00000000000..38a149d8921
--- /dev/null
+++ b/lisp/erc/erc-autojoin.el
@@ -0,0 +1,139 @@
+;;; erc-autojoin.el --- autojoin channels on connect and reconnects
+
+;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Alex Schroeder <alex@gnu.org>
+;; Keywords: irc
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcAutoJoin
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This allows us to customize an `erc-autojoin-channels-alist'. As
+;; we /JOIN and /PART channels, this alist is updated to reflect our
+;; current setup, so that when we reconnect, we rejoin the same
+;; channels. The alist can be customized, so that the customized
+;; value will be used when we reconnect in our next Emacs session.
+
+;;; Code:
+
+(require 'erc)
+;;; Minor Mode
+
+(defgroup erc-autojoin nil
+ "Enable autojoining."
+ :group 'erc)
+
+;;;###autoload (autoload 'erc-autojoin-mode "erc-autojoin" nil t)
+(define-erc-module autojoin nil
+ "Makes ERC autojoin on connects and reconnects."
+ ((add-hook 'erc-after-connect 'erc-autojoin-channels)
+ (add-hook 'erc-server-JOIN-functions 'erc-autojoin-add)
+ (add-hook 'erc-server-PART-functions 'erc-autojoin-remove))
+ ((remove-hook 'erc-after-connect 'erc-autojoin-channels)
+ (remove-hook 'erc-server-JOIN-functions 'erc-autojoin-add)
+ (remove-hook 'erc-server-PART-functions 'erc-autojoin-remove)))
+
+(defcustom erc-autojoin-channels-alist nil
+ "Alist of channels to autojoin on IRC networks.
+Every element in the alist has the form (SERVER . CHANNELS).
+SERVER is a regexp matching the server, and channels is the
+list of channels to join.
+
+Customize this variable to set the value for your first connect.
+Once you are connected and join and part channels, this alist
+keeps track of what channels you are on, and will join them
+again when you get disconnected. When you restart Emacs, however,
+those changes are lost, and the customization you saved the last
+time is used again."
+ :group 'erc-autojoin
+ :type '(repeat (cons :tag "Server"
+ (regexp :tag "Name")
+ (repeat :tag "Channels"
+ (string :tag "Name")))))
+
+(defcustom erc-autojoin-domain-only t
+ "Truncate host name to the domain name when joining a server.
+If non-nil, and a channel on the server a.b.c is joined, then
+only b.c is used as the server for `erc-autojoin-channels-alist'.
+This is important for networks that redirect you to other
+servers, presumably in the same domain."
+ :group 'erc-autojoin
+ :type 'boolean)
+
+(defun erc-autojoin-channels (server nick)
+ "Autojoin channels in `erc-autojoin-channels-alist'."
+ (dolist (l erc-autojoin-channels-alist)
+ (when (string-match (car l) server)
+ (dolist (chan (cdr l))
+ (erc-server-send (concat "join " chan))))))
+
+(defun erc-autojoin-add (proc parsed)
+ "Add the channel being joined to `erc-autojoin-channels-alist'."
+ (let* ((chnl (erc-response.contents parsed))
+ (nick (car (erc-parse-user (erc-response.sender parsed))))
+ (server (with-current-buffer (process-buffer proc)
+ (or erc-server-announced-name erc-session-server))))
+ (when (erc-current-nick-p nick)
+ (when (and erc-autojoin-domain-only
+ (string-match "[^.]+\\.\\([^.]+\\.[^.]+\\)$" server))
+ (setq server (match-string 1 server)))
+ (let ((elem (assoc server erc-autojoin-channels-alist)))
+ (if elem
+ (unless (member chnl (cdr elem))
+ (setcdr elem (cons chnl (cdr elem))))
+ (setq erc-autojoin-channels-alist
+ (cons (list server chnl)
+ erc-autojoin-channels-alist))))))
+ ;; We must return nil to tell ERC to continue running the other
+ ;; functions.
+ nil)
+
+;; (erc-parse-user "kensanata!~user@dclient217-162-233-228.hispeed.ch")
+
+(defun erc-autojoin-remove (proc parsed)
+ "Remove the channel being left from `erc-autojoin-channels-alist'."
+ (let* ((chnl (car (erc-response.command-args parsed)))
+ (nick (car (erc-parse-user (erc-response.sender parsed))))
+ (server (with-current-buffer (process-buffer proc)
+ (or erc-server-announced-name erc-session-server))))
+ (when (erc-current-nick-p nick)
+ (when (and erc-autojoin-domain-only
+ (string-match "[^.]+\\.\\([^.]+\\.[^.]+\\)$" server))
+ (setq server (match-string 1 server)))
+ (let ((elem (assoc server erc-autojoin-channels-alist)))
+ (when elem
+ (setcdr elem (delete chnl (cdr elem)))
+ (unless (cdr elem)
+ (setq erc-autojoin-channels-alist
+ (delete elem erc-autojoin-channels-alist)))))))
+ ;; We must return nil to tell ERC to continue running the other
+ ;; functions.
+ nil)
+
+(provide 'erc-autojoin)
+
+;;; erc-autojoin.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: d62d8b15-8e31-49d6-8a73-12f11e717414
diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el
new file mode 100644
index 00000000000..a99af9dea64
--- /dev/null
+++ b/lisp/erc/erc-backend.el
@@ -0,0 +1,1786 @@
+;;; erc-backend.el --- Backend network communication for ERC
+
+;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+
+;; Filename: erc-backend.el
+;; Author: Lawrence Mitchell <wence@gmx.li>
+;; Created: 2004-05-7
+;; Keywords: IRC chat client internet
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file defines backend network communication handlers for ERC.
+;;
+;; How things work:
+;;
+;; You define a new handler with `define-erc-response-handler'. This
+;; defines a function, a corresponding hook variable, and populates a
+;; global hash table `erc-server-responses' with a map from response
+;; to hook variable. See the function documentation for more
+;; information.
+;;
+;; Upon receiving a line from the server, `erc-parse-server-response'
+;; is called on it.
+;;
+;; A line generally looks like:
+;;
+;; LINE := ':' SENDER ' ' COMMAND ' ' (COMMAND-ARGS ' ')* ':' CONTENTS
+;; SENDER := Not ':' | ' '
+;; COMMAND := Not ':' | ' '
+;; COMMAND-ARGS := Not ':' | ' '
+;;
+;; This gets parsed and stuffed into an `erc-response' struct. You
+;; can access the fields of the struct with:
+;;
+;; COMMAND --- `erc-response.command'
+;; COMMAND-ARGS --- `erc-response.command-args'
+;; CONTENTS --- `erc-response.contents'
+;; SENDER --- `erc-response.sender'
+;; LINE --- `erc-response.unparsed'
+;;
+;; WARNING, WARNING!!
+;; It's probably not a good idea to destructively modify the list
+;; of command-args in your handlers, since other functions down the
+;; line may well need to access the arguments too.
+;;
+;; That is, unless you're /absolutely/ sure that your handler doesn't
+;; invoke some other function that needs to use COMMAND-ARGS, don't do
+;; something like
+;;
+;; (while (erc-response.command-args parsed)
+;; (let ((a (pop (erc-response.command-args parsed))))
+;; ...))
+;;
+;; The parsed response is handed over to
+;; `erc-handle-parsed-server-response', which checks whether it should
+;; carry out duplicate suppression, and then runs `erc-call-hooks'.
+;; `erc-call-hooks' retrieves the relevant hook variable from
+;; `erc-server-responses' and runs it.
+;;
+;; Most handlers then destructure the parsed response in some way
+;; (depending on what the handler is, the arguments have different
+;; meanings), and generally display something, usually using
+;; `erc-display-message'.
+
+;;; TODO:
+
+;; o Generalise the display-line code so that we can use it to
+;; display the stuff we send, as well as the stuff we receive.
+;; Then, move all display-related code into another backend-like
+;; file, erc-display.el, say.
+;;
+;; o Clean up the handlers using new display code (has to be written
+;; first).
+
+;;; History:
+
+;; 2004/05/10 -- Handler bodies taken out of erc.el and ported to new
+;; interface.
+
+;; 2005-08-13 -- Moved sending commands from erc.el.
+
+;;; Code:
+
+(require 'erc-compat)
+(eval-when-compile (require 'cl))
+(autoload 'erc-with-buffer "erc" nil nil 'macro)
+(autoload 'erc-log "erc" nil nil 'macro)
+
+;;;; Variables and options
+
+(defvar erc-server-responses (make-hash-table :test #'equal)
+ "Hashtable mapping server responses to their handler hooks.")
+
+(defstruct (erc-response (:conc-name erc-response.))
+ (unparsed "" :type string)
+ (sender "" :type string)
+ (command "" :type string)
+ (command-args '() :type list)
+ (contents "" :type string))
+
+;;; User data
+
+(defvar erc-server-current-nick nil
+ "Nickname on the current server.
+Use `erc-current-nick' to access this.")
+(make-variable-buffer-local 'erc-server-current-nick)
+
+;;; Server attributes
+
+(defvar erc-server-process nil
+ "The process object of the corresponding server connection.")
+(make-variable-buffer-local 'erc-server-process)
+
+(defvar erc-session-server nil
+ "The server name used to connect to for this session.")
+(make-variable-buffer-local 'erc-session-server)
+
+(defvar erc-session-port nil
+ "The port used to connect to.")
+(make-variable-buffer-local 'erc-session-port)
+
+(defvar erc-server-announced-name nil
+ "The name the server announced to use.")
+(make-variable-buffer-local 'erc-server-announced-name)
+
+(defvar erc-server-version nil
+ "The name and version of the server's ircd.")
+(make-variable-buffer-local 'erc-server-version)
+
+(defvar erc-server-parameters nil
+ "Alist listing the supported server parameters.
+
+This is only set if the server sends 005 messages saying what is
+supported on the server.
+
+Entries are of the form:
+ (PARAMETER . VALUE)
+or
+ (PARAMETER) if no value is provided.
+
+Some examples of possible parameters sent by servers:
+CHANMODES=b,k,l,imnpst - list of supported channel modes
+CHANNELLEN=50 - maximum length of channel names
+CHANTYPES=#&!+ - supported channel prefixes
+CHARMAPPING=rfc1459 - character mapping used for nickname and channels
+KICKLEN=160 - maximum allowed kick message length
+MAXBANS=30 - maximum number of bans per channel
+MAXCHANNELS=10 - maximum number of channels allowed to join
+NETWORK=EFnet - the network identifier
+NICKLEN=9 - maximum allowed length of nicknames
+PREFIX=(ov)@+ - list of channel modes and the user prefixes if user has mode
+RFC2812 - server supports RFC 2812 features
+SILENCE=10 - supports the SILENCE command, maximum allowed number of entries
+TOPICLEN=160 - maximum allowed topic length
+WALLCHOPS - supports sending messages to all operators in a channel")
+(make-variable-buffer-local 'erc-server-parameters)
+
+;;; Server and connection state
+
+(defvar erc-server-connected nil
+ "Non-nil if the `current-buffer' is associated with an open IRC connection.
+This variable is buffer-local.")
+(make-variable-buffer-local 'erc-server-connected)
+
+(defvar erc-server-quitting nil
+ "Non-nil if the user requests a quit.")
+(make-variable-buffer-local 'erc-server-quitting)
+
+(defvar erc-server-lines-sent nil
+ "Line counter.")
+(make-variable-buffer-local 'erc-server-lines-sent)
+
+(defvar erc-server-last-peers '(nil . nil)
+ "Last peers used, both sender and receiver.
+Those are used for /MSG destination shortcuts.")
+(make-variable-buffer-local 'erc-server-last-peers)
+
+(defvar erc-server-last-sent-time nil
+ "Time the message was sent.
+This is useful for flood protection.")
+(make-variable-buffer-local 'erc-server-last-sent-time)
+
+(defvar erc-server-last-ping-time nil
+ "Time the last ping was sent.
+This is useful for flood protection.")
+(make-variable-buffer-local 'erc-server-last-ping-time)
+
+(defvar erc-server-lag nil
+ "Calculated server lag time in seconds.
+This variable is only set in a server buffer.")
+(make-variable-buffer-local 'erc-server-lag)
+
+(defvar erc-server-filter-data nil
+ "The data that arrived from the server
+but has not been processed yet.")
+(make-variable-buffer-local 'erc-server-filter-data)
+
+(defvar erc-server-duplicates (make-hash-table :test 'equal)
+ "Internal variable used to track duplicate messages.")
+(make-variable-buffer-local 'erc-server-duplicates)
+
+;; From Circe
+(defvar erc-server-processing-p nil
+ "Non-nil when we're currently processing a message.
+
+When ERC receives a private message, it sets up a new buffer for
+this query. These in turn, though, do start flyspell. This
+involves starting an external process, in which case Emacs will
+wait - and when it waits, it does accept other stuff from, say,
+network exceptions. So, if someone sends you two messages
+quickly after each other, ispell is started for the first, but
+might take long enough for the second message to be processed
+first.")
+(make-variable-buffer-local 'erc-server-processing-p)
+
+(defvar erc-server-flood-last-message 0
+ "When we sent the last message.
+See `erc-server-flood-margin' for an explanation of the flood
+protection algorithm.")
+(make-variable-buffer-local 'erc-server-flood-last-message)
+
+(defvar erc-server-flood-queue nil
+ "The queue of messages waiting to be sent to the server.
+See `erc-server-flood-margin' for an explanation of the flood
+protection algorithm.")
+(make-variable-buffer-local 'erc-server-flood-queue)
+
+(defvar erc-server-flood-timer nil
+ "The timer to resume sending.")
+(make-variable-buffer-local 'erc-server-flood-timer)
+
+;;; IRC protocol and misc options
+
+(defgroup erc-server nil
+ "Parameters for dealing with IRC servers."
+ :group 'erc)
+
+(defcustom erc-server-auto-reconnect t
+ "Non-nil means that ERC will attempt to reestablish broken connections.
+
+Reconnection will happen automatically for any unexpected disconnection."
+ :group 'erc-server
+ :type 'boolean)
+
+(defcustom erc-split-line-length 440
+ "*The maximum length of a single message.
+If a message exceeds this size, it is broken into multiple ones.
+
+IRC allows for lines up to 512 bytes. Two of them are CR LF.
+And a typical message looks like this:
+
+ :nicky!uhuser@host212223.dialin.fnordisp.net PRIVMSG #lazybastards :Hello!
+
+You can limit here the maximum length of the \"Hello!\" part.
+Good luck."
+ :type 'integer
+ :group 'erc-server)
+
+(defcustom erc-server-coding-system (if (and (fboundp 'coding-system-p)
+ (coding-system-p 'undecided)
+ (coding-system-p 'utf-8))
+ '(utf-8 . undecided)
+ nil)
+ "The default coding system for incoming and outgoing text.
+This is either a coding system, a cons, a function, or nil.
+
+If a cons, the encoding system for outgoing text is in the car
+and the decoding system for incoming text is in the cdr. The most
+interesting use for this is to put `undecided' in the cdr. If a
+function, it is called with no arguments and should return a
+coding system or a cons as described above. Note that you can use
+the dynamically bound variable `target' to get the current
+target. See `erc-coding-system-for-target'.
+
+If you need to send non-ASCII text to people not using a client that
+does decoding on its own, you must tell ERC what encoding to use.
+Emacs cannot guess it, since it does not know what the people on the
+other end of the line are using."
+ :group 'erc-server
+ :type '(choice (const :tag "None" nil)
+ coding-system
+ (cons (coding-system :tag "encoding" :value utf-8)
+ (coding-system :tag "decoding" :value undecided))
+ function))
+
+(defcustom erc-encoding-coding-alist nil
+ "Alist of target regexp and coding-system pairs to use.
+This overrides `erc-server-coding-system' depending on the
+current target as returned by `erc-default-target'.
+
+Example: If you know that the channel #linux-ru uses the coding-system
+`cyrillic-koi8', then add '(\"#linux-ru\" . cyrillic-koi8) to the
+alist."
+ :group 'erc-server
+ :type '(repeat (cons (string :tag "Target")
+ coding-system)))
+
+(defcustom erc-server-connect-function
+ (if (and (fboundp 'open-network-stream-nowait)
+ ;; CVS Emacs claims to define open-network-stream-nowait on
+ ;; windows, however, it does, in fact, not work.
+ (not (memq system-type '(windows-nt cygwin ms-dos darwin))))
+ 'open-network-stream-nowait
+ 'open-network-stream)
+ "Function used to initiate a connection.
+It should take same arguments as `open-network-stream' does."
+ :group 'erc-server
+ :type 'function)
+
+(defcustom erc-server-prevent-duplicates '("301")
+ "*Either nil or a list of strings.
+Each string is a IRC message type, like PRIVMSG or NOTICE.
+All Message types in that list of subjected to duplicate prevention."
+ :type '(choice (const nil) (list string))
+ :group 'erc-server)
+
+(defcustom erc-server-duplicate-timeout 60
+ "*The time allowed in seconds between duplicate messages.
+
+If two identical messages arrive within this value of one another, the second
+isn't displayed."
+ :type 'integer
+ :group 'erc-server)
+
+;;; Flood-related
+
+;; Most of this is courtesy of Jorgen Schaefer and Circe
+;; (http://www.nongnu.org/circe)
+
+(defcustom erc-server-flood-margin 10
+ "*A margin on how much excess data we send.
+The flood protection algorithm of ERC works like the one
+detailed in RFC 2813, section 5.8 \"Flood control of clients\".
+
+ * If `erc-server-flood-last-message' is less than the current
+ time, set it equal.
+ * While `erc-server-flood-last-message' is less than
+ `erc-server-flood-margin' seconds ahead of the current
+ time, send a message, and increase
+ `erc-server-flood-last-message' by
+ `erc-server-flood-penalty' for each message."
+ :type 'integer
+ :group 'erc-server)
+
+(defcustom erc-server-flood-penalty 3
+ "How much we penalize a message.
+See `erc-server-flood-margin' for an explanation of the flood
+protection algorithm."
+ :type 'integer
+ :group 'erc-server)
+
+;; Ping handling
+
+(defcustom erc-server-send-ping-interval 90
+ "*Interval of sending pings to the server, in seconds.
+If this is set to nil, pinging the server is disabled."
+ :group 'erc-server
+ :type '(choice (const nil) (integer :tag "Seconds")))
+
+(defvar erc-server-ping-handler nil
+ "This variable holds the periodic ping timer.")
+(make-variable-buffer-local 'erc-server-ping-handler)
+
+;;;; Helper functions
+
+;; From Circe
+(defun erc-split-line (longline)
+ "Return a list of lines which are not too long for IRC.
+The length is specified in `erc-split-line-length'.
+
+Currently this is called by `erc-send-input'."
+ (if (< (length longline)
+ erc-split-line-length)
+ (list longline)
+ (with-temp-buffer
+ (insert longline)
+ (let ((fill-column erc-split-line-length))
+ (fill-region (point-min) (point-max)
+ nil t))
+ (split-string (buffer-string) "\n"))))
+
+;; Used by CTCP functions
+(defun erc-upcase-first-word (str)
+ "Upcase the first word in STR."
+ (with-temp-buffer
+ (insert str)
+ (goto-char (point-min))
+ (upcase-word 1)
+ (buffer-string)))
+
+(defun erc-server-setup-periodical-server-ping (&rest ignore)
+ "Set up a timer to periodically ping the current server."
+ (and erc-server-ping-handler (erc-cancel-timer erc-server-ping-handler))
+ (when erc-server-send-ping-interval
+ (setq erc-server-ping-handler
+ (run-with-timer
+ 4 erc-server-send-ping-interval
+ (lambda (buf)
+ (when (buffer-live-p buf)
+ (with-current-buffer buf
+ (erc-server-send
+ (format "PING %.0f"
+ (erc-current-time))))))
+ (current-buffer)))))
+
+(defun erc-server-process-alive ()
+ "Return non-nil when `erc-server-process' is open or running."
+ (and (boundp 'erc-server-process)
+ (processp erc-server-process)
+ (memq (process-status erc-server-process) '(run open))))
+
+;;;; Connecting to a server
+
+(defun erc-server-connect (server port)
+ "Perform the connection and login.
+We will store server variables in the current buffer."
+ (let ((msg (erc-format-message 'connect ?S server ?p port)))
+ (message "%s" msg)
+ (setq erc-server-process
+ (funcall erc-server-connect-function
+ (format "erc-%s-%s" server port)
+ (current-buffer) server port))
+ (message "%s...done" msg))
+ ;; Misc server variables
+ (setq erc-server-quitting nil)
+ (setq erc-server-last-sent-time (erc-current-time))
+ (setq erc-server-last-ping-time (erc-current-time))
+ (setq erc-server-lines-sent 0)
+ ;; last peers (sender and receiver)
+ (setq erc-server-last-peers '(nil . nil))
+ ;; process handlers
+ (set-process-sentinel erc-server-process 'erc-process-sentinel)
+ (set-process-filter erc-server-process 'erc-server-filter-function)
+ ;; we do our own encoding and decoding
+ (when (fboundp 'set-process-coding-system)
+ (set-process-coding-system erc-server-process 'raw-text))
+ (set-marker (process-mark erc-server-process) (point))
+ (erc-log "\n\n\n********************************************\n")
+ (message (erc-format-message 'login ?n (erc-current-nick)))
+ ;; wait with script loading until we receive a confirmation (first
+ ;; MOTD line)
+ (if (eq erc-server-connect-function 'open-network-stream-nowait)
+ ;; it's a bit unclear otherwise that it's attempting to establish a
+ ;; connection
+ (erc-display-message nil nil (current-buffer)
+ "Opening connection..\n")
+ (erc-login)))
+
+(defun erc-server-filter-function (process string)
+ "The process filter for the ERC server."
+ (with-current-buffer (process-buffer process)
+ ;; If you think this is written in a weird way - please refer to the
+ ;; docstring of `erc-server-processing-p'
+ (if erc-server-processing-p
+ (setq erc-server-filter-data
+ (if erc-server-filter-data
+ (concat erc-server-filter-data string)
+ string))
+ ;; This will be true even if another process is spawned!
+ (let ((erc-server-processing-p t))
+ (setq erc-server-filter-data (if erc-server-filter-data
+ (concat erc-server-filter-data
+ string)
+ string))
+ (while (and erc-server-filter-data
+ (string-match "[\n\r]+" erc-server-filter-data))
+ (let ((line (substring erc-server-filter-data
+ 0 (match-beginning 0))))
+ (setq erc-server-filter-data
+ (if (= (match-end 0)
+ (length erc-server-filter-data))
+ nil
+ (substring erc-server-filter-data
+ (match-end 0))))
+ (erc-parse-server-response process line)))))))
+
+(defun erc-process-sentinel-1 (event)
+ "This will be called when erc-process-sentinel has decided that we
+are going to quit. Determine whether user has quit or whether erc has
+been terminated. Conditionally try to reconnect and take appropriate
+action."
+ (if erc-server-quitting
+ ;; normal quit
+ (progn
+ (let ((string "\n\n*** ERC finished ***\n")
+ (inhibit-read-only t))
+ (erc-put-text-property 0 (length string)
+ 'face 'erc-error-face string)
+ (insert string))
+ (when erc-kill-server-buffer-on-quit
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer))))
+ ;; unexpected disconnect
+ (erc-display-message nil 'error (current-buffer)
+ (if erc-server-auto-reconnect
+ 'disconnected
+ 'disconnected-noreconnect))
+ (erc-update-mode-line)
+ (erc-set-active-buffer (current-buffer))
+ (setq erc-server-last-sent-time 0)
+ (setq erc-server-lines-sent 0)
+ (if (and erc-server-auto-reconnect
+ (not (string-match "^deleted" event))
+ ;; open-network-stream-nowait error for connection refused
+ (not (string-match "^failed with code 111" event)))
+ ;; Yuck, this should perhaps funcall
+ ;; erc-server-reconnect-function with no args
+ (erc erc-session-server erc-session-port erc-server-current-nick
+ erc-session-user-full-name t erc-session-password)
+ ;; terminate, do not reconnect
+ (let ((string (concat "\n\n*** ERC terminated: " event
+ "\n"))
+ (inhibit-read-only t))
+ (erc-put-text-property 0 (length string)
+ 'face 'erc-error-face string)
+ (insert string)))))
+
+(defun erc-process-sentinel (cproc event)
+ "Sentinel function for ERC process."
+ (with-current-buffer (process-buffer cproc)
+ (erc-log (format
+ "SENTINEL: proc: %S status: %S event: %S (quitting: %S)"
+ cproc (process-status cproc) event erc-server-quitting))
+ (if (string-match "^open" event)
+ ;; newly opened connection (no wait)
+ (erc-login)
+ ;; assume event is 'failed
+ (let ((buf (process-buffer cproc)))
+ (erc-with-all-buffers-of-server cproc nil
+ (setq erc-server-connected nil))
+ (when erc-server-ping-handler
+ (progn (erc-cancel-timer erc-server-ping-handler)
+ (setq erc-server-ping-handler nil)))
+ (run-hook-with-args 'erc-disconnected-hook
+ (erc-current-nick) (system-name) "")
+ ;; Remove the prompt
+ (forward-line 0)
+ (erc-remove-text-properties-region (point) (point-max))
+ (delete-region (point) (point-max))
+ ;; Decide what to do with the buffer
+ ;; Restart if disconnected
+ (erc-process-sentinel-1 event)
+ ;; Make sure we don't write to the buffer if it has been
+ ;; killed
+ (when (buffer-live-p buf)
+ (erc-update-mode-line)
+ (set-buffer-modified-p nil))))))
+
+;;;; Sending messages
+
+(defun erc-coding-system-for-target (target)
+ "Return the coding system or cons cell appropriate for TARGET.
+This is determined via `erc-encoding-coding-alist' or
+`erc-server-coding-system'."
+ (or (cdr (assoc target erc-encoding-coding-alist))
+ (and (functionp erc-server-coding-system)
+ (funcall erc-server-coding-system))
+ erc-server-coding-system))
+
+(defun erc-decode-string-from-target (str target)
+ "Decode STR as appropriate for TARGET.
+This is indicated by `erc-encoding-coding-alist', defaulting to the value of
+`erc-server-coding-system'."
+ (unless (stringp str)
+ (setq str ""))
+ (let ((coding (erc-coding-system-for-target target)))
+ (when (consp coding)
+ (setq coding (cdr coding)))
+ (erc-decode-coding-string str coding)))
+
+;; proposed name, not used by anything yet
+(defun erc-send-line (text display-fn)
+ "Send TEXT to the current server. Wrapping and flood control apply.
+Use DISPLAY-FN to show the results."
+ (mapc (lambda (line)
+ (erc-server-send line)
+ (funcall display-fn))
+ (erc-split-line text)))
+
+;; From Circe, with modifications
+(defun erc-server-send (string &optional forcep target)
+ "Send STRING to the current server.
+If FORCEP is non-nil, no flood protection is done - the string is
+sent directly. This might cause the messages to arrive in a wrong
+order.
+
+If TARGET is specified, look up encoding information for that
+channel in `erc-encoding-coding-alist' or
+`erc-server-coding-system'.
+
+See `erc-server-flood-margin' for an explanation of the flood
+protection algorithm."
+ (erc-log (concat "erc-server-send: " string "(" (buffer-name) ")"))
+ (setq erc-server-last-sent-time (erc-current-time))
+ (let ((buf (erc-server-buffer))
+ (encoding (erc-coding-system-for-target
+ (or target (erc-default-target)))))
+ (when (consp encoding)
+ (setq encoding (car encoding)))
+ (if (and buf
+ (erc-server-process-alive))
+ (with-current-buffer buf
+ (let ((str (concat string "\r\n")))
+ (if forcep
+ (progn
+ (setq erc-server-flood-last-message
+ (+ erc-server-flood-penalty
+ erc-server-flood-last-message))
+ (erc-log-irc-protocol str 'outbound)
+ (condition-case err
+ (progn
+ ;; Set encoding just before sending the string
+ (when (fboundp 'set-process-coding-system)
+ (set-process-coding-system erc-server-process
+ 'raw-text encoding))
+ (process-send-string erc-server-process str))
+ ;; See `erc-server-send-queue' for full
+ ;; explanation of why we need this condition-case
+ (error nil)))
+ (setq erc-server-flood-queue
+ (append erc-server-flood-queue
+ (list (cons str encoding))))
+ (erc-server-send-queue (current-buffer))))
+ t)
+ (message "ERC: No process running")
+ nil)))
+
+;; From Circe
+(defun erc-server-send-queue (buffer)
+ "Send messages in `erc-server-flood-queue'.
+See `erc-server-flood-margin' for an explanation of the flood
+protection algorithm."
+ (with-current-buffer buffer
+ (let ((now (erc-current-time)))
+ (when erc-server-flood-timer
+ (erc-cancel-timer erc-server-flood-timer)
+ (setq erc-server-flood-timer nil))
+ (when (< erc-server-flood-last-message
+ now)
+ (setq erc-server-flood-last-message now))
+ (while (and erc-server-flood-queue
+ (< erc-server-flood-last-message
+ (+ now erc-server-flood-margin)))
+ (let ((msg (caar erc-server-flood-queue))
+ (encoding (cdar erc-server-flood-queue)))
+ (setq erc-server-flood-queue (cdr erc-server-flood-queue)
+ erc-server-flood-last-message
+ (+ erc-server-flood-last-message
+ erc-server-flood-penalty))
+ (erc-log-irc-protocol msg 'outbound)
+ (erc-log (concat "erc-server-send-queue: "
+ msg "(" (buffer-name buffer) ")"))
+ (when (erc-server-process-alive)
+ (condition-case err
+ ;; Set encoding just before sending the string
+ (progn
+ (when (fboundp 'set-process-coding-system)
+ (set-process-coding-system erc-server-process
+ 'raw-text encoding))
+ (process-send-string erc-server-process msg))
+ ;; Sometimes the send can occur while the process is
+ ;; being killed, which results in a weird SIGPIPE error.
+ ;; Catch this and ignore it.
+ (error nil)))))
+ (when erc-server-flood-queue
+ (setq erc-server-flood-timer
+ (run-at-time 2 nil #'erc-server-send-queue buffer))))))
+
+(defun erc-message (message-command line &optional force)
+ "Send LINE to the server as a privmsg or a notice.
+MESSAGE-COMMAND should be either \"PRIVMSG\" or \"NOTICE\".
+If the target is \",\", the last person you've got a message from will
+be used. If the target is \".\", the last person you've sent a message
+to will be used."
+ (cond
+ ((string-match "^\\s-*\\(\\S-+\\) ?\\(.*\\)" line)
+ (let ((tgt (match-string 1 line))
+ (s (match-string 2 line)))
+ (erc-log (format "cmd: MSG(%s): [%s] %s" message-command tgt s))
+ (cond
+ ((string= tgt ",")
+ (if (car erc-server-last-peers)
+ (setq tgt (car erc-server-last-peers))
+ (setq tgt nil)))
+ ((string= tgt ".")
+ (if (cdr erc-server-last-peers)
+ (setq tgt (cdr erc-server-last-peers))
+ (setq tgt nil))))
+ (cond
+ (tgt
+ (setcdr erc-server-last-peers tgt)
+ (erc-server-send (format "%s %s :%s" message-command tgt s)
+ force))
+ (t
+ (erc-display-message nil 'error (current-buffer) 'no-target))))
+ t)
+ (t nil)))
+
+;;; CTCP
+
+(defun erc-send-ctcp-message (tgt l &optional force)
+ "Send CTCP message L to TGT.
+
+If TGT is nil the message is not sent.
+The command must contain neither a prefix nor a trailing `\\n'.
+
+See also `erc-server-send'."
+ (let ((l (erc-upcase-first-word l)))
+ (cond
+ (tgt
+ (erc-log (format "erc-send-CTCP-message: [%s] %s" tgt l))
+ (erc-server-send (format "PRIVMSG %s :\C-a%s\C-a" tgt l)
+ force)))))
+
+(defun erc-send-ctcp-notice (tgt l &optional force)
+ "Send CTCP notice L to TGT.
+
+If TGT is nil the message is not sent.
+The command must contain neither a prefix nor a trailing `\\n'.
+
+See also `erc-server-send'."
+ (let ((l (erc-upcase-first-word l)))
+ (cond
+ (tgt
+ (erc-log (format "erc-send-CTCP-notice: [%s] %s" tgt l))
+ (erc-server-send (format "NOTICE %s :\C-a%s\C-a" tgt l)
+ force)))))
+
+;;;; Handling responses
+
+(defun erc-parse-server-response (proc string)
+ "Parse and act upon a complete line from an IRC server.
+PROC is the process (connection) from which STRING was received.
+PROCs `process-buffer' is `current-buffer' when this function is called."
+ (unless (string= string "") ;; Ignore empty strings
+ (save-match-data
+ (let ((posn (if (eq (aref string 0) ?:)
+ (string-match " " string)
+ 0))
+ (msg (make-erc-response :unparsed string)))
+
+ (setf (erc-response.sender msg)
+ (if (eq posn 0)
+ erc-session-server
+ (substring string 1 posn)))
+
+ (setf (erc-response.command msg)
+ (let* ((bposn (string-match "[^ ]" string posn))
+ (eposn (string-match " " string bposn)))
+ (setq posn (and eposn
+ (string-match "[^ ]" string eposn)))
+ (substring string bposn eposn)))
+
+ (while (and posn
+ (not (eq (aref string posn) ?:)))
+ (push (let* ((bposn posn)
+ (eposn (string-match " " string bposn)))
+ (setq posn (and eposn
+ (string-match "[^ ]" string eposn)))
+ (substring string bposn eposn))
+ (erc-response.command-args msg)))
+ (when posn
+ (let ((str (substring string (1+ posn))))
+ (push str (erc-response.command-args msg))))
+
+ (setf (erc-response.contents msg)
+ (first (erc-response.command-args msg)))
+
+ (setf (erc-response.command-args msg)
+ (nreverse (erc-response.command-args msg)))
+
+ (erc-decode-parsed-server-response msg)
+
+ (erc-handle-parsed-server-response proc msg)))))
+
+(defun erc-decode-parsed-server-response (parsed-response)
+ "Decode a pre-parsed PARSED-RESPONSE before it can be handled.
+
+If there is a channel name in `erc-response.command-args', decode
+`erc-response' according to this channel name and
+`erc-encoding-coding-alist', or use `erc-server-coding-system'
+for decoding."
+ (let ((args (erc-response.command-args parsed-response))
+ (decode-target nil)
+ (decoded-args ()))
+ (dolist (arg args nil)
+ (when (string-match "^[#&].*" arg)
+ (setq decode-target arg)))
+ (when (stringp decode-target)
+ (setq decode-target (erc-decode-string-from-target decode-target nil)))
+ (setf (erc-response.unparsed parsed-response)
+ (erc-decode-string-from-target
+ (erc-response.unparsed parsed-response)
+ decode-target))
+ (setf (erc-response.sender parsed-response)
+ (erc-decode-string-from-target
+ (erc-response.sender parsed-response)
+ decode-target))
+ (setf (erc-response.command parsed-response)
+ (erc-decode-string-from-target
+ (erc-response.command parsed-response)
+ decode-target))
+ (dolist (arg (nreverse args) nil)
+ (push (erc-decode-string-from-target arg decode-target)
+ decoded-args))
+ (setf (erc-response.command-args parsed-response) decoded-args)
+ (setf (erc-response.contents parsed-response)
+ (erc-decode-string-from-target
+ (erc-response.contents parsed-response)
+ decode-target))))
+
+(defun erc-handle-parsed-server-response (process parsed-response)
+ "Handle a pre-parsed PARSED-RESPONSE from PROCESS.
+
+Hands off to helper functions via `erc-call-hooks'."
+ (if (member (erc-response.command parsed-response)
+ erc-server-prevent-duplicates)
+ (let ((m (erc-response.unparsed parsed-response)))
+ ;; duplicate supression
+ (if (< (or (gethash m erc-server-duplicates) 0)
+ (- (erc-current-time) erc-server-duplicate-timeout))
+ (erc-call-hooks process parsed-response))
+ (puthash m (erc-current-time) erc-server-duplicates))
+ ;; Hand off to the relevant handler.
+ (erc-call-hooks process parsed-response)))
+
+(defun erc-get-hook (command)
+ "Return the hook variable associated with COMMAND.
+
+See also `erc-server-responses'."
+ (gethash (format (if (numberp command) "%03i" "%s") command)
+ erc-server-responses))
+
+(defun erc-call-hooks (process message)
+ "Call hooks associated with MESSAGE in PROCESS.
+
+Finds hooks by looking in the `erc-server-responses' hashtable."
+ (let ((hook (or (erc-get-hook (erc-response.command message))
+ 'erc-default-server-functions)))
+ (run-hook-with-args-until-success hook process message)
+ (with-current-buffer (erc-server-buffer)
+ (run-hook-with-args 'erc-timer-hook (erc-current-time)))))
+
+(add-hook 'erc-default-server-functions 'erc-handle-unknown-server-response)
+
+(defun erc-handle-unknown-server-response (proc parsed)
+ "Display unknown server response's message."
+ (let ((line (concat (erc-response.sender parsed)
+ " "
+ (erc-response.command parsed)
+ " "
+ (mapconcat 'identity (erc-response.command-args parsed)
+ " "))))
+ (erc-display-message parsed 'notice proc line)))
+
+
+(put 'define-erc-response-handler 'edebug-form-spec
+ '(&define :name erc-response-handler
+ (name &rest name)
+ &optional sexp sexp def-body))
+
+(defmacro* define-erc-response-handler ((name &rest aliases)
+ &optional extra-fn-doc extra-var-doc
+ &rest fn-body)
+ "Define an ERC handler hook/function pair.
+NAME is the response name as sent by the server (see the IRC RFC for
+meanings).
+
+This creates:
+ - a hook variable `erc-server-NAME-functions' initialised to `erc-server-NAME'.
+ - a function `erc-server-NAME' with body FN-BODY.
+
+If ALIASES is non-nil, each alias in ALIASES is `defalias'ed to
+`erc-server-NAME'.
+Alias hook variables are created as `erc-server-ALIAS-functions' and
+initialised to the same default value as `erc-server-NAME-functions'.
+
+FN-BODY is the body of `erc-server-NAME' it may refer to the two
+function arguments PROC and PARSED.
+
+If EXTRA-FN-DOC is non-nil, it is inserted at the beginning of the
+defined function's docstring.
+
+If EXTRA-VAR-DOC is non-nil, it is inserted at the beginning of the
+defined variable's docstring.
+
+As an example:
+
+ (define-erc-response-handler (311 WHOIS WI)
+ \"Some non-generic function documentation.\"
+ \"Some non-generic variable documentation.\"
+ (do-stuff-with-whois proc parsed))
+
+Would expand to:
+
+ (prog2
+ (defvar erc-server-311-functions 'erc-server-311
+ \"Some non-generic variable documentation.
+
+ Hook called upon receiving a 311 server response.
+ Each function is called with two arguments, the process associated
+ with the response and the parsed response.
+ See also `erc-server-311'.\")
+
+ (defun erc-server-311 (proc parsed)
+ \"Some non-generic function documentation.
+
+ Handler for a 311 server response.
+ PROC is the server process which returned the response.
+ PARSED is the actual response as an `erc-response' struct.
+ If you want to add responses don't modify this function, but rather
+ add things to `erc-server-311-functions' instead.\"
+ (do-stuff-with-whois proc parsed))
+
+ (puthash \"311\" 'erc-server-311-functions erc-server-responses)
+ (puthash \"WHOIS\" 'erc-server-WHOIS-functions erc-server-responses)
+ (puthash \"WI\" 'erc-server-WI-functions erc-server-responses)
+
+ (defalias 'erc-server-WHOIS 'erc-server-311)
+ (defvar erc-server-WHOIS-functions 'erc-server-311
+ \"Some non-generic variable documentation.
+
+ Hook called upon receiving a WHOIS server response.
+ Each function is called with two arguments, the process associated
+ with the response and the parsed response.
+ See also `erc-server-311'.\")
+
+ (defalias 'erc-server-WI 'erc-server-311)
+ (defvar erc-server-WI-functions 'erc-server-311
+ \"Some non-generic variable documentation.
+
+ Hook called upon receiving a WI server response.
+ Each function is called with two arguments, the process associated
+ with the response and the parsed response.
+ See also `erc-server-311'.\"))
+
+\(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)"
+ (if (numberp name) (setq name (intern (format "%03i" name))))
+ (setq aliases (mapcar (lambda (a)
+ (if (numberp a)
+ (format "%03i" a)
+ a))
+ aliases))
+ (let* ((hook-name (intern (format "erc-server-%s-functions" name)))
+ (fn-name (intern (format "erc-server-%s" name)))
+ (hook-doc (format "%sHook called upon receiving a %%s server response.
+Each function is called with two arguments, the process associated
+with the response and the parsed response.
+See also `%s'."
+ (if extra-var-doc
+ (concat extra-var-doc "\n\n")
+ "")
+ fn-name))
+ (fn-doc (format "%sHandler for a %s server response.
+PROC is the server process which returned the response.
+PARSED is the actual response as an `erc-response' struct.
+If you want to add responses don't modify this function, but rather
+add things to `%s' instead."
+ (if extra-fn-doc
+ (concat extra-fn-doc "\n\n")
+ "")
+ name hook-name))
+ (fn-alternates
+ (loop for alias in aliases
+ collect (intern (format "erc-server-%s" alias))))
+ (var-alternates
+ (loop for alias in aliases
+ collect (intern (format "erc-server-%s-functions" alias)))))
+ `(prog2
+ ;; Normal hook variable.
+ (defvar ,hook-name ',fn-name ,(format hook-doc name))
+ ;; Handler function
+ (defun ,fn-name (proc parsed)
+ ,fn-doc
+ ,@fn-body)
+
+ ;; Make find-function and find-variable find them
+ (put ',fn-name 'definition-name ',name)
+ (put ',hook-name 'definition-name ',name)
+
+ ;; Hashtable map of responses to hook variables
+ ,@(loop for response in (cons name aliases)
+ for var in (cons hook-name var-alternates)
+ collect `(puthash ,(format "%s" response) ',var
+ erc-server-responses))
+ ;; Alternates.
+ ;; Functions are defaliased, hook variables are defvared so we
+ ;; can add hooks to one alias, but not another.
+ ,@(loop for fn in fn-alternates
+ for var in var-alternates
+ for a in aliases
+ nconc (list `(defalias ',fn ',fn-name)
+ `(defvar ,var ',fn-name ,(format hook-doc a))
+ `(put ',var 'definition-name ',hook-name))))))
+
+(define-erc-response-handler (ERROR)
+ "Handle an ERROR command from the server." nil
+ (erc-display-message
+ parsed 'error nil 'ERROR
+ ?s (erc-response.sender parsed) ?c (erc-response.contents parsed)))
+
+(define-erc-response-handler (INVITE)
+ "Handle invitation messages."
+ nil
+ (let ((target (first (erc-response.command-args parsed)))
+ (chnl (erc-response.contents parsed)))
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ (setq erc-invitation chnl)
+ (when (string= target (erc-current-nick))
+ (erc-display-message
+ parsed 'notice 'active
+ 'INVITE ?n nick ?u login ?h host ?c chnl)))))
+
+
+(define-erc-response-handler (JOIN)
+ "Handle join messages."
+ nil
+ (let ((chnl (erc-response.contents parsed))
+ (buffer nil))
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ ;; strip the stupid combined JOIN facility (IRC 2.9)
+ (if (string-match "^\\(.*\\)?\^g.*$" chnl)
+ (setq chnl (match-string 1 chnl)))
+ (save-excursion
+ (let* ((str (cond
+ ;; If I have joined a channel
+ ((erc-current-nick-p nick)
+ (setq buffer (erc erc-session-server erc-session-port
+ nick erc-session-user-full-name
+ nil nil
+ erc-default-recipients chnl
+ erc-server-process))
+ (when buffer
+ (set-buffer buffer)
+ (erc-add-default-channel chnl)
+ (erc-server-send (format "MODE %s" chnl)))
+ (erc-with-buffer (chnl proc)
+ (erc-channel-begin-receiving-names))
+ (erc-update-mode-line)
+ (run-hooks 'erc-join-hook)
+ (erc-make-notice
+ (erc-format-message 'JOIN-you ?c chnl)))
+ (t
+ (setq buffer (erc-get-buffer chnl proc))
+ (erc-make-notice
+ (erc-format-message
+ 'JOIN ?n nick ?u login ?h host ?c chnl))))))
+ (when buffer (set-buffer buffer))
+ (erc-update-channel-member chnl nick nick t nil nil host login)
+ ;; on join, we want to stay in the new channel buffer
+ ;;(set-buffer ob)
+ (erc-display-message parsed nil buffer str))))))
+
+(define-erc-response-handler (KICK)
+ "Handle kick messages received from the server." nil
+ (let* ((ch (first (erc-response.command-args parsed)))
+ (tgt (second (erc-response.command-args parsed)))
+ (reason (erc-trim-string (erc-response.contents parsed)))
+ (buffer (erc-get-buffer ch proc)))
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ (erc-remove-channel-member buffer tgt)
+ (cond
+ ((string= tgt (erc-current-nick))
+ (erc-display-message
+ parsed 'notice buffer
+ 'KICK-you ?n nick ?u login ?h host ?c ch ?r reason)
+ (run-hook-with-args 'erc-kick-hook buffer)
+ (erc-with-buffer
+ (buffer)
+ (erc-remove-channel-users))
+ (erc-delete-default-channel ch buffer)
+ (erc-update-mode-line buffer))
+ ((string= nick (erc-current-nick))
+ (erc-display-message
+ parsed 'notice buffer
+ 'KICK-by-you ?k tgt ?c ch ?r reason))
+ (t (erc-display-message
+ parsed 'notice buffer
+ 'KICK ?k tgt ?n nick ?u login ?h host ?c ch ?r reason))))))
+
+(define-erc-response-handler (MODE)
+ "Handle server mode changes." nil
+ (let ((tgt (first (erc-response.command-args parsed)))
+ (mode (mapconcat 'identity (cdr (erc-response.command-args parsed))
+ " ")))
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ (erc-log (format "MODE: %s -> %s: %s" nick tgt mode))
+ ;; dirty hack
+ (let ((buf (cond ((erc-channel-p tgt)
+ (erc-get-buffer tgt proc))
+ ((string= tgt (erc-current-nick)) nil)
+ ((erc-active-buffer) (erc-active-buffer))
+ (t (erc-get-buffer tgt)))))
+ (with-current-buffer (or buf
+ (current-buffer))
+ (erc-update-modes tgt mode nick host login))
+ (if (or (string= login "") (string= host ""))
+ (erc-display-message parsed 'notice buf
+ 'MODE-nick ?n nick
+ ?t tgt ?m mode)
+ (erc-display-message parsed 'notice buf
+ 'MODE ?n nick ?u login
+ ?h host ?t tgt ?m mode)))
+ (erc-banlist-update proc parsed))))
+
+(define-erc-response-handler (NICK)
+ "Handle nick change messages." nil
+ (let ((nn (erc-response.contents parsed))
+ bufs)
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ (setq bufs (erc-buffer-list-with-nick nick proc))
+ (erc-log (format "NICK: %s -> %s" nick nn))
+ ;; if we had a query with this user, make sure future messages will be
+ ;; sent to the correct nick. also add to bufs, since the user will want
+ ;; to see the nick change in the query, and if it's a newly begun query,
+ ;; erc-channel-users won't contain it
+ (erc-buffer-filter
+ (lambda ()
+ (when (equal (erc-default-target) nick)
+ (setq erc-default-recipients
+ (cons nn (cdr erc-default-recipients)))
+ (rename-buffer nn)
+ (erc-update-mode-line)
+ (add-to-list 'bufs (current-buffer)))))
+ (erc-update-user-nick nick nn host nil nil login)
+ (cond
+ ((string= nick (erc-current-nick))
+ (add-to-list 'bufs (erc-server-buffer))
+ (erc-set-current-nick nn)
+ (erc-update-mode-line)
+ (setq erc-nick-change-attempt-count 0)
+ (setq erc-default-nicks (if (consp erc-nick) erc-nick (list erc-nick)))
+ (erc-display-message
+ parsed 'notice bufs
+ 'NICK-you ?n nick ?N nn)
+ (run-hook-with-args 'erc-nick-changed-functions nn nick))
+ (t
+ (erc-handle-user-status-change 'nick (list nick login host) (list nn))
+ (erc-display-message parsed 'notice bufs 'NICK ?n nick
+ ?u login ?h host ?N nn))))))
+
+(define-erc-response-handler (PART)
+ "Handle part messages." nil
+ (let* ((chnl (first (erc-response.command-args parsed)))
+ (reason (erc-trim-string (erc-response.contents parsed)))
+ (buffer (erc-get-buffer chnl proc)))
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ (erc-remove-channel-member buffer nick)
+ (erc-display-message parsed 'notice buffer
+ 'PART ?n nick ?u login
+ ?h host ?c chnl ?r (or reason ""))
+ (when (string= nick (erc-current-nick))
+ (run-hook-with-args 'erc-part-hook buffer)
+ (erc-with-buffer
+ (buffer)
+ (erc-remove-channel-users))
+ (erc-delete-default-channel chnl buffer)
+ (erc-update-mode-line buffer)
+ (when erc-kill-buffer-on-part
+ (kill-buffer buffer))))))
+
+(define-erc-response-handler (PING)
+ "Handle ping messages." nil
+ (let ((pinger (first (erc-response.command-args parsed))))
+ (erc-log (format "PING: %s" pinger))
+ ;; ping response to the server MUST be forced, or you can lose big
+ (erc-server-send (format "PONG :%s" pinger) t)
+ (when erc-verbose-server-ping
+ (erc-display-message
+ parsed 'error proc
+ 'PING ?s (erc-time-diff erc-server-last-ping-time (erc-current-time))))
+ (setq erc-server-last-ping-time (erc-current-time))))
+
+(define-erc-response-handler (PONG)
+ "Handle pong messages." nil
+ (let ((time (string-to-number (erc-response.contents parsed))))
+ (when (> time 0)
+ (setq erc-server-lag (erc-time-diff time (erc-current-time)))
+ (when erc-verbose-server-ping
+ (erc-display-message
+ parsed 'notice proc 'PONG
+ ?h (first (erc-response.command-args parsed)) ?i erc-server-lag
+ ?s (if (/= erc-server-lag 1) "s" "")))
+ (erc-update-mode-line))))
+
+(define-erc-response-handler (PRIVMSG NOTICE)
+ nil nil
+ (let ((sender-spec (erc-response.sender parsed))
+ (cmd (erc-response.command parsed))
+ (tgt (car (erc-response.command-args parsed)))
+ (msg (erc-response.contents parsed)))
+ (if (or (erc-ignored-user-p sender-spec)
+ (erc-ignored-reply-p msg tgt proc))
+ (when erc-minibuffer-ignored
+ (message "Ignored %s from %s to %s" cmd sender-spec tgt))
+ (let* ((sndr (erc-parse-user sender-spec))
+ (nick (nth 0 sndr))
+ (login (nth 1 sndr))
+ (host (nth 2 sndr))
+ (msgp (string= cmd "PRIVMSG"))
+ (noticep (string= cmd "NOTICE"))
+ ;; S.B. downcase *both* tgt and current nick
+ (privp (erc-current-nick-p tgt))
+ s buffer
+ fnick)
+ (setf (erc-response.contents parsed) msg)
+ (setq buffer (erc-get-buffer (if privp nick tgt) proc))
+ (when buffer
+ (with-current-buffer buffer
+ ;; update the chat partner info. Add to the list if private
+ ;; message. We will accumulate private identities indefinitely
+ ;; at this point.
+ (erc-update-channel-member (if privp nick tgt) nick nick
+ privp nil nil host login nil nil t)
+ (let ((cdata (erc-get-channel-user nick)))
+ (setq fnick (funcall erc-format-nick-function
+ (car cdata) (cdr cdata))))))
+ (cond
+ ((erc-is-message-ctcp-p msg)
+ (setq s (if msgp
+ (erc-process-ctcp-query proc parsed nick login host)
+ (erc-process-ctcp-reply proc parsed nick login host
+ (match-string 1 msg)))))
+ (t
+ (setcar erc-server-last-peers nick)
+ (setq s (erc-format-privmessage
+ (or fnick nick) msg
+ ;; If buffer is a query buffer,
+ ;; format the nick as for a channel.
+ (and (not (and buffer
+ (erc-query-buffer-p buffer)
+ erc-format-query-as-channel-p))
+ privp)
+ msgp))))
+ (when s
+ (if (and noticep privp)
+ (progn
+ (run-hook-with-args 'erc-echo-notice-always-hook
+ s parsed buffer nick)
+ (run-hook-with-args-until-success
+ 'erc-echo-notice-hook s parsed buffer nick))
+ (erc-display-message parsed nil buffer s)))
+ (when (string= cmd "PRIVMSG")
+ (erc-auto-query proc parsed))))))
+
+;; FIXME: need clean way of specifiying extra hooks in
+;; define-erc-response-handler.
+(add-hook 'erc-server-PRIVMSG-functions 'erc-auto-query)
+
+(define-erc-response-handler (QUIT)
+ nil nil
+ (let ((reason (erc-response.contents parsed))
+ bufs)
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ (setq bufs (erc-buffer-list-with-nick nick proc))
+ (erc-remove-user nick)
+ (setq reason (erc-wash-quit-reason reason nick login host))
+ (erc-display-message parsed 'notice bufs
+ 'QUIT ?n nick ?u login
+ ?h host ?r reason))))
+
+(define-erc-response-handler (TOPIC)
+ nil nil
+ (let* ((ch (first (erc-response.command-args parsed)))
+ (topic (erc-trim-string (erc-response.contents parsed)))
+ (time (format-time-string "%T %m/%d/%y" (current-time))))
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ (erc-update-channel-member ch nick nick nil nil nil host login)
+ (erc-update-channel-topic ch (format "%s\C-o (%s, %s)" topic nick time))
+ (erc-display-message parsed 'notice (erc-get-buffer ch proc)
+ 'TOPIC ?n nick ?u login ?h host
+ ?c ch ?T topic))))
+
+(define-erc-response-handler (WALLOPS)
+ nil nil
+ (let ((message (erc-response.contents parsed)))
+ (multiple-value-bind (nick login host)
+ (erc-parse-user (erc-response.sender parsed))
+ (erc-display-message
+ parsed 'notice nil
+ 'WALLOPS ?n nick ?m message))))
+
+(define-erc-response-handler (001)
+ "Set `erc-server-current-nick' to reflect server settings and display the welcome message."
+ nil
+ (erc-set-current-nick (first (erc-response.command-args parsed)))
+ (erc-update-mode-line) ; needed here?
+ (setq erc-nick-change-attempt-count 0)
+ (setq erc-default-nicks (if (consp erc-nick) erc-nick (list erc-nick)))
+ (erc-display-message
+ parsed 'notice 'active (erc-response.contents parsed)))
+
+(define-erc-response-handler (MOTD 002 003 371 372 374 375)
+ "Display the server's message of the day." nil
+ (erc-handle-login)
+ (erc-display-message
+ parsed 'notice (if erc-server-connected 'active proc)
+ (erc-response.contents parsed)))
+
+(define-erc-response-handler (376 422)
+ nil nil
+ (erc-server-MOTD proc parsed)
+ (erc-connection-established proc parsed))
+
+(define-erc-response-handler (004)
+ nil nil
+ (multiple-value-bind (server-name server-version)
+ (cdr (erc-response.command-args parsed))
+ (setq erc-server-version server-version)
+ (setq erc-server-announced-name server-name)
+ (erc-update-mode-line-buffer (process-buffer proc))
+ (erc-display-message
+ parsed 'notice proc
+ 's004 ?s server-name ?v server-version
+ ?U (fourth (erc-response.command-args parsed))
+ ?C (fifth (erc-response.command-args parsed)))))
+
+(define-erc-response-handler (005)
+ "Set the variable `erc-server-parameters' and display the received message.
+
+According to RFC 2812, suggests alternate servers on the network.
+Many servers, however, use this code to show which parameters they have set,
+for example, the network identifier, maximum allowed topic length, whether
+certain commands are accepted and more. See documentation for
+`erc-server-parameters' for more information on the parameters sent.
+
+A server may send more than one 005 message."
+ nil
+ (let ((line (mapconcat 'identity
+ (setf (erc-response.command-args parsed)
+ (cdr (erc-response.command-args parsed)))
+ " ")))
+ (while (erc-response.command-args parsed)
+ (let ((section (pop (erc-response.command-args parsed))))
+ ;; fill erc-server-parameters
+ (when (string-match "^\\([A-Z]+\\)\=\\(.*\\)$\\|^\\([A-Z]+\\)$"
+ section)
+ (add-to-list 'erc-server-parameters
+ `(,(or (match-string 1 section)
+ (match-string 3 section))
+ .
+ ,(match-string 2 section))))))
+ (erc-display-message parsed 'notice proc line)))
+
+(define-erc-response-handler (221)
+ nil nil
+ (let* ((nick (first (erc-response.command-args parsed)))
+ (modes (mapconcat 'identity
+ (cdr (erc-response.command-args parsed)) " ")))
+ (erc-set-modes nick modes)
+ (erc-display-message parsed 'notice 'active 's221 ?n nick ?m modes)))
+
+(define-erc-response-handler (252)
+ "Display the number of IRC operators online." nil
+ (erc-display-message parsed 'notice 'active 's252
+ ?i (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (253)
+ "Display the number of unknown connections." nil
+ (erc-display-message parsed 'notice 'active 's253
+ ?i (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (254)
+ "Display the number of channels formed." nil
+ (erc-display-message parsed 'notice 'active 's254
+ ?i (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (250 251 255 256 257 258 259 265 266 377 378)
+ "Generic display of server messages as notices.
+
+See `erc-display-server-message'." nil
+ (erc-display-server-message proc parsed))
+
+(define-erc-response-handler (301)
+ "AWAY notice." nil
+ (erc-display-message parsed 'notice 'active 's301
+ ?n (second (erc-response.command-args parsed))
+ ?r (erc-response.contents parsed)))
+
+(define-erc-response-handler (303)
+ "ISON reply" nil
+ (erc-display-message parsed 'notice 'active 's303
+ ?n (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (305)
+ "Return from AWAYness." nil
+ (erc-process-away proc nil)
+ (erc-display-message parsed 'notice 'active
+ 's305 ?m (erc-response.contents parsed)))
+
+(define-erc-response-handler (306)
+ "Set AWAYness." nil
+ (erc-process-away proc t)
+ (erc-display-message parsed 'notice 'active
+ 's306 ?m (erc-response.contents parsed)))
+
+(define-erc-response-handler (311 314)
+ "WHOIS/WHOWAS notices." nil
+ (let ((fname (erc-response.contents parsed))
+ (catalog-entry (intern (format "s%s" (erc-response.command parsed)))))
+ (multiple-value-bind (nick user host)
+ (cdr (erc-response.command-args parsed))
+ (erc-update-user-nick nick nick host nil fname user)
+ (erc-display-message
+ parsed 'notice 'active catalog-entry
+ ?n nick ?f fname ?u user ?h host))))
+
+(define-erc-response-handler (312)
+ nil nil
+ (multiple-value-bind (nick server-host)
+ (cdr (erc-response.command-args parsed))
+ (erc-display-message
+ parsed 'notice 'active 's312
+ ?n nick ?s server-host ?c (erc-response.contents parsed))))
+
+(define-erc-response-handler (313)
+ "IRC Operator response in WHOIS." nil
+ (erc-display-message
+ parsed 'notice 'active 's313
+ ?n (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (315 318 323 369)
+ ;; 315 - End of WHO
+ ;; 318 - End of WHOIS list
+ ;; 323 - End of channel LIST
+ ;; 369 - End of WHOWAS
+ nil nil
+ (ignore proc parsed))
+
+(define-erc-response-handler (317)
+ "IDLE notice." nil
+ (multiple-value-bind (nick seconds-idle on-since time)
+ (cdr (erc-response.command-args parsed))
+ (setq time (when on-since
+ (format-time-string "%T %Y/%m/%d"
+ (erc-string-to-emacs-time on-since))))
+ (erc-update-user-nick nick nick nil nil nil
+ (and time (format "on since %s" time)))
+ (if time
+ (erc-display-message
+ parsed 'notice 'active 's317-on-since
+ ?n nick ?i (erc-sec-to-time (string-to-number seconds-idle)) ?t time)
+ (erc-display-message
+ parsed 'notice 'active 's317
+ ?n nick ?i (erc-sec-to-time (string-to-number seconds-idle))))))
+
+(define-erc-response-handler (319)
+ nil nil
+ (erc-display-message
+ parsed 'notice 'active 's319
+ ?n (second (erc-response.command-args parsed))
+ ?c (erc-response.contents parsed)))
+
+(define-erc-response-handler (320)
+ "Identified user in WHOIS." nil
+ (erc-display-message
+ parsed 'notice 'active 's320
+ ?n (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (321)
+ "LIST header." nil
+ (setq erc-channel-list nil)
+ (erc-display-message parsed 'notice 'active 's321))
+
+(define-erc-response-handler (322)
+ "LIST notice." nil
+ (let ((topic (erc-response.contents parsed)))
+ (multiple-value-bind (channel num-users)
+ (cdr (erc-response.command-args parsed))
+ (add-to-list 'erc-channel-list (list channel))
+ (erc-update-channel-topic channel topic)
+ (erc-display-message
+ parsed 'notice 'active 's322
+ ?c channel ?u num-users ?t (or topic "")))))
+
+(define-erc-response-handler (324)
+ "Channel or nick modes." nil
+ (let ((channel (second (erc-response.command-args parsed)))
+ (modes (mapconcat 'identity (cddr (erc-response.command-args parsed))
+ " ")))
+ (erc-set-modes channel modes)
+ (erc-display-message
+ parsed 'notice (erc-get-buffer channel proc)
+ 's324 ?c channel ?m modes)))
+
+(define-erc-response-handler (329)
+ "Channel creation date." nil
+ (let ((channel (second (erc-response.command-args parsed)))
+ (time (erc-string-to-emacs-time
+ (third (erc-response.command-args parsed)))))
+ (erc-display-message
+ parsed 'notice (erc-get-buffer channel proc)
+ 's329 ?c channel ?t (format-time-string "%A %Y/%m/%d %X" time))))
+
+(define-erc-response-handler (330)
+ nil nil
+ ;; FIXME: I don't know what the magic numbers mean. Mummy, make
+ ;; the magic numbers go away.
+ ;; No seriously, I have no clue about the format of this command,
+ ;; and don't sit on Quakenet, so can't test. Originally we had:
+ ;; nick == (aref parsed 3)
+ ;; authaccount == (aref parsed 4)
+ ;; authmsg == (aref parsed 5)
+ ;; The guesses below are, well, just that. -- Lawrence 2004/05/10
+ (let ((nick (second (erc-response.command-args parsed)))
+ (authaccount (third (erc-response.command-args parsed)))
+ (authmsg (erc-response.contents parsed)))
+ (erc-display-message parsed 'notice 'active 's330
+ ?n nick ?a authmsg ?i authaccount)))
+
+(define-erc-response-handler (331)
+ "Channel topic." nil
+ (let ((channel (second (erc-response.command-args parsed)))
+ (topic (erc-response.contents parsed)))
+ ;; FIXME: why don't we do anything with the topic? -- Lawrence 2004/05/10
+ (erc-display-message parsed 'notice (erc-get-buffer channel proc)
+ 's331 ?c channel)))
+
+(define-erc-response-handler (332)
+ "TOPIC notice." nil
+ (let ((channel (second (erc-response.command-args parsed)))
+ (topic (erc-response.contents parsed)))
+ (erc-update-channel-topic channel topic)
+ (erc-display-message parsed 'notice (erc-get-buffer channel proc)
+ 's332 ?c channel ?T topic)))
+
+(define-erc-response-handler (333)
+ ;; Who set the topic, and when
+ nil nil
+ (multiple-value-bind (channel nick time)
+ (cdr (erc-response.command-args parsed))
+ (setq time (format-time-string "%T %Y/%m/%d"
+ (erc-string-to-emacs-time time)))
+ (erc-update-channel-topic channel
+ (format "\C-o (%s, %s)" nick time)
+ 'append)
+ (erc-display-message parsed 'notice (erc-get-buffer channel proc)
+ 's333 ?c channel ?n nick ?t time)))
+
+(define-erc-response-handler (341)
+ "Let user know when an INVITE attempt has been sent successfully."
+ nil
+ (multiple-value-bind (nick channel)
+ (cdr (erc-response.command-args parsed))
+ (erc-display-message parsed 'notice (erc-get-buffer channel proc)
+ 's341 ?n nick ?c channel)))
+
+(define-erc-response-handler (352)
+ "WHO notice." nil
+ (multiple-value-bind (channel user host server nick away-flag)
+ (cdr (erc-response.command-args parsed))
+ (let ((full-name (erc-response.contents parsed))
+ hopcount)
+ (when (string-match "\\(^[0-9]+ \\)\\(.*\\)$" full-name)
+ (setq hopcount (match-string 1 full-name))
+ (setq full-name (match-string 2 full-name)))
+ (erc-update-channel-member channel nick nick nil nil nil host
+ user full-name)
+ (erc-display-message parsed 'notice 'active 's352
+ ?c channel ?n nick ?a away-flag
+ ?u user ?h host ?f full-name))))
+
+(define-erc-response-handler (353)
+ "NAMES notice." nil
+ (let ((channel (third (erc-response.command-args parsed)))
+ (users (erc-response.contents parsed)))
+ (erc-with-buffer (channel proc)
+ (erc-channel-receive-names users))
+ (erc-display-message parsed 'notice (or (erc-get-buffer channel proc)
+ 'active)
+ 's353 ?c channel ?u users)))
+
+(define-erc-response-handler (366)
+ "End of NAMES." nil
+ (erc-with-buffer ((second (erc-response.command-args parsed)) proc)
+ (erc-channel-end-receiving-names)))
+
+(define-erc-response-handler (367)
+ "Channel ban list entries" nil
+ (multiple-value-bind (channel banmask setter time)
+ (cdr (erc-response.command-args parsed))
+ (erc-display-message parsed 'notice 'active 's367
+ ?c channel
+ ?b banmask
+ ?s setter
+ ?t time)))
+
+(define-erc-response-handler (368)
+ "End of channel ban list" nil
+ (let ((channel (second (erc-response.command-args parsed))))
+ (erc-display-message parsed 'notice 'active 's368
+ ?c channel)))
+
+(define-erc-response-handler (379)
+ "Forwarding to another channel." nil
+ ;; FIXME: Yet more magic numbers in original code, I'm guessing this
+ ;; command takes two arguments, and doesn't have any "contents". --
+ ;; Lawrence 2004/05/10
+ (multiple-value-bind (from to)
+ (cdr (erc-response.command-args parsed))
+ (erc-display-message parsed 'notice 'active
+ 's379 ?c from ?f to)))
+
+(define-erc-response-handler (391)
+ "Server's time string" nil
+ (erc-display-message
+ parsed 'notice 'active
+ 's391 ?s (second (erc-response.command-args parsed))
+ ?t (third (erc-response.command-args parsed))))
+
+(define-erc-response-handler (401)
+ "No such nick/channel." nil
+ (let ((nick/channel (second (erc-response.command-args parsed))))
+ (when erc-whowas-on-nosuchnick
+ (erc-log (format "cmd: WHOWAS: %s" nick/channel))
+ (erc-server-send (format "WHOWAS %s 1" nick/channel)))
+ (erc-display-message parsed '(notice error) 'active
+ 's401 ?n nick/channel)))
+
+(define-erc-response-handler (403)
+ "No such channel." nil
+ (erc-display-message parsed '(notice error) 'active
+ 's403 ?c (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (404)
+ "Cannot send to channel." nil
+ (erc-display-message parsed '(notice error) 'active
+ 's404 ?c (second (erc-response.command-args parsed))))
+
+
+(define-erc-response-handler (405)
+ ;; Can't join that many channels.
+ nil nil
+ (erc-display-message parsed '(notice error) 'active
+ 's405 ?c (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (406)
+ ;; No such nick
+ nil nil
+ (erc-display-message parsed '(notice error) 'active
+ 's406 ?n (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (412)
+ ;; No text to send
+ nil nil
+ (erc-display-message parsed '(notice error) 'active 's412))
+
+(define-erc-response-handler (421)
+ ;; Unknown command
+ nil nil
+ (erc-display-message parsed '(notice error) 'active 's421
+ ?c (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (432)
+ ;; Bad nick.
+ nil nil
+ (erc-display-message parsed '(notice error) 'active 's432
+ ?n (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (433)
+ ;; Login-time "nick in use"
+ nil nil
+ (erc-nickname-in-use (second (erc-response.command-args parsed))
+ "already in use"))
+
+(define-erc-response-handler (437)
+ ;; Nick temporarily unavailable (IRCnet)
+ nil nil
+ (let ((nick/channel (second (erc-response.command-args parsed))))
+ (unless (erc-channel-p nick/channel)
+ (erc-nickname-in-use nick/channel "temporarily unavailable"))))
+
+(define-erc-response-handler (442)
+ ;; Not on channel
+ nil nil
+ (erc-display-message parsed '(notice error) 'active 's442
+ ?c (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (461)
+ ;; Not enough params for command.
+ nil nil
+ (erc-display-message parsed '(notice error) 'active 's461
+ ?c (second (erc-response.command-args parsed))
+ ?m (erc-response.contents parsed)))
+
+(define-erc-response-handler (474)
+ "Banned from channel errors" nil
+ (erc-display-message parsed '(notice error) nil
+ (intern (format "s%s"
+ (erc-response.command parsed)))
+ ?c (second (erc-response.command-args parsed))))
+
+(define-erc-response-handler (475)
+ "Channel key needed." nil
+ (erc-display-message parsed '(notice error) nil 's475
+ ?c (second (erc-response.command-args parsed)))
+ (when erc-prompt-for-channel-key
+ (let ((channel (second (erc-response.command-args parsed)))
+ (key (read-from-minibuffer
+ (format "Channel %s is mode +k. Enter key (RET to cancel): "
+ (second (erc-response.command-args parsed))))))
+ (when (and key (> (length key) 0))
+ (erc-cmd-JOIN channel key)))))
+
+(define-erc-response-handler (477)
+ nil nil
+ (let ((channel (second (erc-response.command-args parsed)))
+ (message (erc-response.contents parsed)))
+ (erc-display-message parsed 'notice (erc-get-buffer channel proc)
+ (format "%s: %s" channel message))))
+
+(define-erc-response-handler (482)
+ nil nil
+ (let ((channel (second (erc-response.command-args parsed)))
+ (message (erc-response.contents parsed)))
+ (erc-display-message parsed '(error notice) 'active 's482
+ ?c channel ?m message)))
+
+(define-erc-response-handler (431 445 446 451 462 463 464 465 481 483 484 485
+ 491 501 502)
+ ;; 431 - No nickname given
+ ;; 445 - SUMMON has been disabled
+ ;; 446 - USERS has been disabled
+ ;; 451 - You have not registered
+ ;; 462 - Unauthorized command (already registered)
+ ;; 463 - Your host isn't among the privileged
+ ;; 464 - Password incorrect
+ ;; 465 - You are banned from this server
+ ;; 481 - Need IRCop privileges
+ ;; 483 - You can't kill a server!
+ ;; 484 - Your connection is restricted!
+ ;; 485 - You're not the original channel operator
+ ;; 491 - No O-lines for your host
+ ;; 501 - Unknown MODE flag
+ ;; 502 - Cannot change mode for other users
+ nil nil
+ (erc-display-error-notice
+ parsed
+ (intern (format "s%s" (erc-response.command parsed)))))
+
+;; FIXME: These are yet to be implemented, they're just stubs for now
+;; -- Lawrence 2004/05/12
+
+;; response numbers left here for reference
+
+;; (define-erc-response-handler (323 364 365 381 382 392 393 394 395
+;; 200 201 202 203 204 205 206 208 209 211 212 213
+;; 214 215 216 217 218 219 241 242 243 244 249 261
+;; 262 302 342 351 402 407 409 411 413 414 415
+;; 423 424 436 441 443 444 467 471 472 473 KILL)
+;; nil nil
+;; (ignore proc parsed))
+
+(provide 'erc-backend)
+
+;;; erc-backend.el ends here
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;; arch-tag: a64e6bb7-a780-4efd-8f98-083b18c7c84a
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
new file mode 100644
index 00000000000..6c6998a3afc
--- /dev/null
+++ b/lisp/erc/erc-button.el
@@ -0,0 +1,504 @@
+;; erc-button.el --- A way of buttonizing certain things in ERC buffers
+
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+;; 2006 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Keywords: irc, button, url, regexp
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcButton
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Heavily borrowed from gnus-art.el. Thanks to the original authors.
+;; This buttonizes nicks and other stuff to make it all clickable.
+;; To enable, add to your ~/.emacs:
+;; (require 'erc-button)
+;; (erc-button-mode 1)
+;;
+;; Todo:
+;; * Rewrite all this to do the same, but use button.el from GNU Emacs
+;; if it's available for xemacs too. Why? button.el is much faster,
+;; and much more elegant, and solves the problem we get with large buffers
+;; and a large erc-button-marker-list.
+
+
+;;; Code:
+
+(require 'erc)
+(require 'wid-edit)
+(require 'erc-fill)
+
+;;; Minor Mode
+
+(defgroup erc-button nil
+ "Define how text can be turned into clickable buttons."
+ :group 'erc)
+
+;;;###autoload (autoload 'erc-button-mode "erc-button" nil t)
+(define-erc-module button nil
+ "This mode buttonizes all messages according to `erc-button-alist'."
+ ((add-hook 'erc-insert-modify-hook 'erc-button-add-buttons 'append)
+ (add-hook 'erc-send-modify-hook 'erc-button-add-buttons 'append)
+ (add-hook 'erc-complete-functions 'erc-button-next))
+ ((remove-hook 'erc-insert-modify-hook 'erc-button-add-buttons)
+ (remove-hook 'erc-send-modify-hook 'erc-button-add-buttons)
+ (remove-hook 'erc-complete-functions 'erc-button-next)))
+
+;; Make XEmacs use `erc-button-face'.
+(when (featurep 'xemacs)
+ (add-hook 'erc-mode-hook
+ (lambda () (set (make-local-variable 'widget-button-face) nil))))
+
+;;; Variables
+
+(defface erc-button '((t (:bold t)))
+ "ERC button face."
+ :group 'erc-faces)
+
+(defcustom erc-button-face 'erc-button
+ "Face used for highlighting buttons in ERC buffers.
+
+A button is a piece of text that you can activate by pressing
+`RET' or `mouse-2' above it. See also `erc-button-keymap'."
+ :type 'face
+ :group 'erc-faces)
+
+(defcustom erc-button-nickname-face 'erc-nick-default-face
+ "Face used for ERC nickname buttons."
+ :type 'face
+ :group 'erc-faces)
+
+(defcustom erc-button-mouse-face 'highlight
+ "Face used for mouse highlighting in ERC buffers.
+
+Buttons will be displayed in this face when the mouse cursor is
+above them."
+ :type 'face
+ :group 'erc-faces)
+
+(defcustom erc-button-url-regexp
+ (concat "\\(www\\.\\|\\(s?https?\\|"
+ "ftp\\|file\\|gopher\\|news\\|telnet\\|wais\\|mailto\\):\\)"
+ "\\(//[-a-zA-Z0-9_.]+:[0-9]*\\)?"
+ "[-a-zA-Z0-9_=!?#$@~`%&*+\\/:;.,]+[-a-zA-Z0-9_=#$@~`%&*+\\/]")
+ "Regular expression that matches URLs."
+ :group 'erc-button
+ :type 'regexp)
+
+(defcustom erc-button-wrap-long-urls nil
+ "If non-nil, \"long\" URLs matching `erc-button-url-regexp' will be wrapped.
+
+If this variable is a number, consider URLs longer than its value to
+be \"long\". If t, URLs will be considered \"long\" if they are
+longer than `erc-fill-column'."
+ :group 'erc-button
+ :type '(choice integer boolean))
+
+(defcustom erc-button-buttonize-nicks t
+ "Flag indicating whether nicks should be buttonized or not."
+ :group 'erc-button
+ :type 'boolean)
+
+(defcustom erc-button-rfc-url "http://www.faqs.org/rfcs/rfc%s.html"
+ "*URL used to browse rfc references.
+%s is replaced by the number."
+ :group 'erc-button
+ :type 'string)
+
+(defcustom erc-button-google-url "http://www.google.com/search?q=%s"
+ "*URL used to browse Google search references.
+%s is replaced by the search string."
+ :group 'erc-button
+ :type 'string)
+
+(defcustom erc-button-alist
+ ;; Since the callback is only executed when the user is clicking on
+ ;; a button, it makes no sense to optimize performance by
+ ;; bytecompiling lambdas in this alist. On the other hand, it makes
+ ;; things hard to maintain.
+ '(('nicknames 0 erc-button-buttonize-nicks erc-nick-popup 0)
+ (erc-button-url-regexp 0 t browse-url 0)
+ ("<URL: *\\([^<> ]+\\) *>" 0 t browse-url 1)
+ ("(\\(\\([^~\n \t@][^\n \t@]*\\)@\\([a-zA-Z0-9.:-]+\\)\\)" 1 t finger 2 3)
+ ;; emacs internal
+ ("[`]\\([a-zA-Z][-a-zA-Z_0-9]+\\)[']" 1 t erc-button-describe-symbol 1)
+ ;; pseudo links
+ ("\\bInfo:[\"]\\([^\"]+\\)[\"]" 0 t Info-goto-node 1)
+ ("\\b\\(Ward\\|Wiki\\|WardsWiki\\|TheWiki\\):\\([A-Z][a-z]+\\([A-Z][a-z]+\\)+\\)"
+ 0 t (lambda (page)
+ (browse-url (concat "http://c2.com/cgi-bin/wiki?" page)))
+ 2)
+ ("EmacsWiki:\\([A-Z][a-z]+\\([A-Z][a-z]+\\)+\\)" 0 t erc-browse-emacswiki 1)
+ ("Lisp:\\([a-zA-Z.+-]+\\)" 0 t erc-browse-emacswiki-lisp 1)
+ ("\\bGoogle:\\([^ \t\n\r\f]+\\)"
+ 0 t (lambda (keywords)
+ (browse-url (format erc-button-google-url keywords)))
+ 1)
+ ("\\brfc[#: ]?\\([0-9]+\\)"
+ 0 t (lambda (num)
+ (browse-url (format erc-button-rfc-url num)))
+ 1)
+ ;; other
+ ("\\s-\\(@\\([0-9][0-9][0-9]\\)\\)" 1 t erc-button-beats-to-time 2))
+ "*Alist of regexps matching buttons in ERC buffers.
+Each entry has the form (REGEXP BUTTON FORM CALLBACK PAR...), where
+
+REGEXP is the string matching text around the button or a symbol
+ indicating a variable holding that string, or a list of
+ strings, or an alist with the strings in the car. Note that
+ entries in lists or alists are considered to be nicks or other
+ complete words. Therefore they are enclosed in \\< and \\>
+ while searching. REGEXP can also be the quoted symbol
+ 'nicknames, which matches the nickname of any user on the
+ current server.
+
+BUTTON is the number of the regexp grouping actually matching the
+ button, This is ignored if REGEXP is 'nicknames.
+
+FORM is a lisp expression which must eval to true for the button to
+ be added,
+
+CALLBACK is the function to call when the user push this button.
+ CALLBACK can also be a symbol. Its variable value will be used
+ as the callback function.
+
+PAR is a number of a regexp grouping whose text will be passed to
+ CALLBACK. There can be several PAR arguments. If REGEXP is
+ 'nicknames, these are ignored, and CALLBACK will be called with
+ the nickname matched as the argument."
+ :group 'erc-button
+ :type '(repeat
+ (list :tag "Button"
+ (choice :tag "Matches"
+ regexp
+ (variable :tag "Variable containing regexp")
+ (const :tag "Nicknames" 'nicknames))
+ (integer :tag "Number of the regexp section that matches")
+ (choice :tag "When to buttonize"
+ (const :tag "Always" t)
+ (sexp :tag "Only when this evaluates to non-nil"))
+ (function :tag "Function to call when button is pressed")
+ (repeat :tag "Sections of regexp to send to the function"
+ :inline t
+ (integer :tag "Regexp section number")))))
+
+(defcustom erc-emacswiki-url "http://www.emacswiki.org/cgi-bin/wiki.pl?"
+ "*URL of the EmacsWiki Homepage."
+ :group 'erc-button
+ :type 'string)
+
+(defcustom erc-emacswiki-lisp-url "http://www.emacswiki.org/elisp/"
+ "*URL of the EmacsWiki ELisp area."
+ :group 'erc-button
+ :type 'string)
+
+(defvar erc-button-keymap
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "RET") 'erc-button-press-button)
+ (if (featurep 'xemacs)
+ (define-key map (kbd "<button2>") 'erc-button-click-button)
+ (define-key map (kbd "<mouse-2>") 'erc-button-click-button))
+ (define-key map (kbd "TAB") 'erc-button-next)
+ (set-keymap-parent map erc-mode-map)
+ map)
+ "Local keymap for ERC buttons.")
+
+(defvar erc-button-syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?\( "w" table)
+ (modify-syntax-entry ?\) "w" table)
+ (modify-syntax-entry ?\[ "w" table)
+ (modify-syntax-entry ?\] "w" table)
+ (modify-syntax-entry ?\{ "w" table)
+ (modify-syntax-entry ?\} "w" table)
+ (modify-syntax-entry ?` "w" table)
+ (modify-syntax-entry ?' "w" table)
+ (modify-syntax-entry ?^ "w" table)
+ (modify-syntax-entry ?- "w" table)
+ (modify-syntax-entry ?_ "w" table)
+ (modify-syntax-entry ?| "w" table)
+ (modify-syntax-entry ?\\ "w" table)
+ table)
+ "Syntax table used when buttonizing messages.
+This syntax table should make all the legal nick characters word
+constituents.")
+
+(defun erc-button-add-buttons ()
+ "Find external references in the current buffer and make buttons of them.
+\"External references\" are things like URLs, as
+specified by `erc-button-alist'."
+ (interactive)
+ (save-excursion
+ (with-syntax-table erc-button-syntax-table
+ (let ((buffer-read-only nil)
+ (inhibit-point-motion-hooks t)
+ (inhibit-field-text-motion t)
+ (alist erc-button-alist)
+ entry regexp data)
+ (erc-button-remove-old-buttons)
+ (dolist (entry alist)
+ (if (equal (car entry) (quote (quote nicknames)))
+ (erc-button-add-nickname-buttons entry)
+ (progn
+ (setq regexp (or (and (stringp (car entry)) (car entry))
+ (and (boundp (car entry))
+ (symbol-value (car entry)))))
+ (cond ((stringp regexp)
+ (erc-button-add-buttons-1 regexp entry))
+ ((and (listp regexp) (stringp (car regexp)))
+ (dolist (r regexp)
+ (erc-button-add-buttons-1
+ (concat "\\<" (regexp-quote r) "\\>")
+ entry)))
+ ((and (listp regexp) (listp (car regexp))
+ (stringp (caar regexp)))
+ (dolist (elem regexp)
+ (erc-button-add-buttons-1
+ (concat "\\<" (regexp-quote (car elem)) "\\>")
+ entry)))))))))))
+
+(defun erc-button-add-nickname-buttons (entry)
+ "Search through the buffer for nicknames, and add buttons."
+ (let ((form (nth 2 entry))
+ (fun (nth 3 entry))
+ bounds word)
+ (when (or (eq t form)
+ (eval form))
+ (goto-char (point-min))
+ (while (forward-word 1)
+ (setq bounds (bounds-of-thing-at-point 'word))
+ (setq word (buffer-substring-no-properties
+ (car bounds) (cdr bounds)))
+ (if (erc-get-server-user word)
+ (erc-button-add-button (car bounds) (cdr bounds)
+ fun t (list word)))))))
+
+(defun erc-button-add-buttons-1 (regexp entry)
+ "Search through the buffer for matches to ENTRY and add buttons."
+ (goto-char (point-min))
+ (while (re-search-forward regexp nil t)
+ (let ((start (match-beginning (nth 1 entry)))
+ (end (match-end (nth 1 entry)))
+ (form (nth 2 entry))
+ (fun (nth 3 entry))
+ (data (mapcar 'match-string (nthcdr 4 entry))))
+ (when (or (eq t form)
+ (eval form))
+ (erc-button-add-button start end fun nil data regexp)))))
+
+(defun erc-button-remove-old-buttons ()
+ "Remove all existing buttons.
+This is called with narrowing in effect, just before the text is
+buttonized again. Removing a button means to remove all the properties
+that `erc-button-add-button' adds, except for the face."
+ (remove-text-properties
+ (point-min) (point-max)
+ '(erc-callback nil
+ erc-data nil
+ mouse-face nil
+ keymap nil)))
+
+(defun erc-button-add-button (from to fun nick-p &optional data regexp)
+ "Create a button between FROM and TO with callback FUN and data DATA.
+NICK-P specifies if this is a nickname button.
+REGEXP is the regular expression which matched for this button."
+ ;; Really nasty hack to <URL: > ise urls, and line-wrap them if
+ ;; they're going to be wider than `erc-fill-column'.
+ ;; This could be a lot cleaner, but it works for me -- lawrence.
+ (let (fill-column)
+ (when (and erc-button-wrap-long-urls
+ (string= regexp erc-button-url-regexp)
+ (> (- to from)
+ (setq fill-column (- (if (numberp erc-button-wrap-long-urls)
+ erc-button-wrap-long-urls
+ erc-fill-column)
+ (length erc-fill-prefix)))))
+ (setq to (prog1 (point-marker) (insert ">"))
+ from (prog2 (goto-char from) (point-marker) (insert "<URL: ")))
+ (let ((pos (copy-marker from)))
+ (while (> (- to pos) fill-column)
+ (goto-char (+ pos fill-column))
+ (insert "\n" erc-fill-prefix) ; This ought to figure out
+ ; what type of filling we're
+ ; doing, and indent accordingly.
+ (move-marker pos (point))))))
+ (if nick-p
+ (when erc-button-nickname-face
+ (erc-button-add-face from to erc-button-nickname-face))
+ (when erc-button-face
+ (erc-button-add-face from to erc-button-face)))
+ (add-text-properties
+ from to
+ (nconc (and erc-button-mouse-face
+ (list 'mouse-face erc-button-mouse-face))
+ (list 'erc-callback fun)
+ (list 'keymap erc-button-keymap)
+ (list 'rear-nonsticky t)
+ (and data (list 'erc-data data))))
+ (widget-convert-button 'link from to :action 'erc-button-press-button
+ :suppress-face t
+ ;; Make XEmacs use our faces.
+ :button-face (if nick-p
+ erc-button-nickname-face
+ erc-button-face)
+ ;; Make XEmacs behave with mouse-clicks, for
+ ;; some reason, widget stuff overrides the
+ ;; 'keymap text-property.
+ :mouse-down-action 'erc-button-click-button))
+
+(defun erc-button-add-face (from to face)
+ "Add FACE to the region between FROM and TO."
+ ;; If we just use `add-text-property', then this will overwrite any
+ ;; face text property already used for the button. It will not be
+ ;; merged correctly. If we use overlays, then redisplay will be
+ ;; very slow with lots of buttons. This is why we manually merge
+ ;; face text properties.
+ (let ((old (erc-list (get-text-property from 'face)))
+ (pos from)
+ (end (next-single-property-change from 'face nil to))
+ new)
+ ;; old is the face at pos, in list form. It is nil if there is no
+ ;; face at pos. If nil, the new face is FACE. If not nil, the
+ ;; new face is a list containing FACE and the old stuff. end is
+ ;; where this face changes.
+ (while (< pos to)
+ (setq new (if old (cons face old) face))
+ (put-text-property pos end 'face new)
+ (setq pos end
+ old (erc-list (get-text-property pos 'face))
+ end (next-single-property-change pos 'face nil to)))))
+
+;; widget-button-click calls with two args, we ignore the first.
+;; Since Emacs runs this directly, rather than with
+;; widget-button-click, we need to fake an extra arg in the
+;; interactive spec.
+(defun erc-button-click-button (ignore event)
+ "Call `erc-button-press-button'."
+ (interactive "P\ne")
+ (save-excursion
+ (mouse-set-point event)
+ (erc-button-press-button)))
+
+;; XEmacs calls this via widget-button-press with a bunch of arguments
+;; which we don't care about.
+(defun erc-button-press-button (&rest ignore)
+ "Check text at point for a callback function.
+If the text at point has a `erc-callback' property,
+call it with the value of the `erc-data' text property."
+ (interactive)
+ (let* ((data (get-text-property (point) 'erc-data))
+ (fun (get-text-property (point) 'erc-callback)))
+ (unless fun
+ (message "No button at point"))
+ (when (and fun (symbolp fun) (not (fboundp fun)))
+ (error "Function %S is not bound" fun))
+ (apply fun data)))
+
+(defun erc-button-next ()
+ "Go to the next button in this buffer."
+ (interactive)
+ (let ((here (point)))
+ (when (< here (erc-beg-of-input-line))
+ (while (and (get-text-property here 'erc-callback)
+ (not (= here (point-max))))
+ (setq here (1+ here)))
+ (while (and (not (get-text-property here 'erc-callback))
+ (not (= here (point-max))))
+ (setq here (1+ here)))
+ (if (< here (point-max))
+ (goto-char here)
+ (error "No next button"))
+ t)))
+
+(defun erc-browse-emacswiki (thing)
+ "Browse to thing in the emacs-wiki."
+ (browse-url (concat erc-emacswiki-url thing)))
+
+(defun erc-browse-emacswiki-lisp (thing)
+ "Browse to THING in the emacs-wiki elisp area."
+ (browse-url (concat erc-emacswiki-lisp-url thing)))
+
+;;; Nickname buttons:
+
+(defcustom erc-nick-popup-alist
+ '(("DeOp" . (erc-cmd-DEOP nick))
+ ("Kick" . (erc-cmd-KICK (concat nick " "
+ (read-from-minibuffer
+ (concat "Kick " nick ", reason: ")))))
+ ("Msg" . (erc-cmd-MSG (concat nick " "
+ (read-from-minibuffer
+ (concat "Message to " nick ": ")))))
+ ("Op" . (erc-cmd-OP nick))
+ ("Query" . (erc-cmd-QUERY nick))
+ ("Whois" . (erc-cmd-WHOIS nick))
+ ("Lastlog" . (erc-cmd-LASTLOG nick)))
+ "*An alist of possible actions to take on a nickname.
+An entry looks like (\"Action\" . SEXP) where SEXP is evaluated with
+the variable `nick' bound to the nick in question.
+
+Examples:
+ (\"DebianDB\" .
+ (shell-command
+ (format
+ \"ldapsearch -x -P 2 -h db.debian.org -b dc=debian,dc=org ircnick=%s\"
+ nick)))"
+ :group 'erc-button
+ :type '(repeat (cons (string :tag "Op")
+ sexp)))
+
+(defun erc-nick-popup (nick)
+ (let* ((completion-ignore-case t)
+ (action (completing-read (concat "What action to take on '" nick "'? ")
+ erc-nick-popup-alist))
+ (code (cdr (assoc action erc-nick-popup-alist))))
+ (when code
+ (erc-set-active-buffer (current-buffer))
+ (eval code))))
+
+;;; Callback functions
+(defun erc-button-describe-symbol (symbol-name)
+ "Describe SYMBOL-NAME.
+Use `describe-function' for functions, `describe-variable' for variables,
+and `apropos' for other symbols."
+ (let ((symbol (intern-soft symbol-name)))
+ (cond ((and symbol (fboundp symbol))
+ (describe-function symbol))
+ ((and symbol (boundp symbol))
+ (describe-variable symbol))
+ (t (apropos symbol-name)))))
+
+(defun erc-button-beats-to-time (beats)
+ "Display BEATS in a readable time format."
+ (let* ((seconds (- (* (string-to-number beats) 86.4)
+ 3600
+ (- (car (current-time-zone)))))
+ (hours (mod (floor seconds 3600) 24))
+ (minutes (mod (round seconds 60) 60)))
+ (message (format "@%s is %d:%02d local time"
+ beats hours minutes))))
+
+(provide 'erc-button)
+
+;;; erc-button.el ends here
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;; arch-tag: 7d23bed4-2f30-4273-a03f-d7a274c605c4
diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el
new file mode 100644
index 00000000000..2a06fa96b62
--- /dev/null
+++ b/lisp/erc/erc-compat.el
@@ -0,0 +1,207 @@
+;;; erc-compat.el --- ERC compatibility code for XEmacs
+
+;; Copyright (C) 2002, 2003, 2005, 2006 Free Software Foundation, Inc.
+
+;; Author: Alex Schroeder <alex@gnu.org>
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?EmacsIRCClient
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This mostly defines stuff that cannot be worked around easily.
+
+;;; Code:
+
+(require 'format-spec)
+
+;;;###autoload (autoload 'erc-define-minor-mode "erc-compat")
+(defalias 'erc-define-minor-mode 'define-minor-mode)
+(put 'erc-define-minor-mode 'edebug-form-spec 'define-minor-mode)
+
+(defun erc-decode-coding-string (s coding-system)
+ "Decode S using CODING-SYSTEM."
+ (decode-coding-string s coding-system t))
+
+(defun erc-encode-coding-string (s coding-system)
+ "Encode S using CODING-SYSTEM.
+Return the same string, if the encoding operation is trivial.
+See `erc-encoding-coding-alist'."
+ (encode-coding-string s coding-system t))
+
+(defalias 'erc-propertize 'propertize)
+(defalias 'erc-view-mode-enter 'view-mode-enter)
+(defalias 'erc-function-arglist 'help-function-arglist)
+(defalias 'erc-delete-dups 'delete-dups)
+(defalias 'erc-replace-regexp-in-string 'replace-regexp-in-string)
+
+(defvar erc-emacs-build-time
+ (if (stringp emacs-build-time)
+ emacs-build-time
+ (format-time-string "%Y-%m-%d" emacs-build-time))
+ "Time at which Emacs was dumped out.")
+
+;; XEmacs' `replace-match' does not replace matching subexpressions in strings.
+(defun erc-replace-match-subexpression-in-string
+ (newtext string match subexp start &optional fixedcase literal)
+ "Replace the subexpression SUBEXP of the last match in STRING with NEWTEXT.
+MATCH is the text which matched the subexpression (see `match-string').
+START is the beginning position of the last match (see `match-beginning').
+See `replace-match' for explanations of FIXEDCASE and LITERAL."
+ (cond ((featurep 'xemacs)
+ (string-match match string start)
+ (replace-match newtext fixedcase literal string))
+ (t (replace-match newtext fixedcase literal string subexp))))
+
+(defalias 'erc-cancel-timer 'cancel-timer)
+(defalias 'erc-make-obsolete 'make-obsolete)
+(defalias 'erc-make-obsolete-variable 'make-obsolete-variable)
+
+;; Provde an equivalent of `assert', based on the code from cl-macs.el
+(defun erc-const-expr-p (x)
+ (cond ((consp x)
+ (or (eq (car x) 'quote)
+ (and (memq (car x) '(function function*))
+ (or (symbolp (nth 1 x))
+ (and (eq (and (consp (nth 1 x))
+ (car (nth 1 x))) 'lambda) 'func)))))
+ ((symbolp x) (and (memq x '(nil t)) t))
+ (t t)))
+
+(put 'erc-assertion-failed 'error-conditions '(error))
+(put 'erc-assertion-failed 'error-message "Assertion failed")
+
+(defun erc-list* (arg &rest rest)
+ "Return a new list with specified args as elements, cons'd to last arg.
+Thus, `(list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to
+`(cons A (cons B (cons C D)))'."
+ (cond ((not rest) arg)
+ ((not (cdr rest)) (cons arg (car rest)))
+ (t (let* ((n (length rest))
+ (copy (copy-sequence rest))
+ (last (nthcdr (- n 2) copy)))
+ (setcdr last (car (cdr last)))
+ (cons arg copy)))))
+
+(defmacro erc-assert (form &optional show-args string &rest args)
+ "Verify that FORM returns non-nil; signal an error if not.
+Second arg SHOW-ARGS means to include arguments of FORM in message.
+Other args STRING and ARGS... are arguments to be passed to `error'.
+They are not evaluated unless the assertion fails. If STRING is
+omitted, a default message listing FORM itself is used."
+ (let ((sargs
+ (and show-args
+ (delq nil (mapcar
+ (function
+ (lambda (x)
+ (and (not (erc-const-expr-p x)) x)))
+ (cdr form))))))
+ (list 'progn
+ (list 'or form
+ (if string
+ (erc-list* 'error string (append sargs args))
+ (list 'signal '(quote erc-assertion-failed)
+ (erc-list* 'list (list 'quote form) sargs))))
+ nil)))
+
+;; Provide a simpler replacement for `member-if'
+(defun erc-member-if (predicate list)
+ "Find the first item satisfying PREDICATE in LIST.
+Return the sublist of LIST whose car matches."
+ (let ((ptr list))
+ (catch 'found
+ (while ptr
+ (when (funcall predicate (car ptr))
+ (throw 'found ptr))
+ (setq ptr (cdr ptr))))))
+
+;; Provide a simpler replacement for `delete-if'
+(defun erc-delete-if (predicate seq)
+ "Remove all items satisfying PREDICATE in SEQ.
+This is a destructive function: it reuses the storage of SEQ
+whenever possible."
+ ;; remove from car
+ (while (when (funcall predicate (car seq))
+ (setq seq (cdr seq))))
+ ;; remove from cdr
+ (let ((ptr seq)
+ (next (cdr seq)))
+ (while next
+ (when (funcall predicate (car next))
+ (setcdr ptr (if (consp next)
+ (cdr next)
+ nil)))
+ (setq ptr (cdr ptr))
+ (setq next (cdr ptr))))
+ seq)
+
+;; Provide a simpler replacement for `remove-if-not'
+(defun erc-remove-if-not (predicate seq)
+ "Remove all items not satisfying PREDICATE in SEQ.
+This is a non-destructive function; it makes a copy of SEQ to
+avoid corrupting the original SEQ."
+ (let (newseq)
+ (dolist (el seq)
+ (when (funcall predicate el)
+ (setq newseq (cons el newseq))))
+ (nreverse newseq)))
+
+;; Provide a simpler replacement for `gensym'.
+(defvar *erc-sym-counter* 0)
+(defun erc-gensym ()
+ "Generate a new uninterned symbol."
+ (let ((num (prog1 *erc-sym-counter*
+ (setq *erc-sym-counter* (1+ *erc-sym-counter*)))))
+ (make-symbol (format "*erc-sym-%d*" num))))
+
+;; Copied from cl-extra.el
+(defun erc-subseq (seq start &optional end)
+ "Return the subsequence of SEQ from START to END.
+If END is omitted, it defaults to the length of the sequence.
+If START or END is negative, it counts from the end."
+ (if (stringp seq) (substring seq start end)
+ (let (len)
+ (and end (< end 0) (setq end (+ end (setq len (length seq)))))
+ (if (< start 0) (setq start (+ start (or len (setq len (length seq))))))
+ (cond ((listp seq)
+ (if (> start 0) (setq seq (nthcdr start seq)))
+ (if end
+ (let ((res nil))
+ (while (>= (setq end (1- end)) start)
+ (push (pop seq) res))
+ (nreverse res))
+ (copy-sequence seq)))
+ (t
+ (or end (setq end (or len (length seq))))
+ (let ((res (make-vector (max (- end start) 0) nil))
+ (i 0))
+ (while (< start end)
+ (aset res i (aref seq start))
+ (setq i (1+ i) start (1+ start)))
+ res))))))
+
+(provide 'erc-compat)
+
+;;; erc-compat.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 8948ffe0-aff8-4ad8-a196-368ebbfd58ff
diff --git a/lisp/erc/erc-complete.el b/lisp/erc/erc-complete.el
new file mode 100644
index 00000000000..3b124f597ce
--- /dev/null
+++ b/lisp/erc/erc-complete.el
@@ -0,0 +1,222 @@
+;;; erc-complete.el --- Provides Nick name completion for ERC
+
+;; Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+
+;; Author: Alex Schroeder <alex@gnu.org>
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcCompletion
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file is obsolete. Use completion from erc-pcomplete instead.
+;; This file is based on hippie-expand, while the new file is based on
+;; pcomplete. There is no autoload cookie in this file. If you want
+;; to use the code in this file, add the following to your ~/.emacs:
+
+;; (autoload 'erc-complete "erc-complete" "Complete nick at point." t)
+
+;;; Code:
+
+(require 'erc)
+(require 'erc-match); for erc-pals
+(require 'hippie-exp); for the hippie expand stuff
+
+;;;###autoload
+(defun erc-complete ()
+ "Complete nick at point.
+See `erc-try-complete-nick' for more technical info.
+This function is obsolete, use `erc-pcomplete' instead."
+ (interactive)
+ (let ((hippie-expand-try-functions-list '(erc-try-complete-nick)))
+ (hippie-expand nil)))
+
+(defgroup erc-old-complete nil
+ "Nick completion. Obsolete, use erc-pcomplete instead."
+ :group 'erc)
+
+(defcustom erc-nick-completion 'all
+ "Determine how the list of nicks is determined during nick completion.
+See `erc-complete-nick' for information on how to activate this.
+
+pals: Use `erc-pals'.
+all: All channel members.
+
+You may also provide your own function that returns a list of completions.
+One example is `erc-nick-completion-exclude-myself',
+or you may use an arbitrary lisp expression."
+ :type '(choice (const :tag "List of pals" pals)
+ (const :tag "All channel members" all)
+ (const :tag "All channel members except yourself"
+ erc-nick-completion-exclude-myself)
+ (repeat :tag "List" (string :tag "Nick"))
+ function
+ sexp)
+ :group 'erc-old-complete)
+
+(defcustom erc-nick-completion-ignore-case t
+ "*Non-nil means don't consider case significant in nick completion.
+Case will be automatically corrected when non-nil.
+For instance if you type \"dely TAB\" the word completes and changes to
+\"delYsid\"."
+ :group 'erc-old-complete
+ :type 'boolean)
+
+(defun erc-nick-completion-exclude-myself ()
+ "Get a list of all the channel members except you.
+
+This function returns a list of all the members in the channel, except
+your own nick. This way if you're named foo and someone is called foobar,
+typing \"f o TAB\" will directly give you foobar. Use this with
+`erc-nick-completion'."
+ (delete
+ (erc-current-nick)
+ (mapcar (function car) (erc-get-channel-user-list))))
+
+(defcustom erc-nick-completion-postfix ": "
+ "*When `erc-complete' is used in the first word after the prompt,
+add this string when a unique expansion was found."
+ :group 'erc-old-complete
+ :type 'string)
+
+(defun erc-command-list ()
+ "Returns a list of strings of the defined user commands."
+ (let ((case-fold-search nil))
+ (mapcar (lambda (x)
+ (concat "/" (downcase (substring (symbol-name x) 8))))
+ (apropos-internal "erc-cmd-[A-Z]+"))))
+
+(defun erc-try-complete-nick (old)
+ "Complete nick at point.
+This is a function to put on `hippie-expand-try-functions-list'.
+Then use \\[hippie-expand] to expand nicks.
+The type of completion depends on `erc-nick-completion'."
+ (cond ((eq erc-nick-completion 'pals)
+ (try-complete-erc-nick old erc-pals))
+ ((eq erc-nick-completion 'all)
+ (try-complete-erc-nick old (append
+ (mapcar (function car)
+ (erc-get-channel-user-list))
+ (erc-command-list))))
+ ((functionp erc-nick-completion)
+ (try-complete-erc-nick old (funcall erc-nick-completion)))
+ (t
+ (try-complete-erc-nick old erc-nick-completion))))
+
+(defvar try-complete-erc-nick-window-configuration nil
+ "The window configuration for `try-complete-erc-nick'.
+When called the first time, a window config is stored here,
+and when completion is done, the window config is restored
+from here. See `try-complete-erc-nick-restore' and
+`try-complete-erc-nick'.")
+
+(defun try-complete-erc-nick-restore ()
+ "Restore window configuration."
+ (if (not try-complete-erc-nick-window-configuration)
+ (when (get-buffer "*Completions*")
+ (delete-windows-on "*Completions*"))
+ (set-window-configuration
+ try-complete-erc-nick-window-configuration)
+ (setq try-complete-erc-nick-window-configuration nil)))
+
+(defun try-complete-erc-nick (old completions)
+ "Try to complete current word depending on `erc-try-complete-nick'.
+The argument OLD has to be nil the first call of this function, and t
+for subsequent calls (for further possible completions of the same
+string). It returns t if a new completion is found, nil otherwise. The
+second argument COMPLETIONS is a list of completions to use. Actually,
+it is only used when OLD is nil. It will be copied to `he-expand-list'
+on the first call. After that, it is no longer used.
+Window configurations are stored in
+`try-complete-erc-nick-window-configuration'."
+ (let (expansion
+ final
+ (alist (if (consp (car completions))
+ completions
+ (mapcar (lambda (s)
+ (if (and (erc-complete-at-prompt)
+ (and (not (= (length s) 0))
+ (not (eq (elt s 0) ?/))))
+ (list (concat s erc-nick-completion-postfix))
+ (list (concat s " "))))
+ completions))) ; make alist if required
+ (completion-ignore-case erc-nick-completion-ignore-case))
+ (he-init-string (he-dabbrev-beg) (point))
+ ;; If there is a string to complete, complete it using alist.
+ ;; expansion is the possible expansion, or t. If expansion is t
+ ;; or if expansion is the "real" thing, we are finished (final is
+ ;; t). Take care -- expansion can also be nil!
+ (unless (string= he-search-string "")
+ (setq expansion (try-completion he-search-string alist)
+ final (or (eq t expansion)
+ (and expansion
+ (eq t (try-completion expansion alist))))))
+ (cond ((not expansion)
+ ;; There is no expansion at all.
+ (try-complete-erc-nick-restore)
+ (he-reset-string)
+ nil)
+ ((eq t expansion)
+ ;; The user already has the correct expansion.
+ (try-complete-erc-nick-restore)
+ (he-reset-string)
+ t)
+ ((and old (string= expansion he-search-string))
+ ;; This is the second time around and nothing changed,
+ ;; ie. the user tried to expand something incomplete
+ ;; without making a choice -- hitting TAB twice, for
+ ;; example.
+ (try-complete-erc-nick-restore)
+ (he-reset-string)
+ nil)
+ (final
+ ;; The user has found the correct expansion.
+ (try-complete-erc-nick-restore)
+ (he-substitute-string expansion)
+ t)
+ (t
+ ;; We found something but we are not finished. Show a
+ ;; completions buffer. Substitute what we found and return
+ ;; t.
+ (setq try-complete-erc-nick-window-configuration
+ (current-window-configuration))
+ (with-output-to-temp-buffer "*Completions*"
+ (display-completion-list (all-completions he-search-string alist)))
+ (he-substitute-string expansion)
+ t))))
+
+(defun erc-at-beginning-of-line-p (point &optional bol-func)
+ (save-excursion
+ (funcall (or bol-func
+ 'erc-bol))
+ (equal point (point))))
+
+(defun erc-complete-at-prompt ()
+ "Returns t if point is directly after `erc-prompt' when doing completion."
+ (erc-at-beginning-of-line-p (he-dabbrev-beg)))
+
+(provide 'erc-complete)
+
+;;; erc-complete.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 3be13ee8-8fdb-41ab-83c2-6582c757b91e
diff --git a/lisp/erc/erc-dcc.el b/lisp/erc/erc-dcc.el
new file mode 100644
index 00000000000..d5789a51708
--- /dev/null
+++ b/lisp/erc/erc-dcc.el
@@ -0,0 +1,1135 @@
+;;; erc-dcc.el --- CTCP DCC module for ERC
+
+;; Copyright (C) 1993, 1994, 1995, 1998, 2002, 2003, 2004
+;; Free Software Foundation, Inc.
+
+;; Author: Ben A. Mesander <ben@gnu.ai.mit.edu>
+;; Noah Friedman <friedman@prep.ai.mit.edu>
+;; Per Persson <pp@sno.pp.se>
+;; Maintainer: mlang@delysid.org
+;; Keywords: comm, processes
+;; Created: 1994-01-23
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides Direct Client-to-Client support for the Emacs IRC Client.
+;;
+;; The original code was taken from zenirc-dcc.el, heavily mangled and
+;; rewritten to support the way how ERC operates. Server socket support
+;; was added for DCC CHAT and SEND afterwards. Thanks
+;; to the original authors for their work.
+;;
+;; To use this file, put
+;; (require 'erc-dcc)
+;; in your .emacs.
+;;
+;; Provided commands
+;; /dcc chat nick - Either accept pending chat offer from nick, or offer
+;; DCC chat to nick
+;; /dcc close type [nick] - Close DCC connection (SEND/GET/CHAT) with nick
+;; /dcc get nick [file] - Accept DCC offer from nick
+;; /dcc list - List all DCC offers/connections
+;; /dcc send nick file - Offer DCC SEND to nick
+;;
+;; Please note that offering DCC connections (offering chats and sending
+;; files) is only supported with Emacs 21.3.50 (CVS).
+
+;;; Code:
+
+(require 'erc)
+(eval-when-compile
+ (require 'pcomplete))
+
+(defgroup erc-dcc nil
+ "DCC stands for Direct Client Communication, where you and your
+friend's client programs connect directly to each other,
+bypassing IRC servers and their occasional \"lag\" or \"split\"
+problems. Like /MSG, the DCC chat is completely private.
+
+Using DCC get and send, you can transfer files directly from and to other
+IRC users."
+ :group 'erc)
+
+(defcustom erc-verbose-dcc t
+ "*If non-nil, be verbose about DCC activity reporting."
+ :group 'erc-dcc
+ :type 'boolean)
+
+(defvar erc-dcc-list nil
+ "List of DCC connections. Looks like:
+ ((:nick \"nick!user@host\" :type GET :peer proc :parent proc :size size :file file)
+ (:nick \"nick!user@host\" :type CHAT :peer proc :parent proc)
+ (:nick \"nick\" :type SEND :peer server-proc :parent parent-proc :file
+ file :sent <marker> :confirmed <marker>))
+
+ :nick - a user or userhost for the peer. combine with :parent to reach them
+
+ :type - the type of DCC connection - SEND for outgoing files, GET for
+ incoming, and CHAT for both directions. To tell which end started
+ the DCC chat, look at :peer
+
+ :peer - the other end of the DCC connection. In the case of outgoing DCCs,
+ this represents a server process until a connection is established
+
+ :parent - the server process where the dcc connection was established.
+ Note that this can be nil or an invalid process since a DCC
+ connection is in general independent from a particular server
+ connection after it was established.
+
+ :file - for outgoing sends, the full path to the file. for incoming sends,
+ the suggested filename or vetted filename
+
+ :size - size of the file, may be nil on incoming DCCs")
+
+(defun erc-dcc-list-add (type nick peer parent &rest args)
+ "Add a new entry of type TYPE to `erc-dcc-list' and return it."
+ (car
+ (setq erc-dcc-list
+ (cons
+ (append (list :nick nick :type type :peer peer :parent parent) args)
+ erc-dcc-list))))
+
+;; This function takes all the usual args as open-network-stream, plus one
+;; more: the entry data from erc-dcc-list for this particular process.
+(defvar erc-dcc-connect-function 'erc-dcc-open-network-stream)
+
+(defun erc-dcc-open-network-stream (procname buffer addr port entry)
+ (if nil; (fboundp 'open-network-stream-nowait) ;; this currently crashes
+ ;; cvs emacs
+ (open-network-stream-nowait procname buffer addr port)
+ (open-network-stream procname buffer addr port)))
+
+(erc-define-catalog
+ 'english
+ '((dcc-chat-discarded
+ . "DCC: previous chat request from %n (%u@%h) discarded")
+ (dcc-chat-ended . "DCC: chat with %n ended %t: %e")
+ (dcc-chat-no-request . "DCC: chat request from %n not found")
+ (dcc-chat-offered . "DCC: chat offered by %n (%u@%h:%p)")
+ (dcc-chat-offer . "DCC: offering chat to %n")
+ (dcc-chat-accept . "DCC: accepting chat from %n")
+ (dcc-chat-privmsg . "=%n= %m")
+ (dcc-closed . "DCC: Closed %T from %n")
+ (dcc-command-undefined
+ . "DCC: %c undefined subcommand. GET, CHAT and LIST are defined.")
+ (dcc-ctcp-errmsg . "DCC: `%s' is not a DCC subcommand known to this client")
+ (dcc-ctcp-unknown . "DCC: unknown dcc command `%q' from %n (%u@%h)")
+ (dcc-get-bytes-received . "DCC: %f: %b bytes received")
+ (dcc-get-complete
+ . "DCC: file %f transfer complete (%s bytes in %t seconds)")
+ (dcc-get-cmd-aborted . "DCC: Aborted getting %f from %n")
+ (dcc-get-file-too-long
+ . "DCC: %f: File longer than sender claimed; aborting transfer")
+ (dcc-get-notfound . "DCC: %n hasn't offered %f for DCC transfer")
+ (dcc-list-head . "DCC: From Type Active Size Filename")
+ (dcc-list-line . "DCC: -------- ---- ------ ------------ --------")
+ (dcc-list-item . "DCC: %-8n %-4t %-6a %-12s %f")
+ (dcc-list-end . "DCC: End of list.")
+ (dcc-malformed . "DCC: error: %n (%u@%h) sent malformed request: %q")
+ (dcc-privileged-port
+ . "DCC: possibly bogus request: %p is a privileged port.")
+ (dcc-request-bogus . "DCC: bogus dcc `%r' from %n (%u@%h)")
+ (dcc-send-finished . "DCC: SEND of %f to %n finished (size %s)")
+ (dcc-send-offered . "DCC: file %f offered by %n (%u@%h) (size %s)")
+ (dcc-send-offer . "DCC: offering %f to %n")))
+
+;;; Misc macros and utility functions
+
+(defun erc-dcc-member (&rest args)
+ "Return the first matching entry in `erc-dcc-list' which satisfies the
+constraints given as a plist in ARGS. Returns nil on no match.
+
+The property :nick is treated specially, if it contains a '!' character,
+it is treated as a nick!user@host string, and compared with the :nick property
+value of the individual elements using string-equal. Otherwise it is
+compared with `erc-nick-equal-p' which is IRC case-insensitive."
+ (let ((list erc-dcc-list)
+ result test)
+ ;; for each element in erc-dcc-list
+ (while (and list (not result))
+ (let ((elt (car list))
+ (prem args)
+ (cont t))
+ ;; loop through the constraints
+ (while (and prem cont)
+ (let ((prop (car prem))
+ (val (cadr prem)))
+ (setq prem (cddr prem)
+ ;; plist-member is a predicate in xemacs
+ test (and (plist-member elt prop)
+ (plist-get elt prop)))
+ ;; if the property exists and is equal, we continue, else, try the
+ ;; next element of the list
+ (or (and (eq prop :nick) (string-match "!" val)
+ test (string-equal test val))
+ (and (eq prop :nick)
+ test val
+ (erc-nick-equal-p
+ (erc-extract-nick test)
+ (erc-extract-nick val)))
+ ;; not a nick
+ (eq test val)
+ (setq cont nil))))
+ (if cont
+ (setq result elt)
+ (setq list (cdr list)))))
+ result))
+
+;; msa wrote this nifty little frob to convert an n-byte integer to a packed
+;; string.
+(defun erc-pack-int (value count)
+ (if (> count 0)
+ (concat (erc-pack-int (/ value 256) (1- count))
+ (char-to-string (% value 256)))
+ ""))
+
+(defun erc-unpack-int (str)
+ "Unpack a 1-4 character packed string into an integer."
+ (let ((len (length str))
+ (num 0)
+ (count 0))
+ (erc-assert (<= len 4)) ;; this isn't going to fit in elisp bounds
+ (while (< count len)
+ (setq num (+ num (lsh (aref str (- len count 1)) (* 8 count))))
+ (setq count (1+ count)))
+ num))
+
+(defconst erc-dcc-ipv4-regexp
+ (concat "^"
+ (mapconcat #'identity (make-list 4 "\\([0-9]\\{1,3\\}\\)") "\\.")
+ "$"))
+
+(defun erc-ip-to-decimal (ip)
+ "Convert IP address to its decimal representation.
+Argument IP is the address as a string. The result is also a string."
+ (interactive "sIP Address: ")
+ (if (not (string-match erc-dcc-ipv4-regexp ip))
+ (error "Not an IP address")
+ (let* ((ips (mapcar
+ (lambda (str)
+ (let ((n (string-to-number str)))
+ (if (and (>= n 0) (< n 256))
+ n
+ (error "%d out of range" n))))
+ (split-string ip "\\.")))
+ (res (+ (* (car ips) 16777216.0)
+ (* (nth 1 ips) 65536.0)
+ (* (nth 2 ips) 256.0)
+ (nth 3 ips))))
+ (if (interactive-p)
+ (message "%s is %.0f" ip res)
+ (format "%.0f" res)))))
+
+(defun erc-decimal-to-ip (dec)
+ "Convert a decimal representation DEC to an IP address.
+The result is also a string."
+ (when (stringp dec)
+ (setq dec (string-to-number (concat dec ".0"))))
+ (let* ((first (floor (/ dec 16777216.0)))
+ (first-rest (- dec (* first 16777216.0)))
+ (second (floor (/ first-rest 65536.0)))
+ (second-rest (- first-rest (* second 65536.0)))
+ (third (floor (/ second-rest 256.0)))
+ (third-rest (- second-rest (* third 256.0)))
+ (fourth (floor third-rest)))
+ (format "%s.%s.%s.%s" first second third fourth)))
+
+;;; Server code
+
+(defcustom erc-dcc-host nil
+ "*IP address to use for outgoing DCC offers.
+Should be set to a string or nil, if nil, automatic detection of the
+host interface to use will be attempted."
+ :group 'erc-dcc
+ :type (list 'choice (list 'const :tag "Auto-detect" nil)
+ (list 'string :tag "IP-address"
+ :valid-regexp erc-dcc-ipv4-regexp)))
+
+(defcustom erc-dcc-send-request 'ask
+ "*How to treat incoming DCC Send requests.
+'ask - Report the Send request, and wait for the user to manually accept it
+ You might want to set `erc-dcc-auto-masks' for this.
+'auto - Automatically accept the request and begin downloading the file
+'ignore - Ignore incoming DCC Send requests completely."
+ :group 'erc-dcc
+ :type '(choice (const ask) (const auto) (const ignore)))
+
+(defun erc-dcc-get-host (proc)
+ "Returns the local IP address used for an open PROCess."
+ (format-network-address (process-contact proc :local) t))
+
+(defun erc-dcc-host ()
+ "Determine the IP address we are using.
+If variable `erc-dcc-host' is non-nil, use it. Otherwise call
+`erc-dcc-get-host' on the erc-server-process."
+ (or erc-dcc-host (erc-dcc-get-host erc-server-process)
+ (error "Unable to determine local address")))
+
+(defcustom erc-dcc-port-range nil
+ "If nil, any available user port is used for outgoing DCC connections.
+If set to a cons, it specifies a range of ports to use in the form (min . max)"
+ :group 'erc-dcc
+ :type '(choice
+ (const :tag "Any port" nil)
+ (cons :tag "Port range"
+ (integer :tag "Lower port")
+ (integer :tag "Upper port"))))
+
+(defcustom erc-dcc-auto-masks nil
+ "List of regexps matching user identifiers whose DCC send offers should be
+accepted automatically. A user identifier has the form \"nick!login@host\".
+For instance, to accept all incoming DCC send offers automatically, add the
+string \".*!.*@.*\" to this list."
+ :group 'erc-dcc
+ :type '(repeat regexp))
+
+(defun erc-dcc-server (name filter sentinel)
+ "Start listening on a port for an incoming DCC connection. Returns the newly
+created subprocess, or nil."
+ (let ((port (or (and erc-dcc-port-range (car erc-dcc-port-range)) t))
+ (upper (and erc-dcc-port-range (cdr erc-dcc-port-range)))
+ process)
+ (while (not process)
+ (condition-case err
+ (setq process
+ (make-network-process :name name
+ :buffer nil
+ :host (erc-dcc-host)
+ :service port
+ :nowait t
+ :noquery nil
+ :filter filter
+ :sentinel sentinel
+ :log #'erc-dcc-server-accept
+ :server t))
+ (file-error
+ (unless (and (string= "Cannot bind server socket" (cadr err))
+ (string= "address already in use" (caddr err)))
+ (signal (car err) (cdr err)))
+ (setq port (1+ port))
+ (unless (< port upper)
+ (error "No available ports in erc-dcc-port-range")))))
+ process))
+
+(defun erc-dcc-server-accept (server client message)
+ "Log an accepted DCC offer, then terminate the listening process and set up
+the accepted connection."
+ (erc-log (format "(erc-dcc-server-accept): server %s client %s message %s"
+ server client message))
+ (when (and (string-match "^accept from " message)
+ (processp server) (processp client))
+ (let ((elt (erc-dcc-member :peer server)))
+ ;; change the entry in erc-dcc-list from the listening process to the
+ ;; accepted process
+ (setq elt (plist-put elt :peer client))
+ ;; delete the listening process, as we've accepted the connection
+ (delete-process server))))
+
+;;; Interactive command handling
+
+(defcustom erc-dcc-get-default-directory nil
+ "*Default directory for incoming DCC file transfers.
+If this is nil, then the current value of `default-directory' is used."
+ :group 'erc-dcc
+ :type '(choice (const nil :tag "Default directory") directory))
+
+;;;###autoload
+(defun erc-cmd-DCC (cmd &rest args)
+ "Parser for /dcc command.
+This figures out the dcc subcommand and calls the appropriate routine to
+handle it. The function dispatched should be named \"erc-dcc-do-FOO-command\",
+where FOO is one of CLOSE, GET, SEND, LIST, CHAT, etc."
+ (when cmd
+ (let ((fn (intern-soft (concat "erc-dcc-do-" (upcase cmd) "-command"))))
+ (if fn
+ (apply fn erc-server-process args)
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-command-undefined ?c cmd)
+ (apropos "erc-dcc-do-.*-command")
+ t))))
+
+;;;###autoload
+(defun pcomplete/erc-mode/DCC ()
+ "Provides completion for the /DCC command."
+ (pcomplete-here (append '("chat" "close" "get" "list")
+ (when (fboundp 'make-network-process) '("send"))))
+ (pcomplete-here
+ (case (intern (downcase (pcomplete-arg 1)))
+ (chat (mapcar (lambda (elt) (plist-get elt :nick))
+ (erc-remove-if-not
+ #'(lambda (elt)
+ (eq (plist-get elt :type) 'CHAT))
+ erc-dcc-list)))
+ (close (remove-duplicates
+ (mapcar (lambda (elt) (symbol-name (plist-get elt :type)))
+ erc-dcc-list) :test 'string=))
+ (get (mapcar #'erc-dcc-nick
+ (erc-remove-if-not
+ #'(lambda (elt)
+ (eq (plist-get elt :type) 'GET))
+ erc-dcc-list)))
+ (send (pcomplete-erc-all-nicks))))
+ (pcomplete-here
+ (case (intern (downcase (pcomplete-arg 2)))
+ (get (mapcar (lambda (elt) (plist-get elt :file))
+ (erc-remove-if-not
+ #'(lambda (elt)
+ (and (eq (plist-get elt :type) 'GET)
+ (erc-nick-equal-p (erc-extract-nick
+ (plist-get elt :nick))
+ (pcomplete-arg 1))))
+ erc-dcc-list)))
+ (close (mapcar #'erc-dcc-nick
+ (erc-remove-if-not
+ #'(lambda (elt)
+ (eq (plist-get elt :type)
+ (intern (upcase (pcomplete-arg 1)))))
+ erc-dcc-list)))
+ (send (pcomplete-entries)))))
+
+(defun erc-dcc-do-CHAT-command (proc &optional nick)
+ (when nick
+ (let ((elt (erc-dcc-member :nick nick :type 'CHAT :parent proc)))
+ (if (and elt (not (processp (plist-get elt :peer))))
+ ;; accept an existing chat offer
+ ;; FIXME: perhaps /dcc accept like other clients?
+ (progn (erc-dcc-chat-accept elt erc-server-process)
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-chat-accept ?n nick)
+ t)
+ (erc-dcc-chat nick erc-server-process)
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-chat-offer ?n nick)
+ t))))
+
+(defun erc-dcc-do-CLOSE-command (proc &optional type nick)
+ "/dcc close type nick
+type and nick are optional."
+ ;; FIXME, should also work if only nick is specified
+ (when (string-match (concat "^\\s-*\\(\\S-+\\)? *\\("
+ erc-valid-nick-regexp "\\)?\\s-*$") line)
+ (let ((type (when (match-string 1 line)
+ (intern (upcase (match-string 1 line)))))
+ (nick (match-string 2 line))
+ (ret t))
+ (while ret
+ (if nick
+ (setq ret (erc-dcc-member :type type :nick nick))
+ (setq ret (erc-dcc-member :type type)))
+ (when ret
+ ;; found a match - delete process if it exists.
+ (and (processp (plist-get ret :peer))
+ (delete-process (plist-get ret :peer)))
+ (setq erc-dcc-list (delq ret erc-dcc-list))
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-closed
+ ?T (plist-get ret :type)
+ ?n (erc-extract-nick (plist-get ret :nick))))))
+ t))
+
+(defun erc-dcc-do-GET-command (proc nick &optional file)
+ (let* ((elt (erc-dcc-member :nick nick :type 'GET))
+ (filename (or file (plist-get elt :file) "unknown")))
+ (if elt
+ (let* ((file (read-file-name
+ (format "Local filename (default %s): "
+ (file-name-nondirectory filename))
+ (or erc-dcc-get-default-directory
+ default-directory)
+ (expand-file-name (file-name-nondirectory filename)
+ (or erc-dcc-get-default-directory
+ default-directory)))))
+ (cond ((file-exists-p file)
+ (if (yes-or-no-p (format "File %s exists. Overwrite? "
+ file))
+ (erc-dcc-get-file elt file proc)
+ (erc-display-message
+ nil '(notice error) proc
+ 'dcc-get-cmd-aborted
+ ?n nick ?f filename)))
+ (t
+ (erc-dcc-get-file elt file proc))))
+ (erc-display-message
+ nil '(notice error) 'active
+ 'dcc-get-notfound ?n nick ?f filename))))
+
+(defun erc-dcc-do-LIST-command (proc)
+ "This is the handler for the /dcc list command.
+It lists the current state of `erc-dcc-list' in an easy to read manner."
+ (let ((alist erc-dcc-list)
+ size elt)
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-list-head)
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-list-line)
+ (while alist
+ (setq elt (car alist)
+ alist (cdr alist))
+
+ (setq size (or (and (plist-member elt :size)
+ (plist-get elt :size))
+ ""))
+ (setq size
+ (cond ((null size) "")
+ ((numberp size) (number-to-string size))
+ ((string= size "") "unknown")))
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-list-item
+ ?n (erc-dcc-nick elt)
+ ?t (plist-get elt :type)
+ ?a (if (processp (plist-get elt :peer))
+ (process-status (plist-get elt :peer))
+ "no")
+ ?s (concat size
+ (if (and (eq 'GET (plist-get elt :type))
+ (plist-member elt :file)
+ (buffer-live-p (get-buffer (plist-get elt :file)))
+ (plist-member elt :size))
+ (concat " (" (number-to-string
+ (* 100
+ (/ (buffer-size
+ (get-buffer (plist-get elt :file)))
+ (plist-get elt :size))))
+ "%)")))
+ ?f (or (and (plist-member elt :file) (plist-get elt :file)) "")))
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-list-end)
+ t))
+
+(defun erc-dcc-do-SEND-command (proc nick file)
+ "Offer FILE to NICK by sending a ctcp dcc send message."
+ (if (file-exists-p file)
+ (progn
+ (erc-display-message
+ nil 'notice 'active
+ 'dcc-send-offer ?n nick ?f file)
+ (erc-dcc-send-file nick file) t)
+ (erc-display-message nil '(notice error) proc "File not found") t))
+
+;;; Server message handling (i.e. messages from remote users)
+
+;;;###autoload
+(defvar erc-ctcp-query-DCC-hook '(erc-ctcp-query-DCC)
+ "Hook variable for CTCP DCC queries")
+
+(defvar erc-dcc-query-handler-alist
+ '(("SEND" . erc-dcc-handle-ctcp-send)
+ ("CHAT" . erc-dcc-handle-ctcp-chat)))
+
+;;;###autoload
+(defun erc-ctcp-query-DCC (proc nick login host to query)
+ "The function called when a CTCP DCC request is detected by the client.
+It examines the DCC subcommand, and calls the appropriate routine for
+that subcommand."
+ (let* ((cmd (cadr (split-string query " ")))
+ (handler (cdr (assoc cmd erc-dcc-query-handler-alist))))
+ (if handler
+ (funcall handler proc query nick login host to)
+ ;; FIXME: Send a ctcp error notice to the remote end?
+ (erc-display-message
+ nil '(notice error) proc
+ 'dcc-ctcp-unknown
+ ?q query ?n nick ?u login ?h host))))
+
+(defconst erc-dcc-ctcp-query-send-regexp
+ "^DCC SEND \\([^ ]+\\) \\([0-9]+\\) \\([0-9]+\\) *\\([0-9]*\\)")
+
+(defun erc-dcc-handle-ctcp-send (proc query nick login host to)
+ "This is called if a CTCP DCC SEND subcommand is sent to the client.
+It extracts the information about the dcc request and adds it to
+`erc-dcc-list'."
+ (unless (eq erc-dcc-send-request 'ignore)
+ (cond
+ ((not (erc-current-nick-p to))
+ ;; DCC SEND requests must be sent to you, and you alone.
+ (erc-display-message
+ nil 'notice proc
+ 'dcc-request-bogus
+ ?r "SEND" ?n nick ?u login ?h host))
+ ((string-match erc-dcc-ctcp-query-send-regexp query)
+ (let ((filename (match-string 1 query))
+ (ip (erc-decimal-to-ip (match-string 2 query)))
+ (port (match-string 3 query))
+ (size (match-string 4 query)))
+ ;; FIXME: a warning really should also be sent
+ ;; if the ip address != the host the dcc sender is on.
+ (erc-display-message
+ nil 'notice proc
+ 'dcc-send-offered
+ ?f filename ?n nick ?u login ?h host
+ ?s (if (string= size "") "unknown" size))
+ (and (< (string-to-number port) 1025)
+ (erc-display-message
+ nil 'notice proc
+ 'dcc-privileged-port
+ ?p port))
+ (erc-dcc-list-add
+ 'GET (format "%s!%s@%s" nick login host)
+ nil proc
+ :ip ip :port port :file filename
+ :size (string-to-number size))
+ (if (and (eq erc-dcc-send-request 'auto)
+ (erc-dcc-auto-mask-p (format "\"%s!%s@%s\"" nick login host)))
+ (erc-dcc-get-file (car erc-dcc-list) filename proc))))
+ (t
+ (erc-display-message
+ nil 'notice proc
+ 'dcc-malformed
+ ?n nick ?u login ?h host ?q query)))))
+
+(defun erc-dcc-auto-mask-p (spec)
+ "Takes a full SPEC of a user in the form \"nick!login@host\" and
+matches against all the regexp's in `erc-dcc-auto-masks'. If any
+match, returns that regexp and nil otherwise."
+ (let ((lst erc-dcc-auto-masks))
+ (while (and lst
+ (not (string-match (car lst) spec)))
+ (setq lst (cdr lst)))
+ (and lst (car lst))))
+
+(defconst erc-dcc-ctcp-query-chat-regexp
+ "^DCC CHAT +chat +\\([0-9]+\\) +\\([0-9]+\\)")
+
+(defcustom erc-dcc-chat-request 'ask
+ "*How to treat incoming DCC Chat requests.
+'ask - Report the Chat request, and wait for the user to manually accept it
+'auto - Automatically accept the request and open a new chat window
+'ignore - Ignore incoming DCC chat requests completely."
+ :group 'erc-dcc
+ :type '(choice (const ask) (const auto) (const ignore)))
+
+(defun erc-dcc-handle-ctcp-chat (proc query nick login host to)
+ (unless (eq erc-dcc-chat-request 'ignore)
+ (cond
+ (;; DCC CHAT requests must be sent to you, and you alone.
+ (not (erc-current-nick-p to))
+ (erc-display-message
+ nil '(notice error) proc
+ 'dcc-request-bogus ?r "CHAT" ?n nick ?u login ?h host))
+ ((string-match erc-dcc-ctcp-query-chat-regexp query)
+ ;; We need to use let* here, since erc-dcc-member might clutter
+ ;; the match value.
+ (let* ((ip (erc-decimal-to-ip (match-string 1 query)))
+ (port (match-string 2 query))
+ (elt (erc-dcc-member :nick nick :type 'CHAT)))
+ ;; FIXME: A warning really should also be sent if the ip
+ ;; address != the host the dcc sender is on.
+ (erc-display-message
+ nil 'notice proc
+ 'dcc-chat-offered
+ ?n nick ?u login ?h host ?p port)
+ (and (< (string-to-number port) 1025)
+ (erc-display-message
+ nil 'notice proc
+ 'dcc-privileged-port ?p port))
+ (cond (elt
+ ;; XXX: why are we updating ip/port on the existing connection?
+ (setq elt (plist-put (plist-put elt :port port) :ip ip))
+ (erc-display-message
+ nil 'notice proc
+ 'dcc-chat-discarded ?n nick ?u login ?h host))
+ (t
+ (erc-dcc-list-add
+ 'CHAT (format "%s!%s@%s" nick login host)
+ nil proc
+ :ip ip :port port)))
+ (if (eq erc-dcc-chat-request 'auto)
+ (erc-dcc-chat-accept (erc-dcc-member :nick nick :type 'CHAT)
+ proc))))
+ (t
+ (erc-display-message
+ nil '(notice error) proc
+ 'dcc-malformed ?n nick ?u login ?h host ?q query)))))
+
+
+(defvar erc-dcc-entry-data nil
+ "Holds the `erc-dcc-list' entry for this DCC connection.")
+(make-variable-buffer-local 'erc-dcc-entry-data)
+
+;;; SEND handling
+
+(defcustom erc-dcc-block-size 1024
+ "*Block size to use for DCC SEND sessions."
+ :group 'erc-dcc
+ :type 'integer)
+
+(defcustom erc-dcc-pump-bytes nil
+ "*If set to an integer, keep sending until that number of bytes are
+unconfirmed."
+ :group 'erc-dcc
+ :type '(choice (const nil) integer))
+
+(defsubst erc-dcc-get-parent (proc)
+ (plist-get (erc-dcc-member :peer proc) :parent))
+
+(defun erc-dcc-send-block (proc)
+ "Send one block of data.
+PROC is the process-object of the DCC connection. Returns the number of
+bytes sent."
+ (let* ((elt (erc-dcc-member :peer proc))
+ (confirmed-marker (plist-get elt :sent))
+ (sent-marker (plist-get elt :sent)))
+ (with-current-buffer (process-buffer proc)
+ (when erc-verbose-dcc
+ (erc-display-message
+ nil 'notice (erc-dcc-get-parent proc)
+ (format "DCC: Confirmed %d, sent %d, sending block now"
+ (- confirmed-marker (point-min))
+ (- sent-marker (point-min)))))
+ (let* ((end (min (+ sent-marker erc-dcc-block-size)
+ (point-max)))
+ (string (buffer-substring-no-properties sent-marker end)))
+ (when (< sent-marker end)
+ (set-marker sent-marker end)
+ (process-send-string proc string))
+ (length string)))))
+
+(defun erc-dcc-send-filter (proc string)
+ (erc-assert (= (% (length string) 4) 0))
+ (let* ((size (erc-unpack-int (substring string (- (length string) 4))))
+ (elt (erc-dcc-member :peer proc))
+ (parent (plist-get elt :parent))
+ (sent-marker (plist-get elt :sent))
+ (confirmed-marker (plist-get elt :confirmed)))
+ (with-current-buffer (process-buffer proc)
+ (set-marker confirmed-marker (+ (point-min) size))
+ (cond
+ ((and (= confirmed-marker sent-marker)
+ (= confirmed-marker (point-max)))
+ (erc-display-message
+ nil 'notice parent
+ 'dcc-send-finished
+ ?n (plist-get elt :nick)
+ ?f buffer-file-name
+ ?s (number-to-string (- sent-marker (point-min))))
+ (setq erc-dcc-list (delete elt erc-dcc-list))
+ (set-buffer-modified-p nil)
+ (kill-buffer (current-buffer))
+ (delete-process proc))
+ ((<= confirmed-marker sent-marker)
+ (while (and (< (- sent-marker confirmed-marker)
+ (or erc-dcc-pump-bytes
+ erc-dcc-block-size))
+ (> (erc-dcc-send-block proc) 0))))
+ ((> confirmed-marker sent-marker)
+ (erc-display-message
+ nil 'notice parent
+ (format "DCC: Client confirmed too much!"))
+ (delete-process proc))))))
+
+(defcustom erc-dcc-send-connect-hook
+ '((lambda (proc)
+ (erc-display-message
+ nil 'notice (erc-dcc-get-parent proc)
+ (format "DCC: SEND connect from %s"
+ (format-network-address (process-contact proc :remote)))))
+ erc-dcc-send-block)
+ "*Hook run whenever the remote end of a DCC SEND offer connected to your
+listening port."
+ :group 'erc-dcc
+ :type 'hook)
+
+(defun erc-dcc-nick (plist)
+ "Extract the nickname portion of the :nick property value in PLIST."
+ (erc-extract-nick (plist-get plist :nick)))
+
+(defun erc-dcc-send-sentinel (proc event)
+ (let* ((elt (erc-dcc-member :peer proc))
+ (buf (marker-buffer (plist-get elt :sent))))
+ (cond
+ ((string-match "^open from " event)
+ (when elt
+ (with-current-buffer buf
+ (set-process-buffer proc buf)
+ (setq erc-dcc-entry-data elt))
+ (run-hook-with-args 'erc-dcc-send-connect-hook proc))))))
+
+(defun erc-dcc-find-file (file)
+ (with-current-buffer (generate-new-buffer (file-name-nondirectory file))
+ (insert-file-contents-literally file)
+ (setq buffer-file-name file)
+ (current-buffer)))
+
+(defun erc-dcc-file-to-name (file)
+ (with-temp-buffer
+ (insert (file-name-nondirectory file))
+ (subst-char-in-region (point-min) (point-max) ? ?_ t)
+ (buffer-string)))
+
+(defun erc-dcc-send-file (nick file &optional pproc)
+ "Open a socket for incoming connections, and send a CTCP send request to the
+other client."
+ (interactive "sNick: \nfFile: ")
+ (when (null pproc) (if (processp erc-server-process)
+ (setq pproc erc-server-process)
+ (error "Can not find parent process")))
+ (if (featurep 'make-network-process)
+ (let* ((buffer (erc-dcc-find-file file))
+ (size (buffer-size buffer))
+ (start (with-current-buffer buffer
+ (set-marker (make-marker) (point-min))))
+ (sproc (erc-dcc-server "dcc-send"
+ 'erc-dcc-send-filter
+ 'erc-dcc-send-sentinel))
+ (contact (process-contact sproc)))
+ (erc-dcc-list-add
+ 'SEND nick sproc pproc
+ :file file :size size
+ :sent start :confirmed (copy-marker start))
+ (process-send-string
+ pproc (format "PRIVMSG %s :\C-aDCC SEND %s %s %d %d\C-a\n"
+ nick (erc-dcc-file-to-name file)
+ (erc-ip-to-decimal (nth 0 contact))
+ (nth 1 contact)
+ size)))
+ (error "`make-network-process' not supported by your emacs.")))
+
+;;; GET handling
+
+(defvar erc-dcc-byte-count nil)
+(make-variable-buffer-local 'erc-dcc-byte-count)
+
+(defun erc-dcc-get-file (entry file parent-proc)
+ "This function does the work of setting up a transfer from the remote client
+to the local one over a tcp connection. This involves setting up a process
+filter and a process sentinel, and making the connection."
+ (let* ((buffer (generate-new-buffer (file-name-nondirectory file)))
+ proc)
+ (with-current-buffer buffer
+ (fundamental-mode)
+ ;; This is necessary to have the buffer saved as-is in GNU
+ ;; Emacs.
+ ;; XEmacs change: We don't have `set-buffer-multibyte', setting
+ ;; coding system to 'binary below takes care of us.
+ (when (fboundp 'set-buffer-multibyte)
+ (set-buffer-multibyte nil))
+
+ (setq mode-line-process '(":%s")
+ buffer-file-type t
+ buffer-read-only t)
+ (set-visited-file-name file)
+
+ (setq erc-server-process parent-proc
+ erc-dcc-entry-data entry)
+ (setq erc-dcc-byte-count 0)
+ (setq proc
+ (funcall erc-dcc-connect-function
+ "dcc-get" buffer
+ (plist-get entry :ip)
+ (string-to-number (plist-get entry :port))
+ entry))
+ (set-process-buffer proc buffer)
+ ;; The following two lines make saving as-is work under Windows
+ (set-process-coding-system proc 'binary 'binary)
+ (set-buffer-file-coding-system 'binary t)
+
+ (set-process-filter proc 'erc-dcc-get-filter)
+ (set-process-sentinel proc 'erc-dcc-get-sentinel)
+ (setq entry (plist-put entry :start-time (erc-current-time)))
+ (setq entry (plist-put entry :peer proc)))))
+
+(defun erc-dcc-get-filter (proc str)
+ "This is the process filter for transfers from other clients to this one.
+It reads incoming bytes from the network and stores them in the DCC
+buffer, and sends back the replies after each block of data per the DCC
+protocol spec. Well not really. We write back a reply after each read,
+rather than every 1024 byte block, but nobody seems to care."
+ (with-current-buffer (process-buffer proc)
+ (setq buffer-read-only nil) ;; FIXME
+ (goto-char (point-max))
+ (insert (string-make-unibyte str))
+
+ (setq erc-dcc-byte-count (+ (length str) erc-dcc-byte-count))
+ (erc-assert (= erc-dcc-byte-count (1- (point-max))))
+ (and erc-verbose-dcc
+ (erc-display-message
+ nil 'notice erc-server-process
+ 'dcc-get-bytes-received
+ ?f (file-name-nondirectory buffer-file-name)
+ ?b (number-to-string erc-dcc-byte-count)))
+ (cond
+ ((and (> (plist-get erc-dcc-entry-data :size) 0)
+ (> erc-dcc-byte-count (plist-get erc-dcc-entry-data :size)))
+ (erc-display-message
+ nil '(error notice) 'active
+ 'dcc-get-file-too-long
+ ?f (file-name-nondirectory buffer-file-name))
+ (delete-process proc))
+ (t
+ (process-send-string
+ proc (erc-pack-int erc-dcc-byte-count 4))))))
+
+
+(defun erc-dcc-get-sentinel (proc event)
+ "This is the process sentinel for CTCP DCC SEND connections.
+It shuts down the connection and notifies the user that the
+transfer is complete."
+ ;; FIXME, we should look at EVENT, and also check size.
+ (with-current-buffer (process-buffer proc)
+ (delete-process proc)
+ (setq buffer-read-only nil)
+ (setq erc-dcc-list (delete erc-dcc-entry-data erc-dcc-list))
+ (erc-display-message
+ nil 'notice erc-server-process
+ 'dcc-get-complete
+ ?f (file-name-nondirectory buffer-file-name)
+ ?s (number-to-string (buffer-size))
+ ?t (format "%.0f"
+ (erc-time-diff (plist-get erc-dcc-entry-data :start-time)
+ (erc-current-time))))
+ (save-buffer))
+ (kill-buffer (process-buffer proc))
+ (delete-process proc))
+
+;;; CHAT handling
+
+(defcustom erc-dcc-chat-buffer-name-format "DCC-CHAT-%s"
+ "*Format to use for DCC Chat buffer names."
+ :group 'erc-dcc
+ :type 'string)
+
+(defcustom erc-dcc-chat-mode-hook nil
+ "*Hook calls when `erc-dcc-chat-mode' finished setting up the buffer."
+ :group 'erc-dcc
+ :type 'hook)
+
+(defcustom erc-dcc-chat-connect-hook nil
+ ""
+ :group 'erc-dcc
+ :type 'hook)
+
+(defcustom erc-dcc-chat-exit-hook nil
+ ""
+ :group 'erc-dcc
+ :type 'hook)
+
+(defun erc-cmd-CREQ (line &optional force)
+ "Set or get the DCC chat request flag.
+Possible values are: ask, auto, ignore."
+ (when (string-match "^\\s-*\\(auto\\|ask\\|ignore\\)?$" line)
+ (let ((cmd (match-string 1 line)))
+ (if (stringp cmd)
+ (erc-display-message
+ nil 'notice 'active
+ (format "Set DCC Chat requests to %S"
+ (setq erc-dcc-chat-request (intern cmd))))
+ (erc-display-message nil 'notice 'active
+ (format "DCC Chat requests are set to %S"
+ erc-dcc-chat-request)))
+ t)))
+
+(defun erc-cmd-SREQ (line &optional force)
+ "Set or get the DCC send request flag.
+Possible values are: ask, auto, ignore."
+ (when (string-match "^\\s-*\\(auto\\|ask\\|ignore\\)?$" line)
+ (let ((cmd (match-string 1 line)))
+ (if (stringp cmd)
+ (erc-display-message
+ nil 'notice 'active
+ (format "Set DCC Send requests to %S"
+ (setq erc-dcc-send-request (intern cmd))))
+ (erc-display-message nil 'notice 'active
+ (format "DCC Send requests are set to %S"
+ erc-dcc-send-request)))
+ t)))
+
+(defun pcomplete/erc-mode/CREQ ()
+ (pcomplete-here '("auto" "ask" "ignore")))
+(defalias 'pcomplete/erc-mode/SREQ 'pcomplete/erc-mode/CREQ)
+
+(defvar erc-dcc-chat-filter-hook '(erc-dcc-chat-parse-output)
+ "*Hook to run after doing parsing (and possible insertion) of DCC messages.")
+
+(defvar erc-dcc-chat-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "RET") 'erc-send-current-line)
+ (define-key map "\t" 'erc-complete-word)
+ map)
+ "Keymap for `erc-dcc-mode'.")
+
+(defun erc-dcc-chat-mode ()
+ "Major mode for wasting time via DCC chat."
+ (interactive)
+ (kill-all-local-variables)
+ (setq mode-line-process '(":%s")
+ mode-name "DCC-Chat"
+ major-mode 'erc-dcc-chat-mode
+ erc-send-input-line-function 'erc-dcc-chat-send-input-line
+ erc-default-recipients '(dcc))
+ (use-local-map erc-dcc-chat-mode-map)
+ (run-hooks 'erc-dcc-chat-mode-hook))
+
+(defun erc-dcc-chat-send-input-line (recipient line &optional force)
+ "Send LINE to the remote end.
+Argument RECIPIENT should always be the symbol dcc, and force
+is ignored."
+ ;; FIXME: We need to get rid of all force arguments one day!
+ (if (eq recipient 'dcc)
+ (process-send-string
+ (get-buffer-process (current-buffer)) line)
+ (error "erc-dcc-chat-send-input-line in %s" (current-buffer))))
+
+(defun erc-dcc-chat (nick &optional pproc)
+ "Open a socket for incoming connections, and send a chat request to the
+other client."
+ (interactive "sNick: ")
+ (when (null pproc) (if (processp erc-server-process)
+ (setq pproc erc-server-process)
+ (error "Can not find parent process")))
+ (let* ((sproc (erc-dcc-server "dcc-chat-out"
+ 'erc-dcc-chat-filter
+ 'erc-dcc-chat-sentinel))
+ (contact (process-contact sproc)))
+ (erc-dcc-list-add 'OCHAT nick sproc pproc)
+ (process-send-string pproc
+ (format "PRIVMSG %s :\C-aDCC CHAT chat %s %d\C-a\n"
+ nick
+ (erc-ip-to-decimal (nth 0 contact)) (nth 1 contact)))))
+
+(defvar erc-dcc-from)
+(make-variable-buffer-local 'erc-dcc-from)
+
+(defvar erc-dcc-unprocessed-output)
+(make-variable-buffer-local 'erc-dcc-unprocessed-output)
+
+(defun erc-dcc-chat-setup (entry)
+ "Setup a DCC chat buffer, returning the buffer."
+ (let* ((nick (erc-extract-nick (plist-get entry :nick)))
+ (buffer (generate-new-buffer
+ (format erc-dcc-chat-buffer-name-format nick)))
+ (proc (plist-get entry :peer))
+ (parent-proc (plist-get entry :parent)))
+ (erc-setup-buffer buffer)
+ ;; buffer is now the current buffer.
+ (erc-dcc-chat-mode)
+ (setq erc-server-process parent-proc)
+ (setq erc-dcc-from nick)
+ (setq erc-dcc-entry-data entry)
+ (setq erc-dcc-unprocessed-output "")
+ (setq erc-insert-marker (set-marker (make-marker) (point-max)))
+ (erc-display-prompt buffer (point-max))
+ (set-process-buffer proc buffer)
+ (add-hook 'kill-buffer-hook 'erc-dcc-chat-buffer-killed nil t)
+ (run-hook-with-args 'erc-dcc-chat-connect-hook proc)
+ buffer))
+
+(defun erc-dcc-chat-accept (entry parent-proc)
+ "Accept an incoming DCC connection and open a DCC window"
+ (let* ((nick (erc-extract-nick (plist-get entry :nick)))
+ buffer proc)
+ (setq proc
+ (funcall erc-dcc-connect-function
+ "dcc-chat" nil
+ (plist-get entry :ip)
+ (string-to-number (plist-get entry :port))
+ entry))
+ ;; XXX: connected, should we kill the ip/port properties?
+ (setq entry (plist-put entry :peer proc))
+ (setq entry (plist-put entry :parent parent-proc))
+ (set-process-filter proc 'erc-dcc-chat-filter)
+ (set-process-sentinel proc 'erc-dcc-chat-sentinel)
+ (setq buffer (erc-dcc-chat-setup entry))))
+
+(defun erc-dcc-chat-filter (proc str)
+ (let ((orig-buffer (current-buffer)))
+ (unwind-protect
+ (progn
+ (set-buffer (process-buffer proc))
+ (setq erc-dcc-unprocessed-output
+ (concat erc-dcc-unprocessed-output str))
+ (run-hook-with-args 'erc-dcc-chat-filter-hook proc
+ erc-dcc-unprocessed-output))
+ (set-buffer orig-buffer))))
+
+(defun erc-dcc-chat-parse-output (proc str)
+ (save-match-data
+ (let ((posn 0)
+ line)
+ (while (string-match "\n" str posn)
+ (setq line (substring str posn (match-beginning 0)))
+ (setq posn (match-end 0))
+ (erc-display-message
+ nil nil proc
+ 'dcc-chat-privmsg ?n (erc-propertize erc-dcc-from 'face
+ 'erc-nick-default-face) ?m line))
+ (setq erc-dcc-unprocessed-output (substring str posn)))))
+
+(defun erc-dcc-chat-buffer-killed ()
+ (erc-dcc-chat-close "killed buffer"))
+
+(defun erc-dcc-chat-close (&optional event)
+ "Close a DCC chat, removing any associated processes and tidying up
+`erc-dcc-list'"
+ (let ((proc (plist-get erc-dcc-entry-data :peer))
+ (evt (or event "")))
+ (when proc
+ (setq erc-dcc-list (delq erc-dcc-entry-data erc-dcc-list))
+ (run-hook-with-args 'erc-dcc-chat-exit-hook proc)
+ (delete-process proc)
+ (erc-display-message
+ nil 'notice erc-server-process
+ 'dcc-chat-ended ?n erc-dcc-from ?t (current-time-string) ?e evt)
+ (setq erc-dcc-entry-data (plist-put erc-dcc-entry-data :peer nil)))))
+
+(defun erc-dcc-chat-sentinel (proc event)
+ (let ((buf (current-buffer))
+ (elt (erc-dcc-member :peer proc)))
+ ;; the sentinel is also notified when the connection is opened, so don't
+ ;; immediately kill it again
+ ;(message "buf %s elt %S evt %S" buf elt event)
+ (unwind-protect
+ (if (string-match "^open from" event)
+ (erc-dcc-chat-setup elt)
+ (erc-dcc-chat-close event))
+ (set-buffer buf))))
+
+(defun erc-dcc-no-such-nick (proc parsed)
+ "Detect and handle no-such-nick replies from the IRC server."
+ (let* ((elt (erc-dcc-member :nick (second (erc-response.command-args parsed))
+ :parent proc))
+ (peer (plist-get elt :peer)))
+ (when (or (and (processp peer) (not (eq (process-status peer) 'open)))
+ elt)
+ ;; Since we already created an entry before sending the CTCP
+ ;; message, we now remove it, if it doesn't point to a process
+ ;; which is already open.
+ (setq erc-dcc-list (delq elt erc-dcc-list))
+ (if (processp peer) (delete-process peer)))
+ nil))
+
+(add-hook 'erc-server-401-functions 'erc-dcc-no-such-nick)
+
+(provide 'erc-dcc)
+
+;;; erc-dcc.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;; arch-tag: cda5a6b3-c510-4dbe-b699-84cccfa04edb
diff --git a/lisp/erc/erc-ezbounce.el b/lisp/erc/erc-ezbounce.el
new file mode 100644
index 00000000000..59e80b60b8d
--- /dev/null
+++ b/lisp/erc/erc-ezbounce.el
@@ -0,0 +1,180 @@
+;;; erc-ezbounce.el --- Handle EZBounce bouncer commands
+
+;; Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+;; Author: Andreas Fuchs <asf@void.at>
+;; Keywords: comm
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'erc)
+(eval-when-compile (require 'cl))
+
+(defgroup erc-ezbounce nil
+ "Interface to the EZBounce IRC bouncer (a virtual IRC server)"
+ :group 'erc)
+
+(defcustom erc-ezb-regexp "^ezbounce!srv$"
+ "Regexp used by the EZBouncer to identify itself to the user."
+ :group 'erc-ezbounce
+ :type 'string)
+
+(defcustom erc-ezb-login-alist '()
+ "Alist of logins suitable for the server we're connecting to.
+
+The alist's format is as follows:
+
+ (((server . port) . (username . password))
+ ((server . port) . (username . password))
+ ...)"
+ :group 'erc-ezbounce
+ :type '(repeat
+ (cons (cons :tag "Server"
+ string
+ string)
+ (cons :tag "Login"
+ string
+ string))))
+
+(defvar erc-ezb-action-alist '(("^\\[awaiting login/pass command\\]$" . erc-ezb-identify)
+ ("^\\[use /quote CONN <server> to connect\\]$" . erc-ezb-select)
+ ("^ID +IRC NICK +TO +TIME$" . erc-ezb-init-session-list)
+ ("^$" . erc-ezb-end-of-session-list)
+ (".*" . erc-ezb-add-session))
+ "Alist of actions to take on NOTICEs from EZBounce.")
+
+
+(defvar erc-ezb-session-list '()
+ "List of detached EZBounce sessions.")
+(make-variable-buffer-local 'erc-ezb-session-list)
+
+(defvar erc-ezb-inside-session-listing nil
+ "Indicate whether current notices are expected to be EZB session listings.")
+
+;;;###autoload
+(defun erc-cmd-ezb (line &optional force)
+ "Send EZB commands to the EZBouncer verbatim."
+ (erc-server-send (concat "EZB " line)))
+(put 'erc-cmd-EZB 'do-not-parse-args t)
+
+;;;###autoload
+(defun erc-ezb-get-login (server port)
+ "Return an appropriate EZBounce login for SERVER and PORT.
+Look up entries in `erc-ezb-login-alist'. If the username or password
+in the alist is `nil', prompt for the appropriate values."
+ (let ((login (cdr (assoc (cons server port) erc-ezb-login-alist))))
+ (when login
+ (let ((username (car login))
+ (password (cdr login)))
+ (when (null username)
+ (setq username (read-from-minibuffer (format "EZBounce user name for %s:%s: " server port))))
+ (when (null password)
+ (setq password (read-passwd (format "EZBounce password for %s:%s: " server port))))
+ (cons username password)))))
+
+;;;###autoload
+(defun erc-ezb-lookup-action (message)
+ (let ((function-alist erc-ezb-action-alist)
+ found)
+ (while (and (not found)
+ function-alist)
+ (let ((regexp (caar function-alist))
+ (function (cdar function-alist)))
+ (when (string-match regexp message)
+ (setq found function))
+ (setq function-alist (cdr function-alist))))
+ found))
+
+;;;###autoload
+(defun erc-ezb-notice-autodetect (proc parsed)
+ "React on an EZBounce NOTICE request."
+ (let* ((sender (erc-response.sender parsed))
+ (message (erc-response.contents parsed))
+ (function (erc-ezb-lookup-action message)))
+ (when (and (string-match erc-ezb-regexp sender)
+ function)
+ (funcall function message)))
+ nil)
+
+;;;###autoload
+(defun erc-ezb-identify (message)
+ "Identify to the EZBouncer server."
+ (let ((login (erc-ezb-get-login erc-session-server (erc-port-to-string erc-session-port))))
+ (unless (null login)
+ (let ((username (car login))
+ (pass (cdr login)))
+ (erc-server-send (concat "LOGIN " username " " pass))))))
+
+;;;###autoload
+(defun erc-ezb-init-session-list (message)
+ "Reset the EZBounce session list to NIL."
+ (setq erc-ezb-session-list nil)
+ (setq erc-ezb-inside-session-listing t))
+
+;;;###autoload
+(defun erc-ezb-end-of-session-list (message)
+ "Indicate the end of the EZBounce session listing."
+ (setq erc-ezb-inside-session-listing nil))
+
+;;;###autoload
+(defun erc-ezb-add-session (message)
+ "Add an EZBounce session to the session list."
+ (when (and erc-ezb-inside-session-listing
+ (string-match "^\\([^ ]+\\) +\\([^ ]+\\) +\\([^ ]+\\) +\\([^ ]+\\)$" message))
+ (let ((id (match-string 1 message))
+ (nick (match-string 2 message))
+ (to (match-string 3 message)))
+ (add-to-list 'erc-ezb-session-list (list id nick to)))))
+
+;;;###autoload
+(defun erc-ezb-select (message)
+ "Select an IRC server to use by EZBounce, in ERC style."
+ (unless (and erc-ezb-session-list
+ (erc-ezb-select-session))
+ (let* ((server (read-from-minibuffer
+ "IRC server: " "" nil nil 'erc-server-history-list))
+ (port
+ (erc-string-to-port
+ (read-from-minibuffer "IRC port: "
+ (erc-port-to-string "6667")))))
+ (erc-server-send (format "CONN %s %s" server port)))))
+
+
+;;;###autoload
+(defun erc-ezb-select-session ()
+ "Select a detached EZBounce session."
+ (let ((session (completing-read "Existing Session (RET to enter a new one): "
+ erc-ezb-session-list)))
+ (if (string= session "")
+ nil
+ (erc-server-send (format "REATTACH %s" session)))))
+
+
+;;;###autoload
+(defun erc-ezb-initialize ()
+ "Add EZBouncer convenience functions to ERC."
+ (add-hook 'erc-server-NOTICE-functions 'erc-ezb-notice-autodetect))
+
+(provide 'erc-ezbounce)
+
+;; arch-tag: e972aa7b-a9f4-4d16-a489-074ec7a1002e
+;;; erc-ezbounce.el ends here
diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el
new file mode 100644
index 00000000000..f945d838c2a
--- /dev/null
+++ b/lisp/erc/erc-fill.el
@@ -0,0 +1,197 @@
+;;; erc-fill.el --- Filling IRC messages in various ways
+
+;; Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Andreas Fuchs <asf@void.at>
+;; Mario Lang <mlang@delysid.org>
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcFilling
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This package implements filling of messages sent and received. Use
+;; `erc-fill-mode' to switch it on. Customize `erc-fill-function' to
+;; change the style.
+
+;;; Code:
+
+(require 'erc)
+(require 'erc-stamp); for the timestamp stuff
+
+(defgroup erc-fill nil
+ "Filling means to reformat long lines in different ways."
+ :group 'erc)
+
+;;;###autoload (autoload 'erc-fill-mode "erc-fill" nil t)
+(erc-define-minor-mode erc-fill-mode
+ "Toggle ERC fill mode.
+With numeric arg, turn ERC fill mode on if and only if arg is
+positive. In ERC fill mode, messages in the channel buffers are
+filled."
+ nil nil nil
+ :global t :group 'erc-fill
+ (if erc-fill-mode
+ (erc-fill-enable)
+ (erc-fill-disable)))
+
+(defun erc-fill-enable ()
+ "Setup hooks for `erc-fill-mode'."
+ (interactive)
+ (add-hook 'erc-insert-modify-hook 'erc-fill)
+ (add-hook 'erc-send-modify-hook 'erc-fill))
+
+(defun erc-fill-disable ()
+ "Cleanup hooks, disable `erc-fill-mode'."
+ (interactive)
+ (remove-hook 'erc-insert-modify-hook 'erc-fill)
+ (remove-hook 'erc-send-modify-hook 'erc-fill))
+
+(defcustom erc-fill-prefix nil
+ "Values used as `fill-prefix' for `erc-fill-variable'.
+nil means fill with space, a string means fill with this string."
+ :group 'erc-fill
+ :type '(choice (const nil) string))
+
+(defcustom erc-fill-function 'erc-fill-variable
+ "Function to use for filling messages.
+
+Variable Filling with an `erc-fill-prefix' of nil:
+
+<shortnick> this is a very very very long message with no
+ meaning at all
+
+Variable Filling with an `erc-fill-prefix' of four spaces:
+
+<shortnick> this is a very very very long message with no
+ meaning at all
+
+Static Filling with `erc-fill-static-center' of 27:
+
+ <shortnick> foo bar baz
+ <a-very-long-nick> foo bar baz quuuuux
+ <shortnick> this is a very very very long message with no
+ meaning at all
+
+These two styles are implemented using `erc-fill-variable' and
+`erc-fill-static'. You can, of course, define your own filling
+function. Narrowing to the region in question is in effect while your
+function is called."
+ :group 'erc-fill
+ :type '(choice (const :tag "Variable Filling" erc-fill-variable)
+ (const :tag "Static Filling" erc-fill-static)
+ function))
+
+(defcustom erc-fill-static-center 27
+ "Column around which all statically filled messages will be
+centered. This column denotes the point where the ' ' character
+between <nickname> and the entered text will be put, thus aligning
+nick names right and text left."
+ :group 'erc-fill
+ :type 'integer)
+
+(defcustom erc-fill-variable-maximum-indentation 17
+ "If we indent a line after a long nick, don't indent more then this
+characters. Set to nil to disable."
+ :group 'erc-fill
+ :type 'integer)
+
+(defcustom erc-fill-column 78
+ "The column at which a filled paragraph is broken."
+ :group 'erc-fill
+ :type 'integer)
+
+;;;###autoload
+(defun erc-fill ()
+ "Fill a region using the function referenced in `erc-fill-function'.
+You can put this on `erc-insert-modify-hook' and/or `erc-send-modify-hook'."
+ (unless (erc-string-invisible-p (buffer-substring (point-min) (point-max)))
+ (when erc-fill-function
+ (funcall erc-fill-function))))
+
+(defun erc-fill-static ()
+ "Fills a text such that messages start at column `erc-fill-static-center'."
+ (save-match-data
+ (goto-char (point-min))
+ (looking-at "^\\(\\S-+\\)")
+ (let ((nick (match-string 1)))
+ (let ((fill-column (- erc-fill-column (erc-timestamp-offset)))
+ (fill-prefix (make-string erc-fill-static-center 32)))
+ (insert (make-string (max 0 (- erc-fill-static-center
+ (length nick) 1))
+ 32))
+ (erc-fill-regarding-timestamp))
+ (erc-restore-text-properties))))
+
+(defun erc-fill-variable ()
+ "Fill from `point-min' to `point-max'."
+ (let ((fill-prefix erc-fill-prefix)
+ (fill-column (or erc-fill-column fill-column)))
+ (goto-char (point-min))
+ (if fill-prefix
+ (let ((first-line-offset (make-string (erc-timestamp-offset) 32)))
+ (insert first-line-offset)
+ (fill-region (point-min) (point-max) t t)
+ (goto-char (point-min))
+ (delete-char (length first-line-offset)))
+ (save-match-data
+ (let* ((nickp (looking-at "^\\(\\S-+\\)"))
+ (nick (if nickp
+ (match-string 1)
+ ""))
+ (fill-column (- erc-fill-column (erc-timestamp-offset)))
+ (fill-prefix (make-string (min (+ 1 (length nick))
+ (- fill-column 1)
+ (or erc-fill-variable-maximum-indentation
+ fill-column))
+ 32)))
+ (erc-fill-regarding-timestamp))))
+ (erc-restore-text-properties)))
+
+(defun erc-fill-regarding-timestamp ()
+ "Fills a text such that messages start at column `erc-fill-static-center'."
+ (fill-region (point-min) (point-max) t t)
+ (goto-char (point-min))
+ (forward-line)
+ (indent-rigidly (point) (point-max) (erc-timestamp-offset)))
+
+(defun erc-timestamp-offset ()
+ "Get length of timestamp if inserted left."
+ (if (and (boundp 'erc-timestamp-format)
+ erc-timestamp-format
+ (eq erc-insert-timestamp-function 'erc-insert-timestamp-left)
+ (not erc-hide-timestamps))
+ (length (format-time-string erc-timestamp-format))
+ 0))
+
+(defun erc-restore-text-properties ()
+ "Restore the property 'erc-parsed for the region."
+ (let* ((parsed-posn (text-property-not-all (point-min) (point-max)
+ 'erc-parsed nil))
+ (parsed-prop (when parsed-posn
+ (get-text-property parsed-posn 'erc-parsed))))
+ (put-text-property (point-min) (point-max) 'erc-parsed parsed-prop)))
+
+(provide 'erc-fill)
+
+;;; erc-fill.el ends here
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;; arch-tag: 89224581-c2c2-4e26-92e5-e3a390dc516a
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
new file mode 100644
index 00000000000..dbbdaacc141
--- /dev/null
+++ b/lisp/erc/erc-goodies.el
@@ -0,0 +1,522 @@
+;; erc-goodies.el --- Collection of ERC modules
+
+;; Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+
+;; Most code is taken verbatim from erc.el, see there for the original
+;; authors.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This provides some small but still useful modes for ERC.
+
+;;; Code:
+
+(require 'erc)
+
+;; Imenu Autoload
+(add-hook 'erc-mode-hook
+ (lambda ()
+ (setq imenu-create-index-function 'erc-create-imenu-index)))
+(autoload 'erc-create-imenu-index "erc-imenu" "Imenu index creation function")
+
+;;; Automatically scroll to bottom
+(defcustom erc-input-line-position nil
+ "Specify where to position the input line when using `erc-scroll-to-bottom'.
+
+This should be an integer specifying the line of the buffer on which
+the input line should stay. A value of \"-1\" would keep the input
+line positioned on the last line in the buffer. This is passed as an
+argument to `recenter'."
+ :group 'erc-display
+ :type '(choice integer (const nil)))
+
+(define-erc-module scrolltobottom nil
+ "This mode causes the prompt to stay at the end of the window.
+You have to activate or deactivate it in already created windows
+separately."
+ ((add-hook 'erc-mode-hook 'erc-add-scroll-to-bottom))
+ ((remove-hook 'erc-mode-hook 'erc-add-scroll-to-bottom)))
+
+(defun erc-add-scroll-to-bottom ()
+ "A hook function for `erc-mode-hook' to recenter output at bottom of window.
+
+If you find that ERC hangs when using this function, try customizing
+the value of `erc-input-line-position'.
+
+This works whenever scrolling happens, so it's added to
+`window-scroll-functions' rather than `erc-insert-post-hook'."
+ ;;(make-local-hook 'window-scroll-functions)
+ (add-hook 'window-scroll-functions 'erc-scroll-to-bottom nil t))
+
+(defun erc-scroll-to-bottom (window display-start)
+ "Recenter WINDOW so that `point' is on the last line.
+
+This is added to `window-scroll-functions' by `erc-add-scroll-to-bottom'.
+
+You can control which line is recentered to by customizing the
+variable `erc-input-line-position'.
+
+DISPLAY-START is ignored."
+ (if (and window (window-live-p window))
+ ;; Temporarily bind resize-mini-windows to nil so that users who have it
+ ;; set to a non-nil value will not suffer from premature minibuffer
+ ;; shrinkage due to the below recenter call. I have no idea why this
+ ;; works, but it solves the problem, and has no negative side effects.
+ ;; (Fran Litterio, 2003/01/07)
+ (let ((resize-mini-windows nil))
+ (save-selected-window
+ (select-window window)
+ (save-restriction
+ (widen)
+ (when (and erc-insert-marker
+ ;; we're editing a line. Scroll.
+ (> (point) erc-insert-marker))
+ (save-excursion
+ (goto-char (point-max))
+ (recenter (or erc-input-line-position -1))
+ (sit-for 0))))))))
+
+;;; Make read only
+(define-erc-module readonly nil
+ "This mode causes all inserted text to be read-only."
+ ((add-hook 'erc-insert-post-hook 'erc-make-read-only)
+ (add-hook 'erc-send-post-hook 'erc-make-read-only))
+ ((remove-hook 'erc-insert-post-hook 'erc-make-read-only)
+ (remove-hook 'erc-send-post-hook 'erc-make-read-only)))
+
+(defun erc-make-read-only ()
+ "Make all the text in the current buffer read-only.
+Put this function on `erc-insert-post-hook' and/or `erc-send-post-hook'."
+ (put-text-property (point-min) (point-max) 'read-only t)
+ (put-text-property (point-min) (point-max) 'front-sticky t)
+ (put-text-property (point-min) (point-max) 'rear-nonsticky t))
+
+;; Distingush non-commands
+(defvar erc-noncommands-list '(erc-cmd-ME
+ erc-cmd-COUNTRY
+ erc-cmd-SV
+ erc-cmd-SM
+ erc-cmd-SMV
+ erc-cmd-LASTLOG)
+ "List of commands that are aliases for CTCP ACTION or for erc messages.
+
+If a command's function symbol is in this list, the typed command
+does not appear in the ERC buffer after the user presses ENTER.")
+
+(define-erc-module noncommands nil
+ "This mode distinguishies non-commands.
+Commands listed in `erc-insert-this' know how to display
+themselves."
+ ((add-hook 'erc-send-pre-hook 'erc-send-distinguish-noncommands))
+ ((remove-hook 'erc-send-pre-hook 'erc-send-distinguish-noncommands)))
+
+(defun erc-send-distinguish-noncommands (str)
+ "If STR is an ERC non-command, set `erc-insert-this' to nil."
+ (let* ((command (erc-extract-command-from-line str))
+ (cmd-fun (and command
+ (car command))))
+ (when (and cmd-fun
+ (not (string-match "\n.+$" str))
+ (memq cmd-fun erc-noncommands-list))
+ (setq erc-insert-this nil))))
+
+;;; IRC control character processing.
+(defgroup erc-control-characters nil
+ "Dealing with control characters"
+ :group 'erc)
+
+(defcustom erc-interpret-controls-p t
+ "*If non-nil, display IRC colours and other highlighting effects.
+
+If this is set to the symbol `remove', ERC removes all IRC colors and
+highlighting effects. When this variable is non-nil, it can cause Emacs to run
+slowly on systems lacking sufficient CPU speed. In chatty channels, or in an
+emergency (message flood) it can be turned off to save processing time. See
+`erc-toggle-interpret-controls'."
+ :group 'erc-control-characters
+ :type '(choice (const :tag "Highlight control characters" t)
+ (const :tag "Remove control characters" remove)
+ (const :tag "Display raw control characters" nil)))
+
+(defcustom erc-interpret-mirc-color nil
+ "*If non-nil, erc will interpret mIRC color codes."
+ :group 'erc-control-characters
+ :type 'boolean)
+
+(defcustom erc-beep-p nil
+ "Beep if C-g is in the server message.
+The value `erc-interpret-controls-p' must also be t for this to work."
+ :group 'erc-control-characters
+ :type 'boolean)
+
+(defface erc-bold-face '((t (:bold t)))
+ "ERC bold face."
+ :group 'erc-faces)
+(defface erc-inverse-face
+ '((t (:foreground "White" :background "Black")))
+ "ERC inverse face."
+ :group 'erc-faces)
+(defface erc-underline-face '((t (:underline t)))
+ "ERC underline face."
+ :group 'erc-faces)
+
+(defface fg:erc-color-face0 '((t (:foreground "White")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face1 '((t (:foreground "black")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face2 '((t (:foreground "blue4")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face3 '((t (:foreground "green4")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face4 '((t (:foreground "red")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face5 '((t (:foreground "brown")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face6 '((t (:foreground "purple")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face7 '((t (:foreground "orange")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face8 '((t (:foreground "yellow")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face9 '((t (:foreground "green")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face10 '((t (:foreground "lightblue1")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face11 '((t (:foreground "cyan")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face12 '((t (:foreground "blue")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face13 '((t (:foreground "deeppink")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face14 '((t (:foreground "gray50")))
+ "ERC face."
+ :group 'erc-faces)
+(defface fg:erc-color-face15 '((t (:foreground "gray90")))
+ "ERC face."
+ :group 'erc-faces)
+
+(defface bg:erc-color-face0 '((t (:background "White")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face1 '((t (:background "black")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face2 '((t (:background "blue4")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face3 '((t (:background "green4")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face4 '((t (:background "red")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face5 '((t (:background "brown")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face6 '((t (:background "purple")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face7 '((t (:background "orange")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face8 '((t (:background "yellow")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face9 '((t (:background "green")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face10 '((t (:background "lightblue1")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face11 '((t (:background "cyan")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face12 '((t (:background "blue")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face13 '((t (:background "deeppink")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face14 '((t (:background "gray50")))
+ "ERC face."
+ :group 'erc-faces)
+(defface bg:erc-color-face15 '((t (:background "gray90")))
+ "ERC face."
+ :group 'erc-faces)
+
+(defun erc-get-bg-color-face (n)
+ "Fetches the right face for background color N (0-15)."
+ (if (stringp n) (setq n (string-to-number n)))
+ (if (not (numberp n))
+ (progn
+ (message "erc-get-bg-color-face: n is NaN: %S" n)
+ (beep)
+ 'default)
+ (when (> n 16)
+ (erc-log (format " Wrong color: %s" n))
+ (setq n (mod n 16)))
+ (cond
+ ((and (>= n 0) (< n 16))
+ (intern (concat "bg:erc-color-face" (number-to-string n))))
+ (t (erc-log (format " Wrong color: %s" n)) 'default))))
+
+(defun erc-get-fg-color-face (n)
+ "Fetches the right face for foreground color N (0-15)."
+ (if (stringp n) (setq n (string-to-number n)))
+ (if (not (numberp n))
+ (progn
+ (message "erc-get-fg-color-face: n is NaN: %S" n)
+ (beep)
+ 'default)
+ (when (> n 16)
+ (erc-log (format " Wrong color: %s" n))
+ (setq n (mod n 16)))
+ (cond
+ ((and (>= n 0) (< n 16))
+ (intern (concat "fg:erc-color-face" (number-to-string n))))
+ (t (erc-log (format " Wrong color: %s" n)) 'default))))
+
+(define-erc-module irccontrols nil
+ "This mode enables the interpretation of IRC control chars."
+ ((add-hook 'erc-insert-modify-hook 'erc-controls-highlight)
+ (add-hook 'erc-send-modify-hook 'erc-controls-highlight))
+ ((remove-hook 'erc-insert-modify-hook 'erc-controls-highlight)
+ (remove-hook 'erc-send-modify-hook 'erc-controls-highlight)))
+
+(defun erc-controls-interpret (str)
+ "Return a copy of STR after dealing with IRC control characters.
+See `erc-interpret-controls-p' and `erc-interpret-mirc-color' for options."
+ (when str
+ (let ((s str))
+ (cond ((eq erc-interpret-controls-p 'remove)
+ (erc-controls-strip s))
+ (erc-interpret-controls-p
+ (let ((boldp nil)
+ (inversep nil)
+ (underlinep nil)
+ (fg nil)
+ (bg nil))
+ (while (string-match erc-controls-highlight-regexp s)
+ (let ((control (match-string 1 s))
+ (fg-color (match-string 2 s))
+ (bg-color (match-string 4 s))
+ (start (match-beginning 0))
+ (end (+ (match-beginning 0)
+ (length (match-string 5 s)))))
+ (setq s (erc-replace-match-subexpression-in-string
+ "" s control 1 start))
+ (cond ((and erc-interpret-mirc-color (or fg-color bg-color))
+ (setq fg fg-color)
+ (setq bg bg-color))
+ ((string= control "\C-b")
+ (setq boldp (not boldp)))
+ ((string= control "\C-v")
+ (setq inversep (not inversep)))
+ ((string= control "\C-_")
+ (setq underlinep (not underlinep)))
+ ((string= control "\C-c")
+ (setq fg nil
+ bg nil))
+ ((string= control "\C-g")
+ (when erc-beep-p
+ (ding)))
+ ((string= control "\C-o")
+ (setq boldp nil
+ inversep nil
+ underlinep nil
+ fg nil
+ bg nil))
+ (t nil))
+ (erc-controls-propertize
+ start end boldp inversep underlinep fg bg s)))
+ s))
+ (t s)))))
+
+(defun erc-controls-strip (str)
+ "Return a copy of STR with all IRC control characters removed."
+ (when str
+ (let ((s str))
+ (while (string-match erc-controls-remove-regexp s)
+ (setq s (replace-match "" nil nil s)))
+ s)))
+
+(defvar erc-controls-remove-regexp
+ "\C-b\\|\C-_\\|\C-v\\|\C-g\\|\C-o\\|\C-c[0-9]?[0-9]?\\(,[0-9][0-9]?\\)?"
+ "Regular expression which matches control characters to remove.")
+
+(defvar erc-controls-highlight-regexp
+ (concat "\\(\C-b\\|\C-v\\|\C-_\\|\C-g\\|\C-o\\|"
+ "\C-c\\([0-9][0-9]?\\)?\\(,\\([0-9][0-9]?\\)\\)?\\)"
+ "\\([^\C-b\C-v\C-_\C-c\C-g\C-o\n]*\\)")
+ "Regular expression which matches control chars and the text to highlight.")
+
+(defun erc-controls-highlight ()
+ "Highlight IRC control chars in the buffer.
+This is useful for `erc-insert-modify-hook' and
+`erc-send-modify-hook'. Also see `erc-interpret-controls-p' and
+`erc-interpret-mirc-color'."
+ (goto-char (point-min))
+ (cond ((eq erc-interpret-controls-p 'remove)
+ (while (re-search-forward erc-controls-remove-regexp nil t)
+ (replace-match "")))
+ (erc-interpret-controls-p
+ (let ((boldp nil)
+ (inversep nil)
+ (underlinep nil)
+ (fg nil)
+ (bg nil))
+ (while (re-search-forward erc-controls-highlight-regexp nil t)
+ (let ((control (match-string 1))
+ (fg-color (match-string 2))
+ (bg-color (match-string 4))
+ (start (match-beginning 0))
+ (end (+ (match-beginning 0) (length (match-string 5)))))
+ (replace-match "" nil nil nil 1)
+ (cond ((and erc-interpret-mirc-color (or fg-color bg-color))
+ (setq fg fg-color)
+ (setq bg bg-color))
+ ((string= control "\C-b")
+ (setq boldp (not boldp)))
+ ((string= control "\C-v")
+ (setq inversep (not inversep)))
+ ((string= control "\C-_")
+ (setq underlinep (not underlinep)))
+ ((string= control "\C-c")
+ (setq fg nil
+ bg nil))
+ ((string= control "\C-g")
+ (when erc-beep-p
+ (ding)))
+ ((string= control "\C-o")
+ (setq boldp nil
+ inversep nil
+ underlinep nil
+ fg nil
+ bg nil))
+ (t nil))
+ (erc-controls-propertize start end
+ boldp inversep underlinep fg bg)))))
+ (t nil)))
+
+(defun erc-controls-propertize (from to boldp inversep underlinep fg bg
+ &optional str)
+ "Prepend properties from IRC control characters between FROM and TO.
+If optional argument STR is provided, apply to STR, otherwise prepend properties
+to a region in the current buffer."
+ (font-lock-prepend-text-property
+ from
+ to
+ 'face
+ (append (if boldp
+ '(erc-bold-face)
+ nil)
+ (if inversep
+ '(erc-inverse-face)
+ nil)
+ (if underlinep
+ '(erc-underline-face)
+ nil)
+ (if fg
+ (list (erc-get-fg-color-face fg))
+ nil)
+ (if bg
+ (list (erc-get-bg-color-face bg))
+ nil))
+ str)
+ str)
+
+(defun erc-toggle-interpret-controls (&optional arg)
+ "Toggle interpretation of control sequences in messages.
+
+If ARG is positive, interpretation is turned on.
+Else interpretation is turned off."
+ (interactive "P")
+ (cond ((and (numberp arg) (> arg 0))
+ (setq erc-interpret-controls-p t))
+ (arg (setq erc-interpret-controls-p nil))
+ (t (setq erc-interpret-controls-p (not erc-interpret-controls-p))))
+ (message "ERC color interpretation %s"
+ (if erc-interpret-controls-p "ON" "OFF")))
+
+;; Smiley
+(define-erc-module smiley nil
+ "This mode translates text-smileys such as :-) into pictures.
+This requires the function `smiley-region', which is defined in
+smiley.el, which is part of Gnus."
+ ((add-hook 'erc-insert-modify-hook 'erc-smiley)
+ (add-hook 'erc-send-modify-hook 'erc-smiley))
+ ((remove-hook 'erc-insert-modify-hook 'erc-smiley)
+ (remove-hook 'erc-send-modify-hook 'erc-smiley)))
+
+(defun erc-smiley ()
+ "Smilify a region.
+This function should be used with `erc-insert-modify-hook'."
+ (when (fboundp 'smiley-region)
+ (smiley-region (point-min) (point-max))))
+
+;; Unmorse
+(define-erc-module unmorse nil
+ "This mode causes morse code in the current channel to be unmorsed."
+ ((add-hook 'erc-insert-modify-hook 'erc-unmorse))
+ ((remove-hook 'erc-insert-modify-hook 'erc-unmorse)))
+
+(defun erc-unmorse ()
+ "Unmorse some text.
+Add this to `erc-insert-modify-hook' if you happen to be on a
+channel that has weird people talking in morse to each other.
+
+See also `unmorse-region'."
+ (goto-char (point-min))
+ (when (re-search-forward "[.-]+\\([.-]+[/ ]\\)+[.-]+" nil t)
+ (unmorse-region (match-beginning 0) (match-end 0))))
+
+;;; erc-occur
+(defun erc-occur (string &optional proc)
+ "Search for STRING in all buffers related to current server.
+If called interactively and prefix argument is given, search on all connected
+servers. If called from a program, PROC specifies the server process."
+ (interactive
+ (list (read-string "Search for: ")
+ (if current-prefix-arg
+ nil erc-server-process)))
+ (if (fboundp 'multi-occur)
+ (multi-occur (erc-buffer-list nil proc) string)
+ (error "`multi-occur' is not defined as a function")))
+
+(provide 'erc-goodies)
+
+;; arch-tag: d987ae26-9e28-4c72-9596-e617309fb582
+;;; erc-goodies.el ends here
diff --git a/lisp/erc/erc-ibuffer.el b/lisp/erc/erc-ibuffer.el
new file mode 100644
index 00000000000..63ec7bcecb0
--- /dev/null
+++ b/lisp/erc/erc-ibuffer.el
@@ -0,0 +1,184 @@
+;;; erc-ibuffer.el --- ibuffer integration with ERC
+
+;; Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Keywords: comm
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcIbuffer
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file contains code related to Ibuffer and ERC. Totally alpha,
+;; needs work. Usage: Type / C-e C-h when in Ibuffer-mode to see new
+;; limiting commands
+
+;;; Code:
+
+(require 'ibuffer)
+(require 'erc)
+
+(defgroup erc-ibuffer nil
+ "The Ibuffer group for ERC."
+ :group 'erc)
+
+(defcustom erc-ibuffer-keyword-char ?k
+ "Char used to indicate a channel which had keyword traffic lately (hidden)."
+ :group 'erc-ibuffer
+ :type 'character)
+(defcustom erc-ibuffer-pal-char ?p
+ "Char used to indicate a channel which had pal traffic lately (hidden)."
+ :group 'erc-ibuffer
+ :type 'character)
+(defcustom erc-ibuffer-fool-char ?f
+ "Char used to indicate a channel which had fool traffic lately (hidden)."
+ :group 'erc-ibuffer
+ :type 'character)
+(defcustom erc-ibuffer-dangerous-host-char ?d
+ "Char used to indicate a channel which had dangerous-host traffic lately (hidden)."
+ :group 'erc-ibuffer
+ :type 'character)
+
+(ibuffer-define-limiter erc-server
+ (:documentation
+ "Toggle current view to buffers which are related to ERC servers."
+ :description "erc servers"
+ :reader
+ (let ((regexp (read-from-minibuffer "Limit by server (regexp) (RET for all): ")))
+ (if (string= regexp "")
+ ".*"
+ regexp)))
+ (with-current-buffer buf
+ (and (eq major-mode 'erc-mode)
+ (string-match qualifier (or erc-server-announced-name
+ erc-session-server)))))
+
+(ibuffer-define-column erc-modified (:name "M")
+ (if (and (boundp 'erc-track-mode)
+ erc-track-mode)
+ (let ((entry (assq (current-buffer) erc-modified-channels-alist)))
+ (if entry
+ (if (> (length entry) 1)
+ (cond ((eq 'pal (nth 1 entry))
+ (string erc-ibuffer-pal-char))
+ ((eq 'fool (nth 1 entry))
+ (string erc-ibuffer-fool-char))
+ ((eq 'keyword (nth 1 entry))
+ (string erc-ibuffer-keyword-char))
+ ((eq 'dangerous-host (nth 1 entry))
+ (string erc-ibuffer-dangerous-host-char))
+ (t "$"))
+ (string ibuffer-modified-char))
+ " "))
+ " "))
+
+(ibuffer-define-column erc-server-name (:name "Server")
+ (if (and (boundp 'erc-server-process) (processp erc-server-process))
+ (with-current-buffer (process-buffer erc-server-process)
+ (or erc-server-announced-name erc-session-server))
+ ""))
+
+(ibuffer-define-column erc-target (:name "Target")
+ (if (eq major-mode 'erc-mode)
+ (cond ((and (boundp 'erc-server-process) (processp erc-server-process)
+ (eq (current-buffer) (process-buffer erc-server-process)))
+ (concat "Server " erc-session-server ":"
+ (erc-port-to-string erc-session-port)))
+ ((erc-channel-p (erc-default-target))
+ (concat (erc-default-target)))
+ ((erc-default-target)
+ (concat "Query: " (erc-default-target)))
+ (t "(parted)"))
+ (buffer-name)))
+
+(ibuffer-define-column erc-topic (:name "Topic")
+ (if (and (eq major-mode 'erc-mode)
+ erc-channel-topic)
+ (erc-controls-interpret erc-channel-topic)
+ ""))
+
+(ibuffer-define-column
+ erc-members (:name "Users")
+ (if (and (eq major-mode 'erc-mode)
+ (boundp 'erc-channel-users)
+ (hash-table-p erc-channel-users)
+ (> (hash-table-size erc-channel-users) 0))
+ (number-to-string (hash-table-size erc-channel-users))
+ ""))
+
+(ibuffer-define-column erc-away (:name "A")
+ (if (and (boundp 'erc-server-process)
+ (processp erc-server-process)
+ (with-current-buffer (process-buffer erc-server-process)
+ erc-away))
+ "A"
+ " "))
+
+(ibuffer-define-column
+ erc-op (:name "O")
+ (if (and (eq major-mode 'erc-mode)
+ (erc-channel-user-op-p (erc-current-nick)))
+ "@"
+ " "))
+
+(ibuffer-define-column erc-voice (:name "V")
+ (if (and (eq major-mode 'erc-mode)
+ (erc-channel-user-voice-p (erc-current-nick)))
+ "+"
+ " "))
+
+(ibuffer-define-column erc-channel-modes (:name "Mode")
+ (if (and (eq major-mode 'erc-mode)
+ (or (> (length erc-channel-modes) 0)
+ erc-channel-user-limit))
+ (concat (apply 'concat
+ "(+" erc-channel-modes)
+ (if erc-channel-user-limit
+ (format "l %d" erc-channel-user-limit)
+ "")
+ ")")
+ (if (not (eq major-mode 'erc-mode))
+ mode-name
+ "")))
+
+(ibuffer-define-column erc-nick (:name "Nick")
+ (if (eq major-mode 'erc-mode)
+ (erc-current-nick)
+ ""))
+
+(defvar erc-ibuffer-formats '((mark erc-modified erc-away erc-op erc-voice " " (erc-nick 8 8) " " (erc-target 18 40) (erc-members 5 5 :center) (erc-channel-modes 6 16 :center) " " (erc-server-name 20 30) " " (erc-topic 10 -1))
+ (mark erc-modified erc-away erc-op erc-voice " " (erc-target 18 40) (erc-members 5 5 :center) (erc-channel-modes 9 20 :center) " " (erc-topic 10 -1))))
+(setq ibuffer-formats (append ibuffer-formats erc-ibuffer-formats))
+
+(defvar erc-ibuffer-limit-map nil
+ "Prefix keymap to use for ERC related limiting.")
+(define-prefix-command 'erc-ibuffer-limit-map)
+(define-key 'erc-ibuffer-limit-map (kbd "s") 'ibuffer-limit-by-erc-server)
+(define-key ibuffer-mode-map (kbd "/ \C-e") 'erc-ibuffer-limit-map)
+
+(provide 'erc-ibuffer)
+
+;;; erc-ibuffer.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: fbad56a5-8595-45e0-a8c8-d8bb91e26944
diff --git a/lisp/erc/erc-identd.el b/lisp/erc/erc-identd.el
new file mode 100644
index 00000000000..5cb179c7e22
--- /dev/null
+++ b/lisp/erc/erc-identd.el
@@ -0,0 +1,87 @@
+;;; erc-identd.el --- RFC1413 (identd authentication protocol) server
+
+;; Copyright (C) 2003 Free Software Foundation, Inc.
+
+;; Author: John Wiegley <johnw@gnu.org>
+;; Keywords: comm, processes
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; You can have a local identd server (running on port 8113; I use DNAT
+;; to bind 113->8113) if you add this to .emacs.el:
+
+;; (add-hook 'erc-connect-pre-hook 'erc-identd-start)
+;; (add-hook 'erc-disconnected-hook 'erc-identd-stop)
+
+;;; Code:
+
+(defvar erc-identd-process nil)
+
+(defun erc-identd-filter (proc string)
+ "This filter implements RFC1413 (identd authentication protocol)."
+ (let ((erc-identd-process proc))
+ (when (string-match "\\([0-9]+\\)\\s-*,\\s-*\\([0-9]+\\)" string)
+ (let ((port-on-server (match-string 1 string))
+ (port-on-client (match-string 2 string)))
+ (send-string erc-identd-process
+ (format "%s, %s : USERID : %s : %s\n"
+ port-on-server port-on-client
+ system-type (user-login-name)))
+ (process-send-eof erc-identd-process)))))
+
+(defun erc-identd-start (&optional port)
+ "Start an identd server listening to port 8113.
+Port 113 (auth) will need to be redirected to port 8113 on your
+machine -- using iptables, or a program like redir which can be
+run from inetd. The idea is to provide a simple identd server
+when you need one, without having to install one globally on your
+system."
+ (interactive (list (read-string "Serve identd requests on port: " "8113")))
+ (if (null port)
+ (setq port 8113)
+ (if (stringp port)
+ (setq port (string-to-number port))))
+ (if erc-identd-process
+ (delete-process erc-identd-process))
+ (if (fboundp 'make-network-process)
+ (setq erc-identd-process
+ (make-network-process :name "identd"
+ :buffer (generate-new-buffer "identd")
+ :service port :server t :noquery t
+ :filter 'erc-identd-filter))
+ (open-network-stream-server "identd" (generate-new-buffer "identd")
+ port nil 'erc-identd-filter)))
+
+(defun erc-identd-stop (&rest ignore)
+ (interactive)
+ (when erc-identd-process
+ (delete-process erc-identd-process)
+ (setq erc-identd-process nil)))
+
+(provide 'erc-identd)
+
+;;; erc-identd.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: e0b5f926-0f35-40b9-8ddb-ca06b62a7544
diff --git a/lisp/erc/erc-imenu.el b/lisp/erc/erc-imenu.el
new file mode 100644
index 00000000000..c64c9c04723
--- /dev/null
+++ b/lisp/erc/erc-imenu.el
@@ -0,0 +1,143 @@
+;;; erc-imenu.el -- Imenu support for ERC
+
+;; Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Keywords: comm
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcImenu
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file contains code related to Ibuffer and ERC. Totally alpha,
+;; needs work. Usage: Type / C-e C-h when in Ibuffer-mode to see new
+;; limiting commands
+
+;;; Code:
+
+
+;; Author: Mario Lang <mlang@delysid.org>
+
+;; This file is not part of GNU Emacs. But the same license applies.
+
+;;; Commentary:
+
+;; This package defines the function `erc-create-imenu-index'. ERC
+;; uses this for `imenu-create-index-function', and autoloads it.
+;; Therefore, nothing needs to be done to use this package.
+
+;;; Code:
+
+(require 'erc)
+(require 'imenu)
+
+(defun erc-unfill-notice ()
+ "Return text from point to a computed end as a string unfilled.
+Don't rely on this function, read it first!"
+ (let ((str (buffer-substring
+ (save-excursion
+ (re-search-forward (regexp-quote erc-notice-prefix)))
+ (progn
+ (while (save-excursion
+ (forward-line 1)
+ (looking-at " "))
+ (forward-line 1))
+ (end-of-line) (point)))))
+ (with-temp-buffer
+ (insert str)
+ (goto-char (point-min))
+ (while (re-search-forward "\n +" nil t)
+ (replace-match " "))
+ (buffer-substring (point-min) (point-max)))))
+
+;;;###autoload
+(defun erc-create-imenu-index ()
+ (let ((index-alist '())
+ (notice-alist '())
+ (join-alist '())
+ (left-alist '())
+ (quit-alist '())
+ (message-alist '())
+ (mode-change-alist '())
+ (topic-change-alist '())
+ prev-pos)
+ (goto-char (point-max))
+ (imenu-progress-message prev-pos 0)
+ (while (if (bolp)
+ (> (forward-line -1)
+ -1)
+ (progn (forward-line 0)
+ t))
+ (imenu-progress-message prev-pos nil t)
+ (save-match-data
+ (when (looking-at (concat (regexp-quote erc-notice-prefix)
+ "\\(.+\\)$"))
+ (let ((notice-text ;; Ugly hack, but seems to work.
+ (save-excursion (erc-unfill-notice)))
+ (pos (point)))
+ (push (cons notice-text pos) notice-alist)
+ (or
+ (when (string-match "^\\(.*\\) has joined channel" notice-text)
+ (push (cons (match-string 1 notice-text) pos) join-alist))
+ (when (string-match "^\\(.+\\) has left channel" notice-text)
+ (push (cons (match-string 1 notice-text) pos) left-alist))
+ (when (string-match "^\\(.+\\) has quit\\(.*\\)$" notice-text)
+ (push (cons (concat (match-string 1 notice-text)
+ (match-string 2 notice-text))
+ (point))
+ quit-alist))
+ (when (string-match
+ "^\\(\\S-+\\) (.+) has changed mode for \\S-+ to \\(.*\\)$"
+ notice-text)
+ (push (cons (concat (match-string 1 notice-text) ": "
+ (match-string 2 notice-text))
+ (point))
+ mode-change-alist))
+ (when (string-match
+ "^\\(\\S-+\\) (.+) has set the topic for \\S-+: \\(.*\\)$"
+ notice-text)
+ (push (cons (concat (match-string 1 notice-text) ": "
+ (match-string 2 notice-text)) pos)
+ topic-change-alist)))))
+ (when (looking-at "<\\(\\S-+\\)> \\(.+\\)$")
+ (let ((from (match-string 1))
+ (message-text (match-string 2)))
+ (push (cons (concat from ": " message-text) (point))
+ message-alist)))))
+ (and notice-alist (push (cons "notices" notice-alist) index-alist))
+ (and join-alist (push (cons "joined" join-alist) index-alist))
+ (and left-alist (push (cons "parted" left-alist) index-alist))
+ (and quit-alist (push (cons "quit" quit-alist) index-alist))
+ (and mode-change-alist (push (cons "mode-change" mode-change-alist)
+ index-alist))
+ (and message-alist (push (cons "messages" message-alist) index-alist))
+ (and topic-change-alist (push (cons "topic-change" topic-change-alist)
+ index-alist))
+ index-alist))
+
+(provide 'erc-imenu)
+
+;;; erc-imenu.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 35c69082-ca29-43f7-a050-8da5f400de81
diff --git a/lisp/erc/erc-lang.el b/lisp/erc/erc-lang.el
new file mode 100644
index 00000000000..20c89a8b0b6
--- /dev/null
+++ b/lisp/erc/erc-lang.el
@@ -0,0 +1,213 @@
+;;; erc-lang.el --- provide the LANG command to ERC
+
+;; Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+
+;; Author: Alex Schroeder <alex@gnu.org>
+;; Maintainer: Alex Schroeder <alex@gnu.org>
+;; Version: 1.0.0
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcLang
+;; Keywords: comm languages processes
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This provides two commands: `language' is for everyday use, and
+;; `erc-cmd-LANG' provides the /LANG command to ERC.
+
+;;; Code:
+
+(require 'erc)
+
+(defvar iso-638-languages
+ '(("aa" . "Afar")
+ ("ab" . "Abkhazian")
+ ("af" . "Afrikaans")
+ ("am" . "Amharic")
+ ("ar" . "Arabic")
+ ("as" . "Assamese")
+ ("ay" . "Aymara")
+ ("az" . "Azerbaijani")
+ ("ba" . "Bashkir")
+ ("be" . "Byelorussian")
+ ("bg" . "Bulgarian")
+ ("bh" . "Bihari")
+ ("bi" . "Bislama")
+ ("bn" . "Bengali; Bangla")
+ ("bo" . "Tibetan")
+ ("br" . "Breton")
+ ("ca" . "Catalan")
+ ("co" . "Corsican")
+ ("cs" . "Czech")
+ ("cy" . "Welsh")
+ ("da" . "Danish")
+ ("de" . "German")
+ ("dz" . "Bhutani")
+ ("el" . "Greek")
+ ("en" . "English")
+ ("eo" . "Esperanto")
+ ("es" . "Spanish")
+ ("et" . "Estonian")
+ ("eu" . "Basque")
+ ("fa" . "Persian")
+ ("fi" . "Finnish")
+ ("fj" . "Fiji")
+ ("fo" . "Faroese")
+ ("fr" . "French")
+ ("fy" . "Frisian")
+ ("ga" . "Irish")
+ ("gd" . "Scots Gaelic")
+ ("gl" . "Galician")
+ ("gn" . "Guarani")
+ ("gu" . "Gujarati")
+ ("ha" . "Hausa")
+ ("he" . "Hebrew (formerly iw)")
+ ("hi" . "Hindi")
+ ("hr" . "Croatian")
+ ("hu" . "Hungarian")
+ ("hy" . "Armenian")
+ ("ia" . "Interlingua")
+ ("id" . "Indonesian (formerly in)")
+ ("ie" . "Interlingue")
+ ("ik" . "Inupiak")
+ ("is" . "Icelandic")
+ ("it" . "Italian")
+ ("iu" . "Inuktitut")
+ ("ja" . "Japanese")
+ ("jw" . "Javanese")
+ ("ka" . "Georgian")
+ ("kk" . "Kazakh")
+ ("kl" . "Greenlandic")
+ ("km" . "Cambodian")
+ ("kn" . "Kannada")
+ ("ko" . "Korean")
+ ("ks" . "Kashmiri")
+ ("ku" . "Kurdish")
+ ("ky" . "Kirghiz")
+ ("la" . "Latin")
+ ("ln" . "Lingala")
+ ("lo" . "Laothian")
+ ("lt" . "Lithuanian")
+ ("lv" . "Latvian, Lettish")
+ ("mg" . "Malagasy")
+ ("mi" . "Maori")
+ ("mk" . "Macedonian")
+ ("ml" . "Malayalam")
+ ("mn" . "Mongolian")
+ ("mo" . "Moldavian")
+ ("mr" . "Marathi")
+ ("ms" . "Malay")
+ ("mt" . "Maltese")
+ ("my" . "Burmese")
+ ("na" . "Nauru")
+ ("ne" . "Nepali")
+ ("nl" . "Dutch")
+ ("no" . "Norwegian")
+ ("oc" . "Occitan")
+ ("om" . "(Afan) Oromo")
+ ("or" . "Oriya")
+ ("pa" . "Punjabi")
+ ("pl" . "Polish")
+ ("ps" . "Pashto, Pushto")
+ ("pt" . "Portuguese")
+ ("qu" . "Quechua")
+ ("rm" . "Rhaeto-Romance")
+ ("rn" . "Kirundi")
+ ("ro" . "Romanian")
+ ("ru" . "Russian")
+ ("rw" . "Kinyarwanda")
+ ("sa" . "Sanskrit")
+ ("sd" . "Sindhi")
+ ("sg" . "Sangho")
+ ("sh" . "Serbo-Croatian")
+ ("si" . "Sinhalese")
+ ("sk" . "Slovak")
+ ("sl" . "Slovenian")
+ ("sm" . "Samoan")
+ ("sn" . "Shona")
+ ("so" . "Somali")
+ ("sq" . "Albanian")
+ ("sr" . "Serbian")
+ ("ss" . "Siswati")
+ ("st" . "Sesotho")
+ ("su" . "Sundanese")
+ ("sv" . "Swedish")
+ ("sw" . "Swahili")
+ ("ta" . "Tamil")
+ ("te" . "Telugu")
+ ("tg" . "Tajik")
+ ("th" . "Thai")
+ ("ti" . "Tigrinya")
+ ("tk" . "Turkmen")
+ ("tl" . "Tagalog")
+ ("tn" . "Setswana")
+ ("to" . "Tonga")
+ ("tr" . "Turkish")
+ ("ts" . "Tsonga")
+ ("tt" . "Tatar")
+ ("tw" . "Twi")
+ ("ug" . "Uighur")
+ ("uk" . "Ukrainian")
+ ("ur" . "Urdu")
+ ("uz" . "Uzbek")
+ ("vi" . "Vietnamese")
+ ("vo" . "Volapuk")
+ ("wo" . "Wolof")
+ ("xh" . "Xhosa")
+ ("yi" . "Yiddish (formerly ji)")
+ ("yo" . "Yoruba")
+ ("za" . "Zhuang")
+ ("zh" . "Chinese")
+ ("zu" . "Zulu"))
+ "Alist of ISO language codes and language names.
+This is based on the technical contents of ISO 639:1988 (E/F)
+\"Code for the representation of names of languages\".
+
+Typed by Keld.Simonsen@dkuug.dk 1990-11-30
+ <ftp://dkuug.dk/i18n/ISO_639>
+Minor corrections, 1992-09-08 by Keld Simonsen
+Sundanese corrected, 1992-11-11 by Keld Simonsen
+Telugu corrected, 1995-08-24 by Keld Simonsen
+Hebrew, Indonesian, Yiddish corrected 1995-10-10 by Michael Everson
+Inuktitut, Uighur, Zhuang added 1995-10-10 by Michael Everson
+Sinhalese corrected, 1995-10-10 by Michael Everson
+Faeroese corrected to Faroese, 1995-11-18 by Keld Simonsen
+Sangro corrected to Sangho, 1996-07-28 by Keld Simonsen
+
+Two-letter lower-case symbols are used.
+The Registration Authority for ISO 639 is Infoterm, Osterreichisches
+Normungsinstitut (ON), Postfach 130, A-1021 Vienna, Austria.")
+
+(defun language (code)
+ "Return the language name for the ISO CODE."
+ (interactive (list (completing-read "ISO language code: "
+ iso-638-languages)))
+ (message (cdr (assoc code iso-638-languages))))
+
+(defun erc-cmd-LANG (language)
+ "Display the language name for the language code given by LANGUAGE."
+ (let ((lang (cdr (assoc language iso-638-languages))))
+ (erc-display-message
+ nil 'notice 'active
+ (or lang (concat line ": No such domain"))))
+ t)
+
+(provide 'erc-lang)
+
+;; arch-tag: 8ffb1563-cc03-4517-b067-16309d4ff97b
+;;; erc-lang.el ends here
diff --git a/lisp/erc/erc-list.el b/lisp/erc/erc-list.el
new file mode 100644
index 00000000000..785e4d19750
--- /dev/null
+++ b/lisp/erc/erc-list.el
@@ -0,0 +1,396 @@
+;;; erc-list.el --- Provide a faster channel listing mechanism
+
+;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+;; Copyright (C) 2004 Brian Palmer
+
+;; Author: Mario Lang <mlang@lexx.delysid.org>
+;; Keywords: comm
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides a simple derived mode for viewing Channel lists.
+;; It also serves as a demonstration of how the new server hook facility
+;; can be used.
+
+;;; Code:
+
+(require 'erc)
+(require 'erc-nets)
+(require 'sort)
+(unless (fboundp 'make-overlay)
+ (require 'overlay))
+(eval-when-compile (require 'cl))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; User customizable variables.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defgroup erc-list nil
+ "Display IRC channels in another window when using /LIST"
+ :group 'erc)
+
+(defcustom erc-chanlist-progress-message t
+ "*Show progress message while accumulating channel list."
+ :group 'erc-list
+ :type 'boolean)
+
+(defcustom erc-no-list-networks nil
+ "*A list of network names on which the /LIST command refuses to work."
+ :group 'erc-list
+ :type '(repeat string))
+
+(defcustom erc-chanlist-frame-parameters nil
+ "*If nil, the channel list is displayed in a new window; if non-nil,
+this variable holds the frame parameters used to make a frame to
+display the channel list."
+ :group 'erc-list
+ :type 'list)
+
+(defcustom erc-chanlist-hide-modeline nil
+ "*If nil, the channel list buffer has a modeline, otherwise the modeline is hidden."
+ :group 'erc-list
+ :type 'boolean)
+
+(defface erc-chanlist-header-face '((t (:bold t)))
+ "Face used for the headers in erc's channel list."
+ :group 'erc-faces)
+
+(defface erc-chanlist-odd-line-face '((t (:inverse-video t)))
+ "Face used for the odd lines in erc's channel list."
+ :group 'erc-faces)
+
+(defface erc-chanlist-even-line-face '((t (:inverse-video nil)))
+ "Face used for the even lines in erc's channel list."
+ :group 'erc-faces)
+
+(defface erc-chanlist-highlight '((t (:foreground "red")))
+ "Face used to highlight the current line in the channel list."
+ :group 'erc-faces)
+
+;; This should perhaps be a defface that inherits values from the highlight face
+;; but xemacs does not support inheritance
+(defcustom erc-chanlist-highlight-face 'erc-chanlist-highlight
+ "Face used for highlighting the current line in a list."
+ :type 'face
+ :group 'erc-faces)
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; All variables below this line are for internal use only.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defvar erc-chanlist-channel-line-regexp "^\\([#&\\*][^ \t\n]*\\)\\s-+[0-9]+"
+ "Regexp that matches a channel line in the channel list buffer.")
+
+(defvar erc-chanlist-buffer nil)
+(make-variable-buffer-local 'erc-chanlist-buffer)
+
+(defvar erc-chanlist-last-time 0
+ "A time value used to throttle the progress indicator.")
+
+(defvar erc-chanlist-frame nil
+ "The frame displaying the most recent channel list buffer.")
+
+(defvar erc-chanlist-sort-state 'channel
+ "The sort mode of the channel list buffer. Either 'channel or 'users.")
+(make-variable-buffer-local 'erc-chanlist-sort-state)
+
+(defvar erc-chanlist-highlight-overlay nil
+ "The overlay used for erc chanlist highlighting")
+(make-variable-buffer-local 'erc-chanlist-highlight-overlay)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Define erc-chanlist-mode.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defcustom erc-chanlist-mode-hook nil
+ "Hook run by erc-chanlist-mode."
+ :group 'erc-list
+ :type 'hook)
+
+(define-derived-mode erc-chanlist-mode fundamental-mode "ERC Channel List"
+ "Mode for viewing a channel list of a particular server.
+
+\\{erc-chanlist-mode-map}"
+ (local-set-key "\C-c\C-j" 'erc-join-channel)
+ (local-set-key "j" 'erc-chanlist-join-channel)
+ (local-set-key "n" 'next-line)
+ (local-set-key "p" 'previous-line)
+ (local-set-key "q" 'erc-chanlist-quit)
+ (local-set-key "s" 'erc-chanlist-toggle-sort-state)
+ (local-set-key "t" 'toggle-truncate-lines)
+ (setq erc-chanlist-sort-state 'channel)
+ (setq truncate-lines t)
+ (add-hook 'post-command-hook 'erc-chanlist-post-command-hook 'append 'local))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Functions.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;;###autoload
+(defun erc-cmd-LIST (&rest channel)
+ "Display a buffer containing a list of channels on the current server.
+Optional argument CHANNEL specifies a single channel to list (instead of every
+available channel)."
+ (interactive
+ (remove "" (split-string
+ (read-from-minibuffer "List channels (RET for all): ") " ")))
+ (if (and (null channel)
+ (erc-member-ignore-case (erc-network-name) erc-no-list-networks))
+ (erc-display-line "ERC is configured not to allow the /LIST command on this network!"
+ (current-buffer))
+ (erc-display-line (erc-make-notice (concat "Listing channel"
+ (if channel
+ "."
+ "s. This may take a while."))))
+ (erc-chanlist channel))
+ t)
+
+;;;###autoload
+(defun erc-chanlist (&optional channels)
+ "Show a channel listing of the current server in a special mode.
+Please note that this function only works with IRC servers which conform
+to RFC and send the LIST header (#321) at start of list transmission."
+ (interactive)
+ (with-current-buffer (erc-server-buffer)
+ (erc-once-with-server-event
+ 321
+ '(progn
+ (add-hook 'erc-server-322-functions 'erc-chanlist-322 nil t)
+
+ (erc-once-with-server-event
+ 323
+ '(progn
+ (remove-hook 'erc-server-322-functions 'erc-chanlist-322 t)
+ (let ((buf erc-chanlist-buffer))
+ (if (not (buffer-live-p buf))
+ (error "`erc-chanlist-buffer' does not refer to a live buffer"))
+
+ (set-buffer buf)
+ (buffer-disable-undo)
+ (let (buffer-read-only
+ (sort-fold-case t))
+ (sort-lines nil (point-min) (point-max))
+ (setq erc-chanlist-sort-state 'channel)
+
+ (let ((sum (count-lines (point-min) (point-max))))
+ (goto-char (point-min))
+ (insert (substitute-command-keys
+ (concat "'\\[erc-chanlist-toggle-sort-state]' toggle sort mode.\n"
+ "'\\[erc-chanlist-quit]' kill this buffer.\n"
+ "'\\[toggle-truncate-lines]' toggle line truncation.\n"
+ "'\\[erc-chanlist-join-channel]' join the channel listed on the current line.\n\n")))
+ (insert (format "%d channels (sorted by %s).\n\n"
+ sum (if (eq erc-chanlist-sort-state 'channel)
+ "channel name"
+ "number of users"))))
+
+ (insert (format "%-25s%5s %s\n------------------------ ----- ----------------------------\n"
+ "Channel"
+ "Users"
+ "Topic"))
+
+ ;; Display the channel list buffer.
+ (if erc-chanlist-frame-parameters
+ (progn
+ (if (or (null erc-chanlist-frame)
+ (not (frame-live-p erc-chanlist-frame)))
+ (setq erc-chanlist-frame
+ (make-frame `((name . ,(format "Channels on %s"
+ erc-session-server))
+ ,@erc-chanlist-frame-parameters))))
+ (select-frame erc-chanlist-frame)
+ (switch-to-buffer buf)
+ (erc-prettify-channel-list))
+ (pop-to-buffer buf)
+ (erc-prettify-channel-list))))
+ (goto-char (point-min))
+ (search-forward-regexp "^------" nil t)
+ (forward-line 1)
+ (erc-chanlist-highlight-line)
+ (message "")
+ t))
+
+ (setq erc-chanlist-buffer (get-buffer-create
+ (format "*Channels on %s*"
+ (erc-response.sender parsed))))
+ (with-current-buffer erc-chanlist-buffer
+ (setq buffer-read-only nil)
+ (erase-buffer)
+ (erc-chanlist-mode)
+ (setq erc-server-process proc)
+ (if erc-chanlist-hide-modeline
+ (setq mode-line-format nil))
+ (setq buffer-read-only t))
+ t))
+
+ ;; Now that we've setup our callbacks, pull the trigger.
+ (if (interactive-p)
+ (message "Collecting channel list for server %s" erc-session-server))
+ (erc-server-send (if (null channels)
+ "LIST"
+ (concat "LIST "
+ (mapconcat #'identity channels ","))))))
+
+(defun erc-chanlist-322 (proc parsed)
+ "Process an IRC 322 message.
+
+The message carries information about one channel for the LIST
+command."
+ (multiple-value-bind (channel num-users)
+ (cdr (erc-response.command-args parsed))
+ (let ((topic (erc-response.contents parsed)))
+ (with-current-buffer erc-chanlist-buffer
+ (save-excursion
+ (goto-char (point-max))
+ (let (buffer-read-only)
+ (insert (format "%-26s%4s %s\n" (erc-controls-strip channel)
+ num-users
+ (erc-controls-strip topic))))
+
+ ;; Maybe display a progress indicator in the minibuffer.
+ (when (and erc-chanlist-progress-message
+ (> (erc-time-diff
+ erc-chanlist-last-time (erc-current-time))
+ 3))
+ (setq erc-chanlist-last-time (erc-current-time))
+ (message "Accumulating channel list ... %c"
+ (aref [?/ ?| ?\\ ?- ?! ?O ?o] (random 7))))
+
+ ;; Return success to prevent other hook functions from being run.
+ t)))))
+
+(defun erc-chanlist-post-command-hook ()
+ "Keep the current line highlighted."
+ (ignore-errors
+ (save-excursion
+ (beginning-of-line)
+ (if (looking-at erc-chanlist-channel-line-regexp)
+ (erc-chanlist-highlight-line)
+ (erc-chanlist-dehighlight-line)))))
+
+(defun erc-chanlist-highlight-line ()
+ "Highlight the current line."
+ (unless erc-chanlist-highlight-overlay
+ (setq erc-chanlist-highlight-overlay
+ (make-overlay (point-min) (point-min)))
+ ;; Detach it from the buffer.
+ (delete-overlay erc-chanlist-highlight-overlay)
+ (overlay-put erc-chanlist-highlight-overlay
+ 'face erc-chanlist-highlight-face)
+ ;; Expressly put it at a higher priority than the text
+ ;; properties used for faces later on. Gnu emacs promises that
+ ;; right now overlays are higher priority than text properties,
+ ;; but why take chances?
+ (overlay-put erc-chanlist-highlight-overlay 'priority 1))
+ (move-overlay erc-chanlist-highlight-overlay (point) (1+ (point-at-eol))))
+
+(defun erc-chanlist-dehighlight-line ()
+ "Remove the line highlighting."
+ (delete-overlay erc-chanlist-highlight-overlay))
+
+(defun erc-prettify-channel-list ()
+ "Make the channel list buffer look pretty.
+When this function runs, the current buffer must be the channel
+list buffer, or it does nothing."
+ (if (eq major-mode 'erc-chanlist-mode)
+ (save-excursion
+ (let ((inhibit-read-only t))
+ (goto-char (point-min))
+ (when (search-forward-regexp "^-------" nil t)
+ (add-text-properties
+ (point-min) (1+ (point-at-eol)) '(face erc-chanlist-header-face))
+ (forward-line 1))
+
+ (while (not (eobp))
+ (add-text-properties
+ (point) (1+ (point-at-eol)) '(face erc-chanlist-odd-line-face))
+ (forward-line 1)
+ (unless (eobp)
+ (add-text-properties
+ (point) (1+ (point-at-eol)) '(face erc-chanlist-even-line-face)))
+ (forward-line 1))))))
+
+(defun erc-chanlist-toggle-sort-state ()
+ "Toggle the channel list buffer sorting method.
+Either sort by channel names or by number of users in each channel."
+ (interactive)
+ (let ((inhibit-read-only t)
+ (sort-fold-case t))
+ (save-excursion
+ (goto-char (point-min))
+ (search-forward-regexp "^-----" nil t)
+ (forward-line 1)
+ (unless (eobp)
+ (if (eq erc-chanlist-sort-state 'channel)
+ (progn
+ (sort-numeric-fields 2 (point) (point-max))
+ (reverse-region (point) (point-max))
+ (setq erc-chanlist-sort-state 'users))
+ (sort-lines nil (point) (point-max))
+ (setq erc-chanlist-sort-state 'channel))
+
+ (goto-char (point-min))
+ (if (search-forward-regexp "^[0-9]+ channels (sorted by \\(.*\\)).$"
+ nil t)
+ (replace-match (if (eq erc-chanlist-sort-state 'channel)
+ "channel name"
+ "number of users")
+ nil nil nil 1))
+
+ (goto-char (point-min))
+ (search-forward-regexp "^-----" nil t)
+ (forward-line 1)
+ (recenter -1)
+
+ (erc-prettify-channel-list)))))
+
+(defun erc-chanlist-quit ()
+ "Quit Chanlist mode.
+Kill the channel list buffer, window, and frame (if there's a frame
+devoted to the channel list)."
+ (interactive)
+ (kill-buffer (current-buffer))
+ (if (eq (selected-frame) erc-chanlist-frame)
+ (delete-frame)
+ (delete-window)))
+
+(defun erc-chanlist-join-channel ()
+ "Join the channel listed on the current line of the channel list buffer.
+Private channels, which are shown as asterisks (*), are ignored."
+ (interactive)
+ (save-excursion
+ (beginning-of-line)
+ (when (looking-at erc-chanlist-channel-line-regexp)
+ (let ((channel-name (match-string 1)))
+ (when (and (stringp channel-name)
+ (not (string= channel-name "*")))
+ (run-at-time 0.5 nil 'erc-join-channel channel-name))))))
+
+(provide 'erc-list)
+
+;;; erc-list.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 4a13196a-a61b-465a-9926-044dfbc7e5ff
diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el
new file mode 100644
index 00000000000..d4e6e5ad3fa
--- /dev/null
+++ b/lisp/erc/erc-log.el
@@ -0,0 +1,358 @@
+;;; erc-log.el --- Logging facilities for ERC.
+
+;; Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Lawrence Mitchell <wence@gmx.li>
+;; Keywords: IRC, chat, client, Internet, logging
+
+;; Created 2003-04-26
+;; Logging code taken from erc.el and modified to use markers.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file implements log file writing support for ERC.
+
+;; Quick start:
+;;
+;; (setq erc-enable-logging t)
+;; (setq erc-log-channels-directory "/path/to/logfiles") ; must be writable
+;;
+;; There are two ways to setup logging. The first will write to the log files
+;; on each incoming or outgoing line - this may not be optimal on a laptop
+;; HDD. To do this, M-x customize-variable erc-modules, and add "log".
+;;
+;; The second method will save buffers on /part, /quit, or killing the
+;; channel buffer. To do this, add the following to your .emacs:
+;;
+;; (require 'erc-log)
+;;
+;; You may optionally want the following code, to save all ERC buffers
+;; without confirmation when exiting emacs:
+;;
+;; (defadvice save-buffers-kill-emacs (before save-logs (&rest args) activate)
+;; (save-some-buffers t (lambda ()
+;; (when (and (eq major-mode 'erc-mode)
+;; (not (null buffer-file-name))) t))))
+;;
+;; If you only want to save logs for some buffers, customise the
+;; variable `erc-enable-logging'.
+
+;; How it works:
+;;
+;; If logging is enabled, at some point, `erc-save-buffer-in-logs'
+;; will be called. The "end" of the buffer is taken from
+;; `erc-insert-marker', while `erc-last-saved-position' holds the
+;; position the buffer was last saved at (as a marker, or if the
+;; buffer hasn't been saved before, as the number 1 (point-min)).
+
+;; The region between `erc-last-saved-position' and
+;; `erc-insert-marker' is saved to the current buffer's logfile, and
+;; `erc-last-saved-position' is updated to reflect this.
+
+;;; History:
+;; 2003-04-26: logging code pulled out of erc.el. Switched to using
+;; markers.
+
+;;; TODO:
+;; * Erc needs a generalised make-safe-file-name function, so that
+;; generated file names don't contain any invalid file characters.
+;;
+;; * Really, we need to lock the logfiles somehow, so that if a user
+;; is running multiple emacsen and/or on the same channel as more
+;; than one user, only one process writes to the logfile. This is
+;; especially needed for those logfiles with no nick in them, as
+;; these would become corrupted.
+;; For a single emacs process, the problem could be solved using a
+;; variable which contained the names of buffers already being
+;; logged. This would require that logging be buffer-local,
+;; possibly not a bad thing anyway, since many people don't want to
+;; log the server buffer.
+;; For multiple emacsen the problem is trickier. On some systems,
+;; on could use the function `lock-buffer' and `unlock-buffer'.
+;; However, file locking isn't implemented on all platforms, for
+;; example, there is none on w32 systems.
+;; A third possibility might be to fake lockfiles. However, this
+;; might lead to problems if an emacs crashes, as the lockfile
+;; would be left lying around.
+
+;;; Code:
+
+(require 'erc)
+(eval-when-compile (require 'cl))
+
+(defgroup erc-log nil
+ "Logging facilities for ERC."
+ :group 'erc)
+
+(defcustom erc-generate-log-file-name-function 'erc-generate-log-file-name-long
+ "*A function to generate a log filename.
+The function must take five arguments: BUFFER, TARGET, NICK, SERVER and PORT.
+BUFFER is the buffer to be saved,
+TARGET is the name of the channel, or the target of the query,
+NICK is the current nick,
+SERVER and PORT are the parameters used to connect BUFFERs
+`erc-server-process'."
+ :group 'erc-log
+ :type '(choice (const erc-generate-log-file-name-long)
+ (const erc-generate-log-file-name-short)
+ (const erc-generate-log-file-name-with-date)
+ (symbol)))
+
+(defcustom erc-save-buffer-on-part nil
+ "*Save the channel buffer content using `erc-save-buffer-in-logs' on PART."
+ :group 'erc-log
+ :type 'boolean)
+
+(defcustom erc-truncate-buffer-on-save nil
+ "Truncate any ERC (channel, query, server) buffer when it is saved."
+ :group 'erc-log
+ :type 'boolean)
+
+(defcustom erc-enable-logging t
+ "If non-nil, ERC will log IRC conversations.
+This can either be a boolean value of nil or t, or a function.
+If the value is a function, it will be called with one argument, the
+name of the current ERC buffer. One possible function, which saves
+all but server buffers is `erc-log-all-but-server-buffers'.
+
+This variable is buffer local. Setting it via \\[customize] sets the
+default value.
+
+Log files are stored in `erc-log-channels-directory'."
+ :group 'erc-log
+ :type '(choice boolean
+ function))
+(make-variable-buffer-local 'erc-enable-logging)
+
+(defcustom erc-log-channels-directory "~/log"
+ "The directory to place log files for channels.
+Leave blank to disable logging. If not nil, all the channel
+buffers are logged in separate files in that directory. The
+directory should not end with a trailing slash."
+ :group 'erc-log
+ :type '(choice directory
+ (const nil)))
+
+(defcustom erc-log-insert-log-on-open t
+ "*Insert log file contents into the buffer if a log file exists."
+ :group 'erc-log
+ :type 'boolean)
+
+(defcustom erc-save-queries-on-quit nil
+ "Save all query (also channel) buffers of the server on QUIT.
+See the variable `erc-save-buffer-on-part' for details."
+ :group 'erc-log
+ :type 'boolean)
+
+(defcustom erc-log-file-coding-system (if (featurep 'xemacs)
+ 'binary
+ 'emacs-mule)
+ "*The coding system ERC should use for writing log files.
+
+This should ideally, be a \"catch-all\" coding system, like
+`emacs-mule', or `iso-2022-7bit'."
+ :group 'erc-log)
+
+;;;###autoload (autoload 'erc-log-mode "erc-log" nil t)
+(define-erc-module log nil
+ "Automatically logs things you receive on IRC into files.
+Files are stored in `erc-log-channels-directory'; file name
+format is defined through a formatting function on
+`erc-generate-log-file-name-function'.
+
+Since automatic logging is not always a Good Thing (especially if
+people say things in different coding systems), you can turn logging
+behaviour on and off with the variable `erc-enable-logging', which can
+also be a predicate function. To only log when you are not set away, use:
+
+\(setq erc-enable-logging
+ (lambda (buffer)
+ (with-current-buffer buffer
+ (not erc-away))))"
+ ;; enable
+ ((add-hook 'erc-insert-post-hook
+ 'erc-save-buffer-in-logs)
+ (add-hook 'erc-send-post-hook
+ 'erc-save-buffer-in-logs))
+ ;; disable
+ ((remove-hook 'erc-insert-post-hook
+ 'erc-save-buffer-in-logs)
+ (remove-hook 'erc-send-post-hook
+ 'erc-save-buffer-in-logs)))
+
+(when erc-enable-logging
+ (add-hook 'erc-kill-buffer-hook
+ 'erc-save-buffer-in-logs)
+ (add-hook 'erc-kill-channel-hook
+ 'erc-save-buffer-in-logs)
+ (add-hook 'erc-quit-hook
+ 'erc-conditional-save-queries)
+ (add-hook 'erc-part-hook
+ 'erc-conditional-save-buffer))
+
+(define-key erc-mode-map "\C-c\C-l" 'erc-save-buffer-in-logs)
+
+;;;functionality referenced from erc.el
+(defun erc-log-setup-logging ()
+ "Setup the buffer-local logging variables in the current buffer.
+This function is destined to be run from `erc-connect-pre-hook'."
+ (when (erc-logging-enabled)
+ (auto-save-mode -1)
+ (setq buffer-offer-save t
+ buffer-file-name "")
+ (set (make-local-variable 'write-file-functions)
+ '(erc-save-buffer-in-logs))
+ (when erc-log-insert-log-on-open
+ (ignore-errors (insert-file-contents (erc-current-logfile))
+ (move-marker erc-last-saved-position
+ (1- (point-max)))))))
+
+;;; Append, so that 'erc-initialize-log-marker keeps running first.
+(add-hook 'erc-connect-pre-hook 'erc-log-setup-logging 'append)
+
+(defun erc-log-all-but-server-buffers (buffer)
+ "Returns t if logging should be enabled in BUFFER.
+Returns nil iff `erc-server-buffer-p' returns t."
+ (save-excursion
+ (save-window-excursion
+ (set-buffer buffer)
+ (not (erc-server-buffer-p)))))
+
+(defun erc-save-query-buffers (process)
+ "Save all buffers process."
+ (erc-with-all-buffers-of-server process
+ nil
+ (erc-save-buffer-in-logs)))
+
+(defun erc-conditional-save-buffer (buffer)
+ "Save Query BUFFER if `erc-save-queries-on-quit' is t."
+ (when erc-save-buffer-on-part
+ (erc-save-buffer-in-logs buffer)))
+
+(defun erc-conditional-save-queries (process)
+ "Save Query buffers of PROCESS if `erc-save-queries-on-quit' is t."
+ (when erc-save-queries-on-quit
+ (erc-save-query-buffers process)))
+
+;;;###autoload
+(defun erc-logging-enabled (&optional buffer)
+ "Return non-nil if logging is enabled for BUFFER.
+If BUFFER is nil, the value of `current-buffer' is used.
+Logging is enabled if `erc-log-channels-directory' is non-nil, the directory
+is writeable (it will be created as necessary) and
+`erc-enable-logging' returns a non-nil value."
+ (and erc-log-channels-directory
+ (erc-directory-writable-p erc-log-channels-directory)
+ (if (functionp erc-enable-logging)
+ (funcall erc-enable-logging (or buffer (current-buffer)))
+ erc-enable-logging)))
+
+(defun erc-current-logfile (&optional buffer)
+ "Return the logfile to use for BUFFER.
+If BUFFER is nil, the value of `current-buffer' is used.
+This is determined by `erc-generate-log-file-name-function'.
+The result is converted to lowercase, as IRC is case-insensitive"
+ (expand-file-name
+ (downcase (funcall erc-generate-log-file-name-function
+ (or buffer (current-buffer))
+ (or (erc-default-target) (buffer-name buffer))
+ (erc-current-nick)
+ erc-session-server erc-session-port))
+ erc-log-channels-directory))
+
+(defun erc-generate-log-file-name-with-date (buffer &rest ignore)
+ "This function computes a short log file name.
+The name of the log file is composed of BUFFER and the current date.
+This function is a possible value for `erc-generate-log-file-name-function'."
+ (concat (buffer-name buffer) "-" (format-time-string "%Y-%m-%d") ".txt"))
+
+(defun erc-generate-log-file-name-short (buffer &rest ignore)
+ "This function computes a short log file name.
+In fact, it only uses the buffer name of the BUFFER argument, so
+you can affect that using `rename-buffer' and the-like. This
+function is a possible value for
+`erc-generate-log-file-name-function'."
+ (concat (buffer-name buffer) ".txt"))
+
+(defun erc-generate-log-file-name-long (buffer target nick server port)
+ "Generates a log-file name in the way ERC always did it.
+This results in a file name of the form #channel!nick@server:port.txt.
+This function is a possible value for `erc-generate-log-file-name-function'."
+ (let ((file (concat
+ (if target (concat target "!"))
+ nick "@" server ":" (cond ((stringp port) port)
+ ((numberp port)
+ (number-to-string port))) ".txt")))
+ ;; we need a make-safe-file-name function.
+ (convert-standard-filename file)))
+
+;;;###autoload
+(defun erc-save-buffer-in-logs (&optional buffer)
+ "Append BUFFER contents to the log file, if logging is enabled.
+If BUFFER is not provided, current buffer is used.
+Logging is enabled if `erc-logging-enabled' returns non-nil.
+
+This is normally done on exit, to save the unsaved portion of the
+buffer, since only the text that runs off the buffer limit is logged
+automatically.
+
+You can save every individual message by putting this function on
+`erc-insert-post-hook'."
+ (interactive)
+ (or buffer (setq buffer (current-buffer)))
+ (when (erc-logging-enabled buffer)
+ (let ((file (erc-current-logfile buffer))
+ (coding-system-for-write erc-log-file-coding-system))
+ (save-excursion
+ (with-current-buffer buffer
+ (save-restriction
+ (widen)
+ ;; early on in the initalisation, don't try and write the log out
+ (when (and (markerp erc-last-saved-position)
+ (> erc-insert-marker (1+ erc-last-saved-position)))
+ (write-region (1+ (marker-position erc-last-saved-position))
+ (marker-position erc-insert-marker)
+ file t 'nomessage)
+ (if (and erc-truncate-buffer-on-save (interactive-p))
+ (progn
+ (let ((inhibit-read-only t)) (erase-buffer))
+ (move-marker erc-last-saved-position (point-max))
+ (erc-display-prompt))
+ (move-marker erc-last-saved-position
+ ;; If we place erc-last-saved-position at
+ ;; erc-insert-marker, because text gets
+ ;; inserted /before/ erc-insert-marker,
+ ;; the log file will not be saved
+ ;; (erc-last-saved-position will always
+ ;; be equal to erc-insert-marker).
+ (1- (marker-position erc-insert-marker)))))
+ (set-buffer-modified-p nil))))))
+ t)
+
+(provide 'erc-log)
+
+;;; erc-log.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 54072f99-9f0a-4846-8908-2ccde92221de
diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el
new file mode 100644
index 00000000000..a5e3bf88ccf
--- /dev/null
+++ b/lisp/erc/erc-match.el
@@ -0,0 +1,658 @@
+;;; erc-match.el --- Highlight messages matching certain regexps
+
+;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Andreas Fuchs <asf@void.at>
+;; Keywords: comm, faces
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcMatch
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file includes stuff to work with pattern matching in ERC. If
+;; you were used to customizing erc-fools, erc-keywords, erc-pals,
+;; erc-dangerous-hosts and the like, this file contains these
+;; customizable variables.
+
+;; Usage:
+;; Put (erc-match-mode 1) into your ~/.emacs file.
+
+;;; Code:
+
+(require 'erc)
+(eval-when-compile (require 'cl))
+
+;; Customisation:
+
+(defgroup erc-match nil
+ "Keyword and Friend/Foe/... recognition.
+Group containing all things concerning pattern matching in ERC
+messages."
+ :group 'erc)
+
+;;;###autoload (autoload 'erc-match-mode "erc-match")
+(define-erc-module match nil
+ "This mode checks whether messages match certain patterns. If so,
+they are hidden or highlighted. This is controlled via the variables
+`erc-pals', `erc-fools', `erc-keywords', `erc-dangerous-hosts', and
+`erc-current-nick-highlight-type'. For all these highlighting types,
+you can decide whether the entire message or only the sending nick is
+highlighted."
+ ((add-hook 'erc-insert-modify-hook 'erc-match-message 'append))
+ ((remove-hook 'erc-insert-modify-hook 'erc-match-message)))
+
+;; Remaining customizations
+
+(defcustom erc-pals nil
+ "List of pals on IRC."
+ :group 'erc-match
+ :type '(repeat regexp))
+
+(defcustom erc-fools nil
+ "List of fools on IRC."
+ :group 'erc-match
+ :type '(repeat regexp))
+
+(defcustom erc-keywords nil
+ "List of keywords to highlight in all incoming messages.
+Each entry in the list is either a regexp, or a cons cell with the
+regexp in the car and the face to use in the cdr. If no face is
+specified, `erc-keyword-face' is used."
+ :group 'erc-match
+ :type '(repeat (choice regexp
+ (list regexp face))))
+
+(defcustom erc-dangerous-hosts nil
+ "List of regexps for hosts to highlight.
+Useful to mark nicks from dangerous hosts."
+ :group 'erc-match
+ :type '(repeat regexp))
+
+(defcustom erc-current-nick-highlight-type 'keyword
+ "*Determines how to highlight text in which your current nickname appears
+\(does not apply to text sent by you\).
+
+The following values are allowed:
+
+ nil - do not highlight the message at all
+ 'keyword - highlight all instances of current nickname in message
+ 'nick - highlight the nick of the user who typed your nickname
+ 'nick-or-keyword - highlight the nick of the user who typed your nickname,
+ or all instances of the current nickname if there was
+ no sending user
+ 'all - highlight the entire message where current nickname occurs
+
+Any other value disables highlighting of current nickname altogether."
+ :group 'erc-match
+ :type '(choice (const nil)
+ (const nick)
+ (const keyword)
+ (const nick-or-keyword)
+ (const all)))
+
+(defcustom erc-pal-highlight-type 'nick
+ "*Determines how to highlight messages by pals.
+See `erc-pals'.
+
+The following values are allowed:
+
+ nil - do not highlight the message at all
+ 'nick - highlight pal's nickname only
+ 'all - highlight the entire message from pal
+
+Any other value disables pal highlighting altogether."
+ :group 'erc-match
+ :type '(choice (const nil)
+ (const nick)
+ (const all)))
+
+(defcustom erc-fool-highlight-type 'nick
+ "*Determines how to highlight messages by fools.
+See `erc-fools'.
+
+The following values are allowed:
+
+ nil - do not highlight the message at all
+ 'nick - highlight fool's nickname only
+ 'all - highlight the entire message from fool
+
+Any other value disables fool highlighting altogether."
+ :group 'erc-match
+ :type '(choice (const nil)
+ (const nick)
+ (const all)))
+
+(defcustom erc-keyword-highlight-type 'keyword
+ "*Determines how to highlight messages containing keywords.
+See variable `erc-keywords'.
+
+The following values are allowed:
+
+ 'keyword - highlight keyword only
+ 'all - highlight the entire message containing keyword
+
+Any other value disables keyword highlighting altogether."
+ :group 'erc-match
+ :type '(choice (const nil)
+ (const keyword)
+ (const all)))
+
+(defcustom erc-dangerous-host-highlight-type 'nick
+ "*Determines how to highlight messages by nicks from dangerous-hosts.
+See `erc-dangerous-hosts'.
+
+The following values are allowed:
+
+ 'nick - highlight nick from dangerous-host only
+ 'all - highlight the entire message from dangerous-host
+
+Any other value disables dangerous-host highlighting altogether."
+ :group 'erc-match
+ :type '(choice (const nil)
+ (const nick)
+ (const all)))
+
+
+(defcustom erc-log-matches-types-alist '((keyword . "ERC Keywords"))
+ "Alist telling ERC where to log which match types.
+Valid match type keys are:
+- keyword
+- pal
+- dangerous-host
+- fool
+- current-nick
+
+The other element of each cons pair in this list is the buffer name to
+use for the logged message."
+ :group 'erc-match
+ :type '(repeat (cons (choice :tag "Key"
+ (const keyword)
+ (const pal)
+ (const dangerous-host)
+ (const fool)
+ (const current-nick))
+ (string :tag "Buffer name"))))
+
+(defcustom erc-log-matches-flag 'away
+ "Flag specifying when matched message logging should happen.
+When nil, don't log any matched messages.
+When t, log messages.
+When 'away, log messages only when away."
+ :group 'erc-match
+ :type '(choice (const nil)
+ (const away)
+ (const t)))
+
+(defcustom erc-log-match-format "%t<%n:%c> %m"
+ "Format for matched Messages.
+This variable specifies how messages in the corresponding log buffers will
+be formatted. The various format specs are:
+
+%t Timestamp (uses `erc-timestamp-format' if non-nil or \"[%Y-%m-%d %H:%M] \")
+%n Nickname of sender
+%u Nickname!user@host of sender
+%c Channel in which this was received
+%m Message"
+ :group 'erc-match
+ :type 'string)
+
+(defcustom erc-beep-match-types '(current-nick)
+ "Types of matches to beep for when a match occurs.
+The function `erc-beep-on-match' needs to be added to `erc-text-matched-hook'
+for beeping to work."
+ :group 'erc-match
+ :type '(choice (repeat :tag "Beep on match" (choice
+ (const current-nick)
+ (const keyword)
+ (const pal)
+ (const dangerous-host)
+ (const fool)))
+ (const :tag "Don't beep" nil)))
+
+(defcustom erc-text-matched-hook '(erc-log-matches)
+ "Hook run when text matches a given match-type.
+Functions in this hook are passed as arguments:
+\(match-type nick!user@host message) where MATCH-TYPE is a symbol of:
+current-nick, keyword, pal, dangerous-host, fool"
+ :options '(erc-log-matches erc-hide-fools erc-beep-on-match)
+ :group 'erc-match
+ :type 'hook)
+
+;; Internal variables:
+
+;; This is exactly the same as erc-button-syntax-table. Should we
+;; just put it in erc.el
+(defvar erc-match-syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?\( "w" table)
+ (modify-syntax-entry ?\) "w" table)
+ (modify-syntax-entry ?\[ "w" table)
+ (modify-syntax-entry ?\] "w" table)
+ (modify-syntax-entry ?\{ "w" table)
+ (modify-syntax-entry ?\} "w" table)
+ (modify-syntax-entry ?` "w" table)
+ (modify-syntax-entry ?' "w" table)
+ (modify-syntax-entry ?^ "w" table)
+ (modify-syntax-entry ?- "w" table)
+ (modify-syntax-entry ?_ "w" table)
+ (modify-syntax-entry ?| "w" table)
+ (modify-syntax-entry ?\\ "w" table)
+ table)
+ "Syntax table used when highlighting messages.
+This syntax table should make all the legal nick characters word
+constituents.")
+
+;; Faces:
+
+(defface erc-current-nick-face '((t (:bold t :foreground "DarkTurquoise")))
+ "ERC face for occurrences of your current nickname."
+ :group 'erc-faces)
+
+(defface erc-dangerous-host-face '((t (:foreground "red")))
+ "ERC face for people on dangerous hosts.
+See `erc-dangerous-hosts'."
+ :group 'erc-faces)
+
+(defface erc-pal-face '((t (:bold t :foreground "Magenta")))
+ "ERC face for your pals.
+See `erc-pals'."
+ :group 'erc-faces)
+
+(defface erc-fool-face '((t (:foreground "dim gray")))
+ "ERC face for fools on the channel.
+See `erc-fools'."
+ :group 'erc-faces)
+
+(defface erc-keyword-face '((t (:bold t :foreground "pale green")))
+ "ERC face for your keywords.
+Note that this is the default face to use if
+`erc-keywords' does not specify another."
+ :group 'erc-faces)
+
+;; Functions:
+
+(defun erc-add-entry-to-list (list prompt &optional completions)
+ "Add an entry interactively to a list.
+LIST must be passed as a symbol
+The query happens using PROMPT.
+Completion is performed on the optional alist COMPLETIONS."
+ (let ((entry (completing-read
+ prompt
+ completions
+ (lambda (x)
+ (not (erc-member-ignore-case (car x) (symbol-value list)))))))
+ (if (erc-member-ignore-case entry (symbol-value list))
+ (error (format "\"%s\" is already on the list" entry))
+ (set list (cons entry (symbol-value list))))))
+
+(defun erc-remove-entry-from-list (list prompt)
+ "Remove an entry interactively from a list.
+LIST must be passed as a symbol.
+The elements of LIST can be strings, or cons cells where the
+car is the string."
+ (let* ((alist (mapcar (lambda (x)
+ (if (listp x)
+ x
+ (list x)))
+ (symbol-value list)))
+ (entry (completing-read
+ prompt
+ alist
+ nil
+ t)))
+ (if (erc-member-ignore-case entry (symbol-value list))
+ ;; plain string
+ (set list (delete entry (symbol-value list)))
+ ;; cons cell
+ (set list (delete (assoc entry (symbol-value list))
+ (symbol-value list))))))
+
+;;;###autoload
+(defun erc-add-pal ()
+ "Add pal interactively to `erc-pals'."
+ (interactive)
+ (erc-add-entry-to-list 'erc-pals "Add pal: " (erc-get-server-nickname-alist)))
+
+;;;###autoload
+(defun erc-delete-pal ()
+ "Delete pal interactively to `erc-pals'."
+ (interactive)
+ (erc-remove-entry-from-list 'erc-pals "Delete pal: "))
+
+;;;###autoload
+(defun erc-add-fool ()
+ "Add fool interactively to `erc-fools'."
+ (interactive)
+ (erc-add-entry-to-list 'erc-fools "Add fool: "
+ (erc-get-server-nickname-alist)))
+
+;;;###autoload
+(defun erc-delete-fool ()
+ "Delete fool interactively to `erc-fools'."
+ (interactive)
+ (erc-remove-entry-from-list 'erc-fools "Delete fool: "))
+
+;;;###autoload
+(defun erc-add-keyword ()
+ "Add keyword interactively to `erc-keywords'."
+ (interactive)
+ (erc-add-entry-to-list 'erc-keywords "Add keyword: "))
+
+;;;###autoload
+(defun erc-delete-keyword ()
+ "Delete keyword interactively to `erc-keywords'."
+ (interactive)
+ (erc-remove-entry-from-list 'erc-keywords "Delete keyword: "))
+
+;;;###autoload
+(defun erc-add-dangerous-host ()
+ "Add dangerous-host interactively to `erc-dangerous-hosts'."
+ (interactive)
+ (erc-add-entry-to-list 'erc-dangerous-hosts "Add dangerous-host: "))
+
+;;;###autoload
+(defun erc-delete-dangerous-host ()
+ "Delete dangerous-host interactively to `erc-dangerous-hosts'."
+ (interactive)
+ (erc-remove-entry-from-list 'erc-dangerous-hosts "Delete dangerous-host: "))
+
+(defun erc-match-current-nick-p (nickuserhost msg)
+ "Check whether the current nickname is in MSG.
+NICKUSERHOST will be ignored."
+ (with-syntax-table erc-match-syntax-table
+ (and msg
+ (string-match (concat "\\b"
+ (regexp-quote (erc-current-nick))
+ "\\b")
+ msg))))
+
+(defun erc-match-pal-p (nickuserhost msg)
+ "Check whether NICKUSERHOST is in `erc-pals'.
+MSG will be ignored."
+ (and nickuserhost
+ (erc-list-match erc-pals nickuserhost)))
+
+(defun erc-match-fool-p (nickuserhost msg)
+ "Check whether NICKUSERHOST is in `erc-fools' or MSG is directed at a fool."
+ (and msg nickuserhost
+ (or (erc-list-match erc-fools nickuserhost)
+ (erc-match-directed-at-fool-p msg))))
+
+(defun erc-match-keyword-p (nickuserhost msg)
+ "Check whether any keyword of `erc-keywords' matches for MSG.
+NICKUSERHOST will be ignored."
+ (and msg
+ (erc-list-match
+ (mapcar (lambda (x)
+ (if (listp x)
+ (car x)
+ x))
+ erc-keywords)
+ msg)))
+
+(defun erc-match-dangerous-host-p (nickuserhost msg)
+ "Check whether NICKUSERHOST is in `erc-dangerous-hosts'.
+MSG will be ignored."
+ (and nickuserhost
+ (erc-list-match erc-dangerous-hosts nickuserhost)))
+
+(defun erc-match-directed-at-fool-p (msg)
+ "Check whether MSG is directed at a fool.
+In order to do this, every entry in `erc-fools' will be used.
+In any of the following situations, MSG is directed at an entry FOOL:
+
+- MSG starts with \"FOOL: \" or \"FOO, \"
+- MSG contains \", FOOL.\" (actually, \"\\s. FOOL\\s.\")"
+ (let ((fools-beg (mapcar (lambda (entry)
+ (concat "^" entry "[:,] "))
+ erc-fools))
+ (fools-end (mapcar (lambda (entry)
+ (concat "\\s. " entry "\\s."))
+ erc-fools)))
+ (or (erc-list-match fools-beg msg)
+ (erc-list-match fools-end msg))))
+
+(defun erc-get-parsed-vector (point)
+ "Return the whole parsed vector on POINT."
+ (get-text-property point 'erc-parsed))
+
+(defun erc-get-parsed-vector-nick (vect)
+ "Return nickname in the parsed vector VECT."
+ (let* ((untreated-nick (and vect (erc-response.sender vect)))
+ (maybe-nick (when untreated-nick
+ (car (split-string untreated-nick "!")))))
+ (when (and (not (null maybe-nick))
+ (erc-is-valid-nick-p maybe-nick))
+ untreated-nick)))
+
+(defun erc-get-parsed-vector-type (vect)
+ "Return message type in the parsed vector VECT."
+ (and vect
+ (erc-response.command vect)))
+
+(defun erc-match-message ()
+ "Mark certain keywords in a region.
+Use this defun with `erc-insert-modify-hook'."
+ ;; This needs some refactoring.
+ (goto-char (point-min))
+ (let* ((to-match-nick-dep '("pal" "fool" "dangerous-host"))
+ (to-match-nick-indep '("keyword" "current-nick"))
+ (vector (erc-get-parsed-vector (point-min)))
+ (nickuserhost (erc-get-parsed-vector-nick vector))
+ (nickname (and nickuserhost
+ (nth 0 (erc-parse-user nickuserhost))))
+ (old-pt (point))
+ (nick-beg (and nickname
+ (re-search-forward (regexp-quote nickname)
+ (point-max) t)
+ (match-beginning 0)))
+ (nick-end (when nick-beg
+ (match-end 0)))
+ (message (buffer-substring (if (and nick-end
+ (<= (+ 2 nick-end) (point-max)))
+ (+ 2 nick-end)
+ (point-min))
+ (point-max))))
+ (when vector
+ (mapc
+ (lambda (match-type)
+ (goto-char (point-min))
+ (let* ((match-prefix (concat "erc-" match-type))
+ (match-pred (intern (concat "erc-match-" match-type "-p")))
+ (match-htype (eval (intern (concat match-prefix
+ "-highlight-type"))))
+ (match-regex (if (string= match-type "current-nick")
+ (regexp-quote (erc-current-nick))
+ (eval (intern (concat match-prefix "s")))))
+ (match-face (intern (concat match-prefix "-face"))))
+ (when (funcall match-pred nickuserhost message)
+ (cond
+ ;; Highlight the nick of the message
+ ((and (eq match-htype 'nick)
+ nick-end)
+ (erc-put-text-property
+ nick-beg nick-end
+ 'face match-face (current-buffer)))
+ ;; Highlight the nick of the message, or the current
+ ;; nick if there's no nick in the message (e.g. /NAMES
+ ;; output)
+ ((and (string= match-type "current-nick")
+ (eq match-htype 'nick-or-keyword))
+ (if nick-end
+ (erc-put-text-property
+ nick-beg nick-end
+ 'face match-face (current-buffer))
+ (goto-char (+ 2 (or nick-end
+ (point-min))))
+ (while (re-search-forward match-regex nil t)
+ (erc-put-text-property (match-beginning 0) (match-end 0)
+ 'face match-face))))
+ ;; Highlight the whole message
+ ((eq match-htype 'all)
+ (erc-put-text-property
+ (point-min) (point-max)
+ 'face match-face (current-buffer)))
+ ;; Highlight all occurrences of the word to be
+ ;; highlighted.
+ ((and (string= match-type "keyword")
+ (eq match-htype 'keyword))
+ (mapc (lambda (elt)
+ (let ((regex elt)
+ (face match-face))
+ (when (consp regex)
+ (setq regex (car elt)
+ face (cdr elt)))
+ (goto-char (+ 2 (or nick-end
+ (point-min))))
+ (while (re-search-forward regex nil t)
+ (erc-put-text-property
+ (match-beginning 0) (match-end 0)
+ 'face face))))
+ match-regex))
+ ;; Highlight all occurrences of our nick.
+ ((and (string= match-type "current-nick")
+ (eq match-htype 'keyword))
+ (goto-char (+ 2 (or nick-end
+ (point-min))))
+ (while (re-search-forward match-regex nil t)
+ (erc-put-text-property (match-beginning 0) (match-end 0)
+ 'face match-face)))
+ ;; Else twiddle your thumbs.
+ (t nil))
+ (run-hook-with-args
+ 'erc-text-matched-hook
+ (intern match-type)
+ (or nickuserhost
+ (concat "Server:" (erc-get-parsed-vector-type vector)))
+ message))))
+ (if nickuserhost
+ (append to-match-nick-dep to-match-nick-indep)
+ to-match-nick-indep)))))
+
+(defun erc-log-matches (match-type nickuserhost message)
+ "Log matches in a separate buffer, determined by MATCH-TYPE.
+The behaviour of this function is controlled by the variables
+`erc-log-matches-types-alist' and `erc-log-matches-flag'. Specify the
+match types which should be logged in the former, and
+deactivate/activate match logging in the latter. See
+`erc-log-match-format'."
+ (let ((match-buffer-name (cdr (assq match-type
+ erc-log-matches-types-alist)))
+ (nick (nth 0 (erc-parse-user nickuserhost))))
+ (when (and
+ (or (eq erc-log-matches-flag t)
+ (and (eq erc-log-matches-flag 'away)
+ erc-away))
+ match-buffer-name)
+ (let ((line (format-spec erc-log-match-format
+ (format-spec-make
+ ?n nick
+ ?t (format-time-string
+ (or (and (boundp 'erc-timestamp-format)
+ erc-timestamp-format)
+ "[%Y-%m-%d %H:%M] "))
+ ?c (or (erc-default-target) "")
+ ?m message
+ ?u nickuserhost))))
+ (with-current-buffer (erc-log-matches-make-buffer match-buffer-name)
+ (toggle-read-only -1)
+ (point-max)
+ (insert line)
+ (toggle-read-only 1))))))
+
+(defun erc-log-matches-make-buffer (name)
+ "Create or get a log-matches buffer named NAME and return it."
+ (let* ((buffer-already (get-buffer name))
+ (buffer (or buffer-already
+ (get-buffer-create name))))
+ (with-current-buffer buffer
+ (unless buffer-already
+ (insert " == Type \"q\" to dismiss messages ==\n")
+ (erc-view-mode-enter nil (lambda (buffer)
+ (when (y-or-n-p "Discard messages?")
+ (kill-buffer buffer)))))
+ buffer)))
+
+(defun erc-log-matches-come-back (proc parsed)
+ "Display a notice that messages were logged while away."
+ (when (and erc-away
+ (eq erc-log-matches-flag 'away))
+ (mapc
+ (lambda (match-type)
+ (let ((buffer (get-buffer (cdr match-type)))
+ (buffer-name (cdr match-type)))
+ (when buffer
+ (let* ((last-msg-time (erc-emacs-time-to-erc-time
+ (with-current-buffer buffer
+ (get-text-property (1- (point-max))
+ 'timestamp))))
+ (away-time (erc-emacs-time-to-erc-time erc-away)))
+ (when (and away-time last-msg-time
+ (erc-time-gt last-msg-time away-time))
+ (erc-display-message
+ nil 'notice 'active
+ (format "You have logged messages waiting in \"%s\"."
+ buffer-name))
+ (erc-display-message
+ nil 'notice 'active
+ (format "Type \"C-c C-k %s RET\" to view them."
+ buffer-name)))))))
+ erc-log-matches-types-alist))
+ nil)
+
+; This handler must be run _before_ erc-process-away is.
+(add-hook 'erc-server-305-functions 'erc-log-matches-come-back nil)
+
+(defun erc-go-to-log-matches-buffer ()
+ "Interactively open an erc-log-matches buffer."
+ (interactive)
+ (let ((buffer-name (completing-read "Switch to ERC Log buffer: "
+ (mapcar (lambda (x)
+ (cons (cdr x) t))
+ erc-log-matches-types-alist)
+ (lambda (buffer-cons)
+ (get-buffer (car buffer-cons))))))
+ (switch-to-buffer buffer-name)))
+
+(define-key erc-mode-map "\C-c\C-k" 'erc-go-to-log-matches-buffer)
+
+(defun erc-hide-fools (match-type nickuserhost message)
+ "Hide foolish comments.
+This function should be called from `erc-text-matched-hook'."
+ (when (eq match-type 'fool)
+ (erc-put-text-properties (point-min) (point-max)
+ '(invisible intangible)
+ (current-buffer))))
+
+(defun erc-beep-on-match (match-type nickuserhost message)
+ "Beep when text matches.
+This function is meant to be called from `erc-text-matched-hook'."
+ (when (member match-type erc-beep-match-types)
+ (beep)))
+
+(provide 'erc-match)
+
+;;; erc-match.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 1f1f595e-abcc-4b0b-83db-598a1d3f0f82
diff --git a/lisp/erc/erc-menu.el b/lisp/erc/erc-menu.el
new file mode 100644
index 00000000000..8e1f81adf75
--- /dev/null
+++ b/lisp/erc/erc-menu.el
@@ -0,0 +1,121 @@
+;; erc-menu.el -- Menu-bar definitions for ERC
+
+;; Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Keywords: comm, processes, menu
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcMenu
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Loading this file defines a menu for ERC.
+
+;;; Code:
+
+(require 'easymenu)
+
+(defvar erc-menu-definition
+ (list "IRC"
+ ["Connect to server..." erc-select t]
+ ["Disconnect from server..." erc-quit-server erc-server-connected]
+ "-"
+ ["List channels..." erc-cmd-LIST
+ (and erc-server-connected (fboundp 'erc-cmd-LIST))]
+ ["Join channel..." erc-join-channel erc-server-connected]
+ ["Start a query..." erc-cmd-QUERY erc-server-connected]
+ "-"
+ ["List users in channel" erc-channel-names erc-channel-users]
+ ["List channel operators" erc-cmd-OPS erc-channel-users]
+ ["Input action..." erc-input-action (erc-default-target)]
+ ["Set topic..." erc-set-topic
+ (and (and (erc-default-target) (not (erc-query-buffer-p)))
+ (or (not (member "t" erc-channel-modes))
+ (erc-channel-user-op-p (erc-current-nick))))]
+ (list "Channel modes"
+ ["Change mode..." erc-insert-mode-command
+ (erc-channel-user-op-p (erc-current-nick))]
+ ["No external send" (erc-toggle-channel-mode "n")
+ :active (erc-channel-user-op-p (erc-current-nick))
+ :style toggle :selected (member "n" erc-channel-modes)]
+ ["Topic set by channel operator" (erc-toggle-channel-mode "t")
+ :style toggle :selected (member "t" erc-channel-modes)
+ :active (erc-channel-user-op-p (erc-current-nick))]
+ ["Invite only" (erc-toggle-channel-mode "i")
+ :style toggle :selected (member "i" erc-channel-modes)
+ :active (erc-channel-user-op-p (erc-current-nick))]
+ ["Private" (erc-toggle-channel-mode "p")
+ :style toggle :selected (member "p" erc-channel-modes)
+ :active (erc-channel-user-op-p (erc-current-nick))]
+ ["Secret" (erc-toggle-channel-mode "s")
+ :style toggle :selected (member "s" erc-channel-modes)
+ :active (erc-channel-user-op-p (erc-current-nick))]
+ ["Moderated" (erc-toggle-channel-mode "m")
+ :style toggle :selected (member "m" erc-channel-modes)
+ :active (erc-channel-user-op-p (erc-current-nick))]
+ ["Set a limit..." erc-set-channel-limit
+ (erc-channel-user-op-p (erc-current-nick))]
+ ["Set a key..." erc-set-channel-key
+ (erc-channel-user-op-p (erc-current-nick))])
+ ["Leave this channel..." erc-part-from-channel erc-channel-users]
+ "-"
+ (list "Pals, fools and other keywords"
+ ["Add pal..." erc-add-pal]
+ ["Delete pal..." erc-delete-pal]
+ ["Add fool..." erc-add-fool]
+ ["Delete fool..." erc-delete-fool]
+ ["Add keyword..." erc-add-keyword]
+ ["Delete keyword..." erc-delete-keyword]
+ ["Add dangerous host..." erc-add-dangerous-host]
+ ["Delete dangerous host..." erc-delete-dangerous-host])
+ "-"
+ (list "IRC services"
+ ["Identify to NickServ..." erc-nickserv-identify
+ (and erc-server-connected (functionp 'erc-nickserv-identify))])
+ "-"
+ ["Save buffer in log" erc-save-buffer-in-logs
+ (fboundp 'erc-save-buffer-in-logs)]
+ ["Truncate buffer" erc-truncate-buffer (fboundp 'erc-truncate-buffer)]
+ "-"
+ ["Customize ERC" (customize-group 'erc) t]
+ ["Enable/Disable ERC Modules" (customize-variable 'erc-modules) t]
+ ["Show ERC version" erc-version t])
+ "ERC menu definition.")
+
+;; `erc-mode-map' must be defined before doing this
+(eval-after-load "erc"
+ '(progn
+ (easy-menu-define erc-menu erc-mode-map "ERC menu" erc-menu-definition)
+ (easy-menu-add erc-menu erc-mode-map)
+
+ ;; for some reason the menu isn't automatically added to the menu bar
+ (when (featurep 'xemacs)
+ (add-hook 'erc-mode-hook
+ (lambda () (easy-menu-add erc-menu erc-mode-map))))))
+
+(provide 'erc-menu)
+
+;;; erc-menu.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 671219f2-b082-4753-a185-1d0c7e0c05bd
diff --git a/lisp/erc/erc-nets.el b/lisp/erc/erc-nets.el
new file mode 100644
index 00000000000..716a42996d5
--- /dev/null
+++ b/lisp/erc/erc-nets.el
@@ -0,0 +1,861 @@
+;;; erc-nets.el --- IRC networks
+
+;; Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@lexx.delysid.org>
+;; Keywords: comm
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file deals with IRC networks.
+;;
+;; Usage:
+;;
+;; Put into your .emacs:
+;;
+;; (require 'erc-nets)
+;;
+;; M-x erc-server-select provides an alternative way to connect to servers by
+;; choosing networks.
+;; You can use (eq (erc-network) 'Network) if you'd like to set variables or do
+;; certain actions according to which network you're connected to.
+;; If a network you use is not listed in `erc-networks-alist', you can put
+;; (add-to-list 'erc-networks-alist '(Network "irc.server-name.net")) in your
+;; config file.
+
+;;; Code:
+
+(require 'erc)
+(eval-when-compile (require 'cl))
+
+;; Variables
+
+(defgroup erc-networks nil
+ "IRC Networks"
+ :group 'erc)
+
+(defcustom erc-server-alist
+'(("4-irc: Random server" 4-irc "4-irc.com" 6667)
+ ("A5KNet: Random server" A5KNet "irc.a5knet.com" ((6660 6669)))
+ ("AbleNet: Random server" AbleNet "irc.ablenet.org" 6667)
+ ("Accessirc: Random server" Accessirc "irc.accessirc.net" 6667)
+ ("Acestar: Random server" Acestar "irc.acestar.org" 6667)
+ ("Action-IRC: Random server" Action-IRC "irc.action-irc.net" ((6660 6669)))
+ ("AfterNET: Random server" AfterNET "irc.afternet.org" 6667)
+ ("Alternativenet: Random server" Alternativenet "irc.altnet.org" 6667)
+ ("AmigaNet: Random server" AmigaNet "irc.amiganet.org" 6667)
+ ("AngelEyez: Random server" AngelEyez "irc.angeleyez.net" ((6666 7000)))
+ ("AnotherNet: Random server" Anothernet "irc.another.net" (6667 7000 ))
+ ("ArabChat: Random server" ArabChat "irc.arabchat.org" ((6660 6667)))
+ ("AsiaTalk: Random server" AsiaTalk "irc.asiatalk.org" ((6667 6669) 7000 ))
+ ("AstroLink: Random server" AstroLink "irc.astrolink.org" ((6660 6667)))
+ ("Asylumnet: Random server" Asylumnet "irc.asylum-net.org" ((6661 6669) 7000 7777 ))
+ ("Austnet: Random AU server" Austnet "au.austnet.org" 6667)
+ ("Austnet: Random NZ server" Austnet "nz.austnet.org" 6667)
+ ("Austnet: Random SG server" Austnet "sg.austnet.org" 6667)
+ ("Austnet: Random US server" Austnet "us.austnet.org" 6667)
+ ("AwesomeChat: Random server" AwesomeChat "irc.awesomechat.net" ((6661 6669)))
+ ("Awesomechristians: Random server" Awesomechristians "irc.awesomechristians.com" 7000)
+ ("Axenet: Random server" Axenet "irc.axenet.org" ((6660 6667)))
+ ("BeyondIRC: Random server" Beyondirc "irc.beyondirc.net" ((6660 6669)))
+ ("BGIRC: Random server" BGIRC "irc.bulgaria.org" ((6666 6669) 7000 ))
+ ("Blabbernet: Random server" Blabbernet "irc.blabber.net" (6667 7000 ))
+ ("Blitzed: Random server" Blitzed "irc.blitzed.org" (6667 7000 ))
+ ("Brasirc: Random server" Brasirc "irc.brasirc.net" ((6666 6667)))
+ ("Brasirc: BR, PA, Belem" Brasirc "irc.libnet.com.br" ((6666 6668) 7777 8002 ))
+ ("BRASnet: Random European server" BRASnet "eu.brasnet.org" ((6665 6669)))
+ ("BRASnet: Random US server" BRASnet "us.brasnet.org" ((6665 6669)))
+ ("BubbleNet: Random server" BubbleNet "irc.bubblenet.org" ((6667 6669)))
+ ("CCnet: Random server" CCnet "irc.cchat.net" (6667 7000 ))
+ ("CCnet: US, TX, Dallas" CCnet "irc2.cchat.net" (6667 7000 ))
+ ("Chat-Net: Random server" Chat-Net "irc.chat-net.org" 6667)
+ ("Chat-Solutions: Random server" Chat-Solutions "irc.chat-solutions.org" 6667)
+ ("Chatcafe: Random server" Chatcafe "irc.chatcafe.net" 6667)
+ ("Chatchannel: Random server" Chatchannel "irc.chatchannel.org" ((6666 6669) 7000 ))
+ ("ChatCircuit: Random server" ChatCircuit "irc.chatcircuit.com" 6668)
+ ("Chatlink: Random server" Chatlink "irc.chatlink.org" 6667)
+ ("Chatnet: Random AU server" Chatnet "au.chatnet.org" 6667)
+ ("Chatnet: Random EU server" Chatnet "eu.chatnet.org" 6667)
+ ("Chatnet: Random US server" Chatnet "us.chatnet.org" 6667)
+ ("ChatNut: Random server" ChatNut "irc.chatnut.net" (6667 7000 ))
+ ("Chatpinoy: Random server" Chatpinoy "irc.chatpinoy.com" 6667)
+ ("ChatPR: Random server" ChatPR "irc.chatpr.org" 6667)
+ ("Chatroom: Random server" Chatroom "irc.chatroom.org" 6667)
+ ("Chatster: Random server" Chatster "irc.chatster.org" 6667)
+ ("ChatX: Random server" ChatX "irc.chatx.net" 6667)
+ ("China263: Random server" China263 "irc.263.net" 6667)
+ ("Cineplex1: Random server" Cineplex1 "irc.cineplex1.com" ((6666 6668)))
+ ("CNN: CNN News discussions" CNN "chat.cnn.com" ((6667 6669) 7000 ))
+ ("CobraNet: Random server" CobraNet "irc.cobra.net" 6667)
+ ("Coolchat: Random server" Coolchat "irc.coolchat.net" 6667)
+ ("Criten: Random server" Criten "irc.criten.net" 6667)
+ ("Cyberchat: Random server" Cyberchat "irc.cyberchat.org" (6667 6668 ))
+ ("CyGanet: Random server" CyGanet "irc.cyga.net" 6667)
+ ("DALnet: AS, MY, Coins" DALnet "coins.dal.net" ((6663 6668) 7000 ))
+ ("DALnet: CA, ON, Sodre" DALnet "sodre.on.ca.dal.net" ((6661 6669) 7000 ))
+ ("DALnet: EU, DE, Nexgo" DALnet "nexgo.de.eu.dal.net" ((6664 6669) 7000 ))
+ ("DALnet: EU, NO, Powertech" DALnet "powertech.no.eu.dal.net" ((6666 6667) 7000 ))
+ ("DALnet: EU, SE, Borg" DALnet "borg.se.eu.dal.net" (6667 7000 ))
+ ("DALnet: EU, SE, Ced" DALnet "ced.se.eu.dal.net" (6667 7000 ))
+ ("DALnet: US, GA, Astro" DALnet "astro.ga.us.dal.net" ((6661 6669) 7000 ))
+ ("DALnet: US, GA, Dragons" DALnet "dragons.ga.us.dal.net" ((6661 6669) 7000 ))
+ ("DALnet: US, GA, Elysium" DALnet "elysium.ga.us.dal.net" ((6661 6669) 7000 ))
+ ("DALnet: US, MA, Twisted" DALnet "twisted.ma.us.dal.net" ((6660 6669) 7001 7002 ))
+ ("DALnet: US, MO, Global" DALnet "global.mo.us.dal.net" ((6661 6669) 7000 ))
+ ("DALnet: US, NJ, Liberty" DALnet "liberty.nj.us.dal.net" ((6662 6669) 7000 ))
+ ("DALnet: US, VA, Wombat" DALnet "wombat.va.us.dal.net" ((6661 6669) 7000 ))
+ ("DALnet: Random EU server" DALnet "irc.eu.dal.net" 6667)
+ ("DALnet: Random US server" DALnet "irc.dal.net" ((6660 6667)))
+ ("Dark-Tou-Net: Random server" Dark-Tou-Net "irc.d-t-net.de" 6667)
+ ("Darkfire: Random server" Darkfire "irc.darkfire.net" (6667 7000 8000 ))
+ ("DarkMyst: Random server" DarkMyst "irc.darkmyst.org" 6667)
+ ("Darkserv: Random server" Darkserv "irc.darkserv.net" 6667)
+ ("Darksystem: Random server" Darksystem "irc.darksystem.com" 6667)
+ ("Darktree: Random server" Darktree "irc.darktree.net" 6667)
+ ("DayNet: Random server" DayNet "irc.daynet.org" 6667)
+ ("Deepspace: Disability network" Deepspace "irc.deepspace.org" 6667)
+ ("Different: Random server" Different "irc.different.net" 6667)
+ ("Digarix: Random server" Digarix "irc.digarix.net" 6667)
+ ("Digatech: Random server" Digatech "irc.digatech.net" 6667)
+ ("Digital-Base: Random server" Digital-Base "irc.digital-base.net" ((6660 7000)))
+ ("Digitalirc: Random server" Digitalirc "irc.digitalirc.net" 6667)
+ ("Discussioni: Random server" Discussioni "irc.discussioni.org" ((6666 6669)))
+ ("DorukNet: TR, Istanbul" DorukNet "irc.doruk.net.tr" ((6660 6669) 7000 8888 ))
+ ("Dreamcast: Random server" Dreamcast "irc0.dreamcast.com" 6667)
+ ("DWChat: Random server" DWChat "irc.dwchat.net" 6667)
+ ("Dynastynet: Random server" Dynastynet "irc.dynastynet.net" 6667)
+ ("EFnet: CA, AB, Edmonton (arcti)" EFnet "irc.arcti.ca" 6667)
+ ("EFnet: CA, AB, Edmonton (mpls)" EFnet "irc.mpls.ca" ((6660 6669)))
+ ("EFnet: CA, ON, Toronto" EFnet "irc2.magic.ca" 6667)
+ ("EFnet: CA, QB, Montreal" EFnet "irc.qeast.net" 6667)
+ ("EFnet: EU, DK, Aarhus" EFnet "irc.inet.tele.dk" 6667)
+ ("EFnet: EU, FI, Helsinki" EFnet "efnet.cs.hut.fi" 6667)
+ ("EFnet: EU, FR, Paris" EFnet "irc.isdnet.fr" ((6667 6669)))
+ ("EFnet: EU, NL, Amsterdam" EFnet "efnet.vuurwerk.nl" 6667)
+ ("EFnet: EU, NO, Homelien" EFnet "irc.homelien.no" (5190 (6666 6667) (7000 7001) ))
+ ("EFnet: EU, NO, Oslo" EFnet "irc.daxnet.no" ((6666 7000)))
+ ("EFnet: EU, PL, Warszawa" EFnet "irc.efnet.pl" 6667)
+ ("EFnet: EU, RU, Moscow" EFnet "irc.rt.ru" ((6661 6669)))
+ ("EFnet: EU, SE, Dalarna" EFnet "irc.du.se" ((6666 6669)))
+ ("EFnet: EU, SE, Gothenberg" EFnet "irc.hemmet.chalmers.se" ((6666 7000)))
+ ("EFnet: EU, SE, Sweden" EFnet "irc.light.se" 6667)
+ ("EFnet: EU, UK, London (carrier)" EFnet "irc.carrier1.net.uk" ((6666 6669)))
+ ("EFnet: EU, UK, London (demon)" EFnet "efnet.demon.co.uk" ((6665 6669)))
+ ("EFnet: ME, IL, Inter" EFnet "irc.inter.net.il" ((6665 6669)))
+ ("EFnet: US, AZ, Phoenix" EFnet "irc.easynews.com" (6660 (6665 6667) 7000 ))
+ ("EFnet: US, CA, San Jose" EFnet "irc.concentric.net" ((6665 6668)))
+ ("EFnet: US, CA, San Luis Obispo" EFnet "irc.prison.net" ((6666 6667)))
+ ("EFnet: US, GA, Atlanta" EFnet "irc.mindspring.com" ((6660 6669)))
+ ("EFnet: US, MI, Ann Arbor" EFnet "irc.umich.edu" 6667)
+ ("EFnet: US, MN, Twin Cities" EFnet "irc.umn.edu" ((6665 6669)))
+ ("EFnet: US, NY, Mineola" EFnet "irc.lightning.net" ((6665 7000)))
+ ("EFnet: US, NY, New York (east)" EFnet "irc.east.gblx.net" 6667)
+ ("EFnet: US, NY, New York (flamed)" EFnet "irc.flamed.net" ((6665 6669)))
+ ("EFnet: US, TX, Houston" EFnet "ircd.lagged.org" ((6660 6669)))
+ ("EFnet: US, VA, Ashburn" EFnet "irc.secsup.uu.net" ((6665 6669) 8080 ))
+ ("EFnet: Random AU server" EFnet "au.rr.efnet.net" 6667)
+ ("EFnet: Random CA server" EFnet "ca.rr.efnet.net" 6667)
+ ("EFnet: Random EU server" EFnet "eu.rr.efnet.net" 6667)
+ ("EFnet: Random US server" EFnet "us.rr.efnet.net" 6667)
+ ("EgyptianIRC: Random server" EgyptianIRC "irc.egyptianirc.net" ((6667 6669)))
+ ("Eircnet: Random server" Eircnet "irc.eircnet.org" ((6660 6669) 7000 ))
+ ("Eleethal: Random server" Eleethal "irc.eleethal.com" ((6660 6669) 7000 ))
+ ("EntertheGame: Random server" EntertheGame "irc.enterthegame.com" ((6667 6669)))
+ ("EpiKnet: Random server" EpiKnet "irc.epiknet.org" ((6660 6669) 7000 7001 ))
+ ("EsperNet: Random server" EsperNet "irc.esper.net" (5555 (6667 6669) ))
+ ("Esprit: Random server" Esprit "irc.esprit.net" 6667)
+ ("euIRC: Random server" euIRC "irc.euirc.net" ((6665 6669)))
+ ("Evilzinc: Random server" Evilzinc "irc.evilzinc.net" ((6660 6669) 7000 8000 ))
+ ("ExodusIRC: Random server" ExodusIRC "irc.exodusirc.net" ((6660 6669)))
+ ("FDFnet: Random server" FDFnet "irc.fdfnet.net" ((6666 6668) 9999 ))
+ ("FEFnet: Random server" FEFnet "irc.fef.net" 6667)
+ ("Financialchat: Random server" Financialchat "irc.financialchat.com" ((6667 6669) 7000 ))
+ ("Forestnet: Random server" Forestnet "irc.forestnet.org" (6667 7000 ))
+ ("ForeverChat: Random server" ForeverChat "irc.foreverchat.net" ((6660 6669) 7000 ))
+ ("Fraggers: Random server" Fraggers "irc.fraggers.co.uk" ((6661 6669) (7000 7001) ))
+ ("FreedomChat: Random server" FreedomChat "chat.freedomchat.net" 6667)
+ ("FreedomIRC: Random server" FreedomIRC "irc.freedomirc.net" 6667)
+ ("Freenode: Random server" freenode "irc.freenode.net" 6667)
+ ("Freenode: Random EU server" freenode "irc.eu.freenode.net" 6667)
+ ("Freenode: Random US server" freenode "irc.us.freenode.net" 6667)
+ ("FunNet: Random server" FunNet "irc.funnet.org" 6667)
+ ("Galaxynet: Random server" GalaxyNet "irc.galaxynet.org" ((6662 6668) 7000 ))
+ ("Galaxynet: AU, NZ, Auckland" GalaxyNet "auckland.nz.galaxynet.org" ((6661 6669)))
+ ("Galaxynet: EU, BE, Online" GalaxyNet "online.be.galaxynet.org" ((6661 6669)))
+ ("Galaxynet: US, FL, Florida" GalaxyNet "gymnet.us.galaxynet.org" ((6661 6669)))
+ ("Gamesnet: Random east US server" Gamesnet "east.gamesnet.net" 6667)
+ ("Gamesnet: Random west US server" Gamesnet "west.gamesnet.net" 6667)
+ ("GammaForce: Random server" GammaForce "irc.gammaforce.org" ((6660 6669) 7000 ))
+ ("GIKInet: Random server" GIKInet "irc.giki.edu.pk" 6667)
+ ("GizNet: Random server" GizNet "irc.giznet.org" ((6666 6669) 7000 ))
+ ("Globalchat: Random server" Globalchat "irc.globalchat.org" 6667)
+ ("GlobIRC: Random server" GlobIRC "irc.globirc.net" ((6666 6668) 9999 ))
+ ("Goldchat: Random server" Goldchat "irc.goldchat.nl" ((6660 6669) 7000 ))
+ ("Goodchatting: Random server" Goodchatting "irc.goodchatting.com" ((6661 6669) 7000 ))
+ ("GravityLords: Random server" GravityLords "irc.gravitylords.net" 6667)
+ ("Grnet: Random EU server" GRnet "gr.irc.gr" (6667 7000 ))
+ ("Grnet: Random server" GRnet "srv.irc.gr" (6667 7000 ))
+ ("Grnet: Random US server" GRnet "us.irc.gr" (6667 7000 ))
+ ("GulfChat: Random server" GulfChat "irc.gulfchat.net" ((6660 6669)))
+ ("HabberNet: Random server" HabberNet "irc.habber.net" 6667)
+ ("HanIRC: Random server" HanIRC "irc.hanirc.org" 6667)
+ ("Hellenicnet: Random server" Hellenicnet "irc.mirc.gr" (6667 7000 ))
+ ("IceNet: Random server" IceNet "irc.icenet.org.za" 6667)
+ ("ICQnet: Random server" ICQnet "irc.icq.com" 6667)
+ ("Infatech: Random server" Infatech "irc.infatech.net" ((6660 6669)))
+ ("Infinity: Random server" Infinity "irc.infinity-irc.org" 6667)
+ ("Infomatrix: Random server" Infomatrix "irc.infomatrix.net" 6667)
+ ("Inside3D: Random server" Inside3D "irc.inside3d.net" ((6661 6669)))
+ ("InterlinkChat: Random server" InterlinkChat "irc.interlinkchat.net" ((6660 6669) 7000 ))
+ ("IRC-Chile: Random server" IRC-Chile "irc.cl" 6667)
+ ("IRC-Hispano: Random server" IRC-Hispano "irc.irc-hispano.org" 6667)
+ ("IRCchat: Random server" IRCchat "irc.ircchat.tk" 6667)
+ ("IRCGate: Random server" IRCGate "irc.ircgate.net" ((6667 6669)))
+ ("IRCGeeks: Random server" IRCGeeks "irc.ircgeeks.org" ((6660 6669)))
+ ("IRChat: Random server" IRChat "irc.irchat.net" ((6660 6669)))
+ ("IrcLordz: Random server" IrcLordz "irc.irclordz.com" 6667)
+ ("IrcMalta: Random server" IrcMalta "irc.ircmalta.org" ((6660 6667)))
+ ("IRCnet: EU, FR, Random" IRCnet "irc.fr.ircnet.net" 6667)
+ ("IRCnet: EU, IT, Random" IRCnet "irc.ircd.it" ((6665 6669)))
+ ("IRCnet: AS, IL, Haifa" IRCnet "ircnet.netvision.net.il" ((6661 6668)))
+ ("IRCnet: AS, JP, Tokyo" IRCnet "irc.tokyo.wide.ad.jp" 6667)
+ ("IRCnet: AS, TW, Seed" IRCnet "irc.seed.net.tw" 6667)
+ ("IRCnet: EU, AT, Linz" IRCnet "linz.irc.at" ((6666 6668)))
+ ("IRCnet: EU, AT, Wien" IRCnet "vienna.irc.at" ((6666 6669)))
+ ("IRCnet: EU, BE, Brussels" IRCnet "irc.belnet.be" 6667)
+ ("IRCnet: EU, BE, Zaventem" IRCnet "ircnet.wanadoo.be" ((6661 6669)))
+ ("IRCnet: EU, CZ, Prague" IRCnet "irc.felk.cvut.cz" 6667)
+ ("IRCnet: EU, DE, Berlin" IRCnet "irc.fu-berlin.de" ((6665 6669)))
+ ("IRCnet: EU, DE, Dusseldorf" IRCnet "irc.freenet.de" ((6665 6669)))
+ ("IRCnet: EU, DE, Stuttgart" IRCnet "irc.belwue.de" ((6665 6669)))
+ ("IRCnet: EU, DK, Copenhagen" IRCnet "irc.ircnet.dk" 6667)
+ ("IRCnet: EU, EE, Tallinn" IRCnet "irc.estpak.ee" ((6666 6668)))
+ ("IRCnet: EU, FI, Helsinki" IRCnet "irc.cs.hut.fi" 6667)
+ ("IRCnet: EU, GR, Thessaloniki" IRCnet "irc.ee.auth.gr" ((6666 6669)))
+ ("IRCnet: EU, HU, Budapest" IRCnet "irc.elte.hu" 6667)
+ ("IRCnet: EU, IS, Reykjavik (ircnet)" IRCnet "irc.ircnet.is" ((6661 6669)))
+ ("IRCnet: EU, IS, Reykjavik (simnet)" IRCnet "irc.simnet.is" ((6661 6669)))
+ ("IRCnet: EU, IT, Rome" IRCnet "irc.tin.it" ((6665 6669)))
+ ("IRCnet: EU, NL, Amsterdam (nlnet)" IRCnet "irc.nl.uu.net" ((6660 6669)))
+ ("IRCnet: EU, NL, Amsterdam (xs4all)" IRCnet "irc.xs4all.nl" ((6660 6669)))
+ ("IRCnet: EU, NL, Enschede" IRCnet "irc.snt.utwente.nl" ((6660 6669)))
+ ("IRCnet: EU, NL, Nijmegen" IRCnet "irc.sci.kun.nl" ((6660 6669)))
+ ("IRCnet: EU, NO, Oslo" IRCnet "irc.ifi.uio.no" 6667)
+ ("IRCnet: EU, NO, Trondheim" IRCnet "irc.pvv.ntnu.no" 6667)
+ ("IRCnet: EU, PL, Lublin" IRCnet "lublin.irc.pl" ((6666 6668)))
+ ("IRCnet: EU, PL, Warsaw" IRCnet "warszawa.irc.pl" ((6666 6668)))
+ ("IRCnet: EU, RU, Moscow" IRCnet "irc.msu.ru" 6667)
+ ("IRCnet: EU, SE, Lulea" IRCnet "irc.ludd.luth.se" ((6661 6669)))
+ ("IRCnet: EU, UK, London (Demon)" IRCnet "ircnet.demon.co.uk" ((6665 6669)))
+ ("IRCnet: EU, UK, London (Easynet)" IRCnet "ircnet.easynet.co.uk" ((6666 6669)))
+ ("IRCnet: US, NY, New York" IRCnet "irc.stealth.net" ((6660 6669)))
+ ("IRCnet: Random AU server" IRCnet "au.ircnet.org" 6667)
+ ("IRCnet: Random EU server" IRCnet "eu.ircnet.org" ((6665 6668)))
+ ("IRCnet: Random US server" IRCnet "us.ircnet.org" ((6665 6668)))
+ ("IRCSoulZ: Random server" IRCSoulZ "irc.ircsoulz.net" 6667)
+ ("IRCSul: BR, PR, Maringa" IRCSul "irc.wnet.com.br" 6667)
+ ("IrcTalk: Random server" IrcTalk "irc.irctalk.net" ((6660 6669)))
+ ("Irctoo: Random server" Irctoo "irc.irctoo.net" 6667)
+ ("IRCtown: Random server" IRCtown "irc.irctown.net" ((6666 6669) 7000 ))
+ ("IRCworld: Random server" IRCworld "irc.ircworld.org" 6667)
+ ("ircXtreme: Random server" ircXtreme "irc.ircXtreme.net" ((6660 6669)))
+ ("Israelnet: Random server" Israelnet "irc.israel.net" 6667)
+ ("K0wNet: Random server" K0wNet "irc.k0w.net" ((6660 6669)))
+ ("KDFSnet: Random server" KDFSnet "irc.kdfs.net" ((6667 6669)))
+ ("Kemik: Random server" Kemik "irc.kemik.net" 6667)
+ ("Kewl.Org: Random server" Kewl.Org "irc.kewl.org" (6667 7000 ))
+ ("Kickchat: Random server" Kickchat "irc.kickchat.com" ((6660 6669) 7000 ))
+ ("Kidsworld: Random server" KidsWorld "irc.kidsworld.org" ((6666 6669)))
+ ("Knightnet: AF, ZA, Durban" Knightnet "orc.dbn.za.knightnet.net" (6667 5555 ))
+ ("Knightnet: US, CA, Goldengate" Knightnet "goldengate.ca.us.knightnet.net" (6667 5555 ))
+ ("Konfido.Net: Random server" Konfido.Net "irc.konfido.net" 6667)
+ ("KreyNet: Random server" Kreynet "irc.krey.net" 6667)
+ ("Krono: Random server" Krono "irc.krono.net" ((6660 6669) 7000 ))
+ ("Krushnet: Random server" Krushnet "irc.krushnet.org" 6667)
+ ("LagNet: Random server" LagNet "irc.lagnet.org.za" 6667)
+ ("LagNet: AF, ZA, Cape Town" LagNet "reaper.lagnet.org.za" 6667)
+ ("LagNet: AF, ZA, Johannesburg" LagNet "mystery.lagnet.org.za" 6667)
+ ("Librenet: Random server" Librenet "irc.librenet.net" 6667)
+ ("LinkNet: Random server" LinkNet "irc.link-net.org" ((6667 6669)))
+ ("Liquidized: Random server" Liquidized "irc.liquidized.net" (6667 7000 ))
+ ("M-IRC: Random server" M-IRC "irc.m-sys.org" ((6667 6669)))
+ ("MagicStar: Random server" MagicStar "irc.magicstar.net" 6667)
+ ("Mavra: Random server" Mavra "irc.mavra.net" 6667)
+ ("MediaDriven: Random server" MediaDriven "irc.mediadriven.com" ((6667 6669)))
+ ("mIRC-X: Random server" mIRC-X "irc.mircx.com" (6667 7000 ))
+ ("Morat: Random server" Morat "irc.morat.net" 6667)
+ ("MusicCity: Random server" MusicCity "chat.musiccity.com" 6667)
+ ("Mysteria: Random server" Mysteria "irc.mysteria.net" (6667 7000 ))
+ ("Mysterychat: Random server" Mysterychat "irc.mysterychat.net" ((6667 6669)))
+ ("Mystical: Random server" Mystical "irc.mystical.net" (6667 7000 ))
+ ("Narancs: Random server" Narancs "irc.narancs.com" ((6667 6669) 7000 ))
+ ("Net-France: Random server" Net-France "irc.net-france.com" 6667)
+ ("Nevernet: Random server" Nevernet "irc.nevernet.net" 6667)
+ ("Newnet: Random server" Newnet "irc.newnet.net" ((6665 6667)))
+ ("Nexusirc: Random server" Nexusirc "irc.nexusirc.org" 6667)
+ ("Nightstar: Random server" NightStar "irc.nightstar.net" ((6665 6669)))
+ ("NitrousNet: Random server" NitrousNet "irc.nitrousnet.net" 6667)
+ ("Novernet: Random server" Novernet "irc.novernet.com" ((6665 6669) 7000 ))
+ ("Nullrouted: Random server" Nullrouted "irc.nullrouted.org" ((6666 6669) 7000 ))
+ ("NullusNet: Random server" NullusNet "irc.nullus.net" 6667)
+ ("OpChat: Random server" OpChat "irc.opchat.org" ((6667 6669)))
+ ("Othernet: Random server" Othernet "irc.othernet.org" 6667)
+ ("Othernet: US, FL, Miami" Othernet "miami.fl.us.othernet.org" 6667)
+ ("Othernet: US, MO, StLouis" Othernet "stlouis.mo.us.othernet.org" 6667)
+ ("Otherside: Random server" OtherSide "irc.othersideirc.net" 6667)
+ ("Outsiderz: Random server" Outsiderz "irc.outsiderz.com" 6667)
+ ("OzOrg: AU, Perth" OzOrg "iinet.perth.oz.org" 6667)
+ ("Peacefulhaven: Random server" Peacefulhaven "irc.peacefulhaven.net" ((6660 6669) 7000 ))
+ ("PhazedIRC: Random server" PhazedIRC "irc.phazedirc.net" 6667)
+ ("Philchat: Random server" Philchat "irc.philchat.net" 6667)
+ ("phrozN: Random server" phrozN "irc.phrozn.net" 6667)
+ ("PiNet: Random server" PiNet "irc.praetorians.org" ((6665 6669)))
+ ("Pinoycentral: Random server" Pinoycentral "chat.abs-cbn.com" 6667)
+ ("Planetarion: Random server" Planetarion "irc.planetarion.com" 6667)
+ ("POLNet: Random server" POLNet "irc.ircnet.pl" 6667)
+ ("Psionics: CA, PQ, Montreal" Psionics "chat.psionics.net" ((6660 6669)))
+ ("PTirc: Random server" PTirc "irc.ptirc.com.pt" 6667)
+ ("PTlink: Random server" PTlink "irc.ptlink.net" 6667)
+ ("PTnet: Random server" PTnet "irc.ptnet.org" 6667)
+ ("QChat: Random server" QChat "irc.qchat.net" 6667)
+ ("QuakeNet: Random German server" QuakeNet "de.quakenet.org" ((6667 6669)))
+ ("QuakeNet: Random server" QuakeNet "irc.quakenet.eu.org" ((6667 6669)))
+ ("QuakeNet: Random Swedish server" QuakeNet "se.quakenet.org" ((6667 6669)))
+ ("QuakeNet: Random UK server" QuakeNet "uk.quakenet.org" ((6667 6669)))
+ ("QuakeNet: Random US server" QuakeNet "us.quakenet.org" ((6667 6669)))
+ ("Realirc: Random server" Realirc "irc.realirc.org" 6667)
+ ("RealmNET: Random server" RealmNET "irc.realmnet.com" 6667)
+ ("Rebelchat: Random server" Rebelchat "irc.rebelchat.org" 6667)
+ ("Red-Latina: Random server" Red-Latina "irc.red-latina.org" 6667)
+ ("RedLatona: Random server" RedLatona "irc.redlatona.net" (6667 6668 ))
+ ("Relicnet: Random server" Relicnet "irc.relic.net" 6667)
+ ("Rezosup: Random server" Rezosup "irc.rezosup.org" 6667)
+ ("Risanet: Random server" Risanet "irc.risanet.com" ((6667 6669)))
+ ("Rubiks: Random server" Rubiks "irc.rubiks.net" 6667)
+ ("Rusnet: EU, RU, Tomsk" Rusnet "irc.tsk.ru" ((6667 6669) (7770 7775) ))
+ ("Rusnet: EU, RU, Vladivostok" Rusnet "irc.vladivostok.ru" ((6667 6669) (7770 7775) ))
+ ("Rusnet: EU, UA, Kiev" Rusnet "irc.kar.net" ((6667 6669) (7770 7775) ))
+ ("Sandnet: Random server" Sandnet "irc.sandnet.net" ((6660 6669) 7000 ))
+ ("Scunc: Random server" Scunc "irc.scunc.net" 6667)
+ ("SerbianCafe: Random server" SerbianCafe "irc.serbiancafe.ws" ((6665 6669)))
+ ("SexNet: Random server" SexNet "irc.sexnet.org" 6667)
+ ("ShadowFire: Random server" ShadowFire "irc.shadowfire.org" 6667)
+ ("ShadowWorld: Random server" ShadowWorld "irc.shadowworld.net" 6667)
+ ("SkyNet: Random server" SkyNet "irc.bronowski.pl" ((6666 6668)))
+ ("Slashnet: Random server" Slashnet "irc.slashnet.org" 6667)
+ ("SolarStone: Random server" SolarStone "irc.solarstone.net" ((6660 6669)))
+ ("Sorcerynet: Random server" Sorcery "irc.sorcery.net" (6667 7000 9000 ))
+ ("Sorcerynet: EU, SE, Karlskrona" Sorcery "nexus.sorcery.net" (6667 7000 9000 ))
+ ("Sorcerynet: US, CA, Palo Alto" Sorcery "kechara.sorcery.net" (6667 7000 9000 ))
+ ("SourceIRC: Random server" SourceIRC "irc.sourceirc.net" ((6667 6669) 7000 ))
+ ("SpaceTronix: Random server" SpaceTronix "irc.spacetronix.net" ((6660 6669) 7000 ))
+ ("Spirit-Harmony: Random server" Spirit-Harmony "irc.spirit-harmony.com" ((6661 6669)))
+ ("StarChat: Random server" StarChat "irc.starchat.net" ((6667 6669) 7000 ))
+ ("StarEquinox: Random server" StarEquinox "irc.starequinox.net" ((6660 6669)))
+ ("StarLink: Random server" Starlink "irc.starlink.net" ((6660 6669)))
+ ("StarLink-irc: Random server" starlink-irc "irc.starlink-irc.org" 6667)
+ ("StarWars-IRC: Random server" StarWars-IRC "irc.starwars-irc.net" ((6663 6667)))
+ ("Stormdancing: Random server" Stormdancing "irc.stormdancing.net" ((6664 6669) 7000 9000 ))
+ ("Superchat: Random server" Superchat "irc.superchat.org" ((6660 6668)))
+ ("Sysopnet: Random server" Sysopnet "irc.sysopnet.org" ((6666 6668)))
+ ("Telstra: Random server" Telstra "irc.telstra.com" ((6667 6669)))
+ ("TR-net: EU, TR, Ankara" TR-net "irc.dominet.com.tr" 6667)
+ ("TR-net: EU, Tr, Istanbul" TR-net "irc.teklan.com.tr" 6667)
+ ("Tri-net: Random server" Tri-net "irc.tri-net.org" 6667)
+ ("TriLink: Random server" TriLink "irc.ft4u.net" 6667)
+ ("TurkishChat: Random server" TurkishChat "irc.turkishchat.org" ((6660 6669) 7000 ))
+ ("UberNinja: Random server" UberNinja "irc.uberninja.net" ((6667 6669)))
+ ("UICN: Random server" UICN "irc.uicn.net" 6667)
+ ("UltraIRC: Random server" UltraIRC "irc.ultrairc.net" 6667)
+ ("UnderChat: Random server" UnderChat "irc.underchat.it" ((6660 6669) 7000 ))
+ ("Undernet: CA, ON, Toronto" Undernet "toronto.on.ca.undernet.org" ((6661 6669)))
+ ("Undernet: CA, QC, Montreal" Undernet "montreal.qu.ca.undernet.org" ((6660 6669)))
+ ("Undernet: EU, AT, Graz" Undernet "graz.at.eu.undernet.org" ((6661 6669)))
+ ("Undernet: EU, BE, Antwerp" Undernet "flanders.be.eu.undernet.org" ((6660 6669)))
+ ("Undernet: EU, BE, Brussels" Undernet "brussels.be.eu.undernet.org" 6667)
+ ("Undernet: EU, CH, Geneva" Undernet "geneva.ch.eu.undernet.org" ((6660 6669) 7777 8000 ))
+ ("Undernet: EU, FR, Caen" Undernet "caen.fr.eu.undernet.org" ((6666 6669)))
+ ("Undernet: EU, NL, Diemen" Undernet "diemen.nl.eu.undernet.org" ((6660 6669)))
+ ("Undernet: EU, NL, Haarlem" Undernet "haarlem.nl.eu.undernet.org" ((6660 6669)))
+ ("Undernet: EU, NO, Oslo" Undernet "oslo.no.eu.undernet.org" ((6660 6669)))
+ ("Undernet: EU, SE, Stockholm" Undernet "stockholm.se.eu.undernet.org" ((6666 6669)))
+ ("Undernet: EU, UK, Surrey" Undernet "surrey.uk.eu.undernet.org" ((6660 6669)))
+ ("Undernet: US, AZ, Mesa" Undernet "mesa.az.us.undernet.org" ((6665 6667)))
+ ("Undernet: US, CA, San Diego" Undernet "sandiego.ca.us.undernet.org" ((6660 6670)))
+ ("Undernet: US, DC, Washington" Undernet "washington.dc.us.undernet.org" ((6660 6669)))
+ ("Undernet: US, KS, Manhattan" Undernet "manhattan.ks.us.undernet.org" ((6660 6669)))
+ ("Undernet: US, NV, Las Vegas" Undernet "lasvegas.nv.us.undernet.org" ((6660 6669)))
+ ("Undernet: US, TX, Austin" Undernet "austin.tx.us.undernet.org" ((6660 6669)))
+ ("Undernet: US, UT, Saltlake" Undernet "saltlake.ut.us.undernet.org" ((6660 6669)))
+ ("Undernet: US, VA, Arlington" Undernet "arlington.va.us.undernet.org" ((6660 6669)))
+ ("Undernet: US, VA, McLean" Undernet "mclean.va.us.undernet.org" ((6666 6669)))
+ ("Undernet: Random EU server" Undernet "eu.undernet.org" 6667)
+ ("Undernet: Random US server" Undernet "us.undernet.org" 6667)
+ ("UnderZ: Random server" UnderZ "irc.underz.org" ((6667 6668)))
+ ("UniChat: Random server" UniChat "irc.uni-chat.net" 6667)
+ ("UnionLatina: Random server" UnionLatina "irc.unionlatina.org" 6667)
+ ("Univers: Random server" Univers "irc.univers.org" ((6665 6669)))
+ ("UnixR: Random server" UnixR "irc.unixr.net" ((6667 6669)))
+ ("Vidgamechat: Random server" Vidgamechat "irc.vidgamechat.com" 6667)
+ ("VirtuaNet: Random server" VirtuaNet "irc.virtuanet.org" ((6660 6669) 7000 ))
+ ("Vitamina: Random server" Vitamina "irc.vitamina.ca" 6667)
+ ("Voila: Random server" Voila "irc.voila.fr" 6667)
+ ("Wahou: Random server" Wahou "irc.wahou.org" ((6665 6669)))
+ ("Warpednet: Random server" Warpednet "irc.warped.net" 6667)
+ ("Weaklinks: Random server" Weaklinks "irc.weaklinks.net" ((6667 6669)))
+ ("Webnet: Random server" Webnet "irc.webchat.org" ((6667 6669) 7000 ))
+ ("Webnet: US, CA, Santa Clara" Webnet "webmaster.ca.us.webchat.org" ((6661 6669)))
+ ("WinChat: Random server" WinChat "irc.winchat.net" ((6661 6669)))
+ ("WinIRC: Random server" WinIRC "irc.winirc.org" ((6667 6669) 4400 ))
+ ("WorldIRC: Random server" WorldIRC "irc.worldirc.org" ((6660 6667)))
+ ("WyldRyde: Random server" WyldRyde "irc.wyldryde.net" ((6666 6669)))
+ ("XentoniX: Random server" XentoniX "irc.xentonix.net" ((6661 6669)))
+ ("Xevion: Random server" Xevion "irc.xevion.net" (6667 7000 ))
+ ("XNet: Random server" XNet "irc.xnet.org" 6667)
+ ("XWorld: Random server" XWorld "irc.xworld.org" 6667)
+ ("ZAnet Net: Random server" ZAnetNet "irc.zanet.net" 6667)
+ ("ZAnet Org: UK, London" ZAnetOrg "mystic.zanet.org.za" 6667)
+ ("ZiRC: Random server" ZiRC "irc.zirc.org" ((6660 6669)))
+ ("ZUHnet: Random server" ZUHnet "irc.zuh.net" 6667)
+ ("Zurna: Random server" Zurna "irc.zurna.net" 6667))
+ "Alist of irc servers. (NAME NET HOST PORTS) where
+NAME is a name for that server,
+NET is a symbol indicating to which network from `erc-networks-alist' this
+ server corresponds,
+HOST is the servers hostname and
+PORTS is either a number, a list of numbers, or a list of port ranges."
+ :group 'erc-networks
+ :type 'sexp)
+
+(defcustom erc-networks-alist
+ '((4-irc "4-irc.com")
+ (A5KNet "a5knet.com")
+ (AbleNet "ablenet.org")
+ (Accessirc "accessirc.net")
+ (Acestar "acestar.org")
+ (Action-IRC "action-irc.net")
+ (AfterNET "afternet.org")
+ (Alternativenet "altnet.org")
+ (AmigaNet "amiganet.org")
+ (AngelEyez "angeleyez.net")
+ (Anothernet "another.net")
+ (ArabChat "arabchat.org")
+ (AsiaTalk "asiatalk.org")
+ (AstroLink "astrolink.org")
+ (Asylumnet "asylumnet.org")
+ (Austnet "austnet.org")
+ (AwesomeChat "awesomechat.net")
+ (Awesomechristians "awesomechristians.com")
+ (Axenet "axenet.org")
+ (Beyondirc "beyondirc.net")
+ (BGIRC "bulgaria.org")
+ (Blabbernet "blabber.net")
+ (Blitzed "blitzed.org")
+ (BrasIRC "brasirc.net")
+ (BRASnet "brasnet.org")
+ (BubbleNet "bubblenet.org")
+ (CCnet "christian-chat.net")
+ (Chat-Net "chat-net.org")
+ (Chat-Solutions "chat-solutions.org")
+ (Chatcafe "chatcafe.net")
+ (Chatchannel "chatchannel.org")
+ (ChatCircuit "chatcircuit.com")
+ (Chatlink "chatlink.org")
+ (Chatnet "chatnet.org")
+ (ChatNut "chatnut.net")
+ (Chatpinoy "chatpinoy.com")
+ (ChatPR "chatpr.org")
+ (Chatroom "chatroom.org")
+ (Chatster "chatster.org")
+ (ChatX "chatx.net")
+ (China263 "263.net")
+ (Cineplex1 "cineplex1.com")
+ (CNN "cnn.com")
+ (CobraNet "cobra.net")
+ (Coolchat "coolchat.net")
+ (Criten "criten.net")
+ (Cyberchat "cyberchat.org")
+ (CyGanet "cyga.net")
+ (DALnet "dal.net")
+ (Dark-Tou-Net "d-t-net.de")
+ (Darkfire "darkfire.net")
+ (DarkMyst "darkmyst.org")
+ (Darkserv "darkserv.net")
+ (Darksystem "darksystem.com")
+ (Darktree "darktree.net")
+ (DayNet "daynet.org")
+ (Deepspace "deepspace.org")
+ (Different "different.net")
+ (Digarix "digarix.net")
+ (Digatech "digatech.net")
+ (Digital-Base "digital-base.net")
+ (Digitalirc "digitalirc.net")
+ (Discussioni "discussioni.org")
+ (DorukNet "doruk.net.tr")
+ (DWChat "dwchat.net")
+ (Dynastynet "dynastynet.net")
+ (EFnet nil)
+ (EgyptianIRC "egyptianirc.net")
+ (Eircnet "eircnet.org")
+ (Eleethal "eleethal.com")
+ (EntertheGame "enterthegame.com")
+ (EpiKnet "epiknet.org")
+ (EsperNet "esper.net")
+ (Esprit "esprit.net")
+ (euIRC "euirc.net")
+ (Evilzinc "evilzinc.net")
+ (ExodusIRC "exodusirc.net")
+ (FDFnet "fdfnet.net")
+ (FEFnet "fef.net")
+ (Financialchat "financialchat.com")
+ (Forestnet "forestnet.org")
+ (ForeverChat "foreverchat.net")
+ (Fraggers "fraggers.co.uk")
+ (FreedomChat "freedomchat.net")
+ (FreedomIRC "freedomirc.net")
+ (freenode "freenode.net")
+ (FunNet "funnet.org")
+ (GalaxyNet "galaxynet.org")
+ (Gamesnet "gamesnet.net")
+ (GammaForce "gammaforce.org")
+ (GIKInet "giki.edu.pk")
+ (GizNet "giznet.org")
+ (Globalchat "globalchat.org")
+ (GlobIRC "globirc.net")
+ (Goldchat "goldchat.nl")
+ (Goodchatting "goodchatting.com")
+ (GravityLords "gravitylords.net")
+ (GRnet "irc.gr")
+ (GulfChat "gulfchat.net")
+ (HabberNet "habber.net")
+ (HanIRC "hanirc.org")
+ (Hellenicnet "mirc.gr")
+ (IceNet "icenet.org.za")
+ (ICQnet "icq.com")
+ (iip "anon.iip")
+ (Infatech "infatech.net")
+ (Infinity "infinity-irc.org")
+ (Infomatrix "infomatrix.net")
+ (Inside3D "inside3d.net")
+ (InterlinkChat "interlinkchat.net")
+ (IRC-Chile "irc.cl")
+ (IRC-Hispano "irc-hispano.org")
+ (IRCchat "ircchat.tk")
+ (IRCGate "ircgate.net")
+ (IRCGeeks "ircgeeks.org")
+ (IRChat "irchat.net")
+ (IrcLordz "irclordz.com")
+ (IrcMalta "ircmalta.org")
+ (IRCnet nil)
+ (IRCSoulZ "ircsoulz.net")
+ (IRCSul "wnet.com.br")
+ (IrcTalk "irctalk.net")
+ (Irctoo "irctoo.net")
+ (IRCtown "irc.irctown.net")
+ (IRCworld "ircworld.org")
+ (ircXtreme "ircXtreme.net")
+ (Israelnet "israel.net")
+ (K0wNet "k0w.net")
+ (KDFSnet "kdfs.net")
+ (Kemik "kemik.net")
+ (Kewl\.Org "kewl.org")
+ (Kickchat "kickchat.com")
+ (KidsWorld "kidsworld.org")
+ (Knightnet "knightnet.net")
+ (Konfido\.Net "konfido.net")
+ (Kreynet "krey.net")
+ (Krono "krono.net")
+ (Krushnet "krushnet.org")
+ (LagNet "lagnet.org.za")
+ (Librenet "librenet.net")
+ (LinkNet "link-net.org")
+ (Liquidized "liquidized.net")
+ (M-IRC "m-sys.org")
+ (MagicStar "magicstar.net")
+ (Mavra "mavra.net")
+ (MediaDriven "mediadriven.com")
+ (mIRC-X "mircx.com")
+ (Morat "morat.net")
+ (MusicCity "musiccity.com")
+ (Mysteria "mysteria.net")
+ (Mysterychat "mysterychat.net")
+ (Mystical "mystical.net")
+ (Narancs "narancs.com")
+ (Net-France "net-france.com")
+ (Nevernet "nevernet.net")
+ (Newnet "newnet.net")
+ (Nexusirc "nexusirc.org")
+ (NightStar "nightstar.net")
+ (NitrousNet "nitrousnet.net")
+ (Novernet "novernet.com")
+ (Nullrouted "nullrouted.org")
+ (NullusNet "nullus.net")
+ (OpChat "opchat.org")
+ (Openprojects "openprojects.net")
+ (Othernet "othernet.org")
+ (OtherSide "othersideirc.net")
+ (Outsiderz "outsiderz.com")
+ (OzOrg "oz.org")
+ (Peacefulhaven "peacefulhaven.net")
+ (PhazedIRC "phazedirc.net")
+ (Philchat "philchat.net")
+ (phrozN "phrozn.net")
+ (PiNet "praetorians.org")
+ (Pinoycentral "abs-cbn.com")
+ (Planetarion "planetarion.com")
+ (POLNet "ircnet.pl")
+ (Psionics "psionics.net")
+ (PTirc "ptirc.com.pt")
+ (PTlink "ptlink.net")
+ (PTnet "ptnet.org")
+ (QChat "qchat.net")
+ (QuakeNet "quakenet.org")
+ (Realirc "realirc.org")
+ (RealmNET "realmnet.com")
+ (Rebelchat "rebelchat.org")
+ (Red-Latina "red-latina.org")
+ (RedLatona "redlatona.net")
+ (Relicnet "relic.net")
+ (Rezosup "rezosup.org")
+ (Risanet "risanet.com")
+ (Rubiks "rubiks.net")
+ (Rusnet "nil")
+ (Sandnet "sandnet.net")
+ (Scunc "scunc.net")
+ (SerbianCafe "serbiancafe.ws")
+ (SexNet "sexnet.org")
+ (ShadowFire "shadowfire.org")
+ (ShadowWorld "shadowworld.net")
+ (SkyNet "bronowski.pl")
+ (SlashNET "slashnet.org")
+ (SolarStone "solarstone.net")
+ (Sorcery "sorcery.net")
+ (SourceIRC "sourceirc.net")
+ (SpaceTronix "spacetronix.net")
+ (Spirit-Harmony "spirit-harmony.com")
+ (StarChat "starchat.net")
+ (StarEquinox "starequinox.net")
+ (Starlink "starlink.net")
+ (starlink-irc "starlink-irc.org")
+ (StarWars-IRC "starwars-irc.net")
+ (Stormdancing "stormdancing.net")
+ (Superchat "superchat.org")
+ (Sysopnet "sysopnet.org")
+ (Telstra "telstra.com")
+ (TR-net "dominet.com.tr")
+ (Tri-net "tri-net.org")
+ (TriLink "ft4u.net")
+ (TurkishChat "turkishchat.org")
+ (UberNinja "uberninja.net")
+ (UICN "uicn.net")
+ (UltraIRC "ultrairc.net")
+ (UnderChat "underchat.it")
+ (Undernet "undernet.org")
+ (UnderZ "underz.org")
+ (UniChat "irc.uni-chat.net")
+ (UnionLatina "unionlatina.org")
+ (Univers "univers.org")
+ (UnixR "unixr.net")
+ (Vidgamechat "vidgamechat.com")
+ (VirtuaNet "virtuanet.org")
+ (Vitamina "vitamina.ca")
+ (Voila "voila.fr")
+ (Wahou "wf-net.org")
+ (Warpednet "warped.net")
+ (Weaklinks "weaklinks.net")
+ (Webnet "webchat.org")
+ (WinChat "winchat.net")
+ (WinIRC "winirc.org")
+ (WorldIRC "worldirc.org")
+ (WyldRyde "wyldryde.net")
+ (XentoniX "xentonix.net")
+ (Xevion "xevion.net")
+ (XNet "xnet.org")
+ (XWorld "xworld.org")
+ (ZAnetNet "zanet.net")
+ (ZAnetOrg "zanet.org.za")
+ (ZiRC "zirc.org")
+ (ZUHnet "zuh.net")
+ (Zurna "zurna.net"))
+ "Alist of IRC networks. (NET MATCHER) where
+NET is a symbol naming that IRC network and
+MATCHER is used to find a corresponding network to a server while connected to
+ it. If it is regexp, it's used to match against `erc-server-announced-name'.
+ It can also be a function (predicate). Then it is executed with the
+ server buffer as current-buffer."
+ :group 'erc-networks
+ :type '(repeat
+ (list :tag "Network"
+ (symbol :tag "Network name")
+ (choice :tag "Network's common server ending"
+ (regexp)
+ (const :tag "Network has no common server ending" nil)))))
+
+(defvar erc-network nil
+ "The name of the network you are connected to (a symbol).")
+(make-variable-buffer-local 'erc-network)
+
+;; Functions:
+
+;;;###autoload
+(defun erc-determine-network ()
+ "Return the name of the network or \"Unknown\" as a symbol. Use the
+server parameter NETWORK if provided, otherwise parse the server name and
+search for a match in `erc-networks-alist'."
+ ;; The server made it easy for us and told us the name of the NETWORK
+ (if (assoc "NETWORK" erc-server-parameters)
+ (intern (cdr (assoc "NETWORK" erc-server-parameters)))
+ (or
+ ;; Loop through `erc-networks-alist' looking for a match.
+ (let ((server (or erc-server-announced-name erc-session-server)))
+ (loop for (name matcher) in erc-networks-alist
+ when (and matcher
+ (string-match (concat matcher "\\'") server))
+ do (return name)))
+ 'Unknown)))
+
+(defun erc-network ()
+ "Return the value of `erc-network' for the current server."
+ (with-current-buffer (erc-server-buffer) erc-network))
+
+(defun erc-current-network ()
+ "Deprecated. Use `erc-network' instead. Return the name of this server's
+network as a symbol."
+ (with-current-buffer (erc-server-buffer)
+ (intern (downcase (symbol-name erc-network)))))
+
+(erc-make-obsolete 'erc-current-network 'erc-network
+ "Obsolete since erc-nets 1.5")
+
+(defun erc-network-name ()
+ "Returns the name of the current network as a string."
+ (with-current-buffer (erc-server-buffer) (symbol-name erc-network)))
+
+(defun erc-set-network-name (proc parsed)
+ "Set `erc-network' to the value returned by `erc-determine-network'."
+ (unless erc-server-connected
+ (setq erc-network (erc-determine-network)))
+ nil)
+
+(defun erc-unset-network-name (nick ip reason)
+ "Set `erc-network' to nil."
+ (setq erc-network nil)
+ nil)
+
+(add-hook 'erc-server-375-functions 'erc-set-network-name)
+(add-hook 'erc-server-422-functions 'erc-set-network-name)
+(add-hook 'erc-disconnected-hook 'erc-unset-network-name)
+
+(defun erc-ports-list (ports)
+ "Return a list of PORTS.
+
+PORTS should be a list of either:
+ A number, in which case it is returned a list.
+ Or a pair of the form (LOW HIGH), in which case, a list of all the
+ numbers between LOW and HIGH (inclusive) is returned.
+
+As an example:
+ (erc-ports-list '(1)) => (1)
+ (erc-ports-list '((1 5))) => (1 2 3 4 5)
+ (erc-ports-list '(1 (3 5))) => (1 3 4 5)"
+ (let (result)
+ (dolist (p ports)
+ (cond ((numberp p)
+ (push p result))
+ ((listp p)
+ (setq result (nconc (loop for i from (cadr p) downto (car p)
+ collect i)
+ result)))))
+ (nreverse result)))
+
+;;;###autoload
+(defun erc-server-select ()
+ "Interactively select a server to connect to using `erc-server-alist'."
+ (interactive)
+ (let* ((completion-ignore-case t)
+ (net (intern
+ (completing-read "Network: "
+ (erc-delete-dups
+ (mapcar (lambda (x)
+ (list (symbol-name (nth 1 x))))
+ erc-server-alist)))))
+ (srv (assoc
+ (completing-read "Server: "
+ (delq nil
+ (mapcar (lambda (x)
+ (when (equal (nth 1 x) net)
+ x))
+ erc-server-alist)))
+ erc-server-alist))
+ (host (nth 2 srv))
+ (ports (if (listp (nth 3 srv))
+ (erc-ports-list (nth 3 srv))
+ (list (nth 3 srv))))
+ (port (nth (random (length ports)) ports)))
+ (erc host port erc-nick erc-user-full-name t)))
+
+;;; The following experimental
+;; It does not work yet, help me with it if you
+;; think it is worth the effort.
+
+(defvar erc-settings
+ '((pals freenode ("kensanata" "shapr" "anti\\(fuchs\\|gone\\)"))
+ (format-nick-function (freenode "#emacs") erc-format-@nick))
+ "Experimental: Alist of configuration options.
+The format is (VARNAME SCOPE VALUE) where
+VARNAME is a symbol identifying the configuration option,
+SCOPE is either a symbol which identifies an entry from
+ `erc-networks-alist' or a list (NET TARGET) where NET is a network symbol and
+ TARGET is a string identifying the channel/query target.
+VALUE is the options value.")
+
+(defun erc-get (var &optional net target)
+ (let ((items erc-settings)
+ elt val)
+ (while items
+ (setq elt (car items)
+ items (cdr items))
+ (when (eq (car elt) var)
+ (cond ((and net target (listp (nth 1 elt))
+ (eq net (car (nth 1 elt)))
+ (string-equal target (nth 1 (nth 1 elt))))
+ (setq val (nth 2 elt)
+ items nil))
+ ((and net (eq net (nth 1 elt)))
+ (setq val (nth 2 elt)
+ items nil))
+ ((and (not net) (not target) (not (nth 1 elt)))
+ (setq val (nth 2 elt)
+ items nil)))))
+ val))
+
+(erc-get 'pals 'freenode)
+
+
+(provide 'erc-nets)
+
+;;; erc-nets.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 68cccabd-f66b-456c-9abe-5f993a2dc91c
diff --git a/lisp/erc/erc-netsplit.el b/lisp/erc/erc-netsplit.el
new file mode 100644
index 00000000000..70ec2f2fc0d
--- /dev/null
+++ b/lisp/erc/erc-netsplit.el
@@ -0,0 +1,212 @@
+;;; erc-netsplit.el --- Reduce JOIN/QUIT messages on netsplits
+
+;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Keywords: comm
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This module hides quit/join messages if a netsplit occurs.
+;; To enable, add the following to your ~/.emacs:
+;; (require 'erc-netsplit)
+;; (erc-netsplit-mode 1)
+
+;;; Code:
+
+(require 'erc)
+(eval-when-compile (require 'cl))
+
+(defgroup erc-netsplit nil
+ "Netsplit detection tries to automatically figure when a
+netsplit happens, and filters the QUIT messages. It also keeps
+track of netsplits, so that it can filter the JOIN messages on a netjoin too."
+ :group 'erc)
+
+;;;###autoload (autoload 'erc-netsplit-mode "erc-netsplit")
+(define-erc-module netsplit nil
+ "This mode hides quit/join messages if a netsplit occurs."
+ ((erc-netsplit-install-message-catalogs)
+ (add-hook 'erc-server-JOIN-functions 'erc-netsplit-JOIN)
+ (add-hook 'erc-server-MODE-functions 'erc-netsplit-MODE)
+ (add-hook 'erc-server-QUIT-functions 'erc-netsplit-QUIT)
+ (add-hook 'erc-timer-hook 'erc-netsplit-timer))
+ ((remove-hook 'erc-server-JOIN-functions 'erc-netsplit-JOIN)
+ (remove-hook 'erc-server-MODE-functions 'erc-netsplit-MODE)
+ (remove-hook 'erc-server-QUIT-functions 'erc-netsplit-QUIT)
+ (remove-hook 'erc-timer-hook 'erc-netsplit-timer)))
+
+(defcustom erc-netsplit-show-server-mode-changes-flag nil
+ "Set to t to enable display of server mode changes."
+ :group 'erc-netsplit
+ :type 'boolean)
+
+(defcustom erc-netsplit-debug nil
+ "If non-nil, debug messages will be shown in the
+sever buffer."
+ :group 'erc-netsplit
+ :type 'boolean)
+
+(defcustom erc-netsplit-regexp "^[^ @!\"]+\\.[^ @!]+ [^ @!]+\\.[^ @!\"]+$"
+ "This regular expression should match quit reasons produced
+by netsplits."
+ :group 'erc-netsplit
+ :type 'regexp)
+
+(defcustom erc-netsplit-hook nil
+ "Run whenever a netsplit is detected the first time.
+Args: PROC is the process the netsplit originated from and
+ SPLIT is the netsplit (e.g. \"server.name.1 server.name.2\")."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-netjoin-hook nil
+ "Run whenever a netjoin is detected the first time.
+Args: PROC is the process the netjoin originated from and
+ SPLIT is the netsplit (e.g. \"server.name.1 server.name.2\")."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defvar erc-netsplit-list nil
+ "This is a list of the form
+\((\"a.b.c.d e.f.g\" TIMESTAMP FIRST-JOIN \"nick1\" ... \"nickn\") ...)
+where FIRST-JOIN is t or nil, depending on whether or not the first
+join from that split has been detected or not.")
+(make-variable-buffer-local 'erc-netsplit-list)
+
+(defun erc-netsplit-install-message-catalogs ()
+ (erc-define-catalog
+ 'english
+ '((netsplit . "netsplit: %s")
+ (netjoin . "netjoin: %s, %N were split")
+ (netjoin-done . "netjoin: All lost souls are back!")
+ (netsplit-none . "No netsplits in progress")
+ (netsplit-wholeft . "split: %s missing: %n %t"))))
+
+(defun erc-netsplit-JOIN (proc parsed)
+ "Show/don't show rejoins."
+ (let ((nick (erc-response.sender parsed))
+ (no-next-hook nil))
+ (dolist (elt erc-netsplit-list)
+ (if (member nick (nthcdr 3 elt))
+ (progn
+ (if (not (caddr elt))
+ (progn
+ (erc-display-message
+ parsed 'notice (process-buffer proc)
+ 'netjoin ?s (car elt) ?N (length (nthcdr 3 elt)))
+ (setcar (nthcdr 2 elt) t)
+ (run-hook-with-args 'erc-netjoin-hook proc (car elt))))
+ ;; need to remove this nick, perhaps the whole entry here.
+ ;; Note that by removing the nick now, we can't tell if further
+ ;; join messages (for other channels) should also be
+ ;; suppressed.
+ (if (null (nthcdr 4 elt))
+ (progn
+ (erc-display-message
+ parsed 'notice (process-buffer proc)
+ 'netjoin-done ?s (car elt))
+ (setq erc-netsplit-list (delq elt erc-netsplit-list)))
+ (delete nick elt))
+ (setq no-next-hook t))))
+ no-next-hook))
+
+(defun erc-netsplit-MODE (proc parsed)
+ "Hide mode changes from servers."
+ ;; regexp matches things with a . in them, and no ! or @ in them.
+ (when (string-match "^[^@!]+\\.[^@!]+$" (erc-response.sender parsed))
+ (and erc-netsplit-debug
+ (erc-display-message
+ parsed 'notice (process-buffer proc)
+ "[debug] server mode change."))
+ (not erc-netsplit-show-server-mode-changes-flag)))
+
+(defun erc-netsplit-QUIT (proc parsed)
+ "Detect netsplits."
+ (let ((split (erc-response.contents parsed))
+ (nick (erc-response.sender parsed))
+ ass)
+ (when (string-match erc-netsplit-regexp split)
+ (setq ass (assoc split erc-netsplit-list))
+ (if ass
+ ;; element for this netsplit exists already
+ (progn
+ (setcdr (nthcdr 2 ass) (cons nick (nthcdr 3 ass)))
+ (when (caddr ass)
+ ;; There was already a netjoin for this netsplit, it
+ ;; seems like the old one didn't get finished...
+ (erc-display-message
+ parsed 'notice (process-buffer proc)
+ 'netsplit ?s split)
+ (setcar (nthcdr 2 ass) t)
+ (run-hook-with-args 'erc-netsplit-hook proc split)))
+ ;; element for this netsplit does not yet exist
+ (setq erc-netsplit-list
+ (cons (list split
+ (erc-current-time)
+ nil
+ nick)
+ erc-netsplit-list))
+ (erc-display-message
+ parsed 'notice (process-buffer proc)
+ 'netsplit ?s split)
+ (run-hook-with-args 'erc-netsplit-hook proc split))
+ t)))
+
+(defun erc-netsplit-timer (now)
+ "Clean cruft from `erc-netsplit-list' older than 10 minutes."
+ (dolist (elt erc-netsplit-list)
+ (when (> (erc-time-diff (cadr elt) now) 600)
+ (when erc-netsplit-debug
+ (erc-display-message
+ nil 'notice (current-buffer)
+ (concat "Netsplit: Removing " (car elt))))
+ (setq erc-netsplit-list (delq elt erc-netsplit-list)))))
+
+;;;###autoload
+(defun erc-cmd-WHOLEFT ()
+ "Show who's gone."
+ (with-current-buffer (erc-server-buffer)
+ (if (null erc-netsplit-list)
+ (erc-display-message
+ nil 'notice 'active
+ 'netsplit-none)
+ (dolist (elt erc-netsplit-list)
+ (erc-display-message
+ nil 'notice 'active
+ 'netsplit-wholeft ?s (car elt)
+ ?n (mapconcat 'erc-extract-nick (nthcdr 3 elt) " ")
+ ?t (if (caddr elt)
+ "(joining)"
+ "")))))
+ t)
+
+(defalias 'erc-cmd-WL 'erc-cmd-WHOLEFT)
+
+(provide 'erc-netsplit)
+
+;;; erc-netsplit.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 61a85cb0-7e7b-4312-a4f6-313c7a25a6e8
diff --git a/lisp/erc/erc-nicklist.el b/lisp/erc/erc-nicklist.el
new file mode 100644
index 00000000000..5599565844b
--- /dev/null
+++ b/lisp/erc/erc-nicklist.el
@@ -0,0 +1,411 @@
+;;; erc-nicklist.el --- Display channel nicknames in a side buffer.
+
+;; Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+
+;; Filename: erc-nicklist.el
+;; Author: Lawrence Mitchell <wence@gmx.li>
+;; Created: 2004-04-30
+;; Keywords: IRC chat client Internet
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; This provides a minimal mIRC style nicklist buffer for ERC. To
+;; activate, do M-x erc-nicklist RET in the channel buffer you want
+;; the nicklist to appear for. To close and quit the nicklist
+;; buffer, do M-x erc-nicklist-quit RET.
+;;
+;; TODO:
+;; o Somehow associate nicklist windows with channel windows so they
+;; appear together, and if one gets buried, then the other does.
+;;
+;; o Make "Query" and "Message" work.
+;;
+;; o Prettify the actual list of nicks in some way.
+;;
+;; o Add a proper erc-module that people can turn on and off, figure
+;; out a way of creating the nicklist window at an appropriate time
+;; --- probably in `erc-join-hook'.
+;;
+;; o Ensure XEmacs compatibility --- the mouse-menu support is likely
+;; broken.
+;;
+;; o Add option to display in a separate frame --- will again need to
+;; be able to associate the nicklist with the currently active
+;; channel buffer or something similar.
+;;
+;; o Allow toggling of visibility of nicklist via ERC commands.
+
+;;; History:
+;;
+
+;; Changes by Edgar Gonçalves <edgar.goncalves@inesc-id.pt>
+;; Jun 25 2005:
+;; - images are changed to a standard set of names.
+;; - /images now contain gaim's status icons.
+;; May 31 2005:
+;; - tooltips are improved. they try to access bbdb for a nice nick!
+;; Apr 26 2005:
+;; - erc-nicklist-channel-users-info was fixed (sorting bug)
+;; - Away names don't need parenthesis when using icons
+;; Apr 26 2005:
+;; - nicks can display icons of their connection type (msn, icq, for now)
+;; Mar 15 2005:
+;; - nicks now are different for unvoiced and op users
+;; - nicks now have tooltips displaying more info
+;; Mar 18 2005:
+;; - queries now work ok, both on menu and keyb shortcut RET.
+;; - nicklist is now sorted ignoring the case. Voiced nicks will
+;; appear according to `erc-nicklist-voiced-position'.
+
+;;; Code:
+
+(require 'erc)
+(condition-case nil
+ (require 'erc-bbdb)
+ (error nil))
+(eval-when-compile (require 'cl))
+
+(defgroup erc-nicklist nil
+ "Display a list of nicknames in a separate window."
+ :group 'erc)
+
+(defcustom erc-nicklist-use-icons t
+ "*If non-nil, display an icon instead of the name of the chat medium.
+By \"chat medium\", we mean IRC, AOL, MSN, ICQ, etc."
+ :group 'erc-nicklist
+ :type 'boolean)
+
+(defcustom erc-nicklist-icons-directory
+ (concat default-directory "images/")
+ "*Directory of the PNG files for chat icons.
+Icons are displayed if `erc-nicklist-use-icons' is non-nil."
+ :group 'erc-nicklist
+ :type 'string)
+
+(defcustom erc-nicklist-voiced-position 'bottom
+ "*Position of voiced nicks in the nicklist.
+The value can be `top', `bottom' or nil (don't sort)."
+ :group 'erc-nicklist
+ :type '(choice
+ (const :tag "Top" 'top)
+ (const :tag "Bottom" 'bottom)
+ (const :tag "Mixed" nil)))
+
+(defcustom erc-nicklist-window-size 20.0
+ "*The size of the nicklist window.
+
+This specifies a percentage of the channel window width.
+
+A negative value means the nicklist window appears on the left of the
+channel window, and vice versa."
+ :group 'erc-nicklist
+ :type 'float)
+
+
+(defun erc-nicklist-buffer-name (&optional buffer)
+ "Return the buffer name for a nicklist associated with BUFFER.
+
+If BUFFER is nil, use the value of `current-buffer'."
+ (format " *%s-nicklist*" (buffer-name (or buffer (current-buffer)))))
+
+(defun erc-nicklist-make-window ()
+ "Create an ERC nicklist window.
+
+See also `erc-nicklist-window-size'."
+ (let ((width (floor (* (window-width) (/ erc-nicklist-window-size 100.0))))
+ (buffer (erc-nicklist-buffer-name))
+ window)
+ (split-window-horizontally (- width))
+ (setq window (next-window))
+ (set-window-buffer window (get-buffer-create buffer))
+ (with-current-buffer buffer
+ (set-window-dedicated-p window t))))
+
+
+(defvar erc-nicklist-images-alist '()
+ "Alist that maps a connection type to an icon.")
+
+(defun erc-nicklist-insert-medium-name-or-icon (host channel is-away)
+ "Inserts an icon or a string identifying the current host type.
+This is configured using `erc-nicklist-use-icons' and
+`erc-nicklist-icons-directory'."
+ ;; identify the network (for bitlebee usage):
+ (let ((bitlbee-p (save-match-data
+ (string-match "\\`&bitlbee\\b"
+ (buffer-name channel)))))
+ (cond ((and bitlbee-p
+ (string= "login.icq.com" host))
+ (if erc-nicklist-use-icons
+ (if is-away
+ (insert-image (cdr (assoc 'icq-away
+ erc-nicklist-images-alist)))
+ (insert-image (cdr (assoc 'icq
+ erc-nicklist-images-alist))))
+ (insert "ICQ")))
+ (bitlbee-p
+ (if erc-nicklist-use-icons
+ (if is-away
+ (insert-image (cdr (assoc 'msn-away
+ erc-nicklist-images-alist)))
+ (insert-image (cdr (assoc 'msn
+ erc-nicklist-images-alist))))
+ (insert "MSN")))
+ (t
+ (if erc-nicklist-use-icons
+ (if is-away
+ (insert-image (cdr (assoc 'irc-away
+ erc-nicklist-images-alist)))
+ (insert-image (cdr (assoc 'irc
+ erc-nicklist-images-alist))))
+ (insert "IRC"))))
+ (insert " ")))
+
+(defun erc-nicklist-search-for-nick (finger-host)
+ "Return the bitlbee-nick field for this contact given FINGER-HOST.
+Seach for the BBDB record of this contact. If not found, return nil."
+ (when (boundp 'erc-bbdb-bitlbee-name-field)
+ (let ((record (car
+ (erc-member-if
+ #'(lambda (r)
+ (let ((fingers (bbdb-record-finger-host r)))
+ (when fingers
+ (string-match finger-host
+ (car (bbdb-record-finger-host r))))))
+ (bbdb-records)))))
+ (when record
+ (bbdb-get-field record erc-bbdb-bitlbee-name-field)))))
+
+(defun erc-nicklist-insert-contents (channel)
+ "Insert the nicklist contents, with text properties and the optional images."
+ (setq buffer-read-only nil)
+ (erase-buffer)
+ (dolist (u (erc-nicklist-channel-users-info channel))
+ (let* ((server-user (car u))
+ (channel-user (cdr u))
+ (nick (erc-server-user-nickname server-user))
+ (host (erc-server-user-host server-user))
+ (login (erc-server-user-login server-user))
+ (full-name(erc-server-user-full-name server-user))
+ (info (erc-server-user-info server-user))
+ (channels (erc-server-user-buffers server-user))
+ (op (erc-channel-user-op channel-user))
+ (voice (erc-channel-user-voice channel-user))
+ (bbdb-nick (erc-nicklist-search-for-nick (concat login "@" host)))
+ (away-status (if voice "" "\n(Away)"))
+ (balloon-text (concat bbdb-nick (if (string= "" bbdb-nick)
+ "" "\n")
+ "Login: " login "@" host
+ away-status)))
+ (erc-nicklist-insert-medium-name-or-icon host channel (not voice))
+ (unless (or voice erc-nicklist-use-icons)
+ (setq nick (concat "(" nick ")")))
+ (when op
+ (setq nick (concat nick " (OP)")))
+ (insert (erc-propertize nick
+ 'erc-nicklist-nick nick
+ 'mouse-face 'highlight
+ 'erc-nicklist-channel channel
+ 'help-echo balloon-text)
+ "\n")))
+ (erc-nicklist-mode))
+
+
+(defun erc-nicklist ()
+ "Create an ERC nicklist buffer."
+ (interactive)
+ (let ((channel (current-buffer)))
+ (unless (or (not erc-nicklist-use-icons)
+ erc-nicklist-images-alist)
+ (setq erc-nicklist-images-alist
+ `((msn . ,(create-image (concat erc-nicklist-icons-directory
+ "msn-online.png")))
+ (msn-away . ,(create-image (concat erc-nicklist-icons-directory
+ "msn-offline.png")))
+ (irc . ,(create-image (concat erc-nicklist-icons-directory
+ "irc-online.png")))
+ (irc-away . ,(create-image (concat erc-nicklist-icons-directory
+ "irc-offline.png")))
+ (icq . ,(create-image (concat erc-nicklist-icons-directory
+ "icq-online.png")))
+ (icq-away . ,(create-image (concat erc-nicklist-icons-directory
+ "icq-offline.png"))))))
+ (erc-nicklist-make-window)
+ (with-current-buffer (get-buffer (erc-nicklist-buffer-name channel))
+ (erc-nicklist-insert-contents channel)))
+ (add-hook 'erc-channel-members-changed-hook #'erc-nicklist-update))
+
+(defun erc-nicklist-update ()
+ "Update the ERC nicklist buffer."
+ (let ((b (get-buffer (erc-nicklist-buffer-name)))
+ (channel (current-buffer)))
+ (when b
+ (with-current-buffer b
+ (erc-nicklist-insert-contents channel)))))
+
+(defvar erc-nicklist-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map (kbd "<down-mouse-3>") 'erc-nicklist-menu)
+ (define-key map "\C-j" 'erc-nicklist-kbd-menu)
+ (define-key map "q" 'erc-nicklist-quit)
+ (define-key map (kbd "RET") 'erc-nicklist-kbd-cmd-QUERY)
+ map)
+ "Keymap for `erc-nicklist-mode'.")
+
+(define-derived-mode erc-nicklist-mode fundamental-mode
+ "Nicklist"
+ "Major mode for the ERC nicklist buffer."
+ (setq buffer-read-only t))
+
+(defun erc-nicklist-call-erc-command (command point buffer window)
+ "Call an ERC COMMAND.
+
+Depending on what COMMAND is, it's called with one of POINT, BUFFER,
+or WINDOW as arguments."
+ (when command
+ (let* ((p (text-properties-at point))
+ (b (plist-get p 'erc-nicklist-channel)))
+ (if (memq command '(erc-nicklist-quit ignore))
+ (funcall command window)
+ ;; EEEK! Horrble, but it's the only way we can ensure the
+ ;; response goes to the correct buffer.
+ (erc-set-active-buffer b)
+ (switch-to-buffer-other-window b)
+ (funcall command (plist-get p 'erc-nicklist-nick))))))
+
+(defun erc-nicklist-cmd-QUERY (user &optional server)
+ "Opens a query buffer with USER."
+ ;; FIXME: find a way to switch to that buffer afterwards...
+ (let ((send (if server
+ (format "QUERY %s %s" user server)
+ (format "QUERY %s" user))))
+ (erc-cmd-QUERY user)
+ t))
+
+(defun erc-nicklist-kbd-cmd-QUERY (&optional window)
+ (interactive)
+ (let* ((p (text-properties-at (point)))
+ (server (plist-get p 'erc-nicklist-channel))
+ (nick (plist-get p 'erc-nicklist-nick))
+ (nick (or (and (string-match "(\\(.*\\))" nick)
+ (match-string 1 nick))
+ nick))
+ (nick (or (and (string-match "\\+\\(.*\\)" nick)
+ (match-string 1 nick))
+ nick))
+ (send (format "QUERY %s %s" nick server)))
+ (switch-to-buffer-other-window server)
+ (erc-cmd-QUERY nick)))
+
+
+(defvar erc-nicklist-menu
+ (let ((map (make-sparse-keymap "Action")))
+ (define-key map [erc-cmd-WHOIS]
+ '("Whois" . erc-cmd-WHOIS))
+ (define-key map [erc-cmd-DEOP]
+ '("Deop" . erc-cmd-DEOP))
+ (define-key map [erc-cmd-MSG]
+ '("Message" . erc-cmd-MSG)) ;; TODO!
+ (define-key map [erc-nicklist-cmd-QUERY]
+ '("Query" . erc-nicklist-kbd-cmd-QUERY))
+ (define-key map [ignore]
+ '("Cancel" . ignore))
+ (define-key map [erc-nicklist-quit]
+ '("Close nicklist" . erc-nicklist-quit))
+ map)
+ "Menu keymap for the ERC nicklist.")
+
+(defun erc-nicklist-quit (&optional window)
+ "Delete the ERC nicklist.
+
+Deletes WINDOW and stops updating the nicklist buffer."
+ (interactive)
+ (let ((b (window-buffer window)))
+ (with-current-buffer b
+ (set-buffer-modified-p nil)
+ (kill-this-buffer)
+ (remove-hook 'erc-channel-members-changed-hook 'erc-nicklist-update))))
+
+
+(defun erc-nicklist-kbd-menu ()
+ "Show the ERC nicklist menu."
+ (interactive)
+ (let* ((point (point))
+ (window (selected-window))
+ (buffer (current-buffer)))
+ (with-current-buffer buffer
+ (erc-nicklist-call-erc-command
+ (car (x-popup-menu point
+ erc-nicklist-menu))
+ point
+ buffer
+ window))))
+
+(defun erc-nicklist-menu (&optional arg)
+ "Show the ERC nicklist menu.
+
+ARG is a parametrized event (see `interactive')."
+ (interactive "e")
+ (let* ((point (nth 1 (cadr arg)))
+ (window (car (cadr arg)))
+ (buffer (window-buffer window)))
+ (with-current-buffer buffer
+ (erc-nicklist-call-erc-command
+ (car (x-popup-menu arg
+ erc-nicklist-menu))
+ point
+ buffer
+ window))))
+
+
+(defun erc-nicklist-channel-users-info (channel)
+ "Return a nick-sorted list of all users on CHANNEL.
+Result are elements in the form (SERVER-USER . CHANNEL-USER). The
+list has all the voiced users according to
+`erc-nicklist-voiced-position'."
+ (let* ((nicks (erc-sort-channel-users-alphabetically
+ (with-current-buffer channel (erc-get-channel-user-list)))))
+ (if erc-nicklist-voiced-position
+ (let ((voiced-nicks (erc-remove-if-not
+ #'(lambda (x)
+ (null (erc-channel-user-voice (cdr x))))
+ nicks))
+ (devoiced-nicks (erc-remove-if-not
+ #'(lambda (x)
+ (erc-channel-user-voice
+ (cdr x)))
+ nicks)))
+ (cond ((eq erc-nicklist-voiced-position 'top)
+ (append devoiced-nicks voiced-nicks))
+ ((eq erc-nicklist-voiced-position 'bottom)
+ (append voiced-nicks devoiced-nicks))))
+ nicks)))
+
+
+
+(provide 'erc-nicklist)
+
+;;; erc-nicklist.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: db37a256-87a7-4544-bd90-e5f16c9f5ca5
diff --git a/lisp/erc/erc-nickserv.el b/lisp/erc/erc-nickserv.el
new file mode 100644
index 00000000000..be5541d3b5c
--- /dev/null
+++ b/lisp/erc/erc-nickserv.el
@@ -0,0 +1,337 @@
+;;; erc-nickserv.el --- Identify to NickServ
+
+;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; There are two ways to go about identifying yourself automatically to
+;; NickServ with this module. The more secure way is to listen for identify
+;; requests from the user NickServ. Another way is to identify yourself to
+;; NickServ directly after a successful connection and every time you change
+;; your nickname. This method is rather insecure, though, because no checks
+;; are made to test if NickServ is the real NickServ for a given network or
+;; server.
+
+;; As a default, ERC has the data for the official nickname services on the
+;; networks Austnet, BrasNET, Dalnet, freenode, GalaxyNet, and Slashnet.
+;; You can add more by using M-x customize-variable RET erc-nickserv-alist.
+
+;; Usage:
+;;
+;; Put into your .emacs:
+;;
+;; (require 'erc-nickserv)
+;; (erc-services-mode 1)
+;;
+;; Add your nickname and NickServ password to `erc-nickserv-passwords'.
+;; Using the freenode network as an example:
+;;
+;; (setq erc-nickserv-passwords '((freenode (("nickname" "password")))))
+;;
+;; The default automatic identification mode is autodetection of NickServ
+;; identify requests. Set the variable `erc-nickserv-identify-mode' if
+;; you'd like to change this behavior. You can also change the way
+;; automatic identification is handled by using:
+;;
+;; M-x erc-nickserv-identify-mode
+;;
+;; If you'd rather not identify yourself automatically but would like access
+;; to the functions contained in this file, just load this file without
+;; enabling `erc-services-mode'.
+;;
+
+;;; Code:
+
+(require 'erc)
+(require 'erc-nets)
+(eval-when-compile (require 'cl))
+
+;; Customization:
+
+(defgroup erc-services nil
+ "Configuration for IRC services.
+
+On some networks, there exists a special type of automated irc bot,
+called Services. Those usually allow you to register your nickname,
+post/read memos to other registered users who are currently offline,
+and do various other things.
+
+This group allows you to set variables to somewhat automate
+communication with those Services."
+ :group 'erc)
+
+;;;###autoload (autoload 'erc-services-mode "erc-nickserv" nil t)
+(define-erc-module services nickserv
+ "This mode automates communication with services."
+ ((erc-nickserv-identify-mode erc-nickserv-identify-mode))
+ ((remove-hook 'erc-server-NOTICE-functions
+ 'erc-nickserv-identify-autodetect)
+ (remove-hook 'erc-after-connect
+ 'erc-nickserv-identify-on-connect)
+ (remove-hook 'erc-nick-changed-functions
+ 'erc-nickserv-identify-on-nick-change)))
+
+;;;###autoload
+(defun erc-nickserv-identify-mode (mode)
+ "Set up hooks according to which MODE the user has chosen."
+ (interactive
+ (list (intern (completing-read
+ "Choose Nickserv identify mode (RET to disable): "
+ '(("autodetect") ("nick-change")) nil t))))
+ (cond ((eq mode 'autodetect)
+ (setq erc-nickserv-identify-mode 'autodetect)
+ (add-hook 'erc-server-NOTICE-functions
+ 'erc-nickserv-identify-autodetect)
+ (remove-hook 'erc-nick-changed-functions
+ 'erc-nickserv-identify-on-nick-change)
+ (remove-hook 'erc-after-connect
+ 'erc-nickserv-identify-on-connect))
+ ((eq mode 'nick-change)
+ (setq erc-nickserv-identify-mode 'nick-change)
+ (add-hook 'erc-after-connect
+ 'erc-nickserv-identify-on-connect)
+ (add-hook 'erc-nick-changed-functions
+ 'erc-nickserv-identify-on-nick-change)
+ (remove-hook 'erc-server-NOTICE-functions
+ 'erc-nickserv-identify-autodetect))
+ (t
+ (setq erc-nickserv-identify-mode nil)
+ (remove-hook 'erc-server-NOTICE-functions
+ 'erc-nickserv-identify-autodetect)
+ (remove-hook 'erc-after-connect
+ 'erc-nickserv-identify-on-connect)
+ (remove-hook 'erc-nick-changed-functions
+ 'erc-nickserv-identify-on-nick-change))))
+
+(defcustom erc-nickserv-identify-mode 'autodetect
+ "The mode which is used when identifying to Nickserv.
+
+Possible settings are:.
+
+'autodetect - Identify when the real Nickserv sends an identify request.
+'nick-change - Identify when you change your nickname.
+nil - Disables automatic Nickserv identification.
+
+You can also use M-x erc-nickserv-identify-mode to change modes."
+ :group 'erc-services
+ :type '(choice (const autodetect)
+ (const nick-change)
+ (const nil))
+ :set (lambda (sym val)
+ (set-default sym val)
+ (erc-nickserv-identify-mode val)))
+
+(defcustom erc-prompt-for-nickserv-password t
+ "Ask for the password when identifying to NickServ."
+ :group 'erc-services
+ :type 'boolean)
+
+(defcustom erc-nickserv-passwords nil
+ "Passwords used when identifying to NickServ automatically.
+
+Example of use:
+ (setq erc-nickserv-passwords
+ '((freenode ((\"nick-one\" . \"password\")
+ (\"nick-two\" . \"password\")))
+ (DALnet ((\"nick\" . \"password\")))))"
+ :group 'erc-services
+ :type '(repeat
+ (list :tag "Network"
+ (choice :tag "Network name"
+ (const freenode)
+ (const DALnet)
+ (const GalaxyNet)
+ (const SlashNET)
+ (const BRASnet)
+ (const iip)
+ (const Austnet)
+ (symbol :tag "Network name"))
+ (repeat :tag "Nickname and password"
+ (cons :tag "Identity"
+ (string :tag "Nick")
+ (string :tag "Password"))))))
+
+;; Variables:
+
+(defcustom erc-nickserv-alist
+ '((DALnet
+ "NickServ!service@dal.net"
+ "/msg\\s-NickServ@services.dal.net\\s-IDENTIFY\\s-<password>"
+ "NickServ@services.dal.net"
+ "IDENTIFY"
+ nil)
+ (freenode
+ "NickServ!NickServ@services."
+ "/msg\\s-NickServ\\s-IDENTIFY\\s-<password>"
+ "NickServ"
+ "IDENTIFY"
+ nil)
+ (GalaxyNet
+ "NS!nickserv@galaxynet.org"
+ "Please\\s-change\\s-nicks\\s-or\\s-authenticate."
+ "NS@services.galaxynet.org"
+ "AUTH"
+ t)
+ (SlashNET
+ "NickServ!services@services.slashnet.org"
+ "/msg\\s-NickServ\\s-IDENTIFY\\s-password"
+ "NickServ@services.slashnet.org"
+ "IDENTIFY"
+ nil)
+ (iip
+ "Trent@anon.iip"
+ "type\\s-/squery\\s-Trent\\s-identify\\s-<password>"
+ "Trent@anon.iip"
+ "IDENTIFY"
+ nil
+ "SQUERY")
+ (BRASnet
+ "NickServ!services@brasnet.org"
+ "/NickServ\\s-IDENTIFY\\s-senha"
+ "NickServ"
+ "IDENTIFY"
+ nil
+ "")
+ (Austnet
+ "NickOP!service@austnet.org"
+ "/msg\\s-NickOP@austnet.org\\s-identify\\s-<password>"
+ "nickop@austnet.org"
+ "identify"
+ nil)
+ (Azzurra
+ "NickServ!service@azzurra.org"
+ "/ns\\s-IDENTIFY\\s-password"
+ "NickServ"
+ "IDENTIFY"
+ nil)
+ (OFTC
+ "NickServ!services@services.oftc.net"
+ "/msg\\s-NickServ\\s-IDENTIFY\\s-\^_password"
+ "NickServ"
+ "IDENTIFY"
+ nil))
+ "Alist of NickServer details, sorted by network.
+Every element in the list has the form
+ \(SYMBOL NICKSERV REGEXP NICK KEYWORD USE-CURRENT ANSWER)
+
+SYMBOL is a network identifier, a symbol, as used in `erc-networks-alist'.
+NICKSERV is the description of the nickserv in the form nick!user@host.
+REGEXP is a regular expression matching the message from nickserv.
+NICK is nickserv's nickname. Use nick@server where necessary/possible.
+KEYWORD is the keyword to use in the reply message to identify yourself.
+USE-CURRENT indicates whether the current nickname must be used when
+ identifying.
+ANSWER is the command to use for the answer. The default is 'privmsg.
+ This last element is optional."
+ :group 'erc-services
+ :type '(repeat
+ (list :tag "Nickserv data"
+ (symbol :tag "Network name")
+ (string :tag "Nickserv's nick!user@host")
+ (regexp :tag "Identify request sent by Nickserv")
+ (string :tag "Identify to")
+ (string :tag "Identify keyword")
+ (boolean :tag "Use current nick in identify message?")
+ (choice :tag "Command to use (optional)"
+ (string :tag "Command")
+ (const :tag "No special command necessary" nil)))))
+
+;; Functions:
+
+(defun erc-nickserv-identify-autodetect (proc parsed)
+ "Check for a NickServ identify request everytime a notice is received.
+Make sure it is the real NickServ for this network and that it has
+specifically asked the user to IDENTIFY.
+If `erc-prompt-for-nickserv-password' is non-nil, prompt the user for the
+password for this nickname, otherwise try to send it automatically."
+ (unless (and (null erc-nickserv-passwords)
+ (null erc-prompt-for-nickserv-password))
+ (let* ((network (erc-network))
+ (nickserv (nth 1 (assoc network erc-nickserv-alist)))
+ (identify-regex (nth 2 (assoc network erc-nickserv-alist)))
+ (sspec (erc-response.sender parsed))
+ (nick (car (erc-response.command-args parsed)))
+ (msg (erc-response.contents parsed)))
+ ;; continue only if we're sure it's the real nickserv for this network
+ ;; and it's asked us to identify
+ (when (and nickserv (equal sspec nickserv)
+ (string-match identify-regex msg))
+ (erc-log "NickServ IDENTIFY request detected")
+ (erc-nickserv-call-identify-function nick)
+ nil))))
+
+(defun erc-nickserv-identify-on-connect (server nick)
+ "Identify to Nickserv after the connection to the server is established."
+ (unless (and (null erc-nickserv-passwords)
+ (null erc-prompt-for-nickserv-password))
+ (erc-nickserv-call-identify-function nick)))
+
+(defun erc-nickserv-identify-on-nick-change (nick old-nick)
+ "Identify to Nickserv whenever your nick changes."
+ (unless (and (null erc-nickserv-passwords)
+ (null erc-prompt-for-nickserv-password))
+ (erc-nickserv-call-identify-function nick)))
+
+(defun erc-nickserv-call-identify-function (nickname)
+ "Call `erc-nickserv-identify' interactively or run it with NICKNAME's
+password.
+The action is determined by the value of `erc-prompt-for-nickserv-password'."
+ (if erc-prompt-for-nickserv-password
+ (call-interactively 'erc-nickserv-identify)
+ (when erc-nickserv-passwords
+ (erc-nickserv-identify
+ (cdr (assoc nickname
+ (nth 1 (assoc (erc-network)
+ erc-nickserv-passwords))))))))
+
+;;;###autoload
+(defun erc-nickserv-identify (password)
+ "Send an \"identify <PASSWORD>\" message to NickServ.
+When called interactively, read the password using `read-passwd'."
+ (interactive
+ (list (read-passwd
+ (format "NickServ password for %s on %s (RET to cancel): "
+ (erc-current-nick)
+ (or (and (erc-network)
+ (symbol-name (erc-network)))
+ "Unknown network")))))
+ (when (and password (not (string= "" password)))
+ (let* ((erc-auto-discard-away nil)
+ (network (erc-network))
+ (nickserv-info (assoc network erc-nickserv-alist))
+ (nickserv (or (nth 3 nickserv-info) "NickServ"))
+ (identify-word (or (nth 4 nickserv-info) "IDENTIFY"))
+ (nick (if (nth 5 nickserv-info)
+ (concat (erc-current-nick) " ")
+ ""))
+ (msgtype (or (nth 6 nickserv-info) "PRIVMSG")))
+ (erc-message msgtype
+ (concat nickserv " " identify-word " " nick password)))))
+
+(provide 'erc-nickserv)
+
+;;; erc-nickserv.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: d401c8aa-d938-4255-96a9-3efb64c47e58
diff --git a/lisp/erc/erc-notify.el b/lisp/erc/erc-notify.el
new file mode 100644
index 00000000000..9fc7f572977
--- /dev/null
+++ b/lisp/erc/erc-notify.el
@@ -0,0 +1,254 @@
+;;; erc-notify.el --- Online status change notification
+
+;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@lexx.delysid.org>
+;; Keywords: comm
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This module defines a new command, /NOTIFY
+;; See the docstring of `erc-cmd-NOTIFY' for details.
+
+;;; Code:
+
+(require 'erc)
+(require 'erc-nets)
+(eval-when-compile
+ (require 'cl)
+ (require 'pcomplete))
+
+;;;; Customizable variables
+
+(defgroup erc-notify nil
+ "Track online status of certain nicknames."
+ :group 'erc)
+
+(defcustom erc-notify-list nil
+ "*List of nicknames you want to be notified about online/offline
+status change."
+ :group 'erc-notify
+ :type '(repeat string))
+
+(defcustom erc-notify-interval 60
+ "*Time interval (in seconds) for checking online status of notificated
+people."
+ :group 'erc-notify
+ :type 'integer)
+
+(defcustom erc-notify-signon-hook nil
+ "*Hook run after someone on `erc-notify-list' has signed on.
+Two arguments are passed to the function, SERVER and NICK, both
+strings."
+ :group 'erc-notify
+ :type 'hook
+ :options '(erc-notify-signon))
+
+(defcustom erc-notify-signoff-hook nil
+ "*Hook run after someone on `erc-notify-list' has signed off.
+Two arguments are passed to the function, SERVER and NICK, both
+strings."
+ :group 'erc-notify
+ :type 'hook
+ :options '(erc-notify-signoff))
+
+(defun erc-notify-signon (server nick)
+ (message "%s signed on at %s" nick server))
+
+(defun erc-notify-signoff (server nick)
+ (message "%s signed off from %s" nick server))
+
+;;;; Internal variables
+
+(defvar erc-last-ison nil
+ "Last ISON information received through `erc-notify-timer'.")
+(make-variable-buffer-local 'erc-last-ison)
+
+(defvar erc-last-ison-time 0
+ "Last time ISON was sent to the server in `erc-notify-timer'.")
+(make-variable-buffer-local 'erc-last-ison-time)
+
+;;;; Setup
+
+(defun erc-notify-install-message-catalogs ()
+ (erc-define-catalog
+ 'english
+ '((notify_current . "Notificated people online: %l")
+ (notify_list . "Current notify list: %l")
+ (notify_on . "Detected %n on IRC network %m")
+ (notify_off . "%n has left IRC network %m"))))
+
+;;;###autoload (autoload 'erc-notify-mode "erc-notify" nil t)
+(define-erc-module notify nil
+ "Periodically check for the online status of certain users and report
+changes."
+ ((add-hook 'erc-timer-hook 'erc-notify-timer)
+ (add-hook 'erc-server-JOIN-functions 'erc-notify-JOIN)
+ (add-hook 'erc-server-NICK-functions 'erc-notify-NICK)
+ (add-hook 'erc-server-QUIT-functions 'erc-notify-QUIT))
+ ((remove-hook 'erc-timer-hook 'erc-notify-timer)
+ (remove-hook 'erc-server-JOIN-functions 'erc-notify-JOIN)
+ (remove-hook 'erc-server-NICK-functions 'erc-notify-NICK)
+ (remove-hook 'erc-server-QUIT-functions 'erc-notify-QUIT)))
+
+;;;; Timer handler
+
+(defun erc-notify-timer (now)
+ (when (and erc-notify-list
+ (> (erc-time-diff
+ erc-last-ison-time now)
+ erc-notify-interval))
+ (erc-once-with-server-event
+ 303
+ '(let* ((server (erc-response.sender parsed))
+ (ison-list (delete "" (split-string
+ (erc-response.contents parsed))))
+ (new-list ison-list)
+ (old-list (with-current-buffer (erc-server-buffer)
+ erc-last-ison)))
+ (while new-list
+ (when (not (erc-member-ignore-case (car new-list) old-list))
+ (run-hook-with-args 'erc-notify-signon-hook server (car new-list))
+ (erc-display-message
+ parsed 'notice proc
+ 'notify_on ?n (car new-list) ?m (erc-network-name)))
+ (setq new-list (cdr new-list)))
+ (while old-list
+ (when (not (erc-member-ignore-case (car old-list) ison-list))
+ (run-hook-with-args 'erc-notify-signoff-hook server (car old-list))
+ (erc-display-message
+ parsed 'notice proc
+ 'notify_off ?n (car old-list) ?m (erc-network-name)))
+ (setq old-list (cdr old-list)))
+ (setq erc-last-ison ison-list)
+ t))
+ (erc-server-send
+ (concat "ISON " (mapconcat 'identity erc-notify-list " ")))
+ (setq erc-last-ison-time now)))
+
+(defun erc-notify-JOIN (proc parsed)
+ "Check if channel joiner is on `erc-notify-list' and not on `erc-last-ison'.
+If this condition is satisfied, produce a notify_on message and add the nick
+to `erc-last-ison' to prevent any further notifications."
+ (let ((nick (erc-extract-nick (erc-response.sender parsed))))
+ (when (and (erc-member-ignore-case nick erc-notify-list)
+ (not (erc-member-ignore-case nick erc-last-ison)))
+ (add-to-list 'erc-last-ison nick)
+ (run-hook-with-args 'erc-notify-signon-hook
+ (or erc-server-announced-name erc-session-server)
+ nick)
+ (erc-display-message
+ parsed 'notice proc
+ 'notify_on ?n nick ?m (erc-network-name)))
+ nil))
+
+(defun erc-notify-NICK (proc parsed)
+ "Check if new nick is on `erc-notify-list' and not on `erc-last-ison'.
+If this condition is satisfied, produce a notify_on message and add the nick
+to `erc-last-ison' to prevent any further notifications."
+ (let ((nick (erc-response.contents parsed)))
+ (when (and (erc-member-ignore-case nick erc-notify-list)
+ (not (erc-member-ignore-case nick erc-last-ison)))
+ (add-to-list 'erc-last-ison nick)
+ (run-hook-with-args 'erc-notify-signon-hook
+ (or erc-server-announced-name erc-session-server)
+ nick)
+ (erc-display-message
+ parsed 'notice proc
+ 'notify_on ?n nick ?m (erc-network-name)))
+ nil))
+
+(defun erc-notify-QUIT (proc parsed)
+ "Check if quitter is on `erc-notify-list' and on `erc-last-ison'.
+If this condition is satisfied, produce a notify_off message and remove the
+nick from `erc-last-ison' to prevent any further notifications."
+ (let ((nick (erc-extract-nick (erc-response.sender parsed))))
+ (when (and (erc-member-ignore-case nick erc-notify-list)
+ (erc-member-ignore-case nick erc-last-ison))
+ (setq erc-last-ison (erc-delete-if `(lambda (el)
+ (string= ,(erc-downcase nick)
+ (erc-downcase el)))
+ erc-last-ison))
+ (run-hook-with-args 'erc-notify-signoff-hook
+ (or erc-server-announced-name erc-session-server)
+ nick)
+ (erc-display-message
+ parsed 'notice proc
+ 'notify_off ?n nick ?m (erc-network-name)))
+ nil))
+
+;;;; User level command
+
+;;;###autoload
+(defun erc-cmd-NOTIFY (&rest args)
+ "Change `erc-notify-list' or list current notify-list members online.
+Without args, list the current list of notificated people online,
+with args, toggle notify status of people."
+ (cond
+ ((null args)
+ ;; Print current notificated people (online)
+ (let ((ison (with-current-buffer (erc-server-buffer) erc-last-ison)))
+ (if (not ison)
+ (erc-display-message
+ nil 'notice 'active "No ison-list yet!")
+ (erc-display-message
+ nil 'notice 'active
+ 'notify_current ?l ison))))
+ ((string= (car args) "-l")
+ (erc-display-message nil 'notice 'active
+ 'notify_list ?l (mapconcat 'identity erc-notify-list
+ " ")))
+ (t
+ (while args
+ (if (erc-member-ignore-case (car args) erc-notify-list)
+ (progn
+ (setq erc-notify-list (delete (car args) erc-notify-list))
+ ;; Remove the nick from the value of erc-last-ison in
+ ;; every server buffer. This prevents seeing a signoff
+ ;; notification for a nick that you have just _removed_
+ ;; from your notify list.
+ (dolist (buf (erc-buffer-list))
+ (with-current-buffer buf
+ (if (erc-server-buffer-p)
+ (setq erc-last-ison (delete (car args) erc-last-ison))))))
+ (setq erc-notify-list (cons (erc-string-no-properties (car args))
+ erc-notify-list)))
+ (setq args (cdr args)))
+ (erc-display-message
+ nil 'notice 'active
+ 'notify_list ?l (mapconcat 'identity erc-notify-list " "))))
+ t)
+
+;;;###autoload
+(defun pcomplete/erc-mode/NOTIFY ()
+ (pcomplete-here (pcomplete-erc-all-nicks)))
+
+(erc-notify-install-message-catalogs)
+
+(provide 'erc-notify)
+
+;;; erc-notify.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 0fb19dd0-1359-458a-89b7-81dc195a588e
diff --git a/lisp/erc/erc-page.el b/lisp/erc/erc-page.el
new file mode 100644
index 00000000000..d8e677031e3
--- /dev/null
+++ b/lisp/erc/erc-page.el
@@ -0,0 +1,108 @@
+;; erc-page.el - CTCP PAGE support for ERC
+
+;; Copyright (C) 2002, 2004 Free Software Foundation
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Requiring this file will make ERC react to CTCP PAGE messages
+;; received, and it will provide a new /PAGE command to send such
+;; messages yourself. To enable it, customize the variable
+;; `erc-page-mode'.
+
+;;; Code:
+
+(require 'erc)
+
+;;;###autoload (autoload 'erc-page-mode "erc-page")
+(define-erc-module page ctcp-page
+ "Process CTCP PAGE requests from IRC."
+ nil nil)
+
+(erc-define-catalog-entry 'english 'CTCP-PAGE "Page from %n (%u@%h): %m")
+
+(defgroup erc-page nil
+ "React to CTCP PAGE messages."
+ :group 'erc)
+
+(defcustom erc-page-function nil
+ "A function to process a \"page\" request.
+If nil, this prints the page message in the minibuffer and calls
+`beep'. If non-nil, it must be a function that takes two arguments:
+SENDER and MSG, both strings.
+
+Example for your ~/.emacs file:
+
+\(setq erc-page-function
+ (lambda (sender msg)
+ (play-sound-file \"/home/alex/elisp/erc/sounds/ni.wav\")
+ (message \"IRC Page from %s: %s\" sender msg)))"
+ :group 'erc-page
+ :type '(choice (const nil)
+ (function)))
+
+(defcustom erc-ctcp-query-PAGE-hook '(erc-ctcp-query-PAGE)
+ "List of functions to be called when a CTCP PAGE is received.
+This is called from `erc-process-ctcp-query'. The functions are called
+with six arguments: PROC NICK LOGIN HOST TO MSG. Note that you can
+also set `erc-page-function' to a function, which only gets two arguments,
+SENDER and MSG, so that might be easier to use."
+ :group 'erc-page
+ :type '(repeat function))
+
+(defun erc-ctcp-query-PAGE (proc nick login host to msg)
+ "Deal with an CTCP PAGE query, if `erc-page-mode' is non-nil.
+This will call `erc-page-function', if defined, or it will just print
+a message and `beep'. In addition to that, the page message is also
+inserted into the server buffer."
+ (when (and erc-page-mode
+ (string-match "PAGE\\(\\s-+.*\\)?$" msg))
+ (let* ((m (match-string 1 msg))
+ (page-msg (if m (erc-controls-interpret (substring m 1))
+ "[no message]"))
+ text)
+ (if m (setq m (substring m 1)))
+ (setq text (erc-format-message 'CTCP-PAGE
+ ?n nick ?u login
+ ?h host ?m page-msg))
+ (if erc-page-function
+ (funcall erc-page-function nick page-msg)
+ ;; if no function is defined
+ (message "%s" text)
+ (beep))
+ ;; insert text into buffer
+ (erc-display-message
+ nil 'notice nil text)))
+ nil)
+
+(defun erc-cmd-PAGE (line &optional force)
+ "Send a CTCP page to the user given as the first word in LINE.
+The rest of LINE is the message to send. Note that you will only
+receive pages if `erc-page-mode' is on."
+ (when (string-match "^\\s-*\\(\\S-+\\) ?\\(.*\\)" line)
+ (let ((nick (match-string 1 line))
+ (msg (match-string 2 line)))
+ (erc-cmd-CTCP nick "PAGE" msg))))
+
+(put 'erc-cmd-PAGE 'do-not-parse-args t)
+
+(provide 'erc-page)
+
+;; arch-tag: 82fd2e0e-6060-4dd2-9788-8c1411e844de
+;;; erc-page.el ends here
diff --git a/lisp/erc/erc-pcomplete.el b/lisp/erc/erc-pcomplete.el
new file mode 100644
index 00000000000..110704304e2
--- /dev/null
+++ b/lisp/erc/erc-pcomplete.el
@@ -0,0 +1,275 @@
+;;; erc-pcomplete.el --- Provides programmable completion for ERC
+
+;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Sacha Chua <sacha@free.net.ph>
+;; Keywords: comm, convenience
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcCompletion
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file replaces erc-complete.el. It provides nick completion
+;; for ERC based on pcomplete. If you do not have pcomplete, you may
+;; try to use erc-complete.el.
+;;
+;; To use, (require 'erc-auto) or (require 'erc-pcomplete), then
+;; (erc-pcomplete-mode 1)
+;;
+;; If you want nickname completions ordered such that the most recent
+;; speakers are listed first, set
+;; `erc-pcomplete-order-nickname-completions' to `t'.
+;;
+;; See CREDITS for other contributors.
+;;
+;;; Code:
+
+(require 'pcomplete)
+(require 'erc)
+(require 'erc-compat)
+(require 'time-date)
+(eval-when-compile (require 'cl))
+
+(defgroup erc-pcomplete nil
+ "Programmable completion for ERC"
+ :group 'erc)
+
+(defcustom erc-pcomplete-nick-postfix ": "
+ "*When `pcomplete' is used in the first word after the prompt,
+add this string to nicks completed."
+ :group 'erc-pcomplete
+ :type 'string)
+
+(defcustom erc-pcomplete-order-nickname-completions t
+ "If t, channel nickname completions will be ordered such that
+the most recent speakers are listed first."
+ :group 'erc-pcomplete
+ :type 'boolean)
+
+;;;###autoload (autoload 'erc-completion-mode "erc-pcomplete" nil t)
+(define-erc-module pcomplete Completion
+ "In ERC Completion mode, the TAB key does completion whenever possible."
+ ((add-hook 'erc-mode-hook 'pcomplete-erc-setup)
+ (add-hook 'erc-complete-functions 'erc-pcomplete)
+ (erc-buffer-list #'pcomplete-erc-setup))
+ ((remove-hook 'erc-mode-hook 'pcomplete-erc-setup)
+ (remove-hook 'erc-complete-functions 'erc-pcomplete)))
+
+(defun erc-pcomplete ()
+ "Complete the nick before point."
+ (interactive)
+ (when (> (point) (erc-beg-of-input-line))
+ (let ((last-command (if (eq last-command 'erc-complete-word)
+ 'pcomplete
+ last-command)))
+ (call-interactively 'pcomplete))
+ t))
+
+;;; Setup function
+
+(defun pcomplete-erc-setup ()
+ "Setup `erc-mode' to use pcomplete."
+ (set (make-local-variable 'pcomplete-ignore-case)
+ t)
+ (set (make-local-variable 'pcomplete-use-paring)
+ nil)
+ (set (make-local-variable 'pcomplete-suffix-list)
+ '(? ?:))
+ (set (make-local-variable 'pcomplete-parse-arguments-function)
+ 'pcomplete-parse-erc-arguments)
+ (set (make-local-variable 'pcomplete-command-completion-function)
+ 'pcomplete/erc-mode/complete-command)
+ (set (make-local-variable 'pcomplete-command-name-function)
+ 'pcomplete-erc-command-name)
+ (set (make-local-variable 'pcomplete-default-completion-function)
+ (lambda () (pcomplete-here (pcomplete-erc-nicks)))))
+
+;;; Programmable completion logic
+
+(defun pcomplete/erc-mode/complete-command ()
+ (pcomplete-here
+ (append
+ (pcomplete-erc-commands)
+ (pcomplete-erc-nicks erc-pcomplete-nick-postfix))))
+
+(defvar erc-pcomplete-ctcp-commands
+ '("ACTION" "CLIENTINFO" "ECHO" "FINGER" "PING" "TIME" "USERINFO" "VERSION"))
+
+(defun pcomplete/erc-mode/CTCP ()
+ (pcomplete-here (pcomplete-erc-nicks))
+ (pcomplete-here erc-pcomplete-ctcp-commands))
+
+(defun pcomplete/erc-mode/CLEARTOPIC ()
+ (pcomplete-here (pcomplete-erc-channels)))
+
+(defun pcomplete/erc-mode/DEOP ()
+ (while (pcomplete-here (pcomplete-erc-ops))))
+
+(defun pcomplete/erc-mode/DESCRIBE ()
+ (pcomplete-here (pcomplete-erc-nicks)))
+
+(defun pcomplete/erc-mode/IDLE ()
+ (while (pcomplete-here (pcomplete-erc-nicks))))
+
+(defun pcomplete/erc-mode/KICK ()
+ (pcomplete-here (pcomplete-erc-channels))
+ (pcomplete-here (pcomplete-erc-nicks)))
+
+(defun pcomplete/erc-mode/LOAD ()
+ (pcomplete-here (pcomplete-entries)))
+
+(defun pcomplete/erc-mode/MODE ()
+ (pcomplete-here (pcomplete-erc-channels))
+ (while (pcomplete-here (pcomplete-erc-nicks))))
+
+(defun pcomplete/erc-mode/ME ()
+ (while (pcomplete-here (pcomplete-erc-nicks))))
+
+(defun pcomplete/erc-mode/SAY ()
+ (pcomplete-here (pcomplete-erc-nicks))
+ (pcomplete-here (pcomplete-erc-nicks))
+ (while (pcomplete-here (pcomplete-erc-nicks))))
+
+(defun pcomplete/erc-mode/MSG ()
+ (pcomplete-here (append (pcomplete-erc-all-nicks)
+ (pcomplete-erc-channels)))
+ (while (pcomplete-here (pcomplete-erc-nicks))))
+
+(defun pcomplete/erc-mode/NAMES ()
+ (while (pcomplete-here (pcomplete-erc-channels))))
+
+(defalias 'pcomplete/erc-mode/NOTICE 'pcomplete/erc-mode/MSG)
+
+(defun pcomplete/erc-mode/OP ()
+ (while (pcomplete-here (pcomplete-erc-not-ops))))
+
+(defun pcomplete/erc-mode/PART ()
+ (pcomplete-here (pcomplete-erc-channels)))
+
+(defalias 'pcomplete/erc-mode/LEAVE 'pcomplete/erc-mode/PART)
+
+(defun pcomplete/erc-mode/QUERY ()
+ (pcomplete-here (append (pcomplete-erc-all-nicks)
+ (pcomplete-erc-channels)))
+ (while (pcomplete-here (pcomplete-erc-nicks)))
+ )
+
+(defun pcomplete/erc-mode/SOUND ()
+ (while (pcomplete-here (pcomplete-entries))))
+
+(defun pcomplete/erc-mode/TOPIC ()
+ (pcomplete-here (pcomplete-erc-channels)))
+
+(defun pcomplete/erc-mode/WHOIS ()
+ (while (pcomplete-here (pcomplete-erc-nicks))))
+
+(defun pcomplete/erc-mode/UNIGNORE ()
+ (pcomplete-here (with-current-buffer (erc-server-buffer) erc-ignore-list)))
+
+;;; Functions that provide possible completions.
+
+(defun pcomplete-erc-commands ()
+ "Returns a list of strings of the defined user commands."
+ (let ((case-fold-search nil))
+ (mapcar (lambda (x)
+ (concat "/" (downcase (substring (symbol-name x) 8))))
+ (apropos-internal "erc-cmd-[A-Z]+"))))
+
+(defun pcomplete-erc-ops ()
+ "Returns a list of nicks with ops."
+ (let (ops)
+ (maphash (lambda (nick cdata)
+ (if (and (cdr cdata)
+ (erc-channel-user-op (cdr cdata)))
+ (setq ops (cons nick ops))))
+ erc-channel-users)
+ ops))
+
+(defun pcomplete-erc-not-ops ()
+ "Returns a list of nicks without ops."
+ (let (not-ops)
+ (maphash (lambda (nick cdata)
+ (if (and (cdr cdata)
+ (not (erc-channel-user-op (cdr cdata))))
+ (setq not-ops (cons nick not-ops))))
+ erc-channel-users)
+ not-ops))
+
+
+(defun pcomplete-erc-nicks (&optional postfix)
+ "Returns a list of nicks in the current channel."
+ (let ((users (erc-get-channel-user-list)))
+ (if erc-pcomplete-order-nickname-completions
+ (setq users (erc-sort-channel-users-by-activity users)))
+ (mapcar (lambda (x)
+ (concat (erc-server-user-nickname (car x)) postfix))
+ users)))
+
+(defun pcomplete-erc-all-nicks (&optional postfix)
+ "Returns a list of all nicks on the current server."
+ (let (nicks)
+ (with-current-buffer (process-buffer erc-server-process)
+ (maphash (lambda (nick user)
+ (setq nicks (cons (concat nick postfix) nicks)))
+ erc-server-users))
+ nicks))
+
+(defun pcomplete-erc-channels ()
+ "Returns a list of channels associated with the current server."
+ (mapcar (lambda (buf) (with-current-buffer buf (erc-default-target)))
+ (erc-channel-list erc-server-process)))
+
+;;; Functions for parsing
+
+(defun pcomplete-erc-command-name ()
+ "Returns the command name of the first argument."
+ (if (eq (elt (pcomplete-arg 'first) 0) ?/)
+ (upcase (substring (pcomplete-arg 'first) 1))
+ "SAY"))
+
+(defun pcomplete-parse-erc-arguments ()
+ "Returns a list of parsed whitespace-separated arguments.
+These are the words from the beginning of the line after the prompt
+up to where point is right now."
+ (let* ((start erc-input-marker)
+ (end (point))
+ args beginnings)
+ (save-excursion
+ (if (< (skip-chars-backward " \t\n" start) 0)
+ (setq args '("")
+ beginnings (list end)))
+ (setq end (point))
+ (while (< (skip-chars-backward "^ \t\n" start) 0)
+ (setq beginnings (cons (point) beginnings)
+ args (cons (buffer-substring-no-properties
+ (point) end)
+ args))
+ (skip-chars-backward " \t\n" start)
+ (setq end (point))))
+ (cons args beginnings)))
+
+(provide 'erc-pcomplete)
+
+;;; erc-pcomplete.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;; arch-tag: 32a7703b-be87-45a4-82f3-9eed5a628911
diff --git a/lisp/erc/erc-replace.el b/lisp/erc/erc-replace.el
new file mode 100644
index 00000000000..07e8cd16138
--- /dev/null
+++ b/lisp/erc/erc-replace.el
@@ -0,0 +1,93 @@
+;; erc-replace.el -- wash and massage messages inserted into the buffer
+
+;; Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+
+;; Author: Andreas Fuchs <asf@void.at>
+;; Maintainer: Mario Lang (mlang@delysid.org)
+;; Keywords: IRC, client, Internet
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcReplace
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This module allows you to systematically replace text in incoming
+;; messages. Load erc-replace, and customize `erc-replace-alist'.
+;; Then add to your ~/.emacs:
+
+;; (require 'erc-replace)
+;; (erc-replace-mode 1)
+
+;;; Code:
+
+(require 'erc)
+
+(defgroup erc-replace nil
+ "Replace text from incoming messages"
+ :group 'erc)
+
+(defcustom erc-replace-alist nil
+ "Alist describing text to be replaced in incoming messages.
+This is useful for filters.
+
+The alist has elements of the form (FROM . TO). FROM can be a regular
+expression or a variable, or any sexp, TO can be a string or a
+function to call, or any sexp. If a function, it will be called with
+one argument, the string to be replaced, and it should return a
+replacement string."
+ :group 'erc-replace
+ :type '(repeat (cons :tag "Search & Replace"
+ (choice :tag "From"
+ regexp
+ variable
+ sexp)
+ (choice :tag "To"
+ string
+ function
+ sexp))))
+
+(defun erc-replace-insert ()
+ "Function to run from `erc-insert-modify-hook'.
+It replaces text according to `erc-replace-alist'."
+ (mapcar (lambda (elt)
+ (goto-char (point-min))
+ (let ((from (car elt))
+ (to (cdr elt)))
+ (unless (stringp from)
+ (setq from (eval from)))
+ (while (re-search-forward from nil t)
+ (cond ((stringp to)
+ (replace-match to))
+ ((and (symbolp to) (fboundp to))
+ (replace-match (funcall to (match-string 0))))
+ (t
+ (eval to))))))
+ erc-replace-alist))
+
+;;;###autoload (autoload 'erc-replace-mode "erc-replace")
+(define-erc-module replace nil
+ "This mode replaces incoming text according to `erc-replace-alist'."
+ ((add-hook 'erc-insert-modify-hook
+ 'erc-replace-insert))
+ ((remove-hook 'erc-insert-modify-hook
+ 'erc-replace-insert)))
+
+(provide 'erc-replace)
+
+;; arch-tag: dd904a59-d8a6-47f8-ac3a-76b698289a18
+;;; erc-replace.el ends here
diff --git a/lisp/erc/erc-ring.el b/lisp/erc/erc-ring.el
new file mode 100644
index 00000000000..cabb8e2905f
--- /dev/null
+++ b/lisp/erc/erc-ring.el
@@ -0,0 +1,148 @@
+;; erc-ring.el -- Command history handling for erc using ring.el
+
+;; Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Alex Schroeder <alex@gnu.org>
+;; Keywords: comm
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcHistory
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file implements an input ring -- a history of the stuff you
+;; wrote. To activate:
+;;
+;; (require 'erc-auto) or (require 'erc-ring)
+;; (erc-ring-mode 1)
+;;
+;; Use M-n and M-p to navigate the ring
+
+;;; Code:
+
+(require 'erc)
+(require 'comint)
+(require 'ring)
+
+;;;###autoload (autoload 'erc-ring-mode "erc-ring" nil t)
+(define-erc-module ring nil
+ "Stores input in a ring so that previous commands and messages can
+be recalled using M-p and M-n."
+ ((add-hook 'erc-send-pre-hook 'erc-add-to-input-ring)
+ (define-key erc-mode-map "\M-p" 'erc-previous-command)
+ (define-key erc-mode-map "\M-n" 'erc-next-command))
+ ((remove-hook 'erc-send-pre-hook 'erc-add-to-input-ring)
+ (define-key erc-mode-map "\M-p" 'undefined)
+ (define-key erc-mode-map "\M-n" 'undefined)))
+
+(defvar erc-input-ring nil "Input ring for erc.")
+(make-variable-buffer-local 'erc-input-ring)
+
+(defvar erc-input-ring-index nil
+ "Position in the input ring for erc.
+If nil, the input line is blank and the user is conceptually 'after'
+the most recently added item in the ring. If an integer, the input
+line is non-blank and displays the item from the ring indexed by this
+variable.")
+(make-variable-buffer-local 'erc-input-ring-index)
+
+(defun erc-input-ring-setup ()
+ "Do the setup required so that we can use comint style input rings.
+Call this function when setting up the mode."
+ (setq erc-input-ring (make-ring comint-input-ring-size))
+ (setq erc-input-ring-index nil))
+
+(defun erc-add-to-input-ring (s)
+ "Add string S to the input ring and reset history position."
+ (unless erc-input-ring (erc-input-ring-setup))
+ (ring-insert erc-input-ring s)
+ (setq erc-input-ring-index nil))
+
+(defun erc-clear-input-ring ()
+ "Remove all entries from the input ring, then call garbage-collect.
+You might use this for security purposes if you have typed a command
+containing a password."
+ (interactive)
+ (setq erc-input-ring (make-ring comint-input-ring-size)
+ erc-input-ring-index nil)
+ (garbage-collect)
+ (message "ERC input ring cleared."))
+
+(defun erc-previous-command ()
+ "Replace current command with the previous one from the history."
+ (interactive)
+ (unless erc-input-ring (erc-input-ring-setup))
+ ;; if the ring isn't empty
+ (when (> (ring-length erc-input-ring) 0)
+ (if (and erc-input-ring-index
+ (= (ring-length erc-input-ring) (1+ erc-input-ring-index)))
+ (progn
+ (erc-replace-current-command "")
+ (setq erc-input-ring-index nil))
+
+ ;; If we are not viewing old input and there's text in the input
+ ;; area, push it on the history ring before moving back through
+ ;; the input history, so it will be there when we return to the
+ ;; front.
+ (if (null erc-input-ring-index)
+ (when (> (point-max) erc-input-marker)
+ (erc-add-to-input-ring (buffer-substring erc-input-marker
+ (point-max)))
+ (setq erc-input-ring-index 0)))
+
+ (setq erc-input-ring-index (if erc-input-ring-index
+ (ring-plus1 erc-input-ring-index
+ (ring-length erc-input-ring))
+ 0))
+ (erc-replace-current-command (ring-ref erc-input-ring
+ erc-input-ring-index)))))
+
+(defun erc-next-command ()
+ "Replace current command with the next one from the history."
+ (interactive)
+ (unless erc-input-ring (erc-input-ring-setup))
+ ;; if the ring isn't empty
+ (when (> (ring-length erc-input-ring) 0)
+ (if (and erc-input-ring-index
+ (= 0 erc-input-ring-index))
+ (progn
+ (erc-replace-current-command "")
+ (setq erc-input-ring-index nil))
+ (setq erc-input-ring-index (ring-minus1 (or erc-input-ring-index 0)
+ (ring-length erc-input-ring)))
+ (erc-replace-current-command (ring-ref erc-input-ring
+ erc-input-ring-index)))))
+
+
+(defun erc-replace-current-command (s)
+ "Replace current command with string S."
+ ;; delete line
+ (let ((inhibit-read-only t))
+ (delete-region
+ (progn (goto-char erc-insert-marker) (erc-bol))
+ (goto-char (point-max)))
+ (insert s)))
+
+(provide 'erc-ring)
+
+;;; erc-ring.el ends here
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;; arch-tag: b77924a8-a80e-489d-84cd-b351761ea5c8
diff --git a/lisp/erc/erc-sound.el b/lisp/erc/erc-sound.el
new file mode 100644
index 00000000000..c5b0f8177f2
--- /dev/null
+++ b/lisp/erc/erc-sound.el
@@ -0,0 +1,149 @@
+;;; erc-sound.el --- CTCP SOUND support for ERC
+
+;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This used to be in erc.el, I (Jorgen) just extracted it from there
+;; and put it in this file. Bugs and features are those of the
+;; original author.
+
+;;; Code:
+
+(require 'erc)
+
+;;;###autoload (autoload 'erc-sound-mode "erc-sound")
+(define-erc-module sound ctcp-sound
+ "In ERC sound mode, the client will respond to CTCP SOUND requests
+and play sound files as requested."
+ ;; Enable:
+ ((define-key erc-mode-map "\C-c\C-s" 'erc-toggle-sound))
+ ;; Disable:
+ ((define-key erc-mode-map "\C-c\C-s" 'undefined)))
+
+(erc-define-catalog-entry 'english 'CTCP-SOUND "%n (%u@%h) plays %s:%m")
+
+(defgroup erc-sound nil
+ "Make ERC play bells and whistles while chatting with people."
+ :group 'erc)
+
+(defcustom erc-play-sound t
+ "*Play sound on SOUND ctcp requests (used in ICQ chat)."
+ :group 'erc-sound
+ :type 'boolean)
+
+(defcustom erc-sound-path nil
+ "List of directories that contain sound samples to play on SOUND events."
+ :group 'erc-sound
+ :type '(repeat directory))
+
+(defcustom erc-default-sound nil
+ "Play this sound if the requested file was not found."
+ :group 'erc-sound
+ :type '(choice (const nil)
+ file))
+
+(defcustom erc-play-command "play"
+ "Command for playing sound samples."
+ :group 'erc-sound
+ :type 'string)
+
+(defun erc-cmd-SOUND (line &optional force)
+ "Play the sound given in LINE."
+ (cond
+ ((string-match "^\\s-*\\(\\S-+\\)\\(\\s-.*\\)?$" line)
+ (let ((file (match-string 1 line))
+ (msg (match-string 2 line))
+ (tgt (erc-default-target)))
+ (if (null msg)
+ (setq msg "")
+ ;; remove the first white space
+ (setq msg (substring msg 1)))
+ (if tgt
+ (progn
+ (erc-send-ctcp-message tgt (format "SOUND %s %s" file msg) force)
+ (if erc-play-sound (erc-play-sound file)))
+ (erc-display-message nil 'error (current-buffer) 'no-target))
+ t))
+ (t nil)))
+
+(defvar erc-ctcp-query-SOUND-hook '(erc-ctcp-query-SOUND))
+(defun erc-ctcp-query-SOUND (proc nick login host to msg)
+ (when (string-match "^SOUND\\s-+\\(\\S-+\\)\\(\\(\\s-+.*\\)\\|\\(\\s-*\\)\\)$" msg)
+ (let ((sound (match-string 1 msg))
+ (comment (match-string 2 msg)))
+ (when erc-play-sound (erc-play-sound sound))
+ (erc-display-message
+ nil 'notice nil
+ 'CTCP-SOUND ?n nick ?u login ?h host ?s sound ?m comment)))
+ nil)
+
+(defun erc-play-sound (file)
+ "Plays a sound file located in one of the directories in `erc-sound-path'
+with a command `erc-play-command'."
+ (let ((filepath (erc-find-file file erc-sound-path)))
+ (if (and (not filepath) erc-default-sound)
+ (setq filepath erc-default-sound))
+ (cond ((and filepath (file-exists-p filepath))
+ (if (and (fboundp 'device-sound-enabled-p)
+ (device-sound-enabled-p))
+ ; For XEmacs
+ (play-sound-file filepath)
+; (start-process "erc-sound" nil erc-play-command filepath)
+ (start-process "erc-sound" nil "/bin/tcsh" "-c"
+ (concat erc-play-command " " filepath))))
+ (t (beep)))
+ (erc-log (format "Playing sound file %S" filepath))))
+
+;(defun erc-play-sound (file)
+; "Plays a sound file located in one of the directories in `erc-sound-path'
+; with a command `erc-play-command'."
+; (let ((filepath nil)
+; (paths erc-sound-path))
+; (while (and paths
+; (progn (setq filepath (expand-file-name file (car paths)))
+; (not (file-exists-p filepath))))
+; (setq paths (cdr paths)))
+; (if (and (not (and filepath (file-exists-p filepath)))
+; erc-default-sound)
+; (setq filepath erc-default-sound))
+; (cond ((and filepath (file-exists-p filepath))
+;; (start-process "erc-sound" nil erc-play-command filepath)
+; (start-process "erc-sound" nil "/bin/tcsh" "-c"
+; (concat erc-play-command " " filepath))
+; )
+; (t (beep)))
+; (erc-log (format "Playing sound file %S" filepath))))
+
+(defun erc-toggle-sound (&optional arg)
+ "Toggles playing sounds on and off. With positive argument,
+ turns them on. With any other argument turns sounds off."
+ (interactive "P")
+ (cond ((and (numberp arg) (> arg 0))
+ (setq erc-play-sound t))
+ (arg (setq erc-play-sound nil))
+ (t (setq erc-play-sound (not erc-play-sound))))
+ (message "ERC sound is %s" (if erc-play-sound "ON" "OFF")))
+
+
+(provide 'erc-sound)
+
+;; arch-tag: 53657d1d-007f-4a20-91c1-588e71cf0cee
+;;; erc-sound.el ends here
diff --git a/lisp/erc/erc-speedbar.el b/lisp/erc/erc-speedbar.el
new file mode 100644
index 00000000000..e6ca5382338
--- /dev/null
+++ b/lisp/erc/erc-speedbar.el
@@ -0,0 +1,369 @@
+;;; erc-speedbar.el --- Speedbar support for ERC
+
+;; Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Contributor: Eric M. Ludlam <eric@siege-engine.com>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This module provides integration of ERC into the Speedbar.
+
+;;; TODO / ideas:
+
+;; * Write intelligent update function:
+;; update-channel, update-nick, remove-nick-from-channel, ...
+;; * Use indicator-strings for op/voice
+;; * Extract/convert face notes field from bbdb if available and show
+;; it using sb-image.el
+;;
+;;; Code:
+
+(require 'erc)
+(require 'speedbar)
+(condition-case nil (require 'dframe) (error nil))
+
+;;; Customization:
+
+(defgroup erc-speedbar nil
+ "Integration of ERC in the Speedbar"
+ :group 'erc)
+
+(defcustom erc-speedbar-sort-users-type 'activity
+ "How channel nicknames are sorted.
+
+'activity - Sort users by channel activity
+'alphabetical - Sort users alphabetically
+nil - Do not sort users"
+ :group 'erc-speedbar
+ :type '(choice (const :tag "Sort users by channel activity" activity)
+ (const :tag "Sort users alphabetically" alphabetical)
+ (const :tag "Do not sort users" nil)))
+
+(defvar erc-speedbar-key-map nil
+ "Keymap used when in erc display mode.")
+
+(defun erc-install-speedbar-variables ()
+ "Install those variables used by speedbar to enhance ERC."
+ (if erc-speedbar-key-map
+ nil
+ (setq erc-speedbar-key-map (speedbar-make-specialized-keymap))
+
+ ;; Basic tree features
+ (define-key erc-speedbar-key-map "e" 'speedbar-edit-line)
+ (define-key erc-speedbar-key-map "\C-m" 'speedbar-edit-line)
+ (define-key erc-speedbar-key-map "+" 'speedbar-expand-line)
+ (define-key erc-speedbar-key-map "=" 'speedbar-expand-line)
+ (define-key erc-speedbar-key-map "-" 'speedbar-contract-line))
+
+ (speedbar-add-expansion-list '("ERC" erc-speedbar-menu-items
+ erc-speedbar-key-map
+ erc-speedbar-server-buttons))
+ (speedbar-add-mode-functions-list
+ '("ERC" (speedbar-item-info . erc-speedbar-item-info))))
+
+(defvar erc-speedbar-menu-items
+ '(["Goto buffer" speedbar-edit-line t]
+ ["Expand Node" speedbar-expand-line
+ (save-excursion (beginning-of-line)
+ (looking-at "[0-9]+: *.\\+. "))]
+ ["Contract Node" speedbar-contract-line
+ (save-excursion (beginning-of-line)
+ (looking-at "[0-9]+: *.-. "))])
+ "Additional menu-items to add to speedbar frame.")
+
+;; Make sure our special speedbar major mode is loaded
+(if (featurep 'speedbar)
+ (erc-install-speedbar-variables)
+ (add-hook 'speedbar-load-hook 'erc-install-speedbar-variables))
+
+;;; ERC hierarchy display method
+;;;###autoload
+(defun erc-speedbar-browser ()
+ "Initialize speedbar to display an ERC browser.
+This will add a speedbar major display mode."
+ (interactive)
+ (require 'speedbar)
+ ;; Make sure that speedbar is active
+ (speedbar-frame-mode 1)
+ ;; Now, throw us into Info mode on speedbar.
+ (speedbar-change-initial-expansion-list "ERC")
+ (speedbar-get-focus))
+
+(defun erc-speedbar-buttons (buffer)
+ "Create buttons for speedbar in BUFFER."
+ (erase-buffer)
+ (let (serverp chanp)
+ (with-current-buffer buffer
+ (setq serverp (eq buffer (process-buffer erc-server-process)))
+ (setq chanp (erc-channel-p (erc-default-target)))
+ (setq queryp (erc-query-buffer-p)))
+ (cond (serverp
+ (erc-speedbar-channel-buttons nil 0 buffer))
+ (chanp
+ (erc-speedbar-insert-target buffer 0)
+ (forward-line -1)
+ (erc-speedbar-expand-channel "+" buffer 0))
+ (queryp
+ (erc-speedbar-insert-target buffer 0))
+ (t (ignore)))))
+
+(defun erc-speedbar-server-buttons (directory depth)
+ "Insert the initial list of servers you are connected to."
+ (let ((servers (erc-buffer-list
+ (lambda ()
+ (eq (current-buffer)
+ (process-buffer erc-server-process))))))
+ (when servers
+ (speedbar-with-writable
+ (dolist (server servers)
+ (speedbar-make-tag-line
+ 'bracket ?+ 'erc-speedbar-expand-server server
+ (buffer-name server) 'erc-speedbar-goto-buffer server nil
+ depth))
+ t))))
+
+(defun erc-speedbar-expand-server (text server indent)
+ (cond ((string-match "+" text)
+ (speedbar-change-expand-button-char ?-)
+ (if (speedbar-with-writable
+ (save-excursion
+ (end-of-line) (forward-char 1)
+ (erc-speedbar-channel-buttons nil (1+ indent) server)))
+ (speedbar-change-expand-button-char ?-)
+ (speedbar-change-expand-button-char ??)))
+ ((string-match "-" text) ;we have to contract this node
+ (speedbar-change-expand-button-char ?+)
+ (speedbar-delete-subblock indent))
+ (t (error "Ooops... not sure what to do")))
+ (speedbar-center-buffer-smartly))
+
+(defun erc-speedbar-channel-buttons (directory depth server-buffer)
+ (when (get-buffer server-buffer)
+ (let* ((proc (with-current-buffer server-buffer erc-server-process))
+ (targets (erc-buffer-list
+ (lambda ()
+ (not (eq (process-buffer erc-server-process)
+ (current-buffer))))
+ proc)))
+ (when targets
+ (speedbar-with-writable
+ (dolist (target targets)
+ (erc-speedbar-insert-target target depth))
+ t)))))
+
+(defun erc-speedbar-insert-target (buffer depth)
+ (if (with-current-buffer buffer
+ (erc-channel-p (erc-default-target)))
+ (speedbar-make-tag-line
+ 'bracket ?+ 'erc-speedbar-expand-channel buffer
+ (buffer-name buffer) 'erc-speedbar-goto-buffer buffer nil
+ depth)
+ ;; Query target
+ (speedbar-make-tag-line
+ nil nil nil nil
+ (buffer-name buffer) 'erc-speedbar-goto-buffer buffer nil
+ depth)))
+
+(defun erc-speedbar-expand-channel (text channel indent)
+ "For the line matching TEXT, in CHANNEL, expand or contract a line.
+INDENT is the current indentation level."
+ (cond
+ ((string-match "+" text)
+ (speedbar-change-expand-button-char ?-)
+ (speedbar-with-writable
+ (save-excursion
+ (end-of-line) (forward-char 1)
+ (let ((modes (with-current-buffer channel
+ (concat (apply 'concat
+ erc-channel-modes)
+ (cond
+ ((and erc-channel-user-limit
+ erc-channel-key)
+ (if erc-show-channel-key-p
+ (format "lk %.0f %s"
+ erc-channel-user-limit
+ erc-channel-key)
+ (format "kl %.0f" erc-channel-user-limit)))
+ (erc-channel-user-limit
+ ;; Emacs has no bignums
+ (format "l %.0f" erc-channel-user-limit))
+ (erc-channel-key
+ (if erc-show-channel-key-p
+ (format "k %s" erc-channel-key)
+ "k"))
+ (t "")))))
+ (topic (erc-controls-interpret
+ (with-current-buffer channel erc-channel-topic))))
+ (speedbar-make-tag-line
+ 'angle ?i nil nil
+ (concat "Modes: +" modes) nil nil nil
+ (1+ indent))
+ (unless (string= topic "")
+ (speedbar-make-tag-line
+ 'angle ?i nil nil
+ (concat "Topic: " topic) nil nil nil
+ (1+ indent)))
+ (let ((names (cond ((eq erc-speedbar-sort-users-type 'alphabetical)
+ (erc-sort-channel-users-alphabetically
+ (with-current-buffer channel
+ (erc-get-channel-user-list))))
+ ((eq erc-speedbar-sort-users-type 'activity)
+ (erc-sort-channel-users-by-activity
+ (with-current-buffer channel
+ (erc-get-channel-user-list))))
+ (t (with-current-buffer channel
+ (erc-get-channel-user-list))))))
+ (when names
+ (speedbar-with-writable
+ (dolist (entry names)
+ (erc-speedbar-insert-user entry ?+ (1+ indent))))))))))
+ ((string-match "-" text)
+ (speedbar-change-expand-button-char ?+)
+ (speedbar-delete-subblock indent))
+ (t (error "Ooops... not sure what to do")))
+ (speedbar-center-buffer-smartly))
+
+(defun erc-speedbar-insert-user (entry exp-char indent)
+ "Insert one user based on the channel member list ENTRY.
+EXP-CHAR is the expansion character to use.
+INDENT is the current indentation level."
+ (let* ((user (car entry))
+ (cuser (cdr entry))
+ (nick (erc-server-user-nickname user))
+ (host (erc-server-user-host user))
+ (info (erc-server-user-info user))
+ (login (erc-server-user-login user))
+ (name (erc-server-user-full-name user))
+ (voice (and cuser (erc-channel-user-voice cuser)))
+ (op (and cuser (erc-channel-user-op cuser)))
+ (nick-str (concat (if op "@" "") (if voice "+" "") nick))
+ (finger (concat login (when (or login host) "@") host))
+ (sbtoken (list finger name info)))
+ (if (or login host name info) ; we want to be expandable
+ (speedbar-make-tag-line
+ 'bracket ?+ 'erc-speedbar-expand-user sbtoken
+ nick-str nil sbtoken nil
+ indent)
+ (when (equal exp-char ?-)
+ (forward-line -1)
+ (erc-speedbar-expand-user "+" (list finger name info) indent))
+ (speedbar-make-tag-line
+ 'statictag ?? nil nil
+ nick-str nil nil nil
+ indent))))
+
+(defun erc-speedbar-update-channel (buffer)
+ "Update the speedbar information about a ERC buffer. The update
+is only done when the channel is actually expanded already."
+ ;; This is only a rude hack and doesn't care about multiserver usage
+ ;; yet, consider this a brain storming, better ideas?
+ (with-current-buffer speedbar-buffer
+ (save-excursion
+ (goto-char (point-min))
+ (when (re-search-forward (concat "^1: *.+. *"
+ (regexp-quote (buffer-name buffer)))
+ nil t)
+ (beginning-of-line)
+ (speedbar-delete-subblock 1)
+ (erc-speedbar-expand-channel "+" buffer 1)))))
+
+(defun erc-speedbar-expand-user (text token indent)
+ (cond ((string-match "+" text)
+ (speedbar-change-expand-button-char ?-)
+ (speedbar-with-writable
+ (save-excursion
+ (end-of-line) (forward-char 1)
+ (let ((finger (nth 0 token))
+ (name (nth 1 token))
+ (info (nth 2 token)))
+ (when finger
+ (speedbar-make-tag-line
+ nil nil nil nil
+ finger nil nil nil
+ (1+ indent)))
+ (when name
+ (speedbar-make-tag-line
+ nil nil nil nil
+ name nil nil nil
+ (1+ indent)))
+ (when info
+ (speedbar-make-tag-line
+ nil nil nil nil
+ info nil nil nil
+ (1+ indent)))))))
+ ((string-match "-" text)
+ (speedbar-change-expand-button-char ?+)
+ (speedbar-delete-subblock indent))
+ (t (error "Ooops... not sure what to do")))
+ (speedbar-center-buffer-smartly))
+
+(defun erc-speedbar-goto-buffer (text buffer indent)
+ "When user clicks on TEXT, goto an ERC buffer.
+The INDENT level is ignored."
+ (if (featurep 'dframe)
+ (progn
+ (dframe-select-attached-frame speedbar-frame)
+ (let ((bwin (get-buffer-window buffer 0)))
+ (if bwin
+ (progn
+ (select-window bwin)
+ (raise-frame (window-frame bwin)))
+ (if dframe-power-click
+ (let ((pop-up-frames t))
+ (select-window (display-buffer buffer)))
+ (dframe-select-attached-frame speedbar-frame)
+ (switch-to-buffer buffer)))))
+ (let ((bwin (get-buffer-window buffer 0)))
+ (if bwin
+ (progn
+ (select-window bwin)
+ (raise-frame (window-frame bwin)))
+ (if speedbar-power-click
+ (let ((pop-up-frames t)) (select-window (display-buffer buffer)))
+ (select-frame speedbar-attached-frame)
+ (switch-to-buffer buffer))))))
+
+(defun erc-speedbar-line-text ()
+ "Return the text for the item on the current line."
+ (beginning-of-line)
+ (when (re-search-forward "[]>] " nil t)
+ (buffer-substring-no-properties (point) (point-at-eol))))
+
+(defun erc-speedbar-item-info ()
+ "Display information about the current buffer on the current line."
+ (let ((data (speedbar-line-token))
+ (txt (erc-speedbar-line-text)))
+ (cond ((and data (listp data))
+ (message "%s: %s" txt (car data)))
+ ((bufferp data)
+ (message "Channel: %s" txt))
+ (t
+ (message "%s" txt)))))
+
+(provide 'erc-speedbar)
+;;; erc-speedbar.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 7a6558a4-3308-4bf5-a284-e1d042c933c6
diff --git a/lisp/erc/erc-spelling.el b/lisp/erc/erc-spelling.el
new file mode 100644
index 00000000000..dd9aad68f22
--- /dev/null
+++ b/lisp/erc/erc-spelling.el
@@ -0,0 +1,93 @@
+;;; erc-spelling.el --- use flyspell in ERC
+
+;; Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+
+;; Author: Jorgen Schaefer <forcer@forcix.cx>
+;; Keywords: irc
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcSpelling
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This is an ERC module to enable flyspell mode in ERC buffers. This
+;; ensures correct behavior of flyspell, and even sets up a
+;; channel-local dictionary if so required.
+
+;;; Code:
+
+(require 'erc)
+(require 'flyspell)
+
+;;;###autoload (autoload 'erc-spelling-mode "erc-spelling" nil t)
+(define-erc-module spelling nil
+ "Enable flyspell mode in ERC buffers."
+ ;; Use erc-connect-pre-hook instead of erc-mode-hook as pre-hook is
+ ;; called AFTER the server buffer is initialized.
+ ((add-hook 'erc-connect-pre-hook 'erc-spelling-init)
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer (erc-spelling-init)))
+ (erc-buffer-list)))
+ ((remove-hook 'erc-connect-pre-hook 'erc-spelling-init)
+ (mapc (lambda (buffer)
+ (with-current-buffer buffer (flyspell-mode 0)))
+ (erc-buffer-list))))
+
+(defcustom erc-spelling-dictionaries nil
+ "An alist mapping buffer names to dictionaries.
+The `car' of every cell is a buffer name, the `cadr' is the
+string name of an associated dictionary.
+The dictionary is inherited from server buffers, so if you want a
+default dictionary for some server, you can use a server buffer
+name here."
+ :type '(choice (const nil)
+ (repeat (cons (string :tag "Buffer name")
+ (string :tag "Dictionary"))))
+ :group 'erc-spelling)
+
+(defun erc-spelling-init ()
+ "Enable flyspell mode in an ERC buffer."
+ (let ((name (downcase (buffer-name)))
+ (dicts erc-spelling-dictionaries))
+ (while (and dicts
+ (not (string= name (downcase (caar dicts)))))
+ (setq dicts (cdr dicts)))
+ (setq ispell-local-dictionary
+ (if dicts
+ (cadr (car dicts))
+ (let ((server (erc-server-buffer)))
+ (if server
+ (with-current-buffer server
+ ispell-local-dictionary)
+ nil)))))
+ (setq flyspell-generic-check-word-p 'erc-spelling-flyspell-verify)
+ (flyspell-mode 1))
+
+(put 'erc-mode
+ 'flyspell-mode-predicate
+ 'erc-spelling-flyspell-verify)
+
+(defun erc-spelling-flyspell-verify ()
+ "Flyspell only the input line, nothing else."
+ (> (point)
+ erc-input-marker))
+
+(provide 'erc-spelling)
+
+;; arch-tag: 04ae1c46-0fd1-4e1a-8b80-55bfa471c945
+;;; erc-spelling.el ends here
diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el
new file mode 100644
index 00000000000..767839e343b
--- /dev/null
+++ b/lisp/erc/erc-stamp.el
@@ -0,0 +1,335 @@
+;;; erc-stamp.el --- Timestamping for Emacs IRC CLient
+
+;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Keywords: comm, processes, timestamp
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcStamp
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; The code contained in this module is responsible for inserting
+;; timestamps into ERC buffers. In order to actually activate this,
+;; you must call `erc-timestamp-mode'.
+
+;; You can choose between two different ways of inserting timestamps.
+;; Customize `erc-insert-timestamp-function' and
+;; `erc-insert-away-timestamp-function'.
+
+;;; Code:
+
+(require 'erc)
+(require 'erc-compat)
+
+(defgroup erc-stamp nil
+ "For long conversation on IRC it is sometimes quite
+useful to have individual messages timestamp. This
+group provides settings related to the format and display
+of timestamp information in `erc-mode' buffer.
+
+For timestamping to be activated, you just need to load `erc-stamp'
+in your .emacs file or interactively using `load-library'."
+ :group 'erc)
+
+(defcustom erc-timestamp-format "[%H:%M]"
+ "*If set to a string, messages will be timestamped.
+This string is processed using `format-time-string'.
+Good examples are \"%T\" and \"%H:%M\".
+
+If nil, timestamping is turned off."
+ :group 'erc-stamp
+ :type '(choice (const nil)
+ (string)))
+
+(defcustom erc-insert-timestamp-function 'erc-insert-timestamp-right
+ "*Function to use to insert timestamps.
+
+It takes a single argument STRING which is the final string
+which all text-properties already appended. This function only cares about
+inserting this string at the right position. Narrowing is in effect
+while it is called, so (point-min) and (point-max) determine the region to
+operate on."
+ :group 'erc-stamp
+ :type '(choice (const :tag "Right" erc-insert-timestamp-right)
+ (const :tag "Left" erc-insert-timestamp-left)
+ function))
+
+(defcustom erc-away-timestamp-format "<%H:%M>"
+ "*Timestamp format used when marked as being away.
+
+If nil, timestamping is turned off when away unless `erc-timestamp-format'
+is set.
+
+If `erc-timestamp-format' is set, this will not be used."
+ :group 'erc-stamp
+ :type '(choice (const nil)
+ (string)))
+
+(defcustom erc-insert-away-timestamp-function 'erc-insert-timestamp-right
+ "*Function to use to insert the away timestamp.
+
+See `erc-insert-timestamp-function' for details."
+ :group 'erc-stamp
+ :type '(choice (const :tag "Right" erc-insert-timestamp-right)
+ (const :tag "Left" erc-insert-timestamp-left)
+ function))
+
+(defcustom erc-hide-timestamps nil
+ "*If non-nil, timestamps will be invisible.
+
+This is useful for logging, because, although timestamps will be
+hidden, they will still be present in the logs."
+ :group 'erc-stamp
+ :type 'boolean)
+
+(defcustom erc-echo-timestamps nil
+ "*If non-nil, print timestamp in the minibuffer when point is moved.
+Using this variable, you can turn off normal timestamping,
+and simply move point to an irc message to see its timestamp
+printed in the minibuffer."
+ :group 'erc-stamp
+ :type 'boolean)
+
+(defcustom erc-echo-timestamp-format "Timestamped %A, %H:%M:%S"
+ "*Format string to be used when `erc-echo-timestamps' is non-nil.
+This string specifies the format of the timestamp being echoed in
+the minibuffer."
+ :group 'erc-stamp
+ :type 'string)
+
+(defcustom erc-timestamp-intangible t
+ "*Whether the timestamps should be intangible, i.e. prevent the point
+from entering them and instead jump over them."
+ :group 'erc-stamp
+ :type 'boolean)
+
+(defface erc-timestamp-face '((t (:bold t :foreground "green")))
+ "ERC timestamp face."
+ :group 'erc-faces)
+
+;;;###autoload (autoload 'erc-timestamp-mode "erc-stamp" nil t)
+(define-erc-module stamp timestamp
+ "This mode timestamps messages in the channel buffers."
+ ((add-hook 'erc-mode-hook 'erc-munge-invisibility-spec)
+ (add-hook 'erc-insert-modify-hook 'erc-add-timestamp t)
+ (add-hook 'erc-send-modify-hook 'erc-add-timestamp t))
+ ((remove-hook 'erc-mode-hook 'erc-munge-invisibility-spec)
+ (remove-hook 'erc-insert-modify-hook 'erc-add-timestamp)
+ (remove-hook 'erc-send-modify-hook 'erc-add-timestamp)))
+
+(defun erc-add-timestamp ()
+ "Add timestamp and text-properties to message.
+
+This function is meant to be called from `erc-insert-modify-hook'
+or `erc-send-modify-hook'."
+ (unless (get-text-property (point) 'invisible)
+ (let ((ct (current-time)))
+ (if (fboundp erc-insert-timestamp-function)
+ (funcall erc-insert-timestamp-function
+ (erc-format-timestamp ct erc-timestamp-format))
+ (error "Timestamp function unbound"))
+ (when (and (fboundp erc-insert-away-timestamp-function)
+ erc-away-timestamp-format
+ (with-current-buffer (erc-server-buffer) erc-away)
+ (not erc-timestamp-format))
+ (funcall erc-insert-away-timestamp-function
+ (erc-format-timestamp ct erc-away-timestamp-format)))
+ (add-text-properties (point-min) (point-max)
+ (list 'timestamp ct))
+ (add-text-properties (point-min) (point-max)
+ (list 'point-entered 'erc-echo-timestamp)))))
+
+(defvar erc-timestamp-last-inserted nil
+ "Last timestamp inserted into the buffer.")
+(make-variable-buffer-local 'erc-timestamp-last-inserted)
+
+(defcustom erc-timestamp-only-if-changed-flag t
+ "*Insert timestamp only if its value changed since last insertion.
+If `erc-insert-timestamp-function' is `erc-insert-timestamp-left', a
+string of spaces which is the same size as the timestamp is added to
+the beginning of the line in its place. If you use
+`erc-insert-timestamp-right', nothing gets inserted in place of the
+timestamp."
+ :group 'erc-stamp
+ :type 'boolean)
+
+(defcustom erc-timestamp-right-column nil
+ "*If non-nil, the column at which the timestamp is inserted,
+if the timestamp is to be printed to the right. If nil,
+`erc-insert-timestamp-right' will use other means to determine
+the correct column."
+ :group 'erc-stamp
+ :type '(choice
+ (integer :tag "Column number")
+ (const :tag "Unspecified" nil)))
+
+(defun erc-insert-timestamp-left (string)
+ "Insert timestamps at the beginning of the line."
+ (goto-char (point-min))
+ (let* ((ignore-p (and erc-timestamp-only-if-changed-flag
+ (string-equal string erc-timestamp-last-inserted)))
+ (len (length string))
+ (s (if ignore-p (make-string len ? ) string)))
+ (unless ignore-p (setq erc-timestamp-last-inserted string))
+ (erc-put-text-property 0 len 'field 'erc-timestamp s)
+ (insert s)))
+
+(defun erc-insert-aligned (string pos &optional fallback)
+ "Insert STRING based on a fraction of the width of the buffer.
+Fraction is roughly (/ POS (window-width)).
+
+If the current version of Emacs doesn't support this, use
+\(- POS FALLBACK) to determine how many spaces to insert."
+ (if (or (featurep 'xemacs)
+ (< emacs-major-version 22)
+ (not (eq window-system 'x)))
+ (insert (make-string (- pos fallback) ? ) string)
+ (insert " ")
+ (let ((offset (floor (* (/ (1- pos) (window-width) 1.0)
+ (nth 2 (window-inside-pixel-edges))))))
+ (put-text-property (1- (point)) (point) 'display
+ `(space :align-to (,offset))))
+ (insert string)))
+
+(defun erc-insert-timestamp-right (string)
+ "Insert timestamp on the right side of the screen.
+STRING is the timestamp to insert. The function is a possible value
+for `erc-insert-timestamp-function'.
+
+If `erc-timestamp-only-if-changed-flag' is nil, a timestamp is always
+printed. If this variable is non-nil, a timestamp is only printed if
+it is different from the last.
+
+If `erc-timestamp-right-column' is set, its value will be used as the
+column at which the timestamp is to be printed. If it is nil, and
+`erc-fill-mode' is active, then the timestamp will be printed just
+before `erc-fill-column'. Otherwise, if the current buffer is
+shown in a window, that window's width is used. If the buffer is
+not shown, and `fill-column' is set, then the timestamp will be
+printed just `fill-column'. As a last resort, the timestamp will
+be printed just before the window-width."
+ (unless (and erc-timestamp-only-if-changed-flag
+ (string-equal string erc-timestamp-last-inserted))
+ (setq erc-timestamp-last-inserted string)
+ (goto-char (point-max))
+ (forward-char -1);; before the last newline
+ (let* ((current-window (get-buffer-window (current-buffer)))
+ (pos (cond
+ (erc-timestamp-right-column
+ (+ erc-timestamp-right-column (length string)))
+ ((and (boundp 'erc-fill-mode)
+ erc-fill-mode
+ (boundp 'erc-fill-column))
+ (1+ erc-fill-column))
+ (current-window
+ (- (window-width current-window)
+ 1))
+ (fill-column
+ (1+ fill-column))
+ (t
+ (- (window-width)
+ 1))))
+ (from (point))
+ (col (current-column))
+ indent)
+ ;; deal with variable-width characters
+ (setq pos (- pos (string-width string))
+ ;; the following is a kludge that works with most
+ ;; international input
+ col (+ col (ceiling (/ (- col (- (point) (point-at-bol))) 1.6))))
+ (if (< col pos)
+ (erc-insert-aligned string pos col)
+ (newline)
+ (setq from (point))
+ (indent-to pos)
+ (insert string))
+ (erc-put-text-property from (1+ (point)) 'field 'erc-timestamp)
+ (erc-put-text-property from (1+ (point)) 'rear-nonsticky t)
+ (when erc-timestamp-intangible
+ (erc-put-text-property from (1+ (point)) 'intangible t)))))
+
+;; for testing: (setq erc-timestamp-only-if-changed-flag nil)
+
+(defun erc-format-timestamp (time format)
+ "Return TIME formatted as string according to FORMAT.
+Return the empty string if FORMAT is nil."
+ (if format
+ (let ((ts (format-time-string format time)))
+ (erc-put-text-property 0 (length ts) 'face 'erc-timestamp-face ts)
+ (erc-put-text-property 0 (length ts) 'invisible 'timestamp ts)
+ (erc-put-text-property 0 (length ts)
+ 'isearch-open-invisible 'timestamp ts)
+ ;; N.B. Later use categories instead of this harmless, but
+ ;; inelegant, hack. -- BPT
+ (when erc-timestamp-intangible
+ (erc-put-text-property 0 (length ts) 'intangible t ts))
+ ts)
+ ""))
+
+;; This function is used to munge `buffer-invisibility-spec to an
+;; appropriate value. Currently, it only handles timestamps, thus its
+;; location. If you add other features which affect invisibility,
+;; please modify this function and move it to a more appropriate
+;; location.
+(defun erc-munge-invisibility-spec ()
+ (if erc-hide-timestamps
+ (setq buffer-invisibility-spec
+ (if (listp buffer-invisibility-spec)
+ (cons 'timestamp buffer-invisibility-spec)
+ (list 't 'timestamp)))
+ (setq buffer-invisibility-spec
+ (if (listp buffer-invisibility-spec)
+ (remove 'timestamp buffer-invisibility-spec)
+ (list 't)))))
+
+(defun erc-hide-timestamps ()
+ "Hide timestamp information from display."
+ (interactive)
+ (setq erc-hide-timestamps t)
+ (erc-munge-invisibility-spec))
+
+(defun erc-show-timestamps ()
+ "Show timestamp information on display.
+This function only works if `erc-timestamp-format' was previously
+set, and timestamping is already active."
+ (interactive)
+ (setq erc-hide-timestamps nil)
+ (erc-munge-invisibility-spec))
+
+(defun erc-echo-timestamp (before now)
+ "Print timestamp text-property of an IRC message.
+Argument BEFORE is where point was before it got moved and
+NOW is position of point currently."
+ (when erc-echo-timestamps
+ (let ((stamp (get-text-property now 'timestamp)))
+ (when stamp
+ (message (format-time-string erc-echo-timestamp-format
+ stamp))))))
+
+(provide 'erc-stamp)
+
+;;; erc-stamp.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 9f6d31bf-61ba-45c5-bdbf-56331486ea27
diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el
new file mode 100644
index 00000000000..6d760d75ba2
--- /dev/null
+++ b/lisp/erc/erc-track.el
@@ -0,0 +1,839 @@
+;;; erc-track.el --- Track modified channel buffers
+
+;; Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Keywords: comm, faces
+;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?ErcChannelTracking
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Highlights keywords and pals (friends), and hides or highlights fools
+;; (using a dark color). Add to your ~/.emacs:
+
+;; (require 'erc-track)
+;; (erc-track-mode 1)
+
+;; Todo:
+;; * Add extensibility so that custom functions can track
+;; custom modification types.
+
+(eval-when-compile (require 'cl))
+(require 'erc)
+(require 'erc-compat)
+(require 'erc-match)
+
+;;; Code:
+
+(defgroup erc-track nil
+ "Track active buffers and show activity in the modeline."
+ :group 'erc)
+
+(defcustom erc-track-visibility t
+ "Where do we look for buffers to determine their visibility?
+The value of this variable determines, when a buffer is considered
+visible or invisible. New messages in invisible buffers are tracked,
+while switching to visible buffers when they are tracked removes them
+from the list. See also `erc-track-when-inactive-mode'.
+
+Possible values are:
+
+t - all frames
+visible - all visible frames
+nil - only the selected frame
+selected-visible - only the selected frame if it is visible
+
+Activity means that there was no user input in the last 10 seconds."
+ :group 'erc-track
+ :type '(choice (const :tag "All frames" t)
+ (const :tag "All visible frames" visible)
+ (const :tag "Only the selected frame" nil)
+ (const :tag "Only the selected frame if it was active"
+ active)))
+
+(defcustom erc-track-exclude nil
+ "A list targets (channel names or query targets) which should not be tracked."
+ :group 'erc-track
+ :type '(repeat string))
+
+(defcustom erc-track-exclude-types '("NICK")
+ "*List of message types to be ignored.
+This list could look like '(\"JOIN\" \"PART\")."
+ :group 'erc-track
+ :type 'erc-message-type)
+
+(defcustom erc-track-exclude-server-buffer nil
+ "*If true, don't perform tracking on the server buffer; this is
+useful for excluding all the things like MOTDs from the server and
+other miscellaneous functions."
+ :group 'erc-track
+ :type 'boolean)
+
+(defcustom erc-track-shorten-start 1
+ "This number specifies the minimum number of characters a channel name in
+the mode-line should be reduced to."
+ :group 'erc-track
+ :type 'number)
+
+(defcustom erc-track-shorten-cutoff 4
+ "All channel names longer than this value will be shortened."
+ :group 'erc-track
+ :type 'number)
+
+(defcustom erc-track-shorten-aggressively nil
+ "*If non-nil, channel names will be shortened more aggressively.
+Usually, names are not shortened if this will save only one character.
+Example: If there are two channels, #linux-de and #linux-fr, then
+normally these will not be shortened. When shortening aggressively,
+however, these will be shortened to #linux-d and #linux-f.
+
+If this variable is set to `max', then channel names will be shortened
+to the max. Usually, shortened channel names will remain unique for a
+given set of existing channels. When shortening to the max, the shortened
+channel names will be unique for the set of active channels only.
+Example: If there are tow active channels #emacs and #vi, and two inactive
+channels #electronica and #folk, then usually the active channels are
+shortened to #em and #v. When shortening to the max, however, #emacs is
+not compared to #electronica -- only to #vi, therefore it can be shortened
+even more and the result is #e and #v.
+
+This setting is used by `erc-track-shorten-names'."
+ :group 'erc-track
+ :type '(choice (const :tag "No" nil)
+ (const :tag "Yes" t)
+ (const :tag "Max" max)))
+
+(defcustom erc-track-shorten-function 'erc-track-shorten-names
+ "*This function will be used to reduce the channel names before display.
+It takes one argument, CHANNEL-NAMES which is a list of strings.
+It should return a list of strings of the same number of elements.
+If nil instead of a function, shortening is disabled."
+ :group 'erc-track
+ :type '(choice (const :tag "Disabled")
+ function))
+
+(defcustom erc-track-use-faces t
+ "*Use faces in the mode-line.
+The faces used are the same as used for text in the buffers.
+\(e.g. `erc-pal-face' is used if a pal sent a message to that channel.)"
+ :group 'erc-track
+ :type 'boolean)
+
+(defcustom erc-track-faces-priority-list
+ '(erc-error-face erc-current-nick-face erc-keyword-face erc-pal-face
+ erc-nick-msg-face erc-direct-msg-face erc-button erc-dangerous-host-face
+ erc-default-face erc-action-face erc-nick-default-face erc-fool-face
+ erc-notice-face erc-input-face erc-prompt-face)
+ "A list of faces used to highlight active buffer names in the modeline.
+If a message contains one of the faces in this list, the buffer name will
+be highlighted using that face. The first matching face is used."
+ :group 'erc-track
+ :type '(repeat face))
+
+(defcustom erc-track-priority-faces-only nil
+ "Only track text highlighted with a priority face.
+If you would like to ignore changes in certain channels where there
+are no faces corresponding to your `erc-track-faces-priority-list', set
+this variable. You can set a list of channel name strings, so those
+will be ignored while all other channels will be tracked as normal.
+Other options are 'all, to apply this to all channels or nil, to disable
+this feature.
+Note: If you have a lot of faces listed in `erc-track-faces-priority-list',
+setting this variable might not be very useful."
+ :group 'erc-track
+ :type '(choice (const nil)
+ (repeat string)
+ (const all)))
+
+(defcustom erc-track-position-in-mode-line 'before-modes
+ "Where to show modified channel information in the mode-line.
+
+Setting this variable only has effects in GNU Emacs versions above 21.3.
+
+Choices are:
+'before-modes - add to the beginning of `mode-line-modes'
+'after-modes - add to the end of `mode-line-modes'
+
+Any other value means add to the end of `global-mode-string'."
+ :group 'erc-track
+ :type '(choice (const :tag "Just before mode information" before-modes)
+ (const :tag "Just after mode information" after-modes)
+ (const :tag "After all other information" nil))
+ :set (lambda (sym val)
+ (set sym val)
+ (when (and (boundp 'erc-track-mode)
+ erc-track-mode)
+ (erc-track-remove-from-mode-line)
+ (erc-track-add-to-mode-line val))))
+
+(defun erc-modified-channels-object (strings)
+ "Generate a new `erc-modified-channels-object' based on STRINGS.
+If STRINGS is nil, we initialize `erc-modified-channels-object' to
+an appropriate initial value for this flavor of Emacs."
+ (if strings
+ (if (featurep 'xemacs)
+ (let ((e-m-c-s '("[")))
+ (push (cons (extent-at 0 (car strings)) (car strings))
+ e-m-c-s)
+ (dolist (string (cdr strings))
+ (push "," e-m-c-s)
+ (push (cons (extent-at 0 string) string)
+ e-m-c-s))
+ (push "] " e-m-c-s)
+ (reverse e-m-c-s))
+ (concat (if (eq erc-track-position-in-mode-line 'after-modes)
+ "[" " [")
+ (mapconcat 'identity (nreverse strings) ",")
+ (if (eq erc-track-position-in-mode-line 'before-modes)
+ "] " "]")))
+ (if (featurep 'xemacs) '() "")))
+
+(defvar erc-modified-channels-object (erc-modified-channels-object nil)
+ "Internal object used for displaying modified channels in the mode line.")
+
+(put 'erc-modified-channels-object 'risky-local-variable t); allow properties
+
+(defvar erc-modified-channels-alist nil
+ "An ALIST used for tracking channel modification activity.
+Each element looks like (BUFFER COUNT FACE) where BUFFER is a buffer
+object of the channel the entry corresponds to, COUNT is a number
+indicating how often activity was noticed, and FACE is the face to use
+when displaying the buffer's name. See `erc-track-faces-priority-list',
+and `erc-track-showcount'.
+
+Entries in this list should only happen for buffers where activity occurred
+while the buffer was not visible.")
+
+(defcustom erc-track-showcount nil
+ "If non-nil, count of unseen messages will be shown for each channel."
+ :type 'boolean
+ :group 'erc-track)
+
+(defcustom erc-track-showcount-string ":"
+ "The string to display between buffer name and the count in the mode line.
+The default is a colon, resulting in \"#emacs:9\"."
+ :type 'string
+ :group 'erc-track)
+
+(defcustom erc-track-switch-from-erc t
+ "If non-nil, `erc-track-switch-buffer' will return to the last non-erc buffer
+when there are no more active channels."
+ :type 'boolean
+ :group 'erc-track)
+
+(defcustom erc-track-switch-direction 'oldest
+ "Direction `erc-track-switch-buffer' should switch.
+
+ oldest - find oldest active buffer
+ newest - find newest active buffer
+ leastactive - find buffer with least unseen messages
+ mostactive - find buffer with most unseen messages."
+ :group 'erc-track
+ :type '(choice (const oldest)
+ (const newest)
+ (const leastactive)
+ (const mostactive)))
+
+
+(defun erc-track-remove-from-mode-line ()
+ "Remove `erc-track-modified-channels' from the mode-line"
+ (when (boundp 'mode-line-modes)
+ (setq mode-line-modes
+ (remove '(t erc-modified-channels-object) mode-line-modes)))
+ (when (consp global-mode-string)
+ (setq global-mode-string
+ (delq 'erc-modified-channels-object global-mode-string))))
+
+(defun erc-track-add-to-mode-line (position)
+ "Add `erc-track-modified-channels' to POSITION in the mode-line.
+See `erc-track-position-in-mode-line' for possible values."
+ ;; CVS Emacs has a new format string, and global-mode-string
+ ;; is very far to the right.
+ (cond ((and (eq position 'before-modes)
+ (boundp 'mode-line-modes))
+ (add-to-list 'mode-line-modes
+ '(t erc-modified-channels-object)))
+ ((and (eq position 'after-modes)
+ (boundp 'mode-line-modes))
+ (add-to-list 'mode-line-modes
+ '(t erc-modified-channels-object) t))
+ (t
+ (when (not global-mode-string)
+ (setq global-mode-string '(""))) ; Padding for mode-line wart
+ (add-to-list 'global-mode-string
+ 'erc-modified-channels-object
+ t))))
+
+;;; Shortening of names
+
+(defun erc-track-shorten-names (channel-names)
+ "Call `erc-unique-channel-names' with the correct parameters.
+This function is a good value for `erc-track-shorten-function'.
+The list of all channels is returned by `erc-all-buffer-names'.
+CHANNEL-NAMES is the list of active channel names.
+Only channel names longer than `erc-track-shorten-cutoff' are
+actually shortened, and they are only shortened to a minimum
+of `erc-track-shorten-start' characters."
+ (erc-unique-channel-names
+ (erc-all-buffer-names)
+ channel-names
+ (lambda (s)
+ (> (length s) erc-track-shorten-cutoff))
+ erc-track-shorten-start))
+
+(defvar erc-default-recipients)
+
+(defun erc-all-buffer-names ()
+ "Return all channel or query buffer names.
+Note that we cannot use `erc-channel-list' with a nil argument,
+because that does not return query buffers."
+ (save-excursion
+ (let (result)
+ (dolist (buf (buffer-list))
+ (set-buffer buf)
+ (when (or (eq major-mode 'erc-mode) (eq major-mode 'erc-dcc-chat-mode))
+ (setq result (cons (buffer-name) result))))
+ result)))
+
+(defun erc-unique-channel-names (all active &optional predicate start)
+ "Return a list of unique channel names.
+ALL is the list of all channel and query buffer names.
+ACTIVE is the list of active buffer names.
+PREDICATE is a predicate that should return non-nil if a name needs
+ no shortening.
+START is the minimum length of the name used."
+ (if (eq 'max erc-track-shorten-aggressively)
+ ;; Return the unique substrings of all active channels.
+ (erc-unique-substrings active predicate start)
+ ;; Otherwise, determine the unique substrings of all channels, and
+ ;; for every active channel, return the corresponding substring.
+ ;; Given the names of the active channels, we now need to find the
+ ;; corresponding short name from the list of all substrings. To
+ ;; avoid problems when there are two channels and one is a
+ ;; substring of the other (notorious examples are #hurd and
+ ;; #hurd-bunny), every candidate gets the longest possible
+ ;; substring.
+ (let ((all-substrings (sort
+ (erc-unique-substrings all predicate start)
+ (lambda (a b) (> (length a) (length b)))))
+ result)
+ (dolist (channel active)
+ (let ((substrings all-substrings)
+ candidate
+ winner)
+ (while (and substrings (not winner))
+ (setq candidate (car substrings)
+ substrings (cdr substrings))
+ (when (and (string= candidate
+ (substring channel
+ 0
+ (min (length candidate)
+ (length channel))))
+ (not (member candidate result)))
+ (setq winner candidate)))
+ (setq result (cons winner result))))
+ (nreverse result))))
+
+(defun erc-unique-substrings (strings &optional predicate start)
+ "Return a list of unique substrings of STRINGS."
+ (if (or (not (numberp start))
+ (< start 0))
+ (setq start 2))
+ (mapcar
+ (lambda (str)
+ (let* ((others (delete str (copy-sequence strings)))
+ (maxlen (length str))
+ (i (min start
+ (length str)))
+ candidate
+ done)
+ (if (and (functionp predicate) (not (funcall predicate str)))
+ ;; do not shorten if a predicate exists and it returns nil
+ str
+ ;; Start with smallest substring candidate, ie. length 1.
+ ;; Then check all the others and see whether any of them starts
+ ;; with the same substring. While there is such another
+ ;; element in the list, increase the length of the candidate.
+ (while (not done)
+ (if (> i maxlen)
+ (setq done t)
+ (setq candidate (substring str 0 i)
+ done (not (erc-unique-substring-1 candidate others))))
+ (setq i (1+ i)))
+ (if (and (= (length candidate) (1- maxlen))
+ (not erc-track-shorten-aggressively))
+ str
+ candidate))))
+ strings))
+
+(defun erc-unique-substring-1 (candidate others)
+ "Return non-nil when any string in OTHERS starts with CANDIDATE."
+ (let (result other (maxlen (length candidate)))
+ (while (and others
+ (not result))
+ (setq other (car others)
+ others (cdr others))
+ (when (and (>= (length other) maxlen)
+ (string= candidate (substring other 0 maxlen)))
+ (setq result other)))
+ result))
+
+;;; Test:
+
+(erc-assert
+ (and
+ ;; verify examples from the doc strings
+ (equal (let ((erc-track-shorten-aggressively nil))
+ (erc-unique-channel-names
+ '("#emacs" "#vi" "#electronica" "#folk")
+ '("#emacs" "#vi")))
+ '("#em" "#vi")) ; emacs is different from electronica
+ (equal (let ((erc-track-shorten-aggressively t))
+ (erc-unique-channel-names
+ '("#emacs" "#vi" "#electronica" "#folk")
+ '("#emacs" "#vi")))
+ '("#em" "#v")) ; vi is shortened by one letter
+ (equal (let ((erc-track-shorten-aggressively 'max))
+ (erc-unique-channel-names
+ '("#emacs" "#vi" "#electronica" "#folk")
+ '("#emacs" "#vi")))
+ '("#e" "#v")) ; emacs need not be different from electronica
+ (equal (let ((erc-track-shorten-aggressively nil))
+ (erc-unique-channel-names
+ '("#linux-de" "#linux-fr")
+ '("#linux-de" "#linux-fr")))
+ '("#linux-de" "#linux-fr")) ; shortening by one letter is too aggressive
+ (equal (let ((erc-track-shorten-aggressively t))
+ (erc-unique-channel-names
+ '("#linux-de" "#linux-fr")
+ '("#linux-de" "#linux-fr")))
+ '("#linux-d" "#linux-f")); now we want to be aggressive
+ ;; specific problems
+ (equal (let ((erc-track-shorten-aggressively nil))
+ (erc-unique-channel-names
+ '("#dunnet" "#lisp" "#sawfish" "#fsf" "#guile"
+ "#testgnome" "#gnu" "#fsbot" "#hurd" "#hurd-bunny"
+ "#emacs")
+ '("#hurd-bunny" "#hurd" "#sawfish" "#lisp")))
+ '("#hurd-" "#hurd" "#s" "#l"))
+ (equal (let ((erc-track-shorten-aggressively nil))
+ (erc-unique-substrings
+ '("#emacs" "#vi" "#electronica" "#folk")))
+ '("#em" "#vi" "#el" "#f"))
+ (equal (let ((erc-track-shorten-aggressively t))
+ (erc-unique-substrings
+ '("#emacs" "#vi" "#electronica" "#folk")))
+ '("#em" "#v" "#el" "#f"))
+ (equal (let ((erc-track-shorten-aggressively nil))
+ (erc-unique-channel-names
+ '("#emacs" "#burse" "+linux.de" "#starwars"
+ "#bitlbee" "+burse" "#ratpoison")
+ '("+linux.de" "#starwars" "#burse")))
+ '("+l" "#s" "#bu"))
+ (equal (let ((erc-track-shorten-aggressively nil))
+ (erc-unique-channel-names
+ '("fsbot" "#emacs" "deego")
+ '("fsbot")))
+ '("fs"))
+ (equal (let ((erc-track-shorten-aggressively nil))
+ (erc-unique-channel-names
+ '("fsbot" "#emacs" "deego")
+ '("fsbot")
+ (lambda (s)
+ (> (length s) 4))
+ 1))
+ '("f"))
+ (equal (let ((erc-track-shorten-aggressively nil))
+ (erc-unique-channel-names
+ '("fsbot" "#emacs" "deego")
+ '("fsbot")
+ (lambda (s)
+ (> (length s) 4))
+ 2))
+ '("fs"))
+ (let ((erc-track-shorten-aggressively nil))
+ (equal (erc-unique-channel-names '("deego" "#hurd" "#hurd-bunny" "#emacs")
+ '("#hurd" "#hurd-bunny"))
+ '("#hurd" "#hurd-")))
+ ;; general examples
+ (let ((erc-track-shorten-aggressively t))
+ (and (equal (erc-unique-substring-1 "abc" '("ab" "abcd")) "abcd")
+ (not (erc-unique-substring-1 "a" '("xyz" "xab")))
+ (equal (erc-unique-substrings '("abc" "xyz" "xab"))
+ '("ab" "xy" "xa"))
+ (equal (erc-unique-substrings '("abc" "abcdefg"))
+ '("abc" "abcd"))))
+ (let ((erc-track-shorten-aggressively nil))
+ (and (equal (erc-unique-substring-1 "abc" '("ab" "abcd")) "abcd")
+ (not (erc-unique-substring-1 "a" '("xyz" "xab")))
+ (equal (erc-unique-substrings '("abc" "xyz" "xab"))
+ '("abc" "xyz" "xab"))
+ (equal (erc-unique-substrings '("abc" "abcdefg"))
+ '("abc" "abcd"))))))
+
+;;; Module
+
+;;;###autoload (autoload 'erc-track-mode "erc-track" nil t)
+(define-erc-module track track-modified-channels
+ "This mode tracks ERC channel buffers with activity."
+ ((erc-track-add-to-mode-line erc-track-position-in-mode-line)
+ (setq erc-modified-channels-object (erc-modified-channels-object nil))
+ (erc-update-mode-line)
+ (if (featurep 'xemacs)
+ (defadvice switch-to-buffer (after erc-update (&rest args) activate)
+ (erc-modified-channels-update))
+ (add-hook 'window-configuration-change-hook 'erc-modified-channels-update))
+ (add-hook 'erc-insert-post-hook 'erc-track-modified-channels)
+ (add-hook 'erc-disconnected-hook 'erc-modified-channels-update))
+ ((erc-track-remove-from-mode-line)
+ (if (featurep 'xemacs)
+ (ad-disable-advice 'switch-to-buffer 'after 'erc-update)
+ (remove-hook 'window-configuration-change-hook
+ 'erc-modified-channels-update))
+ (remove-hook 'erc-disconnected-hook 'erc-modified-channels-update)
+ (remove-hook 'erc-insert-post-hook 'erc-track-modified-channels)))
+
+;;;###autoload (autoload 'erc-track-when-inactive-mode "erc-track" nil t)
+(define-erc-module track-when-inactive nil
+ "This mode enables channel tracking even for visible buffers,
+if you are inactivity."
+ ((if (featurep 'xemacs)
+ (defadvice switch-to-buffer (after erc-update-when-inactive (&rest args) activate)
+ (erc-user-is-active))
+ (add-hook 'window-configuration-change-hook 'erc-user-is-active))
+ (add-hook 'erc-send-completed-hook 'erc-user-is-active)
+ (add-hook 'erc-server-001-functions 'erc-user-is-active))
+ ((erc-track-remove-from-mode-line)
+ (if (featurep 'xemacs)
+ (ad-disable-advice 'switch-to-buffer 'after 'erc-update-when-inactive)
+ (remove-hook 'window-configuration-change-hook 'erc-user-is-active))
+ (remove-hook 'erc-send-completed-hook 'erc-user-is-active)
+ (remove-hook 'erc-server-001-functions 'erc-user-is-active)
+ (remove-hook 'erc-timer-hook 'erc-user-is-active)))
+
+;;; Visibility
+
+(defvar erc-buffer-activity nil
+ "Last time the user sent something.")
+
+(defvar erc-buffer-activity-timeout 10
+ "How many seconds of inactivity by the user
+to consider when `erc-track-visibility' is set to
+only consider active buffers visible.")
+
+(defun erc-user-is-active (&rest ignore)
+ "Set `erc-buffer-activity'."
+ (setq erc-buffer-activity (erc-current-time))
+ (erc-track-modified-channels))
+
+(defun erc-buffer-visible (buffer)
+ "Return non-nil when the buffer is visible."
+ (if erc-track-when-inactive-mode
+ (when erc-buffer-activity; could be nil
+ (and (get-buffer-window buffer erc-track-visibility)
+ (<= (erc-time-diff erc-buffer-activity (erc-current-time))
+ erc-buffer-activity-timeout)))
+ (get-buffer-window buffer erc-track-visibility)))
+
+;;; Tracking the channel modifications
+
+(defvar erc-modified-channels-update-inside nil
+ "Variable to prevent running `erc-modified-channels-update' multiple
+times. Without it, you cannot debug `erc-modified-channels-display',
+because the debugger also cases changes to the window-configuration.")
+
+(defun erc-modified-channels-update (&rest args)
+ "This function updates the information in `erc-modified-channels-alist'
+according to buffer visibility. It calls
+`erc-modified-channels-display' at the end. This should usually be
+called via `window-configuration-change-hook'.
+ARGS are ignored."
+ (interactive)
+ (unless erc-modified-channels-update-inside
+ (let ((erc-modified-channels-update-inside t))
+ (mapcar (lambda (elt)
+ (let ((buffer (car elt)))
+ (when (or (not (bufferp buffer))
+ (not (buffer-live-p buffer))
+ (erc-buffer-visible buffer)
+ (not (with-current-buffer buffer
+ erc-server-connected)))
+ (erc-modified-channels-remove-buffer buffer))))
+ erc-modified-channels-alist)
+ (erc-modified-channels-display)
+ (force-mode-line-update t))))
+
+(defun erc-make-mode-line-buffer-name (string buffer &optional faces count)
+ "Return STRING as a button that switches to BUFFER when clicked.
+If FACES are provided, color STRING with them."
+ ;; We define a new sparse keymap every time, because 1. this data
+ ;; structure is very small, the alternative would require us to
+ ;; defvar a keymap, 2. the user is not interested in customizing it
+ ;; (really?), 3. the defun needs to switch to BUFFER, so we would
+ ;; need to save that value somewhere.
+ (let ((map (make-sparse-keymap))
+ (name (if erc-track-showcount
+ (concat string
+ erc-track-showcount-string
+ (int-to-string count))
+ (copy-sequence string))))
+ (define-key map (vector 'mode-line 'mouse-2)
+ `(lambda (e)
+ (interactive "e")
+ (save-selected-window
+ (select-window
+ (posn-window (event-start e)))
+ (switch-to-buffer ,buffer))))
+ (define-key map (vector 'mode-line 'mouse-3)
+ `(lambda (e)
+ (interactive "e")
+ (save-selected-window
+ (select-window
+ (posn-window (event-start e)))
+ (switch-to-buffer-other-window ,buffer))))
+ (put-text-property 0 (length name) 'local-map map name)
+ (when (and faces erc-track-use-faces)
+ (put-text-property 0 (length name) 'face faces name))
+ name))
+
+(defun erc-modified-channels-display ()
+ "Set `erc-modified-channels-object'
+according to `erc-modified-channels-alist'.
+Use `erc-make-mode-line-buffer-name' to create buttons."
+ (if (or
+ (eq 'mostactive erc-track-switch-direction)
+ (eq 'leastactive erc-track-switch-direction))
+ (erc-track-sort-by-activest))
+ (if (null erc-modified-channels-alist)
+ (setq erc-modified-channels-object (erc-modified-channels-object nil))
+ ;; erc-modified-channels-alist contains all the data we need. To
+ ;; better understand what is going on, we split things up into
+ ;; four lists: BUFFERS, COUNTS, SHORT-NAMES, and FACES. These
+ ;; four lists we use to create a new
+ ;; `erc-modified-channels-object' using
+ ;; `erc-make-mode-line-buffer-name'.
+ (let* ((buffers (mapcar 'car erc-modified-channels-alist))
+ (counts (mapcar 'cadr erc-modified-channels-alist))
+ (faces (mapcar 'cddr erc-modified-channels-alist))
+ (long-names (mapcar #'(lambda (buf)
+ (or (buffer-name buf)
+ ""))
+ buffers))
+ (short-names (if (functionp erc-track-shorten-function)
+ (funcall erc-track-shorten-function
+ long-names)
+ long-names))
+ strings)
+ (while buffers
+ (when (car short-names)
+ (setq strings (cons (erc-make-mode-line-buffer-name
+ (car short-names)
+ (car buffers)
+ (car faces)
+ (car counts))
+ strings)))
+ (setq short-names (cdr short-names)
+ buffers (cdr buffers)
+ counts (cdr counts)
+ faces (cdr faces)))
+ (when (featurep 'xemacs)
+ (erc-modified-channels-object nil))
+ (setq erc-modified-channels-object
+ (erc-modified-channels-object strings)))))
+
+(defun erc-modified-channels-remove-buffer (buffer)
+ "Remove BUFFER from `erc-modified-channels-alist'."
+ (interactive "bBuffer: ")
+ (setq erc-modified-channels-alist
+ (delete (assq buffer erc-modified-channels-alist)
+ erc-modified-channels-alist))
+ (when (interactive-p)
+ (erc-modified-channels-display)))
+
+(defun erc-track-find-face (faces)
+ "Return the face to use in the modeline from the faces in FACES.
+If `erc-track-faces-priority-list' is set, the one from FACES who is
+first in that list will be used."
+ (let ((candidates erc-track-faces-priority-list)
+ candidate face)
+ (while (and candidates (not face))
+ (setq candidate (car candidates)
+ candidates (cdr candidates))
+ (when (memq candidate faces)
+ (setq face candidate)))
+ face))
+
+(defun erc-track-modified-channels ()
+ "Hook function for `erc-insert-post-hook' to check if the current
+buffer should be added to the modeline as a hidden, modified
+channel. Assumes it will only be called when current-buffer
+is in `erc-mode'."
+ (let ((this-channel (or (erc-default-target)
+ (buffer-name (current-buffer)))))
+ (if (and (not (erc-buffer-visible (current-buffer)))
+ (not (member this-channel erc-track-exclude))
+ (not (and erc-track-exclude-server-buffer
+ (string= this-channel
+ (buffer-name (erc-server-buffer)))))
+ (not (erc-message-type-member
+ (or (erc-find-parsed-property)
+ (point-min))
+ erc-track-exclude-types)))
+ ;; If the active buffer is not visible (not shown in a
+ ;; window), and not to be excluded, determine the kinds of
+ ;; faces used in the current message, and unless the user
+ ;; wants to ignore changes in certain channels where there
+ ;; are no faces corresponding to `erc-track-faces-priority-list',
+ ;; and the faces in the current message are found in said
+ ;; priority list, add the buffer to the erc-modified-channels-alist,
+ ;; if it is not already there. If the buffer is already on the list
+ ;; (in the car), change its face attribute (in the cddr) if
+ ;; necessary. See `erc-modified-channels-alist' for the
+ ;; exact data structure used.
+ (let ((faces (erc-faces-in (buffer-string))))
+ (unless (and
+ (or (eq erc-track-priority-faces-only 'all)
+ (member this-channel erc-track-priority-faces-only))
+ (not (catch 'found
+ (dolist (f faces)
+ (when (member f erc-track-faces-priority-list)
+ (throw 'found t))))))
+ (if (not (assq (current-buffer) erc-modified-channels-alist))
+ ;; Add buffer, faces and counts
+ (setq erc-modified-channels-alist
+ (cons (cons (current-buffer)
+ (cons 1 (erc-track-find-face faces)))
+ erc-modified-channels-alist))
+ ;; Else modify the face for the buffer, if necessary.
+ (when faces
+ (let* ((cell (assq (current-buffer)
+ erc-modified-channels-alist))
+ (old-face (cddr cell))
+ (new-face (erc-track-find-face
+ (if old-face
+ (cons old-face faces)
+ faces))))
+ (setcdr cell (cons (1+ (cadr cell)) new-face)))))
+ ;; And display it
+ (erc-modified-channels-display)))
+ ;; Else if the active buffer is the current buffer, remove it
+ ;; from our list.
+ (when (or (erc-buffer-visible (current-buffer))
+ (and this-channel
+ (assq (current-buffer) erc-modified-channels-alist)
+ (member this-channel erc-track-exclude)))
+ ;; Remove it from mode-line if buffer is visible or
+ ;; channel was added to erc-track-exclude recently.
+ (erc-modified-channels-remove-buffer (current-buffer))
+ (erc-modified-channels-display)))))
+
+(defun erc-faces-in (str)
+ "Return a list of all faces used in STR."
+ (let ((i 0)
+ (m (length str))
+ (faces (erc-list (get-text-property 0 'face str))))
+ (while (and (setq i (next-single-property-change i 'face str m))
+ (not (= i m)))
+ (dolist (face (erc-list (get-text-property i 'face str)))
+ (add-to-list 'faces face)))
+ faces))
+
+(erc-assert
+ (let ((str "is bold"))
+ (put-text-property 3 (length str)
+ 'face '(bold erc-current-nick-face)
+ str)
+ (erc-faces-in str)))
+
+(defun erc-find-parsed-property ()
+ "Find the next occurrence of the `erc-parsed' text property."
+ (text-property-not-all (point-min) (point-max) 'erc-parsed nil))
+
+;;; Buffer switching
+
+(defvar erc-track-last-non-erc-buffer nil
+ "Stores the name of the last buffer you were in before activating
+`erc-track-switch-buffers'")
+
+(defun erc-track-sort-by-activest ()
+ "Sort erc-modified-channels-alist by activity.
+That means the number of unseen messages in a channel."
+ (setq erc-modified-channels-alist
+ (sort erc-modified-channels-alist
+ (lambda (a b) (> (nth 1 a) (nth 1 b))))))
+
+(defun erc-track-get-active-buffer (arg)
+ "Return the buffer name of ARG in `erc-modified-channels-alist'.
+Negative arguments index in the opposite direction. This direction is
+relative to `erc-track-switch-direction'"
+ (let ((dir erc-track-switch-direction)
+ offset)
+ (when (< arg 0)
+ (setq dir (case dir
+ (oldest 'newest)
+ (newest 'oldest)
+ (mostactive 'leastactive)
+ (leastactive 'mostactive)))
+ (setq arg (- arg)))
+ (setq offset (case dir
+ ((oldest leastactive)
+ (- (length erc-modified-channels-alist) arg))
+ (t (1- arg))))
+ ;; normalise out of range user input
+ (cond ((>= offset (length erc-modified-channels-alist))
+ (setq offset (1- (length erc-modified-channels-alist))))
+ ((< offset 0)
+ (setq offset 0)))
+ (car (nth offset erc-modified-channels-alist))))
+
+(defun erc-track-switch-buffer (arg)
+ "Switch to the next active ERC buffer, or if there are no active buffers,
+switch back to the last non-ERC buffer visited. Next is defined by
+`erc-track-switch-direction', a negative argument will reverse this."
+ (interactive "p")
+ (when erc-track-mode
+ (cond (erc-modified-channels-alist
+ ;; if we're not in erc-mode, set this buffer to return to
+ (unless (eq major-mode 'erc-mode)
+ (setq erc-track-last-non-erc-buffer (current-buffer)))
+ ;; and jump to the next active channel
+ (switch-to-buffer (erc-track-get-active-buffer arg)))
+ ;; if no active channels, switch back to what we were doing before
+ ((and erc-track-last-non-erc-buffer
+ erc-track-switch-from-erc
+ (buffer-live-p erc-track-last-non-erc-buffer))
+ (switch-to-buffer erc-track-last-non-erc-buffer)))))
+
+;; These bindings are global, because they pop us from any other
+;; buffer to an active ERC buffer!
+
+(global-set-key (kbd "C-c C-@") 'erc-track-switch-buffer)
+(global-set-key (kbd "C-c C-SPC") 'erc-track-switch-buffer)
+
+(provide 'erc-track)
+
+;;; erc-track.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 11b439f5-e5d7-4c6c-bb3f-eda98f9b0ac1
diff --git a/lisp/erc/erc-truncate.el b/lisp/erc/erc-truncate.el
new file mode 100644
index 00000000000..49cd20d759c
--- /dev/null
+++ b/lisp/erc/erc-truncate.el
@@ -0,0 +1,121 @@
+;;; erc-truncate.el --- Functions for truncating ERC buffers
+
+;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Andreas Fuchs <asf@void.at>
+;; Keywords: IRC, chat, client, Internet, logging
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This implements buffer truncation (and optional log file writing
+;; support for the Emacs IRC client. Use `erc-truncate-mode' to switch
+;; on. Use `erc-enable-logging' to enable logging of the stuff which
+;; is getting truncated.
+
+;;; Code:
+
+(require 'erc)
+
+(defgroup erc-truncate nil
+ "Truncate buffers when they reach a certain size"
+ :group 'erc)
+
+(defcustom erc-max-buffer-size 30000
+ "*Maximum size in chars of each ERC buffer.
+Used only when auto-truncation is enabled.
+\(see `erc-truncate-buffer' and `erc-insert-post-hook')."
+ :group 'erc-truncate
+ :type 'integer)
+
+;;;###autoload (autoload 'erc-truncate-mode "erc-truncate" nil t)
+(define-erc-module truncate nil
+ "Truncate a query buffer if it gets too large.
+This prevents the query buffer from getting too large, which can
+bring any grown emacs to its knees after a few days worth of
+tracking heavy-traffic channels."
+ ;;enable
+ ((add-hook 'erc-insert-post-hook 'erc-truncate-buffer))
+ ;; disable
+ ((remove-hook 'erc-insert-post-hook 'erc-truncate-buffer)))
+
+;;;###autoload
+(defun erc-truncate-buffer-to-size (size &optional buffer)
+ "Truncates the buffer to the size SIZE.
+If BUFFER is not provided, the current buffer is assumed. The deleted
+region is logged if `erc-logging-enabled' returns non-nil."
+ ;; If buffer is non-nil, but get-buffer does not return anything,
+ ;; then this is a bug. If buffer is a buffer name, get the buffer
+ ;; object. If buffer is nil, use the current buffer.
+ (if (not buffer)
+ (setq buffer (current-buffer))
+ (unless (get-buffer buffer)
+ (error "erc-truncate-buffer-to-size: %S is not a buffer" buffer)))
+ (when (> (buffer-size buffer) (+ size 512))
+ (save-excursion
+ (set-buffer buffer)
+ ;; Note that when erc-insert-post-hook runs, the buffer is
+ ;; narrowed to the new message. So do this delicate widening.
+ ;; I am not sure, I think this was not recommended behaviour in
+ ;; Emacs 20.
+ (save-restriction
+ (widen)
+ (let ((end (- erc-insert-marker size)))
+ ;; truncate at line boundaries
+ (goto-char end)
+ (beginning-of-line)
+ (setq end (point))
+ ;; try to save the current buffer using
+ ;; `erc-save-buffer-in-logs'. We use this, in case the
+ ;; user has both `erc-save-buffer-in-logs' and
+ ;; `erc-truncate-buffer' in `erc-insert-post-hook'. If
+ ;; this is the case, only the non-saved part of the current
+ ;; buffer should be saved. Rather than appending the
+ ;; deleted part of the buffer to the log file.
+ ;;
+ ;; Alternatively this could be made conditional on:
+ ;; (not (memq 'erc-save-buffer-in-logs
+ ;; erc-insert-post-hook))
+ ;; Comments?
+ (when (and (boundp 'erc-enable-logging)
+ erc-enable-logging
+ (erc-logging-enabled buffer))
+ (erc-save-buffer-in-logs))
+ ;; disable undoing for the truncating
+ (buffer-disable-undo)
+ (let ((inhibit-read-only t))
+ (delete-region (point-min) end)))
+ (buffer-enable-undo)))))
+
+;;;###autoload
+(defun erc-truncate-buffer ()
+ "Truncates the current buffer to `erc-max-buffer-size'.
+Meant to be used in hooks, like `erc-insert-post-hook'."
+ (interactive)
+ (erc-truncate-buffer-to-size erc-max-buffer-size))
+
+(provide 'erc-truncate)
+;;; erc-truncate.el ends here
+;;
+;; Local Variables:
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: 22a2ea78-871f-4870-8f1e-efe534170311
diff --git a/lisp/erc/erc-viper.el b/lisp/erc/erc-viper.el
new file mode 100644
index 00000000000..0d6ff04ff92
--- /dev/null
+++ b/lisp/erc/erc-viper.el
@@ -0,0 +1,74 @@
+;;; erc-viper.el --- Viper compatibility hacks for ERC
+
+;; Copyright (C) 2005 Free Software Foundation, Inc.
+
+;; Author: Edward O'Connor <ted@oconnor.cx>
+;; Keywords: emulation
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Viper is a VI emulation mode for Emacs. ERC and Viper don't quite get
+;; along by default; the code in this file fixes that. A simple
+;; (require 'erc-viper)
+;; in your ~/.ercrc.el should be all it takes for you to use ERC and
+;; Viper together happily.
+
+;;; Code:
+
+(require 'viper)
+
+;; We need this for `erc-mode-hook' and `erc-buffer-list'. Perhaps it
+;; would be better to use an `eval-after-load', so that there could be
+;; some autodetection / loading of this file from within erc.el?
+(require 'erc)
+
+;; Fix RET in ERC buffers, by telling Viper to pass RET through to the
+;; normal keymap.
+
+(add-to-list 'viper-major-mode-modifier-list
+ '(erc-mode insert-state viper-comint-mode-modifier-map))
+(add-to-list 'viper-major-mode-modifier-list
+ '(erc-mode vi-state viper-comint-mode-modifier-map))
+
+(viper-apply-major-mode-modifiers)
+
+;; Ensure that ERC buffers come up in insert state.
+(add-to-list 'viper-insert-state-mode-list 'erc-mode)
+
+;; Fix various local variables in Viper.
+(add-hook 'erc-mode-hook 'viper-comint-mode-hook)
+
+;; Fix ERC buffers that already exist (buffers in which `erc-mode-hook'
+;; has already been run).
+(mapc (lambda (buf)
+ (with-current-buffer buf
+ (viper-comint-mode-hook)
+ ;; If there *is* a final newline in this buffer, delete it, as
+ ;; it interferes with ERC /-commands.
+ (let ((last (1- (point-max))))
+ (when (eq (char-after last) ?\n)
+ (goto-char last)
+ (delete-char 1)))))
+ (erc-buffer-list))
+
+(provide 'erc-viper)
+
+;; arch-tag: 659fa645-e9ad-428c-ad53-8304d9f900f6
+;;; erc-viper.el ends here
diff --git a/lisp/erc/erc-xdcc.el b/lisp/erc/erc-xdcc.el
new file mode 100644
index 00000000000..7c8ee6fff62
--- /dev/null
+++ b/lisp/erc/erc-xdcc.el
@@ -0,0 +1,130 @@
+;;; erc-xdcc.el --- XDCC file-server support for ERC
+
+;; Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Mario Lang <mlang@delysid.org>
+;; Keywords: comm, processes
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; This file provides a very simple XDCC file server for the Emacs IRC Client.
+
+;;; Code:
+
+(require 'erc-dcc)
+
+(defcustom erc-xdcc-files nil
+ "*List of files to offer via XDCC.
+Your friends should issue \"/ctcp yournick XDCC list\" to see this."
+ :group 'erc-dcc
+ :type '(repeat file))
+
+(defcustom erc-xdcc-verbose-flag t
+ "*Report XDCC CTCP requests in the server buffer."
+ :group 'erc-dcc
+ :type 'boolean)
+
+(defcustom erc-xdcc-handler-alist
+ '(("help" . erc-xdcc-help)
+ ("list" . erc-xdcc-list)
+ ("send" . erc-xdcc-send))
+ "*Sub-command handler alist for XDCC CTCP queries."
+ :group 'erc-dcc
+ :type '(alist :key-type (string :tag "Sub-command") :value-type function))
+
+(defcustom erc-xdcc-help-text
+ '(("Hey " nick ", wondering how this works? Pretty easy.")
+ ("Available commands: XDCC ["
+ (mapconcat 'car erc-xdcc-handler-alist "|") "]")
+ ("Type \"/ctcp " (erc-current-nick)
+ " XDCC list\" to see the list of offered files, then type \"/ctcp "
+ (erc-current-nick) " XDCC send #\" to get a particular file number."))
+ "*Help text sent in response to XDCC help command.
+A list of messages, each consisting of strings and expressions, expressions
+being evaluated and should return stings."
+ :group 'erc-dcc
+ :type '(repeat (repeat :tag "Message" (choice string sexp))))
+
+;;;###autoload
+(defun erc-xdcc-add-file (file)
+ "Add a file to `erc-xdcc-files'."
+ (interactive "fFilename to add to XDCC: ")
+ (if (file-exists-p file)
+ (add-to-list 'erc-xdcc-files file)))
+
+(defun erc-xdcc-reply (proc nick msg)
+ (process-send-string proc
+ (format "PRIVMSG %s :%s\n" nick msg)))
+
+;; CTCP query handlers
+
+(defvar erc-ctcp-query-XDCC-hook '(erc-xdcc)
+ "Hook called whenever a CTCP XDCC message is received.")
+
+(defun erc-xdcc (proc nick login host to query)
+ "Handle incoming CTCP XDCC queries."
+ (when erc-xdcc-verbose-flag
+ (erc-display-message nil 'notice proc
+ (format "XDCC %s (%s@%s) sends %S" nick login host query)))
+ (let* ((args (cdr (delete "" (split-string query " "))))
+ (handler (cdr (assoc (downcase (car args)) erc-xdcc-handler-alist))))
+ (if (and handler (functionp handler))
+ (funcall handler proc nick login host (cdr args))
+ (erc-xdcc-reply
+ proc nick
+ (format "Unknown XDCC sub-command, try \"/ctcp %s XDCC help\""
+ (erc-current-nick))))))
+
+(defun erc-xdcc-help (proc nick login host args)
+ "Send basic help information to NICK."
+ (mapc
+ (lambda (msg)
+ (erc-xdcc-reply proc nick
+ (mapconcat (lambda (elt) (if (stringp elt) elt (eval elt))) msg "")))
+ erc-xdcc-help-text))
+
+(defun erc-xdcc-list (proc nick login host args)
+ "Show the contents of `erc-xdcc-files' via privmsg to NICK."
+ (if (null erc-xdcc-files)
+ (erc-xdcc-reply proc nick "No files offered, sorry")
+ (erc-xdcc-reply proc nick "Num Filename")
+ (erc-xdcc-reply proc nick "--- -------------")
+ (let ((n 0))
+ (dolist (file erc-xdcc-files)
+ (erc-xdcc-reply proc nick
+ (format "%02d. %s"
+ (setq n (1+ n))
+ (erc-dcc-file-to-name file)))))))
+
+(defun erc-xdcc-send (proc nick login host args)
+ "Send a file to NICK."
+ (let ((n (string-to-number (car args)))
+ (len (length erc-xdcc-files)))
+ (cond
+ ((= len 0)
+ (erc-xdcc-reply proc nick "No files offered, sorry"))
+ ((or (< n 1) (> n len))
+ (erc-xdcc-reply proc nick (format "%d out of range" n)))
+ (t (erc-dcc-send-file nick (nth (1- n) erc-xdcc-files) proc)))))
+
+(provide 'erc-xdcc)
+
+;; arch-tag: a13b62fe-2399-4562-af4e-f18a8dd4b9c8
+;;; erc-xdcc.el ends here
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
new file mode 100644
index 00000000000..9ff3ff51dc5
--- /dev/null
+++ b/lisp/erc/erc.el
@@ -0,0 +1,6144 @@
+;; erc.el --- An Emacs Internet Relay Chat client
+
+;; Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+;; 2006 Free Software Foundation, Inc.
+;; Copyright (C) 2004 Brian Palmer
+
+;; Author: Alexander L. Belikoff (alexander@belikoff.net)
+;; Contributors: Sergey Berezin (sergey.berezin@cs.cmu.edu),
+;; Mario Lang (mlang@delysid.org),
+;; Alex Schroeder (alex@gnu.org)
+;; Andreas Fuchs (afs@void.at)
+;; Gergely Nagy (algernon@midgard.debian.net)
+;; David Edmondson (dme@dme.org)
+;; Maintainer: Mario Lang (mlang@delysid.org)
+;; Keywords: IRC, chat, client, Internet
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to the
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; ERC is an IRC client for Emacs.
+
+;; For more information, see the following URLs:
+;; * http://sf.net/projects/erc/
+;; * http://www.emacswiki.org/cgi-bin/wiki.pl?EmacsIRCClient
+
+;; Jul-26-2001. erc.el is now in CVS on SourceForge. I invite everyone
+;; who wants to hack it to contact me <mlang@delysid.org> in order to
+;; get write access on the CVS.
+
+;; Installation:
+
+;; Put erc.el in your load-path, and put (require 'erc) in your .emacs.
+
+;; Configuration:
+
+;; Use M-x customize-group RET erc RET to get an overview
+;; of all the variables you can tweak.
+
+;; Usage:
+
+;; To connect to an IRC server, do
+;;
+;; M-x erc-select RET
+;;
+;; After you are connected to a server, you can use C-h m or have a look at
+;; the IRC menu.
+
+;;; History:
+;;
+
+;;; Code:
+
+(defconst erc-version-string "Version 5.1 (Emacs 22)"
+ "ERC version. This is used by function `erc-version'.")
+
+(eval-when-compile (require 'cl))
+(require 'font-lock)
+(require 'pp)
+(require 'thingatpt)
+(require 'erc-compat)
+(require 'erc-menu)
+
+(defvar erc-official-location
+ "http://erc.sf.net (comments mailto://mlang@delysid.org)"
+ "Location of the ERC client on the Internet.")
+
+(defgroup erc nil
+ "Emacs Internet Relay Chat client."
+ :link '(url-link "http://www.emacswiki.org/cgi-bin/wiki.pl?EmacsIRCClient")
+ :prefix "erc-"
+ :group 'applications)
+
+(defgroup erc-buffers nil
+ "Creating new ERC buffers"
+ :group 'erc)
+
+(defgroup erc-display nil
+ "Settings for how various things are displayed"
+ :group 'erc)
+
+(defgroup erc-mode-line-and-header nil
+ "Displaying information in the mode-line and header"
+ :group 'erc-display)
+
+(defgroup erc-ignore nil
+ "Ignoring certain messages"
+ :group 'erc)
+
+(defgroup erc-query nil
+ "Using separate buffers for private discussions"
+ :group 'erc)
+
+(defgroup erc-quit-and-part nil
+ "Quitting and parting channels"
+ :group 'erc)
+
+(defgroup erc-paranoia nil
+ "Know what is sent and received; control the display of sensitive data."
+ :group 'erc)
+
+(defgroup erc-scripts nil
+ "Running scripts at startup and with /LOAD"
+ :group 'erc)
+
+(require 'erc-backend)
+
+;; compatibility with older ERC releases
+
+(if (fboundp 'defvaralias)
+ (progn
+ (defvaralias 'erc-announced-server-name 'erc-server-announced-name)
+ (erc-make-obsolete-variable 'erc-announced-server-name
+ 'erc-server-announced-name
+ "ERC 5.1")
+ (defvaralias 'erc-process 'erc-server-process)
+ (erc-make-obsolete-variable 'erc-process 'erc-server-process "ERC 5.1")
+ (defvaralias 'erc-default-coding-system 'erc-server-coding-system)
+ (erc-make-obsolete-variable 'erc-default-coding-system
+ 'erc-server-coding-system
+ "ERC 5.1"))
+ (message (concat "ERC: The function `defvaralias' is not bound. See the "
+ "NEWS file for variable name changes since ERC 5.0.4.")))
+
+(defalias 'erc-send-command 'erc-server-send)
+(erc-make-obsolete 'erc-send-command 'erc-server-send "ERC 5.1")
+
+;; tunable connection and authentication parameters
+
+(defcustom erc-server nil
+ "IRC server to use.
+See function `erc-compute-server' for more details on connection
+parameters and authentication."
+ :group 'erc
+ :type '(choice (const nil) string))
+
+(defcustom erc-port nil
+ "IRC port to use."
+ :group 'erc
+ :type '(choice (const nil) number string))
+
+(defcustom erc-nick nil
+ "Nickname to use.
+
+Can be either a string, or a list of strings.
+In the latter case, if the first nick in the list is already in use,
+other nicks are tried in the list order.
+
+See function `erc-compute-nick' for more details on connection
+parameters and authentication."
+ :group 'erc
+ :type '(choice (const nil)
+ (string :tag "Nickname")
+ (repeat string)))
+
+(defcustom erc-nick-uniquifier "`"
+ "The character to append to the nick if it is already in use."
+ :group 'erc
+ :type 'string)
+
+(defcustom erc-manual-set-nick-on-bad-nick-p nil
+ "If the nickname you chose isn't available, ERC should not automatically
+attempt to set another nickname. You can manually set another nickname with
+the /NICK command."
+ :group 'erc
+ :type 'boolean)
+
+(defcustom erc-user-full-name nil
+ "User full name.
+
+See function `erc-compute-full-name' for more details on connection
+parameters and authentication."
+ :group 'erc
+ :type '(choice (const nil) string function)
+ :set (lambda (sym val)
+ (if (functionp val)
+ (set sym (funcall val))
+ (set sym val))))
+
+(defvar erc-password nil
+ "ERC password to use in authentication (not necessary).")
+
+(defcustom erc-user-mode nil
+ "Initial user modes to be set after a connection is established."
+ :group 'erc
+ :type '(choice (const nil) string function))
+
+
+(defcustom erc-prompt-for-password t
+ "Asks before using the default password, or whether to enter a new one."
+ :group 'erc
+ :type 'boolean)
+
+(defcustom erc-warn-about-blank-lines t
+ "Warn the user if they attempt to send a blank line."
+ :group 'erc
+ :type 'boolean)
+
+(defcustom erc-send-whitespace-lines nil
+ "If set to non-nil, send lines consisting of only whitespace."
+ :group 'erc
+ :type 'boolean)
+
+(defcustom erc-hide-prompt nil
+ "If non-nil, do not display the prompt for commands.
+
+\(A command is any input starting with a '/').
+
+See also the variables `erc-prompt' and `erc-command-indicator'."
+ :group 'erc-display
+ :type 'boolean)
+
+;; tunable GUI stuff
+
+(defcustom erc-show-my-nick t
+ "If non-nil, display one's own nickname when sending a message.
+
+If non-nil, \"<nickname>\" will be shown.
+If nil, only \"> \" will be shown."
+ :group 'erc-display
+ :type 'boolean)
+
+(define-widget 'erc-message-type 'set
+ "A set of standard IRC Message types."
+ :args '((const "JOIN")
+ (const "KICK")
+ (const "NICK")
+ (const "PART")
+ (const "QUIT")
+ (const "MODE")
+ (repeat :inline t :tag "Others" (string :tag "IRC Message Type"))))
+
+(defcustom erc-hide-list nil
+ "*List of IRC type messages to hide.
+A typical value would be '(\"JOIN\" \"PART\" \"QUIT\")."
+ :group 'erc-ignore
+ :type 'erc-message-type)
+
+(defvar erc-session-password nil
+ "The password used for the current session.")
+(make-variable-buffer-local 'erc-session-password)
+
+(defcustom erc-disconnected-hook nil
+ "Run this hook with arguments (NICK IP REASON) when disconnected.
+This happens before automatic reconnection. Note, that
+`erc-server-QUIT-functions' might not be run when we disconnect,
+simply because we do not necessarily receive the QUIT event."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-complete-functions nil
+ "These functions get called when the user hits TAB in ERC.
+Each function in turn is called until one returns non-nil to
+indicate it has handled the input."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-join-hook nil
+ "Hook run when we join a channel. Hook functions are called
+without arguments, with the current buffer set to the buffer of
+the new channel.
+
+See also `erc-server-JOIN-functions', `erc-part-hook'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-quit-hook nil
+ "Hook run when processing a quit command directed at our nick.
+
+The hook receives one argument, the current PROCESS.
+See also `erc-server-QUIT-functions' and `erc-disconnected-hook'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-part-hook nil
+ "Hook run when processing a PART message directed at our nick.
+
+The hook receives one argument, the current BUFFER.
+See also `erc-server-QUIT-functions', `erc-quit-hook' and
+`erc-disconnected-hook'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-kick-hook nil
+ "Hook run when processing a KICK message directed at our nick.
+
+The hook receives one argument, the current BUFFER.
+See also `erc-server-PART-functions' and `erc-part-hook'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-nick-changed-functions nil
+ "List of functions run when your nick was successfully changed.
+
+Each function should accept two arguments, NEW-NICK and OLD-NICK."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-connect-pre-hook '(erc-initialize-log-marker)
+ "Hook called just before `erc' calls `erc-connect'.
+Functions are run in the buffer-to-be."
+ :group 'erc-hooks
+ :type 'hook)
+
+
+(defvar erc-channel-users nil
+ "A hash table of members in the current channel, which
+associates nicknames with cons cells of the form:
+\(USER . MEMBER-DATA) where USER is a pointer to an
+erc-server-user struct, and MEMBER-DATA is a pointer to an
+erc-channel-user struct.")
+(make-variable-buffer-local 'erc-channel-users)
+
+(defvar erc-server-users nil
+ "A hash table of users on the current server, which associates
+nicknames with erc-server-user struct instances.")
+(make-variable-buffer-local 'erc-server-users)
+
+(defun erc-downcase (string)
+ "Convert STRING to IRC standard conforming downcase."
+ (let ((s (downcase string))
+ (c '((?\[ . ?\{)
+ (?\] . ?\})
+ (?\\ . ?\|)
+ (?~ . ?^))))
+ (save-match-data
+ (while (string-match "[]\\[~]" s)
+ (aset s (match-beginning 0)
+ (cdr (assq (aref s (match-beginning 0)) c)))))
+ s))
+
+(defstruct (erc-server-user (:type vector) :named)
+ ;; User data
+ nickname host login full-name info
+ ;; Buffers
+ ;;
+ ;; This is an alist of the form (BUFFER . CHANNEL-DATA), where
+ ;; CHANNEL-DATA is either nil or an erc-channel-user struct.
+ (buffers nil)
+ )
+
+(defstruct (erc-channel-user (:type vector) :named)
+ op voice
+ ;; Last message time (in the form of the return value of
+ ;; (current-time)
+ ;;
+ ;; This is useful for ordered name completion.
+ (last-message-time nil))
+
+(defsubst erc-get-channel-user (nick)
+ "Finds the (USER . CHANNEL-DATA) element corresponding to NICK
+in the current buffer's `erc-channel-users' hash table."
+ (gethash (erc-downcase nick) erc-channel-users))
+
+(defsubst erc-get-server-user (nick)
+ "Finds the USER corresponding to NICK in the current server's
+`erc-server-users' hash table."
+ (with-current-buffer (process-buffer erc-server-process)
+ (gethash (erc-downcase nick) erc-server-users)))
+
+(defsubst erc-add-server-user (nick user)
+ "This function is for internal use only.
+
+Adds USER with nickname NICK to the `erc-server-users' hash table."
+ (with-current-buffer (process-buffer erc-server-process)
+ (puthash (erc-downcase nick) user erc-server-users)))
+
+(defsubst erc-remove-server-user (nick)
+ "This function is for internal use only.
+
+Removes the user with nickname NICK from the `erc-server-users'
+hash table. This user is not removed from the
+`erc-channel-users' lists of other buffers.
+
+See also: `erc-remove-user'."
+ (with-current-buffer (process-buffer erc-server-process)
+ (remhash (erc-downcase nick) erc-server-users)))
+
+(defun erc-change-user-nickname (user new-nick)
+ "This function is for internal use only.
+
+Changes the nickname of USER to NEW-NICK in the
+`erc-server-users' hash table. The `erc-channel-users' lists of
+other buffers are also changed."
+ (let ((nick (erc-server-user-nickname user)))
+ (setf (erc-server-user-nickname user) new-nick)
+ (with-current-buffer (process-buffer erc-server-process)
+ (remhash (erc-downcase nick) erc-server-users)
+ (puthash (erc-downcase new-nick) user erc-server-users))
+ (dolist (buf (erc-server-user-buffers user))
+ (if (buffer-live-p buf)
+ (with-current-buffer buf
+ (let ((cdata (erc-get-channel-user nick)))
+ (remhash (erc-downcase nick) erc-channel-users)
+ (puthash (erc-downcase new-nick) cdata
+ erc-channel-users)))))))
+
+(defun erc-remove-channel-user (nick)
+ "This function is for internal use only.
+
+Removes the user with nickname NICK from the `erc-channel-users'
+list for this channel. If this user is not in the
+`erc-channel-users' list of any other buffers, the user is also
+removed from the server's `erc-server-users' list.
+
+See also: `erc-remove-server-user' and `erc-remove-user'."
+ (let ((channel-data (erc-get-channel-user nick)))
+ (when channel-data
+ (let ((user (car channel-data)))
+ (setf (erc-server-user-buffers user)
+ (delq (current-buffer)
+ (erc-server-user-buffers user)))
+ (remhash (erc-downcase nick) erc-channel-users)
+ (if (null (erc-server-user-buffers user))
+ (erc-remove-server-user nick))))))
+
+(defun erc-remove-user (nick)
+ "This function is for internal use only.
+
+Removes the user with nickname NICK from the `erc-server-users'
+list as well as from all `erc-channel-users' lists.
+
+See also: `erc-remove-server-user' and
+`erc-remove-channel-user'."
+ (let ((user (erc-get-server-user nick)))
+ (when user
+ (let ((buffers (erc-server-user-buffers user)))
+ (dolist (buf buffers)
+ (if (buffer-live-p buf)
+ (with-current-buffer buf
+ (remhash (erc-downcase nick) erc-channel-users)
+ (run-hooks 'erc-channel-members-changed-hook)))))
+ (erc-remove-server-user nick))))
+
+(defun erc-remove-channel-users ()
+ "This function is for internal use only.
+
+Removes all users in the current channel. This is called by
+`erc-server-PART' and `erc-server-QUIT'."
+ (when (and erc-server-connected
+ (erc-server-process-alive)
+ (hash-table-p erc-channel-users))
+ (maphash (lambda (nick cdata)
+ (erc-remove-channel-user nick))
+ erc-channel-users)
+ (clrhash erc-channel-users)))
+
+(defsubst erc-channel-user-op-p (nick)
+ "Return `t' if NICK is an operator in the current channel."
+ (and nick
+ (hash-table-p erc-channel-users)
+ (let ((cdata (erc-get-channel-user nick)))
+ (and cdata (cdr cdata)
+ (erc-channel-user-op (cdr cdata))))))
+
+(defsubst erc-channel-user-voice-p (nick)
+ "Return `t' if NICK has voice in the current channel."
+ (and nick
+ (hash-table-p erc-channel-users)
+ (let ((cdata (erc-get-channel-user nick)))
+ (and cdata (cdr cdata)
+ (erc-channel-user-voice (cdr cdata))))))
+
+(defun erc-get-channel-user-list ()
+ "Returns a list of users in the current channel. Each element
+of the list is of the form (USER . CHANNEL-DATA), where USER is
+an erc-server-user struct, and CHANNEL-DATA is either `nil' or an
+erc-channel-user struct.
+
+See also: `erc-sort-channel-users-by-activity'"
+ (let (users)
+ (if (hash-table-p erc-channel-users)
+ (maphash (lambda (nick cdata)
+ (setq users (cons cdata users)))
+ erc-channel-users))
+ users))
+
+(defun erc-get-server-nickname-list ()
+ "Returns a list of known nicknames on the current server."
+ (if (erc-server-process-alive)
+ (with-current-buffer (erc-server-buffer)
+ (let (nicks)
+ (when (hash-table-p erc-server-users)
+ (maphash (lambda (n user)
+ (setq nicks
+ (cons (erc-server-user-nickname user)
+ nicks)))
+ erc-server-users)
+ nicks)))))
+
+(defun erc-get-channel-nickname-list ()
+ "Returns a list of known nicknames on the current channel."
+ (let (nicks)
+ (when (hash-table-p erc-channel-users)
+ (maphash (lambda (n cdata)
+ (setq nicks
+ (cons (erc-server-user-nickname (car cdata))
+ nicks)))
+ erc-channel-users)
+ nicks)))
+
+(defun erc-get-server-nickname-alist ()
+ "Returns an alist of known nicknames on the current server."
+ (if (erc-server-process-alive)
+ (with-current-buffer (erc-server-buffer)
+ (let (nicks)
+ (when (hash-table-p erc-server-users)
+ (maphash (lambda (n user)
+ (setq nicks
+ (cons (cons (erc-server-user-nickname user) nil)
+ nicks)))
+ erc-server-users)
+ nicks)))))
+
+(defun erc-get-channel-nickname-alist ()
+ "Returns an alist of known nicknames on the current channel."
+ (let (nicks)
+ (when (hash-table-p erc-channel-users)
+ (maphash (lambda (n cdata)
+ (setq nicks
+ (cons (cons (erc-server-user-nickname (car cdata)) nil)
+ nicks)))
+ erc-channel-users)
+ nicks)))
+
+(defun erc-sort-channel-users-by-activity (list)
+ "Sorts LIST such that users which have spoken most recently are
+listed first. LIST must be of the form (USER . CHANNEL-DATA).
+
+See also: `erc-get-channel-user-list'."
+ (sort list
+ (lambda (x y)
+ (when (and
+ (cdr x) (cdr y))
+ (let ((tx (erc-channel-user-last-message-time (cdr x)))
+ (ty (erc-channel-user-last-message-time (cdr y))))
+ (if tx
+ (if ty
+ (time-less-p ty tx)
+ t)
+ nil))))))
+
+(defun erc-sort-channel-users-alphabetically (list)
+ "Sort LIST so that users' nicknames are in alphabetical order.
+LIST must be of the form (USER . CHANNEL-DATA).
+
+See also: `erc-get-channel-user-list'."
+ (sort list
+ (lambda (x y)
+ (when (and
+ (cdr x) (cdr y))
+ (let ((nickx (downcase (erc-server-user-nickname (car x))))
+ (nicky (downcase (erc-server-user-nickname (car y)))))
+ (if nickx
+ (if nicky
+ (string-lessp nickx nicky)
+ t)
+ nil))))))
+
+(defvar erc-channel-topic nil
+ "A topic string for the channel. Should only be used in channel-buffers.")
+(make-variable-buffer-local 'erc-channel-topic)
+
+(defvar erc-channel-modes nil
+ "List of strings representing channel modes.
+E.g. '(\"i\" \"m\" \"s\" \"b Quake!*@*\")
+\(not sure the ban list will be here, but why not)")
+(make-variable-buffer-local 'erc-channel-modes)
+
+(defvar erc-insert-marker nil
+ "The place where insertion of new text in erc buffers should happen.")
+(make-variable-buffer-local 'erc-insert-marker)
+
+(defvar erc-input-marker nil
+ "The marker where input should be inserted.")
+(make-variable-buffer-local 'erc-input-marker)
+
+(defun erc-string-no-properties (string)
+ "Return a copy of STRING will all text-properties removed."
+ (let ((newstring (copy-sequence string)))
+ (set-text-properties 0 (length newstring) nil newstring)
+ newstring))
+
+(defcustom erc-prompt "ERC>"
+ "Prompt used by ERC. Trailing whitespace is not required."
+ :group 'erc-display
+ :type '(choice string function))
+
+(defun erc-prompt ()
+ "Return the input prompt as a string.
+
+See also the variable `erc-prompt'."
+ (let ((prompt (if (functionp erc-prompt)
+ (funcall erc-prompt)
+ erc-prompt)))
+ (if (> (length prompt) 0)
+ (concat prompt " ")
+ prompt)))
+
+(defcustom erc-command-indicator nil
+ "Indicator used by ERC for showing commands.
+
+If non-nil, this will be used in the ERC buffer to indicate
+commands (i.e., input starting with a '/').
+
+If nil, the prompt will be constructed from the variable `erc-prompt'."
+ :group 'erc-display
+ :type '(choice (const nil) string function))
+
+(defun erc-command-indicator ()
+ "Return the command indicator prompt as a string.
+
+This only has any meaning if the variable `erc-command-indicator' is non-nil."
+ (and erc-command-indicator
+ (let ((prompt (if (functionp erc-command-indicator)
+ (funcall erc-command-indicator)
+ erc-command-indicator)))
+ (if (> (length prompt) 0)
+ (concat prompt " ")
+ prompt))))
+
+(defcustom erc-notice-prefix "*** "
+ "*Prefix for all notices."
+ :group 'erc-display
+ :type 'string)
+
+(defcustom erc-notice-highlight-type 'all
+ "*Determines how to highlight notices.
+See `erc-notice-prefix'.
+
+The following values are allowed:
+
+ 'prefix - highlight notice prefix only
+ 'all - highlight the entire notice
+
+Any other value disables notice's highlighting altogether."
+ :group 'erc-display
+ :type '(choice (const :tag "highlight notice prefix only" prefix)
+ (const :tag "highlight the entire notice" all)
+ (const :tag "don't highlight notices at all" nil)))
+
+(defcustom erc-echo-notice-hook nil
+ "*Specifies a list of functions to call to echo a private
+notice. Each function is called with four arguments, the string
+to display, the parsed server message, the target buffer (or
+nil), and the sender. The functions are called in order, until a
+function evaluates to non-nil. These hooks are called after
+those specified in `erc-echo-notice-always-hook'.
+
+See also: `erc-echo-notice-always-hook',
+`erc-echo-notice-in-default-buffer',
+`erc-echo-notice-in-target-buffer',
+`erc-echo-notice-in-minibuffer',
+`erc-echo-notice-in-server-buffer',
+`erc-echo-notice-in-active-non-server-buffer',
+`erc-echo-notice-in-active-buffer',
+`erc-echo-notice-in-user-buffers',
+`erc-echo-notice-in-user-and-target-buffers',
+`erc-echo-notice-in-first-user-buffer'"
+ :group 'erc-hooks
+ :type 'hook
+ :options '(erc-echo-notice-in-default-buffer
+ erc-echo-notice-in-target-buffer
+ erc-echo-notice-in-minibuffer
+ erc-echo-notice-in-server-buffer
+ erc-echo-notice-in-active-non-server-buffer
+ erc-echo-notice-in-active-buffer
+ erc-echo-notice-in-user-buffers
+ erc-echo-notice-in-user-and-target-buffers
+ erc-echo-notice-in-first-user-buffer))
+
+(defcustom erc-echo-notice-always-hook
+ '(erc-echo-notice-in-default-buffer)
+ "*Specifies a list of functions to call to echo a private
+notice. Each function is called with four arguments, the string
+to display, the parsed server message, the target buffer (or
+nil), and the sender. The functions are called in order, and all
+functions are called. These hooks are called before those
+specified in `erc-echo-notice-hook'.
+
+See also: `erc-echo-notice-hook',
+`erc-echo-notice-in-default-buffer',
+`erc-echo-notice-in-target-buffer',
+`erc-echo-notice-in-minibuffer',
+`erc-echo-notice-in-server-buffer',
+`erc-echo-notice-in-active-non-server-buffer',
+`erc-echo-notice-in-active-buffer',
+`erc-echo-notice-in-user-buffers',
+`erc-echo-notice-in-user-and-target-buffers',
+`erc-echo-notice-in-first-user-buffer'"
+ :group 'erc-hooks
+ :type 'hook
+ :options '(erc-echo-notice-in-default-buffer
+ erc-echo-notice-in-target-buffer
+ erc-echo-notice-in-minibuffer
+ erc-echo-notice-in-server-buffer
+ erc-echo-notice-in-active-non-server-buffer
+ erc-echo-notice-in-active-buffer
+ erc-echo-notice-in-user-buffers
+ erc-echo-notice-in-user-and-target-buffers
+ erc-echo-notice-in-first-user-buffer))
+
+;; other tunable parameters
+
+(defcustom erc-whowas-on-nosuchnick nil
+ "*If non-nil, do a whowas on a nick if no such nick."
+ :group 'erc
+ :type 'boolean)
+
+(defcustom erc-verbose-server-ping nil
+ "*If non-nil, show every time you get a PING or PONG from the server."
+ :group 'erc-paranoia
+ :type 'boolean)
+
+(defcustom erc-public-away-p nil
+ "*Let others know you are back when you are no longer marked away.
+This happens in this form:
+* <nick> is back (gone for <time>)
+
+Many consider it impolite to do so automatically."
+ :group 'erc
+ :type 'boolean)
+
+(defcustom erc-away-nickname nil
+ "*The nickname to take when you are marked as being away."
+ :group 'erc
+ :type '(choice (const nil)
+ string))
+
+(defcustom erc-paranoid nil
+ "If non-nil, then all incoming CTCP requests will be shown."
+ :group 'erc-paranoia
+ :type 'boolean)
+
+(defcustom erc-disable-ctcp-replies nil
+ "Disable replies to CTCP requests that require a reply.
+If non-nil, then all incoming CTCP requests that normally require
+an automatic reply (like VERSION or PING) will be ignored. Good to
+set if some hacker is trying to flood you away."
+ :group 'erc-paranoia
+ :type 'boolean)
+
+(defcustom erc-anonymous-login t
+ "Be paranoid, don't give away your machine name."
+ :group 'erc-paranoia
+ :type 'boolean)
+
+(defcustom erc-prompt-for-channel-key nil
+ "Prompt for channel key when using `erc-join-channel' interactively"
+ :group 'erc
+ :type 'boolean)
+
+(defcustom erc-email-userid "user"
+ "Use this as your email user ID."
+ :group 'erc
+ :type 'string)
+
+(defcustom erc-ignore-list nil
+ "*List of regexps matching user identifiers to ignore.
+
+A user identifier has the form \"nick!login@host\". If an
+identifier matches, the message from the person will not be
+processed."
+ :group 'erc-ignore
+ :type '(repeat regexp))
+(make-variable-buffer-local 'erc-ignore-list)
+
+(defcustom erc-ignore-reply-list nil
+ "*List of regexps matching user identifiers to ignore completely.
+
+This differs from `erc-ignore-list' in that it also ignores any
+messages directed at the user.
+
+A user identifier has the form \"nick!login@host\".
+
+If an identifier matches, or a message is addressed to a nick
+whose identifier matches, the message will not be processed.
+
+CAVEAT: ERC doesn't know about the user and host of anyone who
+was already in the channel when you joined, but never said
+anything, so it won't be able to match the user and host of those
+people. You can update the ERC internal info using /WHO *."
+ :group 'erc-ignore
+ :type '(repeat regexp))
+
+(defvar erc-flood-protect t
+ "*If non-nil, flood protection is enabled.
+Flooding is sending too much information to the server in too
+short of an interval, which may cause the server to terminate the
+connection.
+
+See `erc-server-flood-margin' for other flood-related parameters.")
+
+;; Script parameters
+
+(defcustom erc-startup-file-list
+ '("~/.ercrc.el" "~/.ercrc" ".ercrc.el" ".ercrc")
+ "List of files to try for a startup script.
+The first existent and readable one will get executed.
+
+If the filename ends with `.el' it is presumed to be an emacs-lisp
+script and it gets (load)ed. Otherwise is is treated as a bunch of
+regular IRC commands"
+ :group 'erc-scripts
+ :type '(repeat file))
+
+(defcustom erc-script-path nil
+ "List of directories to look for a script in /load command.
+The script is first searched in the current directory, then in each
+directory in the list."
+ :group 'erc-scripts
+ :type '(repeat directory))
+
+(defcustom erc-script-echo t
+ "*If not-NIL, echo the IRC script commands locally."
+ :group 'erc-scripts
+ :type 'boolean)
+
+(defvar erc-last-saved-position nil
+ "A marker containing the position the current buffer was last saved at.")
+(make-variable-buffer-local 'erc-last-saved-position)
+
+(defcustom erc-kill-buffer-on-part nil
+ "Kill the channel buffer on PART.
+This variable should probably stay nil, as ERC can reuse buffers if
+you rejoin them later."
+ :group 'erc-quit-and-part
+ :type 'boolean)
+
+(defcustom erc-kill-queries-on-quit nil
+ "Kill all query (also channel) buffers of this server on QUIT.
+See the variable `erc-kill-buffer-on-part' for details."
+ :group 'erc-quit-and-part
+ :type 'boolean)
+
+(defcustom erc-kill-server-buffer-on-quit nil
+ "Kill the server buffer of the process on QUIT."
+ :group 'erc-quit-and-part
+ :type 'boolean)
+
+(defcustom erc-quit-reason-various-alist nil
+ "Alist of possible arguments to the /quit command.
+
+Each element has the form:
+ (REGEXP RESULT)
+
+If REGEXP matches the argument to /quit, then its relevant RESULT
+will be used. RESULT may be either a string, or a function. If
+a function, it should return the quit message as a string.
+
+If no elements match, then the empty string is used.
+
+As an example:
+ (setq erc-quit-reason-various-alist
+ '((\"zippy\" erc-quit-reason-zippy)
+ (\"xmms\" dme:now-playing)
+ (\"version\" erc-quit-reason-normal)
+ (\"home\" \"Gone home !\")
+ (\"\" \"Default Reason\")))
+If the user types \"/quit zippy\", then a Zippy the Pinhead quotation
+will be used as the quit message."
+ :group 'erc-quit-and-part
+ :type '(repeat (list regexp (choice (string) (function)))))
+
+(defcustom erc-part-reason-various-alist nil
+ "Alist of possible arguments to the /part command.
+
+Each element has the form:
+ (REGEXP RESULT)
+
+If REGEXP matches the argument to /part, then its relevant RESULT
+will be used. RESULT may be either a string, or a function. If
+a function, it should return the part message as a string.
+
+If no elements match, then the empty string is used.
+
+As an example:
+ (setq erc-part-reason-various-alist
+ '((\"zippy\" erc-part-reason-zippy)
+ (\"xmms\" dme:now-playing)
+ (\"version\" erc-part-reason-normal)
+ (\"home\" \"Gone home !\")
+ (\"\" \"Default Reason\")))
+If the user types \"/part zippy\", then a Zippy the Pinhead quotation
+will be used as the part message."
+ :group 'erc-quit-and-part
+ :type '(repeat (list regexp (choice (string) (function)))))
+
+(defcustom erc-quit-reason 'erc-quit-reason-normal
+ "*A function which returns the reason for quitting.
+
+The function is passed a single argument, the string typed by the
+user after \"/quit\"."
+ :group 'erc-quit-and-part
+ :type '(choice (const erc-quit-reason-normal)
+ (const erc-quit-reason-zippy)
+ (const erc-quit-reason-various)
+ (symbol)))
+
+(defcustom erc-part-reason 'erc-part-reason-normal
+ "A function which returns the reason for parting a channel.
+
+The function is passed a single argument, the string typed by the
+user after \"/PART\"."
+ :group 'erc-quit-and-part
+ :type '(choice (const erc-part-reason-normal)
+ (const erc-part-reason-zippy)
+ (const erc-part-reason-various)
+ (symbol)))
+
+(defvar erc-grab-buffer-name "*erc-grab*"
+ "The name of the buffer created by `erc-grab-region'.")
+
+;; variables available for IRC scripts
+
+(defvar erc-user-information "ERC User"
+ "USER_INFORMATION IRC variable.")
+
+;; Hooks
+
+(defgroup erc-hooks nil
+ "Hook variables for fancy customizations of ERC."
+ :group 'erc)
+
+(defcustom erc-mode-hook nil
+ "Hook run after `erc-mode' setup is finished."
+ :group 'erc-hooks
+ :type 'hook
+ :options '(erc-add-scroll-to-bottom))
+
+(defcustom erc-timer-hook nil
+ "Put functions which should get called more or less periodically here.
+The idea is that servers always play ping pong with the client, and so there
+is no need for any idle-timer games with Emacs."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-insert-pre-hook nil
+ "Hook called first when some text is inserted through `erc-display-line'.
+It gets called with one argument, STRING.
+To be able to modify the inserted text, use `erc-insert-modify-hook' instead.
+Filtering functions can set `erc-insert-this' to nil to avoid
+display of that particular string at all."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-send-pre-hook nil
+ "Hook called first when some text is sent through `erc-send-current-line'.
+It gets called with one argument, STRING.
+
+To change the text that will be sent, set the variable STR which is
+used in `erc-send-current-line'.
+
+To change the text inserted into the buffer without changing the text
+that will be sent, use `erc-send-modify-hook' instead.
+
+Filtering functions can set `erc-send-this' to nil to avoid sending of
+that particular string at all and `erc-insert-this' to prevent
+inserting that particular string into the buffer.
+
+Note that it's useless to set `erc-send-this' to nil and
+`erc-insert-this' to t. ERC is sane enough to not insert the text
+anyway."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defvar erc-insert-this t
+ "Insert the text into the target buffer or not.
+Functions on `erc-insert-pre-hook' can set this variable to nil
+if they wish to avoid insertion of a particular string.")
+
+(defvar erc-send-this t
+ "Send the text to the target or not.
+Functions on `erc-send-pre-hook' can set this variable to nil
+if they wish to avoid sending of a particular string.")
+
+(defcustom erc-insert-modify-hook ()
+ "Insertion hook for functions that will change the text's appearance.
+This hook is called just after `erc-insert-pre-hook' when the value
+of `erc-insert-this' is t.
+While this hook is run, narrowing is in effect and `current-buffer' is
+the buffer where the text got inserted. One possible value to add here
+is `erc-fill'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-insert-post-hook nil
+ "This hook is called just after `erc-insert-modify-hook'.
+At this point, all modifications from prior hook functions are done."
+ :group 'erc-hooks
+ :type 'hook
+ :options '(erc-truncate-buffer
+ erc-make-read-only
+ erc-save-buffer-in-logs))
+
+(defcustom erc-send-modify-hook nil
+ "Sending hook for functions that will change the text's appearance.
+This hook is called just after `erc-send-pre-hook' when the values
+of `erc-send-this' and `erc-insert-this' are both t.
+While this hook is run, narrowing is in effect and `current-buffer' is
+the buffer where the text got inserted.
+
+Note that no function in this hook can change the appearance of the
+text that is sent. Only changing the sent text's appearance on the
+sending user's screen is possible. One possible value to add here
+is `erc-fill'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-send-post-hook nil
+ "This hook is called just after `erc-send-modify-hook'.
+At this point, all modifications from prior hook functions are done.
+NOTE: The functions on this hook are called _before_ sending a command
+to the server.
+
+This function is called with narrowing, ala `erc-send-modify-hook'"
+ :group 'erc-hooks
+ :type 'hook
+ :options '(erc-make-read-only))
+
+(defcustom erc-send-completed-hook
+ (when (featurep 'emacspeak)
+ (list (byte-compile
+ (lambda (str)
+ (emacspeak-auditory-icon 'select-object)))))
+ "Hook called after a message has been parsed by ERC.
+
+The single argument to the functions is the unmodified string
+which the local user typed."
+ :group 'erc-hooks
+ :type 'hook)
+;; mode-specific tables
+
+(defvar erc-mode-syntax-table
+ (let ((syntax-table (make-syntax-table)))
+ (modify-syntax-entry ?\" ". " syntax-table)
+ (modify-syntax-entry ?\\ ". " syntax-table)
+ (modify-syntax-entry ?' "w " syntax-table)
+ ;; Make dabbrev-expand useful for nick names
+ (modify-syntax-entry ?< "." syntax-table)
+ (modify-syntax-entry ?> "." syntax-table)
+ syntax-table)
+ "Syntax table used while in ERC mode.")
+
+(defvar erc-mode-abbrev-table nil
+ "Abbrev table used while in ERC mode.")
+(define-abbrev-table 'erc-mode-abbrev-table ())
+
+(defvar erc-mode-map
+ (let ((map (make-sparse-keymap)))
+ (define-key map "\C-m" 'erc-send-current-line)
+ (define-key map "\C-a" 'erc-bol)
+ (define-key map [home] 'erc-bol)
+ (define-key map "\C-c\C-a" 'erc-bol)
+ (define-key map "\C-c\C-b" 'erc-iswitchb)
+ (define-key map "\C-c\C-c" 'erc-toggle-interpret-controls)
+ (define-key map "\C-c\C-d" 'erc-input-action)
+ (define-key map "\C-c\C-e" 'erc-toggle-ctcp-autoresponse)
+ (define-key map "\C-c\C-f" 'erc-toggle-flood-control)
+ (define-key map "\C-c\C-i" 'erc-invite-only-mode)
+ (define-key map "\C-c\C-j" 'erc-join-channel)
+ (define-key map "\C-c\C-n" 'erc-channel-names)
+ (define-key map "\C-c\C-o" 'erc-get-channel-mode-from-keypress)
+ (define-key map "\C-c\C-p" 'erc-part-from-channel)
+ (define-key map "\C-c\C-q" 'erc-quit-server)
+ (define-key map "\C-c\C-r" 'erc-remove-text-properties-region)
+ (define-key map "\C-c\C-t" 'erc-set-topic)
+ (define-key map "\C-c\C-u" 'erc-kill-input)
+ (define-key map "\M-\t" 'ispell-complete-word)
+ (define-key map "\t" 'erc-complete-word)
+
+ ;; Suppress `font-lock-fontify-block' key binding since it
+ ;; destroys face properties.
+ (if (fboundp 'command-remapping)
+ (define-key map [remap font-lock-fontify-block] 'undefined)
+ (substitute-key-definition
+ 'font-lock-fontify-block 'undefined map global-map))
+
+ map)
+ "ERC keymap.")
+
+;; Faces
+
+; Honestly, I have a horrible sense of color and the "defaults" below
+; are supposed to be really bad. But colors ARE required in IRC to
+; convey different parts of conversation. If you think you know better
+; defaults - send them to me.
+
+;; Now colors are a bit nicer, at least to my eyes.
+;; You may still want to change them to better fit your background.-- S.B.
+
+(defgroup erc-faces nil
+ "Faces for ERC."
+ :group 'erc)
+
+(defface erc-default-face '((t))
+ "ERC default face."
+ :group 'erc-faces)
+
+(defface erc-direct-msg-face '((t (:foreground "IndianRed")))
+ "ERC face used for messages you receive in the main erc buffer."
+ :group 'erc-faces)
+
+(defface erc-input-face '((t (:foreground "brown")))
+ "ERC face used for your input."
+ :group 'erc-faces)
+
+(defface erc-prompt-face
+ '((t (:bold t :foreground "Black" :background"lightBlue2")))
+ "ERC face for the prompt."
+ :group 'erc-faces)
+
+(defface erc-command-indicator-face
+ '((t (:bold t)))
+ "ERC face for the command indicator.
+See the variable `erc-command-indicator'."
+ :group 'erc-faces)
+
+(defface erc-notice-face '((t (:bold t :foreground "SlateBlue")))
+ "ERC face for notices."
+ :group 'erc-faces)
+
+(defface erc-action-face '((t (:bold t)))
+ "ERC face for actions generated by /ME."
+ :group 'erc-faces)
+
+(defface erc-error-face '((t (:foreground "red")))
+ "ERC face for errors."
+ :group 'erc-faces)
+
+(defface erc-nick-default-face '((t (:bold t)))
+ "ERC nickname default face."
+ :group 'erc-faces)
+
+(defface erc-nick-msg-face '((t (:bold t :foreground "IndianRed")))
+ "ERC nickname face for private messages."
+ :group 'erc-faces)
+
+;; Debugging support
+
+(defvar erc-log-p nil
+ "When set to t, generate debug messages in a separate debug buffer.")
+
+(defvar erc-debug-log-file (expand-file-name "ERC.debug")
+ "Debug log file name.")
+
+(defvar erc-dbuf nil)
+(make-variable-buffer-local 'erc-dbuf)
+
+(defmacro define-erc-module (name alias doc enable-body disable-body
+ &optional local-p)
+ "Define a new minor mode using ERC conventions.
+Symbol NAME is the name of the module.
+Symbol ALIAS is the alias to use, or nil.
+DOC is the documentation string to use for the minor mode.
+ENABLE-BODY is a list of expressions used to enable the mode.
+DISABLE-BODY is a list of expressions used to disable the mode.
+If LOCAL-P is non-nil, the mode will be created as a buffer-local
+mode. Rather than a global one.
+
+This will define a minor mode called erc-NAME-mode, possibly
+an alias erc-ALIAS-mode, as well as the helper functions
+erc-NAME-enable, and erc-NAME-disable.
+
+Example:
+
+ ;;;###autoload (autoload 'erc-replace-mode \"erc-replace\")
+ (define-erc-module replace nil
+ \"This mode replaces incoming text according to `erc-replace-alist'.\"
+ ((add-hook 'erc-insert-modify-hook
+ 'erc-replace-insert))
+ ((remove-hook 'erc-insert-modify-hook
+ 'erc-replace-insert)))"
+ (let* ((sn (symbol-name name))
+ (mode (intern (format "erc-%s-mode" (downcase sn))))
+ (group (intern (format "erc-%s" (downcase sn))))
+ (enable (intern (format "erc-%s-enable" (downcase sn))))
+ (disable (intern (format "erc-%s-disable" (downcase sn)))))
+ `(progn
+ (erc-define-minor-mode
+ ,mode
+ ,(format "Toggle ERC %S mode.
+With arg, turn ERC %S mode on if and only if arg is positive.
+%s" name name doc)
+ nil nil nil
+ :global ,(not local-p) :group (quote ,group)
+ (if ,mode
+ (,enable)
+ (,disable)))
+ (defun ,enable ()
+ ,(format "Enable ERC %S mode."
+ name)
+ (interactive)
+ (add-to-list 'erc-modules (quote ,name))
+ (setq ,mode t)
+ ,@enable-body)
+ (defun ,disable ()
+ ,(format "Disable ERC %S mode."
+ name)
+ (interactive)
+ (setq erc-modules (delq (quote ,name) erc-modules))
+ (setq ,mode nil)
+ ,@disable-body)
+ ,(when (and alias (not (eq name alias)))
+ `(defalias
+ (quote
+ ,(intern
+ (format "erc-%s-mode"
+ (downcase (symbol-name alias)))))
+ (quote
+ ,mode))))))
+
+(put 'define-erc-module 'doc-string-elt 3)
+
+(defun erc-once-with-server-event (event &rest forms)
+ "Execute FORMS the next time EVENT occurs in the `current-buffer'.
+
+You should make sure that `current-buffer' is a server buffer.
+
+This function temporarily adds a function to EVENT's hook to
+execute FORMS. After FORMS are run, the function is removed from
+EVENT's hook. The last expression of FORMS should be either nil
+or t. nil indicates that the other functions on EVENT's hook
+should be run too, and t indicates that other functions should
+not be run.
+
+Please be sure to use this function in server-buffers. In
+channel-buffers it may not work at all, as it uses the LOCAL
+argument of `add-hook' and `remove-hook' to ensure multiserver
+capabilities."
+ (unless (erc-server-buffer-p)
+ (error
+ "You should only run `erc-once-with-server-event' in a server buffer"))
+ (let ((fun (erc-gensym))
+ (hook (erc-get-hook event)))
+ (put fun 'erc-original-buffer (current-buffer))
+ (fset fun `(lambda (proc parsed)
+ (with-current-buffer (get ',fun 'erc-original-buffer)
+ (remove-hook ',hook ',fun t))
+ (fmakunbound ',fun)
+ ,@forms))
+ (add-hook hook fun nil t)
+ fun))
+
+(defun erc-once-with-server-event-global (event &rest forms)
+ "Execute FORMS the next time EVENT occurs in any server buffer.
+
+This function temporarily prepends a function to EVENT's hook to
+execute FORMS. After FORMS are run, the function is removed from
+EVENT's hook. The last expression of FORMS should be either nil
+or t. nil indicates that the other functions on EVENT's hook
+should be run too, and t indicates that other functions should
+not be run.
+
+When FORMS execute, the current buffer is the server buffer associated with the
+connection over which the data was received that triggered EVENT."
+ (let ((fun (erc-gensym))
+ (hook (erc-get-hook event)))
+ (fset fun `(lambda (proc parsed)
+ (remove-hook ',hook ',fun)
+ (fmakunbound ',fun)
+ ,@forms))
+ (add-hook hook fun nil nil)
+ fun))
+
+(defmacro erc-log (string)
+ "Logs STRING if logging is on (see `erc-log-p')."
+ `(when erc-log-p
+ (erc-log-aux ,string)))
+
+(defun erc-server-buffer ()
+ "Return the server buffer for the current buffer's process.
+The buffer-local variable `erc-server-process' is used to find
+the process buffer."
+ (and (erc-server-buffer-live-p)
+ (process-buffer erc-server-process)))
+
+(defun erc-server-buffer-live-p ()
+ "Return t if the buffer associated with `erc-server-process'
+has not been killed."
+ (and (processp erc-server-process)
+ (buffer-live-p (process-buffer erc-server-process))))
+
+(defun erc-server-buffer-p (&optional buffer)
+ "Return non-nil if argument BUFFER is an ERC server buffer.
+
+If BUFFER is nil, the current buffer is used."
+ (with-current-buffer (or buffer (current-buffer))
+ (and (eq major-mode 'erc-mode)
+ (null (erc-default-target)))))
+
+(defun erc-query-buffer-p (&optional buffer)
+ "Return non-nil if BUFFER is an ERC query buffer.
+If BUFFER is nil, the current buffer is used."
+ (with-current-buffer (or buffer (current-buffer))
+ (let ((target (erc-default-target)))
+ (and (eq major-mode 'erc-mode)
+ target
+ (not (memq (aref target 0) '(?# ?& ?+ ?!)))))))
+
+(defun erc-ison-p (nick)
+ "Return non-nil if NICK is online."
+ (interactive "sNick: ")
+ (with-current-buffer (erc-server-buffer)
+ (let ((erc-online-p 'unknown))
+ (erc-once-with-server-event
+ 303
+ `(let ((ison (split-string (aref parsed 3))))
+ (setq erc-online-p (car (erc-member-ignore-case ,nick ison)))
+ t))
+ (erc-server-send (format "ISON %s" nick))
+ (while (eq erc-online-p 'unknown) (accept-process-output))
+ (if (interactive-p)
+ (message "%s is %sonline"
+ (or erc-online-p nick)
+ (if erc-online-p "" "not "))
+ erc-online-p))))
+
+(defun erc-log-aux (string)
+ "Do the debug logging of STRING."
+ (let ((cb (current-buffer))
+ (point 1)
+ (was-eob nil)
+ (session-buffer (erc-server-buffer)))
+ (if session-buffer
+ (progn
+ (set-buffer session-buffer)
+ (if (not (and erc-dbuf (bufferp erc-dbuf) (buffer-live-p erc-dbuf)))
+ (progn
+ (setq erc-dbuf (get-buffer-create
+ (concat "*ERC-DEBUG: "
+ erc-session-server "*")))))
+ (set-buffer erc-dbuf)
+ (setq point (point))
+ (setq was-eob (eobp))
+ (goto-char (point-max))
+ (insert (concat "** " string "\n"))
+ (if was-eob (goto-char (point-max))
+ (goto-char point))
+ (set-buffer cb))
+ (message "ERC: ** %s" string))))
+
+;; Last active buffer, to print server messages in the right place
+
+(defvar erc-active-buffer nil
+ "The current active buffer, the one where the user typed the last command.
+Defaults to the server buffer, and should only be set in the
+server buffer")
+(make-variable-buffer-local 'erc-active-buffer)
+
+(defun erc-active-buffer ()
+ "Return the value of `erc-active-buffer' for the current server.
+Defaults to the server buffer."
+ (with-current-buffer (erc-server-buffer) erc-active-buffer))
+
+(defun erc-set-active-buffer (buffer)
+ "Set the value of `erc-active-buffer' to BUFFER."
+ (cond ((erc-server-buffer)
+ (with-current-buffer (erc-server-buffer)
+ (setq erc-active-buffer buffer)))
+ (t (setq erc-active-buffer buffer))))
+
+;; Mode activation routines
+
+(defun erc-mode ()
+ "Major mode for Emacs IRC.
+Special commands:
+
+\\{erc-mode-map}
+
+Turning on `erc-mode' runs the hook `erc-mode-hook'."
+ (kill-all-local-variables)
+ (use-local-map erc-mode-map)
+ (setq mode-name "ERC"
+ major-mode 'erc-mode
+ local-abbrev-table erc-mode-abbrev-table)
+ (set-syntax-table erc-mode-syntax-table)
+ (when (boundp 'next-line-add-newlines)
+ (set (make-local-variable 'next-line-add-newlines) nil))
+ (setq line-move-ignore-invisible t)
+ (set (make-local-variable 'paragraph-separate)
+ (concat "\C-l\\|\\(^" (regexp-quote (erc-prompt)) "\\)"))
+ (set (make-local-variable 'paragraph-start)
+ (concat "\\(" (regexp-quote (erc-prompt)) "\\)"))
+ ;; Run the mode hooks
+ (run-hooks 'erc-mode-hook))
+
+;; activation
+
+(defconst erc-default-server "irc.freenode.net"
+ "IRC server to use if it cannot be detected otherwise.")
+
+(defconst erc-default-port "ircd"
+ "IRC port to use if it cannot be detected otherwise.")
+
+(defcustom erc-join-buffer 'buffer
+ "Determines how to display the newly created IRC buffer.
+'window - in another window,
+'window-noselect - in another window, but don't select that one,
+'frame - in another frame,
+'bury - bury it in a new buffer,
+any other value - in place of the current buffer"
+ :group 'erc-buffers
+ :type '(choice (const window)
+ (const window-noselect)
+ (const frame)
+ (const bury)
+ (const buffer)))
+
+(defcustom erc-frame-alist nil
+ "*Alist of frame parameters for creating erc frames.
+A value of `nil means to use `default-frame-alist'."
+ :group 'erc-buffers
+ :type '(repeat (cons :format "%v"
+ (symbol :tag "Parameter")
+ (sexp :tag "Value"))))
+
+(defcustom erc-frame-dedicated-flag nil
+ "*Non-nil means the erc frames are dedicated to that buffer.
+This only has effect when `erc-join-buffer' is set to `frame'."
+ :group 'erc-buffers
+ :type 'boolean)
+
+(defun erc-channel-p (channel)
+ "Return non-nil if CHANNEL seems to be an IRC channel name."
+ (cond ((stringp channel)
+ (memq (aref channel 0) '(?# ?& ?+ ?!)))
+ ((and (bufferp channel) (buffer-live-p channel))
+ (with-current-buffer channel
+ (erc-channel-p (erc-default-target))))
+ (t nil)))
+
+(defcustom erc-reuse-buffers t
+ "*If nil, create new buffers on joining a channel/query.
+If non-nil, a new buffer will only be created when you join
+channels with same names on different servers, or have query buffers
+open with nicks of the same name on different servers. Otherwise,
+the existing buffers will be reused."
+ :group 'erc-buffers
+ :type 'boolean)
+
+(defun erc-normalize-port (port)
+ "Normalize the port specification PORT to integer form.
+PORT may be an integer, a string or a symbol. If it is a string or a
+symbol, it may have these values:
+* irc -> 194
+* ircs -> 994
+* ircd -> 6667
+* ircd-dalnet -> 7000"
+ (cond
+ ((symbolp port)
+ (erc-normalize-port (symbol-name port)))
+ ((stringp port)
+ (let ((port-nr (string-to-number port)))
+ (cond
+ ((> port-nr 0)
+ port-nr)
+ ((string-equal port "irc")
+ 194)
+ ((string-equal port "ircs")
+ 994)
+ ((string-equal port "ircd")
+ 6667)
+ ((string-equal port "ircd-dalnet")
+ 7000)
+ (t
+ nil))))
+ ((numberp port)
+ port)
+ (t
+ nil)))
+
+(defun erc-port-equal (a b)
+ "Check whether ports A and B are equal."
+ (= (erc-normalize-port a) (erc-normalize-port b)))
+
+(defun erc-generate-new-buffer-name (server port target &optional proc)
+ "Create a new buffer name based on the arguments."
+ (when (numberp port) (setq port (number-to-string port)))
+ (let* ((buf-name (or target
+ (or (let ((name (concat server ":" port)))
+ (when (> (length name) 1)
+ name))
+ ; This fallback should in fact never happen
+ "*erc-server-buffer*"))))
+ ;; Reuse existing buffers, but not if the buffer is a connected server
+ ;; buffer and not if its associated with a different server than the
+ ;; current ERC buffer.
+ (if (and erc-reuse-buffers
+ (get-buffer buf-name)
+ (or target
+ (with-current-buffer (get-buffer buf-name)
+ (and (erc-server-buffer-p)
+ (not erc-server-connected))))
+ (with-current-buffer (get-buffer buf-name)
+ (and (string= erc-session-server server)
+ (erc-port-equal erc-session-port port))))
+ buf-name
+ (generate-new-buffer-name buf-name))))
+
+(defun erc-get-buffer-create (server port target &optional proc)
+ "Create a new buffer based on the arguments."
+ (get-buffer-create (erc-generate-new-buffer-name server port target proc)))
+
+
+(defun erc-member-ignore-case (string list)
+ "Return non-nil if STRING is a member of LIST.
+
+All strings are compared according to IRC protocol case rules, see
+`erc-downcase'."
+ (setq string (erc-downcase string))
+ (catch 'result
+ (while list
+ (if (string= string (erc-downcase (car list)))
+ (throw 'result list) (setq list (cdr list))))))
+
+(defmacro erc-with-buffer (spec &rest body)
+ "Execute BODY in the buffer associated with SPEC.
+
+SPEC should have the form
+
+ (TARGET [PROCESS])
+
+If TARGET is a buffer, use it. Otherwise, use the buffer
+matching TARGET in the process specified by PROCESS.
+
+If PROCESS is nil, use the current `erc-server-process'
+See `erc-get-buffer' for details.
+
+See also `with-current-buffer'.
+
+\(fn (TARGET [PROCESS]) BODY...)"
+ (let ((buf (erc-gensym))
+ (proc (erc-gensym))
+ (target (erc-gensym))
+ (process (erc-gensym)))
+ `(let* ((,target ,(car spec))
+ (,process ,(cadr spec))
+ (,buf (if (bufferp ,target)
+ ,target
+ (let ((,proc (or ,process
+ (and (processp erc-server-process)
+ erc-server-process))))
+ (if (and ,target ,proc)
+ (erc-get-buffer ,target ,proc))))))
+ (when ,buf
+ (with-current-buffer ,buf
+ ,@body)))))
+(put 'erc-with-buffer 'lisp-indent-function 1)
+(put 'erc-with-buffer 'edebug-form-spec '((form &optional form) body))
+
+(defun erc-get-buffer (target &optional proc)
+ "Return the buffer matching TARGET in the process PROC.
+If PROC is not supplied, all processes are searched."
+ (let ((downcased-target (erc-downcase target)))
+ (catch 'buffer
+ (erc-buffer-filter
+ (lambda ()
+ (let ((current (erc-default-target)))
+ (and (stringp current)
+ (string-equal downcased-target (erc-downcase current))
+ (throw 'buffer (current-buffer)))))
+ proc))))
+
+(defun erc-buffer-filter (predicate &optional proc)
+ "Return a list of `erc-mode' buffers matching certain criteria.
+PREDICATE is a function executed with each buffer, if it returns t, that buffer
+is considered a valid match.
+
+PROC is either an `erc-server-process', identifying a certain
+server connection, or nil which means all open connections."
+ (save-excursion
+ (delq
+ nil
+ (mapcar (lambda (buf)
+ (with-current-buffer buf
+ (and (eq major-mode 'erc-mode)
+ (or (not proc)
+ (eq proc erc-server-process))
+ (funcall predicate)
+ buf)))
+ (buffer-list)))))
+
+(defun erc-buffer-list (&optional predicate proc)
+ "Return a list of ERC buffers.
+PREDICATE is a function which executes with every buffer satisfying
+the predicate. If PREDICATE is passed as nil, return a list of all ERC
+buffers. If PROC is given, the buffers local variable `erc-server-process'
+needs to match PROC."
+ (unless predicate
+ (setq predicate (lambda () t)))
+ (erc-buffer-filter predicate proc))
+
+(defmacro erc-with-all-buffers-of-server (process pred &rest forms)
+ "Execute FORMS in all buffers which have same process as this server.
+FORMS will be evaluated in all buffers having the process PROCESS and
+where PRED matches or in all buffers of the server process if PRED is
+nil."
+ ;; Make the evaluation have the correct order
+ (let ((pre (erc-gensym))
+ (pro (erc-gensym)))
+ `(let ((,pro ,process)
+ (,pre ,pred))
+ (mapcar (lambda (buffer)
+ (with-current-buffer buffer
+ ,@forms))
+ (erc-buffer-list ,pre
+ ,pro)))))
+(put 'erc-with-all-buffers-of-server 'lisp-indent-function 1)
+(put 'erc-with-all-buffers-of-server 'edebug-form-spec '(form form body))
+
+(defun erc-iswitchb (&optional arg)
+ "Use `iswitchb-read-buffer' to prompt for a ERC buffer to switch to.
+When invoked with prefix argument, use all erc buffers. Without prefix
+ARG, allow only buffers related to same session server.
+If `erc-track-mode' is in enabled, put the last element of
+`erc-modified-channels-alist' in front of the buffer list.
+
+Due to some yet unresolved reason, global function `iswitchb-mode'
+needs to be active for this function to work."
+ (interactive "P")
+ (eval-when-compile
+ (require 'iswitchb))
+ (let ((iswitchb-make-buflist-hook
+ (lambda ()
+ (setq iswitchb-temp-buflist
+ (mapcar 'buffer-name
+ (erc-buffer-list
+ nil
+ (when (and arg (boundp 'erc-server-process))
+ erc-server-process)))))))
+ (switch-to-buffer
+ (iswitchb-read-buffer
+ "Switch-to: "
+ (if (boundp 'erc-modified-channels-alist)
+ (buffer-name (caar (last erc-modified-channels-alist)))
+ nil)
+ t))))
+
+(defun erc-channel-list (proc)
+ "Return a list of channel buffers.
+PROC is the process for the server connection. If PROC is nil, return
+all channel buffers on all servers."
+ (erc-buffer-filter
+ (lambda ()
+ (and (erc-default-target)
+ (erc-channel-p (erc-default-target))))
+ proc))
+
+(defun erc-buffer-list-with-nick (nick proc)
+ "Return buffers containing NICK in the `erc-channel-users' list."
+ (with-current-buffer (process-buffer proc)
+ (let ((user (gethash (erc-downcase nick) erc-server-users)))
+ (if user
+ (erc-server-user-buffers user)
+ nil))))
+
+;; Some local variables
+
+(defvar erc-default-recipients nil
+ "List of default recipients of the current buffer.")
+(make-variable-buffer-local 'erc-default-recipients)
+
+(defvar erc-session-user-full-name nil
+ "Full name of the user on the current server.")
+(make-variable-buffer-local 'erc-session-user-full-name)
+
+(defvar erc-channel-user-limit nil
+ "Limit of users per channel.")
+(make-variable-buffer-local 'erc-channel-user-limit)
+
+(defvar erc-channel-key nil
+ "Key needed to join channel.")
+(make-variable-buffer-local 'erc-channel-key)
+
+(defvar erc-invitation nil
+ "Last invitation channel.")
+(make-variable-buffer-local 'erc-invitation)
+
+(defvar erc-away nil
+ "Non-nil indicates that we are away.")
+(make-variable-buffer-local 'erc-away)
+
+(defvar erc-channel-list nil
+ "Server channel list.")
+(make-variable-buffer-local 'erc-channel-list)
+
+(defvar erc-bad-nick nil
+ "Non-nil indicates that we got a `nick in use' error while connecting.")
+(make-variable-buffer-local 'erc-bad-nick)
+
+(defvar erc-logged-in nil
+ "Non-nil indicates that we are logged in.")
+(make-variable-buffer-local 'erc-logged-in)
+
+(defvar erc-default-nicks nil
+ "The local copy of `erc-nick' - the list of nicks to choose from.")
+(make-variable-buffer-local 'erc-default-nicks)
+
+(defvar erc-nick-change-attempt-count 0
+ "Used to keep track of how many times an attempt at changing nick is made.")
+(make-variable-buffer-local 'erc-nick-change-attempt-count)
+
+(defcustom erc-modules '(netsplit fill button match track pcomplete readonly
+ ring autojoin noncommands irccontrols
+ stamp)
+ "A list of modules which erc should enable.
+If you set the value of this without using `customize' remember to call
+\(erc-update-modules) after you change it. When using `customize', modules
+removed from the list will be disabled."
+ :set (lambda (sym val)
+ ;; disable modules which have just been removed
+ (when (and (boundp 'erc-modules) erc-modules val)
+ (dolist (module erc-modules)
+ (unless (member module val)
+ (let ((f (intern-soft (format "erc-%s-mode" module))))
+ (when (and (fboundp f) (boundp f) (symbol-value f))
+ (message "Disabling `erc-%s'" module)
+ (funcall f 0))))))
+ (set-default sym val)
+ ;; this test is for the case where erc hasn't been loaded yet
+ (when (fboundp 'erc-update-modules)
+ (erc-update-modules)))
+ :type '(set :greedy t
+ (const :tag "Set away status automatically" autoaway)
+ (const :tag "Join channels automatically" autojoin)
+ (const :tag "Integrate with Big Brother Database" bbdb)
+ (const :tag "Buttonize URLs, nicknames, and other text" button)
+ (const :tag "Wrap long lines" fill)
+ (const :tag "Highlight or remove IRC control characters"
+ irccontrols)
+ (const :tag "Save buffers in logs" log)
+ (const :tag "Highlight pals, fools, and other keywords" match)
+ (const :tag "Detect netsplits" netsplit)
+ (const :tag "Don't display non-IRC commands after evaluation"
+ noncommands)
+ (const :tag
+ "Notify when the online status of certain users changes"
+ notify)
+ (const :tag "Complete nicknames and commands (programmable)"
+ pcomplete)
+ (const :tag "Complete nicknames and commands (old)" completion)
+ (const :tag "Make displayed lines read-only" readonly)
+ (const :tag "Replace text in messages" replace)
+ (const :tag "Enable an input history" ring)
+ (const :tag "Scroll to the bottom of the buffer" scrolltobottom)
+ (const :tag "Identify to Nickserv (IRC Services) automatically"
+ services)
+ (const :tag "Convert smileys to pretty icons" smiley)
+ (const :tag "Play sounds when you receive CTCP SOUND requests"
+ sound)
+ (const :tag "Add timestamps to messages" stamp)
+ (const :tag "Check spelling" spelling)
+ (const :tag "Track channel activity in the mode-line" track)
+ (const :tag "Truncate buffers to a certain size" truncate)
+ (const :tag "Translate morse code in messages" unmorse)
+ (repeat :tag "Others" :inline t symbol))
+ :group 'erc)
+
+(defun erc-update-modules ()
+ "Run this to enable erc-foo-mode for all modules in `erc-modules'."
+ (let (req)
+ (dolist (mod erc-modules)
+ (setq req (concat "erc-" (symbol-name mod)))
+ (cond
+ ;; yuck. perhaps we should bring the filenames into sync?
+ ((string= req "erc-completion")
+ (setq req "erc-pcomplete")
+ (setq mod 'pcomplete))
+ ((string= req "erc-services")
+ (setq req "erc-nickserv")
+ (setq mod 'services)))
+ (condition-case nil
+ (require (intern req))
+ (error nil))
+ (funcall (or (intern-soft (concat "erc-" (symbol-name mod) "-mode"))
+ (error "`%s' is not a known ERC module" mod))
+ 1))))
+
+(defun erc-setup-buffer (buffer)
+ "Consults `erc-join-buffer' to find out how to display `BUFFER'."
+ (cond ((eq erc-join-buffer 'window)
+ (if (active-minibuffer-window)
+ (display-buffer buffer)
+ (switch-to-buffer-other-window buffer)))
+ ((eq erc-join-buffer 'window-noselect)
+ (display-buffer buffer))
+ ((eq erc-join-buffer 'bury)
+ nil)
+ ((eq erc-join-buffer 'frame)
+ (funcall '(lambda (frame)
+ (raise-frame frame)
+ (select-frame frame))
+ (make-frame (or erc-frame-alist
+ default-frame-alist)))
+ (switch-to-buffer buffer)
+ (when erc-frame-dedicated-flag
+ (set-window-dedicated-p (selected-window) t)))
+ (t
+ (if (active-minibuffer-window)
+ (display-buffer buffer)
+ (switch-to-buffer buffer)))))
+
+(defun erc (&optional server port nick full-name
+ connect passwd tgt-list channel process)
+ "ERC is a powerful, modular, and extensible IRC client.
+
+Connect to SERVER on PORT as NICK with FULL-NAME.
+
+If CONNECT is non-nil, connect to the server. Otherwise assume
+already connected and just create a separate buffer for the new
+target CHANNEL.
+
+Use PASSWD as user password on the server. If TGT-LIST is
+non-nil, use it to initialise `erc-default-recipients'.
+
+Returns the buffer for the given server or channel."
+ (let ((server-announced-name (when (and (boundp 'erc-session-server)
+ (string= server erc-session-server))
+ erc-server-announced-name))
+ (connected-p (unless connect erc-server-connected))
+ (buffer (erc-get-buffer-create server port channel))
+ (old-buffer (current-buffer))
+ continued-session)
+ (erc-update-modules)
+ (set-buffer buffer)
+ (erc-mode)
+ (setq erc-server-announced-name server-announced-name)
+ (setq erc-server-connected connected-p)
+ ;; connection parameters
+ (setq erc-server-process process)
+ (setq erc-insert-marker (make-marker))
+ (setq erc-input-marker (make-marker))
+ ;; go to the end of the buffer and open a new line
+ ;; (the buffer may have existed)
+ (goto-char (point-max))
+ (forward-line 0)
+ (when (get-text-property (point) 'erc-prompt)
+ (setq continued-session t)
+ (set-marker erc-input-marker
+ (or (next-single-property-change (point) 'erc-prompt)
+ (point-max))))
+ (unless continued-session
+ (goto-char (point-max))
+ (insert "\n"))
+ (set-marker erc-insert-marker (point))
+ ;; stack of default recipients
+ (setq erc-default-recipients tgt-list)
+ (setq erc-server-current-nick nil)
+ ;; Initialize erc-server-users and erc-channel-users
+ (if connect
+ (progn ;; server buffer
+ (setq erc-server-users
+ (make-hash-table :test 'equal))
+ (setq erc-channel-users nil))
+ (progn ;; target buffer
+ (setq erc-server-users nil)
+ (setq erc-channel-users
+ (make-hash-table :test 'equal))))
+ ;; clear last incomplete line read
+ (setq erc-server-filter-data nil)
+ (setq erc-channel-topic "")
+ ;; limit on the number of users on the channel (mode +l)
+ (setq erc-channel-user-limit nil)
+ (setq erc-channel-key nil)
+ ;; last active buffer, defaults to this one
+ (erc-set-active-buffer buffer)
+ ;; last invitation channel
+ (setq erc-invitation nil)
+ ;; away flag
+ ;; Should only be used in session-buffers
+ (setq erc-away (let ((serverbuf (erc-server-buffer)))
+ (and serverbuf (with-current-buffer serverbuf erc-away))))
+ ;; Server channel list
+ (setq erc-channel-list ())
+ ;; login-time 'nick in use' error
+ (setq erc-bad-nick nil)
+ ;; whether we have logged in
+ (setq erc-logged-in nil)
+ ;; The local copy of `erc-nick' - the list of nicks to choose
+ (setq erc-default-nicks (if (consp erc-nick) erc-nick (list erc-nick)))
+ ;; password stuff
+ (setq erc-session-password passwd)
+ ;; debug output buffer
+ (setq erc-dbuf
+ (when erc-log-p
+ (get-buffer-create (concat "*ERC-DEBUG: " server "*"))))
+ (erc-determine-parameters server port nick full-name)
+
+ ;; Saving log file on exit
+ (run-hooks 'erc-connect-pre-hook)
+
+ (when connect
+ (erc-server-connect erc-session-server erc-session-port))
+ (erc-update-mode-line)
+ (set-marker erc-insert-marker (point))
+ (unless continued-session
+ (goto-char (point-max))
+ (insert "\n"))
+ (set-marker (process-mark erc-server-process) (point))
+ (unless continued-session
+ (set-marker erc-insert-marker (point))
+ (erc-display-prompt)
+ (goto-char (point-max)))
+
+ ;; Now display the buffer in a window as per user wishes.
+ (unless (eq buffer old-buffer)
+ (when erc-log-p
+ ;; we can't log to debug buffer, it may not exist yet
+ (message "erc: old buffer %s, switching to %s"
+ old-buffer buffer))
+ (erc-setup-buffer buffer))
+
+ buffer))
+
+(defun erc-initialize-log-marker ()
+ "Initialize the `erc-last-saved-position' marker to a sensible position."
+ (setq erc-last-saved-position (make-marker))
+ (move-marker erc-last-saved-position
+ (1- (marker-position erc-insert-marker))))
+
+;; interactive startup
+
+(defvar erc-server-history-list nil
+ "IRC server interactive selection history list.")
+
+(defvar erc-nick-history-list nil
+ "Nickname interactive selection history list.")
+
+(defun erc-already-logged-in (server port nick)
+ "Return the buffers corresponding to a NICK on PORT of a session SERVER.
+This is determined by looking for the appropriate buffer and checking
+whether the connection is still alive.
+If no buffer matches, return nil."
+ (erc-buffer-list
+ (lambda ()
+ (and (erc-server-process-alive)
+ (string= erc-session-server server)
+ (erc-port-equal erc-session-port port)
+ (erc-current-nick-p nick)))))
+
+(if (not (fboundp 'read-passwd))
+ (defun read-passwd (prompt)
+ "Substitute for read-passwd in early emacsen"
+ (read-from-minibuffer prompt)))
+
+(defcustom erc-before-connect nil
+ "Hook called before connecting to a server.
+This hook gets executed before `erc-select' actually invokes `erc-mode'
+with your input data. The functions in here get called with three
+parameters, SERVER, PORT and NICK."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-after-connect nil
+ "Hook called after connecting to a server.
+This hook gets executed when an end of MOTD has been received. All
+functions in here get called with the parameters SERVER and NICK."
+ :group 'erc-hooks
+ :type 'hook)
+
+;;;###autoload
+(defun erc-select-read-args ()
+ "Prompt the user for values of nick, server, port, and password."
+ (let (user-input server port nick passwd)
+ (setq user-input (read-from-minibuffer
+ "IRC server: "
+ (erc-compute-server) nil nil 'erc-server-history-list))
+
+ (if (string-match "\\(.*\\):\\(.*\\)\\'" user-input)
+ (setq port (erc-string-to-port (match-string 2 user-input))
+ user-input (match-string 1 user-input))
+ (setq port
+ (erc-string-to-port (read-from-minibuffer
+ "IRC port: " (erc-port-to-string
+ (erc-compute-port))))))
+
+ (if (string-match "\\`\\(.*\\)@\\(.*\\)" user-input)
+ (setq nick (match-string 1 user-input)
+ user-input (match-string 2 user-input))
+ (setq nick
+ (if (erc-already-logged-in server port nick)
+ (read-from-minibuffer
+ (erc-format-message 'nick-in-use ?n nick)
+ nick
+ nil nil 'erc-nick-history-list)
+ (read-from-minibuffer
+ "Nickname: " (erc-compute-nick nick)
+ nil nil 'erc-nick-history-list))))
+
+ (setq server user-input)
+
+ (setq passwd (if erc-prompt-for-password
+ (if (and erc-password
+ (y-or-n-p "Use the default password? "))
+ erc-password
+ (read-passwd "Password: "))
+ erc-password))
+ (when (and passwd (string= "" passwd))
+ (setq passwd nil))
+
+ (while (erc-already-logged-in server port nick)
+ ;; hmm, this is a problem when using multiple connections to a bnc
+ ;; with the same nick. Currently this code prevents using more than one
+ ;; bnc with the same nick. actually it would be nice to have
+ ;; bncs transparent, so that erc-compute-buffer-name displays
+ ;; the server one is connected to.
+ (setq nick (read-from-minibuffer
+ (erc-format-message 'nick-in-use ?n nick)
+ nick
+ nil nil 'erc-nick-history-list)))
+ (list :server server :port port :nick nick :password passwd)))
+
+;;;###autoload
+(defun* erc-select (&key (server (erc-compute-server))
+ (port (erc-compute-port))
+ (nick (erc-compute-nick))
+ password
+ (full-name (erc-compute-full-name)))
+ "Select connection parameters and run ERC.
+Non-interactively, it takes keyword arguments
+ (server (erc-compute-server))
+ (port (erc-compute-port))
+ (nick (erc-compute-nick))
+ password
+ (full-name (erc-compute-full-name)))
+
+That is, if called with
+ (erc-select :server \"irc.freenode.net\" :full-name \"Harry S Truman\")
+server and full-name will be set to those values, whereas
+erc-compute-port, erc-compute-nick and erc-compute-full-name will
+be invoked for those parameters' values"
+ (interactive (erc-select-read-args))
+
+ (run-hook-with-args 'erc-before-connect server port nick)
+ (erc server port nick erc-user-full-name t password))
+
+
+(defun erc-select-ssl (&rest r)
+ "Interactively select SSL connection parameters and run ERC.
+Arguments are as to erc-select."
+ (interactive (erc-select-read-args))
+ (let ((erc-server-connect-function 'erc-open-ssl-stream))
+ (apply 'erc-select r)))
+
+(defun erc-open-ssl-stream (name buffer host port)
+ "Open an SSL stream to an IRC server.
+The process will be given the name NAME, its target buffer will be
+BUFFER. HOST and PORT specify the connection target."
+ (when (require 'ssl)
+ (let ((proc (open-ssl-stream name buffer host port)))
+ ;; Ugly hack, but it works for now. Problem is it is
+ ;; very hard to detect when ssl is established, because s_client
+ ;; doesn't give any CONNECTIONESTABLISHED kind of message, and
+ ;; most IRC servers send nothing and wait for you to identify.
+ (sit-for 5)
+ proc)))
+
+;;; Debugging the protocol
+
+(defvar erc-debug-irc-protocol nil
+ "If non-nil, log all IRC protocol traffic to the buffer \"*erc-protocol*\".
+
+The buffer is created if it doesn't exist.
+
+NOTE: If this variable is non-nil, and you kill the the only
+visible \"*erc-protocol*\" buffer, it will be recreated shortly,
+but you won't see it.
+
+WARNING: Do not set this variable directly! Instead, use the
+function `erc-toggle-debug-irc-protocol' to toggle its value.")
+
+(defun erc-log-irc-protocol (string &optional outbound)
+ "Append STRING to the buffer *erc-protocol*.
+
+This only has any effect if `erc-debug-irc-protocol' is non-nil.
+
+The buffer is created if it doesn't exist.
+
+If OUTBOUND is non-nil, STRING is being sent to the IRC server
+and appears in erc-input-face in the buffer."
+ (when erc-debug-irc-protocol
+ (let ((network-name (or (ignore-errors (erc-network-name))
+ "???")))
+ (with-current-buffer (get-buffer-create "*erc-protocol*")
+ (save-excursion
+ (goto-char (point-max))
+ (let ((inhibit-read-only t))
+ (insert (if (not outbound)
+ ;; Cope with the fact that string might
+ ;; contain multiple lines of text.
+ (let ((lines (delete "" (split-string string
+ "\n\\|\r\n")))
+ (result ""))
+ (dolist (line lines)
+ (setq result (concat result network-name
+ " << " line "\n")))
+ result)
+ (erc-propertize
+ (concat network-name " >> " string
+ (if (/= ?\n
+ (aref string
+ (1- (length string))))
+ "\n"))
+ 'face 'erc-input-face)))))
+ (let ((orig-win (selected-window))
+ (debug-buffer-window (get-buffer-window (current-buffer) t)))
+ (when debug-buffer-window
+ (select-window debug-buffer-window)
+ (when (= 1 (count-lines (point) (point-max)))
+ (goto-char (point-max))
+ (recenter -1))
+ (select-window orig-win)))))))
+
+(defun erc-toggle-debug-irc-protocol (&optional arg)
+ "Toggle the value of `erc-debug-irc-protocol'.
+
+If ARG is non-nil, show the *erc-protocol* buffer."
+ (interactive "P")
+ (let* ((buf (get-buffer-create "*erc-protocol*")))
+ (with-current-buffer buf
+ (erc-view-mode-enter 1)
+ (when (null (current-local-map))
+ (let ((inhibit-read-only t))
+ (insert (erc-make-notice "This buffer displays all IRC protocol traffic exchanged with each server.\n"))
+ (insert (erc-make-notice "Kill this buffer to terminate protocol logging.\n\n")))
+ (use-local-map (make-sparse-keymap))
+ (local-set-key (kbd "RET") 'erc-toggle-debug-irc-protocol))
+ (add-hook 'kill-buffer-hook
+ #'(lambda () (setq erc-debug-irc-protocol nil))
+ nil 'local)
+ (goto-char (point-max))
+ (let ((inhibit-read-only t))
+ (insert (erc-make-notice
+ (format "IRC protocol logging %s at %s -- Press ENTER to toggle logging.\n"
+ (if erc-debug-irc-protocol "disabled" "enabled")
+ (current-time-string))))))
+ (setq erc-debug-irc-protocol (not erc-debug-irc-protocol))
+ (if (and arg
+ (not (get-buffer-window "*erc-protocol*" t)))
+ (display-buffer buf t))
+ (message "IRC protocol traffic logging %s (see buffer *erc-protocol*)."
+ (if erc-debug-irc-protocol "enabled" "disabled"))))
+
+;;; I/O interface
+
+;; send interface
+
+(defun erc-send-action (tgt str &optional force)
+ "Send CTCP ACTION information described by STR to TGT."
+ (erc-send-ctcp-message tgt (format "ACTION %s" str) force)
+ (erc-display-message
+ nil 'input (current-buffer)
+ 'ACTION ?n (erc-current-nick) ?a str ?u "" ?h ""))
+
+;; Display interface
+
+(defun erc-string-invisible-p (string)
+ "Check whether STRING is invisible or not.
+I.e. any char in it has the `invisible' property set."
+ (text-property-any 0 (length string) 'invisible t string))
+
+(defun erc-display-line-1 (string buffer)
+ "Display STRING in `erc-mode' BUFFER.
+Auxiliary function used in `erc-display-line'. The line gets filtered to
+interpret the control characters. Then, `erc-insert-pre-hook' gets called.
+If `erc-insert-this' is still t, STRING gets inserted into the buffer.
+Afterwards, `erc-insert-modify' and `erc-insert-post-hook' get called.
+If STRING is nil, the function does nothing."
+ (when string
+ (save-excursion
+ (set-buffer (or buffer (process-buffer erc-server-process)))
+ (let ((insert-position (or (marker-position erc-insert-marker)
+ (point-max))))
+ (let ((string string) ;; FIXME! Can this be removed?
+ (buffer-undo-list t)
+ (inhibit-read-only t))
+ (unless (string-match "\n$" string)
+ (setq string (concat string "\n"))
+ (when (erc-string-invisible-p string)
+ (erc-put-text-properties 0 (length string) string
+ '(invisible intangible))))
+ (erc-log (concat "erc-display-line: " string
+ (format "(%S)" string) " in buffer "
+ (format "%s" buffer)))
+ (setq erc-insert-this t)
+ (run-hook-with-args 'erc-insert-pre-hook string)
+ (if (null erc-insert-this)
+ ;; Leave erc-insert-this set to t as much as possible. Fran
+ ;; Litterio <franl> has seen erc-insert-this set to nil while
+ ;; erc-send-pre-hook is running, which should never happen. This
+ ;; may cure it.
+ (setq erc-insert-this t)
+ (save-excursion ;; to restore point in the new buffer
+ (save-restriction
+ (widen)
+ (goto-char insert-position)
+ (insert-before-markers string)
+ ;; run insertion hook, with point at restored location
+ (save-restriction
+ (narrow-to-region insert-position (point))
+ (run-hooks 'erc-insert-modify-hook)
+ (run-hooks 'erc-insert-post-hook))))))
+ (erc-update-undo-list (- (or (marker-position erc-insert-marker)
+ (point-max))
+ insert-position))))))
+
+(defun erc-update-undo-list (shift)
+ ;; Translate buffer positions in buffer-undo-list by SHIFT.
+ (unless (or (zerop shift) (atom buffer-undo-list))
+ (let ((list buffer-undo-list) elt)
+ (while list
+ (setq elt (car list))
+ (cond ((integerp elt) ; POSITION
+ (incf (car list) shift))
+ ((or (atom elt) ; nil, EXTENT
+ ;; (eq t (car elt)) ; (t HIGH . LOW)
+ (markerp (car elt))) ; (MARKER . DISTANCE)
+ nil)
+ ((integerp (car elt)) ; (BEGIN . END)
+ (incf (car elt) shift)
+ (incf (cdr elt) shift))
+ ((stringp (car elt)) ; (TEXT . POSITION)
+ (incf (cdr elt) (* (if (natnump (cdr elt)) 1 -1) shift)))
+ ((null (car elt)) ; (nil PROPERTY VALUE BEG . END)
+ (let ((cons (nthcdr 3 elt)))
+ (incf (car cons) shift)
+ (incf (cdr cons) shift)))
+ ((and (featurep 'xemacs)
+ (extentp (car elt))) ; (EXTENT START END)
+ (incf (nth 1 elt) shift)
+ (incf (nth 2 elt) shift)))
+ (setq list (cdr list))))))
+
+(defvar erc-valid-nick-regexp "[]a-zA-Z^[;\\`_{}|][]^[;\\`_{}|a-zA-Z0-9-]*"
+ "Regexp which matches all legal characters in a IRC nickname.")
+
+(defun erc-is-valid-nick-p (nick)
+ "Check if NICK is a valid IRC nickname."
+ (string-match (concat "^" erc-valid-nick-regexp "$") nick))
+
+(defun erc-display-line (string &optional buffer)
+ "Display STRING in the ERC BUFFER.
+All screen output must be done through this function. If BUFFER is nil
+or omitted, the default ERC buffer for the `erc-session-server' is used.
+The BUFFER can be an actual buffer, a list of buffers, 'all or 'active.
+If BUFFER = 'all, the string is displayed in all the ERC buffers for the
+current session. 'active means the current active buffer
+\(`erc-active-buffer'). If the buffer can't be resolved, the current
+buffer is used. `erc-display-line-1' is used to display STRING.
+
+If STRING is nil, the function does nothing."
+ (let ((inhibit-point-motion-hooks t)
+ new-bufs)
+ (dolist (buf (cond
+ ((bufferp buffer) (list buffer))
+ ((listp buffer) buffer)
+ ((processp buffer) (list (process-buffer buffer)))
+ ((eq 'all buffer)
+ (and (boundp 'erc-server-process)
+ ;; Hmm, or all of the same session server?
+ (erc-buffer-list nil erc-server-process)))
+ ((and (eq 'active buffer) (erc-active-buffer))
+ (list (erc-active-buffer)))
+ ((erc-server-buffer-live-p)
+ (list (process-buffer erc-server-process)))
+ (t (list (current-buffer)))))
+ (when (buffer-live-p buf)
+ (erc-display-line-1 string buf)
+ (add-to-list 'new-bufs buf)))
+ (when (null new-bufs)
+ (if (erc-server-buffer-live-p)
+ (erc-display-line-1 string (process-buffer erc-server-process))
+ (erc-display-line-1 string (current-buffer))))))
+
+(defun erc-display-message-highlight (type string)
+ "Highlight STRING according to TYPE, where erc-TYPE-face is an erc face.
+
+See also `erc-make-notice'"
+ (cond ((eq type 'notice)
+ (erc-make-notice string))
+ (t
+ (erc-put-text-property
+ 0 (length string)
+ 'face (or (intern-soft
+ (concat "erc-" (symbol-name type) "-face"))
+ "erc-default-face")
+ string)
+ string)))
+
+(defun erc-display-message (parsed type buffer msg &rest args)
+ "Display MSG in BUFFER.
+
+ARGS, PARSED, and TYPE are used to format MSG sensibly.
+
+See also `erc-format-message' and `erc-display-line'."
+ (let ((string (if (symbolp msg)
+ (apply 'erc-format-message msg args)
+ msg)))
+ (setq string
+ (cond
+ ((listp type)
+ (mapc (lambda (type)
+ (setq string
+ (erc-display-message-highlight type string)))
+ type)
+ string)
+ ((symbolp type)
+ (erc-display-message-highlight type string))))
+
+ (if (not (erc-response-p parsed))
+ (erc-display-line string buffer)
+ (unless (member (erc-response.command parsed) erc-hide-list)
+ (erc-put-text-property 0 (length string) 'erc-parsed parsed string)
+ (erc-put-text-property 0 (length string) 'rear-sticky t string)
+ (erc-display-line string buffer)))))
+
+(defun erc-message-type-member (position list)
+ "Return non-nil if the erc-parsed text-property at POSITION is in LIST.
+
+This function relies on the erc-parsed text-property being
+present."
+ (let ((prop-val (get-text-property position 'erc-parsed)))
+ (and prop-val (member (erc-response.command prop-val) list))))
+
+(defvar erc-send-input-line-function 'erc-send-input-line)
+(make-variable-buffer-local 'erc-send-input-line-function)
+
+(defun erc-send-input-line (target line &optional force)
+ "Send LINE to TARGET.
+
+See also `erc-server-send'."
+ (setq line (format "PRIVMSG %s :%s"
+ target
+ ;; If the line is empty, we still want to
+ ;; send it - i.e. an empty pasted line.
+ (if (string= line "\n")
+ " \n"
+ line)))
+ (erc-server-send line force target))
+
+(defun erc-get-arglist (fun)
+ "Return the argument list of a function without the parens."
+ (let ((arglist (format "%S" (erc-function-arglist fun))))
+ (if (string-match "^(\\(.*\\))$" arglist)
+ (match-string 1 arglist)
+ arglist)))
+
+(defun erc-command-name (cmd)
+ "For CMD being the function name of a ERC command, something like
+erc-cmd-FOO, this returns a string /FOO."
+ (let ((command-name (symbol-name cmd)))
+ (if (string-match "^erc-cmd-\\(.*\\)$" command-name)
+ (concat "/" (match-string 1 command-name))
+ command-name)))
+
+(defun erc-process-input-line (line &optional force no-command)
+ "Translate LINE to an RFC1459 command and send it based.
+Returns non-nil if the command is actually sent to the server, and nil
+otherwise.
+
+If the command in the LINE is not bound as a function `erc-cmd-<COMMAND>',
+it is passed to `erc-cmd-default'. If LINE is not a command (ie. doesn't
+start with /<COMMAND>) then it is sent as a message.
+
+An optional FORCE argument forces sending the line when flood
+protection is in effect. The optional NO-COMMAND argument prohibits
+this function from interpreting the line as a command."
+ (let ((command-list (erc-extract-command-from-line line)))
+ (if (and command-list
+ (not no-command))
+ (let* ((cmd (nth 0 command-list))
+ (args (nth 1 command-list)))
+ (condition-case nil
+ (if (listp args)
+ (apply cmd args)
+ (funcall cmd args))
+ (wrong-number-of-arguments
+ (erc-display-message nil 'error (current-buffer) 'incorrect-args
+ ?c (erc-command-name cmd)
+ ?u (or (erc-get-arglist cmd)
+ "")
+ ?d (format "%s\n"
+ (or (documentation cmd) "")))
+ nil)))
+ (let ((r (erc-default-target)))
+ (if r
+ (funcall erc-send-input-line-function r line force)
+ (erc-display-message nil 'error (current-buffer) 'no-target)
+ nil)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Input commands handlers
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun erc-cmd-AMSG (line)
+ "Send LINE to all channels of the current server that you are on."
+ (interactive "sSend to all channels you're on: ")
+ (setq line (erc-trim-string line))
+ (erc-with-all-buffers-of-server nil
+ (lambda ()
+ (erc-channel-p (erc-default-target)))
+ (erc-send-message line)))
+(put 'erc-cmd-AMSG 'do-not-parse-args t)
+
+(defun erc-cmd-SAY (line)
+ "Send LINE to the current query or channel as a message, not a command.
+
+Use this when you want to send a message with a leading '/'. Note
+that since multi-line messages are never a command, you don't
+need this when pasting multiple lines of text."
+ (if (string-match "^\\s-*$" line)
+ nil
+ (string-match "^ ?\\(.*\\)" line)
+ (erc-process-input-line (match-string 1 line) nil t)))
+(put 'erc-cmd-SAY 'do-not-parse-args t)
+
+(defun erc-cmd-SET (line)
+ "Set the variable named by the first word in LINE to some VALUE.
+VALUE is computed by evaluating the rest of LINE in Lisp."
+ (cond
+ ((string-match "^\\s-*\\(\\S-+\\)\\s-+\\(.*\\)$" line)
+ (let ((var (read (concat "erc-" (match-string 1 line))))
+ (val (read (match-string 2 line))))
+ (if (boundp var)
+ (progn
+ (set var (eval val))
+ (erc-display-message
+ nil nil 'active (format "Set %S to %S" var val))
+ t)
+ (setq var (read (match-string 1 line)))
+ (if (boundp var)
+ (progn
+ (set var (eval val))
+ (erc-display-message
+ nil nil 'active (format "Set %S to %S" var val))
+ t)
+ (erc-display-message nil 'error 'active 'variable-not-bound)
+ nil))))
+ ((string-match "^\\s-*$" line)
+ (erc-display-line
+ (concat "Available user variables:\n"
+ (apply
+ 'concat
+ (mapcar
+ (lambda (var)
+ (let ((val (symbol-value var)))
+ (concat (format "%S:" var)
+ (if (consp val)
+ (concat "\n" (pp-to-string val))
+ (format " %S\n" val)))))
+ (apropos-internal "^erc-" 'user-variable-p))))
+ (current-buffer)) t)
+ (t nil)))
+(defalias 'erc-cmd-VAR 'erc-cmd-SET)
+(defalias 'erc-cmd-VARIABLE 'erc-cmd-SET)
+(put 'erc-cmd-SET 'do-not-parse-args t)
+
+(defun erc-cmd-default (line)
+ "Fallback command.
+
+Commands for which no erc-cmd-xxx exists, are tunnelled through
+this function. LINE is sent to the server verbatim, and
+therefore has to contain the command itself as well."
+ (erc-log (format "cmd: DEFAULT: %s" line))
+ (erc-server-send (substring line 1))
+ t)
+
+(defun erc-cmd-IGNORE (&optional user)
+ "Ignore USER. This should be a regexp matching nick!user@host.
+If no USER argument is specified, list the contents of `erc-ignore-list'."
+ (if user
+ (progn
+ (erc-display-line
+ (erc-make-notice (format "Now ignoring %s" user))
+ 'active)
+ (with-current-buffer (erc-server-buffer)
+ (add-to-list 'erc-ignore-list user)))
+ (if (null (with-current-buffer (erc-server-buffer) erc-ignore-list))
+ (erc-display-line (erc-make-notice "Ignore list is empty") 'active)
+ (erc-display-line (erc-make-notice "Ignore list:") 'active)
+ (mapc #'(lambda (item)
+ (erc-display-line (erc-make-notice item)
+ 'active))
+ (with-current-buffer (erc-server-buffer) erc-ignore-list))))
+ t)
+
+(defun erc-cmd-UNIGNORE (user)
+ "Remove the user specified in USER from the ignore list."
+ (let ((ignored-nick (car (with-current-buffer (erc-server-buffer)
+ (erc-member-ignore-case user erc-ignore-list)))))
+ (if (null ignored-nick)
+ (erc-display-line
+ (erc-make-notice (format "%s is not currently ignored!" user))
+ 'active)
+ (erc-display-line
+ (erc-make-notice (format "No longer ignoring %s" user))
+ 'active))
+ (with-current-buffer (erc-server-buffer)
+ (setq erc-ignore-list (delete ignored-nick erc-ignore-list))))
+ t)
+
+(defun erc-cmd-CLEAR ()
+ "Clear the window content."
+ (recenter 0)
+ t)
+
+(defun erc-cmd-OPS ()
+ "Show the ops in the current channel."
+ (interactive)
+ (let ((ops nil))
+ (if erc-channel-users
+ (maphash (lambda (nick user-data)
+ (let ((cuser (cdr user-data)))
+ (if (and cuser
+ (erc-channel-user-op cuser))
+ (setq ops (cons (erc-server-user-nickname
+ (car user-data))
+ ops)))))
+ erc-channel-users))
+ (setq ops (sort ops 'string-lessp))
+ (if ops
+ (erc-display-message
+ nil 'notice (current-buffer) 'ops
+ ?i (length ops) ?s (if (> (length ops) 1) "s" "")
+ ?o (mapconcat 'identity ops " "))
+ (erc-display-message nil 'notice (current-buffer) 'ops-none)))
+ t)
+
+(defun erc-cmd-COUNTRY (tld)
+ "Display the country associated with the top level domain TLD."
+ (require 'mail-extr)
+ (let ((co (ignore-errors (what-domain tld))))
+ (if co
+ (erc-display-message
+ nil 'notice 'active 'country ?c co ?d tld)
+ (erc-display-message
+ nil 'notice 'active 'country-unknown ?d tld))
+ t))
+
+(defun erc-cmd-AWAY (line)
+ "Mark the user as being away, the reason being indicated by LINE.
+If no reason is given, unset away status."
+ (when (string-match "^\\s-*\\(.*\\)$" line)
+ (let ((reason (match-string 1 line)))
+ (erc-log (format "cmd: AWAY: %s" reason))
+ (erc-server-send
+ (if (string= reason "")
+ "AWAY"
+ (concat "AWAY :" reason))))
+ t))
+(put 'erc-cmd-AWAY 'do-not-parse-args t)
+
+(defun erc-cmd-GAWAY (line)
+ "Mark the user as being away everywhere, the reason being indicated by LINE."
+ ;; on all server buffers.
+ (erc-with-all-buffers-of-server nil
+ #'erc-server-buffer-p
+ (erc-cmd-AWAY line)))
+(put 'erc-cmd-GAWAY 'do-not-parse-args t)
+
+(defun erc-cmd-CTCP (nick cmd &rest args)
+ "Send a Client To Client Protocol message to NICK.
+
+CMD is the CTCP command, possible values being ECHO, FINGER, CLIENTINFO, TIME,
+VERSION and so on. It is called with ARGS."
+ (let ((str (concat cmd
+ (when args
+ (concat " " (mapconcat #'identity args " "))))))
+ (erc-log (format "cmd: CTCP [%s]: [%s]" nick str))
+ (erc-send-ctcp-message nick str)
+ t))
+
+(defun erc-cmd-HELP (&optional func)
+ "Popup help information.
+
+If FUNC contains a valid function or variable, help about that
+will be displayed. If FUNC is empty, display an apropos about
+erc commands. Otherwise, do apropos in the erc namespace
+\(\"erc-.*LINE\"\).
+
+Examples:
+To find out about erc and bbdb, do
+ /help bbdb.*
+
+For help about the WHOIS command, do:
+ /help whois
+
+For a list of user commands (/join /part, ...):
+ /help."
+ (if func
+ (let* ((sym (or (let ((sym (intern-soft
+ (concat "erc-cmd-" (upcase func)))))
+ (if (and sym (or (boundp sym) (fboundp sym)))
+ sym
+ nil))
+ (let ((sym (intern-soft func)))
+ (if (and sym (or (boundp sym) (fboundp sym)))
+ sym
+ nil))
+ (let ((sym (intern-soft (concat "erc-" func))))
+ (if (and sym (or (boundp sym) (fboundp sym)))
+ sym
+ nil)))))
+ (if sym
+ (cond
+ ((boundp sym) (describe-variable sym))
+ ((fboundp sym) (describe-function sym))
+ (t nil))
+ (apropos-command (concat "erc-.*" func) nil
+ (lambda (x)
+ (or (commandp x)
+ (get x 'custom-type))))
+ t))
+ (apropos "erc-cmd-")
+ (message "Type C-h m to get additional information about keybindings.")
+ t))
+
+(defalias 'erc-cmd-H 'erc-cmd-HELP)
+
+(defun erc-cmd-JOIN (channel &optional key)
+ "Join the channel given in CHANNEL, optionally with KEY.
+If CHANNEL is specified as \"-invite\", join the channel to which you
+were most recently invited. See also `invitation'."
+ (let (chnl)
+ (if (string= (upcase channel) "-INVITE")
+ (if erc-invitation
+ (setq chnl erc-invitation)
+ (erc-display-message nil 'error (current-buffer) 'no-invitation))
+ (setq chnl (erc-ensure-channel-name channel)))
+ (when chnl
+ ;; Prevent double joining of same channel on same server.
+ (let ((joined-channels
+ (mapcar #'(lambda (chanbuf)
+ (with-current-buffer chanbuf (erc-default-target)))
+ (erc-channel-list erc-server-process))))
+ (if (erc-member-ignore-case chnl joined-channels)
+ (switch-to-buffer (car (erc-member-ignore-case chnl
+ joined-channels)))
+ (erc-log (format "cmd: JOIN: %s" chnl))
+ (if (and chnl key)
+ (erc-server-send (format "JOIN %s %s" chnl key))
+ (erc-server-send (format "JOIN %s" chnl)))))))
+ t)
+
+(defalias 'erc-cmd-CHANNEL 'erc-cmd-JOIN)
+(defalias 'erc-cmd-J 'erc-cmd-JOIN)
+
+(defvar erc-channel-new-member-names nil
+ "If non-nil, a names list is currently being received.
+
+If non-nil, this variable is a hash-table that associates
+received nicks with t.")
+(make-variable-buffer-local 'erc-channel-new-member-names)
+
+(defun erc-cmd-NAMES (&optional channel)
+ "Display the users in CHANNEL.
+If CHANNEL is not specified, display the users in the current channel.
+This function clears the channel name list first, then sends the
+command."
+ (let ((tgt (or (and (erc-channel-p channel) channel)
+ (erc-default-target))))
+ (if (and tgt (erc-channel-p tgt))
+ (progn
+ (erc-log (format "cmd: DEFAULT: NAMES %s" tgt))
+ (erc-with-buffer
+ (tgt)
+ (erc-channel-begin-receiving-names))
+ (erc-server-send (concat "NAMES " tgt)))
+ (erc-display-message nil 'error (current-buffer) 'no-default-channel)))
+ t)
+(defalias 'erc-cmd-N 'erc-cmd-NAMES)
+
+(defun erc-cmd-KICK (target &optional reason-or-nick &rest reasonwords)
+ "Kick the user indicated in LINE from the current channel.
+LINE has the format: \"#CHANNEL NICK REASON\" or \"NICK REASON\"."
+ (let ((reasonstring (mapconcat 'identity reasonwords " ")))
+ (if (string= "" reasonstring)
+ (setq reasonstring (format "Kicked by %s" (erc-current-nick))))
+ (if (erc-channel-p target)
+ (let ((nick reason-or-nick))
+ (erc-log (format "cmd: KICK: %s/%s: %s" nick target reasonstring))
+ (erc-server-send (format "KICK %s %s :%s" target nick reasonstring)
+ nil target)
+ t)
+ (when target
+ (let ((ch (erc-default-target)))
+ (setq reasonstring (concat
+ (if reason-or-nick (concat reason-or-nick " "))
+ reasonstring))
+ (if ch
+ (progn
+ (erc-log
+ (format "cmd: KICK: %s/%s: %s" target ch reasonstring))
+ (erc-server-send
+ (format "KICK %s %s :%s" ch target reasonstring) nil ch))
+ (erc-display-message nil 'error (current-buffer)
+ 'no-default-channel))
+ t)))))
+
+(defvar erc-script-args nil)
+
+(defun erc-cmd-LOAD (line)
+ "Load the script provided in the LINE.
+If LINE continues beyond the file name,
+the rest of it is put in a (local) variable
+`erc-script-args', which can be used in elisp scripts.
+
+The optional FORCE argument is ignored here - you can't force loading
+a script after exceeding the flood threshold."
+ (cond
+ ((string-match "^\\s-*\\(\\S-+\\)\\(.*\\)$" line)
+ (let* ((file-to-find (match-string 1 line))
+ (erc-script-args (match-string 2 line))
+ (file (erc-find-file file-to-find erc-script-path)))
+ (erc-log (format "cmd: LOAD: %s" file-to-find))
+ (cond
+ ((not file)
+ (erc-display-message nil 'error (current-buffer)
+ 'cannot-find-file ?f file-to-find))
+ ((not (file-readable-p file))
+ (erc-display-message nil 'error (current-buffer)
+ 'cannot-read-file ?f file))
+ (t
+ (message "Loading \'%s\'..." file)
+ (erc-load-script file)
+ (message "Loading \'%s\'...done" file))))
+ t)
+ (t nil)))
+
+(defun erc-cmd-WHOIS (user &optional server)
+ "Display whois information for USER.
+
+If SERVER is non-nil, use that, rather than the current server."
+ ;; FIXME: is the above docstring correct? -- Lawrence 2004-01-08
+ (let ((send (if server
+ (format "WHOIS %s %s" user server)
+ (format "WHOIS %s" user))))
+ (erc-log (format "cmd: %s" send))
+ (erc-server-send send)
+ t))
+(defalias 'erc-cmd-WI 'erc-cmd-WHOIS)
+
+(defun erc-cmd-WHOAMI ()
+ "Display whois information about yourself."
+ (erc-cmd-WHOIS (erc-current-nick))
+ t)
+
+(defun erc-cmd-IDLE (nick)
+ "Show the length of time NICK has been idle."
+ (let ((serverbuf (erc-server-buffer))
+ (origbuf (current-buffer))
+ symlist)
+ (with-current-buffer serverbuf
+ (add-to-list 'symlist
+ (cons (erc-once-with-server-event
+ 311 `(string= ,nick
+ (second
+ (erc-response.command-args parsed))))
+ 'erc-server-311-functions))
+ (add-to-list 'symlist
+ (cons (erc-once-with-server-event
+ 312 `(string= ,nick
+ (second
+ (erc-response.command-args parsed))))
+ 'erc-server-312-functions))
+ (add-to-list 'symlist
+ (cons (erc-once-with-server-event
+ 318 `(string= ,nick
+ (second
+ (erc-response.command-args parsed))))
+ 'erc-server-318-functions))
+ (add-to-list 'symlist
+ (cons (erc-once-with-server-event
+ 319 `(string= ,nick
+ (second
+ (erc-response.command-args parsed))))
+ 'erc-server-319-functions))
+ (add-to-list 'symlist
+ (cons (erc-once-with-server-event
+ 320 `(string= ,nick
+ (second
+ (erc-response.command-args parsed))))
+ 'erc-server-320-functions))
+ (add-to-list 'symlist
+ (cons (erc-once-with-server-event
+ 330 `(string= ,nick
+ (second
+ (erc-response.command-args parsed))))
+ 'erc-server-330-functions))
+ (add-to-list 'symlist
+ (cons (erc-once-with-server-event
+ 317
+ `(let ((idleseconds
+ (string-to-number
+ (third
+ (erc-response.command-args parsed)))))
+ (erc-display-line
+ (erc-make-notice
+ (format "%s has been idle for %s."
+ (erc-string-no-properties ,nick)
+ (erc-seconds-to-string idleseconds)))
+ ,origbuf))
+ t)
+ 'erc-server-317-functions))
+
+ ;; Send the WHOIS command.
+ (erc-cmd-WHOIS nick)
+
+ ;; Remove the uninterned symbols from the server hooks that did not run.
+ (run-at-time 20 nil `(lambda ()
+ (with-current-buffer ,(current-buffer)
+ (dolist (sym ',symlist)
+ (let ((hooksym (cdr sym))
+ (funcsym (car sym)))
+ (remove-hook hooksym funcsym t))))))))
+ t)
+
+(defun erc-cmd-DESCRIBE (line)
+ "Pose some action to a certain user.
+LINE has the format \"USER ACTION\"."
+ (cond
+ ((string-match
+ "^\\s-*\\(\\S-+\\)\\s-\\(.*\\)$" line)
+ (let ((dst (match-string 1 line))
+ (s (match-string 2 line)))
+ (erc-log (format "cmd: DESCRIBE: [%s] %s" dst s))
+ (erc-send-action dst s))
+ t)
+ (t nil)))
+(put 'erc-cmd-DESCRIBE 'do-not-parse-args t)
+
+(defun erc-cmd-ME (line)
+ "Send LINE as an action."
+ (cond
+ ((string-match "^\\s-\\(.*\\)$" line)
+ (let ((s (match-string 1 line)))
+ (erc-log (format "cmd: ME: %s" s))
+ (erc-send-action (erc-default-target) s))
+ t)
+ (t nil)))
+(put 'erc-cmd-ME 'do-not-parse-args t)
+
+(defun erc-cmd-LASTLOG (line)
+ "Show all lines in the current buffer matching the regexp LINE.
+
+If a match spreads across multiple lines, all those lines are shown.
+
+The lines are shown in a buffer named `*Occur*'.
+It serves as a menu to find any of the occurrences in this buffer.
+\\[describe-mode] in that buffer will explain how.
+
+If LINE contains upper case characters (excluding those preceded by `\'),
+the matching is case-sensitive."
+ (occur line)
+ t)
+(put 'erc-cmd-LASTLOG 'do-not-parse-args t)
+
+(defun erc-send-message (line &optional force)
+ "Send LINE to the current channel or user and display it.
+
+See also `erc-message' and `erc-display-line'."
+ (erc-message "PRIVMSG" (concat (erc-default-target) " " line) force)
+ (erc-display-line
+ (concat (erc-format-my-nick) line)
+ (current-buffer))
+ ;; FIXME - treat multiline, run hooks, or remove me?
+ t)
+
+(defun erc-cmd-MODE (line)
+ "Change or display the mode value of a channel or user.
+The first word specifies the target. The rest is the mode string
+to send.
+
+If only one word is given, display the mode of that target.
+
+A list of valid mode strings for Freenode may be found at
+`http://freenode.net/using_the_network.shtml'."
+ (cond
+ ((string-match "^\\s-\\(.*\\)$" line)
+ (let ((s (match-string 1 line)))
+ (erc-log (format "cmd: MODE: %s" s))
+ (erc-server-send (concat "MODE " line)))
+ t)
+ (t nil)))
+(put 'erc-cmd-MODE 'do-not-parse-args t)
+
+(defun erc-cmd-NOTICE (channel-or-user &rest message)
+ "Send a notice to the channel or user given as the first word.
+The rest is the message to send."
+ (erc-message "NOTICE" (concat channel-or-user " "
+ (mapconcat #'identity message " "))))
+
+(defun erc-cmd-MSG (line)
+ "Send a message to the channel or user given as the first word in LINE.
+
+The rest of LINE is the message to send."
+ (erc-message "PRIVMSG" line))
+
+(defalias 'erc-cmd-M 'erc-cmd-MSG)
+(put 'erc-cmd-MSG 'do-not-parse-args t)
+
+(defun erc-cmd-SQUERY (line)
+ "Send a Service Query to the service given as the first word in LINE.
+
+The rest of LINE is the message to send."
+ (erc-message "SQUERY" line))
+
+(defun erc-cmd-NICK (nick)
+ "Change current nickname to NICK."
+ (erc-log (format "cmd: NICK: %s (erc-bad-nick: %S)" nick erc-bad-nick))
+ (let ((nicklen (cdr (assoc "NICKLEN" (with-current-buffer (erc-server-buffer)
+ erc-server-parameters)))))
+ (and nicklen (> (length nick) (string-to-number nicklen))
+ (erc-display-message
+ nil 'notice 'active 'nick-too-long
+ ?i (length nick) ?l nicklen)))
+ (erc-server-send (format "NICK %s" nick))
+ (cond (erc-bad-nick
+ (erc-set-current-nick nick)
+ (erc-update-mode-line)
+ (setq erc-bad-nick nil)))
+ t)
+
+(defun erc-cmd-PART (line)
+ "When LINE is an empty string, leave the current channel.
+Otherwise leave the channel indicated by LINE."
+ (cond
+ ((string-match "^\\s-*\\([&#+!]\\S-+\\)\\s-?\\(.*\\)$" line)
+ (let* ((ch (match-string 1 line))
+ (msg (match-string 2 line))
+ (reason (funcall erc-part-reason (if (equal msg "") nil msg))))
+ (erc-log (format "cmd: PART: %s: %s" ch reason))
+ (erc-server-send (if (string= reason "")
+ (format "PART %s" ch)
+ (format "PART %s :%s" ch reason))
+ nil ch))
+ t)
+ ((string-match "^\\s-*\\(.*\\)$" line)
+ (let* ((ch (erc-default-target))
+ (msg (match-string 1 line))
+ (reason (funcall erc-part-reason (if (equal msg "") nil msg))))
+ (if (and ch (erc-channel-p ch))
+ (progn
+ (erc-log (format "cmd: PART: %s: %s" ch reason))
+ (erc-server-send (if (string= reason "")
+ (format "PART %s" ch)
+ (format "PART %s :%s" ch reason))
+ nil ch))
+ (erc-display-message nil 'error (current-buffer) 'no-target)))
+ t)
+ (t nil)))
+(put 'erc-cmd-PART 'do-not-parse-args t)
+
+(defalias 'erc-cmd-LEAVE 'erc-cmd-PART)
+
+(defun erc-cmd-PING (recipient)
+ "Ping RECIPIENT."
+ (let ((time (format "%f" (erc-current-time))))
+ (erc-log (format "cmd: PING: %s" time))
+ (erc-cmd-CTCP recipient "PING" time)))
+
+(defun erc-cmd-QUOTE (line)
+ "Send LINE directly to the server.
+All the text given as argument is sent to the sever as unmodified,
+just as you provided it. Use this command with care!"
+ (cond
+ ((string-match "^\\s-\\(.+\\)$" line)
+ (erc-server-send (match-string 1 line)))
+ (t nil)))
+(put 'erc-cmd-QUOTE 'do-not-parse-args t)
+
+(defun erc-cmd-QUERY (&optional user)
+ "Open a query with USER.
+The type of query window/frame/etc will depend on the value of
+`erc-join-buffer'. If USER is omitted, close the current query buffer if one
+exists - except this is broken now ;-)"
+ (interactive
+ (list (read-from-minibuffer "Start a query with: " nil)))
+ (let ((session-buffer (erc-server-buffer)))
+ (if user
+ (erc-query user session-buffer)
+ ;; currently broken, evil hack to display help anyway
+ ;(erc-delete-query))))
+ (signal 'wrong-number-of-arguments ""))))
+(defalias 'erc-cmd-Q 'erc-cmd-QUERY)
+
+(defun erc-quit-reason-normal (&optional s)
+ "Normal quit message.
+
+If S is non-nil, it will be used as the quit reason."
+ (or s
+ (format "\C-bERC\C-b %s (IRC client for Emacs)"; - \C-b%s\C-b"
+ erc-version-string) ; erc-official-location)
+ ))
+
+(defun erc-quit-reason-zippy (&optional s)
+ "Zippy quit message.
+
+If S is non-nil, it will be used as the quit reason."
+ (or s
+ (erc-replace-regexp-in-string "\n" "" (yow))))
+
+(defun erc-quit-reason-various (s)
+ "Choose a quit reason based on S (a string)."
+ (when (featurep 'xemacs) (require 'poe))
+ (let ((res (car (assoc-default (or s "")
+ erc-quit-reason-various-alist 'string-match))))
+ (cond
+ ((functionp res) (funcall res))
+ ((stringp res) res)
+ ;; hopefully never reached
+ (s))))
+
+(defun erc-part-reason-normal (&optional s)
+ "Normal part message.
+
+If S is non-nil, it will be used as the quit reason."
+ (or s
+ (format "\C-bERC\C-b %s (IRC client for Emacs)"; - \C-b%s\C-b"
+ erc-version-string) ; erc-official-location)
+ ))
+
+(defun erc-part-reason-zippy (&optional s)
+ "Zippy part message.
+
+If S is non-nil, it will be used as the quit reason."
+ (or s
+ (erc-replace-regexp-in-string "\n" "" (yow))))
+
+(defun erc-part-reason-various (s)
+ "Choose a part reason based on S (a string)."
+ (when (featurep 'xemacs) (require 'poe))
+ (let ((res (car (assoc-default (or s "")
+ erc-part-reason-various-alist 'string-match))))
+ (cond
+ ((functionp res) (funcall res))
+ ((stringp res) res)
+ (s))))
+
+(defun erc-cmd-QUIT (reason)
+ "Disconnect from the current server.
+If REASON is omitted, display a default quit message, otherwise display
+the message given by REASON."
+ (unless reason
+ (setq reason ""))
+ (cond
+ ((string-match "^\\s-*\\(.*\\)$" reason)
+ (let* ((s (match-string 1 reason))
+ (buffer (erc-server-buffer))
+ (reason (funcall erc-quit-reason (if (equal s "") nil s))))
+ (with-current-buffer (if (and buffer
+ (bufferp buffer))
+ buffer
+ (current-buffer))
+ (erc-log (format "cmd: QUIT: %s" reason))
+ (setq erc-server-quitting t)
+ (erc-set-active-buffer (erc-server-buffer))
+ (erc-server-send (format "QUIT :%s" reason)))
+ (run-hook-with-args 'erc-quit-hook erc-server-process)
+ (when erc-kill-queries-on-quit
+ (erc-kill-query-buffers erc-server-process)))
+ t)
+ (t nil)))
+
+(defalias 'erc-cmd-BYE 'erc-cmd-QUIT)
+(defalias 'erc-cmd-EXIT 'erc-cmd-QUIT)
+(defalias 'erc-cmd-SIGNOFF 'erc-cmd-QUIT)
+(put 'erc-cmd-QUIT 'do-not-parse-args t)
+
+(defun erc-cmd-GQUIT (reason)
+ "Disconnect from all servers at once with the same quit REASON."
+ (erc-with-all-buffers-of-server nil #'(lambda ()
+ (and (erc-server-buffer-p)
+ (erc-server-process-alive)))
+ (erc-cmd-QUIT reason)))
+
+(defalias 'erc-cmd-GQ 'erc-cmd-GQUIT)
+(put 'erc-cmd-GQUIT 'do-not-parse-args t)
+
+(defun erc-cmd-SERVER (server)
+ "Connect to SERVER, leaving existing connection intact."
+ (erc-log (format "cmd: SERVER: %s" server))
+ (condition-case nil
+ (erc-select :server server :nick (erc-current-nick))
+ (error
+ (message "Cannot find host %s." server)
+ (beep)))
+ t)
+
+(eval-when-compile
+ (defvar motif-version-string)
+ (defvar gtk-version-string))
+
+(defun erc-cmd-SV ()
+ "Say the current ERC and Emacs version into channel."
+ (erc-send-message (format "I'm using ERC %s with %s %s (%s%s%s)!"
+ erc-version-string
+ (if (featurep 'xemacs) "XEmacs" "GNU Emacs")
+ emacs-version
+ system-configuration
+ (concat
+ (cond ((featurep 'motif)
+ (concat ", " (substring
+ motif-version-string 4)))
+ ((featurep 'gtk)
+ (concat ", GTK+ Version "
+ gtk-version-string))
+ ((featurep 'mac-carbon) ", Mac Carbon")
+ ((featurep 'x-toolkit) ", X toolkit")
+ (t ""))
+ (if (and (boundp 'x-toolkit-scroll-bars)
+ (memq x-toolkit-scroll-bars
+ '(xaw xaw3d)))
+ (format ", %s scroll bars"
+ (capitalize (symbol-name
+ x-toolkit-scroll-bars)))
+ "")
+ (if (featurep 'multi-tty) ", multi-tty" ""))
+ (concat ", built " erc-emacs-build-time)))
+ t)
+
+(defun erc-cmd-SM ()
+ "Say the current ERC modes into channel."
+ (erc-send-message (format "I'm using the following modules: %s!"
+ (erc-modes)))
+ t)
+
+(defun erc-cmd-SMV ()
+ "Say the current ERC module versions into channel."
+ (erc-send-message (format "I'm using the following module revisions: %s!"
+ (erc-version-modules)))
+ t)
+
+(defun erc-cmd-DEOP (&rest people)
+ "Remove the operator setting from user(s) given in PEOPLE."
+ (when (> (length people) 0)
+ (erc-server-send (concat "MODE " (erc-default-target)
+ " -"
+ (make-string (length people) ?o)
+ " "
+ (mapconcat 'identity people " ")))
+ t))
+
+(defun erc-cmd-OP (&rest people)
+ "Add the operator setting to users(s) given in PEOPLE."
+ (when (> (length people) 0)
+ (erc-server-send (concat "MODE " (erc-default-target)
+ " +"
+ (make-string (length people) ?o)
+ " "
+ (mapconcat 'identity people " ")))
+ t))
+
+(defun erc-cmd-TIME (&optional line)
+ "Request the current time and date from the current server."
+ (cond
+ ((and line (string-match "^\\s-*\\(.*\\)$" line))
+ (let ((args (match-string 1 line)))
+ (erc-log (format "cmd: TIME: %s" args))
+ (erc-server-send (concat "TIME " args)))
+ t)
+ (t (erc-server-send "TIME"))))
+(defalias 'erc-cmd-DATE 'erc-cmd-TIME)
+
+(defun erc-cmd-TOPIC (topic)
+ "Set or request the topic for a channel.
+LINE has the format: \"#CHANNEL TOPIC\", \"#CHANNEL\", \"TOPIC\"
+or the empty string.
+
+If no #CHANNEL is given, the default channel is used. If TOPIC is
+given, the channel topic is modified, otherwise the current topic will
+be displayed."
+ (cond
+ ;; /topic #channel TOPIC
+ ((string-match "^\\s-*\\([&#+!]\\S-+\\)\\s-\\(.*\\)$" topic)
+ (let ((ch (match-string 1 topic))
+ (topic (match-string 2 topic)))
+ (erc-log (format "cmd: TOPIC [%s]: %s" ch topic))
+ (erc-server-send (format "TOPIC %s :%s" ch topic) nil ch))
+ t)
+ ;; /topic #channel
+ ((string-match "^\\s-*\\([&#+!]\\S-+\\)" topic)
+ (let ((ch (match-string 1 topic)))
+ (erc-server-send (format "TOPIC %s" ch) nil ch)
+ t))
+ ;; /topic
+ ((string-match "^\\s-*$" topic)
+ (let ((ch (erc-default-target)))
+ (erc-server-send (format "TOPIC %s" ch) nil ch)
+ t))
+ ;; /topic TOPIC
+ ((string-match "^\\s-*\\(.*\\)$" topic)
+ (let ((ch (erc-default-target))
+ (topic (match-string 1 topic)))
+ (if (and ch (erc-channel-p ch))
+ (progn
+ (erc-log (format "cmd: TOPIC [%s]: %s" ch topic))
+ (erc-server-send (format "TOPIC %s :%s" ch topic) nil ch))
+ (erc-display-message nil 'error (current-buffer) 'no-target)))
+ t)
+ (t nil)))
+(defalias 'erc-cmd-T 'erc-cmd-TOPIC)
+(put 'erc-cmd-TOPIC 'do-not-parse-args t)
+
+(defun erc-cmd-APPENDTOPIC (topic)
+ "Append TOPIC to the current channel topic, separated by a space."
+ (let ((oldtopic erc-channel-topic))
+ ;; display help when given no arguments
+ (when (string-match "^\\s-*$" topic)
+ (signal 'wrong-number-of-arguments nil))
+ ;; strip trailing ^O
+ (when (string-match "\\(.*\\)\C-o" oldtopic)
+ (erc-cmd-TOPIC (concat (match-string 1 oldtopic) topic)))))
+(defalias 'erc-cmd-AT 'erc-cmd-APPENDTOPIC)
+(put 'erc-cmd-APPENDTOPIC 'do-not-parse-args t)
+
+(defun erc-cmd-CLEARTOPIC (&optional channel)
+ "Clear the topic for a CHANNEL.
+If CHANNEL is not specified, clear the topic for the default channel."
+ (interactive "sClear topic of channel (RET is current channel): ")
+ (let ((chnl (or (and (erc-channel-p channel) channel) (erc-default-target))))
+ (when chnl
+ (erc-server-send (format "TOPIC %s :" chnl))
+ t)))
+
+;;; Banlists
+
+(defvar erc-channel-banlist nil
+ "A list of bans seen for the current channel.
+
+Each ban is an alist of the form:
+ (WHOSET . MASK)
+
+The property `received-from-server' indicates whether
+or not the ban list has been requested from the server.")
+(make-variable-buffer-local 'erc-channel-banlist)
+(put 'erc-channel-banlist 'received-from-server nil)
+
+(defun erc-cmd-BANLIST ()
+ "Pretty-print the contents of `erc-channel-banlist'.
+
+The ban list is fetched from the server if necessary."
+ (let ((chnl (erc-default-target))
+ (chnl-name (buffer-name)))
+
+ (cond
+ ((not (erc-channel-p chnl))
+ (erc-display-line (erc-make-notice "You're not on a channel\n")
+ 'active))
+
+ ((not (get 'erc-channel-banlist 'received-from-server))
+ (let ((old-367-hook erc-server-367-functions))
+ (setq erc-server-367-functions 'erc-banlist-store
+ erc-channel-banlist nil)
+ ;; fetch the ban list then callback
+ (with-current-buffer (erc-server-buffer)
+ (erc-once-with-server-event
+ 368
+ `(with-current-buffer ,chnl-name
+ (put 'erc-channel-banlist 'received-from-server t)
+ (setq erc-server-367-functions ',old-367-hook)
+ (erc-cmd-BANLIST)
+ t))
+ (erc-server-send (format "MODE %s b" chnl)))))
+
+ ((null erc-channel-banlist)
+ (erc-display-line (erc-make-notice
+ (format "No bans for channel: %s\n" chnl))
+ 'active)
+ (put 'erc-channel-banlist 'received-from-server nil))
+
+ (t
+ (let* ((erc-fill-column (or (and (boundp 'erc-fill-column)
+ erc-fill-column)
+ (and (boundp 'fill-column)
+ fill-column)
+ (1- (window-width))))
+ (separator (make-string erc-fill-column (string-to-char "=")))
+ (fmt (concat
+ "%-" (number-to-string (/ erc-fill-column 2)) "s"
+ "%" (number-to-string (/ erc-fill-column 2)) "s")))
+
+ (erc-display-line
+ (erc-make-notice (format "Ban list for channel: %s\n"
+ (erc-default-target)))
+ 'active)
+
+ (erc-display-line separator 'active)
+ (erc-display-line (format fmt "Ban Mask" "Banned By") 'active)
+ (erc-display-line separator 'active)
+
+ (mapc
+ (lambda (x)
+ (erc-display-line
+ (format fmt
+ (truncate-string-to-width (cdr x) (/ erc-fill-column 2))
+ (if (car x)
+ (truncate-string-to-width (car x) (/ erc-fill-column 2))
+ ""))
+ 'active))
+ erc-channel-banlist)
+
+ (erc-display-line (erc-make-notice "End of Ban list")
+ 'active)
+ (put 'erc-channel-banlist 'received-from-server nil)))))
+ t)
+
+(defalias 'erc-cmd-BL 'erc-cmd-BANLIST)
+
+(defun erc-cmd-MASSUNBAN ()
+ "Mass Unban.
+
+Unban all currently banned users in the current channel."
+ (let ((chnl (erc-default-target)))
+ (cond
+
+ ((not (erc-channel-p chnl))
+ (erc-display-line
+ (erc-make-notice "You're not on a channel\n")
+ 'active))
+
+ ((not (get 'erc-channel-banlist 'received-from-server))
+ (let ((old-367-hook erc-server-367-functions))
+ (setq erc-server-367-functions 'erc-banlist-store)
+ ;; fetch the ban list then callback
+ (with-current-buffer (erc-server-buffer)
+ (erc-once-with-server-event
+ 368
+ `(with-current-buffer ,chnl
+ (put 'erc-channel-banlist 'received-from-server t)
+ (setq erc-server-367-functions ,old-367-hook)
+ (erc-cmd-MASSUNBAN)
+ t))
+ (erc-server-send (format "MODE %s b" chnl)))))
+
+ (t (let ((bans (mapcar 'cdr erc-channel-banlist)))
+ (when bans
+ ;; Glob the bans into groups of three, and carry out the unban.
+ ;; eg. /mode #foo -bbb a*!*@* b*!*@* c*!*@*
+ (mapc
+ (lambda (x)
+ (erc-server-send
+ (format "MODE %s -%s %s" (erc-default-target)
+ (make-string (length x) (string-to-char "b"))
+ (mapconcat 'identity x " "))))
+ (erc-group-list bans 3))))
+ t))))
+
+(defalias 'erc-cmd-MUB 'erc-cmd-MASSUNBAN)
+
+;;;; End of IRC commands
+
+(defun erc-ensure-channel-name (channel)
+ "Return CHANNEL if it is a valid channel name.
+Eventually add a # in front of it, if that turns it into a valid channel name."
+ (if (erc-channel-p channel)
+ channel
+ (concat "#" channel)))
+
+(defun erc-grab-region (start end)
+ "Copy the region between START and END in a recreatable format.
+
+Converts all the IRC text properties in each line of the region
+into control codes and writes them to a separate buffer. The
+resulting text may be used directly as a script to generate this
+text again."
+ (interactive "r")
+ (erc-set-active-buffer (current-buffer))
+ (save-excursion
+ (let* ((cb (current-buffer))
+ (buf (generate-new-buffer erc-grab-buffer-name))
+ (region (buffer-substring start end))
+ (lines (erc-split-multiline-safe region)))
+ (set-buffer buf)
+ (dolist (line lines)
+ (insert (concat line "\n")))
+ (set-buffer cb)
+ (switch-to-buffer-other-window buf)))
+ (message "erc-grab-region doesn't grab colors etc. anymore. If you use this, please tell the maintainers.")
+ (ding))
+
+(defun erc-display-prompt (&optional buffer pos prompt face)
+ "Display PROMPT in BUFFER at position POS.
+Display an ERC prompt in BUFFER.
+
+If PROMPT is nil, one is constructed with the function `erc-prompt'.
+If BUFFER is nil, the `current-buffer' is used.
+If POS is nil, PROMPT will be displayed at `point'.
+If FACE is non-nil, it will be used to propertize the prompt. If it is nil,
+`erc-prompt-face' will be used."
+ (let* ((prompt (or prompt (erc-prompt)))
+ (l (length prompt))
+ (ob (current-buffer)))
+ ;; We cannot use save-excursion because we move point, therefore
+ ;; we resort to the ol' ob trick to restore this.
+ (when (and buffer (bufferp buffer))
+ (set-buffer buffer))
+
+ ;; now save excursion again to store where point and mark are
+ ;; in the current buffer
+ (save-excursion
+ (setq pos (or pos (point)))
+ (goto-char pos)
+ (when (> l 0)
+ ;; Do not extend the text properties when typing at the end
+ ;; of the prompt, but stuff typed in front of the prompt
+ ;; shall remain part of the prompt.
+ (setq prompt (erc-propertize prompt
+ 'start-open t ; XEmacs
+ 'rear-nonsticky t ; Emacs
+ 'erc-prompt t
+ 'front-sticky t
+ 'read-only t))
+ (erc-put-text-property 0 (1- (length prompt))
+ 'face (or face 'erc-prompt-face)
+ prompt)
+ (insert prompt))
+ ;; Set the input marker
+ (set-marker erc-input-marker (point)))
+
+ ;; Now we are back at the old position. If the prompt was
+ ;; inserted here or before us, advance point by the length of
+ ;; the prompt.
+ (when (or (not pos) (<= (point) pos))
+ (forward-char l))
+ ;; Clear the undo buffer now, so the user can undo his stuff,
+ ;; but not the stuff we did. Sneaky!
+ (setq buffer-undo-list nil)
+ (set-buffer ob)))
+
+;; interactive operations
+
+(defun erc-input-message ()
+ "Read input from the minibuffer."
+ (interactive)
+ (let ((minibuffer-allow-text-properties t)
+ (read-map minibuffer-local-map))
+ (insert (read-from-minibuffer "Message: "
+ (string last-command-char) read-map))
+ (erc-send-current-line)))
+
+(defvar erc-action-history-list ()
+ "History list for interactive action input.")
+
+(defun erc-input-action ()
+ "Interactively input a user action and send it to IRC."
+ (interactive "")
+ (erc-set-active-buffer (current-buffer))
+ (let ((action (read-from-minibuffer
+ "Action: " nil nil nil 'erc-action-history-list)))
+ (if (not (string-match "^\\s-*$" action))
+ (erc-send-action (erc-default-target) action))))
+
+(defun erc-join-channel (channel &optional key)
+ "Join CHANNEL.
+
+If `point' is at the beginning of a channel name, use that as default."
+ (interactive
+ (list
+ (let ((chnl (if (looking-at "\\([&#+!][^ ]+\\)") (match-string 1) ""))
+ (table (when (erc-server-buffer-live-p)
+ (set-buffer (process-buffer erc-server-process))
+ erc-channel-list)))
+ (completing-read "Join channel: " table nil nil nil nil chnl))
+ (when erc-prompt-for-channel-key
+ (read-from-minibuffer "Channel key (RET for none): " nil))))
+ (erc-cmd-JOIN channel (when (>= (length key) 1) key)))
+
+(defun erc-part-from-channel (reason)
+ "Part from the current channel and prompt for a REASON."
+ (interactive
+ (list
+ (if (and (boundp 'reason) (stringp reason) (not (string= reason "")))
+ reason
+ (read-from-minibuffer (concat "Leave " (erc-default-target)
+ ", Reason? ")
+ (cons "No reason" 0)))))
+ (erc-cmd-PART (concat (erc-default-target)" " reason)))
+
+(defun erc-set-topic (topic)
+ "Prompt for a TOPIC for the current channel."
+ (interactive
+ (list
+ (read-from-minibuffer
+ (concat "Set topic of " (erc-default-target) ": ")
+ (when erc-channel-topic
+ (cons (apply 'concat (butlast (split-string erc-channel-topic "\C-o")))
+ 0)))))
+ (let ((topic-list (split-string topic "\C-o"))) ; strip off the topic setter
+ (erc-cmd-TOPIC (concat (erc-default-target) " " (car topic-list)))))
+
+(defun erc-set-channel-limit (&optional limit)
+ "Set a LIMIT for the current channel. Remove limit if nil.
+Prompt for one if called interactively."
+ (interactive (list (read-from-minibuffer
+ (format "Limit for %s (RET to remove limit): "
+ (erc-default-target)))))
+ (let ((tgt (erc-default-target)))
+ (if (and limit (>= (length limit) 1))
+ (erc-server-send (format "MODE %s +l %s" tgt limit))
+ (erc-server-send (format "MODE %s -l" tgt)))))
+
+(defun erc-set-channel-key (&optional key)
+ "Set a KEY for the current channel. Remove key if nil.
+Prompt for one if called interactively."
+ (interactive (list (read-from-minibuffer
+ (format "Key for %s (RET to remove key): "
+ (erc-default-target)))))
+ (let ((tgt (erc-default-target)))
+ (if (and key (>= (length key) 1))
+ (erc-server-send (format "MODE %s +k %s" tgt key))
+ (erc-server-send (format "MODE %s -k" tgt)))))
+
+(defun erc-quit-server (reason)
+ "Disconnect from current server after prompting for REASON.
+`erc-quit-reason' works with this just like with `erc-cmd-QUIT'."
+ (interactive (list (read-from-minibuffer
+ (format "Reason for quitting %s: "
+ (or erc-server-announced-name
+ erc-session-server)))))
+ (erc-cmd-QUIT reason))
+
+;; Movement of point
+
+(defun erc-bol ()
+ "Move `point' to the beginning of the current line.
+
+This places `point' just after the prompt, or at the beginning of the line."
+ (interactive)
+ (forward-line 0)
+ (when (get-text-property (point) 'erc-prompt)
+ (goto-char erc-input-marker))
+ (point))
+
+(defun erc-kill-input ()
+ "Kill current input line using `erc-bol' followed by `kill-line'."
+ (interactive)
+ (when (and (erc-bol)
+ (/= (point) (point-max))) ;; Prevent a (ding) and an error when
+ ;; there's nothing to kill
+ (if (boundp 'erc-input-ring-index)
+ (setq erc-input-ring-index nil))
+ (kill-line)))
+
+(defun erc-complete-word ()
+ "Complete the word before point.
+
+This function uses `erc-complete-functions'."
+ (interactive)
+ (unless (run-hook-with-args-until-success 'erc-complete-functions)
+ (beep)))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; IRC SERVER INPUT HANDLING
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;;;; New Input parsing
+
+; Stolen from ZenIRC. I just wanna test this code, so here is
+; experiment area.
+
+(defcustom erc-default-server-hook '(erc-debug-missing-hooks
+ erc-default-server-handler)
+ "*Default for server messages which aren't covered by `erc-server-hooks'."
+ :group 'erc-server-hooks
+ :type 'hook)
+
+(defun erc-default-server-handler (proc parsed)
+ "Default server handler.
+
+Displays PROC and PARSED appropriately using `erc-display-message'."
+ (erc-display-message
+ parsed 'notice proc
+ (mapconcat
+ 'identity
+ (let (res)
+ (mapc #'(lambda (x)
+ (if (stringp x)
+ (setq res (append res (list x)))))
+ parsed)
+ res)
+ " ")))
+
+(defvar erc-server-vectors
+ '(["msgtype" "sender" "to" "arg1" "arg2" "arg3" "..."])
+ "List of received server messages which ERC does not specifically handle.
+See `erc-debug-missing-hooks'.")
+;(make-variable-buffer-local 'erc-server-vectors)
+
+(defun erc-debug-missing-hooks (proc parsed)
+ "Add PARSED server message ERC does not yet handle to `erc-server-vectors'.
+These vectors can be helpful when adding new server message handlers to ERC.
+See `erc-default-server-hook'."
+ (nconc erc-server-vectors (list parsed))
+ nil)
+
+(defun erc-query (target server)
+ "Open a query buffer on TARGET, using SERVER.
+To change how this query window is displayed, use `let' to bind
+`erc-join-buffer' before calling this."
+ (unless (and server
+ (buffer-live-p server)
+ (set-buffer server))
+ (error "Couldn't switch to server buffer"))
+ (let ((buf (erc erc-session-server
+ erc-session-port
+ (erc-current-nick)
+ erc-session-user-full-name
+ nil
+ nil
+ (list target)
+ target
+ erc-server-process)))
+ (unless buf
+ (error "Couldn't open query window"))
+ (erc-update-mode-line)
+ buf))
+
+(defcustom erc-auto-query nil
+ "If non-nil, create a query buffer each time you receive a private message.
+
+If the buffer doesn't already exist it is created. This can be
+set to a symbol, to control how the new query window should
+appear. See the documentation for `erc-join-buffer' for
+available choices."
+ :group 'erc-query
+ :type '(choice (const nil)
+ (const buffer)
+ (const window)
+ (const window-noselect)
+ (const bury)
+ (const frame)))
+
+(defcustom erc-query-on-unjoined-chan-privmsg t
+ "If non-nil create query buffer on receiving any PRIVMSG at all.
+This includes PRIVMSGs directed to channels. If you are using an IRC
+bouncer, such as dircproxy, to keep a log of channels when you are
+disconnected, you should set this option to t."
+ :group 'erc-query
+ :type 'boolean)
+
+(defcustom erc-format-query-as-channel-p t
+ "If non-nil, format text from others in a query buffer like in a channel,
+otherwise format like a private message."
+ :group 'erc-query
+ :type 'boolean)
+
+(defcustom erc-minibuffer-notice nil
+ "If non-nil, print ERC notices for the user in the minibuffer.
+Only happens when the session buffer isn't visible."
+ :group 'erc-display
+ :type 'boolean)
+
+(defcustom erc-minibuffer-ignored nil
+ "If non-nil, print a message in the minibuffer if we ignored something."
+ :group 'erc-ignore
+ :type 'boolean)
+
+(defun erc-wash-quit-reason (reason nick login host)
+ "Remove duplicate text from quit REASON.
+Specifically in relation to NICK (user@host) information. Returns REASON
+unmodified if nothing can be removed.
+E.g. \"Read error to Nick [user@some.host]: 110\" would be shortened to
+\"Read error: 110\". The same applies for \"Ping Timeout\"."
+ (setq nick (regexp-quote nick)
+ login (regexp-quote login)
+ host (regexp-quote host))
+ (or (when (string-match (concat "^\\(Read error\\) to "
+ nick "\\[" host "\\]: "
+ "\\(.+\\)$") reason)
+ (concat (match-string 1 reason) ": " (match-string 2 reason)))
+ (when (string-match (concat "^\\(Ping timeout\\) for "
+ nick "\\[" host "\\]$") reason)
+ (match-string 1 reason))
+ reason))
+
+(defun erc-nickname-in-use (nick reason)
+ "If NICK is unavailable, tell the user the REASON.
+
+See also `erc-display-error-notice'."
+ (if (or erc-manual-set-nick-on-bad-nick-p
+ ;; how many default-nicks are left + one more try...
+ (eq erc-nick-change-attempt-count
+ (if (consp erc-nick)
+ (+ (length erc-nick) 1)
+ 1)))
+ (erc-display-error-notice
+ nil
+ (format "Nickname %s is %s, try another." nick reason))
+ (setq erc-nick-change-attempt-count (+ erc-nick-change-attempt-count 1))
+ (let ((newnick (nth 1 erc-default-nicks))
+ (nicklen (cdr (assoc "NICKLEN"
+ (with-current-buffer (erc-server-buffer)
+ erc-server-parameters)))))
+ (setq erc-bad-nick t)
+ ;; try to use a different nick
+ (if erc-default-nicks
+ (setq erc-default-nicks (cdr erc-default-nicks)))
+ (if (not newnick)
+ (setq newnick (concat (truncate-string-to-width
+ nick
+ (if (and erc-server-connected nicklen)
+ (- (string-to-number nicklen) 1)
+ ;; rfc2812 max nick length = 9
+ ;; we must assume this is the
+ ;; server's setting if we haven't
+ ;; established a connection yet
+ 8))
+ erc-nick-uniquifier)))
+ (erc-cmd-NICK newnick)
+ (erc-display-error-notice
+ nil
+ (format "Nickname %s is %s, trying %s"
+ nick reason newnick)))))
+
+;;; Server messages
+
+(defgroup erc-server-hooks nil
+ "Server event callbacks.
+Every server event - like numeric replies - has it's own hook.
+Those hooks are all called using `run-hook-with-args-until-success'.
+They receive as first argument the process object from where the event
+originated from,
+and as second argument the event parsed as a vector."
+ :group 'erc-hooks)
+
+(defun erc-display-server-message (proc parsed)
+ "Display the message sent by the server as a notice."
+ (erc-display-message
+ parsed 'notice 'active (erc-response.contents parsed)))
+
+(defun erc-auto-query (proc parsed)
+ ;; FIXME: This needs more documentation, unless it's not a user function --
+ ;; Lawrence 2004-01-08
+ "Put this on `erc-server-PRIVMSG-functions'."
+ (when erc-auto-query
+ (let* ((nick (car (erc-parse-user (erc-response.sender parsed))))
+ (target (car (erc-response.command-args parsed)))
+ (msg (erc-response.contents parsed))
+ (query (if (not erc-query-on-unjoined-chan-privmsg)
+ nick
+ (if (erc-current-nick-p target)
+ nick
+ target))))
+ (and (not (erc-ignored-user-p (erc-response.sender parsed)))
+ (or erc-query-on-unjoined-chan-privmsg
+ (string= target (erc-current-nick)))
+ (not (erc-get-buffer query proc))
+ (not (erc-is-message-ctcp-and-not-action-p msg))
+ (let ((erc-join-buffer erc-auto-query))
+ (erc-cmd-QUERY query))
+ nil))))
+
+(defun erc-is-message-ctcp-p (message)
+ "Check if MESSAGE is a CTCP message or not."
+ (string-match "^\C-a\\([^\C-a]*\\)\C-a?$" message))
+
+(defun erc-is-message-ctcp-and-not-action-p (message)
+ "Check if MESSAGE is a CTCP message or not."
+ (and (erc-is-message-ctcp-p message)
+ (not (string-match "^\C-a\\ACTION.*\C-a$" message))))
+
+(defun erc-format-privmessage (nick msg privp msgp)
+ "Format a PRIVMSG in an insertible fashion."
+ (let* ((mark-s (if msgp (if privp "*" "<") "-"))
+ (mark-e (if msgp (if privp "*" ">") "-"))
+ (str (format "%s%s%s %s" mark-s nick mark-e msg))
+ (nick-face (if privp 'erc-nick-msg-face 'erc-nick-default-face))
+ (msg-face (if privp 'erc-direct-msg-face 'erc-default-face)))
+ ;; add text properties to text before the nick, the nick and after the nick
+ (erc-put-text-property 0 (length mark-s) 'face msg-face str)
+ (erc-put-text-property (length mark-s) (+ (length mark-s) (length nick))
+ 'face nick-face str)
+ (erc-put-text-property (+ (length mark-s) (length nick)) (length str)
+ 'face msg-face str)
+ str))
+
+(defcustom erc-format-nick-function 'erc-format-nick
+ "*Function to format a nickname for message display."
+ :group 'erc-display
+ :type 'function)
+
+(defun erc-format-nick (&optional user channel-data)
+ "Standard nickname formatting function. Only returns the value
+of NICK."
+ (if user
+ (erc-server-user-nickname user)))
+
+(defun erc-format-@nick (&optional user channel-data)
+ "Format a nickname such that @ or + are prefix for the NICK
+if OP or VOICE are t respectively."
+ (if user
+ (let (op voice)
+ (if channel-data
+ (setq op (erc-channel-user-op channel-data)
+ voice (erc-channel-user-voice channel-data)))
+ (concat (if voice "+" "")
+ (if op "@" "")
+ (erc-server-user-nickname user)))))
+
+(defun erc-format-my-nick ()
+ "Return the beginning of this user's message, correctly propertized"
+ (if erc-show-my-nick
+ (let ((open "<")
+ (close "> ")
+ (nick (erc-current-nick)))
+ (concat
+ (erc-propertize open 'face 'erc-default-face)
+ (erc-propertize nick 'face 'erc-nick-default-face)
+ (erc-propertize close 'face 'erc-default-face)))
+ (let ((prefix "> "))
+ (erc-propertize prefix 'face 'erc-default-face))))
+
+(defun erc-echo-notice-in-default-buffer (s parsed buffer sender)
+ "Echos a private notice in the default buffer, namely the
+target buffer specified by BUFFER, or there is no target buffer,
+the server buffer. This function is designed to be added to
+either `erc-echo-notice-hook' or `erc-echo-notice-always-hook',
+and always returns t."
+ (erc-display-message parsed nil buffer s)
+ t)
+
+(defun erc-echo-notice-in-target-buffer (s parsed buffer sender)
+ "Echos a private notice in BUFFER, if BUFFER is non-nil. This
+function is designed to be added to either `erc-echo-notice-hook'
+or `erc-echo-notice-always-hook', and returns non-nil iff BUFFER
+is non-nil."
+ (if buffer
+ (progn (erc-display-message parsed nil buffer s) t)
+ nil))
+
+(defun erc-echo-notice-in-minibuffer (s parsed buffer sender)
+ "Echos a private notice in the minibuffer. This function is
+designed to be added to either `erc-echo-notice-hook' or
+`erc-echo-notice-always-hook', and always returns t."
+ (message "%s" (concat "NOTICE: " s))
+ t)
+
+(defun erc-echo-notice-in-server-buffer (s parsed buffer sender)
+ "Echos a private notice in the server buffer. This function is
+designed to be added to either `erc-echo-notice-hook' or
+`erc-echo-notice-always-hook', and always returns t."
+ (erc-display-message parsed nil nil s)
+ t)
+
+(defun erc-echo-notice-in-active-non-server-buffer (s parsed buffer sender)
+ "Echos a private notice in the active buffer if the active
+buffer is not the server buffer. This function is designed to be
+added to either `erc-echo-notice-hook' or
+`erc-echo-notice-always-hook', and returns non-nil iff the active
+buffer is not the server buffer."
+ (if (not (eq (erc-server-buffer) (erc-active-buffer)))
+ (progn (erc-display-message parsed nil 'active s) t)
+ nil))
+
+(defun erc-echo-notice-in-active-buffer (s parsed buffer sender)
+ "Echos a private notice in the active buffer. This function is
+designed to be added to either `erc-echo-notice-hook' or
+`erc-echo-notice-always-hook', and always returns t."
+ (erc-display-message parsed nil 'active s)
+ t)
+
+(defun erc-echo-notice-in-user-buffers (s parsed buffer sender)
+ "Echos a private notice in all of the buffers for which SENDER
+is a member. This function is designed to be added to either
+`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
+returns non-nil iff there is at least one buffer for which the
+sender is a member.
+
+See also: `erc-echo-notice-in-first-user-buffer',
+`erc-buffer-list-with-nick'"
+ (let ((buffers (erc-buffer-list-with-nick sender erc-server-process)))
+ (if buffers
+ (progn (erc-display-message parsed nil buffers s) t)
+ nil)))
+
+(defun erc-echo-notice-in-user-and-target-buffers (s parsed buffer sender)
+ "Echos a private notice in BUFFER and in all of the buffers for
+which SENDER is a member. This function is designed to be added
+to either `erc-echo-notice-hook' or
+`erc-echo-notice-always-hook', and returns non-nil iff there is
+at least one buffer for which the sender is a member or the
+default target.
+
+See also: `erc-echo-notice-in-user-buffers',
+`erc-buffer-list-with-nick'"
+ (let ((buffers (erc-buffer-list-with-nick sender erc-server-process)))
+ (add-to-list 'buffers buffer)
+ (if buffers
+ (progn (erc-display-message parsed nil buffers s) t)
+ nil)))
+
+(defun erc-echo-notice-in-first-user-buffer (s parsed buffer sender)
+ "Echos a private notice in one of the buffers for which SENDER
+is a member. This function is designed to be added to either
+`erc-echo-notice-hook' or `erc-echo-notice-always-hook', and
+returns non-nil iff there is at least one buffer for which the
+sender is a member.
+
+See also: `erc-echo-notice-in-user-buffers',
+`erc-buffer-list-with-nick'"
+ (let ((buffers (erc-buffer-list-with-nick sender erc-server-process)))
+ (if buffers
+ (progn (erc-display-message parsed nil (car buffers) s) t)
+ nil)))
+
+;;; Ban manipulation
+
+(defun erc-banlist-store (proc parsed)
+ "Record ban entries for a channel."
+ (multiple-value-bind (channel mask whoset)
+ (cdr (erc-response.command-args parsed))
+ ;; Determine to which buffer the message corresponds
+ (let ((buffer (erc-get-buffer channel proc)))
+ (with-current-buffer buffer
+ (unless (member (cons whoset mask) erc-channel-banlist)
+ (setq erc-channel-banlist (cons (cons whoset mask)
+ erc-channel-banlist))))))
+ nil)
+
+(defun erc-banlist-finished (proc parsed)
+ "Record that we have received the banlist."
+ (let* ((channel (second (erc-response.command-args parsed)))
+ (buffer (erc-get-buffer channel proc)))
+ (with-current-buffer buffer
+ (put 'erc-channel-banlist 'received-from-server t)))
+ t) ; suppress the 'end of banlist' message
+
+(defun erc-banlist-update (proc parsed)
+ "Check MODE commands for bans and update the banlist appropriately."
+ ;; FIXME: Possibly incorrect. -- Lawrence 2004-05-11
+ (let* ((tgt (first (erc-response.command-args parsed)))
+ (mode (erc-response.contents parsed))
+ (whoset (erc-response.sender parsed))
+ (buffer (erc-get-buffer tgt proc)))
+ (when buffer
+ (with-current-buffer buffer
+ (cond ((not (get 'erc-channel-banlist 'received-from-server)) nil)
+ ((string-match "^\\([+-]\\)b" mode)
+ ;; This is a ban
+ (cond
+ ((string-match "^-" mode)
+ ;; Remove the unbanned masks from the ban list
+ (setq erc-channel-banlist
+ (erc-delete-if
+ #'(lambda (y)
+ (member (upcase (cdr y))
+ (mapcar #'upcase
+ (cdr (split-string mode)))))
+ erc-channel-banlist)))
+ ((string-match "^+" mode)
+ ;; Add the banned mask(s) to the ban list
+ (mapc
+ (lambda (mask)
+ (unless (member (cons whoset mask) erc-channel-banlist)
+ (setq erc-channel-banlist
+ (cons (cons whoset mask) erc-channel-banlist))))
+ (cdr (split-string mode))))))))))
+ nil)
+
+;; used for the banlist cmds
+(defun erc-group-list (list n)
+ "Group LIST into sublists of length N."
+ (cond ((null list) nil)
+ ((null (nthcdr n list)) (list list))
+ (t (cons (erc-subseq list 0 n) (erc-group-list (nthcdr n list) n)))))
+
+
+;;; MOTD numreplies
+
+(defun erc-handle-login ()
+ "Handle the logging in process of connection."
+ (unless erc-logged-in
+ (setq erc-logged-in t)
+ (message "Logging in as \'%s\'... done" (erc-current-nick))
+ ;; execute a startup script
+ (let ((f (erc-select-startup-file)))
+ (when f
+ (erc-load-script f)))))
+
+(defun erc-connection-established (proc parsed)
+ "Run just after connection.
+
+Set user modes and run `erc-after-connect hook'."
+ (unless erc-server-connected ; only once per session
+ (let ((server (or erc-server-announced-name (erc-response.sender parsed)))
+ (nick (car (erc-response.command-args parsed ))))
+ (setq erc-server-connected t)
+ (erc-update-mode-line)
+ (erc-set-initial-user-mode nick)
+ (erc-server-setup-periodical-server-ping)
+ (run-hook-with-args 'erc-after-connect server nick))))
+
+(defun erc-set-initial-user-mode (nick)
+ "If `erc-user-mode' is non-nil for NICK, set the user modes."
+ (when erc-user-mode
+ (let ((mode (if (functionp erc-user-mode)
+ (funcall erc-user-mode)
+ erc-user-mode)))
+ (when (stringp mode)
+ (erc-log (format "changing mode for %s to %s" nick mode))
+ (erc-server-send (format "MODE %s %s" nick mode))))))
+
+(defun erc-display-error-notice (parsed string)
+ "Display STRING as an error notice.
+
+See also `erc-display-message'."
+ (erc-display-message
+ parsed '(notice error) 'active string))
+
+(defun erc-process-ctcp-query (proc parsed nick login host)
+ ;; FIXME: This needs a proper docstring -- Lawrence 2004-01-08
+ "Process a CTCP query."
+ (let ((queries (delete "" (split-string (erc-response.contents parsed)
+ "\C-a"))))
+ (if (> (length queries) 4)
+ (erc-display-message
+ parsed (list 'notice 'error) proc 'ctcp-too-many)
+ (if (= 0 (length queries))
+ (erc-display-message
+ parsed (list 'notice 'error) proc
+ 'ctcp-empty ?n nick)
+ (while queries
+ (let* ((type (upcase (car (split-string (car queries)))))
+ (hook (intern-soft (concat "erc-ctcp-query-" type "-hook"))))
+ (if (and hook (boundp hook))
+ (if (string-equal type "ACTION")
+ (run-hook-with-args-until-success
+ hook proc parsed nick login host
+ (car (erc-response.command-args parsed))
+ (car queries))
+ (when erc-paranoid
+ (if (erc-current-nick-p
+ (car (erc-response.command-args parsed)))
+ (erc-display-message
+ parsed 'error 'active 'ctcp-request
+ ?n nick ?u login ?h host ?r (car queries))
+ (erc-display-message
+ parsed 'error 'active 'ctcp-request-to
+ ?n nick ?u login ?h host ?r (car queries)
+ ?t (car (erc-response.command-args parsed)))))
+ (run-hook-with-args-until-success
+ hook proc nick login host
+ (car (erc-response.command-args parsed))
+ (car queries)))
+ (erc-display-message
+ parsed (list 'notice 'error) proc
+ 'undefined-ctcp)))
+ (setq queries (cdr queries)))))))
+
+(defvar erc-ctcp-query-ACTION-hook '(erc-ctcp-query-ACTION))
+
+(defun erc-ctcp-query-ACTION (proc parsed nick login host to msg)
+ "Respond to a CTCP ACTION query."
+ (when (string-match "^ACTION\\s-\\(.*\\)\\s-*$" msg)
+ (let ((s (match-string 1 msg))
+ (buf (or (erc-get-buffer to proc)
+ (erc-get-buffer nick proc)
+ (process-buffer proc))))
+ (erc-display-message
+ parsed 'action buf
+ 'ACTION ?n nick ?u login ?h host ?a s))))
+
+(defvar erc-ctcp-query-CLIENTINFO-hook '(erc-ctcp-query-CLIENTINFO))
+
+(defun erc-ctcp-query-CLIENTINFO (proc nick login host to msg)
+ "Respond to a CTCP CLIENTINFO query."
+ (when (string-match "^CLIENTINFO\\(\\s-*\\|\\s-+.*\\)$" msg)
+ (let ((s (erc-client-info (erc-trim-string (match-string 1 msg)))))
+ (unless erc-disable-ctcp-replies
+ (erc-send-ctcp-notice nick (format "CLIENTINFO %s" s)))))
+ nil)
+
+(defvar erc-ctcp-query-ECHO-hook '(erc-ctcp-query-ECHO))
+(defun erc-ctcp-query-ECHO (proc nick login host to msg)
+ "Respond to a CTCP ECHO query."
+ (when (string-match "^ECHO\\s-+\\(.*\\)\\s-*$" msg)
+ (let ((s (match-string 1 msg)))
+ (unless erc-disable-ctcp-replies
+ (erc-send-ctcp-notice nick (format "ECHO %s" s)))))
+ nil)
+
+(defvar erc-ctcp-query-FINGER-hook '(erc-ctcp-query-FINGER))
+(defun erc-ctcp-query-FINGER (proc nick login host to msg)
+ "Respond to a CTCP FINGER query."
+ (unless erc-disable-ctcp-replies
+ (let ((s (if erc-anonymous-login
+ (format "FINGER I'm %s." (erc-current-nick))
+ (format "FINGER %s (%s@%s)."
+ (user-full-name)
+ (user-login-name)
+ (system-name))))
+ (ns (erc-time-diff erc-server-last-sent-time (erc-current-time))))
+ (when (> ns 0)
+ (setq s (concat s " Idle for " (erc-sec-to-time ns))))
+ (erc-send-ctcp-notice nick s)))
+ nil)
+
+(defvar erc-ctcp-query-PING-hook '(erc-ctcp-query-PING))
+(defun erc-ctcp-query-PING (proc nick login host to msg)
+ "Respond to a CTCP PING query."
+ (when (string-match "^PING\\s-+\\(.*\\)" msg)
+ (unless erc-disable-ctcp-replies
+ (let ((arg (match-string 1 msg)))
+ (erc-send-ctcp-notice nick (format "PING %s" arg)))))
+ nil)
+
+(defvar erc-ctcp-query-TIME-hook '(erc-ctcp-query-TIME))
+(defun erc-ctcp-query-TIME (proc nick login host to msg)
+ "Respond to a CTCP TIME query."
+ (unless erc-disable-ctcp-replies
+ (erc-send-ctcp-notice nick (format "TIME %s" (current-time-string))))
+ nil)
+
+(defvar erc-ctcp-query-USERINFO-hook '(erc-ctcp-query-USERINFO))
+(defun erc-ctcp-query-USERINFO (proc nick login host to msg)
+ "Respond to a CTCP USERINFO query."
+ (unless erc-disable-ctcp-replies
+ (erc-send-ctcp-notice nick (format "USERINFO %s" erc-user-information)))
+ nil)
+
+(defvar erc-ctcp-query-VERSION-hook '(erc-ctcp-query-VERSION))
+(defun erc-ctcp-query-VERSION (proc nick login host to msg)
+ "Respond to a CTCP VERSION query."
+ (unless erc-disable-ctcp-replies
+ (erc-send-ctcp-notice
+ nick (format
+ "VERSION \C-bERC\C-b %s - an IRC client for emacs (\C-b%s\C-b)"
+ erc-version-string
+ erc-official-location)))
+ nil)
+
+(defun erc-process-ctcp-reply (proc parsed nick login host msg)
+ "Process MSG as a CTCP reply."
+ (let* ((type (car (split-string msg)))
+ (hook (intern (concat "erc-ctcp-reply-" type "-hook"))))
+ (if (boundp hook)
+ (run-hook-with-args-until-success
+ hook proc nick login host
+ (car (erc-response.command-args parsed)) msg)
+ (erc-display-message
+ parsed 'notice 'active
+ 'CTCP-UNKNOWN ?n nick ?u login ?h host ?m msg))))
+
+(defvar erc-ctcp-reply-ECHO-hook '(erc-ctcp-reply-ECHO))
+(defun erc-ctcp-reply-ECHO (proc nick login host to msg)
+ "Handle a CTCP ECHO reply."
+ (when (string-match "^ECHO\\s-+\\(.*\\)\\s-*$" msg)
+ (let ((message (match-string 1 msg)))
+ (erc-display-message
+ nil '(notice action) 'active
+ 'CTCP-ECHO ?n nick ?m message)))
+ nil)
+
+(defvar erc-ctcp-reply-CLIENTINFO-hook '(erc-ctcp-reply-CLIENTINFO))
+(defun erc-ctcp-reply-CLIENTINFO (proc nick login host to msg)
+ "Handle a CTCP CLIENTINFO reply."
+ (when (string-match "^CLIENTINFO\\s-+\\(.*\\)\\s-*$" msg)
+ (let ((message (match-string 1 msg)))
+ (erc-display-message
+ nil 'notice 'active
+ 'CTCP-CLIENTINFO ?n nick ?m message)))
+ nil)
+
+(defvar erc-ctcp-reply-FINGER-hook '(erc-ctcp-reply-FINGER))
+(defun erc-ctcp-reply-FINGER (proc nick login host to msg)
+ "Handle a CTCP FINGER reply."
+ (when (string-match "^FINGER\\s-+\\(.*\\)\\s-*$" msg)
+ (let ((message (match-string 1 msg)))
+ (erc-display-message
+ nil 'notice 'active
+ 'CTCP-FINGER ?n nick ?m message)))
+ nil)
+
+(defvar erc-ctcp-reply-PING-hook '(erc-ctcp-reply-PING))
+(defun erc-ctcp-reply-PING (proc nick login host to msg)
+ "Handle a CTCP PING reply."
+ (if (not (string-match "^PING\\s-+\\([0-9.]+\\)" msg))
+ nil
+ (let ((time (match-string 1 msg)))
+ (condition-case nil
+ (let ((delta (erc-time-diff (string-to-number time)
+ (erc-current-time))))
+ (erc-display-message
+ nil 'notice 'active
+ 'CTCP-PING ?n nick
+ ?t (erc-sec-to-time delta)))
+ (range-error
+ (erc-display-message
+ nil 'error 'active
+ 'bad-ping-response ?n nick ?t time))))))
+
+(defvar erc-ctcp-reply-TIME-hook '(erc-ctcp-reply-TIME))
+(defun erc-ctcp-reply-TIME (proc nick login host to msg)
+ "Handle a CTCP TIME reply."
+ (when (string-match "^TIME\\s-+\\(.*\\)\\s-*$" msg)
+ (let ((message (match-string 1 msg)))
+ (erc-display-message
+ nil 'notice 'active
+ 'CTCP-TIME ?n nick ?m message)))
+ nil)
+
+(defvar erc-ctcp-reply-VERSION-hook '(erc-ctcp-reply-VERSION))
+(defun erc-ctcp-reply-VERSION (proc nick login host to msg)
+ "Handle a CTCP VERSION reply."
+ (when (string-match "^VERSION\\s-+\\(.*\\)\\s-*$" msg)
+ (let ((message (match-string 1 msg)))
+ (erc-display-message
+ nil 'notice 'active
+ 'CTCP-VERSION ?n nick ?m message)))
+ nil)
+
+(defun erc-process-away (proc away-p)
+ ;; FIXME: This docstring is AWFUL -- Lawrence 2004-01-08
+ "Process the user being away, or returning from an away break."
+ (let ((sessionbuf (process-buffer proc)))
+ (when sessionbuf
+ (with-current-buffer sessionbuf
+ (when erc-away-nickname
+ (erc-log (format "erc-process-away: away-nick: %s, away-p: %s"
+ erc-away-nickname away-p))
+ (erc-cmd-NICK (if away-p
+ erc-away-nickname
+ erc-nick)))
+ (cond
+ (away-p
+ (erc-with-all-buffers-of-server proc nil
+ (setq erc-away (current-time))))
+ (t
+ (let ((away-time erc-away))
+ ;; away must be set to NIL BEFORE sending anything to prevent
+ ;; an infinite recursion
+ (erc-with-all-buffers-of-server proc nil
+ (setq erc-away nil))
+ (save-excursion
+ (set-buffer (erc-active-buffer))
+ (when erc-public-away-p
+ (erc-send-action
+ (erc-default-target)
+ (if away-time
+ (format "is back (gone for %s)"
+ (erc-sec-to-time
+ (erc-time-diff
+ (erc-emacs-time-to-erc-time away-time)
+ (erc-current-time))))
+ "is back")))))))))
+ (erc-update-mode-line)))
+
+;;;; List of channel members handling
+
+(defun erc-channel-begin-receiving-names ()
+ "Internal function.
+
+Used when a channel names list is about to be received. Should
+be called with the current buffer set to the channel buffer.
+
+See also `erc-channel-end-receiving-names'."
+ (setq erc-channel-new-member-names (make-hash-table :test 'equal)))
+
+(defun erc-channel-end-receiving-names ()
+ "Internal function.
+
+Used to fix `erc-channel-users' after a channel names list has been
+received. Should be called with the current buffer set to the
+channel buffer.
+
+See also `erc-channel-begin-receiving-names'."
+ (maphash (lambda (nick user)
+ (if (null (gethash nick erc-channel-new-member-names))
+ (erc-remove-channel-user nick)))
+ erc-channel-users)
+ (setq erc-channel-new-member-names nil))
+
+(defun erc-channel-receive-names (names-string)
+ "This function is for internal use only.
+
+Update `erc-channel-users' according to NAMES-STRING.
+NAMES-STRING is a string listing some of the names on the
+channel."
+ (let (names name op voice)
+ ;; We need to delete "" because in XEmacs, (split-string "a ")
+ ;; returns ("a" "").
+ (setq names (delete "" (split-string names-string)))
+ (let ((erc-channel-members-changed-hook nil))
+ (dolist (item names)
+ (cond ((string-match "^@\\(.*\\)$" item)
+ (setq name (match-string 1 item)
+ op 'on
+ voice 'off))
+ ((string-match "^+\\(.*\\)$" item)
+ (setq name (match-string 1 item)
+ op 'off
+ voice 'on))
+ (t (setq name item
+ op 'off
+ voice 'off)))
+ (puthash (erc-downcase name) t
+ erc-channel-new-member-names)
+ (erc-update-current-channel-member
+ name name t op voice)))
+ (run-hooks 'erc-channel-members-changed-hook)))
+
+(defcustom erc-channel-members-changed-hook nil
+ "*This hook is called every time the variable `channel-members' changes.
+The buffer where the change happened is current while this hook is called."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defun erc-update-user-nick (nick &optional new-nick
+ host login full-name info)
+ "Updates the stored user information for the user with nickname
+NICK.
+
+See also: `erc-update-user'"
+ (erc-update-user (erc-get-server-user nick) new-nick
+ host login full-name info))
+
+(defun erc-update-user (user &optional new-nick
+ host login full-name info)
+ "Update user info for USER. USER must be an erc-server-user
+struct. Any of NEW-NICK, HOST, LOGIN, FULL-NAME, INFO which are
+non-nil and not equal to the existing values for USER are used to
+replace the stored values in USER.
+
+If, any only if a change is made,
+`erc-channel-members-changed-hook' is run for each channel for
+which USER is a member, and `t' is returned."
+ (let (changed)
+ (when user
+ (when (and new-nick
+ (not (equal (erc-server-user-nickname user)
+ new-nick)))
+ (setq changed t)
+ (erc-change-user-nickname user new-nick))
+ (when (and host
+ (not (equal (erc-server-user-host user) host)))
+ (setq changed t)
+ (setf (erc-server-user-host user) host))
+ (when (and login
+ (not (equal (erc-server-user-login user) login)))
+ (setq changed t)
+ (setf (erc-server-user-login user) login))
+ (when (and full-name
+ (not (equal (erc-server-user-full-name user)
+ full-name)))
+ (setq changed t)
+ (setf (erc-server-user-full-name user) full-name))
+ (when (and info
+ (not (equal (erc-server-user-info user) info)))
+ (setq changed t)
+ (setf (erc-server-user-info user) info))
+ (if changed
+ (dolist (buf (erc-server-user-buffers user))
+ (if (buffer-live-p buf)
+ (with-current-buffer buf
+ (run-hooks 'erc-channel-members-changed-hook))))))
+ changed))
+
+(defun erc-update-current-channel-member
+ (nick new-nick &optional add op voice host login full-name info
+ update-message-time)
+ "Updates the stored user information for the user with nickname
+NICK. `erc-update-user' is called to handle changes to nickname,
+host, login, full-name, and info. If `op' or `voice' are
+non-nil, they must be equal to either `on' or `off', in which
+case the operator or voice status of USER in the current channel
+is changed accordingly. If `update-message-time' is non-nil, the
+last-message-time of the user in the current channel is set
+to (current-time).
+
+If ADD is non-nil, the user will be added with the specified
+information if it is not already present in the user or channel
+lists.
+
+If, and only if, changes are made, or the user is added,
+`erc-channel-members-updated-hook' is run, and `t' is returned.
+
+See also: `erc-update-user' and `erc-update-channel-member'."
+ (let* (changed user-changed
+ (channel-data (erc-get-channel-user nick))
+ (cuser (if channel-data (cdr channel-data)))
+ (user (if channel-data (car channel-data)
+ (erc-get-server-user nick))))
+ (if cuser
+ (progn
+ (erc-log (format "update-member: user = %S, cuser = %S" user cuser))
+ (when (and op
+ (not (eq (erc-channel-user-op cuser) op)))
+ (setq changed t)
+ (setf (erc-channel-user-op cuser)
+ (cond ((eq op 'on) t)
+ ((eq op 'off) nil)
+ (t op))))
+ (when (and voice
+ (not (eq (erc-channel-user-voice cuser) voice)))
+ (setq changed t)
+ (setf (erc-channel-user-voice cuser)
+ (cond ((eq voice 'on) t)
+ ((eq voice 'off) nil)
+ (t voice))))
+ (when update-message-time
+ (setf (erc-channel-user-last-message-time cuser) (current-time)))
+ (setq user-changed
+ (erc-update-user user new-nick
+ host login full-name info)))
+ (when add
+ (if (null user)
+ (progn
+ (setq user (make-erc-server-user
+ :nickname nick
+ :host host
+ :full-name full-name
+ :login login
+ :info info
+ :buffers (list (current-buffer))))
+ (erc-add-server-user nick user))
+ (setf (erc-server-user-buffers user)
+ (cons (current-buffer)
+ (erc-server-user-buffers user))))
+ (setq cuser (make-erc-channel-user
+ :op (cond ((eq op 'on) t)
+ ((eq op 'off) nil)
+ (t op))
+ :voice (cond ((eq voice 'on) t)
+ ((eq voice 'off) nil)
+ (t voice))
+ :last-message-time
+ (if update-message-time (current-time))))
+ (puthash (erc-downcase nick) (cons user cuser)
+ erc-channel-users)
+ (setq changed t)))
+ (when (and changed (null user-changed))
+ (run-hooks 'erc-channel-members-changed-hook))
+ (or changed user-changed add)))
+
+(defun erc-update-channel-member (channel nick new-nick
+ &optional add op voice host login
+ full-name info update-message-time)
+ "Updates user and channel information for the user with
+nickname NICK in channel CHANNEL.
+
+See also: `erc-update-current-channel-member'"
+ (erc-with-buffer
+ (channel)
+ (erc-update-current-channel-member nick new-nick add op voice host
+ login full-name info
+ update-message-time)))
+
+(defun erc-remove-current-channel-member (nick)
+ "Remove NICK from current channel membership list. Runs
+`erc-channel-members-changed-hook'."
+ (let ((channel-data (erc-get-channel-user nick)))
+ (when channel-data
+ (erc-remove-channel-user nick)
+ (run-hooks 'erc-channel-members-changed-hook))))
+
+(defun erc-remove-channel-member (channel nick)
+ "Remove NICK from CHANNEL's membership list.
+
+See also `erc-remove-current-channel-member'."
+ (erc-with-buffer
+ (channel)
+ (erc-remove-current-channel-member nick)))
+
+(defun erc-update-channel-topic (channel topic &optional modify)
+ "Find a buffer for CHANNEL and set the TOPIC for it.
+
+If optional MODIFY is 'append or 'prepend, then append or prepend the
+TOPIC string to the current topic."
+ (erc-with-buffer (channel)
+ (cond ((eq modify 'append)
+ (setq erc-channel-topic (concat erc-channel-topic topic)))
+ ((eq modify 'prepend)
+ (setq erc-channel-topic (concat topic erc-channel-topic)))
+ (t (setq erc-channel-topic topic)))
+ (erc-update-mode-line-buffer (current-buffer))))
+
+(defun erc-set-modes (tgt mode-string)
+ "Set the modes for the TGT provided as MODE-STRING."
+ (let* ((modes (erc-parse-modes mode-string))
+ (add-modes (nth 0 modes))
+ (remove-modes (nth 1 modes))
+ ;; list of triples: (mode-char 'on/'off argument)
+ (arg-modes (nth 2 modes)))
+ (cond ((erc-channel-p tgt); channel modes
+ (let ((buf (and (boundp 'erc-server-process) erc-server-process
+ (erc-get-buffer tgt erc-server-process))))
+ (when buf
+ (with-current-buffer buf
+ (setq erc-channel-modes add-modes)
+ (setq erc-channel-user-limit nil)
+ (setq erc-channel-key nil)
+ (while arg-modes
+ (let ((mode (nth 0 (car arg-modes)))
+ (onoff (nth 1 (car arg-modes)))
+ (arg (nth 2 (car arg-modes))))
+ (cond ((string-match "^[Ll]" mode)
+ (erc-update-channel-limit tgt onoff arg))
+ ((string-match "^[Kk]" mode)
+ (erc-update-channel-key tgt onoff arg))
+ (t nil)))
+ (setq arg-modes (cdr arg-modes)))
+ (erc-update-mode-line-buffer buf)))))
+ ;; we do not keep our nick's modes yet
+ ;;(t (setq erc-user-modes add-modes))
+ )
+ ))
+
+(defun erc-sort-strings (list-of-strings)
+ "Sort LIST-OF-STRINGS in lexicographic order.
+
+Side-effect free."
+ (sort (copy-sequence list-of-strings) 'string<))
+
+(defun erc-parse-modes (mode-string)
+ "Parse MODE-STRING into a list.
+
+Returns a list of three elements:
+
+ (ADD-MODES REMOVE-MODES ARG-MODES).
+
+The add-modes and remove-modes are lists of single-character strings
+for modes without parameters to add and remove respectively. The
+arg-modes is a list of triples of the form:
+
+ (MODE-CHAR ON/OFF ARGUMENT)."
+ (if (string-match "^\\s-*\\(\\S-+\\)\\(\\s-.*$\\|$\\)" mode-string)
+ (let ((chars (mapcar 'char-to-string (match-string 1 mode-string)))
+ ;; arguments in channel modes
+ (args-str (match-string 2 mode-string))
+ (args nil)
+ (add-modes nil)
+ (remove-modes nil)
+ (arg-modes nil); list of triples: (mode-char 'on/'off argument)
+ (add-p t))
+ ;; make the argument list
+ (while (string-match "^\\s-*\\(\\S-+\\)\\(\\s-+.*$\\|$\\)" args-str)
+ (setq args (cons (match-string 1 args-str) args))
+ (setq args-str (match-string 2 args-str)))
+ (setq args (nreverse args))
+ ;; collect what modes changed, and match them with arguments
+ (while chars
+ (cond ((string= (car chars) "+") (setq add-p t))
+ ((string= (car chars) "-") (setq add-p nil))
+ ((string-match "^[ovbOVB]" (car chars))
+ (setq arg-modes (cons (list (car chars)
+ (if add-p 'on 'off)
+ (if args (car args) nil))
+ arg-modes))
+ (if args (setq args (cdr args))))
+ ((string-match "^[LlKk]" (car chars))
+ (setq arg-modes (cons (list (car chars)
+ (if add-p 'on 'off)
+ (if (and add-p args)
+ (car args) nil))
+ arg-modes))
+ (if (and add-p args) (setq args (cdr args))))
+ (add-p (setq add-modes (cons (car chars) add-modes)))
+ (t (setq remove-modes (cons (car chars) remove-modes))))
+ (setq chars (cdr chars)))
+ (setq add-modes (nreverse add-modes))
+ (setq remove-modes (nreverse remove-modes))
+ (setq arg-modes (nreverse arg-modes))
+ (list add-modes remove-modes arg-modes))
+ nil))
+
+(defun erc-update-modes (tgt mode-string &optional nick host login)
+ "Update the mode information for TGT, provided as MODE-STRING.
+Optional arguments: NICK, HOST and LOGIN - the attributes of the
+person who changed the modes."
+ (let* ((modes (erc-parse-modes mode-string))
+ (add-modes (nth 0 modes))
+ (remove-modes (nth 1 modes))
+ ;; list of triples: (mode-char 'on/'off argument)
+ (arg-modes (nth 2 modes)))
+ ;; now parse the modes changes and do the updates
+ (cond ((erc-channel-p tgt); channel modes
+ (let ((buf (and (boundp 'erc-server-process) erc-server-process
+ (erc-get-buffer tgt erc-server-process))))
+ (when buf
+ ;; FIXME! This used to have an original buffer
+ ;; variable, but it never switched back to the original
+ ;; buffer. Is this wanted behavior?
+ (set-buffer buf)
+ (if (not (boundp 'erc-channel-modes))
+ (setq erc-channel-modes nil))
+ (while remove-modes
+ (setq erc-channel-modes (delete (car remove-modes)
+ erc-channel-modes)
+ remove-modes (cdr remove-modes)))
+ (while add-modes
+ (setq erc-channel-modes (cons (car add-modes)
+ erc-channel-modes)
+ add-modes (cdr add-modes)))
+ (setq erc-channel-modes (erc-sort-strings erc-channel-modes))
+ (while arg-modes
+ (let ((mode (nth 0 (car arg-modes)))
+ (onoff (nth 1 (car arg-modes)))
+ (arg (nth 2 (car arg-modes))))
+ (cond ((string-match "^[oO]" mode)
+ (erc-update-channel-member tgt arg arg nil onoff))
+ ((string-match "^[Vv]" mode)
+ (erc-update-channel-member tgt arg arg nil nil
+ onoff))
+ ((string-match "^[Ll]" mode)
+ (erc-update-channel-limit tgt onoff arg))
+ ((string-match "^[Kk]" mode)
+ (erc-update-channel-key tgt onoff arg))
+ (t nil)); only ops are tracked now
+ (setq arg-modes (cdr arg-modes))))
+ (erc-update-mode-line buf))))
+ ;; nick modes - ignored at this point
+ (t nil))))
+
+(defun erc-update-channel-limit (channel onoff n)
+ ;; FIXME: what does ONOFF actually do? -- Lawrence 2004-01-08
+ "Update CHANNEL's user limit to N."
+ (if (or (not (eq onoff 'on))
+ (and (stringp n) (string-match "^[0-9]+$" n)))
+ (erc-with-buffer
+ (channel)
+ (cond ((eq onoff 'on) (setq erc-channel-user-limit (string-to-number n)))
+ (t (setq erc-channel-user-limit nil))))))
+
+(defun erc-update-channel-key (channel onoff key)
+ "Update CHANNEL's key to KEY if ONOFF is 'on or to nil if it's 'off."
+ (erc-with-buffer
+ (channel)
+ (cond ((eq onoff 'on) (setq erc-channel-key key))
+ (t (setq erc-channel-key nil)))))
+
+(defun erc-handle-user-status-change (type nlh &optional l)
+ "Handle changes in any user's status.
+
+So far, only nick change is handled.
+
+Generally, the TYPE argument is a symbol describing the change type, NLH is
+a list containing the original nickname, login name and hostname for the user,
+and L is a list containing additional TYPE-specific arguments.
+
+So far the following TYPE/L pairs are supported:
+
+ Event TYPE L
+
+ nickname change 'nick (NEW-NICK)"
+ (erc-log (format "user-change: type: %S nlh: %S l: %S" type nlh l))
+ (cond
+ ;; nickname change
+ ((equal type 'nick)
+ t)
+ (t
+ nil)))
+
+(defun erc-highlight-notice (s)
+ "Highlight notice message S and return it.
+See also variable `erc-notice-highlight-type'"
+ (cond
+ ((eq erc-notice-highlight-type 'prefix)
+ (erc-put-text-property 0 (length erc-notice-prefix)
+ 'face 'erc-notice-face s)
+ s)
+ ((eq erc-notice-highlight-type 'all)
+ (erc-put-text-property 0 (length s) 'face 'erc-notice-face s)
+ s)
+ (t s)))
+
+(defun erc-make-notice (message)
+ "Notify the user of MESSAGE."
+ (when erc-minibuffer-notice
+ (message "%s" message))
+ (erc-highlight-notice (concat erc-notice-prefix message)))
+
+(defun erc-highlight-error (s)
+ "Highlight error message S and return it."
+ (erc-put-text-property 0 (length s) 'face 'erc-error-face s)
+ s)
+
+(defun erc-put-text-property (start end property value &optional object)
+ "Set text-property for an object (usually a string).
+START and END define the characters covered.
+PROPERTY is the text-property set, usually the symbol `face'.
+VALUE is the value for the text-property, usually a face symbol such as
+the face `bold' or `erc-pal-face'.
+OBJECT is a string which will be modified and returned.
+OBJECT is modified without being copied first.
+
+You can redefine or `defadvice' this function in order to add
+EmacsSpeak support."
+ (put-text-property start end property value object))
+
+(defun erc-list (thing)
+ "Return THING if THING is a list, or a list with THING as its element."
+ (if (listp thing)
+ thing
+ (list thing)))
+
+(defun erc-parse-user (string)
+ "Parse STRING as a user specification (nick!login@host).
+
+Return a list of the three separate tokens."
+ (cond
+ ((string-match "^\\([^!]*\\)!\\([^@]*\\)@\\(.*\\)$" string)
+ (list (match-string 1 string)
+ (match-string 2 string)
+ (match-string 3 string)))
+ ;; Some bogus bouncers send Nick!(null), try to live with that.
+ ((string-match "^\\([^!]*\\)!\\(.*\\)$" string)
+ (list (match-string 1 string)
+ ""
+ (match-string 2 string)))
+ (t
+ (list string "" ""))))
+
+(defun erc-extract-nick (string)
+ "Return the nick corresponding to a user specification STRING.
+
+See also `erc-parse-user'."
+ (car (erc-parse-user string)))
+
+(defun erc-put-text-properties (start end properties
+ &optional object value-list)
+ "Set text-properties for OBJECT.
+
+START and END describe positions in OBJECT.
+If VALUE-LIST is nil, set each property in PROPERTIES to t, else set
+each property to the corresponding value in VALUE-LIST."
+ (unless value-list
+ (setq value-list (mapcar (lambda (x)
+ t)
+ properties)))
+ (mapcar* (lambda (prop value)
+ (erc-put-text-property start end prop value object))
+ properties value-list))
+
+;;; Input area handling:
+
+(defun erc-beg-of-input-line ()
+ "Return the value of `point' at the beginning of the input line.
+
+Specifically, return the position of `erc-insert-marker'."
+ (or (and (boundp 'erc-insert-marker)
+ (markerp erc-insert-marker))
+ (error "erc-insert-marker has no value, please report a bug"))
+ (marker-position erc-insert-marker))
+
+(defun erc-end-of-input-line ()
+ "Return the value of `point' at the end of the input line."
+ (point-max))
+
+(defun erc-send-current-line ()
+ "Parse current line and send it to IRC."
+ (interactive)
+ (save-restriction
+ (widen)
+ (cond
+ ((< (point) (erc-beg-of-input-line))
+ (message "Point is not in the input area")
+ (beep))
+ ((not (erc-server-buffer-live-p))
+ (message "ERC: No process running")
+ (beep))
+ (t
+ (erc-set-active-buffer (current-buffer))
+ (let ((inhibit-read-only t)
+ (str (erc-user-input))
+ (old-buf (current-buffer)))
+
+ ;; Kill the input and the prompt
+ (delete-region (erc-beg-of-input-line)
+ (erc-end-of-input-line))
+
+ (unwind-protect
+ (erc-send-input str)
+ ;; Fix the buffer if the command didn't kill it
+ (when (buffer-live-p old-buf)
+ (with-current-buffer old-buf
+ (save-restriction
+ (widen)
+ (goto-char (point-max))
+ (set-marker (process-mark erc-server-process) (point))
+ (set-marker erc-insert-marker (point))
+ (let ((buffer-modified (buffer-modified-p)))
+ (erc-display-prompt)
+ (set-buffer-modified-p buffer-modified))))))
+
+ ;; Only when last hook has been run...
+ (run-hook-with-args 'erc-send-completed-hook str))))))
+
+(defun erc-user-input ()
+ "Return the input of the user in the current buffer."
+ (buffer-substring
+ erc-input-marker
+ (erc-end-of-input-line)))
+
+(defun erc-send-input (input)
+ "Treat INPUT as typed in by the user. It is assumed that the input
+and the prompt is already deleted.
+This returns non-nil only iff we actually send anything."
+ ;; Handle different kinds of inputs
+ (cond
+ ;; Ignore empty input
+ ((if erc-send-whitespace-lines
+ (string= input "")
+ (string-match "\\`[ \t\r\f\n]*\\'" input))
+ (when erc-warn-about-blank-lines
+ (message "Blank line - ignoring...")
+ (beep))
+ nil)
+ (t
+ (let ((str input)
+ (erc-insert-this t))
+ (setq erc-send-this t)
+ (run-hook-with-args 'erc-send-pre-hook input)
+ (when erc-send-this
+ (if (or (string-match "\n" str)
+ (not (char-equal (aref str 0) ?/)))
+ (mapc
+ (lambda (line)
+ (mapc
+ (lambda (line)
+ ;; Insert what has to be inserted for this.
+ (erc-display-msg line)
+ (erc-process-input-line (concat line "\n")
+ (null erc-flood-protect) t))
+ (erc-split-line line)))
+ (split-string str "\n"))
+ ;; Insert the prompt along with the command.
+ (erc-display-command str)
+ (erc-process-input-line (concat str "\n") t nil))
+ t)))))
+
+(defun erc-display-command (line)
+ (when erc-insert-this
+ (let ((insert-position (point)))
+ (unless erc-hide-prompt
+ (erc-display-prompt nil nil (erc-command-indicator)
+ (and (erc-command-indicator)
+ 'erc-command-indicator-face)))
+ (let ((beg (point)))
+ (insert line)
+ (erc-put-text-property beg (point)
+ 'face 'erc-command-indicator-face)
+ (insert "\n"))
+ (set-marker (process-mark erc-server-process) (point))
+ (set-marker erc-insert-marker (point))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region insert-position (point))
+ (run-hooks 'erc-send-modify-hook)
+ (run-hooks 'erc-send-post-hook))))))
+
+(defun erc-display-msg (line)
+ "Display LINE as a message of the user to the current target at the
+current position."
+ (when erc-insert-this
+ (let ((insert-position (point)))
+ (insert (erc-format-my-nick))
+ (let ((beg (point)))
+ (insert line)
+ (erc-put-text-property beg (point)
+ 'face 'erc-input-face))
+ (insert "\n")
+ (set-marker (process-mark erc-server-process) (point))
+ (set-marker erc-insert-marker (point))
+ (save-excursion
+ (save-restriction
+ (narrow-to-region insert-position (point))
+ (run-hooks 'erc-send-modify-hook)
+ (run-hooks 'erc-send-post-hook))))))
+
+(defun erc-command-symbol (command)
+ "Return the erc command symbol for COMMAND if it exists and is bound."
+ (let ((cmd (intern-soft (format "erc-cmd-%s" (upcase command)))))
+ (when (fboundp cmd) cmd)))
+
+(defun erc-extract-command-from-line (line)
+ "Extract command and args from the input LINE.
+If no command was given, return nil. If command matches, return a
+list of the form: (command args) where both elements are strings."
+ (when (string-match "^/\\([A-Za-z]+\\)\\(\\s-+.*\\|\\s-*\\)$" line)
+ (let* ((cmd (erc-command-symbol (match-string 1 line)))
+ ;; note: return is nil, we apply this simply for side effects
+ (canon-defun (while (and cmd (symbolp (symbol-function cmd)))
+ (setq cmd (symbol-function cmd))))
+ (cmd-fun (or cmd #'erc-cmd-default))
+ (arg (if cmd
+ (if (get cmd-fun 'do-not-parse-args)
+ (format "%s" (match-string 2 line))
+ (delete "" (split-string (erc-trim-string
+ (match-string 2 line)) " ")))
+ line)))
+ (list cmd-fun arg))))
+
+(defun erc-split-multiline-safe (string)
+ "Split STRING, containing multiple lines and return them in a list.
+Do it only for STRING as the complete input, do not carry unfinished
+strings over to the next call."
+ (let ((l ())
+ (i0 0)
+ (doit t))
+ (while doit
+ (let ((i (string-match "\r?\n" string i0))
+ (s (substring string i0)))
+ (cond (i (setq l (cons (substring string i0 i) l))
+ (setq i0 (match-end 0)))
+ ((> (length s) 0)
+ (setq l (cons s l))(setq doit nil))
+ (t (setq doit nil)))))
+ (nreverse l)))
+
+;; nick handling
+
+(defun erc-set-current-nick (nick)
+ "Set the current nickname to NICK."
+ (with-current-buffer (or (erc-server-buffer)
+ (current-buffer))
+ (setq erc-server-current-nick nick)))
+
+(defun erc-current-nick ()
+ "Return the current nickname."
+ (with-current-buffer (if (buffer-live-p (erc-server-buffer))
+ (erc-server-buffer)
+ (current-buffer))
+ erc-server-current-nick))
+
+(defun erc-current-nick-p (nick)
+ "Return non-nil if NICK is the current nickname."
+ (erc-nick-equal-p nick (erc-current-nick)))
+
+(defun erc-nick-equal-p (nick1 nick2)
+ "Return non-nil if NICK1 and NICK2 are the same.
+
+This matches strings according to the IRC protocol's case convention.
+
+See also `erc-downcase'."
+ (string= (erc-downcase nick1)
+ (erc-downcase nick2)))
+
+;; default target handling
+
+(defun erc-default-target ()
+ "Return the current default target (as a character string) or nil if none."
+ (let ((tgt (car erc-default-recipients)))
+ (cond
+ ((not tgt) nil)
+ ((listp tgt) (cdr tgt))
+ (t tgt))))
+
+(defun erc-add-default-channel (channel)
+ "Add CHANNEL to the default channel list."
+
+ (let ((d1 (car erc-default-recipients))
+ (d2 (cdr erc-default-recipients))
+ (chl (downcase channel)))
+ (setq erc-default-recipients
+ (cons chl erc-default-recipients))))
+
+(defun erc-delete-default-channel (channel &optional buffer)
+ "Delete CHANNEL from the default channel list."
+ (let ((ob (current-buffer)))
+ (with-current-buffer (if (and buffer
+ (bufferp buffer))
+ buffer
+ (current-buffer))
+ (setq erc-default-recipients (delete (downcase channel)
+ erc-default-recipients)))))
+
+(defun erc-add-query (nickname)
+ "Add QUERY'd NICKNAME to the default channel list.
+
+The previous default target of QUERY type gets removed"
+ (let ((d1 (car erc-default-recipients))
+ (d2 (cdr erc-default-recipients))
+ (qt (cons 'QUERY (downcase nickname))))
+ (if (and (listp d1)
+ (eq (car d1) 'QUERY))
+ (setq erc-default-recipients (cons qt d2))
+ (setq erc-default-recipients (cons qt erc-default-recipients)))))
+
+(defun erc-delete-query ()
+ "Delete the topmost target if it is a QUERY."
+
+ (let ((d1 (car erc-default-recipients))
+ (d2 (cdr erc-default-recipients)))
+ (if (and (listp d1)
+ (eq (car d1) 'QUERY))
+ (setq erc-default-recipients d2)
+ (error "Current target is not a QUERY"))))
+
+(defun erc-ignored-user-p (spec)
+ "Return non-nil if SPEC matches something in `erc-ignore-list'.
+
+Takes a full SPEC of a user in the form \"nick!login@host\", and
+matches against all the regexp's in `erc-ignore-list'. If any
+match, returns that regexp."
+ (dolist (ignored (with-current-buffer (erc-server-buffer) erc-ignore-list))
+ (if (string-match ignored spec)
+ ;; We have `require'd cl, so we can return from the block named nil
+ (return ignored))))
+
+(defun erc-ignored-reply-p (msg tgt proc)
+ ;; FIXME: this docstring needs fixing -- Lawrence 2004-01-08
+ "Return non-nil if MSG matches something in `erc-ignore-reply-list'.
+
+Takes a message MSG to a channel and returns non-nil if the addressed
+user matches any regexp in `erc-ignore-reply-list'."
+ (let ((target-nick (erc-message-target msg)))
+ (if (not target-nick)
+ nil
+ (erc-with-buffer (tgt proc)
+ (let ((user (erc-get-server-user target-nick)))
+ (when user
+ (erc-list-match erc-ignore-reply-list
+ (erc-user-spec user))))))))
+
+(defun erc-message-target (msg)
+ "Return the addressed target in MSG.
+
+The addressed target is the string before the first colon in MSG."
+ (if (string-match "^\\([^: ]*\\):" msg)
+ (match-string 1 msg)
+ nil))
+
+(defun erc-user-spec (user)
+ "Create a nick!user@host spec from a user struct."
+ (let ((nick (erc-server-user-nickname user))
+ (host (erc-server-user-host user))
+ (login (erc-server-user-login user)))
+ (concat (if nick
+ nick
+ "")
+ "!"
+ (if login
+ login
+ "")
+ "@"
+ (if host
+ host
+ ""))))
+
+(defun erc-list-match (lst str)
+ "Return non-nil if any regexp in LST matches STR."
+ (memq nil (mapcar (lambda (regexp)
+ (not (string-match regexp str)))
+ lst)))
+
+;; other "toggles"
+
+(defun erc-toggle-ctcp-autoresponse (&optional arg)
+ "Toggle automatic CTCP replies (like VERSION and PING).
+
+If ARG is positive, turns CTCP replies on.
+
+If ARG is non-nil and not positive, turns CTCP replies off."
+ (interactive "P")
+ (cond ((and (numberp arg) (> arg 0))
+ (setq erc-disable-ctcp-replies t))
+ (arg (setq erc-disable-ctcp-replies nil))
+ (t (setq erc-disable-ctcp-replies (not erc-disable-ctcp-replies))))
+ (message "ERC CTCP replies are %s" (if erc-disable-ctcp-replies "OFF" "ON")))
+
+(defun erc-toggle-flood-control (&optional arg)
+ "Toggle use of flood control on sent messages.
+
+If ARG is non-nil, use flood control.
+If ARG is nil, do not use flood control.
+
+See `erc-server-flood-margin' for an explanation of the available
+flood control parameters."
+ (interactive "P")
+ (setq erc-flood-protect arg)
+ (message "ERC flood control is %s"
+ (cond (erc-flood-protect "ON")
+ (t "OFF"))))
+
+;; Some useful channel and nick commands for fast key bindings
+
+(defun erc-invite-only-mode (&optional arg)
+ "Turn on the invite only mode (+i) for the current channel.
+
+If ARG is non-nil, turn this mode off (-i).
+
+This command is sent even if excess flood is detected."
+ (interactive "P")
+ (erc-set-active-buffer (current-buffer))
+ (let ((tgt (erc-default-target))
+ (erc-force-send t))
+ (cond ((or (not tgt) (not (erc-channel-p tgt)))
+ (erc-display-message nil 'error (current-buffer) 'no-target))
+ (arg (erc-load-irc-script-lines (list (concat "/mode " tgt " -i"))
+ t))
+ (t (erc-load-irc-script-lines (list (concat "/mode " tgt " +i"))
+ t)))))
+
+(defun erc-get-channel-mode-from-keypress (key)
+ "Read a key sequence and call the corresponding channel mode function.
+After doing C-c C-o type in a channel mode letter.
+
+C-g means quit.
+RET let's you type more than one mode at a time.
+If \"l\" is pressed, `erc-set-channel-limit' gets called.
+If \"k\" is pressed, `erc-set-channel-key' gets called.
+Anything else will be sent to `erc-toggle-channel-mode'."
+ (interactive "kChannel mode (RET to set more than one): ")
+ (when (featurep 'xemacs)
+ (setq key (char-to-string (event-to-character (aref key 0)))))
+ (cond ((equal key "\C-g")
+ (keyboard-quit))
+ ((equal key "\C-m")
+ (erc-insert-mode-command))
+ ((equal key "l")
+ (call-interactively 'erc-set-channel-limit))
+ ((equal key "k")
+ (call-interactively 'erc-set-channel-key))
+ (t (erc-toggle-channel-mode key))))
+
+(defun erc-toggle-channel-mode (mode &optional channel)
+ "Toggle channel MODE.
+
+If CHANNEL is non-nil, toggle MODE for that channel, otherwise use
+`erc-default-target'."
+ (interactive "P")
+ (erc-set-active-buffer (current-buffer))
+ (let ((tgt (or channel (erc-default-target)))
+ (erc-force-send t))
+ (cond ((or (null tgt) (null (erc-channel-p tgt)))
+ (erc-display-message nil 'error 'active 'no-target))
+ ((member mode erc-channel-modes)
+ (erc-log (format "%s: Toggle mode %s OFF" tgt mode))
+ (message "Toggle channel mode %s OFF" mode)
+ (erc-server-send (format "MODE %s -%s" tgt mode)))
+ (t (erc-log (format "%s: Toggle channel mode %s ON" tgt mode))
+ (message "Toggle channel mode %s ON" mode)
+ (erc-server-send (format "MODE %s +%s" tgt mode))))))
+
+(defun erc-insert-mode-command ()
+ "Insert the line \"/mode <current target> \" at `point'."
+ (interactive)
+ (let ((tgt (erc-default-target)))
+ (if tgt (insert (concat "/mode " tgt " "))
+ (erc-display-message nil 'error (current-buffer) 'no-target))))
+
+(defun erc-channel-names ()
+ "Run \"/names #channel\" in the current channel."
+ (interactive)
+ (erc-set-active-buffer (current-buffer))
+ (let ((tgt (erc-default-target)))
+ (if tgt (erc-load-irc-script-lines (list (concat "/names " tgt)))
+ (erc-display-message nil 'error (current-buffer) 'no-target))))
+
+(defun erc-remove-text-properties-region (start end &optional object)
+ "Clears the region (START,END) in OBJECT from all colors, etc."
+ (interactive "r")
+ (save-excursion
+ (let ((inhibit-read-only t))
+ (set-text-properties start end nil object))))
+
+;; script execution and startup
+
+(defun erc-find-file (file &optional path)
+ "Search for a FILE in the filesystem.
+First the `default-directory' is searched for FILE, then any directories
+specified in the list PATH.
+
+If FILE is found, return the path to it."
+ (let ((filepath file))
+ (if (file-readable-p filepath) filepath
+ (progn
+ (while (and path
+ (progn (setq filepath (expand-file-name file (car path)))
+ (not (file-readable-p filepath))))
+ (setq path (cdr path)))
+ (if path filepath nil)))))
+
+(defun erc-select-startup-file ()
+ "Select an ERC startup file.
+See also `erc-startup-file-list'."
+ (let ((l erc-startup-file-list)
+ (f nil))
+ (while (and (not f) l)
+ (if (file-readable-p (car l))
+ (setq f (car l)))
+ (setq l (cdr l)))
+ f))
+
+(defun erc-find-script-file (file)
+ "Search for FILE in `default-directory', and any in `erc-script-path'."
+ (erc-find-file file erc-script-path))
+
+(defun erc-load-script (file)
+ "Load a script from FILE.
+
+FILE must be the full name, it is not searched in the
+`erc-script-path'. If the filename ends with `.el', then load it
+as a emacs-lisp program. Otherwise, treat it as a regular IRC
+script"
+ (erc-log (concat "erc-load-script: " file))
+ (cond
+ ((string-match "\\.el$" file)
+ (load file))
+ (t
+ (erc-load-irc-script file))))
+
+(defun erc-process-script-line (line &optional args)
+ "Process an IRC script LINE.
+
+Does script-specific substitutions (script arguments, current nick,
+server, etc.) in LINE and returns it.
+
+Substitutions are: %C and %c = current target (channel or nick),
+%S %s = current server, %N %n = my current nick, and %x is x verbatim,
+where x is any other character;
+$* = the entire argument string, $1 = the first argument, $2 = the second,
+end so on."
+ (if (not args) (setq args ""))
+ (let* ((arg-esc-regexp "\\(\\$\\(\\*\\|[1-9][0-9]*\\)\\)\\([^0-9]\\|$\\)")
+ (percent-regexp "\\(%.\\)")
+ (esc-regexp (concat arg-esc-regexp "\\|" percent-regexp))
+ (tgt (erc-default-target))
+ (server (and (boundp 'erc-session-server) erc-session-server))
+ (nick (erc-current-nick))
+ (res "")
+ (tmp nil)
+ (arg-list nil)
+ (arg-num 0))
+ (if (not tgt) (setq tgt ""))
+ (if (not server) (setq server ""))
+ (if (not nick) (setq nick ""))
+ ;; First, compute the argument list
+ (setq tmp args)
+ (while (string-match "^\\s-*\\(\\S-+\\)\\(\\s-+.*$\\|$\\)" tmp)
+ (setq arg-list (cons (match-string 1 tmp) arg-list))
+ (setq tmp (match-string 2 tmp)))
+ (setq arg-list (nreverse arg-list))
+ (setq arg-num (length arg-list))
+ ;; now do the substitution
+ (setq tmp (string-match esc-regexp line))
+ (while tmp
+ ;;(message "beginning of while: tmp=%S" tmp)
+ (let* ((hd (substring line 0 tmp))
+ (esc "")
+ (subst "")
+ (tail (substring line tmp)))
+ (cond ((string-match (concat "^" arg-esc-regexp) tail)
+ (setq esc (match-string 1 tail))
+ (setq tail (substring tail (match-end 1))))
+ ((string-match (concat "^" percent-regexp) tail)
+ (setq esc (match-string 1 tail))
+ (setq tail (substring tail (match-end 1)))))
+ ;;(message "hd=%S, esc=%S, tail=%S, arg-num=%S" hd esc tail arg-num)
+ (setq res (concat res hd))
+ (setq subst
+ (cond ((string= esc "") "")
+ ((string-match "^\\$\\*$" esc) args)
+ ((string-match "^\\$\\([0-9]+\\)$" esc)
+ (let ((n (string-to-number (match-string 1 esc))))
+ (message "n = %S, integerp(n)=%S" n (integerp n))
+ (if (<= n arg-num) (nth (1- n) arg-list) "")))
+ ((string-match "^%[Cc]$" esc) tgt)
+ ((string-match "^%[Ss]$" esc) server)
+ ((string-match "^%[Nn]$" esc) nick)
+ ((string-match "^%\\(.\\)$" esc) (match-string 1 esc))
+ (t (erc-log (format "BUG in erc-process-script-line: bad escape sequence: %S\n" esc))
+ (message "BUG IN ERC: esc=%S" esc)
+ "")))
+ (setq line tail)
+ (setq tmp (string-match esc-regexp line))
+ (setq res (concat res subst))
+ ;;(message "end of while: line=%S, res=%S, tmp=%S" line res tmp)
+ ))
+ (setq res (concat res line))
+ res))
+
+(defun erc-load-irc-script (file &optional force)
+ "Load an IRC script from FILE."
+ (erc-log (concat "erc-load-script: " file))
+ (let ((str (with-temp-buffer
+ (insert-file-contents file)
+ (buffer-string))))
+ (erc-load-irc-script-lines (erc-split-multiline-safe str) force)))
+
+(defun erc-load-irc-script-lines (lines &optional force noexpand)
+ "Load IRC script LINES (a list of strings).
+
+If optional NOEXPAND is non-nil, do not expand script-specific
+sequences, process the lines verbatim. Use this for multiline
+user input."
+ (let* ((cb (current-buffer))
+ (pnt (point))
+ (s "")
+ (sp (or (erc-command-indicator) (erc-prompt)))
+ (args (and (boundp 'erc-script-args) erc-script-args)))
+ (if (and args (string-match "^ " args))
+ (setq args (substring args 1)))
+ ;; prepare the prompt string for echo
+ (erc-put-text-property 0 (length sp)
+ 'face 'erc-command-indicator-face sp)
+ (while lines
+ (setq s (car lines))
+ (erc-log (concat "erc-load-script: CMD: " s))
+ (unless (string-match "^\\s-*$" s)
+ (let ((line (if noexpand s (erc-process-script-line s args))))
+ (if (and (erc-process-input-line line force)
+ erc-script-echo)
+ (progn
+ (erc-put-text-property 0 (length line)
+ 'face 'erc-input-face line)
+ (erc-display-line (concat sp line) cb)))))
+ (setq lines (cdr lines)))))
+
+;; authentication
+
+(defun erc-login ()
+ "Perform user authentication at the IRC server."
+ (erc-log (format "login: nick: %s, user: %s %s %s :%s"
+ (erc-current-nick)
+ (user-login-name)
+ (system-name)
+ erc-session-server
+ erc-session-user-full-name))
+ (if erc-session-password
+ (erc-server-send (format "PASS %s" erc-session-password))
+ (message "Logging in without password"))
+ (erc-server-send (format "NICK %s" (erc-current-nick)))
+ (erc-server-send
+ (format "USER %s %s %s :%s"
+ ;; hacked - S.B.
+ (if erc-anonymous-login erc-email-userid (user-login-name))
+ "0" "*"
+ erc-session-user-full-name))
+ (erc-update-mode-line))
+
+;; connection properties' heuristics
+
+(defun erc-determine-parameters (&optional server port nick name)
+ "Determine the connection and authentication parameters.
+Sets the buffer local variables:
+
+- erc-session-server
+- erc-session-port
+- erc-session-full-name
+- erc-server-current-nick"
+ (setq erc-session-server (erc-compute-server server)
+ erc-session-port (or port erc-default-port)
+ erc-session-user-full-name (erc-compute-full-name name))
+ (erc-set-current-nick (erc-compute-nick nick)))
+
+(defun erc-compute-server (&optional server)
+ "Return an IRC server name.
+
+Tries a number of increasingly more default methods until a non-nil value is
+found:
+
+- SERVER
+- `erc-server'
+- The value of the IRCSERVER environment variable
+- `erc-default-server'."
+ (or server
+ erc-server
+ (getenv "IRCSERVER")
+ erc-default-server))
+
+(defun erc-compute-nick (&optional nick)
+ "Return user's NICK.
+
+Tries a number of increasingly more default methods until a non-nil value is
+found:
+
+- NICK
+- `erc-nick'
+- The value of the IRCNICK environment variable
+- via the function `user-login-name'."
+ (or nick
+ (if (consp erc-nick) (car erc-nick) erc-nick)
+ (getenv "IRCNICK")
+ (user-login-name)))
+
+
+(defun erc-compute-full-name (&optional full-name)
+ "Return user's FULL-NAME.
+
+Tries a number of increasingly more default methods until a non-nil value is
+found:
+
+- FULL-NAME
+- `erc-user-full-name'
+- The value of the IRCNAME environment variable
+- via the function `user-full-name'."
+ (or full-name
+ erc-user-full-name
+ (getenv "IRCNAME")
+ (if erc-anonymous-login "unknown" nil)
+ (user-full-name)))
+
+(defun erc-compute-port (&optional port)
+ "Return a port for an IRC server.
+
+Tries a number of increasingly more default methods until a non-nil
+value is found:
+
+- PORT
+- \"ircd\"."
+ (or port erc-port "ircd"))
+
+;; time routines
+
+(defun erc-string-to-emacs-time (string)
+ "Convert the long number represented by STRING into an Emacs format.
+Returns a list of the form (HIGH LOW), compatible with Emacs time format."
+ (let* ((n (string-to-number (concat string ".0"))))
+ (list (truncate (/ n 65536))
+ (truncate (mod n 65536)))))
+
+(defun erc-emacs-time-to-erc-time (time)
+ "Convert Emacs TIME to a number of seconds since the epoch."
+ (when time
+ (+ (* (nth 0 time) 65536.0) (nth 1 time))))
+; (round (+ (* (nth 0 tm) 65536.0) (nth 1 tm))))
+
+(defun erc-current-time ()
+ "Return the `current-time' as a number of seconds since the epoch.
+
+See also `erc-emacs-time-to-erc-time'."
+ (erc-emacs-time-to-erc-time (current-time)))
+
+(defun erc-time-diff (t1 t2)
+ "Return the time difference in seconds between T1 and T2."
+ (abs (- t2 t1)))
+
+(defun erc-time-gt (t1 t2)
+ "Check whether T1 > T2."
+ (> t1 t2))
+
+(defun erc-sec-to-time (ns)
+ "Convert NS to a time string HH:MM.SS."
+ (setq ns (truncate ns))
+ (format "%02d:%02d.%02d"
+ (/ ns 3600)
+ (/ (% ns 3600) 60)
+ (% ns 60)))
+
+(defun erc-seconds-to-string (seconds)
+ "Convert a number of SECONDS into an English phrase."
+ (let (days hours minutes format-args output)
+ (setq days (/ seconds 86400)
+ seconds (% seconds 86400)
+ hours (/ seconds 3600)
+ seconds (% seconds 3600)
+ minutes (/ seconds 60)
+ seconds (% seconds 60)
+ format-args (if (> days 0)
+ `("%d days, %d hours, %d minutes, %d seconds"
+ ,days ,hours ,minutes ,seconds)
+ (if (> hours 0)
+ `("%d hours, %d minutes, %d seconds"
+ ,hours ,minutes ,seconds)
+ (if (> minutes 0)
+ `("%d minutes, %d seconds" ,minutes ,seconds)
+ `("%d seconds" ,seconds))))
+ output (apply 'format format-args))
+ ;; Change all "1 units" to "1 unit".
+ (while (string-match "\\([^0-9]\\|^\\)1 \\S-+\\(s\\)" output)
+ (setq output (erc-replace-match-subexpression-in-string
+ "" output (match-string 2 output) 2 (match-beginning 2))))
+ output))
+
+
+;; info
+
+(defconst erc-clientinfo-alist
+ '(("ACTION" . "is used to inform about one's current activity")
+ ("CLIENTINFO" . "gives help on CTCP commands supported by client")
+ ("ECHO" . "echoes its arguments back")
+ ("FINGER" . "shows user's name, location, and idle time")
+ ("PING" . "measures delay between peers")
+ ("TIME" . "shows client-side time")
+ ("USERINFO" . "shows information provided by a user")
+ ("VERSION" . "shows client type and version"))
+ "Alist of CTCP CLIENTINFO for ERC commands.")
+
+(defun erc-client-info (s)
+ "Return CTCP CLIENTINFO on command S.
+If S is NIL or an empty string then return general CLIENTINFO"
+ (if (or (not s) (string= s ""))
+ (concat
+ (apply #'concat
+ (mapcar (lambda (e)
+ (concat (car e) " "))
+ erc-clientinfo-alist))
+ ": use CLIENTINFO <COMMAND> to get more specific information")
+ (let ((h (assoc (upcase s) erc-clientinfo-alist)))
+ (if h
+ (concat s " " (cdr h))
+ (concat s ": unknown command")))))
+
+;; Hook functions
+
+(defun erc-directory-writable-p (dir)
+ "Determine whether DIR is a writable directory.
+If it doesn't exist, create it."
+ (unless (file-attributes dir) (make-directory dir))
+ (or (file-accessible-directory-p dir) (error "Cannot access %s" dir)))
+
+(defun erc-kill-query-buffers (process)
+ "Kill all buffers of PROCESS."
+ ;; here, we only want to match the channel buffers, to avoid
+ ;; "selecting killed buffers" b0rkage.
+ (erc-with-all-buffers-of-server process
+ (lambda ()
+ (not (erc-server-buffer-p)))
+ (kill-buffer (current-buffer))))
+
+(defun erc-nick-at-point ()
+ "Give information about the nickname at `point'.
+
+If called interactively, give a human readable message in the
+minibuffer. If called programatically, return the corresponding
+entry of `channel-members'."
+ (interactive)
+ (require 'thingatpt)
+ (let* ((word (word-at-point))
+ (channel-data (erc-get-channel-user word))
+ (cuser (cdr channel-data))
+ (user (if channel-data
+ (car channel-data)
+ (erc-get-server-user word)))
+ host login full-name info nick op voice)
+ (when user
+ (setq nick (erc-server-user-nickname user)
+ host (erc-server-user-host user)
+ login (erc-server-user-login user)
+ full-name (erc-server-user-full-name user)
+ info (erc-server-user-info user))
+ (if cuser
+ (setq op (erc-channel-user-op cuser)
+ voice (erc-channel-user-voice cuser)))
+ (if (interactive-p)
+ (message "%s is %s@%s%s%s"
+ nick login host
+ (if full-name (format " (%s)" full-name) "")
+ (if (or op voice)
+ (format " and is +%s%s on %s"
+ (if op "o" "")
+ (if voice "v" "")
+ (erc-default-target))
+ ""))
+ user))))
+
+(defun erc-away-p ()
+ "Return t if the current ERC process is set away."
+ (save-excursion
+ (and (erc-server-buffer-live-p)
+ (set-buffer (process-buffer erc-server-process))
+ erc-away)))
+
+;; Mode line handling
+
+(defcustom erc-mode-line-format "%s %a"
+ "A string to be formatted and shown in the mode-line in `erc-mode'.
+
+The string is formatted using `format-spec' and the result is set as the value
+of `mode-line-buffer-identification'.
+
+The following characters are replaced:
+%a: String indicating away status or \"\" if you are not away
+%m: The modes of the channel
+%n: The current nick name
+%o: The topic of the channel
+%p: The session port
+%t: The name of the target (channel, nickname, or servername:port)
+%s: In the server-buffer, this gets filled with the value of
+ `erc-server-announced-name', in a channel, the value of
+ (erc-default-target) also get concatenated."
+ :group 'erc-mode-line-and-header
+ :type 'string)
+
+(defcustom erc-header-line-format "[IRC] %n on %t %m %o"
+ "A string to be formatted and shown in the header-line in `erc-mode'.
+Only used in Emacs 21.
+
+See `erc-mode-line-format' for which characters are can be used."
+ :group 'erc-mode-line-and-header
+ :type 'string)
+
+(defcustom erc-header-line-uses-help-echo-p t
+ "Show the contents of the header line in the echo area or as a tooltip
+when you move point into the header line."
+ :group 'erc-mode-line-and-header
+ :type 'boolean)
+
+(defcustom erc-show-channel-key-p t
+ "Show the the channel key in the header line."
+ :group 'erc-paranoia
+ :type 'boolean)
+
+(defcustom erc-common-server-suffixes
+ '(("openprojects.net$" . "OPN")
+ ("freenode.net$" . "OPN"))
+ "Alist of common server name suffixes.
+This variable is used in mode-line display to save screen
+real estate. Set it to nil if you want to avoid changing
+displayed hostnames."
+ :group 'erc-mode-line-and-header
+ :type 'alist)
+
+(defcustom erc-mode-line-away-status-format
+ "(AWAY since %a %b %d %H:%M) "
+ "When you're away on a server, this is shown in the mode line.
+This should be a string with substitution variables recognized by
+format-time-message."
+ :group 'erc-mode-line-and-header
+ :type 'string)
+
+(defun erc-shorten-server-name (server-name)
+ "Shorten SERVER-NAME according to `erc-common-server-suffixes'."
+ (if (stringp server-name)
+ (with-temp-buffer
+ (insert server-name)
+ (let ((alist erc-common-server-suffixes))
+ (while alist
+ (goto-char (point-min))
+ (if (re-search-forward (caar alist) nil t)
+ (replace-match (cdar alist)))
+ (setq alist (cdr alist))))
+ (buffer-string))))
+
+(defun erc-format-target ()
+ "Return the name of the target (channel or nickname or servername:port)."
+ (let ((target (erc-default-target)))
+ (or target
+ (concat (erc-shorten-server-name
+ (or erc-server-announced-name
+ erc-session-server))
+ ":" (erc-port-to-string erc-session-port)))))
+
+(defun erc-format-target-and/or-server ()
+ "Return the server name or the current target and server name combined."
+ (let ((server-name (erc-shorten-server-name
+ (or erc-server-announced-name
+ erc-session-server))))
+ (cond ((erc-default-target)
+ (concat (erc-string-no-properties (erc-default-target))
+ "@" server-name))
+ (server-name server-name)
+ (t (buffer-name (current-buffer))))))
+
+(defun erc-format-away-status ()
+ "Return a formatted `erc-mode-line-away-status-format'
+if `erc-away' is non-nil."
+ (let ((a (when (erc-server-buffer-live-p)
+ (with-current-buffer (process-buffer erc-server-process)
+ erc-away))))
+ (if a
+ (format-time-string erc-mode-line-away-status-format a)
+ "")))
+
+(defun erc-format-channel-modes ()
+ "Return the current channel's modes and the estimated lag."
+ (let ((lag (when (erc-server-buffer-live-p)
+ (with-current-buffer (process-buffer erc-server-process)
+ erc-server-lag))))
+ (concat (apply 'concat
+ "(+" erc-channel-modes)
+ (cond ((and erc-channel-user-limit erc-channel-key)
+ (if erc-show-channel-key-p
+ (format "lk %.0f %s" erc-channel-user-limit
+ erc-channel-key)
+ (format "kl %.0f" erc-channel-user-limit)))
+ (erc-channel-user-limit
+ ;; Emacs has no bignums
+ (format "l %.0f" erc-channel-user-limit))
+ (erc-channel-key
+ (if erc-show-channel-key-p
+ (format "k %s" erc-channel-key)
+ "k"))
+ (t ""))
+ (if lag (format ",lag:%.0f" lag) "")
+ ")")))
+
+(defun erc-update-mode-line-buffer (buffer)
+ "Update the mode line in a single ERC buffer BUFFER."
+ (with-current-buffer buffer
+ (let ((spec (format-spec-make
+ ?a (erc-format-away-status)
+ ?m (erc-format-channel-modes)
+ ?n (or (erc-current-nick) "")
+ ?o (erc-controls-strip erc-channel-topic)
+ ?p (erc-port-to-string erc-session-port)
+ ?s (erc-format-target-and/or-server)
+ ?t (erc-format-target)))
+ (process-status (cond ((and (erc-server-process-alive)
+ (not erc-server-connected))
+ ":connecting")
+ ((erc-server-process-alive)
+ "")
+ (t
+ ": CLOSED"))))
+ (cond ((featurep 'xemacs)
+ (setq modeline-buffer-identification
+ (list (format-spec erc-mode-line-format spec)))
+ (setq modeline-process (list process-status)))
+ (t
+ (setq mode-line-buffer-identification
+ (list (format-spec erc-mode-line-format spec)))
+ (setq mode-line-process (list process-status))))
+ (when (boundp 'header-line-format)
+ (let ((header (if erc-header-line-format
+ (format-spec erc-header-line-format spec)
+ nil)))
+ (cond ((null header)
+ (setq header-line-format nil))
+ (erc-header-line-uses-help-echo-p
+ (let ((help-echo (with-temp-buffer
+ (insert header)
+ (fill-region (point-min) (point-max))
+ (buffer-string))))
+ (setq header-line-format
+ (erc-replace-regexp-in-string
+ "%"
+ "%%"
+ (erc-propertize header 'help-echo help-echo)))))
+ (t (setq header-line-format header))))))
+ (if (featurep 'xemacs)
+ (redraw-modeline)
+ (force-mode-line-update))))
+
+(defun erc-update-mode-line (&optional buffer)
+ "Update the mode line in BUFFER.
+
+If BUFFER is nil, update the mode line in all ERC buffers."
+ (if (and buffer (bufferp buffer))
+ (erc-update-mode-line-buffer buffer)
+ (dolist (buf (erc-buffer-list))
+ (when (buffer-live-p buf)
+ (erc-update-mode-line-buffer buf)))))
+
+;; Miscellaneous
+
+(defun erc-port-to-string (p)
+ "Convert port P to a string.
+P may be an integer or a service name."
+ (if (integerp p)
+ (int-to-string p)
+ p))
+
+(defun erc-string-to-port (s)
+ "Convert string S to either an integer port number or a service name."
+ (let ((n (string-to-number s)))
+ (if (= n 0)
+ s
+ n)))
+
+(defun erc-version (&optional here)
+ "Show the version number of ERC in the minibuffer.
+If optional argument HERE is non-nil, insert version number at point."
+ (interactive "P")
+ (let ((version-string
+ (format "ERC %s" erc-version-string)))
+ (if here
+ (insert version-string)
+ (if (interactive-p)
+ (message "%s" version-string)
+ version-string))))
+
+(defun erc-version-modules (&optional here)
+ "Show the version numbers of all loaded ERC modules in the minibuffer.
+If optional argument HERE is non-nil, insert version number at point."
+ (interactive "P")
+ (let ((version-string
+ (mapconcat 'identity
+ (let (versions (case-fold-search nil))
+ (dolist (var (apropos-internal "^erc-.*version$"))
+ (when (and (boundp var)
+ (stringp (symbol-value var)))
+ (setq versions (cons (format "%S: %s"
+ var (symbol-value var))
+ versions))))
+ versions) ", ")))
+ (if here
+ (insert version-string)
+ (if (interactive-p)
+ (message "%s" version-string)
+ version-string))))
+
+(defun erc-modes (&optional here)
+ "Show the active ERC modes in the minibuffer.
+If optional argument HERE is non-nil, insert version number at point."
+ (interactive "P")
+ (let ((string
+ (mapconcat 'identity
+ (let (modes (case-fold-search nil))
+ (dolist (var (apropos-internal "^erc-.*mode$"))
+ (when (and (boundp var)
+ (symbol-value var))
+ (setq modes (cons (symbol-name var)
+ modes))))
+ modes)
+ ", ")))
+ (if here
+ (insert string)
+ (if (interactive-p)
+ (message "%s" string)
+ string))))
+
+(defun erc-latest-version ()
+ "Retrieve the latest erc.el version from CVS."
+ (interactive)
+ (if (ignore-errors (require 'url))
+ (progn
+ (switch-to-buffer (get-buffer-create "*erc.el latest version*"))
+ (delete-region (point-min) (point-max))
+ (kill-all-local-variables)
+ (url-insert-file-contents (concat
+ "http://cvs.sourceforge.net/viewcvs.py/"
+ "*checkout*/erc/erc/erc.el?content-type"
+ "=text%2Fplain&rev=HEAD"))
+ (emacs-lisp-mode)
+ (current-buffer))
+ (error "URL needs to be installed")))
+
+(defun erc-ediff-latest-version ()
+ "Ediff your installed erc.el with the latest CVS version.
+See also `erc-latest-version'."
+ (interactive)
+ (let ((current (locate-library "erc.el")))
+ (if current
+ (ediff-buffers (find-file current)
+ (erc-latest-version))
+ (error "You do not appear to have the uncompiled erc.el file"))))
+
+(defun erc-trim-string (s)
+ "Trim leading and trailing spaces off S."
+ (cond
+ ((not (stringp s)) nil)
+ ((string-match "^\\s-*$" s)
+ "")
+ ((string-match "^\\s-*\\(.*\\S-\\)\\s-*$" s)
+ (match-string 1 s))
+ (t
+ s)))
+
+(defun erc-arrange-session-in-multiple-windows ()
+ "Open a window for every non-server buffer related to `erc-session-server'.
+
+All windows are opened in the current frame."
+ (interactive)
+ (unless (boundp 'erc-server-process)
+ (error "No erc-process found in current buffer"))
+ (let ((bufs (erc-buffer-list nil erc-server-process)))
+ (when bufs
+ (delete-other-windows)
+ (switch-to-buffer (car bufs))
+ (setq bufs (cdr bufs))
+ (while bufs
+ (split-window)
+ (switch-to-buffer-other-window (car bufs))
+ (setq bufs (cdr bufs))
+ (balance-windows)))))
+
+(defun erc-popup-input-buffer ()
+ "Provide a input buffer."
+ (interactive)
+ (let ((buffer-name (generate-new-buffer-name "*ERC input*"))
+ (mode (intern
+ (completing-read
+ "Mode: "
+ (mapcar (lambda (e)
+ (list (symbol-name e)))
+ (apropos-internal "-mode$" 'commandp))
+ nil t))))
+ (pop-to-buffer (make-indirect-buffer (current-buffer) buffer-name))
+ (funcall mode)
+ (narrow-to-region (point) (point))
+ (shrink-window-if-larger-than-buffer)))
+
+;;; Message catalog
+
+(defun erc-make-message-variable-name (catalog entry)
+ "Create a variable name corresponding to CATALOG's ENTRY."
+ (intern (concat "erc-message-"
+ (symbol-name catalog) "-" (symbol-name entry))))
+
+(defun erc-define-catalog-entry (catalog entry format-spec)
+ "Set CATALOG's ENTRY to FORMAT-SPEC."
+ (set (erc-make-message-variable-name catalog entry)
+ format-spec))
+
+(defun erc-define-catalog (catalog entries)
+ "Define a CATALOG according to ENTRIES."
+ (dolist (entry entries)
+ (erc-define-catalog-entry catalog (car entry) (cdr entry))))
+
+(erc-define-catalog
+ 'english
+ '((bad-ping-response . "Unexpected PING response from %n (time %t)")
+ (bad-syntax . "Error occurred - incorrect usage?\n%c %u\n%d")
+ (incorrect-args . "Incorrect arguments. Usage:\n%c %u\n%d")
+ (cannot-find-file . "Cannot find file %f")
+ (cannot-read-file . "Cannot read file %f")
+ (connect . "Connecting to %S:%p... ")
+ (country . "%c")
+ (country-unknown . "%d: No such domain")
+ (ctcp-empty . "Illegal empty CTCP query received from %n. Ignoring.")
+ (ctcp-request . "==> CTCP request from %n (%u@%h): %r")
+ (ctcp-request-to . "==> CTCP request from %n (%u@%h) to %t: %r")
+ (ctcp-too-many . "Too many CTCP queries in single message. Ignoring")
+ (flood-ctcp-off . "FLOOD PROTECTION: Automatic CTCP responses turned off.")
+ (flood-strict-mode . "FLOOD PROTECTION: Switched to Strict Flood Control mode.")
+ (disconnected . "Connection failed! Re-establishing connection...")
+ (disconnected-noreconnect . "Connection failed! Not re-establishing connection.")
+ (login . "Logging in as \'%n\'...")
+ (nick-in-use . "%n is in use. Choose new nickname: ")
+ (nick-too-long . "WARNING: Nick length (%i) exceeds max NICKLEN(%l) defined by server")
+ (no-default-channel . "No default channel")
+ (no-invitation . "You've got no invitation")
+ (no-target . "No target")
+ (ops . "%i operator%s: %o")
+ (ops-none . "No operators in this channel.")
+ (undefined-ctcp . "Undefined CTCP query received. Silently ignored")
+ (variable-not-bound . "Variable not bound!")
+ (ACTION . "* %n %a")
+ (CTCP-CLIENTINFO . "Client info for %n: %m")
+ (CTCP-ECHO . "Echo %n: %m")
+ (CTCP-FINGER . "Finger info for %n: %m")
+ (CTCP-PING . "Ping time to %n is %t")
+ (CTCP-TIME . "Time by %n is %m")
+ (CTCP-UNKNOWN . "Unknown CTCP message from %n (%u@%h): %m")
+ (CTCP-VERSION . "Version for %n is %m")
+ (ERROR . "==> ERROR from %s: %c\n")
+ (INVITE . "%n (%u@%h) invites you to channel %c")
+ (JOIN . "%n (%u@%h) has joined channel %c")
+ (JOIN-you . "You have joined channel %c")
+ (KICK . "%n (%u@%h) has kicked %k off channel %c: %r")
+ (KICK-you . "You have been kicked off channel %c by %n (%u@%h): %r")
+ (KICK-by-you . "You have kicked %k off channel %c: %r")
+ (MODE . "%n (%u@%h) has changed mode for %t to %m")
+ (MODE-nick . "%n has changed mode for %t to %m")
+ (NICK . "%n (%u@%h) is now known as %N")
+ (NICK-you . "Your new nickname is %N")
+ (PART . erc-message-english-PART)
+ (PING . "PING from server (last: %s sec. ago)")
+ (PONG . "PONG from %h (%i second%s)")
+ (QUIT . "%n (%u@%h) has quit: %r")
+ (TOPIC . "%n (%u@%h) has set the topic for %c: \"%T\"")
+ (WALLOPS . "Wallops from %n: %m")
+ (s004 . "%s %v %U %C")
+ (s221 . "User modes for %n: %m")
+ (s252 . "%i operator(s) online")
+ (s253 . "%i unknown connection(s)")
+ (s254 . "%i channels formed")
+ (s301 . "%n is AWAY: %r")
+ (s303 . "Is online: %n")
+ (s305 . "%m")
+ (s306 . "%m")
+ (s311 . "%n is %f (%u@%h)")
+ (s312 . "%n is/was on server %s (%c)")
+ (s313 . "%n is an IRC operator")
+ (s314 . "%n was %f (%u@%h)")
+ (s317 . "%n has been idle for %i")
+ (s317-on-since . "%n has been idle for %i, on since %t")
+ (s319 . "%n is on channel(s): %c")
+ (s320 . "%n is an identified user")
+ (s321 . "Channel Users Topic")
+ (s322 . "%c [%u] %t")
+ (s324 . "%c modes: %m")
+ (s329 . "%c was created on %t")
+ (s330 . "%n %a %i")
+ (s331 . "No topic is set for %c")
+ (s332 . "Topic for %c: %T")
+ (s333 . "%c: topic set by %n, %t")
+ (s341 . "Inviting %n to channel %c")
+ (s352 . "%-11c %-10n %-4a %u@%h (%f)")
+ (s353 . "Users on %c: %u")
+ (s367 . "Ban on %b on %c set by %s on %t (Use /banlist!)")
+ (s368 . "Banlist of %c ends.")
+ (s379 . "%c: Forwarded to %f")
+ (s391 . "The time at %s is %t")
+ (s401 . "%n: No such nick/channel")
+ (s403 . "%c: No such channel")
+ (s404 . "%c: Cannot send to channel")
+ (s405 . "%c: You have joined too many channels")
+ (s406 . "%n: There was no such nickname")
+ (s412 . "No text to send")
+ (s421 . "%c: Unknown command")
+ (s431 . "No nickname given")
+ (s432 . "%n is an erroneous nickname")
+ (s442 . "%c: You're not on that channel")
+ (s445 . "SUMMON has been disabled")
+ (s446 . "USERS has been disabled")
+ (s451 . "You have not registered")
+ (s461 . "%c: not enough parameters")
+ (s462 . "Unauthorized command (already registered)")
+ (s463 . "Your host isn't among the privileged")
+ (s464 . "Password incorrect")
+ (s465 . "You are banned from this server")
+ (s474 . "You can't join %c because you're banned (+b)")
+ (s475 . "You must specify the correct channel key (+k) to join %c")
+ (s481 . "Permission Denied - You're not an IRC operator")
+ (s482 . "You need to be a channel operator of %c to do that")
+ (s483 . "You can't kill a server!")
+ (s484 . "Your connection is restricted!")
+ (s485 . "You're not the original channel operator")
+ (s491 . "No O-lines for your host")
+ (s501 . "Unknown MODE flag")
+ (s502 . "You can't change modes for other users")))
+
+(defun erc-message-english-PART (&rest args)
+ "Format a proper PART message.
+
+This function is an example on what could be done with formatting
+functions."
+ (let ((nick (cadr (memq ?n args)))
+ (user (cadr (memq ?u args)))
+ (host (cadr (memq ?h args)))
+ (channel (cadr (memq ?c args)))
+ (reason (cadr (memq ?r args))))
+ (if (string= nick (erc-current-nick))
+ (format "You have left channel %s" channel)
+ (format "%s (%s@%s) has left channel %s%s"
+ nick user host channel
+ (if (not (string= reason ""))
+ (format ": %s" reason)
+ "")))))
+
+
+(defvar erc-current-message-catalog 'english)
+(make-variable-buffer-local 'erc-current-message-catalog)
+
+(defun erc-retrieve-catalog-entry (entry &optional catalog)
+ "Retrieve ENTRY from CATALOG.
+
+If CATALOG is nil, `erc-current-message-catalog' is used.
+
+If ENTRY is nil in CATALOG, it is retrieved from the fallback,
+english, catalog."
+ (unless catalog (setq catalog erc-current-message-catalog))
+ (let ((var (erc-make-message-variable-name catalog entry)))
+ (if (boundp var)
+ (symbol-value var)
+ (when (boundp (erc-make-message-variable-name 'english entry))
+ (symbol-value (erc-make-message-variable-name 'english entry))))))
+
+(defun erc-format-message (msg &rest args)
+ "Format MSG according to ARGS.
+
+See also `format-spec'."
+ (when (eq (logand (length args) 1) 1) ; oddp
+ (error "Obscure usage of this function appeared"))
+ (let ((entry (erc-retrieve-catalog-entry msg)))
+ (when (not entry)
+ (error "No format spec for message %s" msg))
+ (when (functionp entry)
+ (setq entry (apply entry args)))
+ (format-spec entry (apply 'format-spec-make args))))
+
+;;; Various hook functions
+
+(add-hook 'kill-buffer-hook 'erc-kill-buffer-function)
+
+(defcustom erc-kill-server-hook '(erc-kill-server)
+ "*Invoked whenever a server-buffer is killed via `kill-buffer'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-kill-channel-hook '(erc-kill-channel)
+ "*Invoked whenever a channel-buffer is killed via `kill-buffer'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defcustom erc-kill-buffer-hook nil
+ "*Hook run whenever a non-server or channel buffer is killed.
+
+See also `kill-buffer'."
+ :group 'erc-hooks
+ :type 'hook)
+
+(defun erc-kill-buffer-function ()
+ "Function to call when an ERC buffer is killed.
+This function should be on `kill-buffer-hook'.
+When the current buffer is in `erc-mode', this function will run
+one of the following hooks:
+`erc-kill-server-hook' if the server buffer was killed,
+`erc-kill-channel-hook' if a channel buffer was killed,
+or `erc-kill-buffer-hook' if any other buffer."
+ (when (eq major-mode 'erc-mode)
+ (erc-remove-channel-users)
+ (cond
+ ((eq (erc-server-buffer) (current-buffer))
+ (run-hooks 'erc-kill-server-hook))
+ ((erc-channel-p (erc-default-target))
+ (run-hooks 'erc-kill-channel-hook))
+ (t
+ (run-hooks 'erc-kill-buffer-hook)))))
+
+(defun erc-kill-server ()
+ "Sends a QUIT command to the server when the server buffer is killed.
+This function should be on `erc-kill-server-hook'."
+ (when (erc-server-process-alive)
+ (setq erc-server-quitting t)
+ (erc-server-send (format "QUIT :%s" (funcall erc-quit-reason nil)))))
+
+(defun erc-kill-channel ()
+ "Sends a PART command to the server when the channel buffer is killed.
+This function should be on `erc-kill-channel-hook'."
+ (when (erc-server-process-alive)
+ (let ((tgt (erc-default-target)))
+ (erc-server-send (format "PART %s :%s" tgt
+ (funcall erc-part-reason nil))
+ nil tgt))))
+
+(provide 'erc)
+
+;;; Deprecated. We might eventually stop requiring the goodies automatically.
+;;; IMPORTANT: This require must appear _after_ the above (provide 'erc) to
+;;; avoid a recursive require error when byte-compiling the entire package.
+(require 'erc-goodies)
+
+;;; erc.el ends here
+;;
+;; Local Variables:
+;; outline-regexp: ";;+"
+;; indent-tabs-mode: t
+;; tab-width: 8
+;; End:
+
+;; arch-tag: d19587f6-627e-48c1-8d86-58595fa3eca3
diff --git a/man/ChangeLog b/man/ChangeLog
index 810fe60e3fc..209493e0391 100644
--- a/man/ChangeLog
+++ b/man/ChangeLog
@@ -1,3 +1,11 @@
+2006-01-29 Michael Olson <mwolson@gnu.org>
+
+ * makefile.w32-in ($(infodir)/erc, erc.dvi): New targets.
+
+ * Makefile.in (INFO_TARGETS, DVI_TARGETS): Add ERC.
+
+ * faq.texi (New in Emacs 22): Mention ERC.
+
2006-01-28 Luc Teirlinck <teirllm@auburn.edu>
* rcirc.texi: Capitalize dir entry for consistency with the entry
diff --git a/man/Makefile.in b/man/Makefile.in
index bf1553a173d..78e282b6563 100644
--- a/man/Makefile.in
+++ b/man/Makefile.in
@@ -42,7 +42,7 @@ INFO_TARGETS = ../info/emacs ../info/emacs-xtra ../info/ccmode ../info/cl \
../info/idlwave ../info/eudc ../info/ebrowse ../info/pcl-cvs \
../info/woman ../info/eshell ../info/org ../info/url \
../info/speedbar ../info/tramp ../info/ses ../info/smtpmail \
- ../info/flymake ../info/newsticker ../info/rcirc
+ ../info/flymake ../info/newsticker ../info/rcirc ../info/erc
DVI_TARGETS = emacs.dvi calc.dvi cc-mode.dvi cl.dvi dired-x.dvi \
ediff.dvi forms.dvi gnus.dvi message.dvi emacs-mime.dvi \
gnus.dvi message.dvi sieve.dvi pgg.dvi mh-e.dvi \
@@ -50,7 +50,7 @@ DVI_TARGETS = emacs.dvi calc.dvi cc-mode.dvi cl.dvi dired-x.dvi \
ada-mode.dvi autotype.dvi idlwave.dvi eudc.dvi ebrowse.dvi \
pcl-cvs.dvi woman.dvi eshell.dvi org.dvi url.dvi \
speedbar.dvi tramp.dvi ses.dvi smtpmail.dvi flymake.dvi \
- newsticker.dvi emacs-xtra.dvi rcirc.dvi
+ newsticker.dvi emacs-xtra.dvi rcirc.dvi erc.dvi
INFOSOURCES = info.texi
# The following rule does not work with all versions of `make'.
@@ -332,6 +332,11 @@ newsticker.dvi: newsticker.texi
rcirc.dvi: rcirc.texi
$(ENVADD) $(TEXI2DVI) ${srcdir}/rcirc.texi
+../info/erc: erc.texi
+ cd $(srcdir); $(MAKEINFO) erc.texi
+erc.dvi: erc.texi
+ $(ENVADD) $(TEXI2DVI) ${srcdir}/erc.texi
+
mostlyclean:
rm -f *.log *.cp *.fn *.ky *.pg *.vr core *.tp *.core gnustmp.*
diff --git a/man/erc.texi b/man/erc.texi
new file mode 100644
index 00000000000..d4053e5e737
--- /dev/null
+++ b/man/erc.texi
@@ -0,0 +1,624 @@
+\input texinfo
+@c %**start of header
+@setfilename ../info/erc
+@settitle ERC Manual
+@c %**end of header
+
+@dircategory Emacs
+@direntry
+* ERC: (erc). Powerful, modular, and extensible IRC client for Emacs.
+@end direntry
+
+@syncodeindex fn cp
+
+@copying
+This manual is for ERC version 5.1.
+
+Copyright @copyright{} 2005, 2006 Free Software Foundation, Inc.
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, Front-Cover texts, or Back-Cover Texts.
+@end quotation
+@end copying
+
+@titlepage
+@title ERC manual
+@subtitle a full-featured IRC client
+@subtitle for GNU Emacs and XEmacs
+
+@c The following two commands
+@c start the copyright page.
+@page
+@vskip 0pt plus 1filll
+@insertcopying
+@end titlepage
+
+@c So the toc is printed at the start
+@contents
+
+@ifnottex
+@node Top, Introduction, (dir), (dir)
+@comment node-name, next, previous, up
+@top ERC
+
+@insertcopying
+@end ifnottex
+
+@menu
+* Introduction:: What is ERC?
+* Obtaining ERC:: How to get ERC releases and development
+ versions.
+* Installation:: Compiling and installing ERC.
+* Getting Started:: Quick Start guide to using ERC.
+* Keystroke Summary:: Keystrokes used in ERC buffers.
+* Modules:: Available modules for ERC.
+* Advanced Usage:: Cool ways of using ERC.
+* Getting Help and Reporting Bugs::
+* History:: The history of ERC.
+* Concept Index:: Search for terms.
+
+@detailmenu
+ --- The Detailed Node Listing ---
+
+Obtaining ERC
+
+* Releases:: Released versions of ERC.
+* Development:: Latest unreleased development changes.
+
+@end detailmenu
+@end menu
+
+@node Introduction, Obtaining ERC, Top, Top
+@comment node-name, next, previous, up
+@chapter Introduction
+
+ERC is a powerful, modular, and extensible IRC client for Emacs.
+
+It comes with the following capabilities enabled by default.
+
+@itemize @bullet
+@item Flood control
+@item Timestamps
+@item Join channels automatically
+@item Buttonize URLs, nicknames, and other text
+@item Wrap long lines
+@item Highlight or remove IRC control characters
+@item Highlight pals, fools, and other keywords
+@item Detect netsplits
+@item Complete nicknames and commands in a programmable fashion
+@item Make displayed lines read-only
+@item Input history
+@item Track channel activity in the mode-line
+
+@end itemize
+
+@node Obtaining ERC, Installation, Introduction, Top
+@comment node-name, next, previous, up
+@chapter Obtaining ERC
+
+@menu
+* Releases:: Released versions of ERC.
+* Development:: Latest unreleased development changes.
+@end menu
+
+These sections may be skipped if you are using the version of ERC that
+comes with Emacs.
+
+@node Releases, Development, Obtaining ERC, Obtaining ERC
+@comment node-name, next, previous, up
+@section Releases
+
+Choose to install a release if you want to minimize risk.
+
+Errors are corrected in development first. User-visible changes will be
+announced on the @email{erc-help@@lists.sourceforge.net} mailing list.
+@pxref{Getting Help and Reporting Bugs}.
+
+@cindex releases, Debian package
+@cindex Debian package for ERC
+Debian users can get ERC via apt-get. The @file{erc} package is
+available in the official Debian repository.
+
+@cindex releases, from source
+Alternatively, you can download the latest release from
+@uref{http://sourceforge.net/project/showfiles.php?group_id=30118}.
+
+@node Development, , Releases, Obtaining ERC
+@comment node-name, next, previous, up
+@section Development
+@cindex development
+
+Choose the development version if you want to live on the bleeding edge
+of ERC development or try out new features before release.
+
+@subsection Using CVS
+@cindex CVS, using
+
+ERC is primarily developed using a CVS repository on sourceforge.net.
+To check out a copy of the latest changes, do the following.
+
+@example
+cvs -d:pserver:anonymous@@cvs.sourceforge.net:/cvsroot/erc login
+cvs -z3 -d:pserver:anonymous@@cvs.sourceforge.net:/cvsroot/erc co -P erc
+@end example
+
+@cindex CVS snapshot
+Alternatively, the latest CVS snapshot may be downloaded in the
+following forms.
+
+@itemize @bullet
+@item http://mwolson.org/static/dist/erc-latest.tar.gz
+@item http://mwolson.org/static/dist/erc-latest.zip
+@end itemize
+
+@subsection Using the GNU Arch Revision Control System
+@cindex arch revision control system, using
+The Arch revision control system allows you to retrieve previous
+versions and select specific features and bug fixes.
+
+Michael Olson maintains an official Arch branch for ERC which stays
+current with the CVS repository for ERC. If you would like to
+contribute to ERC development, and would prefer to use a modern Revision
+Control System, feel free to make your own branch.
+
+If you are new to Arch, you might find this tutorial helpful:
+@uref{http://www.mwolson.org/projects/ArchTutorial.html}.
+
+Downloading ERC with Arch and staying up-to-date involves the following
+steps.
+
+@enumerate
+@item Install arch
+
+@itemize @bullet
+@item Debian: @kbd{apt-get install tla}.
+@item Other distributions: see @uref{ftp://ftp.gnu.org/gnu/gnu-arch/}.
+@end itemize
+
+@item Register the archive.
+@example
+tla register-archive -f http://www.mwolson.org/archives/2006
+@end example
+
+@item Download the ERC source code.
+@example
+# Download ERC into the @file{erc} directory.
+tla get mwolson@@gnu.org--2006/erc--cvs--0 erc
+@end example
+
+@item List upstream changes that are missing from your local copy.
+Do this whenever you want to see whether new changes have been committed
+to ERC.
+
+@example
+# Change to the source directory you are interested in.
+cd erc/
+
+# Display the summary of changes
+tla missing --summary
+@end example
+
+@cindex updating ERC with Arch
+@item Update to the latest version by replaying missing changes.
+@example
+cd erc
+tla replay
+@end example
+
+@end enumerate
+
+There are other ways to interact with the ERC archive.
+
+@itemize
+@item Browse arch repository: @uref{http://www.mwolson.org/archives/}
+@item Latest development snapshot: @uref{http://www.mwolson.org/static/dist/erc-latest.tar.gz}
+@end itemize
+
+The latest development snapshot will be kept up-to-date since it is
+updated at the same time as the Arch repository.
+
+
+@node Installation, Getting Started, Obtaining ERC, Top
+@comment node-name, next, previous, up
+@chapter Installation
+
+ERC may be compiled and installed on your machine.
+
+This section may be skipped if you are using the version of ERC that
+comes with Emacs.
+
+@subsubheading Compilation
+
+This is an optional step, since Emacs Lisp source code does not
+necessarily have to be byte-compiled. It will yield a speed increase,
+though.
+
+A working copy of Emacs or XEmacs is needed in order to compile ERC. By
+default, the program that is installed with the name @command{emacs}
+will be used.
+
+If you want to use the @command{xemacs} binary to perform the
+compilation, you would need to edit @file{Makefile} in the top-level
+directory as follows. You can put either a full path to an Emacs or
+XEmacs binary or just the command name, as long as it is in the
+@env{PATH}.
+
+@example
+EMACS = xemacs
+SITEFLAG = -no-site-file
+@end example
+
+Running @code{make} should compile the ERC source files in the
+@file{lisp} directory.
+
+@subsubheading Installation
+
+ERC may be installed into your file hierarchy by doing the following.
+
+Edit the @file{Makefile} file so that @env{ELISPDIR} points to where you
+want the source and compiled ERC files to be installed and
+@env{INFODIR} indicates where to put the ERC manual. Of course, you
+will want to edit @env{EMACS} and @env{SITEFLAG} as shown in the
+Compilation section if you are using XEmacs.
+
+If you are installing ERC on a Debian system, you might want to change
+the value of @env{INSTALLINFO} as specified in @file{Makefile}.
+
+Run @code{make} as a normal user.
+
+Run @code{make install} as the root user if you have chosen installation
+locations that require this.
+
+
+@node Getting Started, Keystroke Summary, Installation, Top
+@comment node-name, next, previous, up
+@chapter Getting Started
+@cindex settings
+
+@c PRE5_2: Mention .ercrc.el
+
+To use ERC, add the directory containing its files to your
+@code{load-path} variable, in your @file{.emacs} file. Then, load ERC
+itself along with any extra modules you desire. An example follows.
+
+@lisp
+(require 'erc)
+
+(require 'erc-spelling)
+@end lisp
+
+Once this is loaded, the command @kbd{M-x erc-select} will start ERC and
+prompt for the server to connect to.
+
+@c PRE5_2: Sample session, including:
+@c - connect to Freenode
+@c - /join #emacs
+@c - see messages flying past, point out topic lines, messages, channel
+@c members
+@c - identifying your nick with NickServ (most IRC servers have this)
+@c - talking to the channel
+@c - open a /query buffer to talk to someone (must identify first in
+@c FreeNode)
+
+
+@node Keystroke Summary, Modules, Getting Started, Top
+@comment node-name, next, previous, up
+@chapter Keys Used in ERC
+@cindex keystrokes
+
+This is a summary of keystrokes available in every ERC buffer.
+
+@table @kbd
+
+@item C-a or <home> (`erc-bol')
+Go to beginning of line or end of prompt.
+
+@item RET (`erc-send-current-line')
+Send the current line
+
+@item TAB (`erc-complete-word')
+If at prompt, complete the current word.
+Otherwise, move to the next link or button.
+
+@item M-TAB (`ispell-complete-word')
+Complete the given word, using ispell.
+
+@item C-c C-a (`erc-bol')
+Go to beginning of line or end of prompt.
+
+@item C-c C-b (`erc-iswitchb')
+Use `iswitchb-read-buffer' to prompt for a ERC buffer to switch to.
+
+@item C-c C-c (`erc-toggle-interpret-controls')
+Toggle interpretation of control sequences in messages.
+
+@item C-c C-d (`erc-input-action')
+Interactively input a user action and send it to IRC.
+
+@item C-c C-e (`erc-toggle-ctcp-autoresponse')
+Toggle automatic CTCP replies (like VERSION and PING).
+
+@item C-c C-f (`erc-toggle-flood-control')
+Toggle use of flood control on sent messages.
+
+@item C-c TAB (`erc-invite-only-mode')
+Turn on the invite only mode (+i) for the current channel.
+
+@item C-c C-j (`erc-join-channel')
+Join channel. If point is at the beginning of a channel name, use that
+as default.
+
+@item C-c C-k (`erc-go-to-log-matches-buffer')
+Interactively open an erc-log-matches buffer
+
+@item C-c C-l (`erc-save-buffer-in-logs')
+Append buffer contents to the log file, if logging is enabled.
+
+@item C-c C-n (`erc-channel-names')
+Run "/names #channel" in the current channel.
+
+@item C-c C-o (`erc-get-channel-mode-from-keypress')
+Read a key sequence and call the corresponding channel mode function.
+After doing C-c C-o type in a channel mode letter.
+
+C-g means quit.
+RET let's you type more than one mode at a time.
+If "l" is pressed, `erc-set-channel-limit' gets called.
+If "k" is pressed, `erc-set-channel-key' gets called.
+Anything else will be sent to `erc-toggle-channel-mode'.
+
+@item C-c C-p (`erc-part-from-channel')
+Part from the current channel and prompt for a reason.
+
+@item C-c C-q (`erc-quit-server')
+Disconnect from current server after prompting for reason.
+
+@item C-c C-r (`erc-remove-text-properties-region')
+Clears the region (start,end) in object from all colors, etc.
+
+@item C-c C-t (`erc-set-topic')
+Prompt for a topic for the current channel.
+
+@item C-c C-u (`erc-kill-input')
+Kill current input line using `erc-bol' followed by `kill-line'.
+
+@end table
+
+
+@node Modules, Advanced Usage, Keystroke Summary, Top
+@comment node-name, next, previous, up
+@chapter Modules
+@cindex modules
+
+One way to add functionality to ERC is to customize which of its many
+modules are loaded.
+
+There is a spiffy customize interface, which may be reached by typing
+@kbd{M-x customize-option erc-modules RET}. Alternatively, set
+@code{erc-modules} manually and then call @code{erc-update-modules}.
+
+The following is a list of available modules.
+
+@table @code
+
+@cindex modules, autoaway
+@item autoaway
+Set away status automatically.
+
+@cindex modules, autojoin
+@item autojoin
+Join channels automatically
+
+@cindex modules, bbdb
+@item bbdb
+Integrate with the Big Brother Database
+
+@cindex modules, button
+@item button
+Buttonize URLs, nicknames, and other text
+
+@cindex modules, fill
+@item fill
+Wrap long lines
+
+@cindex modules, irccontrols
+@item irccontrols
+Highlight or remove IRC control characters
+
+@cindex modules, log
+@item log
+Save buffers in logs
+
+@cindex modules, match
+@item match
+Highlight pals, fools, and other keywords
+
+@cindex modules, netsplit
+@item netsplit
+Detect netsplits
+
+@cindex modules, noncommands
+@item noncommands
+Don't display non-IRC commands after evaluation
+
+@cindex modules, notify
+@item notify
+Notify when the online status of certain users changes
+
+@cindex modules, pcomplete
+@item pcomplete
+Complete nicknames and commands (programmable)
+
+@cindex modules, readonly
+@item readonly
+Make displayed lines read-only
+
+@cindex modules, replace
+@item replace
+Replace text in messages
+
+@cindex modules, ring
+@item ring
+Enable an input history
+
+@cindex modules, scrolltobottom
+@item scrolltobottom
+Scroll to the bottom of the buffer
+
+@cindex modules, services
+@item services
+Identify to Nickserv (IRC Services) automatically
+
+@cindex modules, smiley
+@item smiley
+Convert smileys to pretty icons
+
+@cindex modules, sound
+@item sound
+Play sounds when you receive CTCP SOUND requests
+
+@cindex modules, spell
+@item spell
+Check spelling
+
+@cindex modules, stamp
+@item stamp
+Add timestamps to messages
+
+@cindex modules, track
+@item track
+Track channel activity in the mode-line
+
+@cindex modules, truncate
+@item truncate
+Truncate buffers to a certain size
+
+@cindex modules, unmorse
+@item unmorse
+Translate morse code in messages
+
+@end table
+
+@c PRE5_2: Document every option of every module in its own subnode
+
+
+@node Advanced Usage, Getting Help and Reporting Bugs, Modules, Top
+@comment node-name, next, previous, up
+@chapter Advanced Usage
+@cindex advanced topics
+
+Write me.
+
+@c PRE5_2: (Node) Document every ERC option
+
+@c PRE5_2: (Node) Tips and tricks
+
+@c PRE5_2: (Node) Sample configs
+
+
+@node Getting Help and Reporting Bugs, History, Advanced Usage, Top
+@comment node-name, next, previous, up
+@chapter Getting Help and Reporting Bugs
+@cindex help, getting
+@cindex bugs, reporting
+
+After you have read this guide, if you still have questions about ERC,
+or if you have bugs to report, there are several places you can go.
+
+@itemize @bullet
+
+@item
+@uref{http://www.emacswiki.org/cgi-bin/wiki/EmacsIRCClient} is the
+emacswiki.org page for ERC. Anyone may add tips, hints, or bug
+descriptions to it.
+
+@item
+You can join the mailing list at @email{erc-help@@lists.sourceforge.net}
+using the subscription form at
+@uref{http://lists.sourceforge.net/lists/listinfo/erc-help}.
+
+This mailing list is also available via Gmane
+(@url{http://gmane.org/}). The group is called
+@samp{gmane.emacs.erc.general}. This provides additional methods for
+accessing the mailing list, adding content to it, and searching it.
+
+@item
+You can visit the IRC Freenode channel @samp{#emacs}. Many of the
+contributors are frequently around and willing to answer your
+questions.
+
+@end itemize
+
+
+@node History, Concept Index, Getting Help and Reporting Bugs, Top
+@comment node-name, next, previous, up
+@chapter History
+@cindex history, of ERC
+
+ERC was originally written by Alexander L. Belikoff
+@email{abel@@bfr.co.il} and Sergey Berezin
+@email{sergey.berezin@@cs.cmu.edu}. They stopped development around
+december 1999. Their last released version was ERC 2.0.
+
+P.S.: If one of the original developers of ERC reads this, we'd like to
+receive additional information for this file and hear comments in
+general.
+
+@itemize
+@item 2001
+
+In June 2001, Mario Lang @email{mlang@@delysid.org} and Alex Schroeder
+@email{alex@@gnu.org} took over development and created a ERC Project at
+sourceforge.net.
+
+In reaction to a mail about the new erc development, Sergey Berezin
+said, "First of all, I'm glad that my version of ERC is being used out
+there. The thing is, I do not have free time and enough incentive
+anymore to work on ERC, so I would be happy if you guys take over the
+project entirely."
+
+So we happily hacked away on ERC, and soon after (september 2001)
+released the next "stable" version, 2.1.
+
+Most of the development of the new ERC happend on #emacs on
+irc.openprojects.net. Over time, many people contributed code, ideas,
+bugfixes. And not to forget alot of alpha/beta/gamma testing.
+
+See the @file{CREDITS} file for a list of contributors.
+
+@item 2003
+
+ERC 3.0 is released.
+
+@item 2004
+
+ERC 4.0 is released.
+
+@item 2005
+
+ERC 5.0 is released. Michael Olson @email{mwolson@@gnu.org} becomes
+the release manager and eventually the maintainer.
+
+After some discussion between him and the Emacs developers, it is
+decided to include ERC in Emacs.
+
+@item 2006
+
+ERC 5.1 is released.
+
+@end itemize
+
+@node Concept Index, , History, Top
+@comment node-name, next, previous, up
+@unnumbered Index
+
+@printindex cp
+
+@bye
+
+@ignore
+ arch-tag: cf9cfaff-fc12-4297-ad15-ec2493002b1e
+@end ignore
diff --git a/man/faq.texi b/man/faq.texi
index b34a4d4ae12..95b79a86af6 100644
--- a/man/faq.texi
+++ b/man/faq.texi
@@ -1146,7 +1146,7 @@ operation on X. Mouse wheel support is now enabled by default.
@cindex New modes
Many new modes and packages have been included in Emacs, such as Leim,
-Calc, Tramp and URL, as well as IDO, CUA, rcirc, conf-mode,
+Calc, Tramp and URL, as well as IDO, CUA, rcirc, ERC, conf-mode,
python-mode, table, tumme, SES, ruler, Flymake, Org, etc.
@cindex Documentation
diff --git a/man/makefile.w32-in b/man/makefile.w32-in
index ba5435c9585..a6d77de7d11 100644
--- a/man/makefile.w32-in
+++ b/man/makefile.w32-in
@@ -42,7 +42,7 @@ INFO_TARGETS = $(infodir)/emacs $(infodir)/emacs-xtra $(infodir)/ccmode \
$(infodir)/woman $(infodir)/eshell $(infodir)/org \
$(infodir)/url $(infodir)/speedbar $(infodir)/tramp \
$(infodir)/ses $(infodir)/smtpmail $(infodir)/flymake \
- $(infodir)/newsticker $(infodir)/rcirc
+ $(infodir)/newsticker $(infodir)/rcirc $(infodir)/erc
DVI_TARGETS = emacs.dvi calc.dvi cc-mode.dvi cl.dvi dired-x.dvi \
ediff.dvi forms.dvi gnus.dvi message.dvi emacs-mime.dvi \
gnus.dvi message.dvi sieve.dvi pgg.dvi mh-e.dvi \
@@ -50,7 +50,7 @@ DVI_TARGETS = emacs.dvi calc.dvi cc-mode.dvi cl.dvi dired-x.dvi \
ada-mode.dvi autotype.dvi idlwave.dvi eudc.dvi ebrowse.dvi \
pcl-cvs.dvi woman.dvi eshell.dvi org.dvi url.dvi \
speedbar.dvi tramp.dvi ses.dvi smtpmail.dvi flymake.dvi \
- newsticker.dvi emacs-xtra.dvi rcirc.dvi
+ newsticker.dvi emacs-xtra.dvi rcirc.dvi erc.dvi
INFOSOURCES = info.texi
# The following rule does not work with all versions of `make'.
@@ -336,6 +336,11 @@ $(infodir)/rcirc: rcirc.texi
rcirc.dvi: rcirc.texi
$(ENVADD) $(TEXI2DVI) $(srcdir)/rcirc.texi
+$(infodir)/erc: erc.texi
+ $(MAKEINFO) erc.texi
+erc.dvi: erc.texi
+ $(ENVADD) $(TEXI2DVI) $(srcdir)/erc.texi
+
mostlyclean:
- $(DEL) *.log *.cp *.fn *.ky *.pg *.vr core *.tp *.core gnustmp.*