diff options
author | Miles Bader <miles@gnu.org> | 2006-01-29 13:08:58 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 2006-01-29 13:08:58 +0000 |
commit | e5b5275111b6cdf09e573eb494e139834136b91c (patch) | |
tree | 126d410d0f5b787582b9b63ca578362ed498794b | |
parent | 436f2a80d425eb47051fd6675f2cc7edf9d01242 (diff) | |
download | emacs-e5b5275111b6cdf09e573eb494e139834136b91c.tar.gz |
Revision: emacs@sv.gnu.org/emacs--devo--0--patch-22
Creator: Michael Olson <mwolson@gnu.org>
Install ERC.
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 @@ -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 @@ -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.* |