Revision: emacs@sv.gnu.org/emacs--devo--0--patch-22
Creator: Michael Olson <mwolson@gnu.org> Install ERC.
This commit is contained in:
parent
33c7860d38
commit
597993cf44
53 changed files with 28894 additions and 8 deletions
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
599
etc/ERC-NEWS
Normal file
599
etc/ERC-NEWS
Normal file
|
@ -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
|
11
etc/NEWS
11
etc/NEWS
|
@ -1504,6 +1504,17 @@ colors as on X.
|
|||
|
||||
* New Modes and Packages in Emacs 22.1
|
||||
|
||||
** ERC is now part of the Emacs distribution.
|
||||
|
||||
ERC is a powerful, modular, and extensible IRC client for Emacs.
|
||||
|
||||
To see what modules are available, type
|
||||
M-x customize-option erc-modules RET.
|
||||
|
||||
To start an IRC session, type M-x erc-select, and follow the prompts
|
||||
for server, port, and nick.
|
||||
|
||||
---
|
||||
** Rcirc is now part of the Emacs distribution.
|
||||
|
||||
Rcirc is an Internet relay chat (IRC) client. It supports
|
||||
|
|
2
info/dir
2
info/dir
|
@ -41,6 +41,8 @@ Emacs
|
|||
* CC mode: (ccmode). Emacs mode for editing C, C++, Objective-C,
|
||||
Java, Pike, and IDL code.
|
||||
* Ebrowse: (ebrowse). A C++ class browser for Emacs.
|
||||
* ERC: (erc). Powerful, modular, and extensible IRC client
|
||||
for Emacs.
|
||||
* Flymake: (flymake). An on-the-fly syntax checker for Emacs.
|
||||
* IDLWAVE: (idlwave). Major mode and shell for IDL and WAVE/CL files.
|
||||
|
||||
|
|
327
lisp/erc/ChangeLog
Normal file
327
lisp/erc/ChangeLog
Normal file
|
@ -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
|
1042
lisp/erc/ChangeLog.2001
Normal file
1042
lisp/erc/ChangeLog.2001
Normal file
File diff suppressed because it is too large
Load diff
2601
lisp/erc/ChangeLog.2002
Normal file
2601
lisp/erc/ChangeLog.2002
Normal file
File diff suppressed because it is too large
Load diff
2145
lisp/erc/ChangeLog.2003
Normal file
2145
lisp/erc/ChangeLog.2003
Normal file
File diff suppressed because it is too large
Load diff
2074
lisp/erc/ChangeLog.2004
Normal file
2074
lisp/erc/ChangeLog.2004
Normal file
File diff suppressed because it is too large
Load diff
1222
lisp/erc/ChangeLog.2005
Normal file
1222
lisp/erc/ChangeLog.2005
Normal file
File diff suppressed because it is too large
Load diff
207
lisp/erc/erc-autoaway.el
Normal file
207
lisp/erc/erc-autoaway.el
Normal file
|
@ -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
|
139
lisp/erc/erc-autojoin.el
Normal file
139
lisp/erc/erc-autojoin.el
Normal file
|
@ -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
|
1786
lisp/erc/erc-backend.el
Normal file
1786
lisp/erc/erc-backend.el
Normal file
File diff suppressed because it is too large
Load diff
504
lisp/erc/erc-button.el
Normal file
504
lisp/erc/erc-button.el
Normal file
|
@ -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
|
207
lisp/erc/erc-compat.el
Normal file
207
lisp/erc/erc-compat.el
Normal file
|
@ -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
|
222
lisp/erc/erc-complete.el
Normal file
222
lisp/erc/erc-complete.el
Normal file
|
@ -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
|
1135
lisp/erc/erc-dcc.el
Normal file
1135
lisp/erc/erc-dcc.el
Normal file
File diff suppressed because it is too large
Load diff
180
lisp/erc/erc-ezbounce.el
Normal file
180
lisp/erc/erc-ezbounce.el
Normal file
|
@ -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
|
197
lisp/erc/erc-fill.el
Normal file
197
lisp/erc/erc-fill.el
Normal file
|
@ -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
|
522
lisp/erc/erc-goodies.el
Normal file
522
lisp/erc/erc-goodies.el
Normal file
|
@ -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
|
184
lisp/erc/erc-ibuffer.el
Normal file
184
lisp/erc/erc-ibuffer.el
Normal file
|
@ -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
|
87
lisp/erc/erc-identd.el
Normal file
87
lisp/erc/erc-identd.el
Normal file
|
@ -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
|
143
lisp/erc/erc-imenu.el
Normal file
143
lisp/erc/erc-imenu.el
Normal file
|
@ -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
|
213
lisp/erc/erc-lang.el
Normal file
213
lisp/erc/erc-lang.el
Normal file
|
@ -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
|
396
lisp/erc/erc-list.el
Normal file
396
lisp/erc/erc-list.el
Normal file
|
@ -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
|
358
lisp/erc/erc-log.el
Normal file
358
lisp/erc/erc-log.el
Normal file
|
@ -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
|
658
lisp/erc/erc-match.el
Normal file
658
lisp/erc/erc-match.el
Normal file
|
@ -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
|
121
lisp/erc/erc-menu.el
Normal file
121
lisp/erc/erc-menu.el
Normal file
|
@ -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
|
861
lisp/erc/erc-nets.el
Normal file
861
lisp/erc/erc-nets.el
Normal file
|
@ -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
|
212
lisp/erc/erc-netsplit.el
Normal file
212
lisp/erc/erc-netsplit.el
Normal file
|
@ -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
|
411
lisp/erc/erc-nicklist.el
Normal file
411
lisp/erc/erc-nicklist.el
Normal file
|
@ -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
|
337
lisp/erc/erc-nickserv.el
Normal file
337
lisp/erc/erc-nickserv.el
Normal file
|
@ -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
|
254
lisp/erc/erc-notify.el
Normal file
254
lisp/erc/erc-notify.el
Normal file
|
@ -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
|
108
lisp/erc/erc-page.el
Normal file
108
lisp/erc/erc-page.el
Normal file
|
@ -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
|
275
lisp/erc/erc-pcomplete.el
Normal file
275
lisp/erc/erc-pcomplete.el
Normal file
|
@ -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
|
93
lisp/erc/erc-replace.el
Normal file
93
lisp/erc/erc-replace.el
Normal file
|
@ -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
|
148
lisp/erc/erc-ring.el
Normal file
148
lisp/erc/erc-ring.el
Normal file
|
@ -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
|
149
lisp/erc/erc-sound.el
Normal file
149
lisp/erc/erc-sound.el
Normal file
|
@ -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
|
369
lisp/erc/erc-speedbar.el
Normal file
369
lisp/erc/erc-speedbar.el
Normal file
|
@ -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
|
93
lisp/erc/erc-spelling.el
Normal file
93
lisp/erc/erc-spelling.el
Normal file
|
@ -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
|
335
lisp/erc/erc-stamp.el
Normal file
335
lisp/erc/erc-stamp.el
Normal file
|
@ -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
|
839
lisp/erc/erc-track.el
Normal file
839
lisp/erc/erc-track.el
Normal file
|
@ -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
|
121
lisp/erc/erc-truncate.el
Normal file
121
lisp/erc/erc-truncate.el
Normal file
|
@ -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
|
74
lisp/erc/erc-viper.el
Normal file
74
lisp/erc/erc-viper.el
Normal file
|
@ -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
|
130
lisp/erc/erc-xdcc.el
Normal file
130
lisp/erc/erc-xdcc.el
Normal file
|
@ -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
|
6144
lisp/erc/erc.el
Normal file
6144
lisp/erc/erc.el
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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.*
|
||||
|
||||
|
|
624
man/erc.texi
Normal file
624
man/erc.texi
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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.*
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue